712e3ba81cebb50aa84e23c6c1e0d9bb4abd1174.svn-base 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
  3. *
  4. * http://extjs.com/license
  5. */
  6. /**
  7. * @class Ext.tree.DefaultSelectionModel
  8. * @extends Ext.util.Observable The default single selection for a TreePanel.
  9. */
  10. Ext.tree.DefaultSelectionModel = function(config) {
  11. this.selNode = null;
  12. this.addEvents(
  13. /**
  14. * @event selectionchange Fires when the selected node changes
  15. * @param {DefaultSelectionModel}
  16. * this
  17. * @param {TreeNode}
  18. * node the new selection
  19. */
  20. "selectionchange",
  21. /**
  22. * @event beforeselect Fires before the selected node changes,
  23. * return false to cancel the change
  24. * @param {DefaultSelectionModel}
  25. * this
  26. * @param {TreeNode}
  27. * node the new selection
  28. * @param {TreeNode}
  29. * node the old selection
  30. */
  31. "beforeselect");
  32. Ext.apply(this, config);
  33. Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
  34. };
  35. Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
  36. init : function(tree) {
  37. this.tree = tree;
  38. tree.getTreeEl().on("keydown", this.onKeyDown, this);
  39. tree.on("click", this.onNodeClick, this);
  40. },
  41. onNodeClick : function(node, e) {
  42. this.select(node);
  43. },
  44. /**
  45. * Select a node.
  46. *
  47. * @param {TreeNode}
  48. * node The node to select
  49. * @return {TreeNode} The selected node
  50. */
  51. select : function(node) {
  52. var last = this.selNode;
  53. if (last != node
  54. && this.fireEvent('beforeselect', this, node, last) !== false) {
  55. if (last) {
  56. last.ui.onSelectedChange(false);
  57. }
  58. this.selNode = node;
  59. node.ui.onSelectedChange(true);
  60. this.fireEvent("selectionchange", this, node, last);
  61. }
  62. return node;
  63. },
  64. /**
  65. * Deselect a node.
  66. *
  67. * @param {TreeNode}
  68. * node The node to unselect
  69. */
  70. unselect : function(node) {
  71. if (this.selNode == node) {
  72. this.clearSelections();
  73. }
  74. },
  75. /**
  76. * Clear all selections
  77. */
  78. clearSelections : function() {
  79. var n = this.selNode;
  80. if (n) {
  81. n.ui.onSelectedChange(false);
  82. this.selNode = null;
  83. this.fireEvent("selectionchange", this, null);
  84. }
  85. return n;
  86. },
  87. /**
  88. * Get the selected node
  89. *
  90. * @return {TreeNode} The selected node
  91. */
  92. getSelectedNode : function() {
  93. return this.selNode;
  94. },
  95. /**
  96. * Returns true if the node is selected
  97. *
  98. * @param {TreeNode}
  99. * node The node to check
  100. * @return {Boolean}
  101. */
  102. isSelected : function(node) {
  103. return this.selNode == node;
  104. },
  105. /**
  106. * Selects the node above the selected node in the tree,
  107. * intelligently walking the nodes
  108. *
  109. * @return TreeNode The new selection
  110. */
  111. selectPrevious : function() {
  112. var s = this.selNode || this.lastSelNode;
  113. if (!s) {
  114. return null;
  115. }
  116. var ps = s.previousSibling;
  117. if (ps) {
  118. if (!ps.isExpanded() || ps.childNodes.length < 1) {
  119. return this.select(ps);
  120. } else {
  121. var lc = ps.lastChild;
  122. while (lc && lc.isExpanded()
  123. && lc.childNodes.length > 0) {
  124. lc = lc.lastChild;
  125. }
  126. return this.select(lc);
  127. }
  128. } else if (s.parentNode
  129. && (this.tree.rootVisible || !s.parentNode.isRoot)) {
  130. return this.select(s.parentNode);
  131. }
  132. return null;
  133. },
  134. /**
  135. * Selects the node above the selected node in the tree,
  136. * intelligently walking the nodes
  137. *
  138. * @return TreeNode The new selection
  139. */
  140. selectNext : function() {
  141. var s = this.selNode || this.lastSelNode;
  142. if (!s) {
  143. return null;
  144. }
  145. if (s.firstChild && s.isExpanded()) {
  146. return this.select(s.firstChild);
  147. } else if (s.nextSibling) {
  148. return this.select(s.nextSibling);
  149. } else if (s.parentNode) {
  150. var newS = null;
  151. s.parentNode.bubble(function() {
  152. if (this.nextSibling) {
  153. newS = this.getOwnerTree().selModel
  154. .select(this.nextSibling);
  155. return false;
  156. }
  157. });
  158. return newS;
  159. }
  160. return null;
  161. },
  162. onKeyDown : function(e) {
  163. var s = this.selNode || this.lastSelNode;
  164. // undesirable, but required
  165. var sm = this;
  166. if (!s) {
  167. return;
  168. }
  169. var k = e.getKey();
  170. switch (k) {
  171. case e.DOWN :
  172. e.stopEvent();
  173. this.selectNext();
  174. break;
  175. case e.UP :
  176. e.stopEvent();
  177. this.selectPrevious();
  178. break;
  179. case e.RIGHT :
  180. e.preventDefault();
  181. if (s.hasChildNodes()) {
  182. if (!s.isExpanded()) {
  183. s.expand();
  184. } else if (s.firstChild) {
  185. this.select(s.firstChild, e);
  186. }
  187. }
  188. break;
  189. case e.LEFT :
  190. e.preventDefault();
  191. if (s.hasChildNodes() && s.isExpanded()) {
  192. s.collapse();
  193. } else if (s.parentNode
  194. && (this.tree.rootVisible || s.parentNode != this.tree
  195. .getRootNode())) {
  196. this.select(s.parentNode, e);
  197. }
  198. break;
  199. };
  200. }
  201. });
  202. /**
  203. * @class Ext.tree.MultiSelectionModel
  204. * @extends Ext.util.Observable Multi selection for a TreePanel.
  205. */
  206. Ext.tree.MultiSelectionModel = function(config) {
  207. this.selNodes = [];
  208. this.selMap = {};
  209. this.addEvents(
  210. /**
  211. * @event selectionchange Fires when the selected nodes change
  212. * @param {MultiSelectionModel}
  213. * this
  214. * @param {Array}
  215. * nodes Array of the selected nodes
  216. */
  217. "selectionchange");
  218. Ext.apply(this, config);
  219. Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
  220. };
  221. Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
  222. init : function(tree) {
  223. this.tree = tree;
  224. tree.getTreeEl().on("keydown", this.onKeyDown, this);
  225. tree.on("click", this.onNodeClick, this);
  226. },
  227. onNodeClick : function(node, e) {
  228. this.select(node, e, e.ctrlKey);
  229. },
  230. /**
  231. * Select a node.
  232. *
  233. * @param {TreeNode}
  234. * node The node to select
  235. * @param {EventObject}
  236. * e (optional) An event associated with the selection
  237. * @param {Boolean}
  238. * keepExisting True to retain existing selections
  239. * @return {TreeNode} The selected node
  240. */
  241. select : function(node, e, keepExisting) {
  242. if (keepExisting !== true) {
  243. this.clearSelections(true);
  244. }
  245. if (this.isSelected(node)) {
  246. this.lastSelNode = node;
  247. return node;
  248. }
  249. this.selNodes.push(node);
  250. this.selMap[node.id] = node;
  251. this.lastSelNode = node;
  252. node.ui.onSelectedChange(true);
  253. this.fireEvent("selectionchange", this, this.selNodes);
  254. return node;
  255. },
  256. /**
  257. * Deselect a node.
  258. *
  259. * @param {TreeNode}
  260. * node The node to unselect
  261. */
  262. unselect : function(node) {
  263. if (this.selMap[node.id]) {
  264. node.ui.onSelectedChange(false);
  265. var sn = this.selNodes;
  266. var index = sn.indexOf(node);
  267. if (index != -1) {
  268. this.selNodes.splice(index, 1);
  269. }
  270. delete this.selMap[node.id];
  271. this.fireEvent("selectionchange", this, this.selNodes);
  272. }
  273. },
  274. /**
  275. * Clear all selections
  276. */
  277. clearSelections : function(suppressEvent) {
  278. var sn = this.selNodes;
  279. if (sn.length > 0) {
  280. for (var i = 0, len = sn.length; i < len; i++) {
  281. sn[i].ui.onSelectedChange(false);
  282. }
  283. this.selNodes = [];
  284. this.selMap = {};
  285. if (suppressEvent !== true) {
  286. this.fireEvent("selectionchange", this, this.selNodes);
  287. }
  288. }
  289. },
  290. /**
  291. * Returns true if the node is selected
  292. *
  293. * @param {TreeNode}
  294. * node The node to check
  295. * @return {Boolean}
  296. */
  297. isSelected : function(node) {
  298. return this.selMap[node.id] ? true : false;
  299. },
  300. /**
  301. * Returns an array of the selected nodes
  302. *
  303. * @return {Array}
  304. */
  305. getSelectedNodes : function() {
  306. return this.selNodes;
  307. },
  308. onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
  309. selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
  310. selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
  311. });