<?javascript

function selected_node ()
{
   tree = enode ("ctree.top");
   if (tree == null) {
       print ("umm.. no tree.top ?\n");
       return null;
   }

   selected = tree.children_attrib ("selected", "true");
   if (selected) {
       node = selected[0];
       return (node);
   } else {
       return (null);
   }
}   

function hide_window (node)
{
    if (node.type == "window") {
        node.attrib.visible = "false";
    } else {
	window = node.attrib.arg;
	enode (window).attrib.visible = "false";
    }
}

function show_window (node)
{
    window = node.attrib.arg;
    enode(window).attrib.visible = "true";
}

function update_label (calling_node)
{
    label = enode ("label.tool_description");
    label.attrib.text = calling_node.attrib.description;
}

function ctree_new_row (target_node, parent_ctree_row)
{
    title = target_node.attrib.title;

    if (title != "")
	extra = "(" + title + ")";
    else
	extra = "";

    if (target_node.type == "instance") {
	obj = target_node.child("object");

	if (obj != null) {
	    extra = "(" + obj.basename + ")";
	}
    }

    r = parent_ctree_row.new_child ("ctree-row");
    r.attrib["dest-node"] = target_node.path;

    c = r.new_child ("ctree-cell");
    c.attrib.text = target_node.basename + extra;


    more_children = target_node.children();
    if (more_children) {
	n = r.new_child ("ctree-row");
	c = n.new_child ("ctree-cell");
	c.attrib.text = "dummy";
    }

    return (r);
}

function expand_tree (ctree_node, expanded_node)
{
    path = expanded_node.attrib["dest-node"];

    if (path == "")
	return;
   
    dest_node = enode(path);

    // Clean out old info.
    nodes = expanded_node.children("ctree-row");

    try {
	for (node in nodes) {
	    node.destroy();
	}
    } catch (e) {}

    // Get a list of nodes at the destination
    nodes = dest_node.children();
    if (nodes == null)
	return;


    ctree_node.attrib.frozen = "true";

    // Use a try/catch in case something goes wrong.. we don't want to leave the clist
    // frozen forever. 
    try {
	// And generate tree entries for each one
	for (node in nodes) {
	    ctree_new_row (node, expanded_node);
	}
    } catch (e) {}
    
    ctree_node.attrib.frozen = "false";

    // We have to reset the expanded attribute ourselves, because the collapse callback
    // gets called when we clean out the children above.
    expanded_node.attrib_quiet ("expanded", "true");
}


function new_application(node)
{
    element = node.attrib.element;

    currently_selected_node = selected_node ();
    if (currently_selected_node == null) {
        print ("No node selected?");
        return;
    }

    target = enode(currently_selected_node.attrib["dest-node"]);

    new_node = target.new_child("object");
    new_window = new_node.new_child("window");
    new_window.attrib.title = "New Window";
    expand_tree_to (new_window);
}

    
function new_element(node)
{
    element = node.attrib.element;

    currently_selected_node = selected_node ();
    if (currently_selected_node == null) {
      	print ("No node selected.");
	return;
    }

    target = enode(currently_selected_node.attrib["dest-node"]);

    // Make sure it's expanded..
    if (currently_selected_node.attrib.expanded != "true")
	currently_selected_node.attrib.expanded = "true";
    
    //print ("We should add", element);
    new_node = target.new_child(element);
    row = ctree_new_row (new_node, currently_selected_node);
    row.attrib.selected = "true";
}


function expand_tree_to (node)
{
    // Obviously the root will have to be expanded..
    treeroot = enode ("ctree-row.root");
    treeroot.attrib.expanded = "true";
    ctree = enode ("ctree.top");
    
    // Now split the path into its parts, and walk through each, opening
    // the tree as we go.
    path = node.path;

    curnode = treeroot;
    // Split up the path
    basenames = path.split("/");
    for (basename in basenames) {
	
	if (basename.length < 0)
	    continue;

	/* get a list of children at this level */
	treelist = curnode.children ();
	for (tree_node in treelist) {
	    
	    if (tree_node.type != "ctree-row")
		continue;
		
    	    dest_node = enode (tree_node.attrib["dest-node"]);
	    if (!dest_node)
		continue;

	    /* If the destination nodes basename matches this basename, expand it */
	    if (dest_node.basename == basename) {

		print ("expanding node", dest_node.path, "because it matches basename", basename);
		tree_node.attrib.expanded = "true";
		curnode = tree_node;

		/* We matched this far, maybe we're at the end ? */
		if (node.path == dest_node.path) {
		    curnode.attrib.selected = "true";
		    return;
		}
	    }
	}
    }
}



/******************************************************
 * Deal with Context menu and cut/paste etc. stuff.   *
 *****************************************************/
    
popup_on_path = null;

function popup_context (ctree, row_node, cell_node, button, column)
{
    popup_on_path = row_node;

    if (button == 3) {
	enode("popupmenu.context").attrib.popup = "true";
	row_node.attrib.selected = "true";
    }
}

