ext-all-debug.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:1167k
源码类别:

JavaScript

开发平台:

JavaScript

  1.     doAutoWidth : function(){
  2.         if(this.el && this.text && this.width === undefined){
  3.             this.el.setWidth('auto');
  4.             if(Ext.isIE7 && Ext.isStrict){
  5.                 var ib = this.btnEl;
  6.                 if(ib && ib.getWidth() > 20){
  7.                     ib.clip();
  8.                     ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
  9.                 }
  10.             }
  11.             if(this.minWidth){
  12.                 if(this.el.getWidth() < this.minWidth){
  13.                     this.el.setWidth(this.minWidth);
  14.                 }
  15.             }
  16.         }
  17.     },
  18.     
  19.     setHandler : function(handler, scope){
  20.         this.handler = handler;
  21.         this.scope = scope;
  22.         return this;
  23.     },
  24.     
  25.     setText : function(text){
  26.         this.text = text;
  27.         if(this.el){
  28.             this.btnEl.update(text || '&#160;');
  29.             this.setButtonClass();
  30.         }
  31.         this.doAutoWidth();
  32.         return this;
  33.     },
  34.     
  35.     setIcon : function(icon){
  36.         this.icon = icon;
  37.         if(this.el){
  38.             this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
  39.             this.setButtonClass();
  40.         }
  41.         return this;
  42.     },
  43.     
  44.     getText : function(){
  45.         return this.text;
  46.     },
  47.     
  48.     toggle : function(state, suppressEvent){
  49.         state = state === undefined ? !this.pressed : !!state;
  50.         if(state != this.pressed){
  51.             if(this.rendered){
  52.                 this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed');
  53.             }
  54.             this.pressed = state;
  55.             if(!suppressEvent){
  56.                 this.fireEvent('toggle', this, state);
  57.                 if(this.toggleHandler){
  58.                     this.toggleHandler.call(this.scope || this, this, state);
  59.                 }
  60.             }
  61.         }
  62.         return this;
  63.     },
  64.     
  65.     focus : function(){
  66.         this.btnEl.focus();
  67.     },
  68.     
  69.     onDisable : function(){
  70.         this.onDisableChange(true);
  71.     },
  72.     
  73.     onEnable : function(){
  74.         this.onDisableChange(false);
  75.     },
  76.     onDisableChange : function(disabled){
  77.         if(this.el){
  78.             if(!Ext.isIE6 || !this.text){
  79.                 this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass);
  80.             }
  81.             this.el.dom.disabled = disabled;
  82.         }
  83.         this.disabled = disabled;
  84.     },
  85.     
  86.     showMenu : function(){
  87.         if(this.rendered && this.menu){
  88.             if(this.tooltip){
  89.                 Ext.QuickTips.getQuickTip().cancelShow(this.btnEl);
  90.             }
  91.             this.menu.show(this.el, this.menuAlign);
  92.         }
  93.         return this;
  94.     },
  95.     
  96.     hideMenu : function(){
  97.         if(this.menu){
  98.             this.menu.hide();
  99.         }
  100.         return this;
  101.     },
  102.     
  103.     hasVisibleMenu : function(){
  104.         return this.menu && this.menu.isVisible();
  105.     },
  106.     
  107.     onClick : function(e){
  108.         if(e){
  109.             e.preventDefault();
  110.         }
  111.         if(e.button !== 0){
  112.             return;
  113.         }
  114.         if(!this.disabled){
  115.             if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
  116.                 this.toggle();
  117.             }
  118.             if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
  119.                 this.showMenu();
  120.             }
  121.             this.fireEvent('click', this, e);
  122.             if(this.handler){
  123.                 
  124.                 this.handler.call(this.scope || this, this, e);
  125.             }
  126.         }
  127.     },
  128.     
  129.     isMenuTriggerOver : function(e, internal){
  130.         return this.menu && !internal;
  131.     },
  132.     
  133.     isMenuTriggerOut : function(e, internal){
  134.         return this.menu && !internal;
  135.     },
  136.     
  137.     onMouseOver : function(e){
  138.         if(!this.disabled){
  139.             var internal = e.within(this.el,  true);
  140.             if(!internal){
  141.                 this.el.addClass('x-btn-over');
  142.                 if(!this.monitoringMouseOver){
  143.                     this.doc.on('mouseover', this.monitorMouseOver, this);
  144.                     this.monitoringMouseOver = true;
  145.                 }
  146.                 this.fireEvent('mouseover', this, e);
  147.             }
  148.             if(this.isMenuTriggerOver(e, internal)){
  149.                 this.fireEvent('menutriggerover', this, this.menu, e);
  150.             }
  151.         }
  152.     },
  153.     
  154.     monitorMouseOver : function(e){
  155.         if(e.target != this.el.dom && !e.within(this.el)){
  156.             if(this.monitoringMouseOver){
  157.                 this.doc.un('mouseover', this.monitorMouseOver, this);
  158.                 this.monitoringMouseOver = false;
  159.             }
  160.             this.onMouseOut(e);
  161.         }
  162.     },
  163.     
  164.     onMouseOut : function(e){
  165.         var internal = e.within(this.el) && e.target != this.el.dom;
  166.         this.el.removeClass('x-btn-over');
  167.         this.fireEvent('mouseout', this, e);
  168.         if(this.isMenuTriggerOut(e, internal)){
  169.             this.fireEvent('menutriggerout', this, this.menu, e);
  170.         }
  171.     },
  172.     focus : function() {
  173.         this.btnEl.focus();
  174.     },
  175.     blur : function() {
  176.         this.btnEl.blur();
  177.     },
  178.     
  179.     onFocus : function(e){
  180.         if(!this.disabled){
  181.             this.el.addClass('x-btn-focus');
  182.         }
  183.     },
  184.     
  185.     onBlur : function(e){
  186.         this.el.removeClass('x-btn-focus');
  187.     },
  188.     
  189.     getClickEl : function(e, isUp){
  190.        return this.el;
  191.     },
  192.     
  193.     onMouseDown : function(e){
  194.         if(!this.disabled && e.button === 0){
  195.             this.getClickEl(e).addClass('x-btn-click');
  196.             this.doc.on('mouseup', this.onMouseUp, this);
  197.         }
  198.     },
  199.     
  200.     onMouseUp : function(e){
  201.         if(e.button === 0){
  202.             this.getClickEl(e, true).removeClass('x-btn-click');
  203.             this.doc.un('mouseup', this.onMouseUp, this);
  204.         }
  205.     },
  206.     
  207.     onMenuShow : function(e){
  208.         this.menu.ownerCt = this;
  209.         this.ignoreNextClick = 0;
  210.         this.el.addClass('x-btn-menu-active');
  211.         this.fireEvent('menushow', this, this.menu);
  212.     },
  213.     
  214.     onMenuHide : function(e){
  215.         this.el.removeClass('x-btn-menu-active');
  216.         this.ignoreNextClick = this.restoreClick.defer(250, this);
  217.         this.fireEvent('menuhide', this, this.menu);
  218.         delete this.menu.ownerCt;
  219.     },
  220.     
  221.     restoreClick : function(){
  222.         this.ignoreNextClick = 0;
  223.     }
  224.     
  225. });
  226. Ext.reg('button', Ext.Button);
  227. Ext.ButtonToggleMgr = function(){
  228.    var groups = {};
  229.    function toggleGroup(btn, state){
  230.        if(state){
  231.            var g = groups[btn.toggleGroup];
  232.            for(var i = 0, l = g.length; i < l; i++){
  233.                if(g[i] != btn){
  234.                    g[i].toggle(false);
  235.                }
  236.            }
  237.        }
  238.    }
  239.    return {
  240.        register : function(btn){
  241.            if(!btn.toggleGroup){
  242.                return;
  243.            }
  244.            var g = groups[btn.toggleGroup];
  245.            if(!g){
  246.                g = groups[btn.toggleGroup] = [];
  247.            }
  248.            g.push(btn);
  249.            btn.on('toggle', toggleGroup);
  250.        },
  251.        unregister : function(btn){
  252.            if(!btn.toggleGroup){
  253.                return;
  254.            }
  255.            var g = groups[btn.toggleGroup];
  256.            if(g){
  257.                g.remove(btn);
  258.                btn.un('toggle', toggleGroup);
  259.            }
  260.        },
  261.        
  262.        getPressed : function(group){
  263.            var g = groups[group];
  264.            if(g){
  265.                for(var i = 0, len = g.length; i < len; i++){
  266.                    if(g[i].pressed === true){
  267.                        return g[i];
  268.                    }
  269.                }
  270.            }
  271.            return null;
  272.        }
  273.    };
  274. }();
  275. Ext.SplitButton = Ext.extend(Ext.Button, {
  276.     arrowSelector : 'em',
  277.     split: true,
  278.     
  279.     initComponent : function(){
  280.         Ext.SplitButton.superclass.initComponent.call(this);
  281.         
  282.         this.addEvents("arrowclick");
  283.     },
  284.     
  285.     onRender : function(){
  286.         Ext.SplitButton.superclass.onRender.apply(this, arguments);
  287.         if(this.arrowTooltip){
  288.             this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
  289.         }
  290.     },
  291.     
  292.     setArrowHandler : function(handler, scope){
  293.         this.arrowHandler = handler;
  294.         this.scope = scope;
  295.     },
  296.     getMenuClass : function(){
  297.         return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : '');
  298.     },
  299.     isClickOnArrow : function(e){
  300. if (this.arrowAlign != 'bottom') {
  301.     var visBtn = this.el.child('em.x-btn-split');
  302.     var right = visBtn.getRegion().right - visBtn.getPadding('r');
  303.     return e.getPageX() > right;
  304. } else {
  305.     return e.getPageY() > this.btnEl.getRegion().bottom;
  306. }
  307.     },
  308.     
  309.     onClick : function(e, t){
  310.         e.preventDefault();
  311.         if(!this.disabled){
  312.             if(this.isClickOnArrow(e)){
  313.                 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
  314.                     this.showMenu();
  315.                 }
  316.                 this.fireEvent("arrowclick", this, e);
  317.                 if(this.arrowHandler){
  318.                     this.arrowHandler.call(this.scope || this, this, e);
  319.                 }
  320.             }else{
  321.                 if(this.enableToggle){
  322.                     this.toggle();
  323.                 }
  324.                 this.fireEvent("click", this, e);
  325.                 if(this.handler){
  326.                     this.handler.call(this.scope || this, this, e);
  327.                 }
  328.             }
  329.         }
  330.     },
  331.     
  332.     isMenuTriggerOver : function(e){
  333.         return this.menu && e.target.tagName == this.arrowSelector;
  334.     },
  335.     
  336.     isMenuTriggerOut : function(e, internal){
  337.         return this.menu && e.target.tagName != this.arrowSelector;
  338.     }
  339. });
  340. Ext.reg('splitbutton', Ext.SplitButton);
  341. Ext.CycleButton = Ext.extend(Ext.SplitButton, {
  342.     
  343.     
  344.     
  345.     
  346.     
  347.     
  348.     
  349.     getItemText : function(item){
  350.         if(item && this.showText === true){
  351.             var text = '';
  352.             if(this.prependText){
  353.                 text += this.prependText;
  354.             }
  355.             text += item.text;
  356.             return text;
  357.         }
  358.         return undefined;
  359.     },
  360.     
  361.     setActiveItem : function(item, suppressEvent){
  362.         if(!Ext.isObject(item)){
  363.             item = this.menu.getComponent(item);
  364.         }
  365.         if(item){
  366.             if(!this.rendered){
  367.                 this.text = this.getItemText(item);
  368.                 this.iconCls = item.iconCls;
  369.             }else{
  370.                 var t = this.getItemText(item);
  371.                 if(t){
  372.                     this.setText(t);
  373.                 }
  374.                 this.setIconClass(item.iconCls);
  375.             }
  376.             this.activeItem = item;
  377.             if(!item.checked){
  378.                 item.setChecked(true, true);
  379.             }
  380.             if(this.forceIcon){
  381.                 this.setIconClass(this.forceIcon);
  382.             }
  383.             if(!suppressEvent){
  384.                 this.fireEvent('change', this, item);
  385.             }
  386.         }
  387.     },
  388.     
  389.     getActiveItem : function(){
  390.         return this.activeItem;
  391.     },
  392.     
  393.     initComponent : function(){
  394.         this.addEvents(
  395.             
  396.             "change"
  397.         );
  398.         if(this.changeHandler){
  399.             this.on('change', this.changeHandler, this.scope||this);
  400.             delete this.changeHandler;
  401.         }
  402.         this.itemCount = this.items.length;
  403.         this.menu = {cls:'x-cycle-menu', items:[]};
  404.         var checked;
  405.         Ext.each(this.items, function(item, i){
  406.             Ext.apply(item, {
  407.                 group: item.group || this.id,
  408.                 itemIndex: i,
  409.                 checkHandler: this.checkHandler,
  410.                 scope: this,
  411.                 checked: item.checked || false
  412.             });
  413.             this.menu.items.push(item);
  414.             if(item.checked){
  415.                 checked = item;
  416.             }
  417.         }, this);
  418.         this.setActiveItem(checked, true);
  419.         Ext.CycleButton.superclass.initComponent.call(this);
  420.         this.on('click', this.toggleSelected, this);
  421.     },
  422.     
  423.     checkHandler : function(item, pressed){
  424.         if(pressed){
  425.             this.setActiveItem(item);
  426.         }
  427.     },
  428.     
  429.     toggleSelected : function(){
  430.         var m = this.menu;
  431.         m.render();
  432.         
  433.         if(!m.hasLayout){
  434.             m.doLayout();
  435.         }
  436.         
  437.         var nextIdx, checkItem;
  438.         for (var i = 1; i < this.itemCount; i++) {
  439.             nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
  440.             
  441.             checkItem = m.items.itemAt(nextIdx);
  442.             
  443.             if (!checkItem.disabled) {
  444.                 checkItem.setChecked(true);
  445.                 break;
  446.             }
  447.         }
  448.     }
  449. });
  450. Ext.reg('cycle', Ext.CycleButton);
  451. Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
  452.     monitorResize : true,
  453.     triggerWidth : 18,
  454.     lastOverflow : false,
  455.     forceLayout: true,
  456.     noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
  457.     
  458.     onLayout : function(ct, target){
  459.         if(!this.leftTr){
  460.             var align = ct.buttonAlign == 'center' ? 'center' : 'left';
  461.             target.addClass('x-toolbar-layout-ct');
  462.             target.insertHtml('beforeEnd',
  463.                  '<table cellspacing="0" class="x-toolbar-ct"><tbody><tr><td class="x-toolbar-left" align="' + align + '"><table cellspacing="0"><tbody><tr class="x-toolbar-left-row"></tr></tbody></table></td><td class="x-toolbar-right" align="right"><table cellspacing="0" class="x-toolbar-right-ct"><tbody><tr><td><table cellspacing="0"><tbody><tr class="x-toolbar-right-row"></tr></tbody></table></td><td><table cellspacing="0"><tbody><tr class="x-toolbar-extras-row"></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table>');
  464.             this.leftTr = target.child('tr.x-toolbar-left-row', true);
  465.             this.rightTr = target.child('tr.x-toolbar-right-row', true);
  466.             this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
  467.         }
  468.         var side = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
  469.             pos = 0,
  470.             items = ct.items.items;
  471.         for(var i = 0, len = items.length, c; i < len; i++, pos++) {
  472.             c = items[i];
  473.             if(c.isFill){
  474.                 side = this.rightTr;
  475.                 pos = -1;
  476.             }else if(!c.rendered){
  477.                 c.render(this.insertCell(c, side, pos));
  478.             }else{
  479.                 if(!c.xtbHidden && !this.isValidParent(c, side.childNodes[pos])){
  480.                     var td = this.insertCell(c, side, pos);
  481.                     td.appendChild(c.getPositionEl().dom);
  482.                     c.container = Ext.get(td);
  483.                 }
  484.             }
  485.         }
  486.         
  487.         this.cleanup(this.leftTr);
  488.         this.cleanup(this.rightTr);
  489.         this.cleanup(this.extrasTr);
  490.         this.fitToSize(target);
  491.     },
  492.     cleanup : function(row){
  493.         var cn = row.childNodes;
  494.         for(var i = cn.length-1, c; i >= 0 && (c = cn[i]); i--){
  495.             if(!c.firstChild){
  496.                 row.removeChild(c);
  497.             }
  498.         }
  499.     },
  500.     insertCell : function(c, side, pos){
  501.         var td = document.createElement('td');
  502.         td.className='x-toolbar-cell';
  503.         side.insertBefore(td, side.childNodes[pos]||null);
  504.         return td;
  505.     },
  506.     hideItem : function(item){
  507.         var h = (this.hiddens = this.hiddens || []);
  508.         h.push(item);
  509.         item.xtbHidden = true;
  510.         item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
  511.         item.hide();
  512.     },
  513.     unhideItem : function(item){
  514.         item.show();
  515.         item.xtbHidden = false;
  516.         this.hiddens.remove(item);
  517.         if(this.hiddens.length < 1){
  518.             delete this.hiddens;
  519.         }
  520.     },
  521.     getItemWidth : function(c){
  522.         return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
  523.     },
  524.     fitToSize : function(t){
  525.         if(this.container.enableOverflow === false){
  526.             return;
  527.         }
  528.         var w = t.dom.clientWidth,
  529.             lw = this.lastWidth || 0,
  530.             iw = t.dom.firstChild.offsetWidth,
  531.             clipWidth = w - this.triggerWidth,
  532.             hideIndex = -1;
  533.         this.lastWidth = w;
  534.         if(iw > w || (this.hiddens && w >= lw)){
  535.             var i, items = this.container.items.items,
  536.                 len = items.length, c,
  537.                 loopWidth = 0;
  538.             for(i = 0; i < len; i++) {
  539.                 c = items[i];
  540.                 if(!c.isFill){
  541.                     loopWidth += this.getItemWidth(c);
  542.                     if(loopWidth > clipWidth){
  543.                         if(!(c.hidden || c.xtbHidden)){
  544.                             this.hideItem(c);
  545.                         }
  546.                     }else if(c.xtbHidden){
  547.                         this.unhideItem(c);
  548.                     }
  549.                 }
  550.             }
  551.         }
  552.         if(this.hiddens){
  553.             this.initMore();
  554.             if(!this.lastOverflow){
  555.                 this.container.fireEvent('overflowchange', this.container, true);
  556.                 this.lastOverflow = true;
  557.             }
  558.         }else if(this.more){
  559.             this.clearMenu();
  560.             this.more.destroy();
  561.             delete this.more;
  562.             if(this.lastOverflow){
  563.                 this.container.fireEvent('overflowchange', this.container, false);
  564.                 this.lastOverflow = false;
  565.             }
  566.         }
  567.     },
  568.     createMenuConfig : function(c, hideOnClick){
  569.         var cfg = Ext.apply({}, c.initialConfig),
  570.             group = c.toggleGroup;
  571.         Ext.apply(cfg, {
  572.             text: c.overflowText || c.text,
  573.             iconCls: c.iconCls,
  574.             icon: c.icon,
  575.             itemId: c.itemId,
  576.             disabled: c.disabled,
  577.             handler: c.handler,
  578.             scope: c.scope,
  579.             menu: c.menu,
  580.             hideOnClick: hideOnClick
  581.         });
  582.         if(group || c.enableToggle){
  583.             Ext.apply(cfg, {
  584.                 group: group,
  585.                 checked: c.pressed,
  586.                 listeners: {
  587.                     checkchange: function(item, checked){
  588.                         c.toggle(checked);
  589.                     }
  590.                 }
  591.             });
  592.         }
  593.         delete cfg.ownerCt;
  594.         delete cfg.xtype;
  595.         delete cfg.id;
  596.         return cfg;
  597.     },
  598.     
  599.     addComponentToMenu : function(m, c){
  600.         if(c instanceof Ext.Toolbar.Separator){
  601.             m.add('-');
  602.         }else if(Ext.isFunction(c.isXType)){
  603.             if(c.isXType('splitbutton')){
  604.                 m.add(this.createMenuConfig(c, true));
  605.             }else if(c.isXType('button')){
  606.                 m.add(this.createMenuConfig(c, !c.menu));
  607.             }else if(c.isXType('buttongroup')){
  608.                 c.items.each(function(item){
  609.                      this.addComponentToMenu(m, item);
  610.                 }, this);
  611.             }
  612.         }
  613.     },
  614.     clearMenu : function(){
  615.         var m = this.moreMenu;
  616.         if(m && m.items){
  617.             m.items.each(function(item){
  618.                 delete item.menu;
  619.             });
  620.         }
  621.     },
  622.     
  623.     beforeMoreShow : function(m){
  624.         var h = this.container.items.items,
  625.             len = h.length,
  626.             c,
  627.             prev,
  628.             needsSep = function(group, item){
  629.                 return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
  630.             };
  631.         this.clearMenu();
  632.         m.removeAll();
  633.         for(var i = 0; i < len; i++){
  634.             c = h[i];
  635.             if(c.xtbHidden){
  636.                 if(prev && (needsSep(c, prev) || needsSep(prev, c))){
  637.                     m.add('-');
  638.                 }
  639.                 this.addComponentToMenu(m, c);
  640.                 prev = c;
  641.             }
  642.         }
  643.         
  644.         
  645.         if(m.items.length < 1){
  646.             m.add(this.noItemsMenuText);
  647.         }
  648.     },
  649.     initMore : function(){
  650.         if(!this.more){
  651.             this.moreMenu = new Ext.menu.Menu({
  652.                 listeners: {
  653.                     beforeshow: this.beforeMoreShow,
  654.                     scope: this
  655.                 }
  656.             });
  657.             this.moreMenu.ownerCt = this.container;
  658.             this.more = new Ext.Button({
  659.                 iconCls: 'x-toolbar-more-icon',
  660.                 cls: 'x-toolbar-more',
  661.                 menu: this.moreMenu
  662.             });
  663.             var td = this.insertCell(this.more, this.extrasTr, 100);
  664.             this.more.render(td);
  665.         }
  666.     },
  667.     onRemove : function(c){
  668.         delete this.leftTr;
  669.         delete this.rightTr;
  670.         delete this.extrasTr;
  671.         Ext.layout.ToolbarLayout.superclass.onRemove.call(this, c);
  672.     },
  673.     destroy : function(){
  674.         Ext.destroy(this.more, this.moreMenu);
  675.         delete this.leftTr;
  676.         delete this.rightTr;
  677.         delete this.extrasTr;
  678.         Ext.layout.ToolbarLayout.superclass.destroy.call(this);
  679.     }
  680.     
  681. });
  682. Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;
  683. Ext.Toolbar = function(config){
  684.     if(Ext.isArray(config)){
  685.         config = {items: config, layout: 'toolbar'};
  686.     } else {
  687.         config = Ext.apply({
  688.             layout: 'toolbar'
  689.         }, config);
  690.         if(config.buttons) {
  691.             config.items = config.buttons;
  692.         }
  693.     }
  694.     Ext.Toolbar.superclass.constructor.call(this, config);
  695. };
  696. (function(){
  697. var T = Ext.Toolbar;
  698. Ext.extend(T, Ext.Container, {
  699.     defaultType: 'button',
  700.     
  701.     
  702.     trackMenus : true,
  703.     internalDefaults: {removeMode: 'container', hideParent: true},
  704.     toolbarCls: 'x-toolbar',
  705.     initComponent : function(){
  706.         T.superclass.initComponent.call(this);
  707.         
  708.         this.addEvents('overflowchange');
  709.     },
  710.     
  711.     onRender : function(ct, position){
  712.         if(!this.el){
  713.             if(!this.autoCreate){
  714.                 this.autoCreate = {
  715.                     cls: this.toolbarCls + ' x-small-editor'
  716.                 };
  717.             }
  718.             this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
  719.             Ext.Toolbar.superclass.onRender.apply(this, arguments);
  720.         }
  721.     },
  722.     
  723.     
  724.     lookupComponent : function(c){
  725.         if(Ext.isString(c)){
  726.             if(c == '-'){
  727.                 c = new T.Separator();
  728.             }else if(c == ' '){
  729.                 c = new T.Spacer();
  730.             }else if(c == '->'){
  731.                 c = new T.Fill();
  732.             }else{
  733.                 c = new T.TextItem(c);
  734.             }
  735.             this.applyDefaults(c);
  736.         }else{
  737.             if(c.isFormField || c.render){ 
  738.                 c = this.createComponent(c);
  739.             }else if(c.tag){ 
  740.                 c = new T.Item({autoEl: c});
  741.             }else if(c.tagName){ 
  742.                 c = new T.Item({el:c});
  743.             }else if(Ext.isObject(c)){ 
  744.                 c = c.xtype ? this.createComponent(c) : this.constructButton(c);
  745.             }
  746.         }
  747.         return c;
  748.     },
  749.     
  750.     applyDefaults : function(c){
  751.         if(!Ext.isString(c)){
  752.             c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
  753.             var d = this.internalDefaults;
  754.             if(c.events){
  755.                 Ext.applyIf(c.initialConfig, d);
  756.                 Ext.apply(c, d);
  757.             }else{
  758.                 Ext.applyIf(c, d);
  759.             }
  760.         }
  761.         return c;
  762.     },
  763.     
  764.     addSeparator : function(){
  765.         return this.add(new T.Separator());
  766.     },
  767.     
  768.     addSpacer : function(){
  769.         return this.add(new T.Spacer());
  770.     },
  771.     
  772.     addFill : function(){
  773.         this.add(new T.Fill());
  774.     },
  775.     
  776.     addElement : function(el){
  777.         return this.addItem(new T.Item({el:el}));
  778.     },
  779.     
  780.     addItem : function(item){
  781.         return this.add.apply(this, arguments);
  782.     },
  783.     
  784.     addButton : function(config){
  785.         if(Ext.isArray(config)){
  786.             var buttons = [];
  787.             for(var i = 0, len = config.length; i < len; i++) {
  788.                 buttons.push(this.addButton(config[i]));
  789.             }
  790.             return buttons;
  791.         }
  792.         return this.add(this.constructButton(config));
  793.     },
  794.     
  795.     addText : function(text){
  796.         return this.addItem(new T.TextItem(text));
  797.     },
  798.     
  799.     addDom : function(config){
  800.         return this.add(new T.Item({autoEl: config}));
  801.     },
  802.     
  803.     addField : function(field){
  804.         return this.add(field);
  805.     },
  806.     
  807.     insertButton : function(index, item){
  808.         if(Ext.isArray(item)){
  809.             var buttons = [];
  810.             for(var i = 0, len = item.length; i < len; i++) {
  811.                buttons.push(this.insertButton(index + i, item[i]));
  812.             }
  813.             return buttons;
  814.         }
  815.         return Ext.Toolbar.superclass.insert.call(this, index, item);
  816.     },
  817.     
  818.     trackMenu : function(item, remove){
  819.         if(this.trackMenus && item.menu){
  820.             var method = remove ? 'mun' : 'mon';
  821.             this[method](item, 'menutriggerover', this.onButtonTriggerOver, this);
  822.             this[method](item, 'menushow', this.onButtonMenuShow, this);
  823.             this[method](item, 'menuhide', this.onButtonMenuHide, this);
  824.         }
  825.     },
  826.     
  827.     constructButton : function(item){
  828.         var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType);
  829.         return b;
  830.     },
  831.     
  832.     onAdd : function(c){
  833.         Ext.Toolbar.superclass.onAdd.call(this);
  834.         this.trackMenu(c);
  835.     },
  836.     
  837.     onRemove : function(c){
  838.         Ext.Toolbar.superclass.onRemove.call(this);
  839.         this.trackMenu(c, true);
  840.     },
  841.     
  842.     onDisable : function(){
  843.         this.items.each(function(item){
  844.              if(item.disable){
  845.                  item.disable();
  846.              }
  847.         });
  848.     },
  849.     
  850.     onEnable : function(){
  851.         this.items.each(function(item){
  852.              if(item.enable){
  853.                  item.enable();
  854.              }
  855.         });
  856.     },
  857.     
  858.     onButtonTriggerOver : function(btn){
  859.         if(this.activeMenuBtn && this.activeMenuBtn != btn){
  860.             this.activeMenuBtn.hideMenu();
  861.             btn.showMenu();
  862.             this.activeMenuBtn = btn;
  863.         }
  864.     },
  865.     
  866.     onButtonMenuShow : function(btn){
  867.         this.activeMenuBtn = btn;
  868.     },
  869.     
  870.     onButtonMenuHide : function(btn){
  871.         delete this.activeMenuBtn;
  872.     }
  873. });
  874. Ext.reg('toolbar', Ext.Toolbar);
  875. T.Item = Ext.extend(Ext.BoxComponent, {
  876.     hideParent: true, 
  877.     enable:Ext.emptyFn,
  878.     disable:Ext.emptyFn,
  879.     focus:Ext.emptyFn
  880.     
  881. });
  882. Ext.reg('tbitem', T.Item);
  883. T.Separator = Ext.extend(T.Item, {
  884.     onRender : function(ct, position){
  885.         this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position);
  886.     }
  887. });
  888. Ext.reg('tbseparator', T.Separator);
  889. T.Spacer = Ext.extend(T.Item, {
  890.     
  891.     onRender : function(ct, position){
  892.         this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position);
  893.     }
  894. });
  895. Ext.reg('tbspacer', T.Spacer);
  896. T.Fill = Ext.extend(T.Item, {
  897.     
  898.     render : Ext.emptyFn,
  899.     isFill : true
  900. });
  901. Ext.reg('tbfill', T.Fill);
  902. T.TextItem = Ext.extend(T.Item, {
  903.     
  904.     constructor: function(config){
  905.         T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config);
  906.     },
  907.     
  908.     onRender : function(ct, position) {
  909.         this.autoEl = {cls: 'xtb-text', html: this.text || ''};
  910.         T.TextItem.superclass.onRender.call(this, ct, position);
  911.     },
  912.     
  913.     setText : function(t) {
  914.         if(this.rendered){
  915.             this.el.update(t);
  916.         }else{
  917.             this.text = t;
  918.         }
  919.     }
  920. });
  921. Ext.reg('tbtext', T.TextItem);
  922. T.Button = Ext.extend(Ext.Button, {});
  923. T.SplitButton = Ext.extend(Ext.SplitButton, {});
  924. Ext.reg('tbbutton', T.Button);
  925. Ext.reg('tbsplit', T.SplitButton);
  926. })();
  927. Ext.ButtonGroup = Ext.extend(Ext.Panel, {
  928.     
  929.     
  930.     baseCls: 'x-btn-group',
  931.     
  932.     layout:'table',
  933.     defaultType: 'button',
  934.     
  935.     frame: true,
  936.     internalDefaults: {removeMode: 'container', hideParent: true},
  937.     initComponent : function(){
  938.         this.layoutConfig = this.layoutConfig || {};
  939.         Ext.applyIf(this.layoutConfig, {
  940.             columns : this.columns
  941.         });
  942.         if(!this.title){
  943.             this.addClass('x-btn-group-notitle');
  944.         }
  945.         this.on('afterlayout', this.onAfterLayout, this);
  946.         Ext.ButtonGroup.superclass.initComponent.call(this);
  947.     },
  948.     applyDefaults : function(c){
  949.         c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
  950.         var d = this.internalDefaults;
  951.         if(c.events){
  952.             Ext.applyIf(c.initialConfig, d);
  953.             Ext.apply(c, d);
  954.         }else{
  955.             Ext.applyIf(c, d);
  956.         }
  957.         return c;
  958.     },
  959.     onAfterLayout : function(){
  960.         var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
  961.         this.body.setWidth(bodyWidth);
  962.         this.el.setWidth(bodyWidth + this.getFrameWidth());
  963.     }
  964.     
  965. });
  966. Ext.reg('buttongroup', Ext.ButtonGroup);
  967. (function() {
  968. var T = Ext.Toolbar;
  969. Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
  970.     
  971.     
  972.     
  973.     pageSize : 20,
  974.     
  975.     
  976.     displayMsg : 'Displaying {0} - {1} of {2}',
  977.     
  978.     emptyMsg : 'No data to display',
  979.     
  980.     beforePageText : 'Page',
  981.     
  982.     afterPageText : 'of {0}',
  983.     
  984.     firstText : 'First Page',
  985.     
  986.     prevText : 'Previous Page',
  987.     
  988.     nextText : 'Next Page',
  989.     
  990.     lastText : 'Last Page',
  991.     
  992.     refreshText : 'Refresh',
  993.     
  994.     
  995.     
  996.     initComponent : function(){
  997.         var pagingItems = [this.first = new T.Button({
  998.             tooltip: this.firstText,
  999.             overflowText: this.firstText,
  1000.             iconCls: 'x-tbar-page-first',
  1001.             disabled: true,
  1002.             handler: this.moveFirst,
  1003.             scope: this
  1004.         }), this.prev = new T.Button({
  1005.             tooltip: this.prevText,
  1006.             overflowText: this.prevText,
  1007.             iconCls: 'x-tbar-page-prev',
  1008.             disabled: true,
  1009.             handler: this.movePrevious,
  1010.             scope: this
  1011.         }), '-', this.beforePageText,
  1012.         this.inputItem = new Ext.form.NumberField({
  1013.             cls: 'x-tbar-page-number',
  1014.             allowDecimals: false,
  1015.             allowNegative: false,
  1016.             enableKeyEvents: true,
  1017.             selectOnFocus: true,
  1018.             submitValue: false,
  1019.             listeners: {
  1020.                 scope: this,
  1021.                 keydown: this.onPagingKeyDown,
  1022.                 blur: this.onPagingBlur
  1023.             }
  1024.         }), this.afterTextItem = new T.TextItem({
  1025.             text: String.format(this.afterPageText, 1)
  1026.         }), '-', this.next = new T.Button({
  1027.             tooltip: this.nextText,
  1028.             overflowText: this.nextText,
  1029.             iconCls: 'x-tbar-page-next',
  1030.             disabled: true,
  1031.             handler: this.moveNext,
  1032.             scope: this
  1033.         }), this.last = new T.Button({
  1034.             tooltip: this.lastText,
  1035.             overflowText: this.lastText,
  1036.             iconCls: 'x-tbar-page-last',
  1037.             disabled: true,
  1038.             handler: this.moveLast,
  1039.             scope: this
  1040.         }), '-', this.refresh = new T.Button({
  1041.             tooltip: this.refreshText,
  1042.             overflowText: this.refreshText,
  1043.             iconCls: 'x-tbar-loading',
  1044.             handler: this.doRefresh,
  1045.             scope: this
  1046.         })];
  1047.         var userItems = this.items || this.buttons || [];
  1048.         if (this.prependButtons) {
  1049.             this.items = userItems.concat(pagingItems);
  1050.         }else{
  1051.             this.items = pagingItems.concat(userItems);
  1052.         }
  1053.         delete this.buttons;
  1054.         if(this.displayInfo){
  1055.             this.items.push('->');
  1056.             this.items.push(this.displayItem = new T.TextItem({}));
  1057.         }
  1058.         Ext.PagingToolbar.superclass.initComponent.call(this);
  1059.         this.addEvents(
  1060.             
  1061.             'change',
  1062.             
  1063.             'beforechange'
  1064.         );
  1065.         this.on('afterlayout', this.onFirstLayout, this, {single: true});
  1066.         this.cursor = 0;
  1067.         this.bindStore(this.store, true);
  1068.     },
  1069.     
  1070.     onFirstLayout : function(){
  1071.         if(this.dsLoaded){
  1072.             this.onLoad.apply(this, this.dsLoaded);
  1073.         }
  1074.     },
  1075.     
  1076.     updateInfo : function(){
  1077.         if(this.displayItem){
  1078.             var count = this.store.getCount();
  1079.             var msg = count == 0 ?
  1080.                 this.emptyMsg :
  1081.                 String.format(
  1082.                     this.displayMsg,
  1083.                     this.cursor+1, this.cursor+count, this.store.getTotalCount()
  1084.                 );
  1085.             this.displayItem.setText(msg);
  1086.         }
  1087.     },
  1088.     
  1089.     onLoad : function(store, r, o){
  1090.         if(!this.rendered){
  1091.             this.dsLoaded = [store, r, o];
  1092.             return;
  1093.         }
  1094.         var p = this.getParams();
  1095.         this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
  1096.         var d = this.getPageData(), ap = d.activePage, ps = d.pages;
  1097.         this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
  1098.         this.inputItem.setValue(ap);
  1099.         this.first.setDisabled(ap == 1);
  1100.         this.prev.setDisabled(ap == 1);
  1101.         this.next.setDisabled(ap == ps);
  1102.         this.last.setDisabled(ap == ps);
  1103.         this.refresh.enable();
  1104.         this.updateInfo();
  1105.         this.fireEvent('change', this, d);
  1106.     },
  1107.     
  1108.     getPageData : function(){
  1109.         var total = this.store.getTotalCount();
  1110.         return {
  1111.             total : total,
  1112.             activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
  1113.             pages :  total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
  1114.         };
  1115.     },
  1116.     
  1117.     changePage : function(page){
  1118.         this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));
  1119.     },
  1120.     
  1121.     onLoadError : function(){
  1122.         if(!this.rendered){
  1123.             return;
  1124.         }
  1125.         this.refresh.enable();
  1126.     },
  1127.     
  1128.     readPage : function(d){
  1129.         var v = this.inputItem.getValue(), pageNum;
  1130.         if (!v || isNaN(pageNum = parseInt(v, 10))) {
  1131.             this.inputItem.setValue(d.activePage);
  1132.             return false;
  1133.         }
  1134.         return pageNum;
  1135.     },
  1136.     onPagingFocus : function(){
  1137.         this.inputItem.select();
  1138.     },
  1139.     
  1140.     onPagingBlur : function(e){
  1141.         this.inputItem.setValue(this.getPageData().activePage);
  1142.     },
  1143.     
  1144.     onPagingKeyDown : function(field, e){
  1145.         var k = e.getKey(), d = this.getPageData(), pageNum;
  1146.         if (k == e.RETURN) {
  1147.             e.stopEvent();
  1148.             pageNum = this.readPage(d);
  1149.             if(pageNum !== false){
  1150.                 pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
  1151.                 this.doLoad(pageNum * this.pageSize);
  1152.             }
  1153.         }else if (k == e.HOME || k == e.END){
  1154.             e.stopEvent();
  1155.             pageNum = k == e.HOME ? 1 : d.pages;
  1156.             field.setValue(pageNum);
  1157.         }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
  1158.             e.stopEvent();
  1159.             if((pageNum = this.readPage(d))){
  1160.                 var increment = e.shiftKey ? 10 : 1;
  1161.                 if(k == e.DOWN || k == e.PAGEDOWN){
  1162.                     increment *= -1;
  1163.                 }
  1164.                 pageNum += increment;
  1165.                 if(pageNum >= 1 & pageNum <= d.pages){
  1166.                     field.setValue(pageNum);
  1167.                 }
  1168.             }
  1169.         }
  1170.     },
  1171.     
  1172.     getParams : function(){
  1173.         
  1174.         return this.paramNames || this.store.paramNames;
  1175.     },
  1176.     
  1177.     beforeLoad : function(){
  1178.         if(this.rendered && this.refresh){
  1179.             this.refresh.disable();
  1180.         }
  1181.     },
  1182.     
  1183.     doLoad : function(start){
  1184.         var o = {}, pn = this.getParams();
  1185.         o[pn.start] = start;
  1186.         o[pn.limit] = this.pageSize;
  1187.         if(this.fireEvent('beforechange', this, o) !== false){
  1188.             this.store.load({params:o});
  1189.         }
  1190.     },
  1191.     
  1192.     moveFirst : function(){
  1193.         this.doLoad(0);
  1194.     },
  1195.     
  1196.     movePrevious : function(){
  1197.         this.doLoad(Math.max(0, this.cursor-this.pageSize));
  1198.     },
  1199.     
  1200.     moveNext : function(){
  1201.         this.doLoad(this.cursor+this.pageSize);
  1202.     },
  1203.     
  1204.     moveLast : function(){
  1205.         var total = this.store.getTotalCount(),
  1206.             extra = total % this.pageSize;
  1207.         this.doLoad(extra ? (total - extra) : total - this.pageSize);
  1208.     },
  1209.     
  1210.     doRefresh : function(){
  1211.         this.doLoad(this.cursor);
  1212.     },
  1213.     
  1214.     bindStore : function(store, initial){
  1215.         var doLoad;
  1216.         if(!initial && this.store){
  1217.             if(store !== this.store && this.store.autoDestroy){
  1218.                 this.store.destroy();
  1219.             }else{
  1220.                 this.store.un('beforeload', this.beforeLoad, this);
  1221.                 this.store.un('load', this.onLoad, this);
  1222.                 this.store.un('exception', this.onLoadError, this);
  1223.             }
  1224.             if(!store){
  1225.                 this.store = null;
  1226.             }
  1227.         }
  1228.         if(store){
  1229.             store = Ext.StoreMgr.lookup(store);
  1230.             store.on({
  1231.                 scope: this,
  1232.                 beforeload: this.beforeLoad,
  1233.                 load: this.onLoad,
  1234.                 exception: this.onLoadError
  1235.             });
  1236.             doLoad = true;
  1237.         }
  1238.         this.store = store;
  1239.         if(doLoad){
  1240.             this.onLoad(store, null, {});
  1241.         }
  1242.     },
  1243.     
  1244.     unbind : function(store){
  1245.         this.bindStore(null);
  1246.     },
  1247.     
  1248.     bind : function(store){
  1249.         this.bindStore(store);
  1250.     },
  1251.     
  1252.     onDestroy : function(){
  1253.         this.bindStore(null);
  1254.         Ext.PagingToolbar.superclass.onDestroy.call(this);
  1255.     }
  1256. });
  1257. })();
  1258. Ext.reg('paging', Ext.PagingToolbar);
  1259. Ext.History = (function () {
  1260.     var iframe, hiddenField;
  1261.     var ready = false;
  1262.     var currentToken;
  1263.     function getHash() {
  1264.         var href = top.location.href, i = href.indexOf("#");
  1265.         return i >= 0 ? href.substr(i + 1) : null;
  1266.     }
  1267.     function doSave() {
  1268.         hiddenField.value = currentToken;
  1269.     }
  1270.     function handleStateChange(token) {
  1271.         currentToken = token;
  1272.         Ext.History.fireEvent('change', token);
  1273.     }
  1274.     function updateIFrame (token) {
  1275.         var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join('');
  1276.         try {
  1277.             var doc = iframe.contentWindow.document;
  1278.             doc.open();
  1279.             doc.write(html);
  1280.             doc.close();
  1281.             return true;
  1282.         } catch (e) {
  1283.             return false;
  1284.         }
  1285.     }
  1286.     function checkIFrame() {
  1287.         if (!iframe.contentWindow || !iframe.contentWindow.document) {
  1288.             setTimeout(checkIFrame, 10);
  1289.             return;
  1290.         }
  1291.         var doc = iframe.contentWindow.document;
  1292.         var elem = doc.getElementById("state");
  1293.         var token = elem ? elem.innerText : null;
  1294.         var hash = getHash();
  1295.         setInterval(function () {
  1296.             doc = iframe.contentWindow.document;
  1297.             elem = doc.getElementById("state");
  1298.             var newtoken = elem ? elem.innerText : null;
  1299.             var newHash = getHash();
  1300.             if (newtoken !== token) {
  1301.                 token = newtoken;
  1302.                 handleStateChange(token);
  1303.                 top.location.hash = token;
  1304.                 hash = token;
  1305.                 doSave();
  1306.             } else if (newHash !== hash) {
  1307.                 hash = newHash;
  1308.                 updateIFrame(newHash);
  1309.             }
  1310.         }, 50);
  1311.         ready = true;
  1312.         Ext.History.fireEvent('ready', Ext.History);
  1313.     }
  1314.     function startUp() {
  1315.         currentToken = hiddenField.value ? hiddenField.value : getHash();
  1316.         if (Ext.isIE) {
  1317.             checkIFrame();
  1318.         } else {
  1319.             var hash = getHash();
  1320.             setInterval(function () {
  1321.                 var newHash = getHash();
  1322.                 if (newHash !== hash) {
  1323.                     hash = newHash;
  1324.                     handleStateChange(hash);
  1325.                     doSave();
  1326.                 }
  1327.             }, 50);
  1328.             ready = true;
  1329.             Ext.History.fireEvent('ready', Ext.History);
  1330.         }
  1331.     }
  1332.     return {
  1333.         
  1334.         fieldId: 'x-history-field',
  1335.         
  1336.         iframeId: 'x-history-frame',
  1337.         events:{},
  1338.         
  1339.         init: function (onReady, scope) {
  1340.             if(ready) {
  1341.                 Ext.callback(onReady, scope, [this]);
  1342.                 return;
  1343.             }
  1344.             if(!Ext.isReady){
  1345.                 Ext.onReady(function(){
  1346.                     Ext.History.init(onReady, scope);
  1347.                 });
  1348.                 return;
  1349.             }
  1350.             hiddenField = Ext.getDom(Ext.History.fieldId);
  1351.             if (Ext.isIE) {
  1352.                 iframe = Ext.getDom(Ext.History.iframeId);
  1353.             }
  1354.             this.addEvents(
  1355.                 
  1356.                 'ready',
  1357.                 
  1358.                 'change'
  1359.             );
  1360.             if(onReady){
  1361.                 this.on('ready', onReady, scope, {single:true});
  1362.             }
  1363.             startUp();
  1364.         },
  1365.         
  1366.         add: function (token, preventDup) {
  1367.             if(preventDup !== false){
  1368.                 if(this.getToken() == token){
  1369.                     return true;
  1370.                 }
  1371.             }
  1372.             if (Ext.isIE) {
  1373.                 return updateIFrame(token);
  1374.             } else {
  1375.                 top.location.hash = token;
  1376.                 return true;
  1377.             }
  1378.         },
  1379.         
  1380.         back: function(){
  1381.             history.go(-1);
  1382.         },
  1383.         
  1384.         forward: function(){
  1385.             history.go(1);
  1386.         },
  1387.         
  1388.         getToken: function() {
  1389.             return ready ? currentToken : getHash();
  1390.         }
  1391.     };
  1392. })();
  1393. Ext.apply(Ext.History, new Ext.util.Observable());
  1394. Ext.Tip = Ext.extend(Ext.Panel, {
  1395.     
  1396.     
  1397.     
  1398.     minWidth : 40,
  1399.     
  1400.     maxWidth : 300,
  1401.     
  1402.     shadow : "sides",
  1403.     
  1404.     defaultAlign : "tl-bl?",
  1405.     autoRender: true,
  1406.     quickShowInterval : 250,
  1407.     
  1408.     frame:true,
  1409.     hidden:true,
  1410.     baseCls: 'x-tip',
  1411.     floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
  1412.     autoHeight:true,
  1413.     closeAction: 'hide',
  1414.     
  1415.     initComponent : function(){
  1416.         Ext.Tip.superclass.initComponent.call(this);
  1417.         if(this.closable && !this.title){
  1418.             this.elements += ',header';
  1419.         }
  1420.     },
  1421.     
  1422.     afterRender : function(){
  1423.         Ext.Tip.superclass.afterRender.call(this);
  1424.         if(this.closable){
  1425.             this.addTool({
  1426.                 id: 'close',
  1427.                 handler: this[this.closeAction],
  1428.                 scope: this
  1429.             });
  1430.         }
  1431.     },
  1432.     
  1433.     showAt : function(xy){
  1434.         Ext.Tip.superclass.show.call(this);
  1435.         if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
  1436.             this.doAutoWidth();
  1437.         }
  1438.         if(this.constrainPosition){
  1439.             xy = this.el.adjustForConstraints(xy);
  1440.         }
  1441.         this.setPagePosition(xy[0], xy[1]);
  1442.     },
  1443.     
  1444.     doAutoWidth : function(adjust){
  1445.         adjust = adjust || 0;
  1446.         var bw = this.body.getTextWidth();
  1447.         if(this.title){
  1448.             bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
  1449.         }
  1450.         bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr") + adjust;
  1451.         this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
  1452.         
  1453.         
  1454.         if(Ext.isIE7 && !this.repainted){
  1455.             this.el.repaint();
  1456.             this.repainted = true;
  1457.         }
  1458.     },
  1459.     
  1460.     showBy : function(el, pos){
  1461.         if(!this.rendered){
  1462.             this.render(Ext.getBody());
  1463.         }
  1464.         this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
  1465.     },
  1466.     initDraggable : function(){
  1467.         this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
  1468.         this.header.addClass('x-tip-draggable');
  1469.     }
  1470. });
  1471. Ext.reg('tip', Ext.Tip);
  1472. Ext.Tip.DD = function(tip, config){
  1473.     Ext.apply(this, config);
  1474.     this.tip = tip;
  1475.     Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
  1476.     this.setHandleElId(tip.header.id);
  1477.     this.scroll = false;
  1478. };
  1479. Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
  1480.     moveOnly:true,
  1481.     scroll:false,
  1482.     headerOffsets:[100, 25],
  1483.     startDrag : function(){
  1484.         this.tip.el.disableShadow();
  1485.     },
  1486.     endDrag : function(e){
  1487.         this.tip.el.enableShadow(true);
  1488.     }
  1489. });
  1490. Ext.ToolTip = Ext.extend(Ext.Tip, {
  1491.     
  1492.     
  1493.     
  1494.     
  1495.     showDelay : 500,
  1496.     
  1497.     hideDelay : 200,
  1498.     
  1499.     dismissDelay : 5000,
  1500.     
  1501.     
  1502.     trackMouse : false,
  1503.     
  1504.     anchorToTarget : true,
  1505.     
  1506.     anchorOffset : 0,
  1507.     
  1508.     
  1509.     targetCounter : 0,
  1510.     constrainPosition : false,
  1511.     
  1512.     initComponent : function(){
  1513.         Ext.ToolTip.superclass.initComponent.call(this);
  1514.         this.lastActive = new Date();
  1515.         this.initTarget(this.target);
  1516.         this.origAnchor = this.anchor;
  1517.     },
  1518.     
  1519.     onRender : function(ct, position){
  1520.         Ext.ToolTip.superclass.onRender.call(this, ct, position);
  1521.         this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition();
  1522.         this.anchorEl = this.el.createChild({
  1523.             cls: 'x-tip-anchor ' + this.anchorCls
  1524.         });
  1525.     },
  1526.     
  1527.     afterRender : function(){
  1528.         Ext.ToolTip.superclass.afterRender.call(this);
  1529.         this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1);
  1530.     },
  1531.     
  1532.     initTarget : function(target){
  1533.         var t;
  1534.         if((t = Ext.get(target))){
  1535.             if(this.target){
  1536.                 var tg = Ext.get(this.target);
  1537.                 this.mun(tg, 'mouseover', this.onTargetOver, this);
  1538.                 this.mun(tg, 'mouseout', this.onTargetOut, this);
  1539.                 this.mun(tg, 'mousemove', this.onMouseMove, this);
  1540.             }
  1541.             this.mon(t, {
  1542.                 mouseover: this.onTargetOver,
  1543.                 mouseout: this.onTargetOut,
  1544.                 mousemove: this.onMouseMove,
  1545.                 scope: this
  1546.             });
  1547.             this.target = t;
  1548.         }
  1549.         if(this.anchor){
  1550.             this.anchorTarget = this.target;
  1551.         }
  1552.     },
  1553.     
  1554.     onMouseMove : function(e){
  1555.         var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true;
  1556.         if (t) {
  1557.             this.targetXY = e.getXY();
  1558.             if (t === this.triggerElement) {
  1559.                 if(!this.hidden && this.trackMouse){
  1560.                     this.setPagePosition(this.getTargetXY());
  1561.                 }
  1562.             } else {
  1563.                 this.hide();
  1564.                 this.lastActive = new Date(0);
  1565.                 this.onTargetOver(e);
  1566.             }
  1567.         } else if (!this.closable && this.isVisible()) {
  1568.             this.hide();
  1569.         }
  1570.     },
  1571.     
  1572.     getTargetXY : function(){
  1573.         if(this.delegate){
  1574.             this.anchorTarget = this.triggerElement;
  1575.         }
  1576.         if(this.anchor){
  1577.             this.targetCounter++;
  1578.             var offsets = this.getOffsets(),
  1579.                 xy = (this.anchorToTarget && !this.trackMouse) ? this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) : this.targetXY,
  1580.                 dw = Ext.lib.Dom.getViewWidth() - 5,
  1581.                 dh = Ext.lib.Dom.getViewHeight() - 5,
  1582.                 de = document.documentElement,
  1583.                 bd = document.body,
  1584.                 scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5,
  1585.                 scrollY = (de.scrollTop || bd.scrollTop || 0) + 5,
  1586.                 axy = [xy[0] + offsets[0], xy[1] + offsets[1]]
  1587.                 sz = this.getSize();
  1588.                 
  1589.             this.anchorEl.removeClass(this.anchorCls);
  1590.             if(this.targetCounter < 2){
  1591.                 if(axy[0] < scrollX){
  1592.                     if(this.anchorToTarget){
  1593.                         this.defaultAlign = 'l-r';
  1594.                         if(this.mouseOffset){this.mouseOffset[0] *= -1;}
  1595.                     }
  1596.                     this.anchor = 'left';
  1597.                     return this.getTargetXY();
  1598.                 }
  1599.                 if(axy[0]+sz.width > dw){
  1600.                     if(this.anchorToTarget){
  1601.                         this.defaultAlign = 'r-l';
  1602.                         if(this.mouseOffset){this.mouseOffset[0] *= -1;}
  1603.                     }
  1604.                     this.anchor = 'right';
  1605.                     return this.getTargetXY();
  1606.                 }
  1607.                 if(axy[1] < scrollY){
  1608.                     if(this.anchorToTarget){
  1609.                         this.defaultAlign = 't-b';
  1610.                         if(this.mouseOffset){this.mouseOffset[1] *= -1;}
  1611.                     }
  1612.                     this.anchor = 'top';
  1613.                     return this.getTargetXY();
  1614.                 }
  1615.                 if(axy[1]+sz.height > dh){
  1616.                     if(this.anchorToTarget){
  1617.                         this.defaultAlign = 'b-t';
  1618.                         if(this.mouseOffset){this.mouseOffset[1] *= -1;}
  1619.                     }
  1620.                     this.anchor = 'bottom';
  1621.                     return this.getTargetXY();
  1622.                 }
  1623.             }
  1624.             this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition();
  1625.             this.anchorEl.addClass(this.anchorCls);
  1626.             this.targetCounter = 0;
  1627.             return axy;
  1628.         }else{
  1629.             var mouseOffset = this.getMouseOffset();
  1630.             return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]];
  1631.         }
  1632.     },
  1633.     getMouseOffset : function(){
  1634.         var offset = this.anchor ? [0,0] : [15,18];
  1635.         if(this.mouseOffset){
  1636.             offset[0] += this.mouseOffset[0];
  1637.             offset[1] += this.mouseOffset[1];
  1638.         }
  1639.         return offset;
  1640.     },
  1641.     
  1642.     getAnchorPosition : function(){
  1643.         if(this.anchor){
  1644.             this.tipAnchor = this.anchor.charAt(0);
  1645.         }else{
  1646.             var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(?)?$/);
  1647.             if(!m){
  1648.                throw 'AnchorTip.defaultAlign is invalid';
  1649.             }
  1650.             this.tipAnchor = m[1].charAt(0);
  1651.         }
  1652.         switch(this.tipAnchor){
  1653.             case 't': return 'top';
  1654.             case 'b': return 'bottom';
  1655.             case 'r': return 'right';
  1656.         }
  1657.         return 'left';
  1658.     },
  1659.     
  1660.     getAnchorAlign : function(){
  1661.         switch(this.anchor){
  1662.             case 'top'  : return 'tl-bl';
  1663.             case 'left' : return 'tl-tr';
  1664.             case 'right': return 'tr-tl';
  1665.             default     : return 'bl-tl';
  1666.         }
  1667.     },
  1668.     
  1669.     getOffsets : function(){
  1670.         var offsets, 
  1671.             ap = this.getAnchorPosition().charAt(0);
  1672.         if(this.anchorToTarget && !this.trackMouse){
  1673.             switch(ap){
  1674.                 case 't':
  1675.                     offsets = [0, 9];
  1676.                     break;
  1677.                 case 'b':
  1678.                     offsets = [0, -13];
  1679.                     break;
  1680.                 case 'r':
  1681.                     offsets = [-13, 0];
  1682.                     break;
  1683.                 default:
  1684.                     offsets = [9, 0];
  1685.                     break;
  1686.             }
  1687.         }else{
  1688.             switch(ap){
  1689.                 case 't':
  1690.                     offsets = [-15-this.anchorOffset, 30];
  1691.                     break;
  1692.                 case 'b':
  1693.                     offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight];
  1694.                     break;
  1695.                 case 'r':
  1696.                     offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset];
  1697.                     break;
  1698.                 default:
  1699.                     offsets = [25, -13-this.anchorOffset];
  1700.                     break;
  1701.             }
  1702.         }
  1703.         var mouseOffset = this.getMouseOffset();
  1704.         offsets[0] += mouseOffset[0];
  1705.         offsets[1] += mouseOffset[1];
  1706.         return offsets;
  1707.     },
  1708.     
  1709.     onTargetOver : function(e){
  1710.         if(this.disabled || e.within(this.target.dom, true)){
  1711.             return;
  1712.         }
  1713.         var t = e.getTarget(this.delegate);
  1714.         if (t) {
  1715.             this.triggerElement = t;
  1716.             this.clearTimer('hide');
  1717.             this.targetXY = e.getXY();
  1718.             this.delayShow();
  1719.         }
  1720.     },
  1721.     
  1722.     delayShow : function(){
  1723.         if(this.hidden && !this.showTimer){
  1724.             if(this.lastActive.getElapsed() < this.quickShowInterval){
  1725.                 this.show();
  1726.             }else{
  1727.                 this.showTimer = this.show.defer(this.showDelay, this);
  1728.             }
  1729.         }else if(!this.hidden && this.autoHide !== false){
  1730.             this.show();
  1731.         }
  1732.     },
  1733.     
  1734.     onTargetOut : function(e){
  1735.         if(this.disabled || e.within(this.target.dom, true)){
  1736.             return;
  1737.         }
  1738.         this.clearTimer('show');
  1739.         if(this.autoHide !== false){
  1740.             this.delayHide();
  1741.         }
  1742.     },
  1743.     
  1744.     delayHide : function(){
  1745.         if(!this.hidden && !this.hideTimer){
  1746.             this.hideTimer = this.hide.defer(this.hideDelay, this);
  1747.         }
  1748.     },
  1749.     
  1750.     hide: function(){
  1751.         this.clearTimer('dismiss');
  1752.         this.lastActive = new Date();
  1753.         if(this.anchorEl){
  1754.             this.anchorEl.hide();
  1755.         }
  1756.         Ext.ToolTip.superclass.hide.call(this);
  1757.         delete this.triggerElement;
  1758.     },
  1759.     
  1760.     show : function(){
  1761.         if(this.anchor){
  1762.             
  1763.             
  1764.             this.showAt([-1000,-1000]);
  1765.             this.origConstrainPosition = this.constrainPosition;
  1766.             this.constrainPosition = false;
  1767.             this.anchor = this.origAnchor;
  1768.         }
  1769.         this.showAt(this.getTargetXY());
  1770.         if(this.anchor){
  1771.             this.syncAnchor();
  1772.             this.anchorEl.show();
  1773.             this.constrainPosition = this.origConstrainPosition;
  1774.         }else{
  1775.             this.anchorEl.hide();
  1776.         }
  1777.     },
  1778.     
  1779.     showAt : function(xy){
  1780.         this.lastActive = new Date();
  1781.         this.clearTimers();
  1782.         Ext.ToolTip.superclass.showAt.call(this, xy);
  1783.         if(this.dismissDelay && this.autoHide !== false){
  1784.             this.dismissTimer = this.hide.defer(this.dismissDelay, this);
  1785.         }
  1786.         if(this.anchor && !this.anchorEl.isVisible()){
  1787.             this.syncAnchor();
  1788.             this.anchorEl.show();
  1789.         }
  1790.     },
  1791.     
  1792.     syncAnchor : function(){
  1793.         var anchorPos, targetPos, offset;
  1794.         switch(this.tipAnchor.charAt(0)){
  1795.             case 't':
  1796.                 anchorPos = 'b';
  1797.                 targetPos = 'tl';
  1798.                 offset = [20+this.anchorOffset, 2];
  1799.                 break;
  1800.             case 'r':
  1801.                 anchorPos = 'l';
  1802.                 targetPos = 'tr';
  1803.                 offset = [-2, 11+this.anchorOffset];
  1804.                 break;
  1805.             case 'b':
  1806.                 anchorPos = 't';
  1807.                 targetPos = 'bl';
  1808.                 offset = [20+this.anchorOffset, -2];
  1809.                 break;
  1810.             default:
  1811.                 anchorPos = 'r';
  1812.                 targetPos = 'tl';
  1813.                 offset = [2, 11+this.anchorOffset];
  1814.                 break;
  1815.         }
  1816.         this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset);
  1817.     },
  1818.     
  1819.     setPagePosition : function(x, y){
  1820.         Ext.ToolTip.superclass.setPagePosition.call(this, x, y);
  1821.         if(this.anchor){
  1822.             this.syncAnchor();
  1823.         }
  1824.     },
  1825.     
  1826.     clearTimer : function(name){
  1827.         name = name + 'Timer';
  1828.         clearTimeout(this[name]);
  1829.         delete this[name];
  1830.     },
  1831.     
  1832.     clearTimers : function(){
  1833.         this.clearTimer('show');
  1834.         this.clearTimer('dismiss');
  1835.         this.clearTimer('hide');
  1836.     },
  1837.     
  1838.     onShow : function(){
  1839.         Ext.ToolTip.superclass.onShow.call(this);
  1840.         Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
  1841.     },
  1842.     
  1843.     onHide : function(){
  1844.         Ext.ToolTip.superclass.onHide.call(this);
  1845.         Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
  1846.     },
  1847.     
  1848.     onDocMouseDown : function(e){
  1849.         if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){
  1850.             this.disable();
  1851.             this.enable.defer(100, this);
  1852.         }
  1853.     },
  1854.     
  1855.     onDisable : function(){
  1856.         this.clearTimers();
  1857.         this.hide();
  1858.     },
  1859.     
  1860.     adjustPosition : function(x, y){
  1861.         if(this.contstrainPosition){
  1862.             var ay = this.targetXY[1], h = this.getSize().height;
  1863.             if(y <= ay && (y+h) >= ay){
  1864.                 y = ay-h-5;
  1865.             }
  1866.         }
  1867.         return {x : x, y: y};
  1868.     },
  1869.     
  1870.     beforeDestroy : function(){
  1871.         this.clearTimers();
  1872.         Ext.destroy(this.anchorEl);
  1873.         delete this.anchorEl;
  1874.         delete this.target;
  1875.         delete this.anchorTarget;
  1876.         delete this.triggerElement;
  1877.         Ext.ToolTip.superclass.beforeDestroy.call(this);    
  1878.     },
  1879.     
  1880.     onDestroy : function(){
  1881.         Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
  1882.         Ext.ToolTip.superclass.onDestroy.call(this);
  1883.     }
  1884. });
  1885. Ext.reg('tooltip', Ext.ToolTip);
  1886. Ext.QuickTip = Ext.extend(Ext.ToolTip, {
  1887.     
  1888.     
  1889.     interceptTitles : false,
  1890.     
  1891.     tagConfig : {
  1892.         namespace : "ext",
  1893.         attribute : "qtip",
  1894.         width : "qwidth",
  1895.         target : "target",
  1896.         title : "qtitle",
  1897.         hide : "hide",
  1898.         cls : "qclass",
  1899.         align : "qalign",
  1900.         anchor : "anchor"
  1901.     },
  1902.     
  1903.     initComponent : function(){
  1904.         this.target = this.target || Ext.getDoc();
  1905.         this.targets = this.targets || {};
  1906.         Ext.QuickTip.superclass.initComponent.call(this);
  1907.     },
  1908.     
  1909.     register : function(config){
  1910.         var cs = Ext.isArray(config) ? config : arguments;
  1911.         for(var i = 0, len = cs.length; i < len; i++){
  1912.             var c = cs[i];
  1913.             var target = c.target;
  1914.             if(target){
  1915.                 if(Ext.isArray(target)){
  1916.                     for(var j = 0, jlen = target.length; j < jlen; j++){
  1917.                         this.targets[Ext.id(target[j])] = c;
  1918.                     }
  1919.                 } else{
  1920.                     this.targets[Ext.id(target)] = c;
  1921.                 }
  1922.             }
  1923.         }
  1924.     },
  1925.     
  1926.     unregister : function(el){
  1927.         delete this.targets[Ext.id(el)];
  1928.     },
  1929.     
  1930.     
  1931.     cancelShow: function(el){
  1932.         var at = this.activeTarget;
  1933.         el = Ext.get(el).dom;
  1934.         if(this.isVisible()){
  1935.             if(at && at.el == el){
  1936.                 this.hide();
  1937.             }
  1938.         }else if(at && at.el == el){
  1939.             this.clearTimer('show');
  1940.         }
  1941.     },
  1942.     
  1943.     getTipCfg: function(e) {
  1944.         var t = e.getTarget(), 
  1945.             ttp, 
  1946.             cfg;
  1947.         if(this.interceptTitles && t.title && Ext.isString(t.title)){
  1948.             ttp = t.title;
  1949.             t.qtip = ttp;
  1950.             t.removeAttribute("title");
  1951.             e.preventDefault();
  1952.         }else{
  1953.             cfg = this.tagConfig;
  1954.             ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace);
  1955.         }
  1956.         return ttp;
  1957.     },
  1958.     
  1959.     onTargetOver : function(e){
  1960.         if(this.disabled){
  1961.             return;
  1962.         }
  1963.         this.targetXY = e.getXY();
  1964.         var t = e.getTarget();
  1965.         if(!t || t.nodeType !== 1 || t == document || t == document.body){
  1966.             return;
  1967.         }
  1968.         if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){
  1969.             this.clearTimer('hide');
  1970.             this.show();
  1971.             return;
  1972.         }
  1973.         if(t && this.targets[t.id]){
  1974.             this.activeTarget = this.targets[t.id];
  1975.             this.activeTarget.el = t;
  1976.             this.anchor = this.activeTarget.anchor;
  1977.             if(this.anchor){
  1978.                 this.anchorTarget = t;
  1979.             }
  1980.             this.delayShow();
  1981.             return;
  1982.         }
  1983.         var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace;
  1984.         if(ttp = this.getTipCfg(e)){
  1985.             var autoHide = et.getAttribute(cfg.hide, ns);
  1986.             this.activeTarget = {
  1987.                 el: t,
  1988.                 text: ttp,
  1989.                 width: et.getAttribute(cfg.width, ns),
  1990.                 autoHide: autoHide != "user" && autoHide !== 'false',
  1991.                 title: et.getAttribute(cfg.title, ns),
  1992.                 cls: et.getAttribute(cfg.cls, ns),
  1993.                 align: et.getAttribute(cfg.align, ns)
  1994.                 
  1995.             };
  1996.             this.anchor = et.getAttribute(cfg.anchor, ns);
  1997.             if(this.anchor){
  1998.                 this.anchorTarget = t;
  1999.             }
  2000.             this.delayShow();
  2001.         }
  2002.     },
  2003.     
  2004.     onTargetOut : function(e){
  2005.         
  2006.         if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) {
  2007.             return;
  2008.         }
  2009.         this.clearTimer('show');
  2010.         if(this.autoHide !== false){
  2011.             this.delayHide();
  2012.         }
  2013.     },
  2014.     
  2015.     showAt : function(xy){
  2016.         var t = this.activeTarget;
  2017.         if(t){
  2018.             if(!this.rendered){
  2019.                 this.render(Ext.getBody());
  2020.                 this.activeTarget = t;
  2021.             }
  2022.             if(t.width){
  2023.                 this.setWidth(t.width);
  2024.                 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
  2025.                 this.measureWidth = false;
  2026.             } else{
  2027.                 this.measureWidth = true;
  2028.             }
  2029.             this.setTitle(t.title || '');
  2030.             this.body.update(t.text);
  2031.             this.autoHide = t.autoHide;
  2032.             this.dismissDelay = t.dismissDelay || this.dismissDelay;
  2033.             if(this.lastCls){
  2034.                 this.el.removeClass(this.lastCls);
  2035.                 delete this.lastCls;
  2036.             }
  2037.             if(t.cls){
  2038.                 this.el.addClass(t.cls);
  2039.                 this.lastCls = t.cls;
  2040.             }
  2041.             if(this.anchor){
  2042.                 this.constrainPosition = false;
  2043.             }else if(t.align){ 
  2044.                 xy = this.el.getAlignToXY(t.el, t.align);
  2045.                 this.constrainPosition = false;
  2046.             }else{
  2047.                 this.constrainPosition = true;
  2048.             }
  2049.         }
  2050.         Ext.QuickTip.superclass.showAt.call(this, xy);
  2051.     },
  2052.     
  2053.     hide: function(){
  2054.         delete this.activeTarget;
  2055.         Ext.QuickTip.superclass.hide.call(this);
  2056.     }
  2057. });
  2058. Ext.reg('quicktip', Ext.QuickTip);
  2059. Ext.QuickTips = function(){
  2060.     var tip, locks = [];
  2061.     return {
  2062.         
  2063.         init : function(autoRender){
  2064.             if(!tip){
  2065.                 if(!Ext.isReady){
  2066.                     Ext.onReady(function(){
  2067.                         Ext.QuickTips.init(autoRender);
  2068.                     });
  2069.                     return;
  2070.                 }
  2071.                 tip = new Ext.QuickTip({elements:'header,body'});
  2072.                 if(autoRender !== false){
  2073.                     tip.render(Ext.getBody());
  2074.                 }
  2075.             }
  2076.         },
  2077.         
  2078.         enable : function(){
  2079.             if(tip){
  2080.                 locks.pop();
  2081.                 if(locks.length < 1){
  2082.                     tip.enable();
  2083.                 }
  2084.             }
  2085.         },
  2086.         
  2087.         disable : function(){
  2088.             if(tip){
  2089.                 tip.disable();
  2090.             }
  2091.             locks.push(1);
  2092.         },
  2093.         
  2094.         isEnabled : function(){
  2095.             return tip !== undefined && !tip.disabled;
  2096.         },
  2097.         
  2098.         getQuickTip : function(){
  2099.             return tip;
  2100.         },
  2101.         
  2102.         register : function(){
  2103.             tip.register.apply(tip, arguments);
  2104.         },
  2105.         
  2106.         unregister : function(){
  2107.             tip.unregister.apply(tip, arguments);
  2108.         },
  2109.         
  2110.         tips :function(){
  2111.             tip.register.apply(tip, arguments);
  2112.         }
  2113.     }
  2114. }();
  2115. Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
  2116.     rootVisible : true,
  2117.     animate : Ext.enableFx,
  2118.     lines : true,
  2119.     enableDD : false,
  2120.     hlDrop : Ext.enableFx,
  2121.     pathSeparator : '/',
  2122.     
  2123.     bubbleEvents : [],
  2124.     initComponent : function(){
  2125.         Ext.tree.TreePanel.superclass.initComponent.call(this);
  2126.         if(!this.eventModel){
  2127.             this.eventModel = new Ext.tree.TreeEventModel(this);
  2128.         }
  2129.         
  2130.         var l = this.loader;
  2131.         if(!l){
  2132.             l = new Ext.tree.TreeLoader({
  2133.                 dataUrl: this.dataUrl,
  2134.                 requestMethod: this.requestMethod
  2135.             });
  2136.         }else if(Ext.isObject(l) && !l.load){
  2137.             l = new Ext.tree.TreeLoader(l);
  2138.         }
  2139.         this.loader = l;
  2140.         this.nodeHash = {};
  2141.         
  2142.         if(this.root){
  2143.             var r = this.root;
  2144.             delete this.root;
  2145.             this.setRootNode(r);
  2146.         }
  2147.         this.addEvents(
  2148.             
  2149.            'append',
  2150.            
  2151.            'remove',
  2152.            
  2153.            'movenode',
  2154.            
  2155.            'insert',
  2156.            
  2157.            'beforeappend',
  2158.            
  2159.            'beforeremove',
  2160.            
  2161.            'beforemovenode',
  2162.            
  2163.             'beforeinsert',
  2164.             
  2165.             'beforeload',
  2166.             
  2167.             'load',
  2168.             
  2169.             'textchange',
  2170.             
  2171.             'beforeexpandnode',
  2172.             
  2173.             'beforecollapsenode',
  2174.             
  2175.             'expandnode',
  2176.             
  2177.             'disabledchange',
  2178.             
  2179.             'collapsenode',
  2180.             
  2181.             'beforeclick',
  2182.             
  2183.             'click',
  2184.             
  2185.             'containerclick',
  2186.             
  2187.             'checkchange',
  2188.             
  2189.             'beforedblclick',
  2190.             
  2191.             'dblclick',
  2192.             
  2193.             'containerdblclick',
  2194.             
  2195.             'contextmenu',
  2196.             
  2197.             'containercontextmenu',
  2198.             
  2199.             'beforechildrenrendered',
  2200.            
  2201.             'startdrag',
  2202.             
  2203.             'enddrag',
  2204.             
  2205.             'dragdrop',
  2206.             
  2207.             'beforenodedrop',
  2208.             
  2209.             'nodedrop',
  2210.              
  2211.             'nodedragover'
  2212.         );
  2213.         if(this.singleExpand){
  2214.             this.on('beforeexpandnode', this.restrictExpand, this);
  2215.         }
  2216.     },
  2217.     
  2218.     proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
  2219.         if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
  2220.             ename = ename+'node';
  2221.         }
  2222.         
  2223.         return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
  2224.     },
  2225.     
  2226.     getRootNode : function(){
  2227.         return this.root;
  2228.     },
  2229.     
  2230.     setRootNode : function(node){
  2231.         Ext.destroy(this.root);
  2232.         if(!node.render){ 
  2233.             node = this.loader.createNode(node);
  2234.         }
  2235.         this.root = node;
  2236.         node.ownerTree = this;
  2237.         node.isRoot = true;
  2238.         this.registerNode(node);
  2239.         if(!this.rootVisible){
  2240.             var uiP = node.attributes.uiProvider;
  2241.             node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
  2242.         }
  2243.         if (this.innerCt) {
  2244.             this.innerCt.update('');
  2245.             this.afterRender();
  2246.         }
  2247.         return node;
  2248.     },
  2249.     
  2250.     getNodeById : function(id){
  2251.         return this.nodeHash[id];
  2252.     },
  2253.     
  2254.     registerNode : function(node){
  2255.         this.nodeHash[node.id] = node;
  2256.     },
  2257.     
  2258.     unregisterNode : function(node){
  2259.         delete this.nodeHash[node.id];
  2260.     },
  2261.     
  2262.     toString : function(){
  2263.         return '[Tree'+(this.id?' '+this.id:'')+']';
  2264.     },
  2265.     
  2266.     restrictExpand : function(node){
  2267.         var p = node.parentNode;
  2268.         if(p){
  2269.             if(p.expandedChild && p.expandedChild.parentNode == p){
  2270.                 p.expandedChild.collapse();
  2271.             }
  2272.             p.expandedChild = node;
  2273.         }
  2274.     },
  2275.     
  2276.     getChecked : function(a, startNode){
  2277.         startNode = startNode || this.root;
  2278.         var r = [];
  2279.         var f = function(){
  2280.             if(this.attributes.checked){
  2281.                 r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
  2282.             }
  2283.         };
  2284.         startNode.cascade(f);
  2285.         return r;
  2286.     },
  2287.     
  2288.     getLoader : function(){
  2289.         return this.loader;
  2290.     },
  2291.     
  2292.     expandAll : function(){
  2293.         this.root.expand(true);
  2294.     },
  2295.     
  2296.     collapseAll : function(){
  2297.         this.root.collapse(true);
  2298.     },
  2299.     
  2300.     getSelectionModel : function(){
  2301.         if(!this.selModel){
  2302.             this.selModel = new Ext.tree.DefaultSelectionModel();
  2303.         }
  2304.         return this.selModel;
  2305.     },
  2306.     
  2307.     expandPath : function(path, attr, callback){
  2308.         attr = attr || 'id';
  2309.         var keys = path.split(this.pathSeparator);
  2310.         var curNode = this.root;
  2311.         if(curNode.attributes[attr] != keys[1]){ 
  2312.             if(callback){
  2313.                 callback(false, null);
  2314.             }
  2315.             return;
  2316.         }
  2317.         var index = 1;
  2318.         var f = function(){
  2319.             if(++index == keys.length){
  2320.                 if(callback){
  2321.                     callback(true, curNode);
  2322.                 }
  2323.                 return;
  2324.             }
  2325.             var c = curNode.findChild(attr, keys[index]);
  2326.             if(!c){
  2327.                 if(callback){
  2328.                     callback(false, curNode);
  2329.                 }
  2330.                 return;
  2331.             }
  2332.             curNode = c;
  2333.             c.expand(false, false, f);
  2334.         };
  2335.         curNode.expand(false, false, f);
  2336.     },
  2337.     
  2338.     selectPath : function(path, attr, callback){
  2339.         attr = attr || 'id';
  2340.         var keys = path.split(this.pathSeparator),
  2341.             v = keys.pop();
  2342.         if(keys.length > 1){
  2343.             var f = function(success, node){
  2344.                 if(success && node){
  2345.                     var n = node.findChild(attr, v);
  2346.                     if(n){
  2347.                         n.select();
  2348.                         if(callback){
  2349.                             callback(true, n);
  2350.                         }
  2351.                     }else if(callback){
  2352.                         callback(false, n);
  2353.                     }
  2354.                 }else{
  2355.                     if(callback){
  2356.                         callback(false, n);
  2357.                     }
  2358.                 }
  2359.             };
  2360.             this.expandPath(keys.join(this.pathSeparator), attr, f);
  2361.         }else{
  2362.             this.root.select();
  2363.             if(callback){
  2364.                 callback(true, this.root);
  2365.             }
  2366.         }
  2367.     },
  2368.     
  2369.     getTreeEl : function(){
  2370.         return this.body;
  2371.     },
  2372.     
  2373.     onRender : function(ct, position){
  2374.         Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
  2375.         this.el.addClass('x-tree');
  2376.         this.innerCt = this.body.createChild({tag:'ul',
  2377.                cls:'x-tree-root-ct ' +
  2378.                (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')});
  2379.     },
  2380.     
  2381.     initEvents : function(){
  2382.         Ext.tree.TreePanel.superclass.initEvents.call(this);
  2383.         if(this.containerScroll){
  2384.             Ext.dd.ScrollManager.register(this.body);
  2385.         }
  2386.         if((this.enableDD || this.enableDrop) && !this.dropZone){
  2387.            
  2388.              this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
  2389.                ddGroup: this.ddGroup || 'TreeDD', appendOnly: this.ddAppendOnly === true
  2390.            });
  2391.         }
  2392.         if((this.enableDD || this.enableDrag) && !this.dragZone){
  2393.            
  2394.             this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
  2395.                ddGroup: this.ddGroup || 'TreeDD',
  2396.                scroll: this.ddScroll
  2397.            });
  2398.         }
  2399.         this.getSelectionModel().init(this);
  2400.     },
  2401.     
  2402.     afterRender : function(){
  2403.         Ext.tree.TreePanel.superclass.afterRender.call(this);
  2404.         this.root.render();
  2405.         if(!this.rootVisible){
  2406.             this.root.renderChildren();
  2407.         }
  2408.     },
  2409.     beforeDestroy : function(){
  2410.         if(this.rendered){
  2411.             Ext.dd.ScrollManager.unregister(this.body);
  2412.             Ext.destroy(this.dropZone, this.dragZone);
  2413.         }
  2414.         Ext.destroy(this.root, this.loader);
  2415.         this.nodeHash = this.root = this.loader = null;
  2416.         Ext.tree.TreePanel.superclass.beforeDestroy.call(this);
  2417.     }
  2418.     
  2419.     
  2420.     
  2421.     
  2422.     
  2423.     
  2424.     
  2425.     
  2426.     
  2427.     
  2428.     
  2429.     
  2430.     
  2431.     
  2432.     
  2433.     
  2434.     
  2435.     
  2436.     
  2437.     
  2438.     
  2439.     
  2440.     
  2441.     
  2442.     
  2443.     
  2444.     
  2445.     
  2446.     
  2447.     
  2448.     
  2449.     
  2450.     
  2451.     
  2452.     
  2453.     
  2454.     
  2455.     
  2456.     
  2457.     
  2458.     
  2459.     
  2460.     
  2461.     
  2462. });
  2463. Ext.tree.TreePanel.nodeTypes = {};
  2464. Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree){
  2465.     this.tree = tree;
  2466.     this.tree.on('render', this.initEvents, this);
  2467. }
  2468. Ext.tree.TreeEventModel.prototype = {
  2469.     initEvents : function(){
  2470.         var t = this.tree;
  2471.             
  2472.         if(t.trackMouseOver !== false){
  2473.             t.mon(t.innerCt, {
  2474.                 scope: this,
  2475.                 mouseover: this.delegateOver,
  2476.                 mouseout: this.delegateOut
  2477.             });
  2478.         }
  2479.         t.mon(t.getTreeEl(), {
  2480.             scope: this,
  2481.             click: this.delegateClick,
  2482.             dblclick: this.delegateDblClick,
  2483.             contextmenu: this.delegateContextMenu
  2484.         });
  2485.     },
  2486.     getNode : function(e){
  2487.         var t;
  2488.         if(t = e.getTarget('.x-tree-node-el', 10)){
  2489.             var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext');
  2490.             if(id){
  2491.                 return this.tree.getNodeById(id);
  2492.             }
  2493.         }
  2494.         return null;
  2495.     },
  2496.     getNodeTarget : function(e){
  2497.         var t = e.getTarget('.x-tree-node-icon', 1);
  2498.         if(!t){
  2499.             t = e.getTarget('.x-tree-node-el', 6);
  2500.         }
  2501.         return t;
  2502.     },
  2503.     delegateOut : function(e, t){
  2504.         if(!this.beforeEvent(e)){
  2505.             return;
  2506.         }
  2507.         if(e.getTarget('.x-tree-ec-icon', 1)){
  2508.             var n = this.getNode(e);
  2509.             this.onIconOut(e, n);
  2510.             if(n == this.lastEcOver){
  2511.                 delete this.lastEcOver;
  2512.             }
  2513.         }
  2514.         if((t = this.getNodeTarget(e)) && !e.within(t, true)){
  2515.             this.onNodeOut(e, this.getNode(e));
  2516.         }
  2517.     },
  2518.     delegateOver : function(e, t){
  2519.         if(!this.beforeEvent(e)){
  2520.             return;
  2521.         }
  2522.         if(Ext.isGecko && !this.trackingDoc){ 
  2523.             Ext.getBody().on('mouseover', this.trackExit, this);
  2524.             this.trackingDoc = true;
  2525.         }
  2526.         if(this.lastEcOver){ 
  2527.             this.onIconOut(e, this.lastEcOver);
  2528.             delete this.lastEcOver;
  2529.         }
  2530.         if(e.getTarget('.x-tree-ec-icon', 1)){
  2531.             this.lastEcOver = this.getNode(e);
  2532.             this.onIconOver(e, this.lastEcOver);
  2533.         }
  2534.         if(t = this.getNodeTarget(e)){
  2535.             this.onNodeOver(e, this.getNode(e));
  2536.         }
  2537.     },
  2538.     trackExit : function(e){
  2539.         if(this.lastOverNode && !e.within(this.lastOverNode.ui.getEl())){
  2540.             this.onNodeOut(e, this.lastOverNode);
  2541.             delete this.lastOverNode;
  2542.             Ext.getBody().un('mouseover', this.trackExit, this);
  2543.             this.trackingDoc = false;
  2544.         }
  2545.     },
  2546.     delegateClick : function(e, t){
  2547.         if(this.beforeEvent(e)){
  2548.             if(e.getTarget('input[type=checkbox]', 1)){
  2549.                 this.onCheckboxClick(e, this.getNode(e));
  2550.             }else if(e.getTarget('.x-tree-ec-icon', 1)){
  2551.                 this.onIconClick(e, this.getNode(e));
  2552.             }else if(this.getNodeTarget(e)){
  2553.                 this.onNodeClick(e, this.getNode(e));
  2554.             }else{
  2555.                 this.onContainerEvent(e, 'click');
  2556.             }
  2557.         }
  2558.     },
  2559.     delegateDblClick : function(e, t){
  2560.         if(this.beforeEvent(e)){
  2561.             if(this.getNodeTarget(e)){
  2562.                 this.onNodeDblClick(e, this.getNode(e));
  2563.             }else{
  2564.                 this.onContainerEvent(e, 'dblclick');    
  2565.             }
  2566.         }
  2567.     },
  2568.     delegateContextMenu : function(e, t){
  2569.         if(this.beforeEvent(e)){
  2570.             if(this.getNodeTarget(e)){
  2571.                 this.onNodeContextMenu(e, this.getNode(e));
  2572.             }else{
  2573.                 this.onContainerEvent(e, 'contextmenu');    
  2574.             }
  2575.         }
  2576.     },
  2577.     
  2578.     onContainerEvent: function(e, type){
  2579.         this.tree.fireEvent('container' + type, this.tree, e); 
  2580.     },
  2581.     onNodeClick : function(e, node){
  2582.         node.ui.onClick(e);
  2583.     },
  2584.     onNodeOver : function(e, node){
  2585.         this.lastOverNode = node;
  2586.         node.ui.onOver(e);
  2587.     },
  2588.     onNodeOut : function(e, node){
  2589.         node.ui.onOut(e);
  2590.     },
  2591.     onIconOver : function(e, node){
  2592.         node.ui.addClass('x-tree-ec-over');
  2593.     },
  2594.     onIconOut : function(e, node){
  2595.         node.ui.removeClass('x-tree-ec-over');
  2596.     },
  2597.     onIconClick : function(e, node){
  2598.         node.ui.ecClick(e);
  2599.     },
  2600.     onCheckboxClick : function(e, node){
  2601.         node.ui.onCheckChange(e);
  2602.     },
  2603.     onNodeDblClick : function(e, node){
  2604.         node.ui.onDblClick(e);
  2605.     },
  2606.     onNodeContextMenu : function(e, node){
  2607.         node.ui.onContextMenu(e);
  2608.     },
  2609.     beforeEvent : function(e){
  2610.         if(this.disabled){
  2611.             e.stopEvent();
  2612.             return false;
  2613.         }
  2614.         return true;
  2615.     },
  2616.     disable: function(){
  2617.         this.disabled = true;
  2618.     },
  2619.     enable: function(){
  2620.         this.disabled = false;
  2621.     }
  2622. };
  2623. Ext.tree.DefaultSelectionModel = function(config){
  2624.    this.selNode = null;
  2625.    
  2626.    this.addEvents(
  2627.        
  2628.        'selectionchange',
  2629.        
  2630.        'beforeselect'
  2631.    );
  2632.     Ext.apply(this, config);
  2633.     Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
  2634. };
  2635. Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
  2636.     init : function(tree){
  2637.         this.tree = tree;
  2638.         tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
  2639.         tree.on('click', this.onNodeClick, this);
  2640.     },
  2641.     
  2642.     onNodeClick : function(node, e){
  2643.         this.select(node);
  2644.     },
  2645.     
  2646.     
  2647.     select : function(node,  selectNextNode){
  2648.         
  2649.         if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
  2650.             return selectNextNode.call(this, node);
  2651.         }
  2652.         var last = this.selNode;
  2653.         if(node == last){
  2654.             node.ui.onSelectedChange(true);
  2655.         }else if(this.fireEvent('beforeselect', this, node, last) !== false){
  2656.             if(last && last.ui){
  2657.                 last.ui.onSelectedChange(false);
  2658.             }
  2659.             this.selNode = node;
  2660.             node.ui.onSelectedChange(true);
  2661.             this.fireEvent('selectionchange', this, node, last);
  2662.         }
  2663.         return node;
  2664.     },
  2665.     
  2666.     
  2667.     unselect : function(node, silent){
  2668.         if(this.selNode == node){
  2669.             this.clearSelections(silent);
  2670.         }    
  2671.     },
  2672.     
  2673.     
  2674.     clearSelections : function(silent){
  2675.         var n = this.selNode;
  2676.         if(n){
  2677.             n.ui.onSelectedChange(false);
  2678.             this.selNode = null;
  2679.             if(silent !== true){
  2680.                 this.fireEvent('selectionchange', this, null);
  2681.             }
  2682.         }
  2683.         return n;
  2684.     },
  2685.     
  2686.     
  2687.     getSelectedNode : function(){
  2688.         return this.selNode;    
  2689.     },
  2690.     
  2691.     
  2692.     isSelected : function(node){
  2693.         return this.selNode == node;  
  2694.     },
  2695.     
  2696.     selectPrevious : function( s){
  2697.         if(!(s = s || this.selNode || this.lastSelNode)){
  2698.             return null;
  2699.         }
  2700.         
  2701.         var ps = s.previousSibling;
  2702.         if(ps){
  2703.             if(!ps.isExpanded() || ps.childNodes.length < 1){
  2704.                 return this.select(ps, this.selectPrevious);
  2705.             } else{
  2706.                 var lc = ps.lastChild;
  2707.                 while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){
  2708.                     lc = lc.lastChild;
  2709.                 }
  2710.                 return this.select(lc, this.selectPrevious);
  2711.             }
  2712.         } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
  2713.             return this.select(s.parentNode, this.selectPrevious);
  2714.         }
  2715.         return null;
  2716.     },
  2717.     
  2718.     selectNext : function( s){
  2719.         if(!(s = s || this.selNode || this.lastSelNode)){
  2720.             return null;
  2721.         }
  2722.         
  2723.         if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){
  2724.              return this.select(s.firstChild, this.selectNext);
  2725.          }else if(s.nextSibling){
  2726.              return this.select(s.nextSibling, this.selectNext);
  2727.          }else if(s.parentNode){
  2728.             var newS = null;
  2729.             s.parentNode.bubble(function(){
  2730.                 if(this.nextSibling){
  2731.                     newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext);
  2732.                     return false;
  2733.                 }
  2734.             });
  2735.             return newS;
  2736.          }
  2737.         return null;
  2738.     },
  2739.     onKeyDown : function(e){
  2740.         var s = this.selNode || this.lastSelNode;
  2741.         
  2742.         var sm = this;
  2743.         if(!s){
  2744.             return;
  2745.         }
  2746.         var k = e.getKey();
  2747.         switch(k){
  2748.              case e.DOWN:
  2749.                  e.stopEvent();
  2750.                  this.selectNext();
  2751.              break;
  2752.              case e.UP:
  2753.                  e.stopEvent();
  2754.                  this.selectPrevious();
  2755.              break;
  2756.              case e.RIGHT:
  2757.                  e.preventDefault();
  2758.                  if(s.hasChildNodes()){
  2759.                      if(!s.isExpanded()){
  2760.                          s.expand();
  2761.                      }else if(s.firstChild){
  2762.                          this.select(s.firstChild, e);
  2763.                      }
  2764.                  }
  2765.              break;
  2766.              case e.LEFT:
  2767.                  e.preventDefault();
  2768.                  if(s.hasChildNodes() && s.isExpanded()){
  2769.                      s.collapse();
  2770.                  }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
  2771.                      this.select(s.parentNode, e);
  2772.                  }
  2773.              break;
  2774.         };
  2775.     }
  2776. });
  2777. Ext.tree.MultiSelectionModel = function(config){
  2778.    this.selNodes = [];
  2779.    this.selMap = {};
  2780.    this.addEvents(
  2781.        
  2782.        'selectionchange'
  2783.    );
  2784.     Ext.apply(this, config);
  2785.     Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
  2786. };
  2787. Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
  2788.     init : function(tree){
  2789.         this.tree = tree;
  2790.         tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
  2791.         tree.on('click', this.onNodeClick, this);
  2792.     },
  2793.     
  2794.     onNodeClick : function(node, e){
  2795.         if(e.ctrlKey && this.isSelected(node)){
  2796.             this.unselect(node);
  2797.         }else{
  2798.             this.select(node, e, e.ctrlKey);
  2799.         }
  2800.     },
  2801.     
  2802.     
  2803.     select : function(node, e, keepExisting){
  2804.         if(keepExisting !== true){
  2805.             this.clearSelections(true);
  2806.         }
  2807.         if(this.isSelected(node)){
  2808.             this.lastSelNode = node;
  2809.             return node;
  2810.         }
  2811.         this.selNodes.push(node);
  2812.         this.selMap[node.id] = node;
  2813.         this.lastSelNode = node;
  2814.         node.ui.onSelectedChange(true);
  2815.         this.fireEvent('selectionchange', this, this.selNodes);
  2816.         return node;
  2817.     },
  2818.     
  2819.     
  2820.     unselect : function(node){
  2821.         if(this.selMap[node.id]){
  2822.             node.ui.onSelectedChange(false);
  2823.             var sn = this.selNodes;
  2824.             var index = sn.indexOf(node);
  2825.             if(index != -1){
  2826.                 this.selNodes.splice(index, 1);
  2827.             }
  2828.             delete this.selMap[node.id];
  2829.             this.fireEvent('selectionchange', this, this.selNodes);
  2830.         }
  2831.     },
  2832.     
  2833.     
  2834.     clearSelections : function(suppressEvent){
  2835.         var sn = this.selNodes;
  2836.         if(sn.length > 0){
  2837.             for(var i = 0, len = sn.length; i < len; i++){
  2838.                 sn[i].ui.onSelectedChange(false);
  2839.             }
  2840.             this.selNodes = [];
  2841.             this.selMap = {};
  2842.             if(suppressEvent !== true){
  2843.                 this.fireEvent('selectionchange', this, this.selNodes);
  2844.             }
  2845.         }
  2846.     },
  2847.     
  2848.     
  2849.     isSelected : function(node){
  2850.         return this.selMap[node.id] ? true : false;  
  2851.     },
  2852.     
  2853.     
  2854.     getSelectedNodes : function(){
  2855.         return this.selNodes;    
  2856.     },
  2857.     onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
  2858.     selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
  2859.     selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
  2860. });
  2861. Ext.data.Tree = function(root){
  2862.    this.nodeHash = {};
  2863.    
  2864.    this.root = null;
  2865.    if(root){
  2866.        this.setRootNode(root);
  2867.    }
  2868.    this.addEvents(
  2869.        
  2870.        "append",
  2871.        
  2872.        "remove",
  2873.        
  2874.        "move",
  2875.        
  2876.        "insert",
  2877.        
  2878.        "beforeappend",
  2879.        
  2880.        "beforeremove",
  2881.        
  2882.        "beforemove",
  2883.        
  2884.        "beforeinsert"
  2885.    );
  2886.     Ext.data.Tree.superclass.constructor.call(this);
  2887. };
  2888. Ext.extend(Ext.data.Tree, Ext.util.Observable, {
  2889.     
  2890.     pathSeparator: "/",
  2891.     
  2892.     proxyNodeEvent : function(){
  2893.         return this.fireEvent.apply(this, arguments);
  2894.     },
  2895.     
  2896.     getRootNode : function(){
  2897.         return this.root;
  2898.     },
  2899.     
  2900.     setRootNode : function(node){
  2901.         this.root = node;
  2902.         node.ownerTree = this;
  2903.         node.isRoot = true;
  2904.         this.registerNode(node);
  2905.         return node;
  2906.     },
  2907.     
  2908.     getNodeById : function(id){
  2909.         return this.nodeHash[id];
  2910.     },
  2911.     
  2912.     registerNode : function(node){
  2913.         this.nodeHash[node.id] = node;
  2914.     },
  2915.     
  2916.     unregisterNode : function(node){
  2917.         delete this.nodeHash[node.id];
  2918.     },
  2919.     toString : function(){
  2920.         return "[Tree"+(this.id?" "+this.id:"")+"]";
  2921.     }
  2922. });
  2923. Ext.data.Node = function(attributes){
  2924.     
  2925.     this.attributes = attributes || {};
  2926.     this.leaf = this.attributes.leaf;
  2927.     
  2928.     this.id = this.attributes.id;
  2929.     if(!this.id){
  2930.         this.id = Ext.id(null, "xnode-");
  2931.         this.attributes.id = this.id;
  2932.     }
  2933.     
  2934.     this.childNodes = [];
  2935.     if(!this.childNodes.indexOf){ 
  2936.         this.childNodes.indexOf = function(o){
  2937.             for(var i = 0, len = this.length; i < len; i++){
  2938.                 if(this[i] == o){
  2939.                     return i;
  2940.                 }
  2941.             }
  2942.             return -1;
  2943.         };
  2944.     }
  2945.     
  2946.     this.parentNode = null;
  2947.     
  2948.     this.firstChild = null;
  2949.     
  2950.     this.lastChild = null;
  2951.     
  2952.     this.previousSibling = null;
  2953.     
  2954.     this.nextSibling = null;
  2955.     this.addEvents({
  2956.        
  2957.        "append" : true,
  2958.        
  2959.        "remove" : true,
  2960.        
  2961.        "move" : true,
  2962.        
  2963.        "insert" : true,
  2964.        
  2965.        "beforeappend" : true,
  2966.        
  2967.        "beforeremove" : true,
  2968.        
  2969.        "beforemove" : true,
  2970.        
  2971.        "beforeinsert" : true
  2972.    });
  2973.     this.listeners = this.attributes.listeners;
  2974.     Ext.data.Node.superclass.constructor.call(this);
  2975. };
  2976. Ext.extend(Ext.data.Node, Ext.util.Observable, {
  2977.     
  2978.     fireEvent : function(evtName){
  2979.         
  2980.         if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
  2981.             return false;
  2982.         }
  2983.         
  2984.         var ot = this.getOwnerTree();
  2985.         if(ot){
  2986.             if(ot.proxyNodeEvent.apply(ot, arguments) === false){
  2987.                 return false;
  2988.             }
  2989.         }
  2990.         return true;
  2991.     },
  2992.     
  2993.     isLeaf : function(){
  2994.         return this.leaf === true;
  2995.     },
  2996.     
  2997.     setFirstChild : function(node){
  2998.         this.firstChild = node;
  2999.     },
  3000.     
  3001.     setLastChild : function(node){
  3002.         this.lastChild = node;
  3003.     },
  3004.     
  3005.     isLast : function(){
  3006.        return (!this.parentNode ? true : this.parentNode.lastChild == this);
  3007.     },
  3008.     
  3009.     isFirst : function(){
  3010.        return (!this.parentNode ? true : this.parentNode.firstChild == this);
  3011.     },
  3012.     
  3013.     hasChildNodes : function(){
  3014.         return !this.isLeaf() && this.childNodes.length > 0;
  3015.     },
  3016.     
  3017.     
  3018.     isExpandable : function(){
  3019.         return this.attributes.expandable || this.hasChildNodes();
  3020.     },
  3021.     
  3022.     appendChild : function(node){
  3023.         var multi = false;
  3024.         if(Ext.isArray(node)){
  3025.             multi = node;
  3026.         }else if(arguments.length > 1){
  3027.             multi = arguments;
  3028.         }
  3029.         
  3030.         if(multi){
  3031.             for(var i = 0, len = multi.length; i < len; i++) {
  3032.              this.appendChild(multi[i]);
  3033.             }
  3034.         }else{
  3035.             if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
  3036.                 return false;
  3037.             }
  3038.             var index = this.childNodes.length;
  3039.             var oldParent = node.parentNode;
  3040.             
  3041.             if(oldParent){
  3042.                 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
  3043.                     return false;
  3044.                 }
  3045.                 oldParent.removeChild(node);
  3046.             }
  3047.             index = this.childNodes.length;
  3048.             if(index === 0){
  3049.                 this.setFirstChild(node);
  3050.             }
  3051.             this.childNodes.push(node);
  3052.             node.parentNode = this;
  3053.             var ps = this.childNodes[index-1];
  3054.             if(ps){
  3055.                 node.previousSibling = ps;
  3056.                 ps.nextSibling = node;
  3057.             }else{
  3058.                 node.previousSibling = null;
  3059.             }
  3060.             node.nextSibling = null;
  3061.             this.setLastChild(node);
  3062.             node.setOwnerTree(this.getOwnerTree());
  3063.             this.fireEvent("append", this.ownerTree, this, node, index);
  3064.             if(oldParent){
  3065.                 node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
  3066.             }
  3067.             return node;
  3068.         }
  3069.     },
  3070.     
  3071.     removeChild : function(node, destroy){
  3072.         var index = this.childNodes.indexOf(node);
  3073.         if(index == -1){
  3074.             return false;
  3075.         }
  3076.         if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
  3077.             return false;
  3078.         }
  3079.         
  3080.         this.childNodes.splice(index, 1);
  3081.         
  3082.         if(node.previousSibling){
  3083.             node.previousSibling.nextSibling = node.nextSibling;
  3084.         }
  3085.         if(node.nextSibling){
  3086.             node.nextSibling.previousSibling = node.previousSibling;
  3087.         }
  3088.         
  3089.         if(this.firstChild == node){
  3090.             this.setFirstChild(node.nextSibling);
  3091.         }
  3092.         if(this.lastChild == node){
  3093.             this.setLastChild(node.previousSibling);
  3094.         }
  3095.         node.clear();
  3096.         this.fireEvent("remove", this.ownerTree, this, node);
  3097.         if(destroy){
  3098.             node.destroy();
  3099.         }
  3100.         return node;
  3101.     },
  3102.     
  3103.     
  3104.     clear : function(destroy){
  3105.         
  3106.         this.setOwnerTree(null, destroy);
  3107.         this.parentNode = this.previousSibling = this.nextSibling = null
  3108.         if(destroy){
  3109.             this.firstChild = this.lastChild = null; 
  3110.         }
  3111.     },
  3112.     
  3113.     
  3114.     destroy : function(){
  3115.         this.purgeListeners();
  3116.         this.clear(true);  
  3117.         Ext.each(this.childNodes, function(n){
  3118.             n.destroy();
  3119.         });
  3120.         this.childNodes = null;
  3121.     },
  3122.     
  3123.     insertBefore : function(node, refNode){
  3124.         if(!refNode){ 
  3125.             return this.appendChild(node);
  3126.         }
  3127.         
  3128.         if(node == refNode){
  3129.             return false;
  3130.         }
  3131.         if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
  3132.             return false;
  3133.         }
  3134.         var index = this.childNodes.indexOf(refNode);
  3135.         var oldParent = node.parentNode;
  3136.         var refIndex = index;
  3137.         
  3138.         if(oldParent == this && this.childNodes.indexOf(node) < index){
  3139.             refIndex--;
  3140.         }
  3141.         
  3142.         if(oldParent){
  3143.             if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
  3144.                 return false;
  3145.             }
  3146.             oldParent.removeChild(node);
  3147.         }
  3148.         if(refIndex === 0){
  3149.             this.setFirstChild(node);
  3150.         }
  3151.         this.childNodes.splice(refIndex, 0, node);
  3152.         node.parentNode = this;
  3153.         var ps = this.childNodes[refIndex-1];
  3154.         if(ps){
  3155.             node.previousSibling = ps;
  3156.             ps.nextSibling = node;
  3157.         }else{
  3158.             node.previousSibling = null;
  3159.         }
  3160.         node.nextSibling = refNode;
  3161.         refNode.previousSibling = node;
  3162.         node.setOwnerTree(this.getOwnerTree());
  3163.         this.fireEvent("insert", this.ownerTree, this, node, refNode);
  3164.         if(oldParent){
  3165.             node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
  3166.         }
  3167.         return node;
  3168.     },
  3169.     
  3170.     remove : function(destroy){
  3171.         this.parentNode.removeChild(this, destroy);
  3172.         return this;
  3173.     },
  3174.     
  3175.     item : function(index){
  3176.         return this.childNodes[index];
  3177.     },
  3178.     
  3179.     replaceChild : function(newChild, oldChild){
  3180.         var s = oldChild ? oldChild.nextSibling : null;
  3181.         this.removeChild(oldChild);
  3182.         this.insertBefore(newChild, s);
  3183.         return oldChild;
  3184.     },
  3185.     
  3186.     indexOf : function(child){
  3187.         return this.childNodes.indexOf(child);
  3188.     },
  3189.     
  3190.     getOwnerTree : function(){
  3191.         
  3192.         if(!this.ownerTree){
  3193.             var p = this;
  3194.             while(p){
  3195.                 if(p.ownerTree){
  3196.                     this.ownerTree = p.ownerTree;
  3197.                     break;
  3198.                 }
  3199.                 p = p.parentNode;
  3200.             }
  3201.         }
  3202.         return this.ownerTree;
  3203.     },
  3204.     
  3205.     getDepth : function(){
  3206.         var depth = 0;
  3207.         var p = this;
  3208.         while(p.parentNode){
  3209.             ++depth;
  3210.             p = p.parentNode;
  3211.         }
  3212.         return depth;
  3213.     },
  3214.     
  3215.     setOwnerTree : function(tree, destroy){
  3216.         
  3217.         if(tree != this.ownerTree){
  3218.             if(this.ownerTree){
  3219.                 this.ownerTree.unregisterNode(this);
  3220.             }
  3221.             this.ownerTree = tree;
  3222.             
  3223.             if(destroy !== true){
  3224.                 Ext.each(this.childNodes, function(n){
  3225.                     n.setOwnerTree(tree);
  3226.                 });
  3227.             }
  3228.             if(tree){
  3229.                 tree.registerNode(this);
  3230.             }
  3231.         }
  3232.     },
  3233.     
  3234.     
  3235.     setId: function(id){
  3236.         if(id !== this.id){
  3237.             var t = this.ownerTree;
  3238.             if(t){
  3239.                 t.unregisterNode(this);
  3240.             }
  3241.             this.id = this.attributes.id = id;
  3242.             if(t){
  3243.                 t.registerNode(this);
  3244.             }
  3245.             this.onIdChange(id);
  3246.         }
  3247.     },
  3248.     
  3249.     
  3250.     onIdChange: Ext.emptyFn,
  3251.     
  3252.     getPath : function(attr){
  3253.         attr = attr || "id";
  3254.         var p = this.parentNode;
  3255.         var b = [this.attributes[attr]];
  3256.         while(p){
  3257.             b.unshift(p.attributes[attr]);
  3258.             p = p.parentNode;
  3259.         }
  3260.         var sep = this.getOwnerTree().pathSeparator;
  3261.         return sep + b.join(sep);
  3262.     },
  3263.     
  3264.     bubble : function(fn, scope, args){
  3265.         var p = this;
  3266.         while(p){
  3267.             if(fn.apply(scope || p, args || [p]) === false){
  3268.                 break;
  3269.             }
  3270.             p = p.parentNode;
  3271.         }
  3272.     },
  3273.     
  3274.     cascade : function(fn, scope, args){
  3275.         if(fn.apply(scope || this, args || [this]) !== false){
  3276.             var cs = this.childNodes;
  3277.             for(var i = 0, len = cs.length; i < len; i++) {
  3278.              cs[i].cascade(fn, scope, args);
  3279.             }
  3280.         }
  3281.     },
  3282.     
  3283.     eachChild : function(fn, scope, args){
  3284.         var cs = this.childNodes;
  3285.         for(var i = 0, len = cs.length; i < len; i++) {
  3286.          if(fn.apply(scope || this, args || [cs[i]]) === false){
  3287.              break;
  3288.          }
  3289.         }
  3290.     },
  3291.     
  3292.     findChild : function(attribute, value){
  3293.         var cs = this.childNodes;
  3294.         for(var i = 0, len = cs.length; i < len; i++) {
  3295.          if(cs[i].attributes[attribute] == value){
  3296.              return cs[i];
  3297.          }
  3298.         }
  3299.         return null;
  3300.     },
  3301.     
  3302.     findChildBy : function(fn, scope){
  3303.         var cs = this.childNodes;
  3304.         for(var i = 0, len = cs.length; i < len; i++) {
  3305.          if(fn.call(scope||cs[i], cs[i]) === true){
  3306.              return cs[i];
  3307.          }
  3308.         }
  3309.         return null;
  3310.     },
  3311.     
  3312.     sort : function(fn, scope){
  3313.         var cs = this.childNodes;
  3314.         var len = cs.length;
  3315.         if(len > 0){
  3316.             var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
  3317.             cs.sort(sortFn);
  3318.             for(var i = 0; i < len; i++){
  3319.                 var n = cs[i];
  3320.                 n.previousSibling = cs[i-1];
  3321.                 n.nextSibling = cs[i+1];
  3322.                 if(i === 0){
  3323.                     this.setFirstChild(n);
  3324.                 }
  3325.                 if(i == len-1){
  3326.                     this.setLastChild(n);
  3327.                 }
  3328.             }
  3329.         }
  3330.     },
  3331.     
  3332.     contains : function(node){
  3333.         return node.isAncestor(this);
  3334.     },
  3335.     
  3336.     isAncestor : function(node){
  3337.         var p = this.parentNode;
  3338.         while(p){
  3339.             if(p == node){
  3340.                 return true;
  3341.             }
  3342.             p = p.parentNode;
  3343.         }
  3344.         return false;
  3345.     },
  3346.     toString : function(){
  3347.         return "[Node"+(this.id?" "+this.id:"")+"]";
  3348.     }
  3349. });
  3350. Ext.tree.TreeNode = function(attributes){
  3351.     attributes = attributes || {};
  3352.     if(Ext.isString(attributes)){
  3353.         attributes = {text: attributes};
  3354.     }
  3355.     this.childrenRendered = false;
  3356.     this.rendered = false;
  3357.     Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
  3358.     this.expanded = attributes.expanded === true;
  3359.     this.isTarget = attributes.isTarget !== false;
  3360.     this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
  3361.     this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
  3362.     
  3363.     this.text = attributes.text;
  3364.     
  3365.     this.disabled = attributes.disabled === true;
  3366.     
  3367.     this.hidden = attributes.hidden === true;
  3368.     this.addEvents(
  3369.         
  3370.         'textchange',
  3371.         
  3372.         'beforeexpand',
  3373.         
  3374.         'beforecollapse',
  3375.         
  3376.         'expand',
  3377.         
  3378.         'disabledchange',
  3379.         
  3380.         'collapse',
  3381.         
  3382.         'beforeclick',
  3383.         
  3384.         'click',
  3385.         
  3386.         'checkchange',
  3387.         
  3388.         'beforedblclick',
  3389.         
  3390.         'dblclick',
  3391.         
  3392.         'contextmenu',
  3393.         
  3394.         'beforechildrenrendered'
  3395.     );
  3396.     var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
  3397.     
  3398.     this.ui = new uiClass(this);
  3399. };
  3400. Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
  3401.     preventHScroll : true,
  3402.     
  3403.     isExpanded : function(){
  3404.         return this.expanded;
  3405.     },
  3406.     getUI : function(){
  3407.         return this.ui;
  3408.     },
  3409.     getLoader : function(){
  3410.         var owner;
  3411.         return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader()));
  3412.     },
  3413.     
  3414.     setFirstChild : function(node){
  3415.         var of = this.firstChild;
  3416.         Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
  3417.         if(this.childrenRendered && of && node != of){
  3418.             of.renderIndent(true, true);
  3419.         }
  3420.         if(this.rendered){
  3421.             this.renderIndent(true, true);
  3422.         }
  3423.     },
  3424.     
  3425.     setLastChild : function(node){
  3426.         var ol = this.lastChild;
  3427.         Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
  3428.         if(this.childrenRendered && ol && node != ol){
  3429.             ol.renderIndent(true, true);
  3430.         }
  3431.         if(this.rendered){
  3432.             this.renderIndent(true, true);
  3433.         }
  3434.     },
  3435.     
  3436.     
  3437.     appendChild : function(n){
  3438.         if(!n.render && !Ext.isArray(n)){
  3439.             n = this.getLoader().createNode(n);
  3440.         }
  3441.         var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
  3442.         if(node && this.childrenRendered){
  3443.             node.render();
  3444.         }
  3445.         this.ui.updateExpandIcon();
  3446.         return node;
  3447.     },
  3448.     
  3449.     removeChild : function(node, destroy){
  3450.         this.ownerTree.getSelectionModel().unselect(node);
  3451.         Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
  3452.         
  3453.         if(node.ui.rendered){
  3454.             node.ui.remove();
  3455.         }
  3456.         if(this.childNodes.length < 1){
  3457.             this.collapse(false, false);
  3458.         }else{
  3459.             this.ui.updateExpandIcon();
  3460.         }
  3461.         if(!this.firstChild && !this.isHiddenRoot()) {
  3462.             this.childrenRendered = false;
  3463.         }
  3464.         return node;
  3465.     },
  3466.     
  3467.     insertBefore : function(node, refNode){
  3468.         if(!node.render){
  3469.             node = this.getLoader().createNode(node);
  3470.         }
  3471.         var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
  3472.         if(newNode && refNode && this.childrenRendered){
  3473.             node.render();
  3474.         }
  3475.         this.ui.updateExpandIcon();
  3476.         return newNode;
  3477.     },
  3478.     
  3479.     setText : function(text){
  3480.         var oldText = this.text;
  3481.         this.text = this.attributes.text = text;
  3482.         if(this.rendered){ 
  3483.             this.ui.onTextChange(this, text, oldText);
  3484.         }
  3485.         this.fireEvent('textchange', this, text, oldText);
  3486.     },
  3487.     
  3488.     select : function(){
  3489.         var t = this.getOwnerTree();
  3490.         if(t){
  3491.             t.getSelectionModel().select(this);
  3492.         }
  3493.     },
  3494.     
  3495.     unselect : function(silent){
  3496.         var t = this.getOwnerTree();
  3497.         if(t){
  3498.             t.getSelectionModel().unselect(this, silent);
  3499.         }
  3500.     },
  3501.     
  3502.     isSelected : function(){
  3503.         var t = this.getOwnerTree();
  3504.         return t ? t.getSelectionModel().isSelected(this) : false;
  3505.     },
  3506.     
  3507.     expand : function(deep, anim, callback, scope){
  3508.         if(!this.expanded){
  3509.             if(this.fireEvent('beforeexpand', this, deep, anim) === false){
  3510.                 return;
  3511.             }
  3512.             if(!this.childrenRendered){
  3513.                 this.renderChildren();
  3514.             }
  3515.             this.expanded = true;
  3516.             if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
  3517.                 this.ui.animExpand(function(){
  3518.                     this.fireEvent('expand', this);
  3519.                     this.runCallback(callback, scope || this, [this]);
  3520.                     if(deep === true){
  3521.                         this.expandChildNodes(true);
  3522.                     }
  3523.                 }.createDelegate(this));
  3524.                 return;
  3525.             }else{
  3526.                 this.ui.expand();
  3527.                 this.fireEvent('expand', this);
  3528.                 this.runCallback(callback, scope || this, [this]);
  3529.             }
  3530.         }else{
  3531.            this.runCallback(callback, scope || this, [this]);
  3532.         }
  3533.         if(deep === true){
  3534.             this.expandChildNodes(true);
  3535.         }
  3536.     },
  3537.     runCallback : function(cb, scope, args){
  3538.         if(Ext.isFunction(cb)){
  3539.             cb.apply(scope, args);
  3540.         }
  3541.     },
  3542.     isHiddenRoot : function(){
  3543.         return this.isRoot && !this.getOwnerTree().rootVisible;
  3544.     },
  3545.     
  3546.     collapse : function(deep, anim, callback, scope){
  3547.         if(this.expanded && !this.isHiddenRoot()){
  3548.             if(this.fireEvent('beforecollapse', this, deep, anim) === false){
  3549.                 return;
  3550.             }
  3551.             this.expanded = false;
  3552.             if((this.getOwnerTree().animate && anim !== false) || anim){
  3553.                 this.ui.animCollapse(function(){
  3554.                     this.fireEvent('collapse', this);
  3555.                     this.runCallback(callback, scope || this, [this]);
  3556.                     if(deep === true){
  3557.                         this.collapseChildNodes(true);
  3558.                     }
  3559.                 }.createDelegate(this));
  3560.                 return;
  3561.             }else{
  3562.                 this.ui.collapse();
  3563.                 this.fireEvent('collapse', this);
  3564.                 this.runCallback(callback, scope || this, [this]);
  3565.             }
  3566.         }else if(!this.expanded){
  3567.             this.runCallback(callback, scope || this, [this]);
  3568.         }
  3569.         if(deep === true){
  3570.             var cs = this.childNodes;
  3571.             for(var i = 0, len = cs.length; i < len; i++) {
  3572.              cs[i].collapse(true, false);
  3573.             }
  3574.         }
  3575.     },
  3576.     
  3577.     delayedExpand : function(delay){
  3578.         if(!this.expandProcId){
  3579.             this.expandProcId = this.expand.defer(delay, this);
  3580.         }
  3581.     },
  3582.     
  3583.     cancelExpand : function(){
  3584.         if(this.expandProcId){
  3585.             clearTimeout(this.expandProcId);
  3586.         }
  3587.         this.expandProcId = false;
  3588.     },
  3589.     
  3590.     toggle : function(){
  3591.         if(this.expanded){
  3592.             this.collapse();
  3593.         }else{
  3594.             this.expand();
  3595.         }
  3596.     },
  3597.     
  3598.     ensureVisible : function(callback, scope){
  3599.         var tree = this.getOwnerTree();
  3600.         tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
  3601.             var node = tree.getNodeById(this.id);  
  3602.             tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
  3603.             this.runCallback(callback, scope || this, [this]);
  3604.         }.createDelegate(this));
  3605.     },
  3606.     
  3607.     expandChildNodes : function(deep){
  3608.         var cs = this.childNodes;
  3609.         for(var i = 0, len = cs.length; i < len; i++) {
  3610.          cs[i].expand(deep);
  3611.         }
  3612.     },
  3613.     
  3614.     collapseChildNodes : function(deep){
  3615.         var cs = this.childNodes;
  3616.         for(var i = 0, len = cs.length; i < len; i++) {
  3617.          cs[i].collapse(deep);
  3618.         }
  3619.     },
  3620.     
  3621.     disable : function(){
  3622.         this.disabled = true;
  3623.         this.unselect();
  3624.         if(this.rendered && this.ui.onDisableChange){ 
  3625.             this.ui.onDisableChange(this, true);
  3626.         }
  3627.         this.fireEvent('disabledchange', this, true);
  3628.     },
  3629.     
  3630.     enable : function(){
  3631.         this.disabled = false;
  3632.         if(this.rendered && this.ui.onDisableChange){ 
  3633.             this.ui.onDisableChange(this, false);
  3634.         }
  3635.         this.fireEvent('disabledchange', this, false);
  3636.     },
  3637.     
  3638.     renderChildren : function(suppressEvent){
  3639.         if(suppressEvent !== false){
  3640.             this.fireEvent('beforechildrenrendered', this);
  3641.         }
  3642.         var cs = this.childNodes;
  3643.         for(var i = 0, len = cs.length; i < len; i++){
  3644.             cs[i].render(true);
  3645.         }
  3646.         this.childrenRendered = true;
  3647.     },
  3648.     
  3649.     sort : function(fn, scope){
  3650.         Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
  3651.         if(this.childrenRendered){
  3652.             var cs = this.childNodes;
  3653.             for(var i = 0, len = cs.length; i < len; i++){
  3654.                 cs[i].render(true);
  3655.             }
  3656.         }
  3657.     },
  3658.     
  3659.     render : function(bulkRender){
  3660.         this.ui.render(bulkRender);
  3661.         if(!this.rendered){
  3662.             
  3663.             this.getOwnerTree().registerNode(this);
  3664.             this.rendered = true;
  3665.             if(this.expanded){
  3666.                 this.expanded = false;
  3667.                 this.expand(false, false);
  3668.             }
  3669.         }
  3670.     },
  3671.     
  3672.     renderIndent : function(deep, refresh){
  3673.         if(refresh){
  3674.             this.ui.childIndent = null;
  3675.         }
  3676.         this.ui.renderIndent();
  3677.         if(deep === true && this.childrenRendered){
  3678.             var cs = this.childNodes;
  3679.             for(var i = 0, len = cs.length; i < len; i++){
  3680.                 cs[i].renderIndent(true, refresh);
  3681.             }
  3682.         }
  3683.     },
  3684.     beginUpdate : function(){
  3685.         this.childrenRendered = false;
  3686.     },
  3687.     endUpdate : function(){
  3688.         if(this.expanded && this.rendered){
  3689.             this.renderChildren();
  3690.         }
  3691.     },
  3692.     destroy : function(){
  3693.         this.unselect(true);
  3694.         Ext.tree.TreeNode.superclass.destroy.call(this);
  3695.         Ext.destroy(this.ui, this.loader);
  3696.         this.ui = this.loader = null;
  3697.     },
  3698.     
  3699.     onIdChange : function(id){
  3700.         this.ui.onIdChange(id);
  3701.     }
  3702. });
  3703. Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode;
  3704.  Ext.tree.AsyncTreeNode = function(config){
  3705.     this.loaded = config && config.loaded === true;
  3706.     this.loading = false;
  3707.     Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
  3708.     
  3709.     this.addEvents('beforeload', 'load');
  3710.     
  3711.     
  3712. };
  3713. Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
  3714.     expand : function(deep, anim, callback, scope){
  3715.         if(this.loading){ 
  3716.             var timer;
  3717.             var f = function(){
  3718.                 if(!this.loading){ 
  3719.                     clearInterval(timer);
  3720.                     this.expand(deep, anim, callback, scope);
  3721.                 }
  3722.             }.createDelegate(this);
  3723.             timer = setInterval(f, 200);
  3724.             return;
  3725.         }
  3726.         if(!this.loaded){
  3727.             if(this.fireEvent("beforeload", this) === false){
  3728.                 return;
  3729.             }
  3730.             this.loading = true;
  3731.             this.ui.beforeLoad(this);
  3732.             var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
  3733.             if(loader){
  3734.                 loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this);
  3735.                 return;
  3736.             }
  3737.         }
  3738.         Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope);
  3739.     },
  3740.     
  3741.     
  3742.     isLoading : function(){
  3743.         return this.loading;  
  3744.     },
  3745.     
  3746.     loadComplete : function(deep, anim, callback, scope){
  3747.         this.loading = false;
  3748.         this.loaded = true;
  3749.         this.ui.afterLoad(this);
  3750.         this.fireEvent("load", this);
  3751.         this.expand(deep, anim, callback, scope);
  3752.     },
  3753.     
  3754.     
  3755.     isLoaded : function(){
  3756.         return this.loaded;
  3757.     },
  3758.     
  3759.     hasChildNodes : function(){
  3760.         if(!this.isLeaf() && !this.loaded){
  3761.             return true;
  3762.         }else{
  3763.             return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
  3764.         }
  3765.     },
  3766.     
  3767.     reload : function(callback, scope){
  3768.         this.collapse(false, false);
  3769.         while(this.firstChild){
  3770.             this.removeChild(this.firstChild).destroy();
  3771.         }
  3772.         this.childrenRendered = false;
  3773.         this.loaded = false;
  3774.         if(this.isHiddenRoot()){
  3775.             this.expanded = false;
  3776.         }
  3777.         this.expand(false, false, callback, scope);
  3778.     }
  3779. });
  3780. Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode;
  3781. Ext.tree.TreeNodeUI = function(node){
  3782.     this.node = node;
  3783.     this.rendered = false;
  3784.     this.animating = false;
  3785.     this.wasLeaf = true;
  3786.     this.ecc = 'x-tree-ec-icon x-tree-elbow';
  3787.     this.emptyIcon = Ext.BLANK_IMAGE_URL;
  3788. };
  3789. Ext.tree.TreeNodeUI.prototype = {
  3790.     
  3791.     removeChild : function(node){
  3792.         if(this.rendered){
  3793.             this.ctNode.removeChild(node.ui.getEl());
  3794.         } 
  3795.     },
  3796.     
  3797.     beforeLoad : function(){
  3798.          this.addClass("x-tree-node-loading");
  3799.     },
  3800.     
  3801.     afterLoad : function(){
  3802.          this.removeClass("x-tree-node-loading");
  3803.     },
  3804.     
  3805.     onTextChange : function(node, text, oldText){
  3806.         if(this.rendered){
  3807.             this.textNode.innerHTML = text;
  3808.         }
  3809.     },
  3810.     
  3811.     onDisableChange : function(node, state){
  3812.         this.disabled = state;
  3813.         if (this.checkbox) {
  3814.             this.checkbox.disabled = state;
  3815.         }        
  3816.         if(state){
  3817.             this.addClass("x-tree-node-disabled");
  3818.         }else{
  3819.             this.removeClass("x-tree-node-disabled");
  3820.         } 
  3821.     },
  3822.     
  3823.     onSelectedChange : function(state){
  3824.         if(state){
  3825.             this.focus();
  3826.             this.addClass("x-tree-selected");
  3827.         }else{
  3828.             
  3829.             this.removeClass("x-tree-selected");
  3830.         }
  3831.     },
  3832.     
  3833.     onMove : function(tree, node, oldParent, newParent, index, refNode){
  3834.         this.childIndent = null;
  3835.         if(this.rendered){
  3836.             var targetNode = newParent.ui.getContainer();
  3837.             if(!targetNode){
  3838.                 this.holder = document.createElement("div");
  3839.                 this.holder.appendChild(this.wrap);
  3840.                 return;
  3841.             }
  3842.             var insertBefore = refNode ? refNode.ui.getEl() : null;
  3843.             if(insertBefore){
  3844.                 targetNode.insertBefore(this.wrap, insertBefore);
  3845.             }else{
  3846.                 targetNode.appendChild(this.wrap);
  3847.             }
  3848.             this.node.renderIndent(true, oldParent != newParent);
  3849.         }
  3850.     },
  3851.     addClass : function(cls){
  3852.         if(this.elNode){
  3853.             Ext.fly(this.elNode).addClass(cls);
  3854.         }
  3855.     },
  3856.     removeClass : function(cls){
  3857.         if(this.elNode){
  3858.             Ext.fly(this.elNode).removeClass(cls);  
  3859.         }
  3860.     },
  3861.     
  3862.     remove : function(){
  3863.         if(this.rendered){
  3864.             this.holder = document.createElement("div");
  3865.             this.holder.appendChild(this.wrap);
  3866.         }  
  3867.     },
  3868.     
  3869.     fireEvent : function(){
  3870.         return this.node.fireEvent.apply(this.node, arguments);  
  3871.     },
  3872.     
  3873.     initEvents : function(){
  3874.         this.node.on("move", this.onMove, this);
  3875.         if(this.node.disabled){
  3876.             this.onDisableChange(this.node, true);            
  3877.         }
  3878.         if(this.node.hidden){
  3879.             this.hide();
  3880.         }
  3881.         var ot = this.node.getOwnerTree();
  3882.         var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
  3883.         if(dd && (!this.node.isRoot || ot.rootVisible)){
  3884.             Ext.dd.Registry.register(this.elNode, {
  3885.                 node: this.node,
  3886.                 handles: this.getDDHandles(),
  3887.                 isHandle: false
  3888.             });
  3889.         }
  3890.     },
  3891.     
  3892.     getDDHandles : function(){
  3893.         return [this.iconNode, this.textNode, this.elNode];
  3894.     },
  3895.     hide : function(){
  3896.         this.node.hidden = true;
  3897.         if(this.wrap){
  3898.             this.wrap.style.display = "none";
  3899.         }
  3900.     },
  3901.     show : function(){
  3902.         this.node.hidden = false;
  3903.         if(this.wrap){
  3904.             this.wrap.style.display = "";
  3905.         } 
  3906.     },
  3907.     
  3908.     onContextMenu : function(e){
  3909.         if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
  3910.             e.preventDefault();
  3911.             this.focus();
  3912.             this.fireEvent("contextmenu", this.node, e);
  3913.         }
  3914.     },
  3915.     
  3916.     onClick : function(e){
  3917.         if(this.dropping){
  3918.             e.stopEvent();
  3919.             return;
  3920.         }
  3921.         if(this.fireEvent("beforeclick", this.node, e) !== false){
  3922.             var a = e.getTarget('a');
  3923.             if(!this.disabled && this.node.attributes.href && a){
  3924.                 this.fireEvent("click", this.node, e);
  3925.                 return;
  3926.             }else if(a && e.ctrlKey){
  3927.                 e.stopEvent();
  3928.             }
  3929.             e.preventDefault();
  3930.             if(this.disabled){
  3931.                 return;
  3932.             }
  3933.             if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){
  3934.                 this.node.toggle();
  3935.             }
  3936.             this.fireEvent("click", this.node, e);
  3937.         }else{
  3938.             e.stopEvent();
  3939.         }
  3940.     },
  3941.     
  3942.     onDblClick : function(e){
  3943.         e.preventDefault();
  3944.         if(this.disabled){
  3945.             return;
  3946.         }
  3947.         if(this.fireEvent("beforedblclick", this.node, e) !== false){
  3948.             if(this.checkbox){
  3949.                 this.toggleCheck();
  3950.             }
  3951.             if(!this.animating && this.node.isExpandable()){
  3952.                 this.node.toggle();
  3953.             }
  3954.             this.fireEvent("dblclick", this.node, e);
  3955.         }
  3956.     },
  3957.     onOver : function(e){
  3958.         this.addClass('x-tree-node-over');
  3959.     },
  3960.     onOut : function(e){
  3961.         this.removeClass('x-tree-node-over');
  3962.     },
  3963.     
  3964.     onCheckChange : function(){
  3965.         var checked = this.checkbox.checked;
  3966.         
  3967.         this.checkbox.defaultChecked = checked;        
  3968.         this.node.attributes.checked = checked;
  3969.         this.fireEvent('checkchange', this.node, checked);
  3970.     },
  3971.     
  3972.     ecClick : function(e){
  3973.         if(!this.animating && this.node.isExpandable()){
  3974.             this.node.toggle();
  3975.         }
  3976.     },
  3977.     
  3978.     startDrop : function(){
  3979.         this.dropping = true;
  3980.     },
  3981.     
  3982.     
  3983.     endDrop : function(){ 
  3984.        setTimeout(function(){
  3985.            this.dropping = false;
  3986.        }.createDelegate(this), 50); 
  3987.     },
  3988.     
  3989.     expand : function(){
  3990.         this.updateExpandIcon();
  3991.         this.ctNode.style.display = "";
  3992.     },
  3993.     
  3994.     focus : function(){
  3995.         if(!this.node.preventHScroll){
  3996.             try{this.anchor.focus();
  3997.             }catch(e){}
  3998.         }else{
  3999.             try{
  4000.                 var noscroll = this.node.getOwnerTree().getTreeEl().dom;
  4001.                 var l = noscroll.scrollLeft;
  4002.                 this.anchor.focus();
  4003.                 noscroll.scrollLeft = l;
  4004.             }catch(e){}
  4005.         }
  4006.     },
  4007.     toggleCheck : function(value){
  4008.         var cb = this.checkbox;
  4009.         if(cb){
  4010.             cb.checked = (value === undefined ? !cb.checked : value);
  4011.             this.onCheckChange();
  4012.         }
  4013.     },
  4014.     
  4015.     blur : function(){
  4016.         try{
  4017.             this.anchor.blur();
  4018.         }catch(e){} 
  4019.     },
  4020.     
  4021.     animExpand : function(callback){
  4022.         var ct = Ext.get(this.ctNode);
  4023.         ct.stopFx();
  4024.         if(!this.node.isExpandable()){
  4025.             this.updateExpandIcon();
  4026.             this.ctNode.style.display = "";
  4027.             Ext.callback(callback);
  4028.             return;
  4029.         }
  4030.         this.animating = true;
  4031.         this.updateExpandIcon();
  4032.         
  4033.         ct.slideIn('t', {
  4034.            callback : function(){
  4035.                this.animating = false;
  4036.                Ext.callback(callback);
  4037.             },
  4038.             scope: this,
  4039.             duration: this.node.ownerTree.duration || .25
  4040.         });
  4041.     },
  4042.     
  4043.     highlight : function(){
  4044.         var tree = this.node.getOwnerTree();
  4045.         Ext.fly(this.wrap).highlight(
  4046.             tree.hlColor || "C3DAF9",
  4047.             {endColor: tree.hlBaseColor}