/** * Adds custom behavior for left/right keyboard navigation for use with a tree. * Depends on the view having an expand and collapse method which accepts a * record. This selection model is created by default for {@link Ext.tree.Panel}. */ Ext.define('Ext.selection.TreeModel', { extend: 'Ext.selection.RowModel', alias: 'selection.treemodel', /** * @cfg {Boolean} pruneRemoved @hide */ constructor: function(config) { this.callParent(arguments); // If pruneRemoved is required, we must listen to the *TreeStore* to know when nodes // are added and removed if (this.pruneRemoved) { this.pruneRemoved = false; this.pruneRemovedNodes = true; } }, // binds the store to the selModel. bindStore: function(store, initial) { var me = this; me.callParent(arguments); // TreePanel should have injected a reference to the TreeStore so that we can // listen for node removal. if (me.pruneRemovedNodes) { me.view.mon(me.treeStore, { remove: me.onNodeRemove, scope: me }); } }, onNodeRemove: function(parent, node, isMove) { // deselection of deleted records done in base Model class if (!isMove) { this.deselectDeletedRecords([node]); } }, onKeyRight: function(e, t) { var focused = this.getLastFocused(), view = this.view; if (focused) { // tree node is already expanded, go down instead // this handles both the case where we navigate to firstChild and if // there are no children to the nextSibling if (focused.isExpanded()) { this.onKeyDown(e, t); // if its not a leaf node, expand it } else if (focused.isExpandable()) { // If we are the normal side of a locking pair, only the tree view can do expanding if (!view.isTreeView) { view = view.lockingPartner; } view.expand(focused); } } }, onKeyLeft: function(e, t) { var me = this, focused = this.getLastFocused(), view = this.view, parentNode; if (focused) { parentNode = focused.parentNode; // if focused node is already expanded, collapse it if (focused.isExpanded()) { // If we are the normal side of a locking pair, only the tree view can do collapsing if (!view.isTreeView) { view = view.lockingPartner; } view.collapse(focused); // has a parentNode and its not root // TODO: this needs to cover the case where the root isVisible } else if (parentNode && !parentNode.isRoot()) { // Select a range of records when doing multiple selection. if (e.shiftKey) { me.selectRange(parentNode, focused, e.ctrlKey, 'up'); me.setLastFocused(parentNode); // just move focus, not selection } else if (e.ctrlKey) { me.setLastFocused(parentNode); // select it } else { me.select(parentNode); } } } }, onKeySpace: function(e, t) { if (e.record.data.checked != null) { this.toggleCheck(e); } else { this.callParent(arguments); } }, onKeyEnter: function(e, t) { if (e.record.data.checked != null) { this.toggleCheck(e); } else { this.callParent(arguments); } }, toggleCheck: function(e) { var view = this.view, selected = this.getLastSelected(); e.stopEvent(); if (selected) { // If we are the normal side of a locking pair, only the tree view can do on heckChange if (!view.isTreeView) { view = view.lockingPartner; } view.onCheckChange(selected); } } });