~cdparra/gelee/trunk

« back to all changes in this revision

Viewing changes to webui/web/extjs/source/widgets/tree/TreePanel.js

  • Committer: parra
  • Date: 2010-03-15 15:56:56 UTC
  • Revision ID: svn-v4:ac5bba68-f036-4e09-846e-8f32731cc928:trunk/gelee:1448
merged gelee at svn

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Ext JS Library 3.0 RC2
 
3
 * Copyright(c) 2006-2009, Ext JS, LLC.
 
4
 * licensing@extjs.com
 
5
 * 
 
6
 * http://extjs.com/license
 
7
 */
 
8
 
 
9
/**
 
10
 * @class Ext.tree.TreePanel
 
11
 * @extends Ext.Panel
 
12
 * <p>The TreePanel provides tree-structured UI representation of tree-structured data.</p>
 
13
 * <p>{@link Ext.tree.TreeNode TreeNode}s added to the TreePanel may each contain metadata
 
14
 * used by your application in their {@link Ext.tree.TreeNode#attributes attributes} property.</p>
 
15
 * <p><b>A TreePanel must have a {@link #root} node before it is rendered.</b> This may either be
 
16
 * specified using the {@link #root} config option, or using the {@link #setRootNode} method.
 
17
 * <p>An example of tree rendered to an existing div:</p><pre><code>
 
18
var tree = new Ext.tree.TreePanel({
 
19
    el: 'tree-div',
 
20
    useArrows: true,
 
21
    autoScroll: true,
 
22
    animate: true,
 
23
    enableDD: true,
 
24
    containerScroll: true,
 
25
    border: false,
 
26
    // auto create TreeLoader
 
27
    dataUrl: 'get-nodes.php',
 
28
 
 
29
    root: {
 
30
        nodeType: 'async',
 
31
        text: 'Ext JS',
 
32
        draggable: false,
 
33
        id: 'source'
 
34
    }
 
35
});
 
36
 
 
37
// render the tree
 
38
tree.render();
 
39
tree.getRootNode().expand();
 
40
 * </code></pre>
 
41
 * <p>The example above would work with a data packet similar to this:</p><pre><code>
 
42
[
 
43
   {
 
44
      "text":"adapter",
 
45
      "id":"source\/adapter",
 
46
      "cls":"folder"
 
47
   },
 
48
   {
 
49
      "text":"dd",
 
50
      "id":"source\/dd",
 
51
      "cls":"folder"
 
52
   },
 
53
   {
 
54
      "text":"debug.js",
 
55
      "id":"source\/debug.js",
 
56
      "leaf":true,
 
57
      "cls":"file"
 
58
   }
 
59
]
 
60
 * </code></pre>
 
61
 * <p>An example of tree within a Viewport:</p><pre><code>
 
62
new Ext.Viewport({
 
63
    layout: 'border',
 
64
    items: [{
 
65
        region: 'west',
 
66
        collapsible: true,
 
67
        title: 'Navigation',
 
68
        xtype: 'treepanel',
 
69
        width: 200,
 
70
        autoScroll: true,
 
71
        split: true,
 
72
        loader: new Ext.tree.TreeLoader(),
 
73
        root: new Ext.tree.AsyncTreeNode({
 
74
            expanded: true,
 
75
            children: [{
 
76
                text: 'Menu Option 1',
 
77
                leaf: true
 
78
            }, {
 
79
                text: 'Menu Option 2',
 
80
                leaf: true
 
81
            }, {
 
82
                text: 'Menu Option 3',
 
83
                leaf: true
 
84
            }]
 
85
        }),
 
86
        rootVisible: false,
 
87
        listeners: {
 
88
            click: function(n) {
 
89
                Ext.Msg.alert('Navigation Tree Click', 'You clicked: "' + n.attributes.text + '"');
 
90
            }
 
91
        }
 
92
    }, {
 
93
        region: 'center',
 
94
        xtype: 'tabpanel',
 
95
        // remaining code not shown ...
 
96
    }]
 
97
});
 
98
 * 
 
99
 * @cfg {Ext.tree.TreeNode} root The root node for the tree.
 
100
 * @cfg {Boolean} rootVisible <tt>false</tt> to hide the root node (defaults to <tt>true</tt>)
 
101
 * @cfg {Boolean} lines <tt>false</tt> to disable tree lines (defaults to <tt>true</tt>)
 
102
 * @cfg {Boolean} enableDD <tt>true</tt> to enable drag and drop
 
103
 * @cfg {Boolean} enableDrag <tt>true</tt> to enable just drag
 
104
 * @cfg {Boolean} enableDrop <tt>true</tt> to enable just drop
 
105
 * @cfg {Object} dragConfig Custom config to pass to the {@link Ext.tree.TreeDragZone} instance
 
106
 * @cfg {Object} dropConfig Custom config to pass to the {@link Ext.tree.TreeDropZone} instance
 
107
 * @cfg {String} ddGroup The DD group this TreePanel belongs to
 
108
 * @cfg {Boolean} ddAppendOnly <tt>true</tt> if the tree should only allow append drops (use for trees which are sorted)
 
109
 * @cfg {Boolean} ddScroll <tt>true</tt> to enable body scrolling
 
110
 * @cfg {Boolean} containerScroll <tt>true</tt> to register this container with ScrollManager
 
111
 * @cfg {Boolean} hlDrop <tt>false</tt> to disable node highlight on drop (defaults to the value of {@link Ext#enableFx})
 
112
 * @cfg {String} hlColor The color of the node highlight (defaults to <tt>'C3DAF9'</tt>)
 
113
 * @cfg {Boolean} animate <tt>true</tt> to enable animated expand/collapse (defaults to the value of {@link Ext#enableFx})
 
114
 * @cfg {Boolean} singleExpand <tt>true</tt> if only 1 node per branch may be expanded
 
115
 * @cfg {Object} selModel A tree selection model to use with this TreePanel (defaults to an {@link Ext.tree.DefaultSelectionModel})
 
116
 * @cfg {Boolean} trackMouseOver <tt>false</tt> to disable mouse over highlighting 
 
117
 * @cfg {Ext.tree.TreeLoader} loader A {@link Ext.tree.TreeLoader} for use with this TreePanel
 
118
 * @cfg {String} pathSeparator The token used to separate sub-paths in path strings (defaults to <tt>'/'</tt>)
 
119
 * @cfg {Boolean} useArrows <tt>true</tt> to use Vista-style arrows in the tree (defaults to <tt>false</tt>)
 
120
 * @cfg {String} requestMethod The HTTP request method for loading data (defaults to the value of {@link Ext.Ajax#method}).
 
121
 *
 
122
 * @constructor
 
123
 * @param {Object} config
 
124
 */
 
