* Began replacing the old, sux0r-prone tree view with NanoTree.
authorArt Cancro <ajc@citadel.org>
Sun, 12 Jun 2005 22:02:46 +0000 (22:02 +0000)
committerArt Cancro <ajc@citadel.org>
Sun, 12 Jun 2005 22:02:46 +0000 (22:02 +0000)
  WARNING: This isn't finished, but I'm committing it anyway because I have
  to move to a different computer.  DON'T RUN THIS.

24 files changed:
webcit/ChangeLog
webcit/roomops.c
webcit/static/folder_closed.gif [new file with mode: 0644]
webcit/static/folder_open.gif [new file with mode: 0644]
webcit/static/head.html
webcit/static/help_16x16.gif [new file with mode: 0644]
webcit/static/lastnode.gif [new file with mode: 0644]
webcit/static/line.gif [new file with mode: 0644]
webcit/static/minus.gif
webcit/static/minus_last.gif [new file with mode: 0644]
webcit/static/minus_last_no_root.gif [new file with mode: 0644]
webcit/static/minus_no_root.gif [new file with mode: 0644]
webcit/static/minus_nolines.gif [new file with mode: 0644]
webcit/static/nanotree.js [new file with mode: 0644]
webcit/static/page16x16.gif [new file with mode: 0644]
webcit/static/plus.gif
webcit/static/plus_last.gif [new file with mode: 0644]
webcit/static/plus_last_no_root.gif [new file with mode: 0644]
webcit/static/plus_no_root.gif [new file with mode: 0644]
webcit/static/plus_nolines.gif [new file with mode: 0644]
webcit/static/t.gif [new file with mode: 0644]
webcit/static/t_no_root.gif [new file with mode: 0644]
webcit/static/user_16x16.gif [new file with mode: 0644]
webcit/static/white.gif [new file with mode: 0644]

index 1c68c0e2db50d69c8bf3103518b9c01a20fa575c..acdf6924457599b256553fa3320e14942763e682 100644 (file)
@@ -1,4 +1,9 @@
 $Log$
+Revision 611.10  2005/06/12 22:02:45  ajc
+* Began replacing the old, sux0r-prone tree view with NanoTree.
+  WARNING: This isn't finished, but I'm committing it anyway because I have
+  to move to a different computer.  DON'T RUN THIS.
+
 Revision 611.9  2005/06/12 18:34:50  ajc
 * Removed some unreferenced files from the static/ directory.
 
@@ -2573,3 +2578,4 @@ Sun Dec  6 19:50:55 EST 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
 
 1998-12-03 Nathan Bryant <bryant@cs.usm.maine.edu>
        * webserver.c: warning fix