function menu_view_xml_tree (node)
{
    cursel_node = selected_node ();
    target = enode (cursel_node.attrib["dest-node"]);

    xml = target.get_xml();

    enode("text.view").set_data(xml);

    window = enode ("window.text");
    window.attrib.title = "XML Tree for", target.basename;
    window.attrib.visible = "true";
}

function menu_edit_data (node)
{
    cursel_node = selected_node ();
    target = enode (cursel_node.attrib["dest-node"]);

    data = target.get_data();

    enode("text.view").set_data(data);

    window = enode ("window.text");
    window.attrib.title = "Data for " + target.basename;
    window.attrib.visible = "true";
    // Save the target path
    window.attrib.node = target.path;
}

function ok_data_edit (buttun)
{
    window = button.parent ("window");
    text = window.child ("text.data-edit");

    node = enode (window.attrib.node);

    // Save the data from the text into the node
    node.set_data (text.get_data());

    window.attrib.visible = "false";
}

function cancel_data_edit (button)
{
    window = button.parent ("window");
    window.attrib.visible = "false";
}

function menu_delete_tree (node)
{
    target = enode (popup_on_path.attrib["dest-node"]);
    target.destroy();
    popup_on_path.destroy();
}



/*
 * Deal with loading XML files
 */

function menu_load_file (node)
{
    save_dialog = enode ("filesel.dialog");

    save_dialog.attrib.file = "";
    save_dialog.attrib.visible = "true";
    save_dialog.attrib.title = "Load XML Tree";
    save_dialog.attrib.onselect = "menu_load_file_selected";
}

function menu_load_file_selected (filesel, file)
{
    filesel.attrib.visible = "false";
    inc = enode ("/").new_child ("include");
    inc.attrib.file = file;
} 
    

/*
 * Deal with saving XML files
 */

function menu_save_xml_tree (node)
{
    save_dialog = enode ("filesel.dialog");

    cursel_node = selected_node ();
    if (cursel_node == null)
	return;

    node = enode (cursel_node.attrib["dest-node"]);

    file = node.attrib.__filename;

    save_dialog.attrib.file = file;
    save_dialog.attrib.visible = "true";
    save_dialog.attrib.title = "Save XML Tree";
    save_dialog.attrib.onselect = "menu_save_xml_tree_selected";
}

function menu_save_xml_tree_selected (save_dialog, file)
{
    cursel_node = selected_node ();
    node = enode (cursel_node.attrib["dest-node"]);

    node.attrib.__filename = file;

    print ("file =", file);

    xml = node.get_xml();

    fp = new File (file);
    if (!fp.open ("w")) {
    	System.error (program, ": couldn't open input file `", file,
		      "': ", System.strerror (System.errno), "\n");
	return;
    }

    fp.write (xml);
    fp.close ();
}

/***************************************************************
 * Cut and Paste stuff                                         *
 **************************************************************/

function paste_ok ()
{
    enode ("menuitem.paste").attrib.sensitive = "true";
    enode ("menuitem.editpaste").attrib.sensitive = "true";
    enode ("button.toolbarpaste").attrib.sensitive = "true";
}

function cut_tree (node)
{
    cursel_node = selected_node ();
    target = enode (cursel_node.attrib["dest-node"]);

    xml = target.get_xml ();
    node = enode ("data.cutpaste");
    node.set_data (xml);
    
    parent = cursel_node.parent ("ctree-row");
    if (parent)
	parent.attrib.selected = "true";
    cursel_node.destroy ();
    paste_ok ();
    
    target.destroy ();
}

function cut_children_tree (node)
{
    cursel_node = selected_node ();
    target = enode (cursel_node.attrib["dest-node"]);

    xml = target.get_child_xml ();
    node = enode ("data.cutpaste");
    node.set_data (xml);

    children = cursel_node.children ("ctree-row");
    for (child in children)
	child.destroy ();
    paste_ok ();
    
    target.destroy_children ();
}


function copy_tree (node)
{
    cursel_node = selected_node ();
    target = enode (cursel_node.attrib["dest-node"]);

    node = enode ("data.cutpaste");
    xml = target.get_xml();
    node.set_data (xml);
    paste_ok ();
}

function copy_children_tree (node)
{
    cursel_node = selected_node ();
    target = enode (cursel_node.attrib["dest-node"]);

    node = enode ("data.cutpaste");
    xml = target.get_child_xml ();
    node.set_data (xml);
    paste_ok ();
}

function paste_tree (node)
{
    cursel_node = selected_node ();
    target = enode (cursel_node.attrib["dest-node"]);
    
    node = enode ("data.cutpaste");
    xml = node.get_data ();
    target.append_xml (xml);

    cursel_node.attrib.expanded = "true";
}


// Select root node at startup
enode ("ctree-row.root").attrib.expanded = "true";
enode ("ctree-row.root").attrib.selected = "true";
    
	
?>


syntax highlighted by Code2HTML, v. 0.9.1