125
Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
 
126
    rootVisible : true,
 
127
    animate: Ext.enableFx,
 
128
    lines : true,
 
129
    enableDD : false,
 
130
    hlDrop : Ext.enableFx,
 
131
    pathSeparator: "/",
 
132
 
 
133
    initComponent : function(){
 
134
        Ext.tree.TreePanel.superclass.initComponent.call(this);
 
135
 
 
136
        if(!this.eventModel){
 
137
            this.eventModel = new Ext.tree.TreeEventModel(this);
 
138
        }
 
139
 
 
140
        // initialize the loader
 
141
        var l = this.loader;
 
142
        if(!l){
 
143
            l = new Ext.tree.TreeLoader({
 
144
                dataUrl: this.dataUrl,
 
145
                requestMethod: this.requestMethod
 
146
            });
 
147
        }else if(typeof l == 'object' && !l.load){
 
148
            l = new Ext.tree.TreeLoader(l);
 
149
        }
 
150
        this.loader = l;
 
151
        
 
152
        this.nodeHash = {};
 
153
 
 
154
        /**
 
155
        * The root node of this tree.
 
156
        * @type Ext.tree.TreeNode
 
157
        * @property root
 
158
        */
 
159
        if(this.root){
 
160
            var r = this.root;
 
161
            delete this.root;
 
162
            this.setRootNode(r);
 
163
        }
 
164
 
 
165
 
 
166
        this.addEvents(
 
167
 
 
168
            /**
 
169
            * @event append
 
170
            * Fires when a new child node is appended to a node in this tree.
 
171
            * @param {Tree} tree The owner tree
 
172
            * @param {Node} parent The parent node
 
173
            * @param {Node} node The newly appended node
 
174
            * @param {Number} index The index of the newly appended node
 
175
            */
 
176
           "append",
 
177
           /**
 
178
            * @event remove
 
179
            * Fires when a child node is removed from a node in this tree.
 
180
            * @param {Tree} tree The owner tree
 
181
            * @param {Node} parent The parent node
 
182
            * @param {Node} node The child node removed
 
183
            */
 
184
           "remove",
 
185
           /**
 
186
            * @event movenode
 
187
            * Fires when a node is moved to a new location in the tree
 
188
            * @param {Tree} tree The owner tree
 
189
            * @param {Node} node The node moved
 
190
            * @param {Node} oldParent The old parent of this node
 
191
            * @param {Node} newParent The new parent of this node
 
192
            * @param {Number} index The index it was moved to
 
193
            */
 
194
           "movenode",
 
195
           /**
 
196
            * @event insert
 
197
            * Fires when a new child node is inserted in a node in this tree.
 
198
            * @param {Tree} tree The owner tree
 
199
            * @param {Node} parent The parent node
 
200
            * @param {Node} node The child node inserted
 
201
            * @param {Node} refNode The child node the node was inserted before
 
202
            */
 
203
           "insert",
 
204
           /**
 
205
            * @event beforeappend
 
206
            * Fires before a new child is appended to a node in this tree, return false to cancel the append.
 
207
            * @param {Tree} tree The owner tree
 
208
            * @param {Node} parent The parent node
 
209
            * @param {Node} node The child node to be appended
 
210
            */
 
211
           "beforeappend",
 
212
           /**
 
213
            * @event beforeremove
 
214
            * Fires before a child is removed from a node in this tree, return false to cancel the remove.
 
215
            * @param {Tree} tree The owner tree
 
216
            * @param {Node} parent The parent node
 
217
            * @param {Node} node The child node to be removed
 
218
            */
 
219
           "beforeremove",
 
220
           /**
 
221
            * @event beforemovenode
 
222
            * Fires before a node is moved to a new location in the tree. Return false to cancel the move.
 
223
            * @param {Tree} tree The owner tree
 
224
            * @param {Node} node The node being moved
 
225
            * @param {Node} oldParent The parent of the node
 
226
            * @param {Node} newParent The new parent the node is moving to
 
227
            * @param {Number} index The index it is being moved to
 
228
            */
 
229
           "beforemovenode",
 
230
           /**
 
231
            * @event beforeinsert
 
232
            * Fires before a new child is inserted in a node in this tree, return false to cancel the insert.
 
233
            * @param {Tree} tree The owner tree
 
234
            * @param {Node} parent The parent node
 
235
            * @param {Node} node The child node to be inserted
 
236
            * @param {Node} refNode The child node the node is being inserted before
 
237
            */
 
238
            "beforeinsert",
 
239
 
 
240
            /**
 
241
            * @event beforeload
 
242
            * Fires before a node is loaded, return false to cancel
 
243
            * @param {Node} node The node being loaded
 
244
            */
 
245
            "beforeload",
 
246
            /**
 
247
            * @event load
 
248
            * Fires when a node is loaded
 
249
            * @param {Node} node The node that was loaded
 
250
            */
 
251
            "load",
 
252
            /**
 
253
            * @event textchange
 
254
            * Fires when the text for a node is changed
 
255
            * @param {Node} node The node
 
256
            * @param {String} text The new text
 
257
            * @param {String} oldText The old text
 
258
            */
 
259
            "textchange",
 
260
            /**
 
261
            * @event beforeexpandnode
 
262
            * Fires before a node is expanded, return false to cancel.
 
263
            * @param {Node} node The node
 
264
            * @param {Boolean} deep
 
265
            * @param {Boolean} anim
 
266
            */
 
267
            "beforeexpandnode",
 
268
            /**
 
269
            * @event beforecollapsenode
 
270
            * Fires before a node is collapsed, return false to cancel.
 
271
            * @param {Node} node The node
 
272
            * @param {Boolean} deep
 
273
            * @param {Boolean} anim
 
274
            */
 
275
            "beforecollapsenode",
 
276
            /**
 
277
            * @event expandnode
 
278
            * Fires when a node is expanded
 
279
            * @param {Node} node The node
 
280
            */
 
281
            "expandnode",
 
282
            /**
 
283
            * @event disabledchange
 
284
            * Fires when the disabled status of a node changes
 
285
            * @param {Node} node The node
 
286
            * @param {Boolean} disabled
 
287
            */
 
288
            "disabledchange",
 
289
            /**
 
290
            * @event collapsenode
 
291
            * Fires when a node is collapsed
 
292
            * @param {Node} node The node
 
293
            */
 
294
            "collapsenode",
 
295
            /**
 
296
            * @event beforeclick
 
297
            * Fires before click processing on a node. Return false to cancel the default action.
 
298
            * @param {Node} node The node
 
299
            * @param {Ext.EventObject} e The event object
 
300
            */
 
301
            "beforeclick",
 
302
            /**
 
303
            * @event click
 
304
            * Fires when a node is clicked
 
305
            * @param {Node} node The node
 
306
            * @param {Ext.EventObject} e The event object
 
307
            */
 
308
            "click",
 
309
            /**
 
310
            * @event checkchange
 
311
            * Fires when a node with a checkbox's checked property changes
 
312
            * @param {Node} this This node
 
313
            * @param {Boolean} checked
 
314
            */
 
315
            "checkchange",
 
316
            /**
 
317
            * @event dblclick
 
318
            * Fires when a node is double clicked
 
319
            * @param {Node} node The node
 
320
            * @param {Ext.EventObject} e The event object
 
321
            */
 
322
            "dblclick",
 
323
            /**
 
324
            * @event contextmenu
 
325
            * Fires when a node is right clicked. To display a context menu in response to this
 
326
            * event, first create a Menu object (see {@link Ext.menu.Menu} for details), then add
 
327
            * a handler for this event:<code><pre>
 
328
new Ext.tree.TreePanel({
 
329
    title: 'My TreePanel',
 
330
    root: new Ext.tree.AsyncTreeNode({
 
331
        text: 'The Root',
 
332
        children: [
 
333
            { text: 'Child node 1', leaf: true },
 
334
            { text: 'Child node 2', leaf: true }
 
335
        ]
 
336
    }),
 
337
    contextMenu: new Ext.menu.Menu({
 
338
        items: [{
 
339
            id: 'delete-node',
 
340
            text: 'Delete Node'
 
341
        }],
 
342
        listeners: {
 
343
            itemclick: function(item) {
 
344
                switch (item.id) {
 
345
                    case 'delete-node':
 
346
                        var n = item.parentMenu.contextNode;
 
347
                        if (n.parentNode) {
 
348
                            n.remove();
 
349
                        }
 
350
                        break;
 
351
                }
 
352
            }
 
353
        }
 
354
    }),
 
355
    listeners: {
 
356
        contextmenu: function(node, e) {
 
357
//          Register the context node with the menu so that a Menu Item's handler function can access
 
358
//          it via its {@link Ext.menu.BaseItem#parentMenu parentMenu} property.
 
359
            node.select();
 
360
            var c = node.getOwnerTree().contextMenu;
 
361
            c.contextNode = node;
 
362
            c.showAt(e.getXY());
 
363
        }
 
364
    }
 
365
});
 
366
</pre></code>
 
367
            * @param {Node} node The node
 
368
            * @param {Ext.EventObject} e The event object
 
369
            */
 
370
            "contextmenu",
 
371
            /**
 
372
            * @event beforechildrenrendered
 
373
            * Fires right before the child nodes for a node are rendered
 
374
            * @param {Node} node The node
 
375
            */
 
376
            "beforechildrenrendered",
 
377
           /**
 
378
             * @event startdrag
 
379
             * Fires when a node starts being dragged
 
380
             * @param {Ext.tree.TreePanel} this
 
381
             * @param {Ext.tree.TreeNode} node
 
382
             * @param {event} e The raw browser event
 
383
             */
 
384
            "startdrag",
 
385
            /**
 
386
             * @event enddrag
 
387
             * Fires when a drag operation is complete
 
388
             * @param {Ext.tree.TreePanel} this
 
389
             * @param {Ext.tree.TreeNode} node
 
390
             * @param {event} e The raw browser event
 
391
             */
 
392
            "enddrag",
 
393
            /**
 
394
             * @event dragdrop
 
395
             * Fires when a dragged node is dropped on a valid DD target
 
396
             * @param {Ext.tree.TreePanel} this
 
397
             * @param {Ext.tree.TreeNode} node
 
398
             * @param {DD} dd The dd it was dropped on
 
399
             * @param {event} e The raw browser event
 
400
             */
 
401
            "dragdrop",
 
402
            /**
 
403
             * @event beforenodedrop
 
404
             * Fires when a DD object is dropped on a node in this tree for preprocessing. Return false to cancel the drop. The dropEvent
 
405
             * passed to handlers has the following properties:<br />
 
406
             * <ul style="padding:5px;padding-left:16px;">
 
407
             * <li>tree - The TreePanel</li>
 
408
             * <li>target - The node being targeted for the drop</li>
 
409
             * <li>data - The drag data from the drag source</li>
 
410
             * <li>point - The point of the drop - append, above or below</li>
 
411
             * <li>source - The drag source</li>
 
412
             * <li>rawEvent - Raw mouse event</li>
 
413
             * <li>dropNode - Drop node(s) provided by the source <b>OR</b> you can supply node(s)
 
414
             * to be inserted by setting them on this object.</li>
 
415
             * <li>cancel - Set this to true to cancel the drop.</li>
 
416
             * <li>dropStatus - If the default drop action is cancelled but the drop is valid, setting this to true
 
417
             * will prevent the animated "repair" from appearing.</li>
 
418
             * </ul>
 
419
             * @param {Object} dropEvent
 
420
             */
 
421
            "beforenodedrop",
 
422
            /**
 
423
             * @event nodedrop
 
424
             * Fires after a DD object is dropped on a node in this tree. The dropEvent
 
425
             * passed to handlers has the following properties:<br />
 
426
             * <ul style="padding:5px;padding-left:16px;">
 
427
             * <li>tree - The TreePanel</li>
 
428
             * <li>target - The node being targeted for the drop</li>
 
429
             * <li>data - The drag data from the drag source</li>
 
430
             * <li>point - The point of the drop - append, above or below</li>
 
431
             * <li>source - The drag source</li>
 
432
             * <li>rawEvent - Raw mouse event</li>
 
433
             * <li>dropNode - Dropped node(s).</li>
 
434
             * </ul>
 
435
             * @param {Object} dropEvent
 
436
             */
 
437
            "nodedrop",
 
438
             /**
 
439
             * @event nodedragover
 
440
             * Fires when a tree node is being targeted for a drag drop, return false to signal drop not allowed. The dragOverEvent
 
441
             * passed to handlers has the following properties:<br />
 
442
             * <ul style="padding:5px;padding-left:16px;">
 
443
             * <li>tree - The TreePanel</li>
 
444
             * <li>target - The node being targeted for the drop</li>
 
445
             * <li>data - The drag data from the drag source</li>
 
446
             * <li>point - The point of the drop - append, above or below</li>
 
447
             * <li>source - The drag source</li>
 
448
             * <li>rawEvent - Raw mouse event</li>
 
449
             * <li>dropNode - Drop node(s) provided by the source.</li>
 
450
             * <li>cancel - Set this to true to signal drop not allowed.</li>
 
451
             * </ul>
 
452
             * @param {Object} dragOverEvent
 
453
             */
 
454
            "nodedragover"
 
455
        );
 
456
        if(this.singleExpand){
 
457
            this.on("beforeexpandnode", this.restrictExpand, this);
 
458
        }
 
459
    },
 
