ext-all-debug.js
上传用户:zaktkj
上传日期:2022-08-08
资源大小:5770k
文件大小:910k
源码类别:

JavaScript

开发平台:

JavaScript

  1.         if(this.hideEl !== false){
  2.             this.boundEl.show();
  3.         }
  4.     },
  5.     setValue : function(v){
  6.         this.field.setValue(v);
  7.     },
  8.     getValue : function(){
  9.         return this.field.getValue();
  10.     },
  11.     beforeDestroy : function(){
  12.         this.field.destroy();
  13.         this.field = null;
  14.     }
  15. });
  16. Ext.reg('editor', Ext.Editor);
  17. Ext.MessageBox = function(){
  18.     var dlg, opt, mask, waitTimer;
  19.     var bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl;
  20.     var buttons, activeTextEl, bwidth, iconCls = '';
  21.     var handleButton = function(button){
  22.         dlg.hide();
  23.         Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value], 1);
  24.     };
  25.     var handleHide = function(){
  26.         if(opt && opt.cls){
  27.             dlg.el.removeClass(opt.cls);
  28.         }
  29.         progressBar.reset();
  30.     };
  31.     var handleEsc = function(d, k, e){
  32.         if(opt && opt.closable !== false){
  33.             dlg.hide();
  34.         }
  35.         if(e){
  36.             e.stopEvent();
  37.         }
  38.     };
  39.     var updateButtons = function(b){
  40.         var width = 0;
  41.         if(!b){
  42.             buttons["ok"].hide();
  43.             buttons["cancel"].hide();
  44.             buttons["yes"].hide();
  45.             buttons["no"].hide();
  46.             return width;
  47.         }
  48.         dlg.footer.dom.style.display = '';
  49.         for(var k in buttons){
  50.             if(typeof buttons[k] != "function"){
  51.                 if(b[k]){
  52.                     buttons[k].show();
  53.                     buttons[k].setText(typeof b[k] == "string" ? b[k] : Ext.MessageBox.buttonText[k]);
  54.                     width += buttons[k].el.getWidth()+15;
  55.                 }else{
  56.                     buttons[k].hide();
  57.                 }
  58.             }
  59.         }
  60.         return width;
  61.     };
  62.     return {
  63.         getDialog : function(titleText){
  64.            if(!dlg){
  65.                 dlg = new Ext.Window({
  66.                     autoCreate : true,
  67.                     title:titleText,
  68.                     resizable:false,
  69.                     constrain:true,
  70.                     constrainHeader:true,
  71.                     minimizable : false,
  72.                     maximizable : false,
  73.                     stateful: false,
  74.                     modal: true,
  75.                     shim:true,
  76.                     buttonAlign:"center",
  77.                     width:400,
  78.                     height:100,
  79.                     minHeight: 80,
  80.                     plain:true,
  81.                     footer:true,
  82.                     closable:true,
  83.                     close : function(){
  84.                         if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
  85.                             handleButton("no");
  86.                         }else{
  87.                             handleButton("cancel");
  88.                         }
  89.                     }
  90.                 });
  91.                 buttons = {};
  92.                 var bt = this.buttonText;
  93.                 buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));
  94.                 buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));
  95.                 buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));
  96.                 buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));
  97.                 buttons["ok"].hideMode = buttons["yes"].hideMode = buttons["no"].hideMode = buttons["cancel"].hideMode = 'offsets';
  98.                 dlg.render(document.body);
  99.                 dlg.getEl().addClass('x-window-dlg');
  100.                 mask = dlg.mask;
  101.                 bodyEl = dlg.body.createChild({
  102.                     html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div>'
  103.                 });
  104.                 iconEl = Ext.get(bodyEl.dom.firstChild);
  105.                 var contentEl = bodyEl.dom.childNodes[1];
  106.                 msgEl = Ext.get(contentEl.firstChild);
  107.                 textboxEl = Ext.get(contentEl.childNodes[2]);
  108.                 textboxEl.enableDisplayMode();
  109.                 textboxEl.addKeyListener([10,13], function(){
  110.                     if(dlg.isVisible() && opt && opt.buttons){
  111.                         if(opt.buttons.ok){
  112.                             handleButton("ok");
  113.                         }else if(opt.buttons.yes){
  114.                             handleButton("yes");
  115.                         }
  116.                     }
  117.                 });
  118.                 textareaEl = Ext.get(contentEl.childNodes[3]);
  119.                 textareaEl.enableDisplayMode();
  120.                 progressBar = new Ext.ProgressBar({
  121.                     renderTo:bodyEl
  122.                 });
  123.                bodyEl.createChild({cls:'x-clear'});
  124.             }
  125.             return dlg;
  126.         },
  127.         updateText : function(text){
  128.             if(!dlg.isVisible() && !opt.width){
  129.                 dlg.setSize(this.maxWidth, 100);
  130.             }
  131.             msgEl.update(text || '&#160;');
  132.             var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0;
  133.             var mw = msgEl.getWidth() + msgEl.getMargins('lr');
  134.             var fw = dlg.getFrameWidth('lr');
  135.             var bw = dlg.body.getFrameWidth('lr');
  136.             if (Ext.isIE && iw > 0){
  137.                 iw += 3;
  138.             }
  139.             var w = Math.max(Math.min(opt.width || iw+mw+fw+bw, this.maxWidth),
  140.                         Math.max(opt.minWidth || this.minWidth, bwidth || 0));
  141.             if(opt.prompt === true){
  142.                 activeTextEl.setWidth(w-iw-fw-bw);
  143.             }
  144.             if(opt.progress === true || opt.wait === true){
  145.                 progressBar.setSize(w-iw-fw-bw);
  146.             }
  147.             dlg.setSize(w, 'auto').center();
  148.             return this;
  149.         },
  150.         updateProgress : function(value, progressText, msg){
  151.             progressBar.updateProgress(value, progressText);
  152.             if(msg){
  153.                 this.updateText(msg);
  154.             }
  155.             return this;
  156.         },
  157.         isVisible : function(){
  158.             return dlg && dlg.isVisible();
  159.         },
  160.         hide : function(){
  161.             if(this.isVisible()){
  162.                 dlg.hide();
  163.                 handleHide();
  164.             }
  165.             return this;
  166.         },
  167.         show : function(options){
  168.             if(this.isVisible()){
  169.                 this.hide();
  170.             }
  171.             opt = options;
  172.             var d = this.getDialog(opt.title || "&#160;");
  173.             d.setTitle(opt.title || "&#160;");
  174.             var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
  175.             d.tools.close.setDisplayed(allowClose);
  176.             activeTextEl = textboxEl;
  177.             opt.prompt = opt.prompt || (opt.multiline ? true : false);
  178.             if(opt.prompt){
  179.                 if(opt.multiline){
  180.                     textboxEl.hide();
  181.                     textareaEl.show();
  182.                     textareaEl.setHeight(typeof opt.multiline == "number" ?
  183.                         opt.multiline : this.defaultTextHeight);
  184.                     activeTextEl = textareaEl;
  185.                 }else{
  186.                     textboxEl.show();
  187.                     textareaEl.hide();
  188.                 }
  189.             }else{
  190.                 textboxEl.hide();
  191.                 textareaEl.hide();
  192.             }
  193.             activeTextEl.dom.value = opt.value || "";
  194.             if(opt.prompt){
  195.                 d.focusEl = activeTextEl;
  196.             }else{
  197.                 var bs = opt.buttons;
  198.                 var db = null;
  199.                 if(bs && bs.ok){
  200.                     db = buttons["ok"];
  201.                 }else if(bs && bs.yes){
  202.                     db = buttons["yes"];
  203.                 }
  204.                 if (db){
  205.                     d.focusEl = db;
  206.                 }
  207.             }
  208.             this.setIcon(opt.icon);
  209.             bwidth = updateButtons(opt.buttons);
  210.             progressBar.setVisible(opt.progress === true || opt.wait === true);
  211.             this.updateProgress(0, opt.progressText);
  212.             this.updateText(opt.msg);
  213.             if(opt.cls){
  214.                 d.el.addClass(opt.cls);
  215.             }
  216.             d.proxyDrag = opt.proxyDrag === true;
  217.             d.modal = opt.modal !== false;
  218.             d.mask = opt.modal !== false ? mask : false;
  219.             if(!d.isVisible()){
  220.                 document.body.appendChild(dlg.el.dom);
  221.                 d.setAnimateTarget(opt.animEl);
  222.                 d.show(opt.animEl);
  223.             }
  224.             d.on('show', function(){
  225.                 if(allowClose === true){
  226.                     d.keyMap.enable();
  227.                 }else{
  228.                     d.keyMap.disable();
  229.                 }
  230.             }, this, {single:true});
  231.             if(opt.wait === true){
  232.                 progressBar.wait(opt.waitConfig);
  233.             }
  234.             return this;
  235.         },
  236.         setIcon : function(icon){
  237.             if(icon && icon != ''){
  238.                 iconEl.removeClass('x-hidden');
  239.                 iconEl.replaceClass(iconCls, icon);
  240.                 iconCls = icon;
  241.             }else{
  242.                 iconEl.replaceClass(iconCls, 'x-hidden');
  243.                 iconCls = '';
  244.             }
  245.             return this;
  246.         },
  247.         progress : function(title, msg, progressText){
  248.             this.show({
  249.                 title : title,
  250.                 msg : msg,
  251.                 buttons: false,
  252.                 progress:true,
  253.                 closable:false,
  254.                 minWidth: this.minProgressWidth,
  255.                 progressText: progressText
  256.             });
  257.             return this;
  258.         },
  259.         wait : function(msg, title, config){
  260.             this.show({
  261.                 title : title,
  262.                 msg : msg,
  263.                 buttons: false,
  264.                 closable:false,
  265.                 wait:true,
  266.                 modal:true,
  267.                 minWidth: this.minProgressWidth,
  268.                 waitConfig: config
  269.             });
  270.             return this;
  271.         },
  272.         alert : function(title, msg, fn, scope){
  273.             this.show({
  274.                 title : title,
  275.                 msg : msg,
  276.                 buttons: this.OK,
  277.                 fn: fn,
  278.                 scope : scope
  279.             });
  280.             return this;
  281.         },
  282.         confirm : function(title, msg, fn, scope){
  283.             this.show({
  284.                 title : title,
  285.                 msg : msg,
  286.                 buttons: this.YESNO,
  287.                 fn: fn,
  288.                 scope : scope,
  289.                 icon: this.QUESTION
  290.             });
  291.             return this;
  292.         },
  293.         prompt : function(title, msg, fn, scope, multiline){
  294.             this.show({
  295.                 title : title,
  296.                 msg : msg,
  297.                 buttons: this.OKCANCEL,
  298.                 fn: fn,
  299.                 minWidth:250,
  300.                 scope : scope,
  301.                 prompt:true,
  302.                 multiline: multiline
  303.             });
  304.             return this;
  305.         },
  306.         OK : {ok:true},
  307.         CANCEL : {cancel:true},
  308.         OKCANCEL : {ok:true, cancel:true},
  309.         YESNO : {yes:true, no:true},
  310.         YESNOCANCEL : {yes:true, no:true, cancel:true},
  311.         INFO : 'ext-mb-info',
  312.         WARNING : 'ext-mb-warning',
  313.         QUESTION : 'ext-mb-question',
  314.         ERROR : 'ext-mb-error',
  315.         defaultTextHeight : 75,
  316.         maxWidth : 600,
  317.         minWidth : 100,
  318.         minProgressWidth : 250,
  319.         buttonText : {
  320.             ok : "OK",
  321.             cancel : "Cancel",
  322.             yes : "Yes",
  323.             no : "No"
  324.         }
  325.     };
  326. }();
  327. Ext.Msg = Ext.MessageBox;
  328. Ext.Tip = Ext.extend(Ext.Panel, {
  329.     minWidth : 40,
  330.     maxWidth : 300,
  331.     shadow : "sides",
  332.     defaultAlign : "tl-bl?",
  333.     autoRender: true,
  334.     quickShowInterval : 250,
  335.     frame:true,
  336.     hidden:true,
  337.     baseCls: 'x-tip',
  338.     floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
  339.     autoHeight:true,
  340.     initComponent : function(){
  341.         Ext.Tip.superclass.initComponent.call(this);
  342.         if(this.closable && !this.title){
  343.             this.elements += ',header';
  344.         }
  345.     },
  346.     afterRender : function(){
  347.         Ext.Tip.superclass.afterRender.call(this);
  348.         if(this.closable){
  349.             this.addTool({
  350.                 id: 'close',
  351.                 handler: this.hide,
  352.                 scope: this
  353.             });
  354.         }
  355.     },
  356.     showAt : function(xy){
  357.         Ext.Tip.superclass.show.call(this);
  358.         if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
  359.             var bw = this.body.getTextWidth();
  360.             if(this.title){
  361.                 bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
  362.             }
  363.             bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr");
  364.             this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
  365.         }
  366.         if(this.constrainPosition){
  367.             xy = this.el.adjustForConstraints(xy);
  368.         }
  369.         this.setPagePosition(xy[0], xy[1]);
  370.     },
  371.     showBy : function(el, pos){
  372.         if(!this.rendered){
  373.             this.render(Ext.getBody());
  374.         }
  375.         this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
  376.     },
  377.     initDraggable : function(){
  378.         this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
  379.         this.header.addClass('x-tip-draggable');
  380.     }
  381. });
  382. Ext.Tip.DD = function(tip, config){
  383.     Ext.apply(this, config);
  384.     this.tip = tip;
  385.     Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
  386.     this.setHandleElId(tip.header.id);
  387.     this.scroll = false;
  388. };
  389. Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
  390.     moveOnly:true,
  391.     scroll:false,
  392.     headerOffsets:[100, 25],
  393.     startDrag : function(){
  394.         this.tip.el.disableShadow();
  395.     },
  396.     endDrag : function(e){
  397.         this.tip.el.enableShadow(true);
  398.     }
  399. });
  400. Ext.ToolTip = Ext.extend(Ext.Tip, {
  401.     showDelay: 500,
  402.     hideDelay: 200,
  403.     dismissDelay: 5000,
  404.     mouseOffset: [15,18],
  405.     trackMouse : false,
  406.     constrainPosition: true,
  407.     initComponent: function(){
  408.         Ext.ToolTip.superclass.initComponent.call(this);
  409.         this.lastActive = new Date();
  410.         this.initTarget();
  411.     },
  412.     initTarget : function(){
  413.         if(this.target){
  414.             this.target = Ext.get(this.target);
  415.             this.target.on('mouseover', this.onTargetOver, this);
  416.             this.target.on('mouseout', this.onTargetOut, this);
  417.             this.target.on('mousemove', this.onMouseMove, this);
  418.         }
  419.     },
  420.     onMouseMove : function(e){
  421.         this.targetXY = e.getXY();
  422.         if(!this.hidden && this.trackMouse){
  423.             this.setPagePosition(this.getTargetXY());
  424.         }
  425.     },
  426.     getTargetXY : function(){
  427.         return [this.targetXY[0]+this.mouseOffset[0], this.targetXY[1]+this.mouseOffset[1]];
  428.     },
  429.     onTargetOver : function(e){
  430.         if(this.disabled || e.within(this.target.dom, true)){
  431.             return;
  432.         }
  433.         this.clearTimer('hide');
  434.         this.targetXY = e.getXY();
  435.         this.delayShow();
  436.     },
  437.     delayShow : function(){
  438.         if(this.hidden && !this.showTimer){
  439.             if(this.lastActive.getElapsed() < this.quickShowInterval){
  440.                 this.show();
  441.             }else{
  442.                 this.showTimer = this.show.defer(this.showDelay, this);
  443.             }
  444.         }else if(!this.hidden && this.autoHide !== false){
  445.             this.show();
  446.         }
  447.     },
  448.     onTargetOut : function(e){
  449.         if(this.disabled || e.within(this.target.dom, true)){
  450.             return;
  451.         }
  452.         this.clearTimer('show');
  453.         if(this.autoHide !== false){
  454.             this.delayHide();
  455.         }
  456.     },
  457.     delayHide : function(){
  458.         if(!this.hidden && !this.hideTimer){
  459.             this.hideTimer = this.hide.defer(this.hideDelay, this);
  460.         }
  461.     },
  462.     hide: function(){
  463.         this.clearTimer('dismiss');
  464.         this.lastActive = new Date();
  465.         Ext.ToolTip.superclass.hide.call(this);
  466.     },
  467.     show : function(){
  468.         this.showAt(this.getTargetXY());
  469.     },
  470.     showAt : function(xy){
  471.         this.lastActive = new Date();
  472.         this.clearTimers();
  473.         Ext.ToolTip.superclass.showAt.call(this, xy);
  474.         if(this.dismissDelay && this.autoHide !== false){
  475.             this.dismissTimer = this.hide.defer(this.dismissDelay, this);
  476.         }
  477.     },
  478.     clearTimer : function(name){
  479.         name = name + 'Timer';
  480.         clearTimeout(this[name]);
  481.         delete this[name];
  482.     },
  483.     clearTimers : function(){
  484.         this.clearTimer('show');
  485.         this.clearTimer('dismiss');
  486.         this.clearTimer('hide');
  487.     },
  488.     onShow : function(){
  489.         Ext.ToolTip.superclass.onShow.call(this);
  490.         Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
  491.     },
  492.     onHide : function(){
  493.         Ext.ToolTip.superclass.onHide.call(this);
  494.         Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
  495.     },
  496.     onDocMouseDown : function(e){
  497.         if(this.autoHide !== false && !e.within(this.el.dom)){
  498.             this.disable();
  499.             this.enable.defer(100, this);
  500.         }
  501.     },
  502.     onDisable : function(){
  503.         this.clearTimers();
  504.         this.hide();
  505.     },
  506.     adjustPosition : function(x, y){
  507.         var ay = this.targetXY[1], h = this.getSize().height;
  508.         if(this.constrainPosition && y <= ay && (y+h) >= ay){
  509.             y = ay-h-5;
  510.         }
  511.         return {x : x, y: y};
  512.     },
  513.     onDestroy : function(){
  514.         Ext.ToolTip.superclass.onDestroy.call(this);
  515.         if(this.target){
  516.             this.target.un('mouseover', this.onTargetOver, this);
  517.             this.target.un('mouseout', this.onTargetOut, this);
  518.             this.target.un('mousemove', this.onMouseMove, this);
  519.         }
  520.     }
  521. });
  522. Ext.QuickTip = Ext.extend(Ext.ToolTip, {
  523.     interceptTitles : false,
  524.     tagConfig : {
  525.         namespace : "ext",
  526.         attribute : "qtip",
  527.         width : "qwidth",
  528.         target : "target",
  529.         title : "qtitle",
  530.         hide : "hide",
  531.         cls : "qclass",
  532.         align : "qalign"
  533.     },
  534.     initComponent : function(){
  535.         this.target = this.target || Ext.getDoc();
  536.         this.targets = this.targets || {};
  537.         Ext.QuickTip.superclass.initComponent.call(this);
  538.     },
  539.     register : function(config){
  540.         var cs = Ext.isArray(config) ? config : arguments;
  541.         for(var i = 0, len = cs.length; i < len; i++){
  542.             var c = cs[i];
  543.             var target = c.target;
  544.             if(target){
  545.                 if(Ext.isArray(target)){
  546.                     for(var j = 0, jlen = target.length; j < jlen; j++){
  547.                         this.targets[Ext.id(target[j])] = c;
  548.                     }
  549.                 } else{
  550.                     this.targets[Ext.id(target)] = c;
  551.                 }
  552.             }
  553.         }
  554.     },
  555.     unregister : function(el){
  556.         delete this.targets[Ext.id(el)];
  557.     },
  558.     onTargetOver : function(e){
  559.         if(this.disabled){
  560.             return;
  561.         }
  562.         this.targetXY = e.getXY();
  563.         var t = e.getTarget();
  564.         if(!t || t.nodeType !== 1 || t == document || t == document.body){
  565.             return;
  566.         }
  567.         if(this.activeTarget && t == this.activeTarget.el){
  568.             this.clearTimer('hide');
  569.             this.show();
  570.             return;
  571.         }
  572.         if(t && this.targets[t.id]){
  573.             this.activeTarget = this.targets[t.id];
  574.             this.activeTarget.el = t;
  575.             this.delayShow();
  576.             return;
  577.         }
  578.         var ttp, et = Ext.fly(t), cfg = this.tagConfig;
  579.         var ns = cfg.namespace;
  580.         if(this.interceptTitles && t.title){
  581.             ttp = t.title;
  582.             t.qtip = ttp;
  583.             t.removeAttribute("title");
  584.             e.preventDefault();
  585.         } else{
  586.             ttp = t.qtip || et.getAttributeNS(ns, cfg.attribute);
  587.         }
  588.         if(ttp){
  589.             var autoHide = et.getAttributeNS(ns, cfg.hide);
  590.             this.activeTarget = {
  591.                 el: t,
  592.                 text: ttp,
  593.                 width: et.getAttributeNS(ns, cfg.width),
  594.                 autoHide: autoHide != "user" && autoHide !== 'false',
  595.                 title: et.getAttributeNS(ns, cfg.title),
  596.                 cls: et.getAttributeNS(ns, cfg.cls),
  597.                 align: et.getAttributeNS(ns, cfg.align)
  598.             };
  599.             this.delayShow();
  600.         }
  601.     },
  602.     onTargetOut : function(e){
  603.         this.clearTimer('show');
  604.         if(this.autoHide !== false){
  605.             this.delayHide();
  606.         }
  607.     },
  608.     showAt : function(xy){
  609.         var t = this.activeTarget;
  610.         if(t){
  611.             if(!this.rendered){
  612.                 this.render(Ext.getBody());
  613.                 this.activeTarget = t;
  614.             }
  615.             if(t.width){
  616.                 this.setWidth(t.width);
  617.                 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
  618.                 this.measureWidth = false;
  619.             } else{
  620.                 this.measureWidth = true;
  621.             }
  622.             this.setTitle(t.title || '');
  623.             this.body.update(t.text);
  624.             this.autoHide = t.autoHide;
  625.             this.dismissDelay = t.dismissDelay || this.dismissDelay;
  626.             if(this.lastCls){
  627.                 this.el.removeClass(this.lastCls);
  628.                 delete this.lastCls;
  629.             }
  630.             if(t.cls){
  631.                 this.el.addClass(t.cls);
  632.                 this.lastCls = t.cls;
  633.             }
  634.             if(t.align){
  635.                 xy = this.el.getAlignToXY(t.el, t.align);
  636.                 this.constrainPosition = false;
  637.             } else{
  638.                 this.constrainPosition = true;
  639.             }
  640.         }
  641.         Ext.QuickTip.superclass.showAt.call(this, xy);
  642.     },
  643.     hide: function(){
  644.         delete this.activeTarget;
  645.         Ext.QuickTip.superclass.hide.call(this);
  646.     }
  647. });
  648. Ext.QuickTips = function(){
  649.     var tip, locks = [];
  650.     return {
  651.         init : function(){
  652.             if(!tip){
  653.                 tip = new Ext.QuickTip({elements:'header,body'});
  654.             }
  655.         },
  656.         enable : function(){
  657.             if(tip){
  658.                 locks.pop();
  659.                 if(locks.length < 1){
  660.                     tip.enable();
  661.                 }
  662.             }
  663.         },
  664.         disable : function(){
  665.             if(tip){
  666.                 tip.disable();
  667.             }
  668.             locks.push(1);
  669.         },
  670.         isEnabled : function(){
  671.             return tip && !tip.disabled;
  672.         },
  673.         getQuickTip : function(){
  674.             return tip;
  675.         },
  676.         register : function(){
  677.             tip.register.apply(tip, arguments);
  678.         },
  679.         unregister : function(){
  680.             tip.unregister.apply(tip, arguments);
  681.         },
  682.         tips :function(){
  683.             tip.register.apply(tip, arguments);
  684.         }
  685.     }
  686. }();
  687. Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
  688.     rootVisible : true,
  689.     animate: Ext.enableFx,
  690.     lines : true,
  691.     enableDD : false,
  692.     hlDrop : Ext.enableFx,
  693.     pathSeparator: "/",
  694.     initComponent : function(){
  695.         Ext.tree.TreePanel.superclass.initComponent.call(this);
  696.         if(!this.eventModel){
  697.             this.eventModel = new Ext.tree.TreeEventModel(this);
  698.         }
  699.         this.nodeHash = {};
  700.         if(this.root){
  701.            this.setRootNode(this.root);
  702.         }
  703.         this.addEvents(
  704.            "append",
  705.            "remove",
  706.            "movenode",
  707.            "insert",
  708.            "beforeappend",
  709.            "beforeremove",
  710.            "beforemovenode",
  711.             "beforeinsert",
  712.             "beforeload",
  713.             "load",
  714.             "textchange",
  715.             "beforeexpandnode",
  716.             "beforecollapsenode",
  717.             "expandnode",
  718.             "disabledchange",
  719.             "collapsenode",
  720.             "beforeclick",
  721.             "click",
  722.             "checkchange",
  723.             "dblclick",
  724.             "contextmenu",
  725.             "beforechildrenrendered",
  726.             "startdrag",
  727.             "enddrag",
  728.             "dragdrop",
  729.             "beforenodedrop",
  730.             "nodedrop",
  731.             "nodedragover"
  732.         );
  733.         if(this.singleExpand){
  734.             this.on("beforeexpandnode", this.restrictExpand, this);
  735.         }
  736.     },
  737.     proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
  738.         if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
  739.             ename = ename+'node';
  740.         }
  741.         return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
  742.     },
  743.     getRootNode : function(){
  744.         return this.root;
  745.     },
  746.     setRootNode : function(node){
  747.         this.root = node;
  748.         node.ownerTree = this;
  749.         node.isRoot = true;
  750.         this.registerNode(node);
  751.         if(!this.rootVisible){
  752.             var uiP = node.attributes.uiProvider;
  753.             node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
  754.         }
  755.         return node;
  756.     },
  757.     getNodeById : function(id){
  758.         return this.nodeHash[id];
  759.     },
  760.     registerNode : function(node){
  761.         this.nodeHash[node.id] = node;
  762.     },
  763.     unregisterNode : function(node){
  764.         delete this.nodeHash[node.id];
  765.     },
  766.     toString : function(){
  767.         return "[Tree"+(this.id?" "+this.id:"")+"]";
  768.     },
  769.     restrictExpand : function(node){
  770.         var p = node.parentNode;
  771.         if(p){
  772.             if(p.expandedChild && p.expandedChild.parentNode == p){
  773.                 p.expandedChild.collapse();
  774.             }
  775.             p.expandedChild = node;
  776.         }
  777.     },
  778.     getChecked : function(a, startNode){
  779.         startNode = startNode || this.root;
  780.         var r = [];
  781.         var f = function(){
  782.             if(this.attributes.checked){
  783.                 r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
  784.             }
  785.         }
  786.         startNode.cascade(f);
  787.         return r;
  788.     },
  789.     getEl : function(){
  790.         return this.el;
  791.     },
  792.     getLoader : function(){
  793.         return this.loader;
  794.     },
  795.     expandAll : function(){
  796.         this.root.expand(true);
  797.     },
  798.     collapseAll : function(){
  799.         this.root.collapse(true);
  800.     },
  801.     getSelectionModel : function(){
  802.         if(!this.selModel){
  803.             this.selModel = new Ext.tree.DefaultSelectionModel();
  804.         }
  805.         return this.selModel;
  806.     },
  807.     expandPath : function(path, attr, callback){
  808.         attr = attr || "id";
  809.         var keys = path.split(this.pathSeparator);
  810.         var curNode = this.root;
  811.         if(curNode.attributes[attr] != keys[1]){
  812.             if(callback){
  813.                 callback(false, null);
  814.             }
  815.             return;
  816.         }
  817.         var index = 1;
  818.         var f = function(){
  819.             if(++index == keys.length){
  820.                 if(callback){
  821.                     callback(true, curNode);
  822.                 }
  823.                 return;
  824.             }
  825.             var c = curNode.findChild(attr, keys[index]);
  826.             if(!c){
  827.                 if(callback){
  828.                     callback(false, curNode);
  829.                 }
  830.                 return;
  831.             }
  832.             curNode = c;
  833.             c.expand(false, false, f);
  834.         };
  835.         curNode.expand(false, false, f);
  836.     },
  837.     selectPath : function(path, attr, callback){
  838.         attr = attr || "id";
  839.         var keys = path.split(this.pathSeparator);
  840.         var v = keys.pop();
  841.         if(keys.length > 0){
  842.             var f = function(success, node){
  843.                 if(success && node){
  844.                     var n = node.findChild(attr, v);
  845.                     if(n){
  846.                         n.select();
  847.                         if(callback){
  848.                             callback(true, n);
  849.                         }
  850.                     }else if(callback){
  851.                         callback(false, n);
  852.                     }
  853.                 }else{
  854.                     if(callback){
  855.                         callback(false, n);
  856.                     }
  857.                 }
  858.             };
  859.             this.expandPath(keys.join(this.pathSeparator), attr, f);
  860.         }else{
  861.             this.root.select();
  862.             if(callback){
  863.                 callback(true, this.root);
  864.             }
  865.         }
  866.     },
  867.     getTreeEl : function(){
  868.         return this.body;
  869.     },
  870.     onRender : function(ct, position){
  871.         Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
  872.         this.el.addClass('x-tree');
  873.         this.innerCt = this.body.createChild({tag:"ul",
  874.                cls:"x-tree-root-ct " +
  875.                (this.useArrows ? 'x-tree-arrows' : this.lines ? "x-tree-lines" : "x-tree-no-lines")});
  876.     },
  877.     initEvents : function(){
  878.         Ext.tree.TreePanel.superclass.initEvents.call(this);
  879.         if(this.containerScroll){
  880.             Ext.dd.ScrollManager.register(this.body);
  881.         }
  882.         if((this.enableDD || this.enableDrop) && !this.dropZone){
  883.              this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
  884.                ddGroup: this.ddGroup || "TreeDD", appendOnly: this.ddAppendOnly === true
  885.            });
  886.         }
  887.         if((this.enableDD || this.enableDrag) && !this.dragZone){
  888.             this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
  889.                ddGroup: this.ddGroup || "TreeDD",
  890.                scroll: this.ddScroll
  891.            });
  892.         }
  893.         this.getSelectionModel().init(this);
  894.     },
  895.     afterRender : function(){
  896.         Ext.tree.TreePanel.superclass.afterRender.call(this);
  897.         this.root.render();
  898.         if(!this.rootVisible){
  899.             this.root.renderChildren();
  900.         }
  901.     },
  902.     onDestroy : function(){
  903.         if(this.rendered){
  904.             this.body.removeAllListeners();
  905.             Ext.dd.ScrollManager.unregister(this.body);
  906.             if(this.dropZone){
  907.                 this.dropZone.unreg();
  908.             }
  909.             if(this.dragZone){
  910.                this.dragZone.unreg();
  911.             }
  912.         }
  913.         this.root.destroy();
  914.         this.nodeHash = null;
  915.         Ext.tree.TreePanel.superclass.onDestroy.call(this);
  916.     }
  917. });
  918. Ext.reg('treepanel', Ext.tree.TreePanel);
  919. Ext.tree.TreeEventModel = function(tree){
  920.     this.tree = tree;
  921.     this.tree.on('render', this.initEvents, this);
  922. }
  923. Ext.tree.TreeEventModel.prototype = {
  924.     initEvents : function(){
  925.         var el = this.tree.getTreeEl();
  926.         el.on('click', this.delegateClick, this);
  927.         if(this.tree.trackMouseOver !== false){
  928.             el.on('mouseover', this.delegateOver, this);
  929.             el.on('mouseout', this.delegateOut, this);
  930.         }
  931.         el.on('dblclick', this.delegateDblClick, this);
  932.         el.on('contextmenu', this.delegateContextMenu, this);
  933.     },
  934.     getNode : function(e){
  935.         var t;
  936.         if(t = e.getTarget('.x-tree-node-el', 10)){
  937.             var id = Ext.fly(t, '_treeEvents').getAttributeNS('ext', 'tree-node-id');
  938.             if(id){
  939.                 return this.tree.getNodeById(id);
  940.             }
  941.         }
  942.         return null;
  943.     },
  944.     getNodeTarget : function(e){
  945.         var t = e.getTarget('.x-tree-node-icon', 1);
  946.         if(!t){
  947.             t = e.getTarget('.x-tree-node-el', 6);
  948.         }
  949.         return t;
  950.     },
  951.     delegateOut : function(e, t){
  952.         if(!this.beforeEvent(e)){
  953.             return;
  954.         }
  955.         if(e.getTarget('.x-tree-ec-icon', 1)){
  956.             var n = this.getNode(e);
  957.             this.onIconOut(e, n);
  958.             if(n == this.lastEcOver){
  959.                 delete this.lastEcOver;
  960.             }
  961.         }
  962.         if((t = this.getNodeTarget(e)) && !e.within(t, true)){
  963.             this.onNodeOut(e, this.getNode(e));
  964.         }
  965.     },
  966.     delegateOver : function(e, t){
  967.         if(!this.beforeEvent(e)){
  968.             return;
  969.         }
  970.         if(this.lastEcOver){
  971.             this.onIconOut(e, this.lastEcOver);
  972.             delete this.lastEcOver;
  973.         }
  974.         if(e.getTarget('.x-tree-ec-icon', 1)){
  975.             this.lastEcOver = this.getNode(e);
  976.             this.onIconOver(e, this.lastEcOver);
  977.         }
  978.         if(t = this.getNodeTarget(e)){
  979.             this.onNodeOver(e, this.getNode(e));
  980.         }
  981.     },
  982.     delegateClick : function(e, t){
  983.         if(!this.beforeEvent(e)){
  984.             return;
  985.         }
  986.         if(e.getTarget('input[type=checkbox]', 1)){
  987.             this.onCheckboxClick(e, this.getNode(e));
  988.         }
  989.         else if(e.getTarget('.x-tree-ec-icon', 1)){
  990.             this.onIconClick(e, this.getNode(e));
  991.         }
  992.         else if(this.getNodeTarget(e)){
  993.             this.onNodeClick(e, this.getNode(e));
  994.         }
  995.     },
  996.     delegateDblClick : function(e, t){
  997.         if(this.beforeEvent(e) && this.getNodeTarget(e)){
  998.             this.onNodeDblClick(e, this.getNode(e));
  999.         }
  1000.     },
  1001.     delegateContextMenu : function(e, t){
  1002.         if(this.beforeEvent(e) && this.getNodeTarget(e)){
  1003.             this.onNodeContextMenu(e, this.getNode(e));
  1004.         }
  1005.     },
  1006.     onNodeClick : function(e, node){
  1007.         node.ui.onClick(e);
  1008.     },
  1009.     onNodeOver : function(e, node){
  1010.         node.ui.onOver(e);
  1011.     },
  1012.     onNodeOut : function(e, node){
  1013.         node.ui.onOut(e);
  1014.     },
  1015.     onIconOver : function(e, node){
  1016.         node.ui.addClass('x-tree-ec-over');
  1017.     },
  1018.     onIconOut : function(e, node){
  1019.         node.ui.removeClass('x-tree-ec-over');
  1020.     },
  1021.     onIconClick : function(e, node){
  1022.         node.ui.ecClick(e);
  1023.     },
  1024.     onCheckboxClick : function(e, node){
  1025.         node.ui.onCheckChange(e);
  1026.     },
  1027.     onNodeDblClick : function(e, node){
  1028.         node.ui.onDblClick(e);
  1029.     },
  1030.     onNodeContextMenu : function(e, node){
  1031.         node.ui.onContextMenu(e);
  1032.     },
  1033.     beforeEvent : function(e){
  1034.         if(this.disabled){
  1035.             e.stopEvent();
  1036.             return false;
  1037.         }
  1038.         return true;
  1039.     },
  1040.     disable: function(){
  1041.         this.disabled = true;
  1042.     },
  1043.     enable: function(){
  1044.         this.disabled = false;
  1045.     }
  1046. };
  1047. Ext.tree.DefaultSelectionModel = function(config){
  1048.    this.selNode = null;
  1049.    this.addEvents(
  1050.        "selectionchange",
  1051.        "beforeselect"
  1052.    );
  1053.     Ext.apply(this, config);
  1054.     Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
  1055. };
  1056. Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
  1057.     init : function(tree){
  1058.         this.tree = tree;
  1059.         tree.getTreeEl().on("keydown", this.onKeyDown, this);
  1060.         tree.on("click", this.onNodeClick, this);
  1061.     },
  1062.     onNodeClick : function(node, e){
  1063.         this.select(node);
  1064.     },
  1065.     select : function(node){
  1066.         var last = this.selNode;
  1067.         if(last != node && this.fireEvent('beforeselect', this, node, last) !== false){
  1068.             if(last){
  1069.                 last.ui.onSelectedChange(false);
  1070.             }
  1071.             this.selNode = node;
  1072.             node.ui.onSelectedChange(true);
  1073.             this.fireEvent("selectionchange", this, node, last);
  1074.         }
  1075.         return node;
  1076.     },
  1077.     unselect : function(node){
  1078.         if(this.selNode == node){
  1079.             this.clearSelections();
  1080.         }
  1081.     },
  1082.     clearSelections : function(){
  1083.         var n = this.selNode;
  1084.         if(n){
  1085.             n.ui.onSelectedChange(false);
  1086.             this.selNode = null;
  1087.             this.fireEvent("selectionchange", this, null);
  1088.         }
  1089.         return n;
  1090.     },
  1091.     getSelectedNode : function(){
  1092.         return this.selNode;
  1093.     },
  1094.     isSelected : function(node){
  1095.         return this.selNode == node;
  1096.     },
  1097.     selectPrevious : function(){
  1098.         var s = this.selNode || this.lastSelNode;
  1099.         if(!s){
  1100.             return null;
  1101.         }
  1102.         var ps = s.previousSibling;
  1103.         if(ps){
  1104.             if(!ps.isExpanded() || ps.childNodes.length < 1){
  1105.                 return this.select(ps);
  1106.             } else{
  1107.                 var lc = ps.lastChild;
  1108.                 while(lc && lc.isExpanded() && lc.childNodes.length > 0){
  1109.                     lc = lc.lastChild;
  1110.                 }
  1111.                 return this.select(lc);
  1112.             }
  1113.         } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
  1114.             return this.select(s.parentNode);
  1115.         }
  1116.         return null;
  1117.     },
  1118.     selectNext : function(){
  1119.         var s = this.selNode || this.lastSelNode;
  1120.         if(!s){
  1121.             return null;
  1122.         }
  1123.         if(s.firstChild && s.isExpanded()){
  1124.              return this.select(s.firstChild);
  1125.          }else if(s.nextSibling){
  1126.              return this.select(s.nextSibling);
  1127.          }else if(s.parentNode){
  1128.             var newS = null;
  1129.             s.parentNode.bubble(function(){
  1130.                 if(this.nextSibling){
  1131.                     newS = this.getOwnerTree().selModel.select(this.nextSibling);
  1132.                     return false;
  1133.                 }
  1134.             });
  1135.             return newS;
  1136.          }
  1137.         return null;
  1138.     },
  1139.     onKeyDown : function(e){
  1140.         var s = this.selNode || this.lastSelNode;
  1141.         var sm = this;
  1142.         if(!s){
  1143.             return;
  1144.         }
  1145.         var k = e.getKey();
  1146.         switch(k){
  1147.              case e.DOWN:
  1148.                  e.stopEvent();
  1149.                  this.selectNext();
  1150.              break;
  1151.              case e.UP:
  1152.                  e.stopEvent();
  1153.                  this.selectPrevious();
  1154.              break;
  1155.              case e.RIGHT:
  1156.                  e.preventDefault();
  1157.                  if(s.hasChildNodes()){
  1158.                      if(!s.isExpanded()){
  1159.                          s.expand();
  1160.                      }else if(s.firstChild){
  1161.                          this.select(s.firstChild, e);
  1162.                      }
  1163.                  }
  1164.              break;
  1165.              case e.LEFT:
  1166.                  e.preventDefault();
  1167.                  if(s.hasChildNodes() && s.isExpanded()){
  1168.                      s.collapse();
  1169.                  }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
  1170.                      this.select(s.parentNode, e);
  1171.                  }
  1172.              break;
  1173.         };
  1174.     }
  1175. });
  1176. Ext.tree.MultiSelectionModel = function(config){
  1177.    this.selNodes = [];
  1178.    this.selMap = {};
  1179.    this.addEvents(
  1180.        "selectionchange"
  1181.    );
  1182.     Ext.apply(this, config);
  1183.     Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
  1184. };
  1185. Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
  1186.     init : function(tree){
  1187.         this.tree = tree;
  1188.         tree.getTreeEl().on("keydown", this.onKeyDown, this);
  1189.         tree.on("click", this.onNodeClick, this);
  1190.     },
  1191.     onNodeClick : function(node, e){
  1192.         this.select(node, e, e.ctrlKey);
  1193.     },
  1194.     select : function(node, e, keepExisting){
  1195.         if(keepExisting !== true){
  1196.             this.clearSelections(true);
  1197.         }
  1198.         if(this.isSelected(node)){
  1199.             this.lastSelNode = node;
  1200.             return node;
  1201.         }
  1202.         this.selNodes.push(node);
  1203.         this.selMap[node.id] = node;
  1204.         this.lastSelNode = node;
  1205.         node.ui.onSelectedChange(true);
  1206.         this.fireEvent("selectionchange", this, this.selNodes);
  1207.         return node;
  1208.     },
  1209.     unselect : function(node){
  1210.         if(this.selMap[node.id]){
  1211.             node.ui.onSelectedChange(false);
  1212.             var sn = this.selNodes;
  1213.             var index = sn.indexOf(node);
  1214.             if(index != -1){
  1215.                 this.selNodes.splice(index, 1);
  1216.             }
  1217.             delete this.selMap[node.id];
  1218.             this.fireEvent("selectionchange", this, this.selNodes);
  1219.         }
  1220.     },
  1221.     clearSelections : function(suppressEvent){
  1222.         var sn = this.selNodes;
  1223.         if(sn.length > 0){
  1224.             for(var i = 0, len = sn.length; i < len; i++){
  1225.                 sn[i].ui.onSelectedChange(false);
  1226.             }
  1227.             this.selNodes = [];
  1228.             this.selMap = {};
  1229.             if(suppressEvent !== true){
  1230.                 this.fireEvent("selectionchange", this, this.selNodes);
  1231.             }
  1232.         }
  1233.     },
  1234.     isSelected : function(node){
  1235.         return this.selMap[node.id] ? true : false;
  1236.     },
  1237.     getSelectedNodes : function(){
  1238.         return this.selNodes;
  1239.     },
  1240.     onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
  1241.     selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
  1242.     selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
  1243. });
  1244. Ext.tree.TreeNode = function(attributes){
  1245.     attributes = attributes || {};
  1246.     if(typeof attributes == "string"){
  1247.         attributes = {text: attributes};
  1248.     }
  1249.     this.childrenRendered = false;
  1250.     this.rendered = false;
  1251.     Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
  1252.     this.expanded = attributes.expanded === true;
  1253.     this.isTarget = attributes.isTarget !== false;
  1254.     this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
  1255.     this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
  1256.     this.text = attributes.text;
  1257.     this.disabled = attributes.disabled === true;
  1258.     this.addEvents(
  1259.         "textchange",
  1260.         "beforeexpand",
  1261.         "beforecollapse",
  1262.         "expand",
  1263.         "disabledchange",
  1264.         "collapse",
  1265.         "beforeclick",
  1266.         "click",
  1267.         "checkchange",
  1268.         "dblclick",
  1269.         "contextmenu",
  1270.         "beforechildrenrendered"
  1271.     );
  1272.     var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
  1273.     this.ui = new uiClass(this);
  1274. };
  1275. Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
  1276.     preventHScroll: true,
  1277.     isExpanded : function(){
  1278.         return this.expanded;
  1279.     },
  1280.     getUI : function(){
  1281.         return this.ui;
  1282.     },
  1283.     setFirstChild : function(node){
  1284.         var of = this.firstChild;
  1285.         Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
  1286.         if(this.childrenRendered && of && node != of){
  1287.             of.renderIndent(true, true);
  1288.         }
  1289.         if(this.rendered){
  1290.             this.renderIndent(true, true);
  1291.         }
  1292.     },
  1293.     setLastChild : function(node){
  1294.         var ol = this.lastChild;
  1295.         Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
  1296.         if(this.childrenRendered && ol && node != ol){
  1297.             ol.renderIndent(true, true);
  1298.         }
  1299.         if(this.rendered){
  1300.             this.renderIndent(true, true);
  1301.         }
  1302.     },
  1303.     appendChild : function(){
  1304.         var node = Ext.tree.TreeNode.superclass.appendChild.apply(this, arguments);
  1305.         if(node && this.childrenRendered){
  1306.             node.render();
  1307.         }
  1308.         this.ui.updateExpandIcon();
  1309.         return node;
  1310.     },
  1311.     removeChild : function(node){
  1312.         this.ownerTree.getSelectionModel().unselect(node);
  1313.         Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
  1314.         if(this.childrenRendered){
  1315.             node.ui.remove();
  1316.         }
  1317.         if(this.childNodes.length < 1){
  1318.             this.collapse(false, false);
  1319.         }else{
  1320.             this.ui.updateExpandIcon();
  1321.         }
  1322.         if(!this.firstChild && !this.isHiddenRoot()) {
  1323.             this.childrenRendered = false;
  1324.         }
  1325.         return node;
  1326.     },
  1327.     insertBefore : function(node, refNode){
  1328.         var newNode = Ext.tree.TreeNode.superclass.insertBefore.apply(this, arguments);
  1329.         if(newNode && refNode && this.childrenRendered){
  1330.             node.render();
  1331.         }
  1332.         this.ui.updateExpandIcon();
  1333.         return newNode;
  1334.     },
  1335.     setText : function(text){
  1336.         var oldText = this.text;
  1337.         this.text = text;
  1338.         this.attributes.text = text;
  1339.         if(this.rendered){
  1340.             this.ui.onTextChange(this, text, oldText);
  1341.         }
  1342.         this.fireEvent("textchange", this, text, oldText);
  1343.     },
  1344.     select : function(){
  1345.         this.getOwnerTree().getSelectionModel().select(this);
  1346.     },
  1347.     unselect : function(){
  1348.         this.getOwnerTree().getSelectionModel().unselect(this);
  1349.     },
  1350.     isSelected : function(){
  1351.         return this.getOwnerTree().getSelectionModel().isSelected(this);
  1352.     },
  1353.     expand : function(deep, anim, callback){
  1354.         if(!this.expanded){
  1355.             if(this.fireEvent("beforeexpand", this, deep, anim) === false){
  1356.                 return;
  1357.             }
  1358.             if(!this.childrenRendered){
  1359.                 this.renderChildren();
  1360.             }
  1361.             this.expanded = true;
  1362.             if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
  1363.                 this.ui.animExpand(function(){
  1364.                     this.fireEvent("expand", this);
  1365.                     if(typeof callback == "function"){
  1366.                         callback(this);
  1367.                     }
  1368.                     if(deep === true){
  1369.                         this.expandChildNodes(true);
  1370.                     }
  1371.                 }.createDelegate(this));
  1372.                 return;
  1373.             }else{
  1374.                 this.ui.expand();
  1375.                 this.fireEvent("expand", this);
  1376.                 if(typeof callback == "function"){
  1377.                     callback(this);
  1378.                 }
  1379.             }
  1380.         }else{
  1381.            if(typeof callback == "function"){
  1382.                callback(this);
  1383.            }
  1384.         }
  1385.         if(deep === true){
  1386.             this.expandChildNodes(true);
  1387.         }
  1388.     },
  1389.     isHiddenRoot : function(){
  1390.         return this.isRoot && !this.getOwnerTree().rootVisible;
  1391.     },
  1392.     collapse : function(deep, anim){
  1393.         if(this.expanded && !this.isHiddenRoot()){
  1394.             if(this.fireEvent("beforecollapse", this, deep, anim) === false){
  1395.                 return;
  1396.             }
  1397.             this.expanded = false;
  1398.             if((this.getOwnerTree().animate && anim !== false) || anim){
  1399.                 this.ui.animCollapse(function(){
  1400.                     this.fireEvent("collapse", this);
  1401.                     if(deep === true){
  1402.                         this.collapseChildNodes(true);
  1403.                     }
  1404.                 }.createDelegate(this));
  1405.                 return;
  1406.             }else{
  1407.                 this.ui.collapse();
  1408.                 this.fireEvent("collapse", this);
  1409.             }
  1410.         }
  1411.         if(deep === true){
  1412.             var cs = this.childNodes;
  1413.             for(var i = 0, len = cs.length; i < len; i++) {
  1414.                 cs[i].collapse(true, false);
  1415.             }
  1416.         }
  1417.     },
  1418.     delayedExpand : function(delay){
  1419.         if(!this.expandProcId){
  1420.             this.expandProcId = this.expand.defer(delay, this);
  1421.         }
  1422.     },
  1423.     cancelExpand : function(){
  1424.         if(this.expandProcId){
  1425.             clearTimeout(this.expandProcId);
  1426.         }
  1427.         this.expandProcId = false;
  1428.     },
  1429.     toggle : function(){
  1430.         if(this.expanded){
  1431.             this.collapse();
  1432.         }else{
  1433.             this.expand();
  1434.         }
  1435.     },
  1436.     ensureVisible : function(callback){
  1437.         var tree = this.getOwnerTree();
  1438.         tree.expandPath(this.parentNode.getPath(), false, function(){
  1439.             var node = tree.getNodeById(this.id);
  1440.             tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
  1441.             Ext.callback(callback);
  1442.         }.createDelegate(this));
  1443.     },
  1444.     expandChildNodes : function(deep){
  1445.         var cs = this.childNodes;
  1446.         for(var i = 0, len = cs.length; i < len; i++) {
  1447.             cs[i].expand(deep);
  1448.         }
  1449.     },
  1450.     collapseChildNodes : function(deep){
  1451.         var cs = this.childNodes;
  1452.         for(var i = 0, len = cs.length; i < len; i++) {
  1453.             cs[i].collapse(deep);
  1454.         }
  1455.     },
  1456.     disable : function(){
  1457.         this.disabled = true;
  1458.         this.unselect();
  1459.         if(this.rendered && this.ui.onDisableChange){
  1460.             this.ui.onDisableChange(this, true);
  1461.         }
  1462.         this.fireEvent("disabledchange", this, true);
  1463.     },
  1464.     enable : function(){
  1465.         this.disabled = false;
  1466.         if(this.rendered && this.ui.onDisableChange){
  1467.             this.ui.onDisableChange(this, false);
  1468.         }
  1469.         this.fireEvent("disabledchange", this, false);
  1470.     },
  1471.     renderChildren : function(suppressEvent){
  1472.         if(suppressEvent !== false){
  1473.             this.fireEvent("beforechildrenrendered", this);
  1474.         }
  1475.         var cs = this.childNodes;
  1476.         for(var i = 0, len = cs.length; i < len; i++){
  1477.             cs[i].render(true);
  1478.         }
  1479.         this.childrenRendered = true;
  1480.     },
  1481.     sort : function(fn, scope){
  1482.         Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
  1483.         if(this.childrenRendered){
  1484.             var cs = this.childNodes;
  1485.             for(var i = 0, len = cs.length; i < len; i++){
  1486.                 cs[i].render(true);
  1487.             }
  1488.         }
  1489.     },
  1490.     render : function(bulkRender){
  1491.         this.ui.render(bulkRender);
  1492.         if(!this.rendered){
  1493.             this.getOwnerTree().registerNode(this);
  1494.             this.rendered = true;
  1495.             if(this.expanded){
  1496.                 this.expanded = false;
  1497.                 this.expand(false, false);
  1498.             }
  1499.         }
  1500.     },
  1501.     renderIndent : function(deep, refresh){
  1502.         if(refresh){
  1503.             this.ui.childIndent = null;
  1504.         }
  1505.         this.ui.renderIndent();
  1506.         if(deep === true && this.childrenRendered){
  1507.             var cs = this.childNodes;
  1508.             for(var i = 0, len = cs.length; i < len; i++){
  1509.                 cs[i].renderIndent(true, refresh);
  1510.             }
  1511.         }
  1512.     },
  1513.     beginUpdate : function(){
  1514.         this.childrenRendered = false;
  1515.     },
  1516.     endUpdate : function(){
  1517.         if(this.expanded){
  1518.             this.renderChildren();
  1519.         }
  1520.     },
  1521.     destroy : function(){
  1522.         for(var i = 0,l = this.childNodes.length; i < l; i++){
  1523.             this.childNodes[i].destroy();
  1524.         }
  1525.         this.childNodes = null;
  1526.         if(this.ui.destroy){
  1527.             this.ui.destroy();
  1528.         }
  1529.     }
  1530. });
  1531.  Ext.tree.AsyncTreeNode = function(config){
  1532.     this.loaded = false;
  1533.     this.loading = false;
  1534.     Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
  1535.     this.addEvents('beforeload', 'load');
  1536. };
  1537. Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
  1538.     expand : function(deep, anim, callback){
  1539.         if(this.loading){
  1540.             var timer;
  1541.             var f = function(){
  1542.                 if(!this.loading){
  1543.                     clearInterval(timer);
  1544.                     this.expand(deep, anim, callback);
  1545.                 }
  1546.             }.createDelegate(this);
  1547.             timer = setInterval(f, 200);
  1548.             return;
  1549.         }
  1550.         if(!this.loaded){
  1551.             if(this.fireEvent("beforeload", this) === false){
  1552.                 return;
  1553.             }
  1554.             this.loading = true;
  1555.             this.ui.beforeLoad(this);
  1556.             var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
  1557.             if(loader){
  1558.                 loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback]));
  1559.                 return;
  1560.             }
  1561.         }
  1562.         Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback);
  1563.     },
  1564.     isLoading : function(){
  1565.         return this.loading;
  1566.     },
  1567.     loadComplete : function(deep, anim, callback){
  1568.         this.loading = false;
  1569.         this.loaded = true;
  1570.         this.ui.afterLoad(this);
  1571.         this.fireEvent("load", this);
  1572.         this.expand(deep, anim, callback);
  1573.     },
  1574.     isLoaded : function(){
  1575.         return this.loaded;
  1576.     },
  1577.     hasChildNodes : function(){
  1578.         if(!this.isLeaf() && !this.loaded){
  1579.             return true;
  1580.         }else{
  1581.             return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
  1582.         }
  1583.     },
  1584.     reload : function(callback){
  1585.         this.collapse(false, false);
  1586.         while(this.firstChild){
  1587.             this.removeChild(this.firstChild);
  1588.         }
  1589.         this.childrenRendered = false;
  1590.         this.loaded = false;
  1591.         if(this.isHiddenRoot()){
  1592.             this.expanded = false;
  1593.         }
  1594.         this.expand(false, false, callback);
  1595.     }
  1596. });
  1597. Ext.tree.TreeNodeUI = function(node){
  1598.     this.node = node;
  1599.     this.rendered = false;
  1600.     this.animating = false;
  1601.     this.wasLeaf = true;
  1602.     this.ecc = 'x-tree-ec-icon x-tree-elbow';
  1603.     this.emptyIcon = Ext.BLANK_IMAGE_URL;
  1604. };
  1605. Ext.tree.TreeNodeUI.prototype = {
  1606.     removeChild : function(node){
  1607.         if(this.rendered){
  1608.             this.ctNode.removeChild(node.ui.getEl());
  1609.         }
  1610.     },
  1611.     beforeLoad : function(){
  1612.          this.addClass("x-tree-node-loading");
  1613.     },
  1614.     afterLoad : function(){
  1615.          this.removeClass("x-tree-node-loading");
  1616.     },
  1617.     onTextChange : function(node, text, oldText){
  1618.         if(this.rendered){
  1619.             this.textNode.innerHTML = text;
  1620.         }
  1621.     },
  1622.     onDisableChange : function(node, state){
  1623.         this.disabled = state;
  1624.         if (this.checkbox) {
  1625.             this.checkbox.disabled = state;
  1626.         }
  1627.         if(state){
  1628.             this.addClass("x-tree-node-disabled");
  1629.         }else{
  1630.             this.removeClass("x-tree-node-disabled");
  1631.         }
  1632.     },
  1633.     onSelectedChange : function(state){
  1634.         if(state){
  1635.             this.focus();
  1636.             this.addClass("x-tree-selected");
  1637.         }else{
  1638.             this.removeClass("x-tree-selected");
  1639.         }
  1640.     },
  1641.     onMove : function(tree, node, oldParent, newParent, index, refNode){
  1642.         this.childIndent = null;
  1643.         if(this.rendered){
  1644.             var targetNode = newParent.ui.getContainer();
  1645.             if(!targetNode){
  1646.                 this.holder = document.createElement("div");
  1647.                 this.holder.appendChild(this.wrap);
  1648.                 return;
  1649.             }
  1650.             var insertBefore = refNode ? refNode.ui.getEl() : null;
  1651.             if(insertBefore){
  1652.                 targetNode.insertBefore(this.wrap, insertBefore);
  1653.             }else{
  1654.                 targetNode.appendChild(this.wrap);
  1655.             }
  1656.             this.node.renderIndent(true);
  1657.         }
  1658.     },
  1659.     addClass : function(cls){
  1660.         if(this.elNode){
  1661.             Ext.fly(this.elNode).addClass(cls);
  1662.         }
  1663.     },
  1664.     removeClass : function(cls){
  1665.         if(this.elNode){
  1666.             Ext.fly(this.elNode).removeClass(cls);
  1667.         }
  1668.     },
  1669.     remove : function(){
  1670.         if(this.rendered){
  1671.             this.holder = document.createElement("div");
  1672.             this.holder.appendChild(this.wrap);
  1673.         }
  1674.     },
  1675.     fireEvent : function(){
  1676.         return this.node.fireEvent.apply(this.node, arguments);
  1677.     },
  1678.     initEvents : function(){
  1679.         this.node.on("move", this.onMove, this);
  1680.         if(this.node.disabled){
  1681.             this.addClass("x-tree-node-disabled");
  1682.             if (this.checkbox) {
  1683.                 this.checkbox.disabled = true;
  1684.             }
  1685.         }
  1686.         if(this.node.hidden){
  1687.             this.hide();
  1688.         }
  1689.         var ot = this.node.getOwnerTree();
  1690.         var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
  1691.         if(dd && (!this.node.isRoot || ot.rootVisible)){
  1692.             Ext.dd.Registry.register(this.elNode, {
  1693.                 node: this.node,
  1694.                 handles: this.getDDHandles(),
  1695.                 isHandle: false
  1696.             });
  1697.         }
  1698.     },
  1699.     getDDHandles : function(){
  1700.         return [this.iconNode, this.textNode, this.elNode];
  1701.     },
  1702.     hide : function(){
  1703.         this.node.hidden = true;
  1704.         if(this.wrap){
  1705.             this.wrap.style.display = "none";
  1706.         }
  1707.     },
  1708.     show : function(){
  1709.         this.node.hidden = false;
  1710.         if(this.wrap){
  1711.             this.wrap.style.display = "";
  1712.         }
  1713.     },
  1714.     onContextMenu : function(e){
  1715.         if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
  1716.             e.preventDefault();
  1717.             this.focus();
  1718.             this.fireEvent("contextmenu", this.node, e);
  1719.         }
  1720.     },
  1721.     onClick : function(e){
  1722.         if(this.dropping){
  1723.             e.stopEvent();
  1724.             return;
  1725.         }
  1726.         if(this.fireEvent("beforeclick", this.node, e) !== false){
  1727.             var a = e.getTarget('a');
  1728.             if(!this.disabled && this.node.attributes.href && a){
  1729.                 this.fireEvent("click", this.node, e);
  1730.                 return;
  1731.             }else if(a && e.ctrlKey){
  1732.                 e.stopEvent();
  1733.             }
  1734.             e.preventDefault();
  1735.             if(this.disabled){
  1736.                 return;
  1737.             }
  1738.             if(this.node.attributes.singleClickExpand && !this.animating && this.node.hasChildNodes()){
  1739.                 this.node.toggle();
  1740.             }
  1741.             this.fireEvent("click", this.node, e);
  1742.         }else{
  1743.             e.stopEvent();
  1744.         }
  1745.     },
  1746.     onDblClick : function(e){
  1747.         e.preventDefault();
  1748.         if(this.disabled){
  1749.             return;
  1750.         }
  1751.         if(this.checkbox){
  1752.             this.toggleCheck();
  1753.         }
  1754.         if(!this.animating && this.node.hasChildNodes()){
  1755.             this.node.toggle();
  1756.         }
  1757.         this.fireEvent("dblclick", this.node, e);
  1758.     },
  1759.     onOver : function(e){
  1760.         this.addClass('x-tree-node-over');
  1761.     },
  1762.     onOut : function(e){
  1763.         this.removeClass('x-tree-node-over');
  1764.     },
  1765.     onCheckChange : function(){
  1766.         var checked = this.checkbox.checked;
  1767.         this.node.attributes.checked = checked;
  1768.         this.fireEvent('checkchange', this.node, checked);
  1769.     },
  1770.     ecClick : function(e){
  1771.         if(!this.animating && (this.node.hasChildNodes() || this.node.attributes.expandable)){
  1772.             this.node.toggle();
  1773.         }
  1774.     },
  1775.     startDrop : function(){
  1776.         this.dropping = true;
  1777.     },
  1778.     endDrop : function(){
  1779.        setTimeout(function(){
  1780.            this.dropping = false;
  1781.        }.createDelegate(this), 50);
  1782.     },
  1783.     expand : function(){
  1784.         this.updateExpandIcon();
  1785.         this.ctNode.style.display = "";
  1786.     },
  1787.     focus : function(){
  1788.         if(!this.node.preventHScroll){
  1789.             try{this.anchor.focus();
  1790.             }catch(e){}
  1791.         }else if(!Ext.isIE){
  1792.             try{
  1793.                 var noscroll = this.node.getOwnerTree().getTreeEl().dom;
  1794.                 var l = noscroll.scrollLeft;
  1795.                 this.anchor.focus();
  1796.                 noscroll.scrollLeft = l;
  1797.             }catch(e){}
  1798.         }
  1799.     },
  1800.     toggleCheck : function(value){
  1801.         var cb = this.checkbox;
  1802.         if(cb){
  1803.             cb.checked = (value === undefined ? !cb.checked : value);
  1804.         }
  1805.     },
  1806.     blur : function(){
  1807.         try{
  1808.             this.anchor.blur();
  1809.         }catch(e){}
  1810.     },
  1811.     animExpand : function(callback){
  1812.         var ct = Ext.get(this.ctNode);
  1813.         ct.stopFx();
  1814.         if(!this.node.hasChildNodes()){
  1815.             this.updateExpandIcon();
  1816.             this.ctNode.style.display = "";
  1817.             Ext.callback(callback);
  1818.             return;
  1819.         }
  1820.         this.animating = true;
  1821.         this.updateExpandIcon();
  1822.         ct.slideIn('t', {
  1823.            callback : function(){
  1824.                this.animating = false;
  1825.                Ext.callback(callback);
  1826.             },
  1827.             scope: this,
  1828.             duration: this.node.ownerTree.duration || .25
  1829.         });
  1830.     },
  1831.     highlight : function(){
  1832.         var tree = this.node.getOwnerTree();
  1833.         Ext.fly(this.wrap).highlight(
  1834.             tree.hlColor || "C3DAF9",
  1835.             {endColor: tree.hlBaseColor}
  1836.         );
  1837.     },
  1838.     collapse : function(){
  1839.         this.updateExpandIcon();
  1840.         this.ctNode.style.display = "none";
  1841.     },
  1842.     animCollapse : function(callback){
  1843.         var ct = Ext.get(this.ctNode);
  1844.         ct.enableDisplayMode('block');
  1845.         ct.stopFx();
  1846.         this.animating = true;
  1847.         this.updateExpandIcon();
  1848.         ct.slideOut('t', {
  1849.             callback : function(){
  1850.                this.animating = false;
  1851.                Ext.callback(callback);
  1852.             },
  1853.             scope: this,
  1854.             duration: this.node.ownerTree.duration || .25
  1855.         });
  1856.     },
  1857.     getContainer : function(){
  1858.         return this.ctNode;
  1859.     },
  1860.     getEl : function(){
  1861.         return this.wrap;
  1862.     },
  1863.     appendDDGhost : function(ghostNode){
  1864.         ghostNode.appendChild(this.elNode.cloneNode(true));
  1865.     },
  1866.     getDDRepairXY : function(){
  1867.         return Ext.lib.Dom.getXY(this.iconNode);
  1868.     },
  1869.     onRender : function(){
  1870.         this.render();
  1871.     },
  1872.     render : function(bulkRender){
  1873.         var n = this.node, a = n.attributes;
  1874.         var targetNode = n.parentNode ?
  1875.               n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
  1876.         if(!this.rendered){
  1877.             this.rendered = true;
  1878.             this.renderElements(n, a, targetNode, bulkRender);
  1879.             if(a.qtip){
  1880.                if(this.textNode.setAttributeNS){
  1881.                    this.textNode.setAttributeNS("ext", "qtip", a.qtip);
  1882.                    if(a.qtipTitle){
  1883.                        this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);
  1884.                    }
  1885.                }else{
  1886.                    this.textNode.setAttribute("ext:qtip", a.qtip);
  1887.                    if(a.qtipTitle){
  1888.                        this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
  1889.                    }
  1890.                }
  1891.             }else if(a.qtipCfg){
  1892.                 a.qtipCfg.target = Ext.id(this.textNode);
  1893.                 Ext.QuickTips.register(a.qtipCfg);
  1894.             }
  1895.             this.initEvents();
  1896.             if(!this.node.expanded){
  1897.                 this.updateExpandIcon(true);
  1898.             }
  1899.         }else{
  1900.             if(bulkRender === true) {
  1901.                 targetNode.appendChild(this.wrap);
  1902.             }
  1903.         }
  1904.     },
  1905.     renderElements : function(n, a, targetNode, bulkRender){
  1906.         this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
  1907.         var cb = typeof a.checked == 'boolean';
  1908.         var href = a.href ? a.href : Ext.isGecko ? "" : "#";
  1909.         var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
  1910.             '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
  1911.             '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
  1912.             '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
  1913.             cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
  1914.             '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
  1915.              a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
  1916.             '<ul class="x-tree-node-ct" style="display:none;"></ul>',
  1917.             "</li>"].join('');
  1918.         var nel;
  1919.         if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
  1920.             this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
  1921.         }else{
  1922.             this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
  1923.         }
  1924.         this.elNode = this.wrap.childNodes[0];
  1925.         this.ctNode = this.wrap.childNodes[1];
  1926.         var cs = this.elNode.childNodes;
  1927.         this.indentNode = cs[0];
  1928.         this.ecNode = cs[1];
  1929.         this.iconNode = cs[2];
  1930.         var index = 3;
  1931.         if(cb){
  1932.             this.checkbox = cs[3];
  1933.             index++;
  1934.         }
  1935.         this.anchor = cs[index];
  1936.         this.textNode = cs[index].firstChild;
  1937.     },
  1938.     getAnchor : function(){
  1939.         return this.anchor;
  1940.     },
  1941.     getTextEl : function(){
  1942.         return this.textNode;
  1943.     },
  1944.     getIconEl : function(){
  1945.         return this.iconNode;
  1946.     },
  1947.     isChecked : function(){
  1948.         return this.checkbox ? this.checkbox.checked : false;
  1949.     },
  1950.     updateExpandIcon : function(){
  1951.         if(this.rendered){
  1952.             var n = this.node, c1, c2;
  1953.             var cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow";
  1954.             var hasChild = n.hasChildNodes();
  1955.             if(hasChild || n.attributes.expandable){
  1956.                 if(n.expanded){
  1957.                     cls += "-minus";
  1958.                     c1 = "x-tree-node-collapsed";
  1959.                     c2 = "x-tree-node-expanded";
  1960.                 }else{
  1961.                     cls += "-plus";
  1962.                     c1 = "x-tree-node-expanded";
  1963.                     c2 = "x-tree-node-collapsed";
  1964.                 }
  1965.                 if(this.wasLeaf){
  1966.                     this.removeClass("x-tree-node-leaf");
  1967.                     this.wasLeaf = false;
  1968.                 }
  1969.                 if(this.c1 != c1 || this.c2 != c2){
  1970.                     Ext.fly(this.elNode).replaceClass(c1, c2);
  1971.                     this.c1 = c1; this.c2 = c2;
  1972.                 }
  1973.             }else{
  1974.                 if(!this.wasLeaf){
  1975.                     Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");
  1976.                     delete this.c1;
  1977.                     delete this.c2;
  1978.                     this.wasLeaf = true;
  1979.                 }
  1980.             }
  1981.             var ecc = "x-tree-ec-icon "+cls;
  1982.             if(this.ecc != ecc){
  1983.                 this.ecNode.className = ecc;
  1984.                 this.ecc = ecc;
  1985.             }
  1986.         }
  1987.     },
  1988.     getChildIndent : function(){
  1989.         if(!this.childIndent){
  1990.             var buf = [];
  1991.             var p = this.node;
  1992.             while(p){
  1993.                 if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
  1994.                     if(!p.isLast()) {
  1995.                         buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
  1996.                     } else {
  1997.                         buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');
  1998.                     }
  1999.                 }
  2000.                 p = p.parentNode;
  2001.             }
  2002.             this.childIndent = buf.join("");
  2003.         }
  2004.         return this.childIndent;
  2005.     },
  2006.     renderIndent : function(){
  2007.         if(this.rendered){
  2008.             var indent = "";
  2009.             var p = this.node.parentNode;
  2010.             if(p){
  2011.                 indent = p.ui.getChildIndent();
  2012.             }
  2013.             if(this.indentMarkup != indent){
  2014.                 this.indentNode.innerHTML = indent;
  2015.                 this.indentMarkup = indent;
  2016.             }
  2017.             this.updateExpandIcon();
  2018.         }
  2019.     },
  2020.     destroy : function(){
  2021.         if(this.elNode){
  2022.             Ext.dd.Registry.unregister(this.elNode.id);
  2023.         }
  2024.         delete this.elNode;
  2025.         delete this.ctNode;
  2026.         delete this.indentNode;
  2027.         delete this.ecNode;
  2028.         delete this.iconNode;
  2029.         delete this.checkbox;
  2030.         delete this.anchor;
  2031.         delete this.textNode;
  2032.         Ext.removeNode(this.ctNode);
  2033.     }
  2034. };
  2035. Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
  2036.     render : function(){
  2037.         if(!this.rendered){
  2038.             var targetNode = this.node.ownerTree.innerCt.dom;
  2039.             this.node.expanded = true;
  2040.             targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
  2041.             this.wrap = this.ctNode = targetNode.firstChild;
  2042.         }
  2043.     },
  2044.     collapse : Ext.emptyFn,
  2045.     expand : Ext.emptyFn
  2046. });
  2047. Ext.tree.TreeLoader = function(config){
  2048.     this.baseParams = {};
  2049.     this.requestMethod = "POST";
  2050.     Ext.apply(this, config);
  2051.     this.addEvents(
  2052.         "beforeload",
  2053.         "load",
  2054.         "loadexception"
  2055.     );
  2056.     Ext.tree.TreeLoader.superclass.constructor.call(this);
  2057. };
  2058. Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
  2059.     uiProviders : {},
  2060.     clearOnLoad : true,
  2061.     load : function(node, callback){
  2062.         if(this.clearOnLoad){
  2063.             while(node.firstChild){
  2064.                 node.removeChild(node.firstChild);
  2065.             }
  2066.         }
  2067.         if(this.doPreload(node)){
  2068.             if(typeof callback == "function"){
  2069.                 callback();
  2070.             }
  2071.         }else if(this.dataUrl||this.url){
  2072.             this.requestData(node, callback);
  2073.         }
  2074.     },
  2075.     doPreload : function(node){
  2076.         if(node.attributes.children){
  2077.             if(node.childNodes.length < 1){
  2078.                 var cs = node.attributes.children;
  2079.                 node.beginUpdate();
  2080.                 for(var i = 0, len = cs.length; i < len; i++){
  2081.                     var cn = node.appendChild(this.createNode(cs[i]));
  2082.                     if(this.preloadChildren){
  2083.                         this.doPreload(cn);
  2084.                     }
  2085.                 }
  2086.                 node.endUpdate();
  2087.             }
  2088.             return true;
  2089.         }else {
  2090.             return false;
  2091.         }
  2092.     },
  2093.     getParams: function(node){
  2094.         var buf = [], bp = this.baseParams;
  2095.         for(var key in bp){
  2096.             if(typeof bp[key] != "function"){
  2097.                 buf.push(encodeURIComponent(key), "=", encodeURIComponent(bp[key]), "&");
  2098.             }
  2099.         }
  2100.         buf.push("node=", encodeURIComponent(node.id));
  2101.         return buf.join("");
  2102.     },
  2103.     requestData : function(node, callback){
  2104.         if(this.fireEvent("beforeload", this, node, callback) !== false){
  2105.             this.transId = Ext.Ajax.request({
  2106.                 method:this.requestMethod,
  2107.                 url: this.dataUrl||this.url,
  2108.                 success: this.handleResponse,
  2109.                 failure: this.handleFailure,
  2110.                 scope: this,
  2111.                 argument: {callback: callback, node: node},
  2112.                 params: this.getParams(node)
  2113.             });
  2114.         }else{
  2115.             if(typeof callback == "function"){
  2116.                 callback();
  2117.             }
  2118.         }
  2119.     },
  2120.     isLoading : function(){
  2121.         return this.transId ? true : false;
  2122.     },
  2123.     abort : function(){
  2124.         if(this.isLoading()){
  2125.             Ext.Ajax.abort(this.transId);
  2126.         }
  2127.     },
  2128.     createNode : function(attr){
  2129.         if(this.baseAttrs){
  2130.             Ext.applyIf(attr, this.baseAttrs);
  2131.         }
  2132.         if(this.applyLoader !== false){
  2133.             attr.loader = this;
  2134.         }
  2135.         if(typeof attr.uiProvider == 'string'){
  2136.            attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
  2137.         }
  2138.         return(attr.leaf ?
  2139.                         new Ext.tree.TreeNode(attr) :
  2140.                         new Ext.tree.AsyncTreeNode(attr));
  2141.     },
  2142.     processResponse : function(response, node, callback){
  2143.         var json = response.responseText;
  2144.         try {
  2145.             var o = eval("("+json+")");
  2146.             node.beginUpdate();
  2147.             for(var i = 0, len = o.length; i < len; i++){
  2148.                 var n = this.createNode(o[i]);
  2149.                 if(n){
  2150.                     node.appendChild(n);
  2151.                 }
  2152.             }
  2153.             node.endUpdate();
  2154.             if(typeof callback == "function"){
  2155.                 callback(this, node);
  2156.             }
  2157.         }catch(e){
  2158.             this.handleFailure(response);
  2159.         }
  2160.     },
  2161.     handleResponse : function(response){
  2162.         this.transId = false;
  2163.         var a = response.argument;
  2164.         this.processResponse(response, a.node, a.callback);
  2165.         this.fireEvent("load", this, a.node, response);
  2166.     },
  2167.     handleFailure : function(response){
  2168.         this.transId = false;
  2169.         var a = response.argument;
  2170.         this.fireEvent("loadexception", this, a.node, response);
  2171.         if(typeof a.callback == "function"){
  2172.             a.callback(this, a.node);
  2173.         }
  2174.     }
  2175. });
  2176. Ext.tree.TreeFilter = function(tree, config){
  2177.     this.tree = tree;
  2178.     this.filtered = {};
  2179.     Ext.apply(this, config);
  2180. };
  2181. Ext.tree.TreeFilter.prototype = {
  2182.     clearBlank:false,
  2183.     reverse:false,
  2184.     autoClear:false,
  2185.     remove:false,
  2186.     filter : function(value, attr, startNode){
  2187.         attr = attr || "text";
  2188.         var f;
  2189.         if(typeof value == "string"){
  2190.             var vlen = value.length;
  2191.             if(vlen == 0 && this.clearBlank){
  2192.                 this.clear();
  2193.                 return;
  2194.             }
  2195.             value = value.toLowerCase();
  2196.             f = function(n){
  2197.                 return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
  2198.             };
  2199.         }else if(value.exec){
  2200.             f = function(n){
  2201.                 return value.test(n.attributes[attr]);
  2202.             };
  2203.         }else{
  2204.             throw 'Illegal filter type, must be string or regex';
  2205.         }
  2206.         this.filterBy(f, null, startNode);
  2207.     },
  2208.     filterBy : function(fn, scope, startNode){
  2209.         startNode = startNode || this.tree.root;
  2210.         if(this.autoClear){
  2211.             this.clear();
  2212.         }
  2213.         var af = this.filtered, rv = this.reverse;
  2214.         var f = function(n){
  2215.             if(n == startNode){
  2216.                 return true;
  2217.             }
  2218.             if(af[n.id]){
  2219.                 return false;
  2220.             }
  2221.             var m = fn.call(scope || n, n);
  2222.             if(!m || rv){
  2223.                 af[n.id] = n;
  2224.                 n.ui.hide();
  2225.                 return false;
  2226.             }
  2227.             return true;
  2228.         };
  2229.         startNode.cascade(f);
  2230.         if(this.remove){
  2231.            for(var id in af){
  2232.                if(typeof id != "function"){
  2233.                    var n = af[id];
  2234.                    if(n && n.parentNode){
  2235.                        n.parentNode.removeChild(n);
  2236.                    }
  2237.                }
  2238.            }
  2239.         }
  2240.     },
  2241.     clear : function(){
  2242.         var t = this.tree;
  2243.         var af = this.filtered;
  2244.         for(var id in af){
  2245.             if(typeof id != "function"){
  2246.                 var n = af[id];
  2247.                 if(n){
  2248.                     n.ui.show();
  2249.                 }
  2250.             }
  2251.         }
  2252.         this.filtered = {};
  2253.     }
  2254. };
  2255. Ext.tree.TreeSorter = function(tree, config){
  2256.     Ext.apply(this, config);
  2257.     tree.on("beforechildrenrendered", this.doSort, this);
  2258.     tree.on("append", this.updateSort, this);
  2259.     tree.on("insert", this.updateSort, this);
  2260.     tree.on("textchange", this.updateSortParent, this);
  2261.     var dsc = this.dir && this.dir.toLowerCase() == "desc";
  2262.     var p = this.property || "text";
  2263.     var sortType = this.sortType;
  2264.     var fs = this.folderSort;
  2265.     var cs = this.caseSensitive === true;
  2266.     var leafAttr = this.leafAttr || 'leaf';
  2267.     this.sortFn = function(n1, n2){
  2268.         if(fs){
  2269.             if(n1.attributes[leafAttr] && !n2.attributes[leafAttr]){
  2270.                 return 1;
  2271.             }
  2272.             if(!n1.attributes[leafAttr] && n2.attributes[leafAttr]){
  2273.                 return -1;
  2274.             }
  2275.         }
  2276.         var v1 = sortType ? sortType(n1) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
  2277.         var v2 = sortType ? sortType(n2) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
  2278.         if(v1 < v2){
  2279.             return dsc ? +1 : -1;
  2280.         }else if(v1 > v2){
  2281.             return dsc ? -1 : +1;
  2282.         }else{
  2283.             return 0;
  2284.         }
  2285.     };
  2286. };
  2287. Ext.tree.TreeSorter.prototype = {
  2288.     doSort : function(node){
  2289.         node.sort(this.sortFn);
  2290.     },
  2291.     compareNodes : function(n1, n2){
  2292.         return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);
  2293.     },
  2294.     updateSort : function(tree, node){
  2295.         if(node.childrenRendered){
  2296.             this.doSort.defer(1, this, [node]);
  2297.         }
  2298.     },
  2299.     updateSortParent : function(node){
  2300.         var p = node.parentNode;
  2301.         if(p && p.childrenRendered){
  2302.             this.doSort.defer(1, this, [p]);
  2303.         }
  2304.     }
  2305. };
  2306. if(Ext.dd.DropZone){
  2307. Ext.tree.TreeDropZone = function(tree, config){
  2308.     this.allowParentInsert = false;
  2309.     this.allowContainerDrop = false;
  2310.     this.appendOnly = false;
  2311.     Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.innerCt, config);
  2312.     this.tree = tree;
  2313.     this.dragOverData = {};
  2314.     this.lastInsertClass = "x-tree-no-status";
  2315. };
  2316. Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
  2317.     ddGroup : "TreeDD",
  2318.     expandDelay : 1000,
  2319.     expandNode : function(node){
  2320.         if(node.hasChildNodes() && !node.isExpanded()){
  2321.             node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
  2322.         }
  2323.     },
  2324.     queueExpand : function(node){
  2325.         this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
  2326.     },
  2327.     cancelExpand : function(){
  2328.         if(this.expandProcId){
  2329.             clearTimeout(this.expandProcId);
  2330.             this.expandProcId = false;
  2331.         }
  2332.     },
  2333.     isValidDropPoint : function(n, pt, dd, e, data){
  2334.         if(!n || !data){ return false; }
  2335.         var targetNode = n.node;
  2336.         var dropNode = data.node;
  2337.         if(!(targetNode && targetNode.isTarget && pt)){
  2338.             return false;
  2339.         }
  2340.         if(pt == "append" && targetNode.allowChildren === false){
  2341.             return false;
  2342.         }
  2343.         if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
  2344.             return false;
  2345.         }
  2346.         if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
  2347.             return false;
  2348.         }
  2349.         var overEvent = this.dragOverData;
  2350.         overEvent.tree = this.tree;
  2351.         overEvent.target = targetNode;
  2352.         overEvent.data = data;
  2353.         overEvent.point = pt;
  2354.         overEvent.source = dd;
  2355.         overEvent.rawEvent = e;
  2356.         overEvent.dropNode = dropNode;
  2357.         overEvent.cancel = false;
  2358.         var result = this.tree.fireEvent("nodedragover", overEvent);
  2359.         return overEvent.cancel === false && result !== false;
  2360.     },
  2361.     getDropPoint : function(e, n, dd){
  2362.         var tn = n.node;
  2363.         if(tn.isRoot){
  2364.             return tn.allowChildren !== false ? "append" : false;
  2365.         }
  2366.         var dragEl = n.ddel;
  2367.         var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
  2368.         var y = Ext.lib.Event.getPageY(e);
  2369.         var noAppend = tn.allowChildren === false || tn.isLeaf();
  2370.         if(this.appendOnly || tn.parentNode.allowChildren === false){
  2371.             return noAppend ? false : "append";
  2372.         }
  2373.         var noBelow = false;
  2374.         if(!this.allowParentInsert){
  2375.             noBelow = tn.hasChildNodes() && tn.isExpanded();
  2376.         }
  2377.         var q = (b - t) / (noAppend ? 2 : 3);
  2378.         if(y >= t && y < (t + q)){
  2379.             return "above";
  2380.         }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
  2381.             return "below";
  2382.         }else{
  2383.             return "append";
  2384.         }
  2385.     },
  2386.     onNodeEnter : function(n, dd, e, data){
  2387.         this.cancelExpand();
  2388.     },
  2389.     onNodeOver : function(n, dd, e, data){
  2390.         var pt = this.getDropPoint(e, n, dd);
  2391.         var node = n.node;
  2392.         if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
  2393.             this.queueExpand(node);
  2394.         }else if(pt != "append"){
  2395.             this.cancelExpand();
  2396.         }
  2397.         var returnCls = this.dropNotAllowed;
  2398.         if(this.isValidDropPoint(n, pt, dd, e, data)){
  2399.            if(pt){
  2400.                var el = n.ddel;
  2401.                var cls;
  2402.                if(pt == "above"){
  2403.                    returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
  2404.                    cls = "x-tree-drag-insert-above";
  2405.                }else if(pt == "below"){
  2406.                    returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
  2407.                    cls = "x-tree-drag-insert-below";
  2408.                }else{
  2409.                    returnCls = "x-tree-drop-ok-append";
  2410.                    cls = "x-tree-drag-append";
  2411.                }
  2412.                if(this.lastInsertClass != cls){
  2413.                    Ext.fly(el).replaceClass(this.lastInsertClass, cls);
  2414.                    this.lastInsertClass = cls;
  2415.                }
  2416.            }
  2417.        }
  2418.        return returnCls;
  2419.     },
  2420.     onNodeOut : function(n, dd, e, data){
  2421.         this.cancelExpand();
  2422.         this.removeDropIndicators(n);
  2423.     },
  2424.     onNodeDrop : function(n, dd, e, data){
  2425.         var point = this.getDropPoint(e, n, dd);
  2426.         var targetNode = n.node;
  2427.         targetNode.ui.startDrop();
  2428.         if(!this.isValidDropPoint(n, point, dd, e, data)){
  2429.             targetNode.ui.endDrop();
  2430.             return false;
  2431.         }
  2432.         var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
  2433.         var dropEvent = {
  2434.             tree : this.tree,
  2435.             target: targetNode,
  2436.             data: data,
  2437.             point: point,
  2438.             source: dd,
  2439.             rawEvent: e,
  2440.             dropNode: dropNode,
  2441.             cancel: !dropNode,
  2442.             dropStatus: false
  2443.         };
  2444.         var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
  2445.         if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
  2446.             targetNode.ui.endDrop();
  2447.             return dropEvent.dropStatus;
  2448.         }
  2449.         targetNode = dropEvent.target;
  2450.         if(point == "append" && !targetNode.isExpanded()){
  2451.             targetNode.expand(false, null, function(){
  2452.                 this.completeDrop(dropEvent);
  2453.             }.createDelegate(this));
  2454.         }else{
  2455.             this.completeDrop(dropEvent);
  2456.         }
  2457.         return true;
  2458.     },
  2459.     completeDrop : function(de){
  2460.         var ns = de.dropNode, p = de.point, t = de.target;
  2461.         if(!Ext.isArray(ns)){
  2462.             ns = [ns];
  2463.         }
  2464.         var n;
  2465.         for(var i = 0, len = ns.length; i < len; i++){
  2466.             n = ns[i];
  2467.             if(p == "above"){
  2468.                 t.parentNode.insertBefore(n, t);
  2469.             }else if(p == "below"){
  2470.                 t.parentNode.insertBefore(n, t.nextSibling);
  2471.             }else{
  2472.                 t.appendChild(n);
  2473.             }
  2474.         }
  2475.         n.ui.focus();
  2476.         if(this.tree.hlDrop){
  2477.             n.ui.highlight();
  2478.         }
  2479.         t.ui.endDrop();
  2480.         this.tree.fireEvent("nodedrop", de);
  2481.     },
  2482.     afterNodeMoved : function(dd, data, e, targetNode, dropNode){
  2483.         if(this.tree.hlDrop){
  2484.             dropNode.ui.focus();
  2485.             dropNode.ui.highlight();
  2486.         }
  2487.         this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
  2488.     },
  2489.     getTree : function(){
  2490.         return this.tree;
  2491.     },
  2492.     removeDropIndicators : function(n){
  2493.         if(n && n.ddel){
  2494.             var el = n.ddel;
  2495.             Ext.fly(el).removeClass([
  2496.                     "x-tree-drag-insert-above",
  2497.                     "x-tree-drag-insert-below",
  2498.                     "x-tree-drag-append"]);
  2499.             this.lastInsertClass = "_noclass";
  2500.         }
  2501.     },
  2502.     beforeDragDrop : function(target, e, id){
  2503.         this.cancelExpand();
  2504.         return true;
  2505.     },
  2506.     afterRepair : function(data){
  2507.         if(data && Ext.enableFx){
  2508.             data.node.ui.highlight();
  2509.         }
  2510.         this.hideProxy();
  2511.     }
  2512. });
  2513. }
  2514. if(Ext.dd.DragZone){
  2515. Ext.tree.TreeDragZone = function(tree, config){
  2516.     Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.getTreeEl(), config);
  2517.     this.tree = tree;
  2518. };
  2519. Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
  2520.     ddGroup : "TreeDD",
  2521.     onBeforeDrag : function(data, e){
  2522.         var n = data.node;
  2523.         return n && n.draggable && !n.disabled;
  2524.     },
  2525.     onInitDrag : function(e){
  2526.         var data = this.dragData;
  2527.         this.tree.getSelectionModel().select(data.node);
  2528.         this.tree.eventModel.disable();
  2529.         this.proxy.update("");
  2530.         data.node.ui.appendDDGhost(this.proxy.ghost.dom);
  2531.         this.tree.fireEvent("startdrag", this.tree, data.node, e);
  2532.     },
  2533.     getRepairXY : function(e, data){
  2534.         return data.node.ui.getDDRepairXY();
  2535.     },
  2536.     onEndDrag : function(data, e){
  2537.         this.tree.eventModel.enable.defer(100, this.tree.eventModel);
  2538.         this.tree.fireEvent("enddrag", this.tree, data.node, e);
  2539.     },
  2540.     onValidDrop : function(dd, e, id){
  2541.         this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
  2542.         this.hideProxy();
  2543.     },
  2544.     beforeInvalidDrop : function(e, id){
  2545.         var sm = this.tree.getSelectionModel();
  2546.         sm.clearSelections();
  2547.         sm.select(this.dragData.node);
  2548.     }
  2549. });
  2550. }
  2551. Ext.tree.TreeEditor = function(tree, config){
  2552.     config = config || {};
  2553.     var field = config.events ? config : new Ext.form.TextField(config);
  2554.     Ext.tree.TreeEditor.superclass.constructor.call(this, field);
  2555.     this.tree = tree;
  2556.     if(!tree.rendered){
  2557.         tree.on('render', this.initEditor, this);
  2558.     }else{
  2559.         this.initEditor(tree);
  2560.     }
  2561. };
  2562. Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
  2563.     alignment: "l-l",
  2564.         autoSize: false,
  2565.     hideEl : false,
  2566.     cls: "x-small-editor x-tree-editor",
  2567.     shim:false,
  2568.         shadow:"frame",
  2569.     maxWidth: 250,
  2570.     editDelay : 350,
  2571.     initEditor : function(tree){
  2572.         tree.on('beforeclick', this.beforeNodeClick, this);
  2573.         tree.on('dblclick', this.onNodeDblClick, this);
  2574.         this.on('complete', this.updateNode, this);
  2575.         this.on('beforestartedit', this.fitToTree, this);
  2576.         this.on('startedit', this.bindScroll, this, {delay:10});
  2577.         this.on('specialkey', this.onSpecialKey, this);
  2578.     },
  2579.         fitToTree : function(ed, el){
  2580.         var td = this.tree.getTreeEl().dom, nd = el.dom;
  2581.         if(td.scrollLeft >  nd.offsetLeft){             td.scrollLeft = nd.offsetLeft;
  2582.         }
  2583.         var w = Math.min(
  2584.                 this.maxWidth,
  2585.                 (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
  2586.         this.setSize(w, '');
  2587.     },
  2588.         triggerEdit : function(node, defer){
  2589.         this.completeEdit();
  2590.         if(node.attributes.editable !== false){
  2591.             this.editNode = node;
  2592.             this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, node.text]);
  2593.             return false;
  2594.         }
  2595.     },
  2596.         bindScroll : function(){
  2597.         this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
  2598.     },
  2599.         beforeNodeClick : function(node, e){
  2600.         clearTimeout(this.autoEditTimer);
  2601.         if(this.tree.getSelectionModel().isSelected(node)){
  2602.             e.stopEvent();
  2603.             return this.triggerEdit(node);
  2604.         }
  2605.     },
  2606.     onNodeDblClick : function(node, e){
  2607.         clearTimeout(this.autoEditTimer);
  2608.     },
  2609.         updateNode : function(ed, value){
  2610.         this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
  2611.         this.editNode.setText(value);
  2612.     },
  2613.         onHide : function(){
  2614.         Ext.tree.TreeEditor.superclass.onHide.call(this);
  2615.         if(this.editNode){
  2616.             this.editNode.ui.focus.defer(50, this.editNode.ui);
  2617.         }
  2618.     },
  2619.         onSpecialKey : function(field, e){
  2620.         var k = e.getKey();
  2621.         if(k == e.ESC){
  2622.             e.stopEvent();
  2623.             this.cancelEdit();
  2624.         }else if(k == e.ENTER && !e.hasModifier()){
  2625.             e.stopEvent();
  2626.             this.completeEdit();
  2627.         }
  2628.     }
  2629. });
  2630. Ext.menu.Menu = function(config){
  2631.     if(Ext.isArray(config)){
  2632.         config = {items:config};
  2633.     }
  2634.     Ext.apply(this, config);
  2635.     this.id = this.id || Ext.id();
  2636.     this.addEvents(
  2637.         'beforeshow',
  2638.         'beforehide',
  2639.         'show',
  2640.         'hide',
  2641.         'click',
  2642.         'mouseover',
  2643.         'mouseout',
  2644.         'itemclick'
  2645.     );
  2646.     Ext.menu.MenuMgr.register(this);
  2647.     Ext.menu.Menu.superclass.constructor.call(this);
  2648.     var mis = this.items;
  2649.     this.items = new Ext.util.MixedCollection();
  2650.     if(mis){
  2651.         this.add.apply(this, mis);
  2652.     }
  2653. };
  2654. Ext.extend(Ext.menu.Menu, Ext.util.Observable, {
  2655.     minWidth : 120,
  2656.     shadow : "sides",
  2657.     subMenuAlign : "tl-tr?",
  2658.     defaultAlign : "tl-bl?",
  2659.     allowOtherMenus : false,
  2660.     hidden:true,
  2661.     createEl : function(){
  2662.         return new Ext.Layer({
  2663.             cls: "x-menu",
  2664.             shadow:this.shadow,
  2665.             constrain: false,
  2666.             parentEl: this.parentEl || document.body,
  2667.             zindex:15000
  2668.         });
  2669.     },
  2670.         render : function(){
  2671.         if(this.el){
  2672.             return;
  2673.         }
  2674.         var el = this.el = this.createEl();
  2675.         if(!this.keyNav){
  2676.             this.keyNav = new Ext.menu.MenuNav(this);
  2677.         }
  2678.         if(this.plain){
  2679.             el.addClass("x-menu-plain");
  2680.         }
  2681.         if(this.cls){
  2682.             el.addClass(this.cls);
  2683.         }
  2684.                 this.focusEl = el.createChild({
  2685.             tag: "a", cls: "x-menu-focus", href: "#", onclick: "return false;", tabIndex:"-1"
  2686.         });
  2687.         var ul = el.createChild({tag: "ul", cls: "x-menu-list"});
  2688.         ul.on("click", this.onClick, this);
  2689.         ul.on("mouseover", this.onMouseOver, this);
  2690.         ul.on("mouseout", this.onMouseOut, this);
  2691.         this.items.each(function(item){
  2692.             var li = document.createElement("li");
  2693.             li.className = "x-menu-list-item";
  2694.             ul.dom.appendChild(li);
  2695.             item.render(li, this);
  2696.         }, this);
  2697.         this.ul = ul;
  2698.         this.autoWidth();
  2699.     },
  2700.         autoWidth : function(){
  2701.         var el = this.el, ul = this.ul;
  2702.         if(!el){
  2703.             return;
  2704.         }
  2705.         var w = this.width;
  2706.         if(w){
  2707.             el.setWidth(w);
  2708.         }else if(Ext.isIE){
  2709.             el.setWidth(this.minWidth);
  2710.             var t = el.dom.offsetWidth;             el.setWidth(ul.getWidth()+el.getFrameWidth("lr"));
  2711.         }
  2712.     },
  2713.         delayAutoWidth : function(){
  2714.         if(this.el){
  2715.             if(!this.awTask){
  2716.                 this.awTask = new Ext.util.DelayedTask(this.autoWidth, this);
  2717.             }
  2718.             this.awTask.delay(20);
  2719.         }
  2720.     },
  2721.         findTargetItem : function(e){
  2722.         var t = e.getTarget(".x-menu-list-item", this.ul,  true);
  2723.         if(t && t.menuItemId){
  2724.             return this.items.get(t.menuItemId);
  2725.         }
  2726.     },
  2727.         onClick : function(e){
  2728.         var t;
  2729.         if(t = this.findTargetItem(e)){
  2730.             t.onClick(e);
  2731.             this.fireEvent("click", this, t, e);
  2732.         }
  2733.     },
  2734.         setActiveItem : function(item, autoExpand){
  2735.         if(item != this.activeItem){
  2736.             if(this.activeItem){
  2737.                 this.activeItem.deactivate();
  2738.             }
  2739.             this.activeItem = item;
  2740.             item.activate(autoExpand);
  2741.         }else if(autoExpand){
  2742.             item.expandMenu();
  2743.         }
  2744.     },
  2745.         tryActivate : function(start, step){
  2746.         var items = this.items;
  2747.         for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
  2748.             var item = items.get(i);
  2749.             if(!item.disabled && item.canActivate){
  2750.                 this.setActiveItem(item, false);
  2751.                 return item;
  2752.             }
  2753.         }
  2754.         return false;
  2755.     },
  2756.         onMouseOver : function(e){
  2757.         var t;
  2758.         if(t = this.findTargetItem(e)){
  2759.             if(t.canActivate && !t.disabled){
  2760.                 this.setActiveItem(t, true);
  2761.             }
  2762.         }
  2763.         this.fireEvent("mouseover", this, e, t);
  2764.     },
  2765.         onMouseOut : function(e){
  2766.         var t;
  2767.         if(t = this.findTargetItem(e)){
  2768.             if(t == this.activeItem && t.shouldDeactivate(e)){
  2769.                 this.activeItem.deactivate();
  2770.                 delete this.activeItem;
  2771.             }
  2772.         }
  2773.         this.fireEvent("mouseout", this, e, t);
  2774.     },
  2775.     isVisible : function(){
  2776.         return this.el && !this.hidden;
  2777.     },
  2778.     show : function(el, pos, parentMenu){
  2779.         this.parentMenu = parentMenu;
  2780.         if(!this.el){
  2781.             this.render();
  2782.         }
  2783.         this.fireEvent("beforeshow", this);
  2784.         this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
  2785.     },
  2786.     showAt : function(xy, parentMenu, _e){
  2787.         this.parentMenu = parentMenu;
  2788.         if(!this.el){
  2789.             this.render();
  2790.         }
  2791.         if(_e !== false){
  2792.             this.fireEvent("beforeshow", this);
  2793.             xy = this.el.adjustForConstraints(xy);
  2794.         }
  2795.         this.el.setXY(xy);
  2796.         this.el.show();
  2797.         this.hidden = false;
  2798.         this.focus();
  2799.         this.fireEvent("show", this);
  2800.     },
  2801.     focus : function(){
  2802.         if(!this.hidden){
  2803.             this.doFocus.defer(50, this);
  2804.         }
  2805.     },
  2806.     doFocus : function(){
  2807.         if(!this.hidden){
  2808.             this.focusEl.focus();
  2809.         }
  2810.     },
  2811.     hide : function(deep){
  2812.         if(this.el && this.isVisible()){
  2813.             this.fireEvent("beforehide", this);
  2814.             if(this.activeItem){
  2815.                 this.activeItem.deactivate();
  2816.                 this.activeItem = null;
  2817.             }
  2818.             this.el.hide();
  2819.             this.hidden = true;
  2820.             this.fireEvent("hide", this);
  2821.         }
  2822.         if(deep === true && this.parentMenu){
  2823.             this.parentMenu.hide(true);
  2824.         }
  2825.     },
  2826.     add : function(){
  2827.         var a = arguments, l = a.length, item;
  2828.         for(var i = 0; i < l; i++){
  2829.             var el = a[i];
  2830.             if(el.render){                 item = this.addItem(el);
  2831.             }else if(typeof el == "string"){                 if(el == "separator" || el == "-"){
  2832.                     item = this.addSeparator();
  2833.                 }else{
  2834.                     item = this.addText(el);
  2835.                 }
  2836.             }else if(el.tagName || el.el){                 item = this.addElement(el);
  2837.             }else if(typeof el == "object"){                 Ext.applyIf(el, this.defaults);
  2838.                 item = this.addMenuItem(el);
  2839.             }
  2840.         }
  2841.         return item;
  2842.     },
  2843.     getEl : function(){
  2844.         if(!this.el){
  2845.             this.render();
  2846.         }
  2847.         return this.el;
  2848.     },
  2849.     addSeparator : function(){
  2850.         return this.addItem(new Ext.menu.Separator());
  2851.     },
  2852.     addElement : function(el){
  2853.         return this.addItem(new Ext.menu.BaseItem(el));
  2854.     },
  2855.     addItem : function(item){
  2856.         this.items.add(item);
  2857.         if(this.ul){
  2858.             var li = document.createElement("li");
  2859.             li.className = "x-menu-list-item";
  2860.             this.ul.dom.appendChild(li);
  2861.             item.render(li, this);
  2862.             this.delayAutoWidth();
  2863.         }
  2864.         return item;
  2865.     },
  2866.     addMenuItem : function(config){
  2867.         if(!(config instanceof Ext.menu.Item)){
  2868.             if(typeof config.checked == "boolean"){                 config = new Ext.menu.CheckItem(config);
  2869.             }else{
  2870.                 config = new Ext.menu.Item(config);
  2871.             }
  2872.         }
  2873.         return this.addItem(config);
  2874.     },
  2875.     addText : function(text){
  2876.         return this.addItem(new Ext.menu.TextItem(text));
  2877.     },
  2878.     insert : function(index, item){
  2879.         this.items.insert(index, item);
  2880.         if(this.ul){
  2881.             var li = document.createElement("li");
  2882.             li.className = "x-menu-list-item";
  2883.             this.ul.dom.insertBefore(li, this.ul.dom.childNodes[index]);
  2884.             item.render(li, this);
  2885.             this.delayAutoWidth();
  2886.         }
  2887.         return item;
  2888.     },
  2889.     remove : function(item){
  2890.         this.items.removeKey(item.id);
  2891.         item.destroy();
  2892.     },
  2893.     removeAll : function(){
  2894.         var f;
  2895.         while(f = this.items.first()){
  2896.             this.remove(f);
  2897.         }
  2898.     },
  2899.     destroy : function(){
  2900.         this.beforeDestroy();
  2901.         Ext.menu.MenuMgr.unregister(this);
  2902.         if (this.keyNav) {
  2903.             this.keyNav.disable();
  2904.         }
  2905.         this.removeAll();
  2906.         if (this.ul) {
  2907.             this.ul.removeAllListeners();
  2908.         }
  2909.         if (this.el) {
  2910.             this.el.destroy();
  2911.         }
  2912.     },
  2913.         beforeDestroy : Ext.emptyFn
  2914. });
  2915. Ext.menu.MenuNav = function(menu){
  2916.     Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
  2917.     this.scope = this.menu = menu;
  2918. };
  2919. Ext.extend(Ext.menu.MenuNav, Ext.KeyNav, {
  2920.     doRelay : function(e, h){
  2921.         var k = e.getKey();
  2922.         if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
  2923.             this.menu.tryActivate(0, 1);
  2924.             return false;
  2925.         }
  2926.         return h.call(this.scope || this, e, this.menu);
  2927.     },
  2928.     up : function(e, m){
  2929.         if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
  2930.             m.tryActivate(m.items.length-1, -1);
  2931.         }
  2932.     },
  2933.     down : function(e, m){
  2934.         if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
  2935.             m.tryActivate(0, 1);
  2936.         }
  2937.     },
  2938.     right : function(e, m){
  2939.         if(m.activeItem){
  2940.             m.activeItem.expandMenu(true);
  2941.         }
  2942.     },
  2943.     left : function(e, m){
  2944.         m.hide();
  2945.         if(m.parentMenu && m.parentMenu.activeItem){
  2946.             m.parentMenu.activeItem.activate();
  2947.         }
  2948.     },
  2949.     enter : function(e, m){
  2950.         if(m.activeItem){
  2951.             e.stopPropagation();
  2952.             m.activeItem.onClick(e);
  2953.             m.fireEvent("click", this, m.activeItem);
  2954.             return true;
  2955.         }
  2956.     }
  2957. });
  2958. Ext.menu.MenuMgr = function(){
  2959.    var menus, active, groups = {}, attached = false, lastShow = new Date();
  2960.       function init(){
  2961.        menus = {};
  2962.        active = new Ext.util.MixedCollection();
  2963.        Ext.getDoc().addKeyListener(27, function(){
  2964.            if(active.length > 0){
  2965.                hideAll();
  2966.            }
  2967.        });
  2968.    }
  2969.       function hideAll(){
  2970.        if(active && active.length > 0){
  2971.            var c = active.clone();
  2972.            c.each(function(m){
  2973.                m.hide();
  2974.            });
  2975.        }
  2976.    }
  2977.       function onHide(m){
  2978.        active.remove(m);
  2979.        if(active.length < 1){
  2980.            Ext.getDoc().un("mousedown", onMouseDown);
  2981.            attached = false;
  2982.        }
  2983.    }
  2984.       function onShow(m){
  2985.        var last = active.last();
  2986.        lastShow = new Date();
  2987.        active.add(m);
  2988.        if(!attached){
  2989.            Ext.getDoc().on("mousedown", onMouseDown);
  2990.            attached = true;
  2991.        }
  2992.        if(m.parentMenu){
  2993.           m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
  2994.           m.parentMenu.activeChild = m;
  2995.        }else if(last && last.isVisible()){
  2996.           m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
  2997.        }
  2998.    }
  2999.       function onBeforeHide(m){
  3000.        if(m.activeChild){
  3001.            m.activeChild.hide();
  3002.        }
  3003.        if(m.autoHideTimer){
  3004.            clearTimeout(m.autoHideTimer);
  3005.            delete m.autoHideTimer;
  3006.        }
  3007.    }
  3008.       function onBeforeShow(m){
  3009.        var pm = m.parentMenu;
  3010.        if(!pm && !m.allowOtherMenus){
  3011.            hideAll();
  3012.        }else if(pm && pm.activeChild){
  3013.            pm.activeChild.hide();
  3014.        }
  3015.    }
  3016.       function onMouseDown(e){
  3017.        if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
  3018.            hideAll();
  3019.        }
  3020.    }
  3021.       function onBeforeCheck(mi, state){
  3022.        if(state){
  3023.            var g = groups[mi.group];
  3024.            for(var i = 0, l = g.length; i < l; i++){
  3025.                if(g[i] != mi){
  3026.                    g[i].setChecked(false);
  3027.                }
  3028.            }
  3029.        }
  3030.    }
  3031.    return {
  3032.        hideAll : function(){
  3033.             hideAll();
  3034.        },
  3035.               register : function(menu){
  3036.            if(!menus){
  3037.                init();
  3038.            }
  3039.            menus[menu.id] = menu;
  3040.            menu.on("beforehide", onBeforeHide);
  3041.            menu.on("hide", onHide);
  3042.            menu.on("beforeshow", onBeforeShow);
  3043.            menu.on("show", onShow);
  3044.            var g = menu.group;
  3045.            if(g && menu.events["checkchange"]){
  3046.                if(!groups[g]){
  3047.                    groups[g] = [];
  3048.                }
  3049.                groups[g].push(menu);
  3050.                menu.on("checkchange", onCheck);
  3051.            }
  3052.        },
  3053.        get : function(menu){
  3054.            if(typeof menu == "string"){                if(!menus){                     return null;
  3055.                }
  3056.                return menus[menu];
  3057.            }else if(menu.events){                 return menu;
  3058.            }else if(typeof menu.length == 'number'){                return new Ext.menu.Menu({items:menu});
  3059.            }else{                return new Ext.menu.Menu(menu);
  3060.            }
  3061.        },
  3062.               unregister : function(menu){
  3063.            delete menus[menu.id];
  3064.            menu.un("beforehide", onBeforeHide);
  3065.            menu.un("hide", onHide);
  3066.            menu.un("beforeshow", onBeforeShow);
  3067.            menu.un("show", onShow);
  3068.            var g = menu.group;
  3069.            if(g && menu.events["checkchange"]){
  3070.                groups[g].remove(menu);
  3071.                menu.un("checkchange", onCheck);
  3072.            }
  3073.        },
  3074.               registerCheckable : function(menuItem){
  3075.            var g = menuItem.group;
  3076.            if(g){
  3077.                if(!groups[g]){
  3078.                    groups[g] = [];
  3079.                }
  3080.                groups[g].push(menuItem);
  3081.                menuItem.on("beforecheckchange", onBeforeCheck);
  3082.            }
  3083.        },
  3084.               unregisterCheckable : function(menuItem){
  3085.            var g = menuItem.group;
  3086.            if(g){
  3087.                groups[g].remove(menuItem);
  3088.                menuItem.un("beforecheckchange", onBeforeCheck);
  3089.            }
  3090.        },
  3091.        getCheckedItem : function(groupId){
  3092.            var g = groups[groupId];
  3093.            if(g){
  3094.                for(var i = 0, l = g.length; i < l; i++){
  3095.                    if(g[i].checked){
  3096.                        return g[i];
  3097.                    }
  3098.                }
  3099.            }
  3100.            return null;
  3101.        },
  3102.        setCheckedItem : function(groupId, itemId){
  3103.            var g = groups[groupId];
  3104.            if(g){
  3105.                for(var i = 0, l = g.length; i < l; i++){
  3106.                    if(g[i].id == itemId){
  3107.                        g[i].setChecked(true);
  3108.                    }
  3109.                }
  3110.            }
  3111.            return null;
  3112.        }
  3113.    };
  3114. }();
  3115. Ext.menu.BaseItem = function(config){
  3116.     Ext.menu.BaseItem.superclass.constructor.call(this, config);
  3117.     this.addEvents(
  3118.         'click',
  3119.         'activate',
  3120.         'deactivate'
  3121.     );
  3122.     if(this.handler){
  3123.         this.on("click", this.handler, this.scope);
  3124.     }
  3125. };
  3126. Ext.extend(Ext.menu.BaseItem, Ext.Component, {
  3127.     canActivate : false,
  3128.     activeClass : "x-menu-item-active",
  3129.     hideOnClick : true,
  3130.     hideDelay : 100,
  3131.         ctype: "Ext.menu.BaseItem",
  3132.         actionMode : "container",
  3133.         render : function(container, parentMenu){
  3134.         this.parentMenu = parentMenu;
  3135.         Ext.menu.BaseItem.superclass.render.call(this, container);
  3136.         this.container.menuItemId = this.id;
  3137.     },
  3138.         onRender : function(container, position){
  3139.         this.el = Ext.get(this.el);
  3140.         container.dom.appendChild(this.el.dom);
  3141.     },
  3142.     setHandler : function(handler, scope){
  3143.         if(this.handler){
  3144.             this.un("click", this.handler, this.scope);
  3145.         }
  3146.         this.on("click", this.handler = handler, this.scope = scope);
  3147.     },
  3148.         onClick : function(e){
  3149.         if(!this.disabled && this.fireEvent("click", this, e) !== false
  3150.                 && this.parentMenu.fireEvent("itemclick", this, e) !== false){
  3151.             this.handleClick(e);
  3152.         }else{
  3153.             e.stopEvent();
  3154.         }
  3155.     },
  3156.         activate : function(){
  3157.         if(this.disabled){
  3158.             return false;
  3159.         }
  3160.         var li = this.container;
  3161.         li.addClass(this.activeClass);
  3162.         this.region = li.getRegion().adjust(2, 2, -2, -2);
  3163.         this.fireEvent("activate", this);
  3164.         return true;
  3165.     },
  3166.         deactivate : function(){
  3167.         this.container.removeClass(this.activeClass);
  3168.         this.fireEvent("deactivate", this);
  3169.     },
  3170.         shouldDeactivate : function(e){
  3171.         return !this.region || !this.region.contains(e.getPoint());
  3172.     },
  3173.         handleClick : function(e){
  3174.         if(this.hideOnClick){
  3175.             this.parentMenu.hide.defer(this.hideDelay, this.parentMenu, [true]);
  3176.         }
  3177.     },
  3178.         expandMenu : function(autoActivate){
  3179.             },
  3180.         hideMenu : function(){
  3181.             }
  3182. });
  3183. Ext.menu.TextItem = function(text){
  3184.     this.text = text;
  3185.     Ext.menu.TextItem.superclass.constructor.call(this);
  3186. };
  3187. Ext.extend(Ext.menu.TextItem, Ext.menu.BaseItem, {
  3188.     hideOnClick : false,
  3189.     itemCls : "x-menu-text",
  3190.         onRender : function(){
  3191.         var s = document.createElement("span");
  3192.         s.className = this.itemCls;
  3193.         s.innerHTML = this.text;
  3194.         this.el = s;
  3195.         Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
  3196.     }
  3197. });
  3198. Ext.menu.Separator = function(config){
  3199.     Ext.menu.Separator.superclass.constructor.call(this, config);
  3200. };
  3201. Ext.extend(Ext.menu.Separator, Ext.menu.BaseItem, {
  3202.     itemCls : "x-menu-sep",
  3203.     hideOnClick : false,
  3204.         onRender : function(li){
  3205.         var s = document.createElement("span");
  3206.         s.className = this.itemCls;
  3207.         s.innerHTML = "&#160;";
  3208.         this.el = s;
  3209.         li.addClass("x-menu-sep-li");
  3210.         Ext.menu.Separator.superclass.onRender.apply(this, arguments);
  3211.     }
  3212. });
  3213. Ext.menu.Item = function(config){
  3214.     Ext.menu.Item.superclass.constructor.call(this, config);
  3215.     if(this.menu){
  3216.         this.menu = Ext.menu.MenuMgr.get(this.menu);
  3217.     }
  3218. };
  3219. Ext.extend(Ext.menu.Item, Ext.menu.BaseItem, {
  3220.     itemCls : "x-menu-item",
  3221.     canActivate : true,
  3222.     showDelay: 200,
  3223.         hideDelay: 200,
  3224.         ctype: "Ext.menu.Item",
  3225.         onRender : function(container, position){
  3226.         var el = document.createElement("a");
  3227.         el.hideFocus = true;
  3228.         el.unselectable = "on";
  3229.         el.href = this.href || "#";
  3230.         if(this.hrefTarget){
  3231.             el.target = this.hrefTarget;
  3232.         }
  3233.         el.className = this.itemCls + (this.menu ?  " x-menu-item-arrow" : "") + (this.cls ?  " " + this.cls : "");
  3234.         el.innerHTML = String.format(
  3235.                 '<img src="{0}" class="x-menu-item-icon {2}" />{1}',
  3236.                 this.icon || Ext.BLANK_IMAGE_URL, this.itemText||this.text, this.iconCls || '');
  3237.         this.el = el;
  3238.         Ext.menu.Item.superclass.onRender.call(this, container, position);
  3239.     },
  3240.     setText : function(text){
  3241.         this.text = text;
  3242.         if(this.rendered){
  3243.             this.el.update(String.format(
  3244.                 '<img src="{0}" class="x-menu-item-icon {2}">{1}',
  3245.                 this.icon || Ext.BLANK_IMAGE_URL, this.text, this.iconCls || ''));
  3246.             this.parentMenu.autoWidth();
  3247.         }
  3248.     },
  3249.     setIconClass : function(cls){
  3250.         var oldCls = this.iconCls;
  3251.         this.iconCls = cls;
  3252.         if(this.rendered){
  3253.             this.el.child('img.x-menu-item-icon').replaceClass(oldCls, this.iconCls);
  3254.         }
  3255.     },
  3256.         handleClick : function(e){
  3257.         if(!this.href){             e.stopEvent();
  3258.         }
  3259.         Ext.menu.Item.superclass.handleClick.apply(this, arguments);
  3260.     },
  3261.         activate : function(autoExpand){
  3262.         if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
  3263.             this.focus();
  3264.             if(autoExpand){
  3265.                 this.expandMenu();
  3266.             }
  3267.         }
  3268.         return true;
  3269.     },
  3270.         shouldDeactivate : function(e){
  3271.         if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
  3272.             if(this.menu && this.menu.isVisible()){
  3273.                 return !this.menu.getEl().getRegion().contains(e.getPoint());
  3274.             }
  3275.             return true;
  3276.         }
  3277.         return false;
  3278.     },
  3279.         deactivate : function(){
  3280.         Ext.menu.Item.superclass.deactivate.apply(this, arguments);
  3281.         this.hideMenu();
  3282.     },
  3283.         expandMenu : function(autoActivate){
  3284.         if(!this.disabled && this.menu){
  3285.             clearTimeout(this.hideTimer);
  3286.             delete this.hideTimer;
  3287.             if(!this.menu.isVisible() && !this.showTimer){
  3288.                 this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
  3289.             }else if (this.menu.isVisible() && autoActivate){
  3290.                 this.menu.tryActivate(0, 1);
  3291.             }
  3292.         }
  3293.     },
  3294.         deferExpand : function(autoActivate){
  3295.         delete this.showTimer;
  3296.         this.menu.show(this.container, this.parentMenu.subMenuAlign || "tl-tr?", this.parentMenu);
  3297.         if(autoActivate){
  3298.             this.menu.tryActivate(0, 1);
  3299.         }
  3300.     },
  3301.         hideMenu : function(){
  3302.         clearTimeout(this.showTimer);
  3303.         delete this.showTimer;
  3304.         if(!this.hideTimer && this.menu && this.menu.isVisible()){
  3305.             this.hideTimer = this.deferHide.defer(this.hideDelay, this);
  3306.         }
  3307.     },
  3308.         deferHide : function(){
  3309.         delete this.hideTimer;
  3310.         this.menu.hide();
  3311.     }
  3312. });
  3313. Ext.menu.CheckItem = function(config){
  3314.     Ext.menu.CheckItem.superclass.constructor.call(this, config);
  3315.     this.addEvents(
  3316.         "beforecheckchange" ,
  3317.         "checkchange"
  3318.     );
  3319.     if(this.checkHandler){
  3320.         this.on('checkchange', this.checkHandler, this.scope);
  3321.     }
  3322.     Ext.menu.MenuMgr.registerCheckable(this);
  3323. };
  3324. Ext.extend(Ext.menu.CheckItem, Ext.menu.Item, {
  3325.     itemCls : "x-menu-item x-menu-check-item",
  3326.     groupClass : "x-menu-group-item",
  3327.     checked: false,
  3328.         ctype: "Ext.menu.CheckItem",
  3329.         onRender : function(c){
  3330.         Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
  3331.         if(this.group){
  3332.             this.el.addClass(this.groupClass);
  3333.         }
  3334.         if(this.checked){
  3335.             this.checked = false;
  3336.             this.setChecked(true, true);
  3337.         }
  3338.     },
  3339.         destroy : function(){
  3340.         Ext.menu.MenuMgr.unregisterCheckable(this);
  3341.         Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
  3342.     },
  3343.     setChecked : function(state, suppressEvent){
  3344.         if(this.checked != state && this.fireEvent("beforecheckchange", this, state) !== false){
  3345.             if(this.container){
  3346.                 this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
  3347.             }
  3348.             this.checked = state;
  3349.             if(suppressEvent !== true){
  3350.                 this.fireEvent("checkchange", this, state);
  3351.             }
  3352.         }
  3353.     },
  3354.         handleClick : function(e){
  3355.        if(!this.disabled && !(this.checked && this.group)){           this.setChecked(!this.checked);
  3356.        }
  3357.        Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
  3358.     }
  3359. });