Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / tree / View.js
index a31fff8..e07385b 100644 (file)
@@ -1,6 +1,19 @@
+/*
+
+This file is part of Ext JS 4
+
+Copyright (c) 2011 Sencha Inc
+
+Contact:  http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
+
+*/
 /**
- * @class Ext.tree.View
- * @extends Ext.view.Table
+ * Used as a view by {@link Ext.tree.Panel TreePanel}.
  */
 Ext.define('Ext.tree.View', {
     extend: 'Ext.view.Table',
@@ -13,15 +26,22 @@ Ext.define('Ext.tree.View', {
     checkboxSelector: '.' + Ext.baseCSSPrefix + 'tree-checkbox',
     expanderIconOverCls: Ext.baseCSSPrefix + 'tree-expander-over',
 
+    // Class to add to the node wrap element used to hold nodes when a parent is being
+    // collapsed or expanded. During the animation, UI interaction is forbidden by testing
+    // for an ancestor node with this class.
+    nodeAnimWrapCls: Ext.baseCSSPrefix + 'tree-animator-wrap',
+
     blockRefresh: true,
 
     /** 
-     * @cfg {Boolean} rootVisible <tt>false</tt> to hide the root node (defaults to <tt>true</tt>)
+     * @cfg {Boolean} rootVisible
+     * False to hide the root node.
      */
     rootVisible: true,
 
     /** 
-     * @cfg {Boolean} animate <tt>true</tt> to enable animated expand/collapse (defaults to the value of {@link Ext#enableFx Ext.enableFx})
+     * @cfg {Boolean} animate
+     * True to enable animated expand/collapse (defaults to the value of {@link Ext#enableFx Ext.enableFx})
      */
 
     expandDuration: 250,
@@ -54,7 +74,17 @@ Ext.define('Ext.tree.View', {
         me.animQueue = {};
         me.callParent(arguments);
     },
-    
+
+    processUIEvent: function(e) {
+        // If the clicked node is part of an animation, ignore the click.
+        // This is because during a collapse animation, the associated Records
+        // will already have been removed from the Store, and the event is not processable.
+        if (e.getTarget('.' + this.nodeAnimWrapCls, this.el)) {
+            return false;
+        }
+        return this.callParent(arguments);
+    },
+
     onClear: function(){
         this.store.removeAll();    
     },
@@ -70,7 +100,6 @@ Ext.define('Ext.tree.View', {
     
     onRender: function() {
         var me = this,
-            opts = {delegate: me.expanderSelector},
             el;
 
         me.callParent(arguments);
@@ -90,14 +119,20 @@ Ext.define('Ext.tree.View', {
     },
 
     onCheckboxChange: function(e, t) {
-        var item = e.getTarget(this.getItemSelector(), this.getTargetEl()),
-            record, value;
+        var me = this,
+            item = e.getTarget(me.getItemSelector(), me.getTargetEl());
             
         if (item) {
-            record = this.getRecord(item);
-            value = !record.get('checked');
-            record.set('checked', value);
-            this.fireEvent('checkchange', record, value);
+            me.onCheckChange(me.getRecord(item));
+        }
+    },
+    
+    onCheckChange: function(record){
+        var checked = record.get('checked');
+        if (Ext.isBoolean(checked)) {
+            checked = !checked;
+            record.set('checked', checked);
+            this.fireEvent('checkchange', record, checked);
         }
     },
 
@@ -133,7 +168,7 @@ Ext.define('Ext.tree.View', {
             tag: 'tr',
             html: [
                 '<td colspan="' + headerCt.getColumnCount() + '">',
-                    '<div class="' + Ext.baseCSSPrefix + 'tree-animator-wrap' + '">',
+                    '<div class="' + this.nodeAnimWrapCls + '">',
                         '<table class="' + Ext.baseCSSPrefix + 'grid-table" style="width: ' + headerCt.getFullWidth() + 'px;"><tbody>',
                             thHtml,
                         '</tbody></table>',
@@ -209,14 +244,9 @@ Ext.define('Ext.tree.View', {
             // +1 because of the tr with th'es that is already there
             Ext.fly(children[relativeIndex + 1]).insertSibling(nodes, 'before', true);
         }
-        
+
         // We also have to update the CompositeElementLite collection of the DataView
-        if (index < a.length) {
-            a.splice.apply(a, [index, 0].concat(nodes));
-        }
-        else {            
-            a.push.apply(a, nodes);
-        }
+        Ext.Array.insert(a, index, nodes);
         
         // If we were in an animation we need to now change the animation
         // because the targetEl just got higher.
@@ -225,6 +255,36 @@ Ext.define('Ext.tree.View', {
         }
     },
     
+    beginBulkUpdate: function(){
+        this.bulkUpdate = true;
+        this.ownerCt.changingScrollbars = true;  
+    },
+    
+    endBulkUpdate: function(){
+        var me = this,
+            ownerCt = me.ownerCt;
+        
+        me.bulkUpdate = false;
+        me.ownerCt.changingScrollbars = true;  
+        me.resetScrollers();  
+    },
+    
+    onRemove : function(ds, record, index) {
+        var me = this,
+            bulk = me.bulkUpdate;
+
+        me.doRemove(record, index);
+        if (!bulk) {
+            me.updateIndexes(index);
+        }
+        if (me.store.getCount() === 0){
+            me.refresh();
+        }
+        if (!bulk) {
+            me.fireEvent('itemremove', record, index);
+        }
+    },
+    
     doRemove: function(record, index) {
         // If we are adding records which have a parent that is currently expanding
         // lets add them to the animation wrap
@@ -312,10 +372,12 @@ Ext.define('Ext.tree.View', {
     },
     
     resetScrollers: function(){
-        var panel = this.panel;
-        
-        panel.determineScrollbars();
-        panel.invalidateScroller();
+        if (!this.bulkUpdate) {
+            var panel = this.panel;
+            
+            panel.determineScrollbars();
+            panel.invalidateScroller();
+        }
     },
 
     onBeforeCollapse: function(parent, records, index) {
@@ -413,7 +475,7 @@ Ext.define('Ext.tree.View', {
     },
     
     /**
-     * Expand a record that is loaded in the view.
+     * Expands a record that is loaded in the view.
      * @param {Ext.data.Model} record The record to expand
      * @param {Boolean} deep (optional) True to expand nodes all the way down the tree hierarchy.
      * @param {Function} callback (optional) The function to run after the expand is completed
@@ -424,7 +486,7 @@ Ext.define('Ext.tree.View', {
     },
     
     /**
-     * Collapse a record that is loaded in the view.
+     * Collapses a record that is loaded in the view.
      * @param {Ext.data.Model} record The record to collapse
      * @param {Boolean} deep (optional) True to collapse nodes all the way up the tree hierarchy.
      * @param {Function} callback (optional) The function to run after the collapse is completed
@@ -435,8 +497,8 @@ Ext.define('Ext.tree.View', {
     },
     
     /**
-     * Toggle a record between expanded and collapsed.
-     * @param {Ext.data.Record} recordInstance
+     * Toggles a record between expanded and collapsed.
+     * @param {Ext.data.Model} recordInstance
      */
     toggle: function(record) {
         this[record.isExpanded() ? 'collapse' : 'expand'](record);
@@ -489,4 +551,4 @@ Ext.define('Ext.tree.View', {
             });
         }
     }
-});
\ No newline at end of file
+});