+
index 93e60b5dbf05eaa72c14cf5dbdf9ec49b456d03f..d4f6b1acd723b151078c18acd349fe438b049baf 100644 (file)
@@ -2208,13 +2208,39 @@ void do_folder_view(struct folder *fold, int max_folders, int num_floors) {
        int actnum = 0;
        int has_subfolders = 0;
 
-       /* Include the menu expanding/collapsing code */
-       wprintf("<script type=\"text/javascript\" src=\"/static/menuExpandable3.js\"></script>\n");
+       /* include NanoTree */
+       wprintf("<script type=\"text/javascript\" language=\"JavaScript\" src=\"static/nanotree.js\">\n");
+
+       /* initialize NanoTree */
+       wprintf("<script type=\"text/javascript\" language=\"JavaScript\">                      \n"
+               "       showRootNode = true;                                                    \n"
+               "       sortNodes = false;                                                      \n"
+               "       dragable = false;                                                       \n"
+               "       lookAndFeel = WINDOWS_XP;                                               \n"
+               "                                                                               \n"
+               "       function do_nanotree_init() {                                           \n"
+               "               container = document.getElementById('roomlist_div');            \n"
+               "               showTree('');                                                   \n"
+               "       }                                                                       \n"
+               "                                                                               \n"
+               "       function standardClick(treeNode) {                                      \n"
+               "               /* FIXME call a dotgoto function here */                        \n"
+               "       }                                                                       \n"
+               "                                                                               \n"
+               "       function nodeEdited(treeNode) {                                         \n"
+               "               /* FIXME can we make use of this? */                            \n"
+               "       }                                                                       \n"
+               "                                                                               \n"
+               "       var closedGif = 'static/' + getLookAndFeelPath() + '/folder_closed.gif';\n"
+               "       var openGif = 'static/' + getLookAndFeelPath() + '/folder_open.gif';    \n"
+               "       var pageIcon = 'static/page16x16.gif';                                  \n"
+               "       var userIcon = 'static/user_16x16.gif';                                 \n"
+               "       var helpIcon = 'static/help_16x16.gif';                                 \n"
+               "</script>                                                                      \n"
+       );
 
        /* BEGIN TREE MENU */
-       wprintf("<div style=\"background: white\">\n");
-       wprintf("<div id=\"mainMenu\">\n");
-       wprintf("<UL id=\"menuList\">\n");
+       wprintf("<UL>\n");
        levels = 0;
        oldlevels = 0;
 
@@ -2237,10 +2263,7 @@ void do_folder_view(struct folder *fold, int max_folders, int num_floors) {
                }
 
                if (has_subfolders) {
-                       wprintf("<LI");
-                       if (levels == 1) wprintf(" class=\"menubar\"");
-                       wprintf(">");
-                       wprintf("<A href=\"#\" id=\"actuator%d\" class=\"actuator\"></a>\n", actnum);
+                       wprintf("<LI>(has subfolders)");
                }
                else {
                        wprintf("<LI>");
@@ -2275,21 +2298,19 @@ void do_folder_view(struct folder *fold, int max_folders, int num_floors) {
                wprintf("\n");
 
                if (has_subfolders) {
-                       wprintf("<UL id=\"menu%d\" class=\"%s\">\n",
-                               actnum++,
-                               ( (levels == 1) ? "menu" : "submenu")
-                       );
+                       wprintf("<UL>\n");
                }
 
                oldlevels = levels;
        }
        wprintf("</UL></UL>\n");
+/*
        wprintf("<img src=\"/static/blank.gif\" onLoad = ' \n");
        for (i=0; i<actnum; ++i) {
                wprintf(" initializeMenu(\"menu%d\", \"actuator%d\");\n", i, i);
        }
        wprintf(" ' > \n");
-       wprintf("</DIV>\n");
+ */
        /* END TREE MENU */
 }
 
diff --git a/webcit/static/folder_closed.gif b/webcit/static/folder_closed.gif
new file mode 100644 (file)
index 0000000..5a5eac9
Binary files /dev/null and b/webcit/static/folder_closed.gif differ
diff --git a/webcit/static/folder_open.gif b/webcit/static/folder_open.gif
new file mode 100644 (file)
index 0000000..da90b34
Binary files /dev/null and b/webcit/static/folder_open.gif differ
index e67f362e1dad6833a1dfb509987aad073c864805..2685f2aa06be132d8c3a6f49d70f98c939896c79 100644 (file)
@@ -370,66 +370,58 @@ td li.frameset, .elements li.frameset {
        input#toggler, .toolbar { display: none }
 }
 
-<!-- begin tree view styles -->
+<!-- begin nanotree styles -->
 
-#mainMenu {
-  border: 1px solid #CCC;
-  color: #000;
-}
-
-#menuList {
-  margin: 0px;
-  padding: 10px 0px 10px 15px;
-}
-
-li.menubar {
-  background: url(/static/plus.gif) no-repeat 0em 0.3em;
-  font-size: 12px;
-  line-height: 1.5em;
-  list-style: none outside;
-}
-
-.menu, .submenu {
-  display: none;
-  margin-left: 15px;
-  padding: 0px;
-}
-
-.menu li, .submenu li {
-  background: url(/static/square.gif) no-repeat 0em 0.3em;
-  list-style: none outside;
-}
-
-a.actuator {
-  background-color: transparent;
-  color: #000;
-  font-size: 12px;
-  padding-left: 15px;
-  text-decoration: none;
-}
-
-a.actuator:hover {
-  text-decoration: underline;
+.treetitle {
+       padding:2px;
+       cursor:default;
+       
+       font-family: "Bitstream Vera Sans",Arial,Helvetica,sans-serif;
+       font-size: 11px;
+       color: #000000;
 }
-
-.menu li a, .submenu li a {
-  background-color: transparent;
-  color: #000;
-  font-size: 12px;
-  padding-left: 15px;
-  text-decoration: none;
+.editednode {
+       padding:2px;
+       cursor:default;
+       background-color: #FFFFFF;;
+       color: #000000;
+       
+       font-family: "Bitstream Vera Sans",Arial,Helvetica,sans-serif;
+       font-size: 11px;
 }
-
-.menu li a:hover, submenu li a:hover {
-  /*border-bottom: 1px dashed #000;*/
-  text-decoration: underline;
+.editednodeinput {
+       background-color: #FFFFFF;;
+       color: #000000;
+       
+       width: 150px;
+       height: 17px;
+       
+       border-style: solid;
+       border-width: 1px;
+       border-color: #000000;
+       
+       font-family: "Bitstream Vera Sans",Arial,Helvetica,sans-serif;
+       font-size: 11px;
+}
+.treetitleselectedfocused {
+       padding:2px;
+       cursor:default;
+       background-color: highlight;
+       color: highlighttext;
+       
+       font-family: "Bitstream Vera Sans",Arial,Helvetica,sans-serif;
+       font-size: 11px;
 }
-
-span.key {
-  text-decoration: underline;
+.treetitleselectedblured {
+       padding:2px;
+       cursor:default;
+       background-color: menu;
+       color: windowtext;
+       font-family: "Bitstream Vera Sans",Arial,Helvetica,sans-serif;
+       font-size: 11px;
 }
 
-<!-- end tree view styles -->
+<!-- end nanotree styles -->
 
 </style>
 
diff --git a/webcit/static/help_16x16.gif b/webcit/static/help_16x16.gif
new file mode 100644 (file)
index 0000000..e65b683
Binary files /dev/null and b/webcit/static/help_16x16.gif differ
diff --git a/webcit/static/lastnode.gif b/webcit/static/lastnode.gif
new file mode 100644 (file)
index 0000000..d1fbed7
Binary files /dev/null and b/webcit/static/lastnode.gif differ
diff --git a/webcit/static/line.gif b/webcit/static/line.gif
new file mode 100644 (file)
index 0000000..1bb437a
Binary files /dev/null and b/webcit/static/line.gif differ
index 608bc2908dce58c02d76968636466017768a53d2..50f623b8cc8d2a4533061f3784a299d659fa4131 100644 (file)
Binary files a/webcit/static/minus.gif and b/webcit/static/minus.gif differ
diff --git a/webcit/static/minus_last.gif b/webcit/static/minus_last.gif
new file mode 100644 (file)
index 0000000..c316c83
Binary files /dev/null and b/webcit/static/minus_last.gif differ
diff --git a/webcit/static/minus_last_no_root.gif b/webcit/static/minus_last_no_root.gif
new file mode 100644 (file)
index 0000000..cd52861
Binary files /dev/null and b/webcit/static/minus_last_no_root.gif differ
diff --git a/webcit/static/minus_no_root.gif b/webcit/static/minus_no_root.gif
new file mode 100644 (file)
index 0000000..0cd1ab6
Binary files /dev/null and b/webcit/static/minus_no_root.gif differ
diff --git a/webcit/static/minus_nolines.gif b/webcit/static/minus_nolines.gif
new file mode 100644 (file)
index 0000000..b54e870
Binary files /dev/null and b/webcit/static/minus_nolines.gif differ
diff --git a/webcit/static/nanotree.js b/webcit/static/nanotree.js
new file mode 100644 (file)
index 0000000..f8579a2
--- /dev/null
@@ -0,0 +1,910 @@
+/**
+* Original Author of this file: Martin Mouritzen. (martin@nano.dk)
+*
+*
+* (Lack of) Documentation:
+*
+*
+* If a finishedLoading method exists, it will be called when the tree is loaded.
+* (good to display a div, etc.).
+*
+*
+* You have to set the variable rootNode (as a TreeNode).
+*
+* You have to set a container element, this is the element in which the tree will be.
+*
+*
+* TODO: 
+* Save cookies better (only 1 cookie for each tree). Else the page will totally cookieclutter.
+*
+***********************************************************************
+* Configuration variables.
+************************************************************************/
+
+// Should the rootNode be displayed.
+var showRootNode = true;
+
+// Should the dashed lines between nodes be shown.
+var showLines = true;
+
+// Should the nodes be sorted? (You can either specify a number, then it will be sorted by that, else it will
+// be sorted alphabetically (by name).
+var sortNodes = true;
+
+// This is IMPORTANT... use an unique id for each document you use the tree in. (else they'll get mixed up).
+var documentID = window.location.href;
+
+// being read from cookie.
+var nodesOpen = new Array();
+
+// RootNode of the tree.
+var rootNode;
+
+// Container to display the Tree in.
+var container;
+
+// Shows/Hides subnodes on startup
+var showAllNodesOnStartup = false;
+
+// Is the roots dragable?
+var dragable = false;
+
+
+/************************************************************************
+* The following is just instancevariables.
+************************************************************************/
+var href = '';
+
+// rootNodeCallBack name (if null, it's not selectable).
+var rootNodeCallBack = null;
+
+// selectedNode
+var selectedNode = null;
+
+var states = '';
+var statearray = new Array();
+
+var treeNodeEdited = null;
+
+var editaborted = false;
+
+var floatDragElement = null;
+var colouredElement = null;
+var draggedNodeID = null;
+var lastDraggedOnNodeID = null;
+
+
+/**
+* The TreeNode Object
+* @param id unique id of this treenode
+* @param name The title of this node
+* @param icon The icon if this node (Can also be an array with 2 elements, the first one will represent the closed state, and the next one the open state)
+* @param param A parameter, this can be pretty much anything. (eg. an array with information).
+* @param orderNumber an orderNumber If one is given the nodes will be sorted by this (else they'll be sorted alphabetically (If sorting is on).
+*/
+function TreeNode(id,name,icon,param,orderNumber) {
+       this.id = id;
+       this.childs = new Array();
+       this.name = (name == null ? 'unset name' : name);
+       this.icon = (icon == null ? '' : icon);
+       this.parent = null;
+       this.handler = null;
+       this.param = (param == null ? '' : param);
+       this.orderNumber = (orderNumber == null ? -1 : orderNumber);
+       
+       this.openeventlisteners = new Array();
+       this.editeventlisteners = new Array();
+       this.moveeventlisteners = new Array();
+       this.haschilds = false;
+       this.editable = false;
+       this.linestring = '';
+       
+       this.nextSibling = null;
+       this.prevSibling = null;
+       
+       this.childsHasBeenFetched = false;
+
+       this.getID = function() {
+               return this.id;
+       }
+       this.setName = function(newname) {
+               this.name = newname;
+       }
+       this.getName = function() {
+               return this.name;
+       }
+       this.getParam = function() {
+               return this.param;
+       }
+       this.setIcon = function(icon) {
+               this.icon = icon;
+       }
+       this.getIcon = function() {
+               if (typeof(this.icon) == 'object') {
+                       return this.icon[0];
+               }
+               return this.icon;
+       }
+       this.getOpenIcon = function() {
+               if (typeof(this.icon) == 'object') {
+                       return this.icon[1];
+               }
+               return this.icon;
+       }
+       this.hasIcon = function () {
+               return this.icon != '';
+       }
+       this.getOrderNumber = function() {
+               return this.orderNumber;
+       }
+       this.addOpenEventListener = function(event) {
+               this.openeventlisteners[this.openeventlisteners.length] = event;
+       }
+       this.gotOpenEventListeners = function() {
+               return (this.openeventlisteners.length > 0);
+       }
+       this.addEditEventListener = function(event) {
+               this.editeventlisteners[this.editeventlisteners.length] = event;
+       }
+       this.gotEditEventListeners = function() {
+               return (this.editeventlisteners.length > 0);
+       }
+       this.addMoveEventListener = function(event) {
+               this.moveeventlisteners[this.moveeventlisteners.length] = event;
+       }
+       this.gotMoveEventListeners = function() {
+               return (this.moveeventlisteners.length > 0);
+       }
+       this.addChild = function(childNode) {
+               var possiblePrevNode = this.childs[this.childs.length - 1]
+               if (possiblePrevNode) {
+                       possiblePrevNode.nextSibling = childNode;
+                       childNode.prevSibling = possiblePrevNode;
+                       // alert(childNode.prevSibling);
+               }
+
+               this.childs[this.childs.length] = childNode;
+               childNode.setParent(this);
+
+               if (sortNodes) {
+                       function sortByOrder(a,b) {
+                               var order1 = a.getOrderNumber();
+                               var order2 = b.getOrderNumber();
+                               if (order1 == -1 || order2 == -1) {
+                                       return a.getName().toLowerCase() > b.getName().toLowerCase() ? 1 : -1;
+                               }
+                               else {
+                                       if (order1 == order2) {
+                                               // If they got the same order number, then we'll sort by their title.
+                                               return a.getName().toLowerCase() > b.getName().toLowerCase() ? 1 : -1;
+                                       }
+                                       else {
+                                               return order1 - order2;
+                                       }
+                               }
+                       }
+                       this.childs.sort(sortByOrder);
+               }
+       }
+       this.removeChild = function(childNode) {
+               var found = false;
+               for (var i=0;i<this.childs.length;i++) {
+                       if (found) {
+                               this.childs[i] = this.childs[i + 1];
+                       }
+                       if (this.childs[i] == childNode) {
+                               if (i == (this.childs.length - 1)) {
+                                       this.childs[i] = null;
+                               }
+                               else {
+                                       this.childs[i] = this.childs[i + 1];
+                               }
+                               found = true;
+                       }
+               }
+               if (found) {
+                       this.childs.length = this.childs.length-1;
+               }
+       }
+       this.resetChilds = function() {
+               this.childs = new Array();
+       }
+       this.setHasChilds = function(hasChilds) {
+               this.haschilds = hasChilds;
+       }
+       this.hasChilds = function() {
+               if (this.haschilds == true) {
+                       return true;
+               }
+               return (this.childs.length > 0);
+       }
+       this.getChildCount = function() {
+               return this.childs.length;
+       }
+       this.getFirstChild = function() {
+               if (this.hasChilds()) {
+                       return this.childs[0];
+               }
+               return null;
+       }
+       this.gotHandler = function() {
+               return this.handler != null;
+       }
+       this.setHandler = function(handler) {
+               this.handler = handler;
+       }
+       this.getHandler = function() {
+               return this.handler;
+       }
+       this.setParent = function(parent) {
+               this.parent = parent;
+       }
+       this.getParent = function() {
+               return this.parent;
+       }
+       this.getLineString = function() {
+               return this.linestring;
+       }
+       this.setLineString = function(string) {
+               this.linestring = string;
+       }
+       this.isEditable = function() {
+               return this.editable;
+       }
+       this.setEditable = function(editable) {
+               this.editable = editable;
+       }
+       
+}
+function getTreeNode(nodeID) {
+       return findNodeWithID(rootNode,nodeID);
+}
+function findNodeWithID(node,nodeID) {
+       if (node.getID() == nodeID) {
+               return node;
+       }
+       else {
+               if (node.hasChilds()) {
+                       for(var i=0;i<node.getChildCount();i++) {
+                               var value = findNodeWithID(node.childs[i],nodeID);
+                               if (value != false) {
+                                       return value;
+                               }
+                       }
+               }
+               return false;
+       }
+}
+function readStates() {
+       //setCookie('tree' + documentID,'');
+       states = getCookie('tree' + documentID);
+       if (states != null) {
+               var array = states.split(';');
+               for(var i=0;i<array.length;i++) {
+                       var singlestate = array[i].split('|');
+                       statearray[i] = new Array();
+                       statearray[i]["key"] = singlestate[0];
+                       statearray[i]["state"]  = singlestate[1];
+               }
+       }
+}
+function getState(nodeID) {
+       for(var i=0;i<statearray.length;i++) {
+               if (statearray[i]["key"] == nodeID) {
+                       state = statearray[i]["state"];
+                       if (state == null || state == '') {
+                               state = 'closed';
+                       }
+                       return state;
+               }
+       }
+       return "closed";
+}
+function writeStates(nodeID,newstate) {
+       //alert(nodeID);
+       var str = '';
+       var found = false;
+       for(var i=0;i<statearray.length;i++) {
+               if (statearray[i]["key"] == nodeID) {
+                       statearray[i]["state"] = newstate;
+                       found = true;
+               }
+               if (statearray[i]["state"] != null) {
+                       str += statearray[i]["key"] + '|' + statearray[i]["state"] + ';';
+               }
+       }
+       if (found == false) {
+               statearray[statearray.length] = new Array();
+               statearray[statearray.length - 1]["key"] = nodeID;
+               statearray[statearray.length - 1]["state"] = newstate;
+               if (newstate != null) {
+                       str += nodeID + '|' + newstate + ';';
+               }
+       }
+       setCookie('tree' + documentID,str);
+}
+function showTree(path) {
+       readStates();
+       
+       href = path;
+       window.focus();
+       window.onblur = blurSelection;
+       window.onfocus = focusSelection;
+       var str = '';
+       str = '<div id="node' + rootNode.getID() + '" class="treetitle" style="display:' + (showRootNode == true ? 'block' : 'none') + '">';
+       str += '<nobr>';
+       if (rootNode.hasIcon()) {
+               str += '<img src="' + rootNode.getIcon() + '" style="vertical-align:middle;">';
+       }
+       str += '<span style="vertical-align:middle;">&nbsp;' + rootNode.getName() + '</span>';
+       str += '</nobr></div>';
+       
+       if (rootNode.hasChilds()) {
+               for(i=0;i<rootNode.childs.length;i++) {
+                       nodeContents = showNode(rootNode.childs[i],(i == (rootNode.getChildCount() -1)));
+                       str = str + nodeContents;
+               }
+       }
+       container.innerHTML = str;
+       if (window.finishedLoading) {
+               finishedLoading();
+       }
+}
+/**
+* Shows the given node, and subnodes.
+*/
+function showNode(treeNode,lastNode) {
+       linestring = treeNode.getLineString();
+       var state = getState(treeNode.getID());
+       var str;
+       str = '<div style="filter:alpha(opacity=100);" ondragenter="dragEnter(' + treeNode.getID() + ');" ondragleave="dragLeave();" ondragstart="startDrag(' + treeNode.getID() + ');" ondrag="dragMove();" ondragend="endDrag(' + treeNode.getID() + ')" id="node' + treeNode.getID() + '">';
+       str += '<nobr>';
+       for(var y=0;y<linestring.length;y++) {
+               if (linestring.charAt(y) == 'I') {
+                       str += '<img src="' + href + 'static/' + (showLines ? 'line' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
+               }
+               else if (linestring.charAt(y) == 'B') {
+                       str += '<img src="' + href + 'static/white.gif" style="width:19px;height:20px;vertical-align:middle;">';
+               }
+       }
+       if (treeNode.hasChilds()) {
+               // If this is the first child of the rootNode, and showRootNode is false, we want to display a different icon.
+               if (!showRootNode && (treeNode.getParent() == rootNode) && (treeNode.getParent().getFirstChild() == treeNode)) {
+                       if (!lastNode) {
+                               str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (state == 'open' ? (showLines ? 'minus_no_root' : 'minus_nolines') : (showLines ? 'plus_no_root' : 'plus_nolines')) + '.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
+                       }
+                       else {
+                               str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (state == 'open' ? 'minus_last' : 'plus_last') + '_no_root.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
+                       }
+               }
+               else {
+                       if (!lastNode) {
+                               str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (state == 'open' ? (showLines ? 'minus' : 'minus_nolines') : (showLines ? 'plus' : 'plus_nolines')) + '.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
+                       }
+                       else {
+                               str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (state == 'open' ? (showLines ? 'minus_last' : 'minus_nolines') : (showLines ? 'plus_last' : 'plus_nolines')) + '.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
+                       }
+               }
+       }
+       else {
+               // If this is the first child of the rootNode, and showRootNode is false, we want to display a different icon.
+               if (!showRootNode && (treeNode.getParent() == rootNode) && (treeNode.getParent().getFirstChild() == treeNode)) {
+                       if (!lastNode) {
+                               str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (showLines ? 't_no_root' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
+                       }
+                       else {
+                               str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/white.gif" style="width:19px;height:20px;vertical-align:middle;">';
+                       }
+               }
+               else {
+                       if (!lastNode) {
+                               str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (showLines ? 't' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
+                       }
+                       else {
+                               str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (showLines ? 'lastnode' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
+                       }
+               }
+       }
+       iconStartImage = treeNode.getIcon();
+       if (state != 'closed') {
+               if (treeNode.hasChilds()) {
+                       iconStartImage = treeNode.getOpenIcon();
+               }
+       }
+       
+       str += '<img id="iconimage' + treeNode.getID() + '" src="' + iconStartImage + '" style="vertical-align:middle;" OnClick="selectNode(' + treeNode.getID() + ')">';
+       str += '&nbsp;<span unselectable="ON" style="vertical-align:middle;" class="treetitle" ID="title' + treeNode.getID() + '" OnDblClick="handleNode(' + treeNode.getID() + ')" OnClick="selectNode(' + treeNode.getID() + ')">';
+       str += treeNode.getName();
+       str += '</span>';
+       str += '</nobr>';
+       str += '</div>';
+
+       if (treeNode.hasChilds()) {
+               if (state == 'open') {
+                       str += '<div id="node' + treeNode.getID() + 'sub" style="display:block;">';
+                       fireOpenEvent(treeNode);
+                       // alert('openevent: ' + treeNode.getName());
+               }
+               else {
+                       str += '<div id="node' + treeNode.getID() + 'sub" style="display:' + (showAllNodesOnStartup == true ? 'block;' : 'none;') + ';">';
+               }
+               var subgroupstr = '';
+               var newChar = '';
+
+               if (!lastNode) {
+                       newChar = 'I';
+               }
+               else {
+                       newChar = 'B';
+               }
+               for(var z=0;z<treeNode.getChildCount();z++) {
+                       treeNode.childs[z].setLineString(linestring + newChar);
+               }
+               for(var z=0;z<treeNode.getChildCount();z++) {
+                       subgroupstr += showNode(treeNode.childs[z],(z == (treeNode.getChildCount() -1)));
+               }
+               str += subgroupstr;
+               str += '</div>';
+       }
+       else {
+               str += '<div id="node' + treeNode.getID() + 'sub" style="display:none;">';
+               str += '</div>';
+       }
+       return str;
+}
+/*
+function mouseMove() {
+       if (dragging) {
+               alert('bob');
+       }
+}
+function mouseUp() {
+       if (dragging) {
+               alert('dropped on something!');
+       }
+}
+*/
+function startDrag(nodeID) {
+       if (!dragable) {
+               return;
+       }
+       draggedNodeID = nodeID;
+       
+       var srcObj = window.event.srcElement;
+       while(srcObj.tagName != 'DIV') {
+               srcObj = srcObj.parentElement;
+       }
+       floatDragElement = document.createElement('DIV');
+
+       floatDragElement.innerHTML = srcObj.innerHTML;
+       floatDragElement.childNodes[0].removeChild(floatDragElement.childNodes[0].childNodes[0]);
+       
+       document.body.appendChild(floatDragElement);
+       floatDragElement.style.zIndex = 100;
+       floatDragElement.style.position = 'absolute';
+       floatDragElement.style.filter='progid:DXImageTransform.Microsoft.Alpha(1,opacity=60);';
+}
+function findSpanChild(element) {
+       if (element.tagName == 'SPAN') {
+               return element;
+       }
+       else {
+               if (element.childNodes) {
+                       for(var i=0;i<element.childNodes.length;i++) {
+                               var value = findSpanChild(element.childNodes[i]);
+                               if (value != false) {
+                                       return value;
+                               }
+                       }
+                       return false;
+               }
+       }
+}
+function dragEnter(nodeID) {
+       if (!dragable) {
+               return;
+       }
+       lastDraggedOnNodeID = nodeID;
+       
+       if (colouredElement) {
+               findSpanChild(colouredElement).className = 'treetitle';
+       }
+       colouredElement = window.event.srcElement;
+       while(colouredElement.tagName != 'DIV') {
+               colouredElement = colouredElement.parentElement;
+               if (colouredElement.tagName == 'BODY') {
+                       // Something gone seriously wrong.
+                       alert('Drag failure, reached <BODY>!');
+                       return;
+               }
+       }       
+       findSpanChild(colouredElement).className = 'treetitleselectedfocused';
+}
+function dragLeave() {
+       if (!dragable) {
+               return;
+       }
+}
+function endDrag(nodeID) {
+       if (!dragable) {
+               return;
+       }
+       if (lastDraggedOnNodeID != null) {
+               fireMoveEvent(getTreeNode(lastDraggedOnNodeID),draggedNodeID,lastDraggedOnNodeID);
+       }
+}
+function dragProceed() {
+       if (!dragable) {
+               return;
+       }
+       var dragged = getTreeNode(draggedNodeID);
+       var newparent = getTreeNode(lastDraggedOnNodeID);
+
+       var oldparent = dragged.getParent();
+       
+       oldparent.removeChild(dragged);
+       newparent.addChild(dragged);
+       
+       refreshNode(oldparent);
+       refreshNode(newparent);
+       
+       _dragClean()
+}
+function dragCancel() {
+       if (!dragable) {
+               return;
+       }
+       _dragClean()
+}
+/**
+* Don't call this yourself.
+*/
+function _dragClean() {
+       if (!dragable) {
+               return;
+       }
+       if (colouredElement) {
+               findSpanChild(colouredElement).className = 'treetitle';
+       }
+       
+       floatDragElement.parentElement.removeChild(floatDragElement);
+       floatDragElement = null;
+       colouredElement = null;
+       draggedNodeID = null;
+       lastDraggedOnNodeID = null;
+}
+function dragMove() {
+       if (!dragable) {
+               return;
+       }
+       floatDragElement.style.top = window.event.clientY;
+       floatDragElement.style.left = window.event.clientX;
+}
+function editEnded() {
+       if (treeNodeEdited != null) {
+               // treeNodeEdited.getID();
+               var editTitle = document.getElementById('title' + treeNodeEdited.getID());
+               var input = editTitle.childNodes[0];
+       
+               var newValue = input.value;
+               
+               if (newValue == treeNodeEdited.getName()) {
+                       editTitle.innerHTML = newValue;
+                       treeNodeEdited = null;
+                       return;
+               }
+       
+               fireEditEvent(treeNodeEdited,newValue);
+               
+               if (!editaborted) {
+                       treeNodeEdited.setName(newValue);
+                       editTitle.innerHTML = newValue;
+               }
+       
+               treeNodeEdited = null;
+       }
+}
+function selectNode(nodeID) {
+       var treeNode = getTreeNode(nodeID);
+
+       if (selectedNode != null) {
+               if (selectedNode == nodeID) {
+                       if (treeNode.isEditable()) {
+                               if (treeNodeEdited == treeNode) {
+                                       return;
+                               }
+                               treeNodeEdited = treeNode;
+                               var editTitle = document.getElementById('title' + treeNode.getID());
+                               editTitle.className = 'editednode';
+                               
+
+                               editTitle.innerHTML = '<input type="text" onKeypress="if (event.keyCode == 13) { this.onblur = null; editEnded(); }" name="editednode" class="editednodeinput">';
+                               var input = editTitle.childNodes[0];
+                               input.value = treeNode.getName();
+                               input.focus();
+                               input.select();
+                               input.onblur = editEnded;
+                       }
+                       return;
+               }
+               if (treeNodeEdited != null) {
+                       editEnded();
+               }
+               var oldNodeTitle = document.getElementById('title' + selectedNode);
+               oldNodeTitle.className = 'treetitle';
+       }
+       selectedNode = nodeID;
+       var nodetitle = document.getElementById('title' + selectedNode);
+       nodetitle.className = 'treetitleselectedfocused';
+       
+       if (treeNode.gotHandler()) {
+               eval(treeNode.getHandler() + '(getTreeNode(' + nodeID + '));');
+       }
+       else {
+               standardClick(treeNode);
+       }
+}
+function refreshNode(treeNode) {
+       var submenu = document.getElementById('node' + treeNode.getID() + 'sub');
+       var str = '';
+       for(var i=0;i<treeNode.getChildCount();i++) {
+               var parent = treeNode.getParent();
+               if (!parent) {
+                       treeNode.childs[i].setLineString(treeNode.getLineString() + 'B');
+               }
+               else {
+                       if (parent.childs[parent.childs.length - 1] == treeNode) {
+                               treeNode.childs[i].setLineString(treeNode.getLineString() + 'B');
+                       }
+                       else {
+                               treeNode.childs[i].setLineString(treeNode.getLineString() + 'I');
+                       }
+               }
+               str += showNode(treeNode.childs[i],i == (treeNode.getChildCount() - 1));
+       }
+       var actionimage = document.getElementById('handler' + treeNode.getID());
+       if (treeNode.getChildCount() == 0) {
+               // TreeNode haven't got any children, make sure the right image is displayed.
+               if (actionimage.src.indexOf('last') == -1) {
+                       actionimage.src = href + 'static/' + (showLines ? 't' : 'white') + '.gif';
+               }
+               else {
+                       actionimage.src = href + 'static/' + (showLines ? 'lastnode' : 'white') + '.gif';
+               }
+               actionimage.onclick = null;
+               
+               // Close the submenu
+               if (submenu) {
+                       submenu.style.display = 'none';
+               }
+       }
+       else {
+               // We have children, make sure to display the + and - icon.
+               if (actionimage.src.indexOf('plus') != -1) {
+                       // The TreeNode have already got children, and displays them.
+               }
+               else if (actionimage.src.indexOf('minus') != -1) {
+                       // The TreeNode have already got children, and displays them.
+               }
+               else {
+                       if (actionimage.src.indexOf('last') == -1) {
+                               actionimage.outerHTML = '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (showLines ? 'plus' : 'plus_nolines') + '.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
+                       }
+                       else {
+                               actionimage.outerHTML = '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/plus_last.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
+                       }
+               }
+       }
+       submenu.innerHTML = str;
+}
+function handleNode(nodeID) {
+       var treeNode = getTreeNode(nodeID);     
+       if (!treeNode.hasChilds()) { // No reason to handle a node without childs.
+               return;
+       }
+       
+       var submenu = document.getElementById('node' + nodeID + 'sub');
+       
+       var iconimageholder = document.getElementById('iconimage' + nodeID);
+       var actionimage = document.getElementById('handler' + nodeID);
+
+       // This will be used if showRootNode is set to false.
+       var firstChildOfRoot = false;
+       if (actionimage.src.indexOf('_no_root') != -1) {
+               firstChildOfRoot = true;
+       }
+       
+       if (submenu.style.display == 'none') {
+               writeStates(nodeID,'open');
+               fireOpenEvent(treeNode);
+               submenu.style.display = 'block';
+
+               iconimageholder.src = treeNode.getOpenIcon();
+       
+               if (actionimage.src.indexOf('last') == -1) {
+                       actionimage.src = href + 'static/' + ((firstChildOfRoot) ? 'minus_no_root' : (showLines ? 'minus' : 'minus_nolines')) + '.gif';
+               }
+               else {
+                       actionimage.src = href + 'static/' + ((firstChildOfRoot) ? 'minus_last_no_root' : (showLines ? 'minus_last' : 'minus_nolines')) + '.gif';
+               }
+       }
+       else {
+               writeStates(nodeID,'closed');
+               submenu.style.display = 'none';
+               
+               iconimageholder.src = treeNode.getIcon();
+               
+               if (actionimage.src.indexOf('last') == -1) {
+                       actionimage.src = href + 'static/' + ((firstChildOfRoot) ? 'plus_no_root' : (showLines ? 'plus' : 'plus_nolines')) + '.gif';
+               }
+               else {
+                       actionimage.src = href + 'static/' + ((firstChildOfRoot) ? 'plus_last_no_root' : (showLines ? 'plus_last' : 'plus_nolines')) + '.gif';
+               }
+       }
+}
+function fireOpenEvent(treeNode) {
+       if (treeNode.gotOpenEventListeners()) {
+               for(var i=0;i<treeNode.openeventlisteners.length;i++) {
+                       eval(treeNode.openeventlisteners[i] + '(' + treeNode.getID() + ');');
+               }
+       }
+}
+function fireEditEvent(treeNode,newVal) {
+       if (treeNode.gotEditEventListeners()) {
+               for(var i=0;i<treeNode.editeventlisteners.length;i++) {
+                       eval(treeNode.editeventlisteners[i] + '(' + treeNode.getID() + ',\'' + escape(newVal) + '\');');
+               }
+       }
+}
+function fireMoveEvent(treeNode,draggedNodeID,droppedOnNodeID) {
+       if (treeNode.gotMoveEventListeners()) {
+               for(var i=0;i<treeNode.moveeventlisteners.length;i++) {
+                       eval(treeNode.moveeventlisteners[i] + '(' + draggedNodeID + ',' + droppedOnNodeID + ');');
+               }
+       }
+}
+function blurSelection() {
+       if (selectedNode != null) {
+               var oldNodeTitle = document.getElementById('title' + selectedNode);
+               oldNodeTitle.className = 'treetitleselectedblured';
+       }
+}
+function focusSelection() {
+       if (selectedNode != null) {
+               var oldNodeTitle = document.getElementById('title' + selectedNode);
+               oldNodeTitle.className = 'treetitleselectedfocused';
+       }
+}
+function getCookieVal (offset) {  
+       var endstr = document.cookie.indexOf (";",offset);  
+       if (endstr == -1) {
+               endstr = document.cookie.length;
+       }
+       return unescape(document.cookie.substring(offset,endstr));
+}
+function getCookie (name) {  
+       var arg = name + "=";
+       var alen = arg.length;
+       var clen = document.cookie.length;
+       var i = 0;
+       while (i < clen) {
+               var j = i + alen;
+               if (document.cookie.substring(i, j) == arg) {
+                       return getCookieVal(j);
+               }
+               i = document.cookie.indexOf(" ", i) + 1;
+               if (i == 0) {
+                       break;
+               }
+       }
+       return null;
+}
+function setCookie (name, value) {  
+       var argv = setCookie.arguments;  
+       var argc = setCookie.arguments.length;  
+       var expires = (argc > 2) ? argv[2] : null;  
+       var path = (argc > 3) ? argv[3] : null;  
+       var domain = (argc > 4) ? argv[4] : null;  
+       var secure = (argc > 5) ? argv[5] : false;  
+       document.cookie = name + "=" + escape (value) + ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + ((path == null) ? "" : ("; path=" + path)) + ((domain == null) ? "" : ("; domain=" + domain)) + ((secure == true) ? "; secure" : "");
+}
+function expandNode() {
+       var state = getState(selectedNode);
+       if (state == 'open') {
+               var currentTreeNode = getTreeNode(selectedNode);
+               if (currentTreeNode.hasChilds()) {
+                       selectNode(currentTreeNode.childs[0].getID());
+               }
+       }
+       else {
+               handleNode(selectedNode);
+       }
+}
+function subtractNode() {
+       var state = getState(selectedNode);
+       if (state == 'closed') {
+               var currentTreeNode = getTreeNode(selectedNode);
+               var parent = currentTreeNode.getParent();
+               if (parent != null && parent != rootNode) {
+                       selectNode(parent.getID());
+               }
+       }
+       else {
+               handleNode(selectedNode);
+       }
+}
+function selectPrevNode() {
+       var currentTreeNode = getTreeNode(selectedNode);
+       if (currentTreeNode.prevSibling != null) {
+
+               var state = getState(currentTreeNode.prevSibling.getID());
+
+               if (state == 'open' && currentTreeNode.prevSibling.hasChilds()) {
+                       // We have to find the last open child of the previoussiblings childs.
+                       var current = currentTreeNode.prevSibling.childs[currentTreeNode.prevSibling.childs.length - 1];
+                       var currentstate = 'open';
+                       while (current.hasChilds() && (getState(current.getID()) == 'open')) {
+                               current = current.childs[current.childs.length - 1];
+                       }
+                       selectNode(current.getID());
+               }
+               else {
+                       selectNode(currentTreeNode.prevSibling.getID());
+               }
+       }
+       else {
+               if (currentTreeNode.getParent() != null && currentTreeNode.getParent() != rootNode) {
+                       selectNode(currentTreeNode.getParent().getID());
+               }
+       }
+}
+function selectNextNode() {
+       var currentTreeNode = getTreeNode(selectedNode);
+
+       var state = getState(selectedNode);
+       if (state == 'open' && currentTreeNode.hasChilds()) {
+               selectNode(currentTreeNode.childs[0].getID());
+       }       
+       else {
+               if (currentTreeNode.nextSibling != null) {
+                       selectNode(currentTreeNode.nextSibling.getID());
+               }
+               else {
+                       // Continue up the tree until we either hit null, or a parent which have a child.
+                       var parent = currentTreeNode;
+                       while ((parent = parent.getParent()) != rootNode) {
+                               if (parent.nextSibling != null) {
+                                       selectNode(parent.nextSibling.getID());
+                                       break;
+                               }
+                       }
+                       /*
+                       if (currentTreeNode.getParent().nextSibling != null) {
+                               selectNode(currentTreeNode.getParent().nextSibling.getID());
+                       }
+                       */
+               }
+       }
+}
+function keyDown(event) {
+       if (window.event) {
+               event = window.event;
+       }
+       if (event.keyCode == 38) { // Up
+               selectPrevNode();
+               return false;
+       }
+       else if (event.keyCode == 40) { // Down
+               selectNextNode();
+               return false;
+       }
+       else if (event.keyCode == 37) { // left
+               subtractNode();
+               return false;
+       }
+       else if (event.keyCode == 39) { // right
+               expandNode();
+               return false;
+       }
+}
+document.onkeydown = keyDown;
diff --git a/webcit/static/page16x16.gif b/webcit/static/page16x16.gif
new file mode 100644 (file)
index 0000000..a40d430
Binary files /dev/null and b/webcit/static/page16x16.gif differ
index 87ccefe9d71b73d74e7f35508166076430f39fe6..c84dce2e246eff2eaa5894516340e8e30eab8033 100644 (file)
Binary files a/webcit/static/plus.gif and b/webcit/static/plus.gif differ
diff --git a/webcit/static/plus_last.gif b/webcit/static/plus_last.gif
new file mode 100644 (file)
index 0000000..135aa0a
Binary files /dev/null and b/webcit/static/plus_last.gif differ
diff --git a/webcit/static/plus_last_no_root.gif b/webcit/static/plus_last_no_root.gif
new file mode 100644 (file)
index 0000000..84e0662
Binary files /dev/null and b/webcit/static/plus_last_no_root.gif differ
diff --git a/webcit/static/plus_no_root.gif b/webcit/static/plus_no_root.gif
new file mode 100644 (file)
index 0000000..22a4a90
Binary files /dev/null and b/webcit/static/plus_no_root.gif differ
diff --git a/webcit/static/plus_nolines.gif b/webcit/static/plus_nolines.gif
new file mode 100644 (file)
index 0000000..a7dc6be
Binary files /dev/null and b/webcit/static/plus_nolines.gif differ
diff --git a/webcit/static/t.gif b/webcit/static/t.gif
new file mode 100644 (file)
index 0000000..45c91f9
Binary files /dev/null and b/webcit/static/t.gif differ
diff --git a/webcit/static/t_no_root.gif b/webcit/static/t_no_root.gif
new file mode 100644 (file)
index 0000000..3da5e91
Binary files /dev/null and b/webcit/static/t_no_root.gif differ
diff --git a/webcit/static/user_16x16.gif b/webcit/static/user_16x16.gif
new file mode 100644 (file)
index 0000000..0533d2b
Binary files /dev/null and b/webcit/static/user_16x16.gif differ
diff --git a/webcit/static/white.gif b/webcit/static/white.gif
new file mode 100644 (file)
index 0000000..6a62ac8
Binary files /dev/null and b/webcit/static/white.gif differ