460
 
 
461
    // private
 
462
    proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
 
463
        if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
 
464
            ename = ename+'node';
 
465
        }
 
466
        // args inline for performance while bubbling events
 
467
        return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
 
468
    },
 
469
 
 
470
 
 
471
    /**
 
472
     * Returns this root node for this tree
 
473
     * @return {Node}
 
474
     */
 
475
    getRootNode : function(){
 
476
        return this.root;
 
477
    },
 
478
 
 
479
    /**
 
480
     * Sets the root node for this tree. If the TreePanel has already rendered a root node, the
 
481
     * previous root node (and all of its descendants) are destroyed before the new root node is rendered. 
 
482
     * @param {Node} node
 
483
     * @return {Node}
 
484
     */
 
485
    setRootNode : function(node){
 
486
        Ext.destroy(this.root);     
 
487
        if(!node.render){ // attributes passed
 
488
            node = this.loader.createNode(node);
 
489
        }
 
490
        this.root = node;
 
491
        node.ownerTree = this;
 
492
        node.isRoot = true;
 
493
        this.registerNode(node);
 
494
        if(!this.rootVisible){
 
495
            var uiP = node.attributes.uiProvider;
 
496
            node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node); 
 
497
        }        
 
498
        if (this.innerCt) {
 
499
            this.innerCt.update('');
 
500
            this.afterRender();
 
501
        }        
 
