summaryrefslogtreecommitdiff
path: root/webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/treevirtual/SimpleTreeDataModel.js
diff options
context:
space:
mode:
authorDerrell Lipman <derrell@samba.org>2007-02-06 04:35:30 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:44:39 -0500
commita45ea9069c51b6f90d55a2c40346c3ee9becc263 (patch)
tree8208442a0ab9d655f9dbb6953c8db60872c7b7ad /webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/treevirtual/SimpleTreeDataModel.js
parent0a5d888c24c925222dd94cdd80a29e09b235b795 (diff)
downloadsamba-a45ea9069c51b6f90d55a2c40346c3ee9becc263.tar.gz
samba-a45ea9069c51b6f90d55a2c40346c3ee9becc263.tar.bz2
samba-a45ea9069c51b6f90d55a2c40346c3ee9becc263.zip
r21169: - Step 3: Upgrade qooxdoo release code with latest qooxdoo svn's Table and
TreeVirtual. The TreeVirtual that was in the release was a very early pre-release, and had a number of problems and missing features. This brings it up-to-date and provides what seems to be a pretty well-working and highly useful widget. (This used to be commit 194880f1ffde7f01997c120136854acd145189e9)
Diffstat (limited to 'webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/treevirtual/SimpleTreeDataModel.js')
-rw-r--r--webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/treevirtual/SimpleTreeDataModel.js561
1 files changed, 365 insertions, 196 deletions
diff --git a/webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/treevirtual/SimpleTreeDataModel.js b/webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/treevirtual/SimpleTreeDataModel.js
index 215830c224..f9ff3a9758 100644
--- a/webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/treevirtual/SimpleTreeDataModel.js
+++ b/webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/treevirtual/SimpleTreeDataModel.js
@@ -30,33 +30,40 @@
*
* The object structure of a single node of the tree is:
*
+ * <pre>
* {
- * type : qx.ui.treevirtual.Type.LEAF,
- * parentNodeId : 23, // index in _nodeArr of the parent node
- * label : "My Documents",
- * bSelected : true, // true if node is selected; false otherwise
- * opened : null, // true (-), false (+), or null (no +/-)
- * icon : "images/folder.gif",
- * iconSelected : "images/folder_selected.gif",
- * children : [ ], // each value is an index into _nodeArr
- *
- * cellStyle : "background-color:cyan"
- * labelStyle : "background-color:red;color:white"
+ * // USER-PROVIDED ATTRIBUTES
+ * // ------------------------
+ * type : qx.ui.treevirtual.Type.LEAF,
+ * parentNodeId : 23, // index in _nodeArr of the parent node
+ * label : "My Documents",
+ * bSelected : true, // true if node is selected; false otherwise
+ * bOpened : true, // true (-), false (+)
+ * bHideOpenClose : false, // whether to hide the open/close button
+ * icon : "images/folder.gif",
+ * iconSelected : "images/folder_selected.gif",
+ * children : [ ], // each value is an index into _nodeArr
*
+ * cellStyle : "background-color:cyan"
+ * labelStyle : "background-color:red;color:white"
+ *
+ * // INTERNALLY-CALCULATED ATTRIBUTES
+ * // --------------------------------
* // The following properties need not (and should not) be set by the
* // caller, but are automatically calculated. Some are used internally,
* // while others may be of use to event listeners.
*
- * nodeId : 42, // The index in _nodeArr, useful to event listeners
+ * nodeId : 42, // The index in _nodeArr, useful to event listeners
*
- * level : 2, // The indentation level of this tree node
+ * level : 2, // The indentation level of this tree node
*
- * bFirstChild : true,
- * lastChild : [ false ], // Array where the index is the column of
- * // indentation, and the value is a boolean.
- * // These are used to locate the
- * // appropriate "tree line" icon.
+ * bFirstChild : true,
+ * lastChild : [ false ], // Array where the index is the column of
+ * // indentation, and the value is a boolean.
+ * // These are used to locate the
+ * // appropriate "tree line" icon.
* }
+ * </pre>
*/
qx.OO.defineClass("qx.ui.treevirtual.SimpleTreeDataModel",
qx.ui.table.AbstractTableModel,
@@ -80,7 +87,7 @@ function()
this._nodeArr.push( // the root node, needed to store its children
{
label : "<virtual root>",
- opened : true,
+ bOpened : true,
children : [ ]
});
});
@@ -121,42 +128,60 @@ qx.Proto.sortByColumn = function(columnIndex, ascending)
};
+/**
+ * Returns the column index the model is sorted by. This model is never
+ * sorted, so -1 is returned.
+ *
+ * @return {Integer}
+ * -1, to indicate that the model is not sorted.
+ */
qx.Proto.getSortColumnIndex = function()
{
return -1;
};
-qx.Proto.isSortAscending = function()
+/**
+ * Specifies which column the tree is to be displayed in. The tree is
+ * displayed using the SimpleTreeDataCellRenderer. Other columns may be
+ * provided which use different cell renderers.
+ *
+ * @param columnIndex {Integer}
+ * The index of the column in which the tree should be displayed.
+ */
+qx.Proto.setTreeColumn = function(columnIndex)
{
- return true;
+ this._treeColumn = columnIndex;
};
-qx.Proto.getRowCount = function()
+/**
+ * Get the column in which the tree is to be displayed.
+ *
+ * @return {Integer}
+ * The column in whcih the tree is to be displayed
+ */
+qx.Proto.getTreeColumn = function()
{
- return this._rowArr.length;
+ return this._treeColumn;
};
-qx.Proto.setTreeColumn = function(columnIndex)
-{
- this._treeColumn = columnIndex;
-}
-
-
-qx.Proto.getTreeColumn = function()
+// overridden
+qx.Proto.getRowCount = function()
{
- return this._treeColumn;
-}
+ return this._rowArr.length;
+};
+// overridden
qx.Proto.getRowData = function(rowIndex)
{
return this._rowArr[rowIndex];
-}
+};
+// overridden
qx.Proto.getValue = function(columnIndex, rowIndex)
{
if (rowIndex < 0 || rowIndex >= this._rowArr.length)
@@ -181,9 +206,58 @@ qx.Proto.getValue = function(columnIndex, rowIndex)
};
+/**
+ * Add a node to the tree.
+ *
+ * NOTE: This method is for <b>internal use</b> and should not be called by
+ * users of this class. Instead, call {@link #addBranch} or {@link
+ * #addLeaf}. There is no guarantee that the interface to this method
+ * will remain unchanged over time.
+ *
+ * @param parentNodeId {Integer}
+ * The node id of the parent of the node being added
+ *
+ * @param label {String}
+ * The string to display as the label for this node
+ *
+ * @param bOpened {Integer}
+ * <i>true</i> if the tree should be rendered in its opened state;
+ * <i>false</i> otherwise.
+ *
+ * @param bHideOpenCloseButton
+ * <i>true</i> if the open/close button should be hidden (not displayed);
+ * </i>false</i> to display the open/close button for this node.
+ *
+ * @param type {Integer}
+ * The type of node being added. The type determines whether children may
+ * be added, and determines the default icons to use. This parameter must
+ * be one of the following values:
+ * <dl>
+ * <dt>qx.ui.treevirtual.SimpleTreeDataModel.Type.BRANCH</dt>
+ * <dd>
+ * This node is a branch. A branch node may have children.
+ * </dd>
+ * <dt>qx.ui.treevirtual.SimpleTreeDataModel.Type.LEAF</dt>
+ * <dd>
+ * This node is a leaf, and may not have children
+ * </dd>
+ * </dl>
+ *
+ * @param icon {String}
+ * The relative (subject to alias expansion) or full path of the icon to
+ * display for this node when it is not a selected node.
+ *
+ * @param iconSelected {String}
+ * The relative (subject to alias expansion) or full path of the icon to
+ * display for this node when it is a selected node.
+ *
+ * @return {Integer}
+ * The node id of the newly-added node.
+ */
qx.Proto._addNode = function(parentNodeId,
label,
- opened,
+ bOpened,
+ bHideOpenCloseButton,
type,
icon,
iconSelected)
@@ -212,10 +286,12 @@ qx.Proto._addNode = function(parentNodeId,
parentNodeId = 0;
}
- // If this is a file, we don't present open/close icon
- if (type == qx.ui.treevirtual.SimpleTreeDataModel.Type.LEAF && opened)
+ // If this is a leaf, we don't present open/close icon
+ if (type == qx.ui.treevirtual.SimpleTreeDataModel.Type.LEAF)
{
- throw new Error("Attempt to display a LEAF opened [" + label + "]");
+ // mask off the opened bit but retain the hide open/close button bit
+ bOpened = false;
+ bHideOpenClose = false;
}
// Determine the node id of this new node
@@ -224,15 +300,16 @@ qx.Proto._addNode = function(parentNodeId,
// Set the data for this node.
var node =
{
- type : type,
- parentNodeId : parentNodeId,
- label : label,
- bSelected : false,
- opened : opened,
- icon : icon,
- iconSelected : iconSelected,
- children : [ ],
- columnData : [ ]
+ type : type,
+ parentNodeId : parentNodeId,
+ label : label,
+ bSelected : false,
+ bOpened : bOpened,
+ bHideOpenClose : bHideOpenCloseButton,
+ icon : icon,
+ iconSelected : iconSelected,
+ children : [ ],
+ columnData : [ ]
};
// Add this node to the array
@@ -247,21 +324,71 @@ qx.Proto._addNode = function(parentNodeId,
+/**
+ * Add a branch to the tree.
+ *
+ * @param parentNodeId {Integer}
+ * The node id of the parent of the node being added
+ *
+ * @param label {String}
+ * The string to display as the label for this node
+ *
+ * @param bOpened {Boolean}
+ * <i>True</i> if the branch should be rendered in its opened state;
+ * <i>false</i> otherwise.
+ *
+ * @param bHideOpenCloseButton {Boolean}
+ * <i>True</i> if the open/close button should not be displayed;
+ * <i>false</i> if the open/close button should be displayed
+ *
+ * @param icon {String}
+ * The relative (subject to alias expansion) or full path of the icon to
+ * display for this node when it is not a selected node.
+ *
+ * @param iconSelected {String}
+ * The relative (subject to alias expansion) or full path of the icon to
+ * display for this node when it is a selected node.
+ *
+ * @return {Integer}
+ * The node id of the newly-added branch.
+ */
qx.Proto.addBranch = function(parentNodeId,
label,
- opened,
+ bOpened,
+ bHideOpenCloseButton,
icon,
iconSelected)
{
return this._addNode(parentNodeId,
label,
- opened,
+ bOpened,
+ bHideOpenCloseButton,
qx.ui.treevirtual.SimpleTreeDataModel.Type.BRANCH,
icon,
iconSelected);
};
+/**
+ * Add a leaf to the tree.
+ *
+ * @param parentNodeId {Integer}
+ * The node id of the parent of the node being added
+ *
+ * @param label {String}
+ * The string to display as the label for this node
+ *
+ * @param icon {String}
+ * The relative (subject to alias expansion) or full path of the icon to
+ * display for this node when it is not a selected node.
+ *
+ * @param iconSelected {String}
+ * The relative (subject to alias expansion) or full path of the icon to
+ * display for this node when it is a selected node.
+ *
+ * @return {Integer}
+ * The node id of the newly-added leaf.
+ */
qx.Proto.addLeaf = function(parentNodeId,
label,
icon,
@@ -270,12 +397,21 @@ qx.Proto.addLeaf = function(parentNodeId,
return this._addNode(parentNodeId,
label,
false,
+ false,
qx.ui.treevirtual.SimpleTreeDataModel.Type.LEAF,
icon,
iconSelected);
};
+/**
+ * Prune the tree by removing the specified node, and, if the node has
+ * children, recursively all of its children.
+ *
+ * @param nodeId {Integer}
+ * The node id, previously returned by {@link #addLeaf} or {@link
+ * #addBranch}, of the node (and its children) to be pruned from the tree.
+ */
qx.Proto.prune = function(nodeId)
{
// First, recursively remove all children
@@ -308,18 +444,155 @@ qx.Proto.prune = function(nodeId)
*
* @param nodeArr {Array | null}
* Pass either an Array of node objects, or null.
- *
+ * </p><p>
* If non-null, nodeArr is an array of node objects containing the entire
* tree to be displayed. If loading the whole data en bulk in this way, it
* is assumed that the data is correct! No error checking or validation is
* done. You'd better know what you're doing! Caveat emptor.
- *
+ * </p><p>
* If nodeArr is null, then this call is a notification that the user has
* completed building or modifying a tree by issuing a series of calls to
- * addNode().
+ * {@link #addBranch} and/or {@link #addLeaf}.
+ * <p>
*/
qx.Proto.setData = function(nodeArr)
{
+ var _this = this;
+
+ function render()
+ {
+ var inorder = function(nodeId, level)
+ {
+ var child = null;
+ var childNodeId;
+
+ // For each child of the specified node...
+ var numChildren = _this._nodeArr[nodeId].children.length;
+ for (var i = 0; i < numChildren; i++)
+ {
+ // Determine the node id of this child
+ childNodeId = _this._nodeArr[nodeId].children[i];
+
+ // Get the child node
+ child = _this._nodeArr[childNodeId];
+
+ // Skip deleted nodes
+ if (child == null)
+ {
+ continue;
+ }
+
+ // Listeners will need to know a node's id when they receive an event
+ child.nodeId = childNodeId;
+
+ // (Re-)assign this node's level
+ child.level = level;
+
+ // Determine if we're the first child of our parent
+ child.bFirstChild = (i == 0);
+
+ // Determine if we're the last child of our parent
+ child.lastChild = [ i == numChildren - 1 ];
+
+ // Get our parent.
+ var parent = _this._nodeArr[child.parentNodeId];
+
+ // For each parent node, determine if it is a last child
+ while (parent.nodeId)
+ {
+ var bLast = parent.lastChild[parent.lastChild.length - 1];
+ child.lastChild.unshift(bLast);
+ parent = _this._nodeArr[parent.parentNodeId];
+ }
+
+ // Ensure there's an entry in the columnData array for each column
+ if (! child.columnData)
+ {
+ child.columnData = [ ];
+ }
+
+ if (child.columnData.length < _this.getColumnCount())
+ {
+ child.columnData[_this.getColumnCount() - 1] = null;
+ }
+
+ // Add this node to the row array. Initialize a row data array.
+ var rowData = [ ];
+
+ // If additional column data is provided...
+ if (child.columnData)
+ {
+ // ... then add each column data.
+ for (var j = 0; j < child.columnData.length; j++)
+ {
+ // Is this the tree column?
+ if (j == _this._treeColumn)
+ {
+ // Yup. Add the tree node data
+ rowData.push(child);
+ }
+ else
+ {
+ // Otherwise, add the column data verbatim.
+ rowData.push(child.columnData[j]);
+ }
+ }
+ }
+ else
+ {
+ // No column data. Just add the tree node.
+ rowData.push(child);
+ }
+
+ // If this node is selected, ...
+ if (child.bSelected)
+ {
+ // ... indicate so for the row.
+ rowData.selected = true;
+ }
+
+ // Track the _rowArr index for each node so we can handle selections
+ _this._nodeRowMap[child.nodeId] = _this._rowArr.length;
+
+ // Add the row data to the row array
+ _this._rowArr.push(rowData)
+
+ // If this child is opened, ...
+ if (child.bOpened)
+ {
+ // ... then add its children too.
+ inorder(childNodeId, level + 1);
+ }
+ }
+ }
+
+ // Reset the row array
+ _this._rowArr = [];
+
+ // Reset the _nodeArr -> _rowArr map
+ _this._nodeRowMap = [ ];
+
+ // Begin in-order traversal of the tree from the root to regenerate _rowArr
+ inorder(0, 1);
+
+ // Inform the listeners
+ if (_this.hasEventListeners(qx.ui.table.TableModel.EVENT_TYPE_DATA_CHANGED))
+ {
+ var data =
+ {
+ firstRow : 0,
+ lastRow : _this._rowArr.length - 1,
+ firstColumn : 0,
+ lastColumn : _this.getColumnCount() - 1
+ };
+
+ _this.dispatchEvent(new qx.event.type.DataEvent(
+ qx.ui.table.TableModel.EVENT_TYPE_DATA_CHANGED,
+ data),
+ true);
+ }
+ }
+
if (nodeArr instanceof Array)
{
// Determine the set of selected nodes
@@ -341,7 +614,7 @@ qx.Proto.setData = function(nodeArr)
}
// Re-render the row array
- this._render();
+ render();
};
@@ -350,7 +623,7 @@ qx.Proto.setData = function(nodeArr)
*
* @return {Array}
* Array of node objects. See {@link qx.ui.treevirtual.SimpleTreeDataModel}
- * for a description of each node.
+ * for a description nodes in this array.
*/
qx.Proto.getData = function()
{
@@ -360,10 +633,12 @@ qx.Proto.getData = function()
/**
- * Add data to an additional column of the tree.
+ * Add data to an additional column (a column other than the tree column) of
+ * the tree.
*
* @param nodeId
- * A node identifier, as previously returned by addBranch() or addLeaf().
+ * A node identifier, as previously returned by {@link #addBranch} or {@link
+ * addLeaf}.
*
* @param columnIndex
* The column number to which the provided data applies
@@ -377,6 +652,19 @@ qx.Proto.setColumnData = function(nodeId, columnIndex, data)
}
+/**
+ * Set state attributes of a node.
+ *
+ * @param nodeId {Integer}
+ * A node identifier, as previously returned by {@link #addBranch} or {@link
+ * addLeaf}.
+ *
+ * @param attributes {Map}
+ * Each property name in the map may correspond to the property names of a
+ * node which are specified as <i>USER-PROVIDED ATTRIBUTES</i> in {@link
+ * #SimpleTreeDataModel}. Each property value will be assigned to the
+ * corresponding property of the node specified by nodeId.
+ */
qx.Proto.setState = function(nodeId, attributes)
{
for (var attribute in attributes)
@@ -400,13 +688,25 @@ qx.Proto.setState = function(nodeId, attributes)
};
+/**
+ * Return the mapping of nodes to rendered rows. This function is intended
+ * for use by the cell renderer, not by users of this class.
+ *
+ * @return {Array}
+ * The array containing mappings of nodes to rendered rows.
+ */
qx.Proto.getNodeRowMap = function()
{
return this._nodeRowMap;
};
-qx.Proto.clearSelections = function()
+/*
+ * Clear all selections in the data model. This method does not clear
+ * selections displayed in the widget, and is intended for internal use, not
+ * by users of this class.
+ */
+qx.Proto._clearSelections = function()
{
// Clear selected state for any selected nodes.
for (var selection in this._selections)
@@ -419,153 +719,22 @@ qx.Proto.clearSelections = function()
};
-qx.Proto.getSelections = function()
-{
- return this._selections;
-};
-
-
/**
- * Render (or re-render) the tree. Call this function after having added
- * and/or deleted tree nodes (Files or Folders), or after having made changes
- * to tree (or tree node) options that will cause the tree to be rendered
- * differently. This function should typically be called after a set of
- * concurrent changes, not after each change.
+ * Return the nodes that are currently selected.
+ *
+ * @return {Array}
+ * An array containing the nodes that are currently selected.
*/
-qx.Proto._render = function()
+qx.Proto.getSelectedNodes = function()
{
- var _this = this;
+ var nodes = [ ];
- var inorder = function(nodeId, level)
+ for (var nodeId in this._selections)
{
- var child = null;
- var childNodeId;
-
- // For each child of the specified node...
- var numChildren = _this._nodeArr[nodeId].children.length;
- for (var i = 0; i < numChildren; i++)
- {
- // Determine the node id of this child
- childNodeId = _this._nodeArr[nodeId].children[i];
-
- // Get the child node
- child = _this._nodeArr[childNodeId];
-
- // Skip deleted nodes
- if (child == null)
- {
- continue;
- }
-
- // Listeners will need to know a node's id when they receive an event
- child.nodeId = childNodeId;
-
- // (Re-)assign this node's level
- child.level = level;
-
- // Determine if we're the first child of our parent
- child.bFirstChild = (i == 0);
-
- // Determine if we're the last child of our parent
- child.lastChild = [ i == numChildren - 1 ];
-
- // Get our parent.
- var parent = _this._nodeArr[child.parentNodeId];
-
- // For each parent node, determine if it is a last child
- while (parent.nodeId)
- {
- var bLast = parent.lastChild[parent.lastChild.length - 1];
- child.lastChild.unshift(bLast);
- parent = _this._nodeArr[parent.parentNodeId];
- }
-
- // Ensure there's an entry in the columnData array for each column
- if (! child.columnData)
- {
- child.columnData = [ ];
- }
-
- if (child.columnData.length < _this.getColumnCount())
- {
- child.columnData[_this.getColumnCount() - 1] = null;
- }
-
- // Add this node to the row array. Initialize a row data array.
- var rowData = [ ];
-
- // If additional column data is provided...
- if (child.columnData)
- {
- // ... then add each column data.
- for (var j = 0; j < child.columnData.length; j++)
- {
- // Is this the tree column?
- if (j == _this._treeColumn)
- {
- // Yup. Add the tree node data
- rowData.push(child);
- }
- else
- {
- // Otherwise, add the column data verbatim.
- rowData.push(child.columnData[j]);
- }
- }
- }
- else
- {
- // No column data. Just add the tree node.
- rowData.push(child);
- }
-
- // If this node is selected, ...
- if (child.bSelected)
- {
- // ... indicate so for the row.
- rowData.selected = true;
- }
-
- // Track the _rowArr index for each node so we can handle selections
- _this._nodeRowMap[child.nodeId] = _this._rowArr.length;
-
- // Add the row data to the row array
- _this._rowArr.push(rowData)
-
- // If this child is opened, ...
- if (child.opened)
- {
- // ... then add its children too.
- inorder(childNodeId, level + 1);
- }
- }
+ nodes.push(this._nodeArr[nodeId]);
}
- // Reset the row array
- this._rowArr = [];
-
- // Reset the _nodeArr -> _rowArr map
- this._nodeRowMap = [ ];
-
- // Begin in-order traversal of the tree from the root to regenerate _rowArr
- inorder(0, 1);
-
- // Inform the listeners
- if (this.hasEventListeners(qx.ui.table.TableModel.EVENT_TYPE_DATA_CHANGED))
- {
- var data =
- {
- firstRow : 0,
- lastRow : this._rowArr.length - 1,
- firstColumn : 0,
- lastColumn : this.getColumnCount() - 1
- };
-
- this.dispatchEvent(new qx.event.type.DataEvent(
- qx.ui.table.TableModel.EVENT_TYPE_DATA_CHANGED,
- data),
- true);
- }
+ return nodes;
};