/* * Based on: * Ext JS Library 1.1.1 * Copyright(c) 2006-2007, Ext JS, LLC. * * Originally Released Under LGPL - original licence link has changed is not relivant. * * Fork - LGPL * <script type="text/javascript"> */ /** * @class Roo.tree.DefaultSelectionModel * @extends Roo.util.Observable * The default single selection for a TreePanel. * @param {Object} cfg Configuration */ Roo.tree.DefaultSelectionModel = function(cfg){ this.selNode = null; this.addEvents({ /** * @event selectionchange * Fires when the selected node changes * @param {DefaultSelectionModel} this * @param {TreeNode} node the new selection */ "selectionchange" : true, /** * @event beforeselect * Fires before the selected node changes, return false to cancel the change * @param {DefaultSelectionModel} this * @param {TreeNode} node the new selection * @param {TreeNode} node the old selection */ "beforeselect" : true }); Roo.tree.DefaultSelectionModel.superclass.constructor.call(this,cfg); }; Roo.extend(Roo.tree.DefaultSelectionModel, Roo.util.Observable, { init : function(tree){ this.tree = tree; tree.getTreeEl().on("keydown", this.onKeyDown, this); tree.on("click", this.onNodeClick, this); }, onNodeClick : function(node, e){ if (e.ctrlKey && this.selNode == node) { this.unselect(node); return; } this.select(node); }, /** * Select a node. * @param {TreeNode} node The node to select * @return {TreeNode} The selected node */ select : function(node){ var last = this.selNode; if(last != node && this.fireEvent('beforeselect', this, node, last) !== false){ if(last){ last.ui.onSelectedChange(false); } this.selNode = node; node.ui.onSelectedChange(true); this.fireEvent("selectionchange", this, node, last); } return node; }, /** * Deselect a node. * @param {TreeNode} node The node to unselect */ unselect : function(node){ if(this.selNode == node){ this.clearSelections(); } }, /** * Clear all selections */ clearSelections : function(){ var n = this.selNode; if(n){ n.ui.onSelectedChange(false); this.selNode = null; this.fireEvent("selectionchange", this, null); } return n; }, /** * Get the selected node * @return {TreeNode} The selected node */ getSelectedNode : function(){ return this.selNode; }, /** * Returns true if the node is selected * @param {TreeNode} node The node to check * @return {Boolean} */ isSelected : function(node){ return this.selNode == node; }, /** * Selects the node above the selected node in the tree, intelligently walking the nodes * @return TreeNode The new selection */ selectPrevious : function(){ var s = this.selNode || this.lastSelNode; if(!s){ return null; } var ps = s.previousSibling; if(ps){ if(!ps.isExpanded() || ps.childNodes.length < 1){ return this.select(ps); } else{ var lc = ps.lastChild; while(lc && lc.isExpanded() && lc.childNodes.length > 0){ lc = lc.lastChild; } return this.select(lc); } } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){ return this.select(s.parentNode); } return null; }, /** * Selects the node above the selected node in the tree, intelligently walking the nodes * @return TreeNode The new selection */ selectNext : function(){ var s = this.selNode || this.lastSelNode; if(!s){ return null; } if(s.firstChild && s.isExpanded()){ return this.select(s.firstChild); }else if(s.nextSibling){ return this.select(s.nextSibling); }else if(s.parentNode){ var newS = null; s.parentNode.bubble(function(){ if(this.nextSibling){ newS = this.getOwnerTree().selModel.select(this.nextSibling); return false; } }); return newS; } return null; }, onKeyDown : function(e){ var s = this.selNode || this.lastSelNode; // undesirable, but required var sm = this; if(!s){ return; } var k = e.getKey(); switch(k){ case e.DOWN: e.stopEvent(); this.selectNext(); break; case e.UP: e.stopEvent(); this.selectPrevious(); break; case e.RIGHT: e.preventDefault(); if(s.hasChildNodes()){ if(!s.isExpanded()){ s.expand(); }else if(s.firstChild){ this.select(s.firstChild, e); } } break; case e.LEFT: e.preventDefault(); if(s.hasChildNodes() && s.isExpanded()){ s.collapse(); }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){ this.select(s.parentNode, e); } break; }; } }); /** * @class Roo.tree.MultiSelectionModel * @extends Roo.util.Observable * Multi selection for a TreePanel. * @param {Object} cfg Configuration */ Roo.tree.MultiSelectionModel = function(){ this.selNodes = []; this.selMap = {}; this.addEvents({ /** * @event selectionchange * Fires when the selected nodes change * @param {MultiSelectionModel} this * @param {Array} nodes Array of the selected nodes */ "selectionchange" : true }); Roo.tree.MultiSelectionModel.superclass.constructor.call(this,cfg); }; Roo.extend(Roo.tree.MultiSelectionModel, Roo.util.Observable, { init : function(tree){ this.tree = tree; tree.getTreeEl().on("keydown", this.onKeyDown, this); tree.on("click", this.onNodeClick, this); }, onNodeClick : function(node, e){ this.select(node, e, e.ctrlKey); }, /** * Select a node. * @param {TreeNode} node The node to select * @param {EventObject} e (optional) An event associated with the selection * @param {Boolean} keepExisting True to retain existing selections * @return {TreeNode} The selected node */ select : function(node, e, keepExisting){ if(keepExisting !== true){ this.clearSelections(true); } if(this.isSelected(node)){ this.lastSelNode = node; return node; } this.selNodes.push(node); this.selMap[node.id] = node; this.lastSelNode = node; node.ui.onSelectedChange(true); this.fireEvent("selectionchange", this, this.selNodes); return node; }, /** * Deselect a node. * @param {TreeNode} node The node to unselect */ unselect : function(node){ if(this.selMap[node.id]){ node.ui.onSelectedChange(false); var sn = this.selNodes; var index = -1; if(sn.indexOf){ index = sn.indexOf(node); }else{ for(var i = 0, len = sn.length; i < len; i++){ if(sn[i] == node){ index = i; break; } } } if(index != -1){ this.selNodes.splice(index, 1); } delete this.selMap[node.id]; this.fireEvent("selectionchange", this, this.selNodes); } }, /** * Clear all selections */ clearSelections : function(suppressEvent){ var sn = this.selNodes; if(sn.length > 0){ for(var i = 0, len = sn.length; i < len; i++){ sn[i].ui.onSelectedChange(false); } this.selNodes = []; this.selMap = {}; if(suppressEvent !== true){ this.fireEvent("selectionchange", this, this.selNodes); } } }, /** * Returns true if the node is selected * @param {TreeNode} node The node to check * @return {Boolean} */ isSelected : function(node){ return this.selMap[node.id] ? true : false; }, /** * Returns an array of the selected nodes * @return {Array} */ getSelectedNodes : function(){ return this.selNodes; }, onKeyDown : Roo.tree.DefaultSelectionModel.prototype.onKeyDown, selectNext : Roo.tree.DefaultSelectionModel.prototype.selectNext, selectPrevious : Roo.tree.DefaultSelectionModel.prototype.selectPrevious });