502
        return node;
 
503
    },
 
504
 
 
505
    /**
 
506
     * Gets a node in this tree by its id
 
507
     * @param {String} id
 
508
     * @return {Node}
 
509
     */
 
510
    getNodeById : function(id){
 
511
        return this.nodeHash[id];
 
512
    },
 
513
 
 
514
    // private
 
515
    registerNode : function(node){
 
516
        this.nodeHash[node.id] = node;
 
517
    },
 
518
 
 
519
    // private
 
520
    unregisterNode : function(node){
 
521
        delete this.nodeHash[node.id];
 
522
    },
 
523
 
 
524
    // private
 
525
    toString : function(){
 
526
        return "[Tree"+(this.id?" "+this.id:"")+"]";
 
527
    },
 
528
 
 
529
    // private
 
530
    restrictExpand : function(node){
 
531
        var p = node.parentNode;
 
532
        if(p){
 
533
            if(p.expandedChild && p.expandedChild.parentNode == p){
 
534
                p.expandedChild.collapse();
 
535
            }
 
536
            p.expandedChild = node;
 
537
        }
 
538
    },
 
539
 
 
540
    /**
 
541
     * Retrieve an array of checked nodes, or an array of a specific attribute of checked nodes (e.g. "id")
 
542
     * @param {String} attribute (optional) Defaults to null (return the actual nodes)
 
543
     * @param {TreeNode} startNode (optional) The node to start from, defaults to the root
 
544
     * @return {Array}
 
545
     */
 
546
    getChecked : function(a, startNode){
 
547
        startNode = startNode || this.root;
 
548
        var r = [];
 
549
        var f = function(){
 
550
            if(this.attributes.checked){
 
551
                r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
 
552
            }
 
553
        }
 
554
        startNode.cascade(f);
 
555
        return r;
 
556
    },
 
557
 
 
558
    /**
 
559
     * Returns the container element for this TreePanel.
 
560
     * @return {Element} The container element for this TreePanel.
 
561
     */
 
562
    getEl : function(){
 
563
        return this.el;
 
564
    },
 
565
 
 
566
    /**
 
567
     * Returns the default {@link Ext.tree.TreeLoader} for this TreePanel.
 
568
     * @return {Ext.tree.TreeLoader} The TreeLoader for this TreePanel.
 
569
     */
 
570
    getLoader : function(){
 
571
        return this.loader;
 
572
    },
 
573
 
 
574
    /**
 
575
     * Expand all nodes
 
576
     */
 
577
    expandAll : function(){
 
578
        this.root.expand(true);
 
579
    },
 
580
 
 
581
    /**
 
582
     * Collapse all nodes
 
583
     */
 
584
    collapseAll : function(){
 
585
        this.root.collapse(true);
 
586
    },
 
587
 
 
588
    /**
 
589
     * Returns the selection model used by this TreePanel.
 
590
     * @return {TreeSelectionModel} The selection model used by this TreePanel
 
591
     */
 
592
    getSelectionModel : function(){
 
593
        if(!this.selModel){
 
594
            this.selModel = new Ext.tree.DefaultSelectionModel();
 
595
        }
 
596
        return this.selModel;
 
597
    },
 
598
 
 
599
    /**
 
600
     * Expands a specified path in this TreePanel. A path can be retrieved from a node with {@link Ext.data.Node#getPath}
 
601
     * @param {String} path
 
602
     * @param {String} attr (optional) The attribute used in the path (see {@link Ext.data.Node#getPath} for more info)
 
603
     * @param {Function} callback (optional) The callback to call when the expand is complete. The callback will be called with
 
604
     * (bSuccess, oLastNode) where bSuccess is if the expand was successful and oLastNode is the last node that was expanded.
 
605
     */
 
606
    expandPath : function(path, attr, callback){
 
607
        attr = attr || "id";
 
608
        var keys = path.split(this.pathSeparator);
 
609
        var curNode = this.root;
 
610
        if(curNode.attributes[attr] != keys[1]){ // invalid root
 
611
            if(callback){
 
612
                callback(false, null);
 
613
            }
 
614
            return;
 
615
        }
 
616
        var index = 1;
 
617
        var f = function(){
 
618
            if(++index == keys.length){
 
619
                if(callback){
 
620
                    callback(true, curNode);
 
621
                }
 
622
                return;
 
623
            }
 
624
            var c = curNode.findChild(attr, keys[index]);
 
625
            if(!c){
 
626
                if(callback){
 
627
                    callback(false, curNode);
 
628
                }
 
629
                return;
 
630
            }
 
631
            curNode = c;
 
632
            c.expand(false, false, f);
 
633
        };
 
634
        curNode.expand(false, false, f);
 
635
    },
 
636
 
 
637
    /**
 
638
     * Selects the node in this tree at the specified path. A path can be retrieved from a node with {@link Ext.data.Node#getPath}
 
639
     * @param {String} path
 
640
     * @param {String} attr (optional) The attribute used in the path (see {@link Ext.data.Node#getPath} for more info)
 
641
     * @param {Function} callback (optional) The callback to call when the selection is complete. The callback will be called with
 
642
     * (bSuccess, oSelNode) where bSuccess is if the selection was successful and oSelNode is the selected node.
 
643
     */
 
644
    selectPath : function(path, attr, callback){
 
645
        attr = attr || "id";
 
646
        var keys = path.split(this.pathSeparator);
 
647
        var v = keys.pop();
 
648
        if(keys.length > 0){
 
649
            var f = function(success, node){
 
650
                if(success && node){
 
651
                    var n = node.findChild(attr, v);
 
652
                    if(n){
 
653
                        n.select();
 
654
                        if(callback){
 
655
                            callback(true, n);
 
656
                        }
 
657
                    }else if(callback){
 
658
                        callback(false, n);
 
659
                    }
 
660
                }else{
 
661
                    if(callback){
 
662
                        callback(false, n);
 
663
                    }
 
664
                }
 
665
            };
 
666
            this.expandPath(keys.join(this.pathSeparator), attr, f);
 
667
        }else{
 
668
            this.root.select();
 
669
            if(callback){
 
670
                callback(true, this.root);
 
671
            }
 
672
        }
 
673
    },
 
674
 
 
675
    /**
 
676
     * Returns the underlying Element for this tree
 
677
     * @return {Ext.Element} The Element
 
678
     */
 
679
    getTreeEl : function(){
 
680
        return this.body;
 
681
    },
 
682
 
 
683
    // private
 
684
    onRender : function(ct, position){
 
685
        Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
 
686
        this.el.addClass('x-tree');
 
687
        this.innerCt = this.body.createChild({tag:"ul",
 
688
               cls:"x-tree-root-ct " +
 
689
               (this.useArrows ? 'x-tree-arrows' : this.lines ? "x-tree-lines" : "x-tree-no-lines")});
 
690
    },
 
691
 
 
692
    // private
 
693
    initEvents : function(){
 
694
        Ext.tree.TreePanel.superclass.initEvents.call(this);
 
695
 
 
696
        if(this.containerScroll){
 
697
            Ext.dd.ScrollManager.register(this.body);
 
698
        }
 
699
        if((this.enableDD || this.enableDrop) && !this.dropZone){
 
700
           /**
 
701
            * The dropZone used by this tree if drop is enabled (see {@link #enableDD} or {@link #enableDrop})
 
702
            * @property dropZone
 
703
            * @type Ext.tree.TreeDropZone
 
704
            */
 
705
             this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
 
706
               ddGroup: this.ddGroup || "TreeDD", appendOnly: this.ddAppendOnly === true
 
707
           });
 
708
        }
 
709
        if((this.enableDD || this.enableDrag) && !this.dragZone){
 
710
           /**
 
711
            * The dragZone used by this tree if drag is enabled (see {@link #enableDD} or {@link #enableDrag}) 
 
712
            * @property dragZone
 
713
            * @type Ext.tree.TreeDragZone
 
714
            */
 
715
            this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
 
716
               ddGroup: this.ddGroup || "TreeDD",
 
717
               scroll: this.ddScroll
 
718
           });
 
719
        }
 
720
        this.getSelectionModel().init(this);
 
721
    },
 
722
 
 
723
    // private
 
724
    afterRender : function(){
 
725
        Ext.tree.TreePanel.superclass.afterRender.call(this);
 
726
        this.root.render();
 
727
        if(!this.rootVisible){
 
728
            this.root.renderChildren();
 
729
        }
 
730
    },
 
731
 
 
732
    onDestroy : function(){
 
733
        if(this.rendered){
 
734
            this.body.removeAllListeners();
 
735
            Ext.dd.ScrollManager.unregister(this.body);
 
736
            if(this.dropZone){
 
737
                this.dropZone.unreg();
 
738
            }
 
739
            if(this.dragZone){
 
740
               this.dragZone.unreg();
 
741
            }
 
742
        }
 
743
        this.root.destroy();
 
744
        this.nodeHash = null;
 
745
        Ext.tree.TreePanel.superclass.onDestroy.call(this);
 
746
    }
 
747
    
 
748
    /** 
 
749
     * @cfg {String/Number} activeItem 
 
750
     * @hide 
 
751
     */
 
752
    /** 
 
753
     * @cfg {Boolean} autoDestroy 
 
754
     * @hide 
 
755
     */
 
756
    /** 
 
757
     * @cfg {Object/String/Function} autoLoad 
 
758
     * @hide 
 
759
     */
 
760
    /** 
 
761
     * @cfg {Boolean} autoWidth 
 
762
     * @hide 
 
763
     */
 
764
    /** 
 
765
     * @cfg {Boolean/Number} bufferResize 
 
766
     * @hide 
 
767
     */
 
768
    /** 
 
769
     * @cfg {String} defaultType 
 
770
     * @hide 
 
771
     */
 
772
    /** 
 
773
     * @cfg {Object} defaults 
 
774
     * @hide 
 
775
     */
 
776
    /** 
 
777
     * @cfg {Boolean} hideBorders 
 
778
     * @hide 
 
779
     */
 
780
    /** 
 
781
     * @cfg {Mixed} items 
 
782
     * @hide 
 
783
     */
 
784
    /** 
 
785
     * @cfg {String} layout 
 
786
     * @hide 
 
787
     */
 
788
    /** 
 
789
     * @cfg {Object} layoutConfig 
 
790
     * @hide 
 
791
     */
 
792
    /** 
 
793
     * @cfg {Boolean} monitorResize 
 
794
     * @hide 
 
795
     */
 
796
    /** 
 
797
     * @property items 
 
798
     * @hide 
 
799
     */
 
800
    /** 
 
801
     * @method cascade 
 
802
     * @hide 
 
803
     */
 
804
    /** 
 
805
     * @method doLayout 
 
806
     * @hide 
 
807
     */
 
808
    /** 
 
809
     * @method find 
 
810
     * @hide 
 
811
     */
 
812
    /** 
 
813
     * @method findBy 
 
814
     * @hide 
 
815
     */
 
816
    /** 
 
817
     * @method findById 
 
818
     * @hide 
 
819
     */
 
820
    /** 
 
821
     * @method findByType 
 
822
     * @hide 
 
823
     */
 
824
    /** 
 
825
     * @method getComponent 
 
826
     * @hide 
 
827
     */
 
828
    /** 
 
829
     * @method getLayout 
 
830
     * @hide 
 
831
     */
 
832
    /** 
 
833
     * @method getUpdater 
 
834
     * @hide 
 
835
     */
 
836
    /** 
 
837
     * @method insert 
 
838
     * @hide 
 
839
     */
 
840
    /** 
 
841
     * @method load 
 
842
     * @hide 
 
843
     */
 
844
    /** 
 
845
     * @method remove 
 
846
     * @hide 
 
847
     */
 
848
    /** 
 
849
     * @event add 
 
850
     * @hide 
 
851
     */
 
852
    /** 
 
853
     * @method removeAll
 
854
     * @hide 
 
855
     */
 
856
    /** 
 
857
     * @event afterLayout 
 
858
     * @hide 
 
859
     */
 
860
    /** 
 
861
     * @event beforeadd 
 
862
     * @hide 
 
863
     */
 
864
    /** 
 
865
     * @event beforeremove 
 
866
     * @hide 
 
867
     */
 
868
    /** 
 
869
     * @event remove 
 
870
     * @hide 
 
871
     */
 
872
 
 
873
 
 
874
 
 
875
    /**
 
876
     * @cfg {String} allowDomMove  @hide
 
877
     */
 
878
    /**
 
879
     * @cfg {String} autoEl @hide
 
880
     */
 
881
    /**
 
882
     * @cfg {String} applyTo  @hide
 
883
     */
 
884
    /**
 
885
     * @cfg {String} contentEl  @hide
 
886
     */
 
887
    /**
 
888
     * @cfg {String} disabledClass  @hide
 
889
     */
 
890
    /**
 
891
     * @cfg {String} elements  @hide
 
892
     */
 
893
    /**
 
894
     * @cfg {String} html  @hide
 
895
     */
 
896
    /**
 
897
     * @property disabled
 
898
     * @hide
 
899
     */
 
900
    /**
 
901
     * @method applyToMarkup
 
902
     * @hide
 
903
     */
 
904
    /**
 
905
     * @method enable
 
906
     * @hide
 
907
     */
 
908
    /**
 
909
     * @method disable
 
910
     * @hide
 
911
     */
 
912
    /**
 
913
     * @method setDisabled
 
914
     * @hide
 
915
     */
 
916
});
 
917
 
 
918
Ext.tree.TreePanel.nodeTypes = {};
 
919
 
 
920
Ext.reg('treepanel', Ext.tree.TreePanel);
 
 
b'\\ No newline at end of file'