commit extjs-2.2.1
[extjs.git] / air / samples / tasks / ext-2.0 / ext-all.js
1 /*\r
2  * Ext JS Library 0.30\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 /*\r
10  * Ext JS Library 2.0.2\r
11  * Copyright(c) 2006-2008, Ext JS, LLC.\r
12  * licensing@extjs.com\r
13  * \r
14  * http://extjs.com/license\r
15  */\r
16 \r
17 \r
18 Ext.DomHelper = function(){\r
19     var tempTableEl = null;\r
20     var emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i;\r
21     var tableRe = /^table|tbody|tr|td$/i;\r
22     \r
23     
24     var createHtml = function(o){\r
25         if(typeof o == 'string'){\r
26             return o;\r
27         }\r
28         var b = "";\r
29         if (Ext.isArray(o)) {\r
30             for (var i = 0, l = o.length; i < l; i++) {\r
31                 b += createHtml(o[i]);\r
32             }\r
33             return b;\r
34         }\r
35         if(!o.tag){\r
36             o.tag = "div";\r
37         }\r
38         b += "<" + o.tag;\r
39         for(var attr in o){\r
40             if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || typeof o[attr] == "function") continue;\r
41             if(attr == "style"){\r
42                 var s = o["style"];\r
43                 if(typeof s == "function"){\r
44                     s = s.call();\r
45                 }\r
46                 if(typeof s == "string"){\r
47                     b += ' style="' + s + '"';\r
48                 }else if(typeof s == "object"){\r
49                     b += ' style="';\r
50                     for(var key in s){\r
51                         if(typeof s[key] != "function"){\r
52                             b += key + ":" + s[key] + ";";\r
53                         }\r
54                     }\r
55                     b += '"';\r
56                 }\r
57             }else{\r
58                 if(attr == "cls"){\r
59                     b += ' class="' + o["cls"] + '"';\r
60                 }else if(attr == "htmlFor"){\r
61                     b += ' for="' + o["htmlFor"] + '"';\r
62                 }else{\r
63                     b += " " + attr + '="' + o[attr] + '"';\r
64                 }\r
65             }\r
66         }\r
67         if(emptyTags.test(o.tag)){\r
68             b += "/>";\r
69         }else{\r
70             b += ">";\r
71             var cn = o.children || o.cn;\r
72             if(cn){\r
73                 b += createHtml(cn);\r
74             } else if(o.html){\r
75                 b += o.html;\r
76             }\r
77             b += "</" + o.tag + ">";\r
78         }\r
79         return b;\r
80     };\r
81 \r
82     
83     \r
84     var createDom = function(o, parentNode){\r
85         var el;\r
86         if (Ext.isArray(o)) {                       
87             el = document.createDocumentFragment(); 
88             for(var i = 0, l = o.length; i < l; i++) {\r
89                 createDom(o[i], el);\r
90             }\r
91         } else if (typeof o == "string)") {         
92             el = document.createTextNode(o);\r
93         } else {\r
94             el = document.createElement(o.tag||'div');\r
95             var useSet = !!el.setAttribute; 
96             for(var attr in o){\r
97                 if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || attr == "style" || typeof o[attr] == "function") continue;\r
98                 if(attr=="cls"){\r
99                     el.className = o["cls"];\r
100                 }else{\r
101                     if(useSet) el.setAttribute(attr, o[attr]);\r
102                     else el[attr] = o[attr];\r
103                 }\r
104             }\r
105             Ext.DomHelper.applyStyles(el, o.style);\r
106             var cn = o.children || o.cn;\r
107             if(cn){\r
108                 createDom(cn, el);\r
109             } else if(o.html){\r
110                 el.innerHTML = o.html;\r
111             }\r
112         }\r
113         if(parentNode){\r
114            parentNode.appendChild(el);\r
115         }\r
116         return el;\r
117     };\r
118 \r
119     var ieTable = function(depth, s, h, e){\r
120         tempTableEl.innerHTML = [s, h, e].join('');\r
121         var i = -1, el = tempTableEl;\r
122         while(++i < depth){\r
123             el = el.firstChild;\r
124         }\r
125         return el;\r
126     };\r
127 \r
128     
129     var ts = '<table>',\r
130         te = '</table>',\r
131         tbs = ts+'<tbody>',\r
132         tbe = '</tbody>'+te,\r
133         trs = tbs + '<tr>',\r
134         tre = '</tr>'+tbe;\r
135 \r
136     \r
137     var insertIntoTable = function(tag, where, el, html){\r
138         if(!tempTableEl){\r
139             tempTableEl = document.createElement('div');\r
140         }\r
141         var node;\r
142         var before = null;\r
143         if(tag == 'td'){\r
144             if(where == 'afterbegin' || where == 'beforeend'){ 
145                 return;\r
146             }\r
147             if(where == 'beforebegin'){\r
148                 before = el;\r
149                 el = el.parentNode;\r
150             } else{\r
151                 before = el.nextSibling;\r
152                 el = el.parentNode;\r
153             }\r
154             node = ieTable(4, trs, html, tre);\r
155         }\r
156         else if(tag == 'tr'){\r
157             if(where == 'beforebegin'){\r
158                 before = el;\r
159                 el = el.parentNode;\r
160                 node = ieTable(3, tbs, html, tbe);\r
161             } else if(where == 'afterend'){\r
162                 before = el.nextSibling;\r
163                 el = el.parentNode;\r
164                 node = ieTable(3, tbs, html, tbe);\r
165             } else{ 
166                 if(where == 'afterbegin'){\r
167                     before = el.firstChild;\r
168                 }\r
169                 node = ieTable(4, trs, html, tre);\r
170             }\r
171         } else if(tag == 'tbody'){\r
172             if(where == 'beforebegin'){\r
173                 before = el;\r
174                 el = el.parentNode;\r
175                 node = ieTable(2, ts, html, te);\r
176             } else if(where == 'afterend'){\r
177                 before = el.nextSibling;\r
178                 el = el.parentNode;\r
179                 node = ieTable(2, ts, html, te);\r
180             } else{\r
181                 if(where == 'afterbegin'){\r
182                     before = el.firstChild;\r
183                 }\r
184                 node = ieTable(3, tbs, html, tbe);\r
185             }\r
186         } else{ 
187             if(where == 'beforebegin' || where == 'afterend'){ 
188                 return;\r
189             }\r
190             if(where == 'afterbegin'){\r
191                 before = el.firstChild;\r
192             }\r
193             node = ieTable(2, ts, html, te);\r
194         }\r
195         el.insertBefore(node, before);\r
196         return node;\r
197     };\r
198 \r
199 \r
200     return {\r
201     \r
202     useDom : false,\r
203 \r
204     \r
205     markup : function(o){\r
206         return createHtml(o);\r
207     },\r
208 \r
209     \r
210     applyStyles : function(el, styles){\r
211         if(styles){\r
212            el = Ext.fly(el);\r
213            if(typeof styles == "string"){\r
214                var re = /\s?([a-z\-]*)\:\s?([^;]*);?/gi;\r
215                var matches;\r
216                while ((matches = re.exec(styles)) != null){\r
217                    el.setStyle(matches[1], matches[2]);\r
218                }\r
219            }else if (typeof styles == "object"){\r
220                for (var style in styles){\r
221                   el.setStyle(style, styles[style]);\r
222                }\r
223            }else if (typeof styles == "function"){\r
224                 Ext.DomHelper.applyStyles(el, styles.call());\r
225            }\r
226         }\r
227     },\r
228 \r
229     \r
230     insertHtml : function(where, el, html){\r
231         where = where.toLowerCase();\r
232         if(el.insertAdjacentHTML){\r
233             if(tableRe.test(el.tagName)){\r
234                 var rs;\r
235                 if(rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html)){\r
236                     return rs;\r
237                 }\r
238             }\r
239             switch(where){\r
240                 case "beforebegin":\r
241                     el.insertAdjacentHTML('BeforeBegin', html);\r
242                     return el.previousSibling;\r
243                 case "afterbegin":\r
244                     el.insertAdjacentHTML('AfterBegin', html);\r
245                     return el.firstChild;\r
246                 case "beforeend":\r
247                     el.insertAdjacentHTML('BeforeEnd', html);\r
248                     return el.lastChild;\r
249                 case "afterend":\r
250                     el.insertAdjacentHTML('AfterEnd', html);\r
251                     return el.nextSibling;\r
252             }\r
253             throw 'Illegal insertion point -> "' + where + '"';\r
254         }\r
255         var range = el.ownerDocument.createRange();\r
256         var frag;\r
257         switch(where){\r
258              case "beforebegin":\r
259                 range.setStartBefore(el);\r
260                 frag = range.createContextualFragment(html);\r
261                 el.parentNode.insertBefore(frag, el);\r
262                 return el.previousSibling;\r
263              case "afterbegin":\r
264                 if(el.firstChild){\r
265                     range.setStartBefore(el.firstChild);\r
266                     frag = range.createContextualFragment(html);\r
267                     el.insertBefore(frag, el.firstChild);\r
268                     return el.firstChild;\r
269                 }else{\r
270                     el.innerHTML = html;\r
271                     return el.firstChild;\r
272                 }\r
273             case "beforeend":\r
274                 if(el.lastChild){\r
275                     range.setStartAfter(el.lastChild);\r
276                     frag = range.createContextualFragment(html);\r
277                     el.appendChild(frag);\r
278                     return el.lastChild;\r
279                 }else{\r
280                     el.innerHTML = html;\r
281                     return el.lastChild;\r
282                 }\r
283             case "afterend":\r
284                 range.setStartAfter(el);\r
285                 frag = range.createContextualFragment(html);\r
286                 el.parentNode.insertBefore(frag, el.nextSibling);\r
287                 return el.nextSibling;\r
288             }\r
289             throw 'Illegal insertion point -> "' + where + '"';\r
290     },\r
291 \r
292     \r
293     insertBefore : function(el, o, returnElement){\r
294         return this.doInsert(el, o, returnElement, "beforeBegin");\r
295     },\r
296 \r
297     \r
298     insertAfter : function(el, o, returnElement){\r
299         return this.doInsert(el, o, returnElement, "afterEnd", "nextSibling");\r
300     },\r
301 \r
302     \r
303     insertFirst : function(el, o, returnElement){\r
304         return this.doInsert(el, o, returnElement, "afterBegin", "firstChild");\r
305     },\r
306 \r
307     
308     doInsert : function(el, o, returnElement, pos, sibling){\r
309         el = Ext.getDom(el);\r
310         var newNode;\r
311         if(this.useDom){\r
312             newNode = createDom(o, null);\r
313             (sibling === "firstChild" ? el : el.parentNode).insertBefore(newNode, sibling ? el[sibling] : el);\r
314         }else{\r
315             var html = createHtml(o);\r
316             newNode = this.insertHtml(pos, el, html);\r
317         }\r
318         return returnElement ? Ext.get(newNode, true) : newNode;\r
319     },\r
320 \r
321     \r
322     append : function(el, o, returnElement){\r
323         el = Ext.getDom(el);\r
324         var newNode;\r
325         if(this.useDom){\r
326             newNode = createDom(o, null);\r
327             el.appendChild(newNode);\r
328         }else{\r
329             var html = createHtml(o);\r
330             newNode = this.insertHtml("beforeEnd", el, html);\r
331         }\r
332         return returnElement ? Ext.get(newNode, true) : newNode;\r
333     },\r
334 \r
335     \r
336     overwrite : function(el, o, returnElement){\r
337         el = Ext.getDom(el);\r
338         el.innerHTML = createHtml(o);\r
339         return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;\r
340     },\r
341 \r
342     \r
343     createTemplate : function(o){\r
344         var html = createHtml(o);\r
345         return new Ext.Template(html);\r
346     }\r
347     };\r
348 }();\r
349
350 \r
351 Ext.Template = function(html){\r
352     var a = arguments;\r
353     if(Ext.isArray(html)){\r
354         html = html.join("");\r
355     }else if(a.length > 1){\r
356         var buf = [];\r
357         for(var i = 0, len = a.length; i < len; i++){\r
358             if(typeof a[i] == 'object'){\r
359                 Ext.apply(this, a[i]);\r
360             }else{\r
361                 buf[buf.length] = a[i];\r
362             }\r
363         }\r
364         html = buf.join('');\r
365     }\r
366     \r
367     this.html = html;\r
368     if(this.compiled){\r
369         this.compile();   \r
370     }\r
371 };\r
372 Ext.Template.prototype = {\r
373     \r
374     applyTemplate : function(values){\r
375         if(this.compiled){\r
376             return this.compiled(values);\r
377         }\r
378         var useF = this.disableFormats !== true;\r
379         var fm = Ext.util.Format, tpl = this;\r
380         var fn = function(m, name, format, args){\r
381             if(format && useF){\r
382                 if(format.substr(0, 5) == "this."){\r
383                     return tpl.call(format.substr(5), values[name], values);\r
384                 }else{\r
385                     if(args){\r
386                         
387                         
388                         
389                         var re = /^\s*['"](.*)["']\s*$/;\r
390                         args = args.split(',');\r
391                         for(var i = 0, len = args.length; i < len; i++){\r
392                             args[i] = args[i].replace(re, "$1");\r
393                         }\r
394                         args = [values[name]].concat(args);\r
395                     }else{\r
396                         args = [values[name]];\r
397                     }\r
398                     return fm[format].apply(fm, args);\r
399                 }\r
400             }else{\r
401                 return values[name] !== undefined ? values[name] : "";\r
402             }\r
403         };\r
404         return this.html.replace(this.re, fn);\r
405     },\r
406     \r
407     \r
408     set : function(html, compile){\r
409         this.html = html;\r
410         this.compiled = null;\r
411         if(compile){\r
412             this.compile();\r
413         }\r
414         return this;\r
415     },\r
416     \r
417     \r
418     disableFormats : false,\r
419     \r
420     \r
421     re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,\r
422     \r
423     \r
424     compile : function(){\r
425         var fm = Ext.util.Format;\r
426         var useF = this.disableFormats !== true;\r
427         var sep = Ext.isGecko ? "+" : ",";\r
428         var fn = function(m, name, format, args){\r
429             if(format && useF){\r
430                 args = args ? ',' + args : "";\r
431                 if(format.substr(0, 5) != "this."){\r
432                     format = "fm." + format + '(';\r
433                 }else{\r
434                     format = 'this.call("'+ format.substr(5) + '", ';\r
435                     args = ", values";\r
436                 }\r
437             }else{\r
438                 args= ''; format = "(values['" + name + "'] == undefined ? '' : ";\r
439             }\r
440             return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";\r
441         };\r
442         var body;\r
443         
444         if(Ext.isGecko){\r
445             body = "this.compiled = function(values){ return '" +\r
446                    this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +\r
447                     "';};";\r
448         }else{\r
449             body = ["this.compiled = function(values){ return ['"];\r
450             body.push(this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn));\r
451             body.push("'].join('');};");\r
452             body = body.join('');\r
453         }\r
454         eval(body);\r
455         return this;\r
456     },\r
457     \r
458     
459     call : function(fnName, value, allValues){\r
460         return this[fnName](value, allValues);\r
461     },\r
462     \r
463     \r
464     insertFirst: function(el, values, returnElement){\r
465         return this.doInsert('afterBegin', el, values, returnElement);\r
466     },\r
467 \r
468     \r
469     insertBefore: function(el, values, returnElement){\r
470         return this.doInsert('beforeBegin', el, values, returnElement);\r
471     },\r
472 \r
473     \r
474     insertAfter : function(el, values, returnElement){\r
475         return this.doInsert('afterEnd', el, values, returnElement);\r
476     },\r
477     \r
478     \r
479     append : function(el, values, returnElement){\r
480         return this.doInsert('beforeEnd', el, values, returnElement);\r
481     },\r
482 \r
483     doInsert : function(where, el, values, returnEl){\r
484         el = Ext.getDom(el);\r
485         var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));\r
486         return returnEl ? Ext.get(newNode, true) : newNode;\r
487     },\r
488 \r
489     \r
490     overwrite : function(el, values, returnElement){\r
491         el = Ext.getDom(el);\r
492         el.innerHTML = this.applyTemplate(values);\r
493         return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;\r
494     }\r
495 };\r
496 \r
497 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;\r
498 \r
499
500 Ext.DomHelper.Template = Ext.Template;\r
501 \r
502 \r
503 Ext.Template.from = function(el, config){\r
504     el = Ext.getDom(el);\r
505     return new Ext.Template(el.value || el.innerHTML, config || '');\r
506 };
507 \r
508 \r
509 Ext.DomQuery = function(){\r
510     var cache = {}, simpleCache = {}, valueCache = {};\r
511     var nonSpace = /\S/;\r
512     var trimRe = /^\s+|\s+$/g;\r
513     var tplRe = /\{(\d+)\}/g;\r
514     var modeRe = /^(\s?[\/>+~]\s?|\s|$)/;\r
515     var tagTokenRe = /^(#)?([\w-\*]+)/;\r
516     var nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/;\r
517 \r
518     function child(p, index){\r
519         var i = 0;\r
520         var n = p.firstChild;\r
521         while(n){\r
522             if(n.nodeType == 1){\r
523                if(++i == index){\r
524                    return n;\r
525                }\r
526             }\r
527             n = n.nextSibling;\r
528         }\r
529         return null;\r
530     };\r
531 \r
532     function next(n){\r
533         while((n = n.nextSibling) && n.nodeType != 1);\r
534         return n;\r
535     };\r
536 \r
537     function prev(n){\r
538         while((n = n.previousSibling) && n.nodeType != 1);\r
539         return n;\r
540     };\r
541 \r
542     function children(d){\r
543         var n = d.firstChild, ni = -1;\r
544             while(n){\r
545                 var nx = n.nextSibling;\r
546                 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){\r
547                     d.removeChild(n);\r
548                 }else{\r
549                     n.nodeIndex = ++ni;\r
550                 }\r
551                 n = nx;\r
552             }\r
553             return this;\r
554         };\r
555 \r
556     function byClassName(c, a, v){\r
557         if(!v){\r
558             return c;\r
559         }\r
560         var r = [], ri = -1, cn;\r
561         for(var i = 0, ci; ci = c[i]; i++){\r
562             if((' '+ci.className+' ').indexOf(v) != -1){\r
563                 r[++ri] = ci;\r
564             }\r
565         }\r
566         return r;\r
567     };\r
568 \r
569     function attrValue(n, attr){\r
570         if(!n.tagName && typeof n.length != "undefined"){\r
571             n = n[0];\r
572         }\r
573         if(!n){\r
574             return null;\r
575         }\r
576         if(attr == "for"){\r
577             return n.htmlFor;\r
578         }\r
579         if(attr == "class" || attr == "className"){\r
580             return n.className;\r
581         }\r
582         return n.getAttribute(attr) || n[attr];\r
583 \r
584     };\r
585 \r
586     function getNodes(ns, mode, tagName){\r
587         var result = [], ri = -1, cs;\r
588         if(!ns){\r
589             return result;\r
590         }\r
591         tagName = tagName || "*";\r
592         if(typeof ns.getElementsByTagName != "undefined"){\r
593             ns = [ns];\r
594         }\r
595         if(!mode){\r
596             for(var i = 0, ni; ni = ns[i]; i++){\r
597                 cs = ni.getElementsByTagName(tagName);\r
598                 for(var j = 0, ci; ci = cs[j]; j++){\r
599                     result[++ri] = ci;\r
600                 }\r
601             }\r
602         }else if(mode == "/" || mode == ">"){\r
603             var utag = tagName.toUpperCase();\r
604             for(var i = 0, ni, cn; ni = ns[i]; i++){\r
605                 cn = ni.children || ni.childNodes;\r
606                 for(var j = 0, cj; cj = cn[j]; j++){\r
607                     if(cj.nodeName == utag || cj.nodeName == tagName  || tagName == '*'){\r
608                         result[++ri] = cj;\r
609                     }\r
610                 }\r
611             }\r
612         }else if(mode == "+"){\r
613             var utag = tagName.toUpperCase();\r
614             for(var i = 0, n; n = ns[i]; i++){\r
615                 while((n = n.nextSibling) && n.nodeType != 1);\r
616                 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){\r
617                     result[++ri] = n;\r
618                 }\r
619             }\r
620         }else if(mode == "~"){\r
621             for(var i = 0, n; n = ns[i]; i++){\r
622                 while((n = n.nextSibling) && (n.nodeType != 1 || (tagName == '*' || n.tagName.toLowerCase()!=tagName)));\r
623                 if(n){\r
624                     result[++ri] = n;\r
625                 }\r
626             }\r
627         }\r
628         return result;\r
629     };\r
630 \r
631     function concat(a, b){\r
632         if(b.slice){\r
633             return a.concat(b);\r
634         }\r
635         for(var i = 0, l = b.length; i < l; i++){\r
636             a[a.length] = b[i];\r
637         }\r
638         return a;\r
639     }\r
640 \r
641     function byTag(cs, tagName){\r
642         if(cs.tagName || cs == document){\r
643             cs = [cs];\r
644         }\r
645         if(!tagName){\r
646             return cs;\r
647         }\r
648         var r = [], ri = -1;\r
649         tagName = tagName.toLowerCase();\r
650         for(var i = 0, ci; ci = cs[i]; i++){\r
651             if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){\r
652                 r[++ri] = ci;\r
653             }\r
654         }\r
655         return r;\r
656     };\r
657 \r
658     function byId(cs, attr, id){\r
659         if(cs.tagName || cs == document){\r
660             cs = [cs];\r
661         }\r
662         if(!id){\r
663             return cs;\r
664         }\r
665         var r = [], ri = -1;\r
666         for(var i = 0,ci; ci = cs[i]; i++){\r
667             if(ci && ci.id == id){\r
668                 r[++ri] = ci;\r
669                 return r;\r
670             }\r
671         }\r
672         return r;\r
673     };\r
674 \r
675     function byAttribute(cs, attr, value, op, custom){\r
676         var r = [], ri = -1, st = custom=="{";\r
677         var f = Ext.DomQuery.operators[op];\r
678         for(var i = 0, ci; ci = cs[i]; i++){\r
679             var a;\r
680             if(st){\r
681                 a = Ext.DomQuery.getStyle(ci, attr);\r
682             }\r
683             else if(attr == "class" || attr == "className"){\r
684                 a = ci.className;\r
685             }else if(attr == "for"){\r
686                 a = ci.htmlFor;\r
687             }else if(attr == "href"){\r
688                 a = ci.getAttribute("href", 2);\r
689             }else{\r
690                 a = ci.getAttribute(attr);\r
691             }\r
692             if((f && f(a, value)) || (!f && a)){\r
693                 r[++ri] = ci;\r
694             }\r
695         }\r
696         return r;\r
697     };\r
698 \r
699     function byPseudo(cs, name, value){\r
700         return Ext.DomQuery.pseudos[name](cs, value);\r
701     };\r
702 \r
703     
704     
705     
706     var isIE = window.ActiveXObject ? true : false;\r
707 \r
708     
709     
710     eval("var batch = 30803;");\r
711 \r
712     var key = 30803;\r
713 \r
714     function nodupIEXml(cs){\r
715         var d = ++key;\r
716         cs[0].setAttribute("_nodup", d);\r
717         var r = [cs[0]];\r
718         for(var i = 1, len = cs.length; i < len; i++){\r
719             var c = cs[i];\r
720             if(!c.getAttribute("_nodup") != d){\r
721                 c.setAttribute("_nodup", d);\r
722                 r[r.length] = c;\r
723             }\r
724         }\r
725         for(var i = 0, len = cs.length; i < len; i++){\r
726             cs[i].removeAttribute("_nodup");\r
727         }\r
728         return r;\r
729     }\r
730 \r
731     function nodup(cs){\r
732         if(!cs){\r
733             return [];\r
734         }\r
735         var len = cs.length, c, i, r = cs, cj, ri = -1;\r
736         if(!len || typeof cs.nodeType != "undefined" || len == 1){\r
737             return cs;\r
738         }\r
739         if(isIE && typeof cs[0].selectSingleNode != "undefined"){\r
740             return nodupIEXml(cs);\r
741         }\r
742         var d = ++key;\r
743         cs[0]._nodup = d;\r
744         for(i = 1; c = cs[i]; i++){\r
745             if(c._nodup != d){\r
746                 c._nodup = d;\r
747             }else{\r
748                 r = [];\r
749                 for(var j = 0; j < i; j++){\r
750                     r[++ri] = cs[j];\r
751                 }\r
752                 for(j = i+1; cj = cs[j]; j++){\r
753                     if(cj._nodup != d){\r
754                         cj._nodup = d;\r
755                         r[++ri] = cj;\r
756                     }\r
757                 }\r
758                 return r;\r
759             }\r
760         }\r
761         return r;\r
762     }\r
763 \r
764     function quickDiffIEXml(c1, c2){\r
765         var d = ++key;\r
766         for(var i = 0, len = c1.length; i < len; i++){\r
767             c1[i].setAttribute("_qdiff", d);\r
768         }\r
769         var r = [];\r
770         for(var i = 0, len = c2.length; i < len; i++){\r
771             if(c2[i].getAttribute("_qdiff") != d){\r
772                 r[r.length] = c2[i];\r
773             }\r
774         }\r
775         for(var i = 0, len = c1.length; i < len; i++){\r
776            c1[i].removeAttribute("_qdiff");\r
777         }\r
778         return r;\r
779     }\r
780 \r
781     function quickDiff(c1, c2){\r
782         var len1 = c1.length;\r
783         if(!len1){\r
784             return c2;\r
785         }\r
786         if(isIE && c1[0].selectSingleNode){\r
787             return quickDiffIEXml(c1, c2);\r
788         }\r
789         var d = ++key;\r
790         for(var i = 0; i < len1; i++){\r
791             c1[i]._qdiff = d;\r
792         }\r
793         var r = [];\r
794         for(var i = 0, len = c2.length; i < len; i++){\r
795             if(c2[i]._qdiff != d){\r
796                 r[r.length] = c2[i];\r
797             }\r
798         }\r
799         return r;\r
800     }\r
801 \r
802     function quickId(ns, mode, root, id){\r
803         if(ns == root){\r
804            var d = root.ownerDocument || root;\r
805            return d.getElementById(id);\r
806         }\r
807         ns = getNodes(ns, mode, "*");\r
808         return byId(ns, null, id);\r
809     }\r
810 \r
811     return {\r
812         getStyle : function(el, name){\r
813             return Ext.fly(el).getStyle(name);\r
814         },\r
815         \r
816         compile : function(path, type){\r
817             type = type || "select";\r
818 \r
819             var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"];\r
820             var q = path, mode, lq;\r
821             var tk = Ext.DomQuery.matchers;\r
822             var tklen = tk.length;\r
823             var mm;\r
824 \r
825             
826             var lmode = q.match(modeRe);\r
827             if(lmode && lmode[1]){\r
828                 fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';\r
829                 q = q.replace(lmode[1], "");\r
830             }\r
831             
832             while(path.substr(0, 1)=="/"){\r
833                 path = path.substr(1);\r
834             }\r
835 \r
836             while(q && lq != q){\r
837                 lq = q;\r
838                 var tm = q.match(tagTokenRe);\r
839                 if(type == "select"){\r
840                     if(tm){\r
841                         if(tm[1] == "#"){\r
842                             fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");';\r
843                         }else{\r
844                             fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");';\r
845                         }\r
846                         q = q.replace(tm[0], "");\r
847                     }else if(q.substr(0, 1) != '@'){\r
848                         fn[fn.length] = 'n = getNodes(n, mode, "*");';\r
849                     }\r
850                 }else{\r
851                     if(tm){\r
852                         if(tm[1] == "#"){\r
853                             fn[fn.length] = 'n = byId(n, null, "'+tm[2]+'");';\r
854                         }else{\r
855                             fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");';\r
856                         }\r
857                         q = q.replace(tm[0], "");\r
858                     }\r
859                 }\r
860                 while(!(mm = q.match(modeRe))){\r
861                     var matched = false;\r
862                     for(var j = 0; j < tklen; j++){\r
863                         var t = tk[j];\r
864                         var m = q.match(t.re);\r
865                         if(m){\r
866                             fn[fn.length] = t.select.replace(tplRe, function(x, i){\r
867                                                     return m[i];\r
868                                                 });\r
869                             q = q.replace(m[0], "");\r
870                             matched = true;\r
871                             break;\r
872                         }\r
873                     }\r
874                     
875                     if(!matched){\r
876                         throw 'Error parsing selector, parsing failed at "' + q + '"';\r
877                     }\r
878                 }\r
879                 if(mm[1]){\r
880                     fn[fn.length] = 'mode="'+mm[1].replace(trimRe, "")+'";';\r
881                     q = q.replace(mm[1], "");\r
882                 }\r
883             }\r
884             fn[fn.length] = "return nodup(n);\n}";\r
885             eval(fn.join(""));\r
886             return f;\r
887         },\r
888 \r
889         \r
890         select : function(path, root, type){\r
891             if(!root || root == document){\r
892                 root = document;\r
893             }\r
894             if(typeof root == "string"){\r
895                 root = document.getElementById(root);\r
896             }\r
897             var paths = path.split(",");\r
898             var results = [];\r
899             for(var i = 0, len = paths.length; i < len; i++){\r
900                 var p = paths[i].replace(trimRe, "");\r
901                 if(!cache[p]){\r
902                     cache[p] = Ext.DomQuery.compile(p);\r
903                     if(!cache[p]){\r
904                         throw p + " is not a valid selector";\r
905                     }\r
906                 }\r
907                 var result = cache[p](root);\r
908                 if(result && result != document){\r
909                     results = results.concat(result);\r
910                 }\r
911             }\r
912             if(paths.length > 1){\r
913                 return nodup(results);\r
914             }\r
915             return results;\r
916         },\r
917 \r
918         \r
919         selectNode : function(path, root){\r
920             return Ext.DomQuery.select(path, root)[0];\r
921         },\r
922 \r
923         \r
924         selectValue : function(path, root, defaultValue){\r
925             path = path.replace(trimRe, "");\r
926             if(!valueCache[path]){\r
927                 valueCache[path] = Ext.DomQuery.compile(path, "select");\r
928             }\r
929             var n = valueCache[path](root);\r
930             n = n[0] ? n[0] : n;\r
931             var v = (n && n.firstChild ? n.firstChild.nodeValue : null);\r
932             return ((v === null||v === undefined||v==='') ? defaultValue : v);\r
933         },\r
934 \r
935         \r
936         selectNumber : function(path, root, defaultValue){\r
937             var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);\r
938             return parseFloat(v);\r
939         },\r
940 \r
941         \r
942         is : function(el, ss){\r
943             if(typeof el == "string"){\r
944                 el = document.getElementById(el);\r
945             }\r
946             var isArray = Ext.isArray(el);\r
947             var result = Ext.DomQuery.filter(isArray ? el : [el], ss);\r
948             return isArray ? (result.length == el.length) : (result.length > 0);\r
949         },\r
950 \r
951         \r
952         filter : function(els, ss, nonMatches){\r
953             ss = ss.replace(trimRe, "");\r
954             if(!simpleCache[ss]){\r
955                 simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");\r
956             }\r
957             var result = simpleCache[ss](els);\r
958             return nonMatches ? quickDiff(result, els) : result;\r
959         },\r
960 \r
961         \r
962         matchers : [{\r
963                 re: /^\.([\w-]+)/,\r
964                 select: 'n = byClassName(n, null, " {1} ");'\r
965             }, {\r
966                 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,\r
967                 select: 'n = byPseudo(n, "{1}", "{2}");'\r
968             },{\r
969                 re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,\r
970                 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'\r
971             }, {\r
972                 re: /^#([\w-]+)/,\r
973                 select: 'n = byId(n, null, "{1}");'\r
974             },{\r
975                 re: /^@([\w-]+)/,\r
976                 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'\r
977             }\r
978         ],\r
979 \r
980         \r
981         operators : {\r
982             "=" : function(a, v){\r
983                 return a == v;\r
984             },\r
985             "!=" : function(a, v){\r
986                 return a != v;\r
987             },\r
988             "^=" : function(a, v){\r
989                 return a && a.substr(0, v.length) == v;\r
990             },\r
991             "$=" : function(a, v){\r
992                 return a && a.substr(a.length-v.length) == v;\r
993             },\r
994             "*=" : function(a, v){\r
995                 return a && a.indexOf(v) !== -1;\r
996             },\r
997             "%=" : function(a, v){\r
998                 return (a % v) == 0;\r
999             },\r
1000             "|=" : function(a, v){\r
1001                 return a && (a == v || a.substr(0, v.length+1) == v+'-');\r
1002             },\r
1003             "~=" : function(a, v){\r
1004                 return a && (' '+a+' ').indexOf(' '+v+' ') != -1;\r
1005             }\r
1006         },\r
1007 \r
1008         \r
1009         pseudos : {\r
1010             "first-child" : function(c){\r
1011                 var r = [], ri = -1, n;\r
1012                 for(var i = 0, ci; ci = n = c[i]; i++){\r
1013                     while((n = n.previousSibling) && n.nodeType != 1);\r
1014                     if(!n){\r
1015                         r[++ri] = ci;\r
1016                     }\r
1017                 }\r
1018                 return r;\r
1019             },\r
1020 \r
1021             "last-child" : function(c){\r
1022                 var r = [], ri = -1, n;\r
1023                 for(var i = 0, ci; ci = n = c[i]; i++){\r
1024                     while((n = n.nextSibling) && n.nodeType != 1);\r
1025                     if(!n){\r
1026                         r[++ri] = ci;\r
1027                     }\r
1028                 }\r
1029                 return r;\r
1030             },\r
1031 \r
1032             "nth-child" : function(c, a) {\r
1033                 var r = [], ri = -1;\r
1034                 var m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a);\r
1035                 var f = (m[1] || 1) - 0, l = m[2] - 0;\r
1036                 for(var i = 0, n; n = c[i]; i++){\r
1037                     var pn = n.parentNode;\r
1038                     if (batch != pn._batch) {\r
1039                         var j = 0;\r
1040                         for(var cn = pn.firstChild; cn; cn = cn.nextSibling){\r
1041                             if(cn.nodeType == 1){\r
1042                                cn.nodeIndex = ++j;\r
1043                             }\r
1044                         }\r
1045                         pn._batch = batch;\r
1046                     }\r
1047                     if (f == 1) {\r
1048                         if (l == 0 || n.nodeIndex == l){\r
1049                             r[++ri] = n;\r
1050                         }\r
1051                     } else if ((n.nodeIndex + l) % f == 0){\r
1052                         r[++ri] = n;\r
1053                     }\r
1054                 }\r
1055 \r
1056                 return r;\r
1057             },\r
1058 \r
1059             "only-child" : function(c){\r
1060                 var r = [], ri = -1;;\r
1061                 for(var i = 0, ci; ci = c[i]; i++){\r
1062                     if(!prev(ci) && !next(ci)){\r
1063                         r[++ri] = ci;\r
1064                     }\r
1065                 }\r
1066                 return r;\r
1067             },\r
1068 \r
1069             "empty" : function(c){\r
1070                 var r = [], ri = -1;\r
1071                 for(var i = 0, ci; ci = c[i]; i++){\r
1072                     var cns = ci.childNodes, j = 0, cn, empty = true;\r
1073                     while(cn = cns[j]){\r
1074                         ++j;\r
1075                         if(cn.nodeType == 1 || cn.nodeType == 3){\r
1076                             empty = false;\r
1077                             break;\r
1078                         }\r
1079                     }\r
1080                     if(empty){\r
1081                         r[++ri] = ci;\r
1082                     }\r
1083                 }\r
1084                 return r;\r
1085             },\r
1086 \r
1087             "contains" : function(c, v){\r
1088                 var r = [], ri = -1;\r
1089                 for(var i = 0, ci; ci = c[i]; i++){\r
1090                     if((ci.textContent||ci.innerText||'').indexOf(v) != -1){\r
1091                         r[++ri] = ci;\r
1092                     }\r
1093                 }\r
1094                 return r;\r
1095             },\r
1096 \r
1097             "nodeValue" : function(c, v){\r
1098                 var r = [], ri = -1;\r
1099                 for(var i = 0, ci; ci = c[i]; i++){\r
1100                     if(ci.firstChild && ci.firstChild.nodeValue == v){\r
1101                         r[++ri] = ci;\r
1102                     }\r
1103                 }\r
1104                 return r;\r
1105             },\r
1106 \r
1107             "checked" : function(c){\r
1108                 var r = [], ri = -1;\r
1109                 for(var i = 0, ci; ci = c[i]; i++){\r
1110                     if(ci.checked == true){\r
1111                         r[++ri] = ci;\r
1112                     }\r
1113                 }\r
1114                 return r;\r
1115             },\r
1116 \r
1117             "not" : function(c, ss){\r
1118                 return Ext.DomQuery.filter(c, ss, true);\r
1119             },\r
1120 \r
1121             "any" : function(c, selectors){\r
1122                 var ss = selectors.split('|');\r
1123                 var r = [], ri = -1, s;\r
1124                 for(var i = 0, ci; ci = c[i]; i++){\r
1125                     for(var j = 0; s = ss[j]; j++){\r
1126                         if(Ext.DomQuery.is(ci, s)){\r
1127                             r[++ri] = ci;\r
1128                             break;\r
1129                         }\r
1130                     }\r
1131                 }\r
1132                 return r;\r
1133             },\r
1134 \r
1135             "odd" : function(c){\r
1136                 return this["nth-child"](c, "odd");\r
1137             },\r
1138 \r
1139             "even" : function(c){\r
1140                 return this["nth-child"](c, "even");\r
1141             },\r
1142 \r
1143             "nth" : function(c, a){\r
1144                 return c[a-1] || [];\r
1145             },\r
1146 \r
1147             "first" : function(c){\r
1148                 return c[0] || [];\r
1149             },\r
1150 \r
1151             "last" : function(c){\r
1152                 return c[c.length-1] || [];\r
1153             },\r
1154 \r
1155             "has" : function(c, ss){\r
1156                 var s = Ext.DomQuery.select;\r
1157                 var r = [], ri = -1;\r
1158                 for(var i = 0, ci; ci = c[i]; i++){\r
1159                     if(s(ss, ci).length > 0){\r
1160                         r[++ri] = ci;\r
1161                     }\r
1162                 }\r
1163                 return r;\r
1164             },\r
1165 \r
1166             "next" : function(c, ss){\r
1167                 var is = Ext.DomQuery.is;\r
1168                 var r = [], ri = -1;\r
1169                 for(var i = 0, ci; ci = c[i]; i++){\r
1170                     var n = next(ci);\r
1171                     if(n && is(n, ss)){\r
1172                         r[++ri] = ci;\r
1173                     }\r
1174                 }\r
1175                 return r;\r
1176             },\r
1177 \r
1178             "prev" : function(c, ss){\r
1179                 var is = Ext.DomQuery.is;\r
1180                 var r = [], ri = -1;\r
1181                 for(var i = 0, ci; ci = c[i]; i++){\r
1182                     var n = prev(ci);\r
1183                     if(n && is(n, ss)){\r
1184                         r[++ri] = ci;\r
1185                     }\r
1186                 }\r
1187                 return r;\r
1188             }\r
1189         }\r
1190     };\r
1191 }();\r
1192 \r
1193 \r
1194 Ext.query = Ext.DomQuery.select;\r
1195
1196
1197 Ext.util.Observable = function(){
1198     
1199     if(this.listeners){
1200         this.on(this.listeners);
1201         delete this.listeners;
1202     }
1203 };
1204 Ext.util.Observable.prototype = {
1205     
1206     fireEvent : function(){
1207         if(this.eventsSuspended !== true){
1208             var ce = this.events[arguments[0].toLowerCase()];
1209             if(typeof ce == "object"){
1210                 return ce.fire.apply(ce, Array.prototype.slice.call(arguments, 1));
1211             }
1212         }
1213         return true;
1214     },
1215
1216         filterOptRe : /^(?:scope|delay|buffer|single)$/,
1217
1218     
1219     addListener : function(eventName, fn, scope, o){
1220         if(typeof eventName == "object"){
1221             o = eventName;
1222             for(var e in o){
1223                 if(this.filterOptRe.test(e)){
1224                     continue;
1225                 }
1226                 if(typeof o[e] == "function"){
1227                                         this.addListener(e, o[e], o.scope,  o);
1228                 }else{
1229                                         this.addListener(e, o[e].fn, o[e].scope, o[e]);
1230                 }
1231             }
1232             return;
1233         }
1234         o = (!o || typeof o == "boolean") ? {} : o;
1235         eventName = eventName.toLowerCase();
1236         var ce = this.events[eventName] || true;
1237         if(typeof ce == "boolean"){
1238             ce = new Ext.util.Event(this, eventName);
1239             this.events[eventName] = ce;
1240         }
1241         ce.addListener(fn, scope, o);
1242     },
1243
1244     
1245     removeListener : function(eventName, fn, scope){
1246         var ce = this.events[eventName.toLowerCase()];
1247         if(typeof ce == "object"){
1248             ce.removeListener(fn, scope);
1249         }
1250     },
1251
1252     
1253     purgeListeners : function(){
1254         for(var evt in this.events){
1255             if(typeof this.events[evt] == "object"){
1256                  this.events[evt].clearListeners();
1257             }
1258         }
1259     },
1260
1261     relayEvents : function(o, events){
1262         var createHandler = function(ename){
1263             return function(){
1264                 return this.fireEvent.apply(this, Ext.combine(ename, Array.prototype.slice.call(arguments, 0)));
1265             };
1266         };
1267         for(var i = 0, len = events.length; i < len; i++){
1268             var ename = events[i];
1269             if(!this.events[ename]){ this.events[ename] = true; };
1270             o.on(ename, createHandler(ename), this);
1271         }
1272     },
1273
1274     
1275     addEvents : function(o){
1276         if(!this.events){
1277             this.events = {};
1278         }
1279         if(typeof o == 'string'){
1280             for(var i = 0, a = arguments, v; v = a[i]; i++){
1281                 if(!this.events[a[i]]){
1282                     o[a[i]] = true;
1283                 }
1284             }
1285         }else{
1286             Ext.applyIf(this.events, o);
1287         }
1288     },
1289
1290     
1291     hasListener : function(eventName){
1292         var e = this.events[eventName];
1293         return typeof e == "object" && e.listeners.length > 0;
1294     },
1295
1296     
1297     suspendEvents : function(){
1298         this.eventsSuspended = true;
1299     },
1300
1301     
1302     resumeEvents : function(){
1303         this.eventsSuspended = false;
1304     },
1305
1306                 getMethodEvent : function(method){
1307         if(!this.methodEvents){
1308             this.methodEvents = {};
1309         }
1310         var e = this.methodEvents[method];
1311         if(!e){
1312             e = {};
1313             this.methodEvents[method] = e;
1314
1315             e.originalFn = this[method];
1316             e.methodName = method;
1317             e.before = [];
1318             e.after = [];
1319
1320
1321             var returnValue, v, cancel;
1322             var obj = this;
1323
1324             var makeCall = function(fn, scope, args){
1325                 if((v = fn.apply(scope || obj, args)) !== undefined){
1326                     if(typeof v === 'object'){
1327                         if(v.returnValue !== undefined){
1328                             returnValue = v.returnValue;
1329                         }else{
1330                             returnValue = v;
1331                         }
1332                         if(v.cancel === true){
1333                             cancel = true;
1334                         }
1335                     }else if(v === false){
1336                         cancel = true;
1337                     }else {
1338                         returnValue = v;
1339                     }
1340                 }
1341             }
1342
1343             this[method] = function(){
1344                 returnValue = v = undefined; cancel = false;
1345                 var args = Array.prototype.slice.call(arguments, 0);
1346                 for(var i = 0, len = e.before.length; i < len; i++){
1347                     makeCall(e.before[i].fn, e.before[i].scope, args);
1348                     if(cancel){
1349                         return returnValue;
1350                     }
1351                 }
1352
1353                 if((v = e.originalFn.apply(obj, args)) !== undefined){
1354                     returnValue = v;
1355                 }
1356
1357                 for(var i = 0, len = e.after.length; i < len; i++){
1358                     makeCall(e.after[i].fn, e.after[i].scope, args);
1359                     if(cancel){
1360                         return returnValue;
1361                     }
1362                 }
1363                 return returnValue;
1364             };
1365         }
1366         return e;
1367     },
1368
1369         beforeMethod : function(method, fn, scope){
1370         var e = this.getMethodEvent(method);
1371         e.before.push({fn: fn, scope: scope});
1372     },
1373
1374         afterMethod : function(method, fn, scope){
1375         var e = this.getMethodEvent(method);
1376         e.after.push({fn: fn, scope: scope});
1377     },
1378
1379     removeMethodListener : function(method, fn, scope){
1380         var e = this.getMethodEvent(method);
1381         for(var i = 0, len = e.before.length; i < len; i++){
1382             if(e.before[i].fn == fn && e.before[i].scope == scope){
1383                 e.before.splice(i, 1);
1384                 return;
1385             }
1386         }
1387         for(var i = 0, len = e.after.length; i < len; i++){
1388             if(e.after[i].fn == fn && e.after[i].scope == scope){
1389                 e.after.splice(i, 1);
1390                 return;
1391             }
1392         }
1393     }
1394 };
1395
1396 Ext.util.Observable.prototype.on = Ext.util.Observable.prototype.addListener;
1397
1398 Ext.util.Observable.prototype.un = Ext.util.Observable.prototype.removeListener;
1399
1400
1401 Ext.util.Observable.capture = function(o, fn, scope){
1402     o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
1403 };
1404
1405
1406 Ext.util.Observable.releaseCapture = function(o){
1407     o.fireEvent = Ext.util.Observable.prototype.fireEvent;
1408 };
1409
1410 (function(){
1411
1412     var createBuffered = function(h, o, scope){
1413         var task = new Ext.util.DelayedTask();
1414         return function(){
1415             task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
1416         };
1417     };
1418
1419     var createSingle = function(h, e, fn, scope){
1420         return function(){
1421             e.removeListener(fn, scope);
1422             return h.apply(scope, arguments);
1423         };
1424     };
1425
1426     var createDelayed = function(h, o, scope){
1427         return function(){
1428             var args = Array.prototype.slice.call(arguments, 0);
1429             setTimeout(function(){
1430                 h.apply(scope, args);
1431             }, o.delay || 10);
1432         };
1433     };
1434
1435     Ext.util.Event = function(obj, name){
1436         this.name = name;
1437         this.obj = obj;
1438         this.listeners = [];
1439     };
1440
1441     Ext.util.Event.prototype = {
1442         addListener : function(fn, scope, options){
1443             scope = scope || this.obj;
1444             if(!this.isListening(fn, scope)){
1445                 var l = this.createListener(fn, scope, options);
1446                 if(!this.firing){
1447                     this.listeners.push(l);
1448                 }else{                     this.listeners = this.listeners.slice(0);
1449                     this.listeners.push(l);
1450                 }
1451             }
1452         },
1453
1454         createListener : function(fn, scope, o){
1455             o = o || {};
1456             scope = scope || this.obj;
1457             var l = {fn: fn, scope: scope, options: o};
1458             var h = fn;
1459             if(o.delay){
1460                 h = createDelayed(h, o, scope);
1461             }
1462             if(o.single){
1463                 h = createSingle(h, this, fn, scope);
1464             }
1465             if(o.buffer){
1466                 h = createBuffered(h, o, scope);
1467             }
1468             l.fireFn = h;
1469             return l;
1470         },
1471
1472         findListener : function(fn, scope){
1473             scope = scope || this.obj;
1474             var ls = this.listeners;
1475             for(var i = 0, len = ls.length; i < len; i++){
1476                 var l = ls[i];
1477                 if(l.fn == fn && l.scope == scope){
1478                     return i;
1479                 }
1480             }
1481             return -1;
1482         },
1483
1484         isListening : function(fn, scope){
1485             return this.findListener(fn, scope) != -1;
1486         },
1487
1488         removeListener : function(fn, scope){
1489             var index;
1490             if((index = this.findListener(fn, scope)) != -1){
1491                 if(!this.firing){
1492                     this.listeners.splice(index, 1);
1493                 }else{
1494                     this.listeners = this.listeners.slice(0);
1495                     this.listeners.splice(index, 1);
1496                 }
1497                 return true;
1498             }
1499             return false;
1500         },
1501
1502         clearListeners : function(){
1503             this.listeners = [];
1504         },
1505
1506         fire : function(){
1507             var ls = this.listeners, scope, len = ls.length;
1508             if(len > 0){
1509                 this.firing = true;
1510                 var args = Array.prototype.slice.call(arguments, 0);
1511                 for(var i = 0; i < len; i++){
1512                     var l = ls[i];
1513                     if(l.fireFn.apply(l.scope||this.obj||window, arguments) === false){
1514                         this.firing = false;
1515                         return false;
1516                     }
1517                 }
1518                 this.firing = false;
1519             }
1520             return true;
1521         }
1522     };
1523 })();
1524 \r
1525 Ext.EventManager = function(){\r
1526     var docReadyEvent, docReadyProcId, docReadyState = false;\r
1527     var resizeEvent, resizeTask, textEvent, textSize;\r
1528     var E = Ext.lib.Event;\r
1529     var D = Ext.lib.Dom;\r
1530 \r
1531 \r
1532     var fireDocReady = function(){\r
1533         if(!docReadyState){\r
1534             docReadyState = true;\r
1535             Ext.isReady = true;\r
1536             if(docReadyProcId){\r
1537                 clearInterval(docReadyProcId);\r
1538             }\r
1539             if(Ext.isGecko || Ext.isOpera) {\r
1540                 document.removeEventListener("DOMContentLoaded", fireDocReady, false);\r
1541             }\r
1542             if(Ext.isIE){\r
1543                 var defer = document.getElementById("ie-deferred-loader");\r
1544                 if(defer){\r
1545                     defer.onreadystatechange = null;\r
1546                     defer.parentNode.removeChild(defer);\r
1547                 }\r
1548             }\r
1549             if(docReadyEvent){\r
1550                 docReadyEvent.fire();\r
1551                 docReadyEvent.clearListeners();\r
1552             }\r
1553         }\r
1554     };\r
1555 \r
1556     var initDocReady = function(){\r
1557         docReadyEvent = new Ext.util.Event();\r
1558         if(Ext.isGecko || Ext.isOpera) {\r
1559             document.addEventListener("DOMContentLoaded", fireDocReady, false);\r
1560         }else if(Ext.isIE){\r
1561             document.write("<s"+'cript id="ie-deferred-loader" defer="defer" src="/'+'/:"></s'+"cript>");\r
1562             var defer = document.getElementById("ie-deferred-loader");\r
1563             defer.onreadystatechange = function(){\r
1564                 if(this.readyState == "complete"){\r
1565                     fireDocReady();\r
1566                 }\r
1567             };\r
1568         }else if(Ext.isSafari){\r
1569             docReadyProcId = setInterval(function(){\r
1570                 var rs = document.readyState;\r
1571                 if(rs == "complete") {\r
1572                     fireDocReady();\r
1573                  }\r
1574             }, 10);\r
1575         }\r
1576         
1577         E.on(window, "load", fireDocReady);\r
1578     };\r
1579 \r
1580     var createBuffered = function(h, o){\r
1581         var task = new Ext.util.DelayedTask(h);\r
1582         return function(e){\r
1583             
1584             e = new Ext.EventObjectImpl(e);\r
1585             task.delay(o.buffer, h, null, [e]);\r
1586         };\r
1587     };\r
1588 \r
1589     var createSingle = function(h, el, ename, fn){\r
1590         return function(e){\r
1591             Ext.EventManager.removeListener(el, ename, fn);\r
1592             h(e);\r
1593         };\r
1594     };\r
1595 \r
1596     var createDelayed = function(h, o){\r
1597         return function(e){\r
1598             
1599             e = new Ext.EventObjectImpl(e);\r
1600             setTimeout(function(){\r
1601                 h(e);\r
1602             }, o.delay || 10);\r
1603         };\r
1604     };\r
1605 \r
1606     var listen = function(element, ename, opt, fn, scope){\r
1607         var o = (!opt || typeof opt == "boolean") ? {} : opt;\r
1608         fn = fn || o.fn; scope = scope || o.scope;\r
1609         var el = Ext.getDom(element);\r
1610         if(!el){\r
1611             throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';\r
1612         }\r
1613         var h = function(e){\r
1614             e = Ext.EventObject.setEvent(e);\r
1615             var t;\r
1616             if(o.delegate){\r
1617                 t = e.getTarget(o.delegate, el);\r
1618                 if(!t){\r
1619                     return;\r
1620                 }\r
1621             }else{\r
1622                 t = e.target;\r
1623             }\r
1624             if(o.stopEvent === true){\r
1625                 e.stopEvent();\r
1626             }\r
1627             if(o.preventDefault === true){\r
1628                e.preventDefault();\r
1629             }\r
1630             if(o.stopPropagation === true){\r
1631                 e.stopPropagation();\r
1632             }\r
1633 \r
1634             if(o.normalized === false){\r
1635                 e = e.browserEvent;\r
1636             }\r
1637 \r
1638             fn.call(scope || el, e, t, o);\r
1639         };\r
1640         if(o.delay){\r
1641             h = createDelayed(h, o);\r
1642         }\r
1643         if(o.single){\r
1644             h = createSingle(h, el, ename, fn);\r
1645         }\r
1646         if(o.buffer){\r
1647             h = createBuffered(h, o);\r
1648         }\r
1649         fn._handlers = fn._handlers || [];\r
1650         fn._handlers.push([Ext.id(el), ename, h]);\r
1651 \r
1652         E.on(el, ename, h);\r
1653         if(ename == "mousewheel" && el.addEventListener){ 
1654             el.addEventListener("DOMMouseScroll", h, false);\r
1655             E.on(window, 'unload', function(){\r
1656                 el.removeEventListener("DOMMouseScroll", h, false);\r
1657             });\r
1658         }\r
1659         if(ename == "mousedown" && el == document){ 
1660             Ext.EventManager.stoppedMouseDownEvent.addListener(h);\r
1661         }\r
1662         return h;\r
1663     };\r
1664 \r
1665     var stopListening = function(el, ename, fn){\r
1666         var id = Ext.id(el), hds = fn._handlers, hd = fn;\r
1667         if(hds){\r
1668             for(var i = 0, len = hds.length; i < len; i++){\r
1669                 var h = hds[i];\r
1670                 if(h[0] == id && h[1] == ename){\r
1671                     hd = h[2];\r
1672                     hds.splice(i, 1);\r
1673                     break;\r
1674                 }\r
1675             }\r
1676         }\r
1677         E.un(el, ename, hd);\r
1678         el = Ext.getDom(el);\r
1679         if(ename == "mousewheel" && el.addEventListener){\r
1680             el.removeEventListener("DOMMouseScroll", hd, false);\r
1681         }\r
1682         if(ename == "mousedown" && el == document){ 
1683             Ext.EventManager.stoppedMouseDownEvent.removeListener(hd);\r
1684         }\r
1685     };\r
1686 \r
1687     var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;\r
1688     var pub = {\r
1689 \r
1690     \r
1691         addListener : function(element, eventName, fn, scope, options){\r
1692             if(typeof eventName == "object"){\r
1693                 var o = eventName;\r
1694                 for(var e in o){\r
1695                     if(propRe.test(e)){\r
1696                         continue;\r
1697                     }\r
1698                     if(typeof o[e] == "function"){\r
1699                         
1700                         listen(element, e, o, o[e], o.scope);\r
1701                     }else{\r
1702                         
1703                         listen(element, e, o[e]);\r
1704                     }\r
1705                 }\r
1706                 return;\r
1707             }\r
1708             return listen(element, eventName, options, fn, scope);\r
1709         },\r
1710 \r
1711         \r
1712         removeListener : function(element, eventName, fn){\r
1713             return stopListening(element, eventName, fn);\r
1714         },\r
1715 \r
1716         \r
1717         onDocumentReady : function(fn, scope, options){\r
1718             if(docReadyState){ 
1719                 docReadyEvent.addListener(fn, scope, options);\r
1720                 docReadyEvent.fire();\r
1721                 docReadyEvent.clearListeners();\r
1722                 return;\r
1723             }\r
1724             if(!docReadyEvent){\r
1725                 initDocReady();\r
1726             }\r
1727             docReadyEvent.addListener(fn, scope, options);\r
1728         },\r
1729 \r
1730         \r
1731         onWindowResize : function(fn, scope, options){\r
1732             if(!resizeEvent){\r
1733                 resizeEvent = new Ext.util.Event();\r
1734                 resizeTask = new Ext.util.DelayedTask(function(){\r
1735                     resizeEvent.fire(D.getViewWidth(), D.getViewHeight());\r
1736                 });\r
1737                 E.on(window, "resize", this.fireWindowResize, this);\r
1738             }\r
1739             resizeEvent.addListener(fn, scope, options);\r
1740         },\r
1741 \r
1742         
1743         fireWindowResize : function(){\r
1744             if(resizeEvent){\r
1745                 if((Ext.isIE||Ext.isAir) && resizeTask){\r
1746                     resizeTask.delay(50);\r
1747                 }else{\r
1748                     resizeEvent.fire(D.getViewWidth(), D.getViewHeight());\r
1749                 }\r
1750             }\r
1751         },\r
1752 \r
1753         \r
1754         onTextResize : function(fn, scope, options){\r
1755             if(!textEvent){\r
1756                 textEvent = new Ext.util.Event();\r
1757                 var textEl = new Ext.Element(document.createElement('div'));\r
1758                 textEl.dom.className = 'x-text-resize';\r
1759                 textEl.dom.innerHTML = 'X';\r
1760                 textEl.appendTo(document.body);\r
1761                 textSize = textEl.dom.offsetHeight;\r
1762                 setInterval(function(){\r
1763                     if(textEl.dom.offsetHeight != textSize){\r
1764                         textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);\r
1765                     }\r
1766                 }, this.textResizeInterval);\r
1767             }\r
1768             textEvent.addListener(fn, scope, options);\r
1769         },\r
1770 \r
1771         \r
1772         removeResizeListener : function(fn, scope){\r
1773             if(resizeEvent){\r
1774                 resizeEvent.removeListener(fn, scope);\r
1775             }\r
1776         },\r
1777 \r
1778         
1779         fireResize : function(){\r
1780             if(resizeEvent){\r
1781                 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());\r
1782             }\r
1783         },\r
1784         \r
1785         ieDeferSrc : false,\r
1786         \r
1787         textResizeInterval : 50\r
1788     };\r
1789      \r
1790     pub.on = pub.addListener;\r
1791     \r
1792     pub.un = pub.removeListener;\r
1793 \r
1794     pub.stoppedMouseDownEvent = new Ext.util.Event();\r
1795     return pub;\r
1796 }();\r
1797 \r
1798 Ext.onReady = Ext.EventManager.onDocumentReady;\r
1799 \r
1800 Ext.onReady(function(){\r
1801     var bd = Ext.getBody();\r
1802     if(!bd){ return; }\r
1803 \r
1804     var cls = [\r
1805             Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : 'ext-ie7')\r
1806             : Ext.isGecko ? "ext-gecko"\r
1807             : Ext.isOpera ? "ext-opera"\r
1808             : Ext.isSafari ? "ext-safari" : ""];\r
1809 \r
1810     if(Ext.isMac){\r
1811         cls.push("ext-mac");\r
1812     }\r
1813     if(Ext.isLinux){\r
1814         cls.push("ext-linux");\r
1815     }\r
1816     if(Ext.isBorderBox){\r
1817         cls.push('ext-border-box');\r
1818     }\r
1819     if(Ext.isStrict){ 
1820         var p = bd.dom.parentNode;\r
1821         if(p){\r
1822             p.className += ' ext-strict';\r
1823         }\r
1824     }\r
1825     bd.addClass(cls.join(' '));\r
1826 });\r
1827 \r
1828 \r
1829 Ext.EventObject = function(){\r
1830 \r
1831     var E = Ext.lib.Event;\r
1832 \r
1833     
1834     var safariKeys = {\r
1835         63234 : 37, 
1836         63235 : 39, 
1837         63232 : 38, 
1838         63233 : 40, 
1839         63276 : 33, 
1840         63277 : 34, 
1841         63272 : 46, 
1842         63273 : 36, 
1843         63275 : 35  
1844     };\r
1845 \r
1846     
1847     var btnMap = Ext.isIE ? {1:0,4:1,2:2} :\r
1848                 (Ext.isSafari ? {1:0,2:1,3:2} : {0:0,1:1,2:2});\r
1849 \r
1850     Ext.EventObjectImpl = function(e){\r
1851         if(e){\r
1852             this.setEvent(e.browserEvent || e);\r
1853         }\r
1854     };\r
1855     Ext.EventObjectImpl.prototype = {\r
1856         \r
1857         browserEvent : null,\r
1858         \r
1859         button : -1,\r
1860         \r
1861         shiftKey : false,\r
1862         \r
1863         ctrlKey : false,\r
1864         \r
1865         altKey : false,\r
1866 \r
1867         \r
1868         BACKSPACE : 8,\r
1869         \r
1870         TAB : 9,\r
1871         \r
1872         RETURN : 13,\r
1873         \r
1874         ENTER : 13,\r
1875         \r
1876         SHIFT : 16,\r
1877         \r
1878         CONTROL : 17,\r
1879         \r
1880         ESC : 27,\r
1881         \r
1882         SPACE : 32,\r
1883         \r
1884         PAGEUP : 33,\r
1885         \r
1886         PAGEDOWN : 34,\r
1887         \r
1888         END : 35,\r
1889         \r
1890         HOME : 36,\r
1891         \r
1892         LEFT : 37,\r
1893         \r
1894         UP : 38,\r
1895         \r
1896         RIGHT : 39,\r
1897         \r
1898         DOWN : 40,\r
1899         \r
1900         DELETE : 46,\r
1901         \r
1902         F5 : 116,\r
1903 \r
1904            \r
1905         setEvent : function(e){\r
1906             if(e == this || (e && e.browserEvent)){ 
1907                 return e;\r
1908             }\r
1909             this.browserEvent = e;\r
1910             if(e){\r
1911                 
1912                 this.button = e.button ? btnMap[e.button] : (e.which ? e.which-1 : -1);\r
1913                 if(e.type == 'click' && this.button == -1){\r
1914                     this.button = 0;\r
1915                 }\r
1916                 this.type = e.type;\r
1917                 this.shiftKey = e.shiftKey;\r
1918                 
1919                 this.ctrlKey = e.ctrlKey || e.metaKey;\r
1920                 this.altKey = e.altKey;\r
1921                 
1922                 this.keyCode = e.keyCode;\r
1923                 this.charCode = e.charCode;\r
1924                 
1925                 this.target = E.getTarget(e);\r
1926                 
1927                 this.xy = E.getXY(e);\r
1928             }else{\r
1929                 this.button = -1;\r
1930                 this.shiftKey = false;\r
1931                 this.ctrlKey = false;\r
1932                 this.altKey = false;\r
1933                 this.keyCode = 0;\r
1934                 this.charCode =0;\r
1935                 this.target = null;\r
1936                 this.xy = [0, 0];\r
1937             }\r
1938             return this;\r
1939         },\r
1940 \r
1941         \r
1942         stopEvent : function(){\r
1943             if(this.browserEvent){\r
1944                 if(this.browserEvent.type == 'mousedown'){\r
1945                     Ext.EventManager.stoppedMouseDownEvent.fire(this);\r
1946                 }\r
1947                 E.stopEvent(this.browserEvent);\r
1948             }\r
1949         },\r
1950 \r
1951         \r
1952         preventDefault : function(){\r
1953             if(this.browserEvent){\r
1954                 E.preventDefault(this.browserEvent);\r
1955             }\r
1956         },\r
1957 \r
1958         \r
1959         isNavKeyPress : function(){\r
1960             var k = this.keyCode;\r
1961             k = Ext.isSafari ? (safariKeys[k] || k) : k;\r
1962             return (k >= 33 && k <= 40) || k == this.RETURN || k == this.TAB || k == this.ESC;\r
1963         },\r
1964 \r
1965         isSpecialKey : function(){\r
1966             var k = this.keyCode;\r
1967             return (this.type == 'keypress' && this.ctrlKey) || k == 9 || k == 13  || k == 40 || k == 27 ||\r
1968             (k == 16) || (k == 17) ||\r
1969             (k >= 18 && k <= 20) ||\r
1970             (k >= 33 && k <= 35) ||\r
1971             (k >= 36 && k <= 39) ||\r
1972             (k >= 44 && k <= 45);\r
1973         },\r
1974         \r
1975         stopPropagation : function(){\r
1976             if(this.browserEvent){\r
1977                 if(this.browserEvent.type == 'mousedown'){\r
1978                     Ext.EventManager.stoppedMouseDownEvent.fire(this);\r
1979                 }\r
1980                 E.stopPropagation(this.browserEvent);\r
1981             }\r
1982         },\r
1983 \r
1984         \r
1985         getCharCode : function(){\r
1986             return this.charCode || this.keyCode;\r
1987         },\r
1988 \r
1989         \r
1990         getKey : function(){\r
1991             var k = this.keyCode || this.charCode;\r
1992             return Ext.isSafari ? (safariKeys[k] || k) : k;\r
1993         },\r
1994 \r
1995         \r
1996         getPageX : function(){\r
1997             return this.xy[0];\r
1998         },\r
1999 \r
2000         \r
2001         getPageY : function(){\r
2002             return this.xy[1];\r
2003         },\r
2004 \r
2005         \r
2006         getTime : function(){\r
2007             if(this.browserEvent){\r
2008                 return E.getTime(this.browserEvent);\r
2009             }\r
2010             return null;\r
2011         },\r
2012 \r
2013         \r
2014         getXY : function(){\r
2015             return this.xy;\r
2016         },\r
2017 \r
2018         \r
2019         getTarget : function(selector, maxDepth, returnEl){\r
2020                 var t = Ext.get(this.target);\r
2021             return selector ? t.findParent(selector, maxDepth, returnEl) : (returnEl ? t : this.target);\r
2022         },\r
2023         \r
2024         \r
2025         getRelatedTarget : function(){\r
2026             if(this.browserEvent){\r
2027                 return E.getRelatedTarget(this.browserEvent);\r
2028             }\r
2029             return null;\r
2030         },\r
2031 \r
2032         \r
2033         getWheelDelta : function(){\r
2034             var e = this.browserEvent;\r
2035             var delta = 0;\r
2036             if(e.wheelDelta){ \r
2037                 delta = e.wheelDelta/120;\r
2038             }else if(e.detail){ \r
2039                 delta = -e.detail/3;\r
2040             }\r
2041             return delta;\r
2042         },\r
2043 \r
2044         \r
2045         hasModifier : function(){\r
2046             return ((this.ctrlKey || this.altKey) || this.shiftKey) ? true : false;\r
2047         },\r
2048 \r
2049         \r
2050         within : function(el, related){\r
2051             var t = this[related ? "getRelatedTarget" : "getTarget"]();\r
2052             return t && Ext.fly(el).contains(t);\r
2053         },\r
2054 \r
2055         getPoint : function(){\r
2056             return new Ext.lib.Point(this.xy[0], this.xy[1]);\r
2057         }\r
2058     };\r
2059 \r
2060     return new Ext.EventObjectImpl();\r
2061 }();
2062
2063 (function(){
2064 var D = Ext.lib.Dom;
2065 var E = Ext.lib.Event;
2066 var A = Ext.lib.Anim;
2067
2068 var propCache = {};
2069 var camelRe = /(-[a-z])/gi;
2070 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
2071 var view = document.defaultView;
2072
2073 Ext.Element = function(element, forceNew){
2074     var dom = typeof element == "string" ?
2075             document.getElementById(element) : element;
2076     if(!dom){         return null;
2077     }
2078     var id = dom.id;
2079     if(forceNew !== true && id && Ext.Element.cache[id]){         return Ext.Element.cache[id];
2080     }
2081
2082     
2083     this.dom = dom;
2084
2085     
2086     this.id = id || Ext.id(dom);
2087 };
2088
2089 var El = Ext.Element;
2090
2091 El.prototype = {
2092     
2093     originalDisplay : "",
2094
2095     visibilityMode : 1,
2096     
2097     defaultUnit : "px",
2098     
2099     setVisibilityMode : function(visMode){
2100         this.visibilityMode = visMode;
2101         return this;
2102     },
2103     
2104     enableDisplayMode : function(display){
2105         this.setVisibilityMode(El.DISPLAY);
2106         if(typeof display != "undefined") this.originalDisplay = display;
2107         return this;
2108     },
2109
2110     
2111     findParent : function(simpleSelector, maxDepth, returnEl){
2112         var p = this.dom, b = document.body, depth = 0, dq = Ext.DomQuery, stopEl;
2113         maxDepth = maxDepth || 50;
2114         if(typeof maxDepth != "number"){
2115             stopEl = Ext.getDom(maxDepth);
2116             maxDepth = 10;
2117         }
2118         while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
2119             if(dq.is(p, simpleSelector)){
2120                 return returnEl ? Ext.get(p) : p;
2121             }
2122             depth++;
2123             p = p.parentNode;
2124         }
2125         return null;
2126     },
2127
2128
2129     
2130     findParentNode : function(simpleSelector, maxDepth, returnEl){
2131         var p = Ext.fly(this.dom.parentNode, '_internal');
2132         return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
2133     },
2134
2135     
2136     up : function(simpleSelector, maxDepth){
2137         return this.findParentNode(simpleSelector, maxDepth, true);
2138     },
2139
2140
2141
2142     
2143     is : function(simpleSelector){
2144         return Ext.DomQuery.is(this.dom, simpleSelector);
2145     },
2146
2147     
2148     animate : function(args, duration, onComplete, easing, animType){
2149         this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
2150         return this;
2151     },
2152
2153     
2154     anim : function(args, opt, animType, defaultDur, defaultEase, cb){
2155         animType = animType || 'run';
2156         opt = opt || {};
2157         var anim = Ext.lib.Anim[animType](
2158             this.dom, args,
2159             (opt.duration || defaultDur) || .35,
2160             (opt.easing || defaultEase) || 'easeOut',
2161             function(){
2162                 Ext.callback(cb, this);
2163                 Ext.callback(opt.callback, opt.scope || this, [this, opt]);
2164             },
2165             this
2166         );
2167         opt.anim = anim;
2168         return anim;
2169     },
2170
2171         preanim : function(a, i){
2172         return !a[i] ? false : (typeof a[i] == "object" ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
2173     },
2174
2175     
2176     clean : function(forceReclean){
2177         if(this.isCleaned && forceReclean !== true){
2178             return this;
2179         }
2180         var ns = /\S/;
2181         var d = this.dom, n = d.firstChild, ni = -1;
2182             while(n){
2183                 var nx = n.nextSibling;
2184                 if(n.nodeType == 3 && !ns.test(n.nodeValue)){
2185                     d.removeChild(n);
2186                 }else{
2187                     n.nodeIndex = ++ni;
2188                 }
2189                 n = nx;
2190             }
2191             this.isCleaned = true;
2192             return this;
2193         },
2194
2195     
2196     scrollIntoView : function(container, hscroll){
2197         var c = Ext.getDom(container) || Ext.getBody().dom;
2198         var el = this.dom;
2199
2200         var o = this.getOffsetsTo(c),
2201             l = o[0] + c.scrollLeft,
2202             t = o[1] + c.scrollTop,
2203             b = t+el.offsetHeight,
2204             r = l+el.offsetWidth;
2205
2206         var ch = c.clientHeight;
2207         var ct = parseInt(c.scrollTop, 10);
2208         var cl = parseInt(c.scrollLeft, 10);
2209         var cb = ct + ch;
2210         var cr = cl + c.clientWidth;
2211
2212         if(el.offsetHeight > ch || t < ct){
2213                 c.scrollTop = t;
2214         }else if(b > cb){
2215             c.scrollTop = b-ch;
2216         }
2217         c.scrollTop = c.scrollTop; 
2218         if(hscroll !== false){
2219                         if(el.offsetWidth > c.clientWidth || l < cl){
2220                 c.scrollLeft = l;
2221             }else if(r > cr){
2222                 c.scrollLeft = r-c.clientWidth;
2223             }
2224             c.scrollLeft = c.scrollLeft;
2225         }
2226         return this;
2227     },
2228
2229         scrollChildIntoView : function(child, hscroll){
2230         Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
2231     },
2232
2233     
2234     autoHeight : function(animate, duration, onComplete, easing){
2235         var oldHeight = this.getHeight();
2236         this.clip();
2237         this.setHeight(1);         setTimeout(function(){
2238             var height = parseInt(this.dom.scrollHeight, 10);             if(!animate){
2239                 this.setHeight(height);
2240                 this.unclip();
2241                 if(typeof onComplete == "function"){
2242                     onComplete();
2243                 }
2244             }else{
2245                 this.setHeight(oldHeight);                 this.setHeight(height, animate, duration, function(){
2246                     this.unclip();
2247                     if(typeof onComplete == "function") onComplete();
2248                 }.createDelegate(this), easing);
2249             }
2250         }.createDelegate(this), 0);
2251         return this;
2252     },
2253
2254     
2255     contains : function(el){
2256         if(!el){return false;}
2257         return D.isAncestor(this.dom, el.dom ? el.dom : el);
2258     },
2259
2260     
2261     isVisible : function(deep) {
2262         var vis = !(this.getStyle("visibility") == "hidden" || this.getStyle("display") == "none");
2263         if(deep !== true || !vis){
2264             return vis;
2265         }
2266         var p = this.dom.parentNode;
2267         while(p && p.tagName.toLowerCase() != "body"){
2268             if(!Ext.fly(p, '_isVisible').isVisible()){
2269                 return false;
2270             }
2271             p = p.parentNode;
2272         }
2273         return true;
2274     },
2275
2276     
2277     select : function(selector, unique){
2278         return El.select(selector, unique, this.dom);
2279     },
2280
2281     
2282     query : function(selector, unique){
2283         return Ext.DomQuery.select(selector, this.dom);
2284     },
2285
2286     
2287     child : function(selector, returnDom){
2288         var n = Ext.DomQuery.selectNode(selector, this.dom);
2289         return returnDom ? n : Ext.get(n);
2290     },
2291
2292     
2293     down : function(selector, returnDom){
2294         var n = Ext.DomQuery.selectNode(" > " + selector, this.dom);
2295         return returnDom ? n : Ext.get(n);
2296     },
2297
2298     
2299     initDD : function(group, config, overrides){
2300         var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
2301         return Ext.apply(dd, overrides);
2302     },
2303
2304     
2305     initDDProxy : function(group, config, overrides){
2306         var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
2307         return Ext.apply(dd, overrides);
2308     },
2309
2310     
2311     initDDTarget : function(group, config, overrides){
2312         var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
2313         return Ext.apply(dd, overrides);
2314     },
2315
2316     
2317      setVisible : function(visible, animate){
2318         if(!animate || !A){
2319             if(this.visibilityMode == El.DISPLAY){
2320                 this.setDisplayed(visible);
2321             }else{
2322                 this.fixDisplay();
2323                 this.dom.style.visibility = visible ? "visible" : "hidden";
2324             }
2325         }else{
2326                         var dom = this.dom;
2327             var visMode = this.visibilityMode;
2328             if(visible){
2329                 this.setOpacity(.01);
2330                 this.setVisible(true);
2331             }
2332             this.anim({opacity: { to: (visible?1:0) }},
2333                   this.preanim(arguments, 1),
2334                   null, .35, 'easeIn', function(){
2335                      if(!visible){
2336                          if(visMode == El.DISPLAY){
2337                              dom.style.display = "none";
2338                          }else{
2339                              dom.style.visibility = "hidden";
2340                          }
2341                          Ext.get(dom).setOpacity(1);
2342                      }
2343                  });
2344         }
2345         return this;
2346     },
2347
2348     
2349     isDisplayed : function() {
2350         return this.getStyle("display") != "none";
2351     },
2352
2353     
2354     toggle : function(animate){
2355         this.setVisible(!this.isVisible(), this.preanim(arguments, 0));
2356         return this;
2357     },
2358
2359     
2360     setDisplayed : function(value) {
2361         if(typeof value == "boolean"){
2362            value = value ? this.originalDisplay : "none";
2363         }
2364         this.setStyle("display", value);
2365         return this;
2366     },
2367
2368     
2369     focus : function() {
2370         try{
2371             this.dom.focus();
2372         }catch(e){}
2373         return this;
2374     },
2375
2376     
2377     blur : function() {
2378         try{
2379             this.dom.blur();
2380         }catch(e){}
2381         return this;
2382     },
2383
2384     
2385     addClass : function(className){
2386         if(Ext.isArray(className)){
2387             for(var i = 0, len = className.length; i < len; i++) {
2388                 this.addClass(className[i]);
2389             }
2390         }else{
2391             if(className && !this.hasClass(className)){
2392                 this.dom.className = this.dom.className + " " + className;
2393             }
2394         }
2395         return this;
2396     },
2397
2398     
2399     radioClass : function(className){
2400         var siblings = this.dom.parentNode.childNodes;
2401         for(var i = 0; i < siblings.length; i++) {
2402                 var s = siblings[i];
2403                 if(s.nodeType == 1){
2404                     Ext.get(s).removeClass(className);
2405                 }
2406         }
2407         this.addClass(className);
2408         return this;
2409     },
2410
2411     
2412     removeClass : function(className){
2413         if(!className || !this.dom.className){
2414             return this;
2415         }
2416         if(Ext.isArray(className)){
2417             for(var i = 0, len = className.length; i < len; i++) {
2418                 this.removeClass(className[i]);
2419             }
2420         }else{
2421             if(this.hasClass(className)){
2422                 var re = this.classReCache[className];
2423                 if (!re) {
2424                    re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', "g");
2425                    this.classReCache[className] = re;
2426                 }
2427                 this.dom.className =
2428                     this.dom.className.replace(re, " ");
2429             }
2430         }
2431         return this;
2432     },
2433
2434         classReCache: {},
2435
2436     
2437     toggleClass : function(className){
2438         if(this.hasClass(className)){
2439             this.removeClass(className);
2440         }else{
2441             this.addClass(className);
2442         }
2443         return this;
2444     },
2445
2446     
2447     hasClass : function(className){
2448         return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
2449     },
2450
2451     
2452     replaceClass : function(oldClassName, newClassName){
2453         this.removeClass(oldClassName);
2454         this.addClass(newClassName);
2455         return this;
2456     },
2457
2458     
2459     getStyles : function(){
2460         var a = arguments, len = a.length, r = {};
2461         for(var i = 0; i < len; i++){
2462             r[a[i]] = this.getStyle(a[i]);
2463         }
2464         return r;
2465     },
2466
2467     
2468     getStyle : function(){
2469         return view && view.getComputedStyle ?
2470             function(prop){
2471                 var el = this.dom, v, cs, camel;
2472                 if(prop == 'float'){
2473                     prop = "cssFloat";
2474                 }
2475                 if(v = el.style[prop]){
2476                     return v;
2477                 }
2478                 if(cs = view.getComputedStyle(el, "")){
2479                     if(!(camel = propCache[prop])){
2480                         camel = propCache[prop] = prop.replace(camelRe, camelFn);
2481                     }
2482                     return cs[camel];
2483                 }
2484                 return null;
2485             } :
2486             function(prop){
2487                 var el = this.dom, v, cs, camel;
2488                 if(prop == 'opacity'){
2489                     if(typeof el.style.filter == 'string'){
2490                         var m = el.style.filter.match(/alpha\(opacity=(.*)\)/i);
2491                         if(m){
2492                             var fv = parseFloat(m[1]);
2493                             if(!isNaN(fv)){
2494                                 return fv ? fv / 100 : 0;
2495                             }
2496                         }
2497                     }
2498                     return 1;
2499                 }else if(prop == 'float'){
2500                     prop = "styleFloat";
2501                 }
2502                 if(!(camel = propCache[prop])){
2503                     camel = propCache[prop] = prop.replace(camelRe, camelFn);
2504                 }
2505                 if(v = el.style[camel]){
2506                     return v;
2507                 }
2508                 if(cs = el.currentStyle){
2509                     return cs[camel];
2510                 }
2511                 return null;
2512             };
2513     }(),
2514
2515     
2516     setStyle : function(prop, value){
2517         if(typeof prop == "string"){
2518             var camel;
2519             if(!(camel = propCache[prop])){
2520                 camel = propCache[prop] = prop.replace(camelRe, camelFn);
2521             }
2522             if(camel == 'opacity') {
2523                 this.setOpacity(value);
2524             }else{
2525                 this.dom.style[camel] = value;
2526             }
2527         }else{
2528             for(var style in prop){
2529                 if(typeof prop[style] != "function"){
2530                    this.setStyle(style, prop[style]);
2531                 }
2532             }
2533         }
2534         return this;
2535     },
2536
2537     
2538     applyStyles : function(style){
2539         Ext.DomHelper.applyStyles(this.dom, style);
2540         return this;
2541     },
2542
2543     
2544     getX : function(){
2545         return D.getX(this.dom);
2546     },
2547
2548     
2549     getY : function(){
2550         return D.getY(this.dom);
2551     },
2552
2553     
2554     getXY : function(){
2555         return D.getXY(this.dom);
2556     },
2557
2558     
2559     getOffsetsTo : function(el){
2560         var o = this.getXY();
2561         var e = Ext.fly(el, '_internal').getXY();
2562         return [o[0]-e[0],o[1]-e[1]];
2563     },
2564
2565     
2566     setX : function(x, animate){
2567         if(!animate || !A){
2568             D.setX(this.dom, x);
2569         }else{
2570             this.setXY([x, this.getY()], this.preanim(arguments, 1));
2571         }
2572         return this;
2573     },
2574
2575     
2576     setY : function(y, animate){
2577         if(!animate || !A){
2578             D.setY(this.dom, y);
2579         }else{
2580             this.setXY([this.getX(), y], this.preanim(arguments, 1));
2581         }
2582         return this;
2583     },
2584
2585     
2586     setLeft : function(left){
2587         this.setStyle("left", this.addUnits(left));
2588         return this;
2589     },
2590
2591     
2592     setTop : function(top){
2593         this.setStyle("top", this.addUnits(top));
2594         return this;
2595     },
2596
2597     
2598     setRight : function(right){
2599         this.setStyle("right", this.addUnits(right));
2600         return this;
2601     },
2602
2603     
2604     setBottom : function(bottom){
2605         this.setStyle("bottom", this.addUnits(bottom));
2606         return this;
2607     },
2608
2609     
2610     setXY : function(pos, animate){
2611         if(!animate || !A){
2612             D.setXY(this.dom, pos);
2613         }else{
2614             this.anim({points: {to: pos}}, this.preanim(arguments, 1), 'motion');
2615         }
2616         return this;
2617     },
2618
2619     
2620     setLocation : function(x, y, animate){
2621         this.setXY([x, y], this.preanim(arguments, 2));
2622         return this;
2623     },
2624
2625     
2626     moveTo : function(x, y, animate){
2627         this.setXY([x, y], this.preanim(arguments, 2));
2628         return this;
2629     },
2630
2631     
2632     getRegion : function(){
2633         return D.getRegion(this.dom);
2634     },
2635
2636     
2637     getHeight : function(contentHeight){
2638         var h = this.dom.offsetHeight || 0;
2639         h = contentHeight !== true ? h : h-this.getBorderWidth("tb")-this.getPadding("tb");
2640         return h < 0 ? 0 : h;
2641     },
2642
2643     
2644     getWidth : function(contentWidth){
2645         var w = this.dom.offsetWidth || 0;
2646         w = contentWidth !== true ? w : w-this.getBorderWidth("lr")-this.getPadding("lr");
2647         return w < 0 ? 0 : w;
2648     },
2649
2650     
2651     getComputedHeight : function(){
2652         var h = Math.max(this.dom.offsetHeight, this.dom.clientHeight);
2653         if(!h){
2654             h = parseInt(this.getStyle('height'), 10) || 0;
2655             if(!this.isBorderBox()){
2656                 h += this.getFrameWidth('tb');
2657             }
2658         }
2659         return h;
2660     },
2661
2662     
2663     getComputedWidth : function(){
2664         var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
2665         if(!w){
2666             w = parseInt(this.getStyle('width'), 10) || 0;
2667             if(!this.isBorderBox()){
2668                 w += this.getFrameWidth('lr');
2669             }
2670         }
2671         return w;
2672     },
2673
2674     
2675     getSize : function(contentSize){
2676         return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
2677     },
2678
2679     getStyleSize : function(){
2680         var w, h, d = this.dom, s = d.style;
2681         if(s.width && s.width != 'auto'){
2682             w = parseInt(s.width, 10);
2683             if(Ext.isBorderBox){
2684                w -= this.getFrameWidth('lr');
2685             }
2686         }
2687         if(s.height && s.height != 'auto'){
2688             h = parseInt(s.height, 10);
2689             if(Ext.isBorderBox){
2690                h -= this.getFrameWidth('tb');
2691             }
2692         }
2693         return {width: w || this.getWidth(true), height: h || this.getHeight(true)};
2694
2695     },
2696
2697     
2698     getViewSize : function(){
2699         var d = this.dom, doc = document, aw = 0, ah = 0;
2700         if(d == doc || d == doc.body){
2701             return {width : D.getViewWidth(), height: D.getViewHeight()};
2702         }else{
2703             return {
2704                 width : d.clientWidth,
2705                 height: d.clientHeight
2706             };
2707         }
2708     },
2709
2710     
2711     getValue : function(asNumber){
2712         return asNumber ? parseInt(this.dom.value, 10) : this.dom.value;
2713     },
2714
2715         adjustWidth : function(width){
2716         if(typeof width == "number"){
2717             if(this.autoBoxAdjust && !this.isBorderBox()){
2718                width -= (this.getBorderWidth("lr") + this.getPadding("lr"));
2719             }
2720             if(width < 0){
2721                 width = 0;
2722             }
2723         }
2724         return width;
2725     },
2726
2727         adjustHeight : function(height){
2728         if(typeof height == "number"){
2729            if(this.autoBoxAdjust && !this.isBorderBox()){
2730                height -= (this.getBorderWidth("tb") + this.getPadding("tb"));
2731            }
2732            if(height < 0){
2733                height = 0;
2734            }
2735         }
2736         return height;
2737     },
2738
2739     
2740     setWidth : function(width, animate){
2741         width = this.adjustWidth(width);
2742         if(!animate || !A){
2743             this.dom.style.width = this.addUnits(width);
2744         }else{
2745             this.anim({width: {to: width}}, this.preanim(arguments, 1));
2746         }
2747         return this;
2748     },
2749
2750     
2751      setHeight : function(height, animate){
2752         height = this.adjustHeight(height);
2753         if(!animate || !A){
2754             this.dom.style.height = this.addUnits(height);
2755         }else{
2756             this.anim({height: {to: height}}, this.preanim(arguments, 1));
2757         }
2758         return this;
2759     },
2760
2761     
2762      setSize : function(width, height, animate){
2763         if(typeof width == "object"){             height = width.height; width = width.width;
2764         }
2765         width = this.adjustWidth(width); height = this.adjustHeight(height);
2766         if(!animate || !A){
2767             this.dom.style.width = this.addUnits(width);
2768             this.dom.style.height = this.addUnits(height);
2769         }else{
2770             this.anim({width: {to: width}, height: {to: height}}, this.preanim(arguments, 2));
2771         }
2772         return this;
2773     },
2774
2775     
2776     setBounds : function(x, y, width, height, animate){
2777         if(!animate || !A){
2778             this.setSize(width, height);
2779             this.setLocation(x, y);
2780         }else{
2781             width = this.adjustWidth(width); height = this.adjustHeight(height);
2782             this.anim({points: {to: [x, y]}, width: {to: width}, height: {to: height}},
2783                           this.preanim(arguments, 4), 'motion');
2784         }
2785         return this;
2786     },
2787
2788     
2789     setRegion : function(region, animate){
2790         this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.preanim(arguments, 1));
2791         return this;
2792     },
2793
2794     
2795     addListener : function(eventName, fn, scope, options){
2796         Ext.EventManager.on(this.dom,  eventName, fn, scope || this, options);
2797     },
2798
2799     
2800     removeListener : function(eventName, fn){
2801         Ext.EventManager.removeListener(this.dom,  eventName, fn);
2802         return this;
2803     },
2804
2805     
2806     removeAllListeners : function(){
2807         E.purgeElement(this.dom);
2808         return this;
2809     },
2810
2811     
2812     relayEvent : function(eventName, observable){
2813         this.on(eventName, function(e){
2814             observable.fireEvent(eventName, e);
2815         });
2816     },
2817
2818     
2819      setOpacity : function(opacity, animate){
2820         if(!animate || !A){
2821             var s = this.dom.style;
2822             if(Ext.isIE){
2823                 s.zoom = 1;
2824                 s.filter = (s.filter || '').replace(/alpha\([^\)]*\)/gi,"") +
2825                            (opacity == 1 ? "" : " alpha(opacity=" + opacity * 100 + ")");
2826             }else{
2827                 s.opacity = opacity;
2828             }
2829         }else{
2830             this.anim({opacity: {to: opacity}}, this.preanim(arguments, 1), null, .35, 'easeIn');
2831         }
2832         return this;
2833     },
2834
2835     
2836     getLeft : function(local){
2837         if(!local){
2838             return this.getX();
2839         }else{
2840             return parseInt(this.getStyle("left"), 10) || 0;
2841         }
2842     },
2843
2844     
2845     getRight : function(local){
2846         if(!local){
2847             return this.getX() + this.getWidth();
2848         }else{
2849             return (this.getLeft(true) + this.getWidth()) || 0;
2850         }
2851     },
2852
2853     
2854     getTop : function(local) {
2855         if(!local){
2856             return this.getY();
2857         }else{
2858             return parseInt(this.getStyle("top"), 10) || 0;
2859         }
2860     },
2861
2862     
2863     getBottom : function(local){
2864         if(!local){
2865             return this.getY() + this.getHeight();
2866         }else{
2867             return (this.getTop(true) + this.getHeight()) || 0;
2868         }
2869     },
2870
2871     
2872     position : function(pos, zIndex, x, y){
2873         if(!pos){
2874            if(this.getStyle('position') == 'static'){
2875                this.setStyle('position', 'relative');
2876            }
2877         }else{
2878             this.setStyle("position", pos);
2879         }
2880         if(zIndex){
2881             this.setStyle("z-index", zIndex);
2882         }
2883         if(x !== undefined && y !== undefined){
2884             this.setXY([x, y]);
2885         }else if(x !== undefined){
2886             this.setX(x);
2887         }else if(y !== undefined){
2888             this.setY(y);
2889         }
2890     },
2891
2892     
2893     clearPositioning : function(value){
2894         value = value ||'';
2895         this.setStyle({
2896             "left": value,
2897             "right": value,
2898             "top": value,
2899             "bottom": value,
2900             "z-index": "",
2901             "position" : "static"
2902         });
2903         return this;
2904     },
2905
2906     
2907     getPositioning : function(){
2908         var l = this.getStyle("left");
2909         var t = this.getStyle("top");
2910         return {
2911             "position" : this.getStyle("position"),
2912             "left" : l,
2913             "right" : l ? "" : this.getStyle("right"),
2914             "top" : t,
2915             "bottom" : t ? "" : this.getStyle("bottom"),
2916             "z-index" : this.getStyle("z-index")
2917         };
2918     },
2919
2920     
2921     getBorderWidth : function(side){
2922         return this.addStyles(side, El.borders);
2923     },
2924
2925     
2926     getPadding : function(side){
2927         return this.addStyles(side, El.paddings);
2928     },
2929
2930     
2931     setPositioning : function(pc){
2932         this.applyStyles(pc);
2933         if(pc.right == "auto"){
2934             this.dom.style.right = "";
2935         }
2936         if(pc.bottom == "auto"){
2937             this.dom.style.bottom = "";
2938         }
2939         return this;
2940     },
2941
2942         fixDisplay : function(){
2943         if(this.getStyle("display") == "none"){
2944             this.setStyle("visibility", "hidden");
2945             this.setStyle("display", this.originalDisplay);             if(this.getStyle("display") == "none"){                 this.setStyle("display", "block");
2946             }
2947         }
2948     },
2949
2950         setOverflow : function(v){
2951         if(v=='auto' && Ext.isMac && Ext.isGecko){              this.dom.style.overflow = 'hidden';
2952                 (function(){this.dom.style.overflow = 'auto';}).defer(1, this);
2953         }else{
2954                 this.dom.style.overflow = v;
2955         }
2956         },
2957         
2958     
2959      setLeftTop : function(left, top){
2960         this.dom.style.left = this.addUnits(left);
2961         this.dom.style.top = this.addUnits(top);
2962         return this;
2963     },
2964
2965     
2966      move : function(direction, distance, animate){
2967         var xy = this.getXY();
2968         direction = direction.toLowerCase();
2969         switch(direction){
2970             case "l":
2971             case "left":
2972                 this.moveTo(xy[0]-distance, xy[1], this.preanim(arguments, 2));
2973                 break;
2974            case "r":
2975            case "right":
2976                 this.moveTo(xy[0]+distance, xy[1], this.preanim(arguments, 2));
2977                 break;
2978            case "t":
2979            case "top":
2980            case "up":
2981                 this.moveTo(xy[0], xy[1]-distance, this.preanim(arguments, 2));
2982                 break;
2983            case "b":
2984            case "bottom":
2985            case "down":
2986                 this.moveTo(xy[0], xy[1]+distance, this.preanim(arguments, 2));
2987                 break;
2988         }
2989         return this;
2990     },
2991
2992     
2993     clip : function(){
2994         if(!this.isClipped){
2995            this.isClipped = true;
2996            this.originalClip = {
2997                "o": this.getStyle("overflow"),
2998                "x": this.getStyle("overflow-x"),
2999                "y": this.getStyle("overflow-y")
3000            };
3001            this.setStyle("overflow", "hidden");
3002            this.setStyle("overflow-x", "hidden");
3003            this.setStyle("overflow-y", "hidden");
3004         }
3005         return this;
3006     },
3007
3008     
3009     unclip : function(){
3010         if(this.isClipped){
3011             this.isClipped = false;
3012             var o = this.originalClip;
3013             if(o.o){this.setStyle("overflow", o.o);}
3014             if(o.x){this.setStyle("overflow-x", o.x);}
3015             if(o.y){this.setStyle("overflow-y", o.y);}
3016         }
3017         return this;
3018     },
3019
3020
3021     
3022     getAnchorXY : function(anchor, local, s){
3023                 
3024         var w, h, vp = false;
3025         if(!s){
3026             var d = this.dom;
3027             if(d == document.body || d == document){
3028                 vp = true;
3029                 w = D.getViewWidth(); h = D.getViewHeight();
3030             }else{
3031                 w = this.getWidth(); h = this.getHeight();
3032             }
3033         }else{
3034             w = s.width;  h = s.height;
3035         }
3036         var x = 0, y = 0, r = Math.round;
3037         switch((anchor || "tl").toLowerCase()){
3038             case "c":
3039                 x = r(w*.5);
3040                 y = r(h*.5);
3041             break;
3042             case "t":
3043                 x = r(w*.5);
3044                 y = 0;
3045             break;
3046             case "l":
3047                 x = 0;
3048                 y = r(h*.5);
3049             break;
3050             case "r":
3051                 x = w;
3052                 y = r(h*.5);
3053             break;
3054             case "b":
3055                 x = r(w*.5);
3056                 y = h;
3057             break;
3058             case "tl":
3059                 x = 0;
3060                 y = 0;
3061             break;
3062             case "bl":
3063                 x = 0;
3064                 y = h;
3065             break;
3066             case "br":
3067                 x = w;
3068                 y = h;
3069             break;
3070             case "tr":
3071                 x = w;
3072                 y = 0;
3073             break;
3074         }
3075         if(local === true){
3076             return [x, y];
3077         }
3078         if(vp){
3079             var sc = this.getScroll();
3080             return [x + sc.left, y + sc.top];
3081         }
3082                 var o = this.getXY();
3083         return [x+o[0], y+o[1]];
3084     },
3085
3086     
3087     getAlignToXY : function(el, p, o){
3088         el = Ext.get(el);
3089         if(!el || !el.dom){
3090             throw "Element.alignToXY with an element that doesn't exist";
3091         }
3092         var d = this.dom;
3093         var c = false;         var p1 = "", p2 = "";
3094         o = o || [0,0];
3095
3096         if(!p){
3097             p = "tl-bl";
3098         }else if(p == "?"){
3099             p = "tl-bl?";
3100         }else if(p.indexOf("-") == -1){
3101             p = "tl-" + p;
3102         }
3103         p = p.toLowerCase();
3104         var m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
3105         if(!m){
3106            throw "Element.alignTo with an invalid alignment " + p;
3107         }
3108         p1 = m[1]; p2 = m[2]; c = !!m[3];
3109
3110                         var a1 = this.getAnchorXY(p1, true);
3111         var a2 = el.getAnchorXY(p2, false);
3112
3113         var x = a2[0] - a1[0] + o[0];
3114         var y = a2[1] - a1[1] + o[1];
3115
3116         if(c){
3117                         var w = this.getWidth(), h = this.getHeight(), r = el.getRegion();
3118                         var dw = D.getViewWidth()-5, dh = D.getViewHeight()-5;
3119
3120                                                 var p1y = p1.charAt(0), p1x = p1.charAt(p1.length-1);
3121            var p2y = p2.charAt(0), p2x = p2.charAt(p2.length-1);
3122            var swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
3123            var swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));
3124
3125            var doc = document;
3126            var scrollX = (doc.documentElement.scrollLeft || doc.body.scrollLeft || 0)+5;
3127            var scrollY = (doc.documentElement.scrollTop || doc.body.scrollTop || 0)+5;
3128
3129            if((x+w) > dw + scrollX){
3130                 x = swapX ? r.left-w : dw+scrollX-w;
3131             }
3132            if(x < scrollX){
3133                x = swapX ? r.right : scrollX;
3134            }
3135            if((y+h) > dh + scrollY){
3136                 y = swapY ? r.top-h : dh+scrollY-h;
3137             }
3138            if (y < scrollY){
3139                y = swapY ? r.bottom : scrollY;
3140            }
3141         }
3142         return [x,y];
3143     },
3144
3145         getConstrainToXY : function(){
3146         var os = {top:0, left:0, bottom:0, right: 0};
3147
3148         return function(el, local, offsets, proposedXY){
3149             el = Ext.get(el);
3150             offsets = offsets ? Ext.applyIf(offsets, os) : os;
3151
3152             var vw, vh, vx = 0, vy = 0;
3153             if(el.dom == document.body || el.dom == document){
3154                 vw = Ext.lib.Dom.getViewWidth();
3155                 vh = Ext.lib.Dom.getViewHeight();
3156             }else{
3157                 vw = el.dom.clientWidth;
3158                 vh = el.dom.clientHeight;
3159                 if(!local){
3160                     var vxy = el.getXY();
3161                     vx = vxy[0];
3162                     vy = vxy[1];
3163                 }
3164             }
3165
3166             var s = el.getScroll();
3167
3168             vx += offsets.left + s.left;
3169             vy += offsets.top + s.top;
3170
3171             vw -= offsets.right;
3172             vh -= offsets.bottom;
3173
3174             var vr = vx+vw;
3175             var vb = vy+vh;
3176
3177             var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);
3178             var x = xy[0], y = xy[1];
3179             var w = this.dom.offsetWidth, h = this.dom.offsetHeight;
3180
3181                         var moved = false;
3182
3183                         if((x + w) > vr){
3184                 x = vr - w;
3185                 moved = true;
3186             }
3187             if((y + h) > vb){
3188                 y = vb - h;
3189                 moved = true;
3190             }
3191                         if(x < vx){
3192                 x = vx;
3193                 moved = true;
3194             }
3195             if(y < vy){
3196                 y = vy;
3197                 moved = true;
3198             }
3199             return moved ? [x, y] : false;
3200         };
3201     }(),
3202
3203         adjustForConstraints : function(xy, parent, offsets){
3204         return this.getConstrainToXY(parent || document, false, offsets, xy) ||  xy;
3205     },
3206
3207     
3208     alignTo : function(element, position, offsets, animate){
3209         var xy = this.getAlignToXY(element, position, offsets);
3210         this.setXY(xy, this.preanim(arguments, 3));
3211         return this;
3212     },
3213
3214     
3215     anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
3216         var action = function(){
3217             this.alignTo(el, alignment, offsets, animate);
3218             Ext.callback(callback, this);
3219         };
3220         Ext.EventManager.onWindowResize(action, this);
3221         var tm = typeof monitorScroll;
3222         if(tm != 'undefined'){
3223             Ext.EventManager.on(window, 'scroll', action, this,
3224                 {buffer: tm == 'number' ? monitorScroll : 50});
3225         }
3226         action.call(this);         return this;
3227     },
3228     
3229     clearOpacity : function(){
3230         if (window.ActiveXObject) {
3231             if(typeof this.dom.style.filter == 'string' && (/alpha/i).test(this.dom.style.filter)){
3232                 this.dom.style.filter = "";
3233             }
3234         } else {
3235             this.dom.style.opacity = "";
3236             this.dom.style["-moz-opacity"] = "";
3237             this.dom.style["-khtml-opacity"] = "";
3238         }
3239         return this;
3240     },
3241
3242     
3243     hide : function(animate){
3244         this.setVisible(false, this.preanim(arguments, 0));
3245         return this;
3246     },
3247
3248     
3249     show : function(animate){
3250         this.setVisible(true, this.preanim(arguments, 0));
3251         return this;
3252     },
3253
3254     
3255     addUnits : function(size){
3256         return Ext.Element.addUnits(size, this.defaultUnit);
3257     },
3258
3259     
3260     update : function(html, loadScripts, callback){
3261         if(typeof html == "undefined"){
3262             html = "";
3263         }
3264         if(loadScripts !== true){
3265             this.dom.innerHTML = html;
3266             if(typeof callback == "function"){
3267                 callback();
3268             }
3269             return this;
3270         }
3271         var id = Ext.id();
3272         var dom = this.dom;
3273
3274         html += '<span id="' + id + '"></span>';
3275
3276         E.onAvailable(id, function(){
3277             var hd = document.getElementsByTagName("head")[0];
3278             var re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig;
3279             var srcRe = /\ssrc=([\'\"])(.*?)\1/i;
3280             var typeRe = /\stype=([\'\"])(.*?)\1/i;
3281
3282             var match;
3283             while(match = re.exec(html)){
3284                 var attrs = match[1];
3285                 var srcMatch = attrs ? attrs.match(srcRe) : false;
3286                 if(srcMatch && srcMatch[2]){
3287                    var s = document.createElement("script");
3288                    s.src = srcMatch[2];
3289                    var typeMatch = attrs.match(typeRe);
3290                    if(typeMatch && typeMatch[2]){
3291                        s.type = typeMatch[2];
3292                    }
3293                    hd.appendChild(s);
3294                 }else if(match[2] && match[2].length > 0){
3295                     if(window.execScript) {
3296                        window.execScript(match[2]);
3297                     } else {
3298                        window.eval(match[2]);
3299                     }
3300                 }
3301             }
3302             var el = document.getElementById(id);
3303             if(el){Ext.removeNode(el);}
3304             if(typeof callback == "function"){
3305                 callback();
3306             }
3307         });
3308         dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
3309         return this;
3310     },
3311
3312     
3313     load : function(){
3314         var um = this.getUpdater();
3315         um.update.apply(um, arguments);
3316         return this;
3317     },
3318
3319     
3320     getUpdater : function(){
3321         if(!this.updateManager){
3322             this.updateManager = new Ext.Updater(this);
3323         }
3324         return this.updateManager;
3325     },
3326
3327     
3328     unselectable : function(){
3329         this.dom.unselectable = "on";
3330         this.swallowEvent("selectstart", true);
3331         this.applyStyles("-moz-user-select:none;-khtml-user-select:none;");
3332         this.addClass("x-unselectable");
3333         return this;
3334     },
3335
3336     
3337     getCenterXY : function(){
3338         return this.getAlignToXY(document, 'c-c');
3339     },
3340
3341     
3342     center : function(centerIn){
3343         this.alignTo(centerIn || document, 'c-c');
3344         return this;
3345     },
3346
3347     
3348     isBorderBox : function(){
3349         return noBoxAdjust[this.dom.tagName.toLowerCase()] || Ext.isBorderBox;
3350     },
3351
3352     
3353     getBox : function(contentBox, local){
3354         var xy;
3355         if(!local){
3356             xy = this.getXY();
3357         }else{
3358             var left = parseInt(this.getStyle("left"), 10) || 0;
3359             var top = parseInt(this.getStyle("top"), 10) || 0;
3360             xy = [left, top];
3361         }
3362         var el = this.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
3363         if(!contentBox){
3364             bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
3365         }else{
3366             var l = this.getBorderWidth("l")+this.getPadding("l");
3367             var r = this.getBorderWidth("r")+this.getPadding("r");
3368             var t = this.getBorderWidth("t")+this.getPadding("t");
3369             var b = this.getBorderWidth("b")+this.getPadding("b");
3370             bx = {x: xy[0]+l, y: xy[1]+t, 0: xy[0]+l, 1: xy[1]+t, width: w-(l+r), height: h-(t+b)};
3371         }
3372         bx.right = bx.x + bx.width;
3373         bx.bottom = bx.y + bx.height;
3374         return bx;
3375     },
3376
3377     
3378     getFrameWidth : function(sides, onlyContentBox){
3379         return onlyContentBox && Ext.isBorderBox ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
3380     },
3381
3382     
3383     setBox : function(box, adjust, animate){
3384         var w = box.width, h = box.height;
3385         if((adjust && !this.autoBoxAdjust) && !this.isBorderBox()){
3386            w -= (this.getBorderWidth("lr") + this.getPadding("lr"));
3387            h -= (this.getBorderWidth("tb") + this.getPadding("tb"));
3388         }
3389         this.setBounds(box.x, box.y, w, h, this.preanim(arguments, 2));
3390         return this;
3391     },
3392
3393     
3394      repaint : function(){
3395         var dom = this.dom;
3396         this.addClass("x-repaint");
3397         setTimeout(function(){
3398             Ext.get(dom).removeClass("x-repaint");
3399         }, 1);
3400         return this;
3401     },
3402
3403     
3404     getMargins : function(side){
3405         if(!side){
3406             return {
3407                 top: parseInt(this.getStyle("margin-top"), 10) || 0,
3408                 left: parseInt(this.getStyle("margin-left"), 10) || 0,
3409                 bottom: parseInt(this.getStyle("margin-bottom"), 10) || 0,
3410                 right: parseInt(this.getStyle("margin-right"), 10) || 0
3411             };
3412         }else{
3413             return this.addStyles(side, El.margins);
3414          }
3415     },
3416
3417         addStyles : function(sides, styles){
3418         var val = 0, v, w;
3419         for(var i = 0, len = sides.length; i < len; i++){
3420             v = this.getStyle(styles[sides.charAt(i)]);
3421             if(v){
3422                  w = parseInt(v, 10);
3423                  if(w){ val += (w >= 0 ? w : -1 * w); }
3424             }
3425         }
3426         return val;
3427     },
3428
3429     
3430     createProxy : function(config, renderTo, matchBox){
3431         config = typeof config == "object" ?
3432             config : {tag : "div", cls: config};
3433
3434         var proxy;
3435         if(renderTo){
3436             proxy = Ext.DomHelper.append(renderTo, config, true);
3437         }else {
3438             proxy = Ext.DomHelper.insertBefore(this.dom, config, true);
3439         }
3440         if(matchBox){
3441            proxy.setBox(this.getBox());
3442         }
3443         return proxy;
3444     },
3445
3446     
3447     mask : function(msg, msgCls){
3448         if(this.getStyle("position") == "static"){
3449             this.setStyle("position", "relative");
3450         }
3451         if(this._maskMsg){
3452             this._maskMsg.remove();
3453         }
3454         if(this._mask){
3455             this._mask.remove();
3456         }
3457
3458         this._mask = Ext.DomHelper.append(this.dom, {cls:"ext-el-mask"}, true);
3459
3460         this.addClass("x-masked");
3461         this._mask.setDisplayed(true);
3462         if(typeof msg == 'string'){
3463             this._maskMsg = Ext.DomHelper.append(this.dom, {cls:"ext-el-mask-msg", cn:{tag:'div'}}, true);
3464             var mm = this._maskMsg;
3465             mm.dom.className = msgCls ? "ext-el-mask-msg " + msgCls : "ext-el-mask-msg";
3466             mm.dom.firstChild.innerHTML = msg;
3467             mm.setDisplayed(true);
3468             mm.center(this);
3469         }
3470         if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && this.getStyle('height') == 'auto'){             this._mask.setSize(this.dom.clientWidth, this.getHeight());
3471         }
3472         return this._mask;
3473     },
3474
3475     
3476     unmask : function(){
3477         if(this._mask){
3478             if(this._maskMsg){
3479                 this._maskMsg.remove();
3480                 delete this._maskMsg;
3481             }
3482             this._mask.remove();
3483             delete this._mask;
3484         }
3485         this.removeClass("x-masked");
3486     },
3487
3488     
3489     isMasked : function(){
3490         return this._mask && this._mask.isVisible();
3491     },
3492
3493     
3494     createShim : function(){
3495         var el = document.createElement('iframe');
3496         el.frameBorder = 'no';
3497         el.className = 'ext-shim';
3498         if(Ext.isIE && Ext.isSecure){
3499             el.src = Ext.SSL_SECURE_URL;
3500         }
3501         var shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
3502         shim.autoBoxAdjust = false;
3503         return shim;
3504     },
3505
3506     
3507     remove : function(){
3508         Ext.removeNode(this.dom);
3509         delete El.cache[this.dom.id];
3510     },
3511
3512     
3513     hover : function(overFn, outFn, scope){
3514         var preOverFn = function(e){
3515             if(!e.within(this, true)){
3516                 overFn.apply(scope || this, arguments);
3517             }
3518         };
3519         var preOutFn = function(e){
3520             if(!e.within(this, true)){
3521                 outFn.apply(scope || this, arguments);
3522             }
3523         };
3524         this.on("mouseover", preOverFn, this.dom);
3525         this.on("mouseout", preOutFn, this.dom);
3526         return this;
3527     },
3528
3529     
3530     addClassOnOver : function(className, preventFlicker){
3531         this.hover(
3532             function(){
3533                 Ext.fly(this, '_internal').addClass(className);
3534             },
3535             function(){
3536                 Ext.fly(this, '_internal').removeClass(className);
3537             }
3538         );
3539         return this;
3540     },
3541
3542     
3543     addClassOnFocus : function(className){
3544         this.on("focus", function(){
3545             Ext.fly(this, '_internal').addClass(className);
3546         }, this.dom);
3547         this.on("blur", function(){
3548             Ext.fly(this, '_internal').removeClass(className);
3549         }, this.dom);
3550         return this;
3551     },
3552     
3553     addClassOnClick : function(className){
3554         var dom = this.dom;
3555         this.on("mousedown", function(){
3556             Ext.fly(dom, '_internal').addClass(className);
3557             var d = Ext.getDoc();
3558             var fn = function(){
3559                 Ext.fly(dom, '_internal').removeClass(className);
3560                 d.removeListener("mouseup", fn);
3561             };
3562             d.on("mouseup", fn);
3563         });
3564         return this;
3565     },
3566
3567     
3568     swallowEvent : function(eventName, preventDefault){
3569         var fn = function(e){
3570             e.stopPropagation();
3571             if(preventDefault){
3572                 e.preventDefault();
3573             }
3574         };
3575         if(Ext.isArray(eventName)){
3576             for(var i = 0, len = eventName.length; i < len; i++){
3577                  this.on(eventName[i], fn);
3578             }
3579             return this;
3580         }
3581         this.on(eventName, fn);
3582         return this;
3583     },
3584
3585     
3586     parent : function(selector, returnDom){
3587         return this.matchNode('parentNode', 'parentNode', selector, returnDom);
3588     },
3589
3590      
3591     next : function(selector, returnDom){
3592         return this.matchNode('nextSibling', 'nextSibling', selector, returnDom);
3593     },
3594
3595     
3596     prev : function(selector, returnDom){
3597         return this.matchNode('previousSibling', 'previousSibling', selector, returnDom);
3598     },
3599
3600
3601     
3602     first : function(selector, returnDom){
3603         return this.matchNode('nextSibling', 'firstChild', selector, returnDom);
3604     },
3605
3606     
3607     last : function(selector, returnDom){
3608         return this.matchNode('previousSibling', 'lastChild', selector, returnDom);
3609     },
3610
3611     matchNode : function(dir, start, selector, returnDom){
3612         var n = this.dom[start];
3613         while(n){
3614             if(n.nodeType == 1 && (!selector || Ext.DomQuery.is(n, selector))){
3615                 return !returnDom ? Ext.get(n) : n;
3616             }
3617             n = n[dir];
3618         }
3619         return null;
3620     },
3621
3622     
3623     appendChild: function(el){
3624         el = Ext.get(el);
3625         el.appendTo(this);
3626         return this;
3627     },
3628
3629     
3630     createChild: function(config, insertBefore, returnDom){
3631         config = config || {tag:'div'};
3632         if(insertBefore){
3633             return Ext.DomHelper.insertBefore(insertBefore, config, returnDom !== true);
3634         }
3635         return Ext.DomHelper[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config,  returnDom !== true);
3636     },
3637
3638     
3639     appendTo: function(el){
3640         el = Ext.getDom(el);
3641         el.appendChild(this.dom);
3642         return this;
3643     },
3644
3645     
3646     insertBefore: function(el){
3647         el = Ext.getDom(el);
3648         el.parentNode.insertBefore(this.dom, el);
3649         return this;
3650     },
3651
3652     
3653     insertAfter: function(el){
3654         el = Ext.getDom(el);
3655         el.parentNode.insertBefore(this.dom, el.nextSibling);
3656         return this;
3657     },
3658
3659     
3660     insertFirst: function(el, returnDom){
3661         el = el || {};
3662         if(typeof el == 'object' && !el.nodeType && !el.dom){             return this.createChild(el, this.dom.firstChild, returnDom);
3663         }else{
3664             el = Ext.getDom(el);
3665             this.dom.insertBefore(el, this.dom.firstChild);
3666             return !returnDom ? Ext.get(el) : el;
3667         }
3668     },
3669
3670     
3671     insertSibling: function(el, where, returnDom){
3672         var rt;
3673         if(Ext.isArray(el)){
3674             for(var i = 0, len = el.length; i < len; i++){
3675                 rt = this.insertSibling(el[i], where, returnDom);
3676             }
3677             return rt;
3678         }
3679         where = where ? where.toLowerCase() : 'before';
3680         el = el || {};
3681         var refNode = where == 'before' ? this.dom : this.dom.nextSibling;
3682
3683         if(typeof el == 'object' && !el.nodeType && !el.dom){             if(where == 'after' && !this.dom.nextSibling){
3684                 rt = Ext.DomHelper.append(this.dom.parentNode, el, !returnDom);
3685             }else{
3686                 rt = Ext.DomHelper[where == 'after' ? 'insertAfter' : 'insertBefore'](this.dom, el, !returnDom);
3687             }
3688
3689         }else{
3690             rt = this.dom.parentNode.insertBefore(Ext.getDom(el), refNode);
3691             if(!returnDom){
3692                 rt = Ext.get(rt);
3693             }
3694         }
3695         return rt;
3696     },
3697
3698     
3699     wrap: function(config, returnDom){
3700         if(!config){
3701             config = {tag: "div"};
3702         }
3703         var newEl = Ext.DomHelper.insertBefore(this.dom, config, !returnDom);
3704         newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
3705         return newEl;
3706     },
3707
3708     
3709     replace: function(el){
3710         el = Ext.get(el);
3711         this.insertBefore(el);
3712         el.remove();
3713         return this;
3714     },
3715
3716     
3717     replaceWith: function(el){
3718         if(typeof el == 'object' && !el.nodeType && !el.dom){             el = this.insertSibling(el, 'before');
3719         }else{
3720             el = Ext.getDom(el);
3721             this.dom.parentNode.insertBefore(el, this.dom);
3722         }
3723         El.uncache(this.id);
3724         this.dom.parentNode.removeChild(this.dom);
3725         this.dom = el;
3726         this.id = Ext.id(el);
3727         El.cache[this.id] = this;
3728         return this;
3729     },
3730
3731     
3732     insertHtml : function(where, html, returnEl){
3733         var el = Ext.DomHelper.insertHtml(where, this.dom, html);
3734         return returnEl ? Ext.get(el) : el;
3735     },
3736
3737     
3738     set : function(o, useSet){
3739         var el = this.dom;
3740         useSet = typeof useSet == 'undefined' ? (el.setAttribute ? true : false) : useSet;
3741         for(var attr in o){
3742             if(attr == "style" || typeof o[attr] == "function") continue;
3743             if(attr=="cls"){
3744                 el.className = o["cls"];
3745             }else if(o.hasOwnProperty(attr)){
3746                 if(useSet) el.setAttribute(attr, o[attr]);
3747                 else el[attr] = o[attr];
3748             }
3749         }
3750         if(o.style){
3751             Ext.DomHelper.applyStyles(el, o.style);
3752         }
3753         return this;
3754     },
3755
3756     
3757     addKeyListener : function(key, fn, scope){
3758         var config;
3759         if(typeof key != "object" || Ext.isArray(key)){
3760             config = {
3761                 key: key,
3762                 fn: fn,
3763                 scope: scope
3764             };
3765         }else{
3766             config = {
3767                 key : key.key,
3768                 shift : key.shift,
3769                 ctrl : key.ctrl,
3770                 alt : key.alt,
3771                 fn: fn,
3772                 scope: scope
3773             };
3774         }
3775         return new Ext.KeyMap(this, config);
3776     },
3777
3778     
3779     addKeyMap : function(config){
3780         return new Ext.KeyMap(this, config);
3781     },
3782
3783     
3784      isScrollable : function(){
3785         var dom = this.dom;
3786         return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
3787     },
3788
3789     
3790     scrollTo : function(side, value, animate){
3791         var prop = side.toLowerCase() == "left" ? "scrollLeft" : "scrollTop";
3792         if(!animate || !A){
3793             this.dom[prop] = value;
3794         }else{
3795             var to = prop == "scrollLeft" ? [value, this.dom.scrollTop] : [this.dom.scrollLeft, value];
3796             this.anim({scroll: {"to": to}}, this.preanim(arguments, 2), 'scroll');
3797         }
3798         return this;
3799     },
3800
3801     
3802      scroll : function(direction, distance, animate){
3803          if(!this.isScrollable()){
3804              return;
3805          }
3806          var el = this.dom;
3807          var l = el.scrollLeft, t = el.scrollTop;
3808          var w = el.scrollWidth, h = el.scrollHeight;
3809          var cw = el.clientWidth, ch = el.clientHeight;
3810          direction = direction.toLowerCase();
3811          var scrolled = false;
3812          var a = this.preanim(arguments, 2);
3813          switch(direction){
3814              case "l":
3815              case "left":
3816                  if(w - l > cw){
3817                      var v = Math.min(l + distance, w-cw);
3818                      this.scrollTo("left", v, a);
3819                      scrolled = true;
3820                  }
3821                  break;
3822             case "r":
3823             case "right":
3824                  if(l > 0){
3825                      var v = Math.max(l - distance, 0);
3826                      this.scrollTo("left", v, a);
3827                      scrolled = true;
3828                  }
3829                  break;
3830             case "t":
3831             case "top":
3832             case "up":
3833                  if(t > 0){
3834                      var v = Math.max(t - distance, 0);
3835                      this.scrollTo("top", v, a);
3836                      scrolled = true;
3837                  }
3838                  break;
3839             case "b":
3840             case "bottom":
3841             case "down":
3842                  if(h - t > ch){
3843                      var v = Math.min(t + distance, h-ch);
3844                      this.scrollTo("top", v, a);
3845                      scrolled = true;
3846                  }
3847                  break;
3848          }
3849          return scrolled;
3850     },
3851
3852     
3853     translatePoints : function(x, y){
3854         if(typeof x == 'object' || Ext.isArray(x)){
3855             y = x[1]; x = x[0];
3856         }
3857         var p = this.getStyle('position');
3858         var o = this.getXY();
3859
3860         var l = parseInt(this.getStyle('left'), 10);
3861         var t = parseInt(this.getStyle('top'), 10);
3862
3863         if(isNaN(l)){
3864             l = (p == "relative") ? 0 : this.dom.offsetLeft;
3865         }
3866         if(isNaN(t)){
3867             t = (p == "relative") ? 0 : this.dom.offsetTop;
3868         }
3869
3870         return {left: (x - o[0] + l), top: (y - o[1] + t)};
3871     },
3872
3873     
3874     getScroll : function(){
3875         var d = this.dom, doc = document;
3876         if(d == doc || d == doc.body){
3877             var l, t;
3878             if(Ext.isIE && Ext.isStrict){
3879                 l = doc.documentElement.scrollLeft || (doc.body.scrollLeft || 0);
3880                 t = doc.documentElement.scrollTop || (doc.body.scrollTop || 0);
3881             }else{
3882                 l = window.pageXOffset || (doc.body.scrollLeft || 0);
3883                 t = window.pageYOffset || (doc.body.scrollTop || 0);
3884             }
3885             return {left: l, top: t};
3886         }else{
3887             return {left: d.scrollLeft, top: d.scrollTop};
3888         }
3889     },
3890
3891     
3892     getColor : function(attr, defaultValue, prefix){
3893         var v = this.getStyle(attr);
3894         if(!v || v == "transparent" || v == "inherit") {
3895             return defaultValue;
3896         }
3897         var color = typeof prefix == "undefined" ? "#" : prefix;
3898         if(v.substr(0, 4) == "rgb("){
3899             var rvs = v.slice(4, v.length -1).split(",");
3900             for(var i = 0; i < 3; i++){
3901                 var h = parseInt(rvs[i]);
3902                 var s = h.toString(16);
3903                 if(h < 16){
3904                     s = "0" + s;
3905                 }
3906                 color += s;
3907             }
3908         } else {
3909             if(v.substr(0, 1) == "#"){
3910                 if(v.length == 4) {
3911                     for(var i = 1; i < 4; i++){
3912                         var c = v.charAt(i);
3913                         color +=  c + c;
3914                     }
3915                 }else if(v.length == 7){
3916                     color += v.substr(1);
3917                 }
3918             }
3919         }
3920         return(color.length > 5 ? color.toLowerCase() : defaultValue);
3921     },
3922
3923     
3924     boxWrap : function(cls){
3925         cls = cls || 'x-box';
3926         var el = Ext.get(this.insertHtml('beforeBegin', String.format('<div class="{0}">'+El.boxMarkup+'</div>', cls)));
3927         el.child('.'+cls+'-mc').dom.appendChild(this.dom);
3928         return el;
3929     },
3930
3931     
3932     getAttributeNS : Ext.isIE ? function(ns, name){
3933         var d = this.dom;
3934         var type = typeof d[ns+":"+name];
3935         if(type != 'undefined' && type != 'unknown'){
3936             return d[ns+":"+name];
3937         }
3938         return d[name];
3939     } : function(ns, name){
3940         var d = this.dom;
3941         return d.getAttributeNS(ns, name) || d.getAttribute(ns+":"+name) || d.getAttribute(name) || d[name];
3942     },
3943
3944     getTextWidth : function(text, min, max){
3945         return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
3946     }
3947 };
3948
3949 var ep = El.prototype;
3950
3951
3952 ep.on = ep.addListener;
3953     ep.mon = ep.addListener;
3954
3955 ep.getUpdateManager = ep.getUpdater;
3956
3957
3958 ep.un = ep.removeListener;
3959
3960
3961 ep.autoBoxAdjust = true;
3962
3963 El.unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i;
3964
3965 El.addUnits = function(v, defaultUnit){
3966     if(v === "" || v == "auto"){
3967         return v;
3968     }
3969     if(v === undefined){
3970         return '';
3971     }
3972     if(typeof v == "number" || !El.unitPattern.test(v)){
3973         return v + (defaultUnit || 'px');
3974     }
3975     return v;
3976 };
3977
3978 El.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
3979
3980 El.VISIBILITY = 1;
3981
3982 El.DISPLAY = 2;
3983
3984 El.borders = {l: "border-left-width", r: "border-right-width", t: "border-top-width", b: "border-bottom-width"};
3985 El.paddings = {l: "padding-left", r: "padding-right", t: "padding-top", b: "padding-bottom"};
3986 El.margins = {l: "margin-left", r: "margin-right", t: "margin-top", b: "margin-bottom"};
3987
3988
3989
3990
3991 El.cache = {};
3992
3993 var docEl;
3994
3995
3996 El.get = function(el){
3997     var ex, elm, id;
3998     if(!el){ return null; }
3999     if(typeof el == "string"){         if(!(elm = document.getElementById(el))){
4000             return null;
4001         }
4002         if(ex = El.cache[el]){
4003             ex.dom = elm;
4004         }else{
4005             ex = El.cache[el] = new El(elm);
4006         }
4007         return ex;
4008     }else if(el.tagName){         if(!(id = el.id)){
4009             id = Ext.id(el);
4010         }
4011         if(ex = El.cache[id]){
4012             ex.dom = el;
4013         }else{
4014             ex = El.cache[id] = new El(el);
4015         }
4016         return ex;
4017     }else if(el instanceof El){
4018         if(el != docEl){
4019             el.dom = document.getElementById(el.id) || el.dom;                                                                       El.cache[el.id] = el;         }
4020         return el;
4021     }else if(el.isComposite){
4022         return el;
4023     }else if(Ext.isArray(el)){
4024         return El.select(el);
4025     }else if(el == document){
4026                 if(!docEl){
4027             var f = function(){};
4028             f.prototype = El.prototype;
4029             docEl = new f();
4030             docEl.dom = document;
4031         }
4032         return docEl;
4033     }
4034     return null;
4035 };
4036
4037 El.uncache = function(el){
4038     for(var i = 0, a = arguments, len = a.length; i < len; i++) {
4039         if(a[i]){
4040             delete El.cache[a[i].id || a[i]];
4041         }
4042     }
4043 };
4044
4045 El.garbageCollect = function(){
4046     if(!Ext.enableGarbageCollector){
4047         clearInterval(El.collectorThread);
4048         return;
4049     }
4050     for(var eid in El.cache){
4051         var el = El.cache[eid], d = el.dom;
4052                                                                                                                                                 if(!d || !d.parentNode || (!d.offsetParent && !document.getElementById(eid))){
4053             delete El.cache[eid];
4054             if(d && Ext.enableListenerCollection){
4055                 E.purgeElement(d);
4056             }
4057         }
4058     }
4059 }
4060 El.collectorThreadId = setInterval(El.garbageCollect, 30000);
4061
4062 var flyFn = function(){};
4063 flyFn.prototype = El.prototype;
4064 var _cls = new flyFn();
4065
4066 El.Flyweight = function(dom){
4067     this.dom = dom;
4068 };
4069
4070 El.Flyweight.prototype = _cls;
4071 El.Flyweight.prototype.isFlyweight = true;
4072
4073 El._flyweights = {};
4074
4075 El.fly = function(el, named){
4076     named = named || '_global';
4077     el = Ext.getDom(el);
4078     if(!el){
4079         return null;
4080     }
4081     if(!El._flyweights[named]){
4082         El._flyweights[named] = new El.Flyweight();
4083     }
4084     El._flyweights[named].dom = el;
4085     return El._flyweights[named];
4086 };
4087
4088
4089 Ext.get = El.get;
4090
4091 Ext.fly = El.fly;
4092
4093 var noBoxAdjust = Ext.isStrict ? {
4094     select:1
4095 } : {
4096     input:1, select:1, textarea:1
4097 };
4098 if(Ext.isIE || Ext.isGecko){
4099     noBoxAdjust['button'] = 1;
4100 }
4101
4102
4103 Ext.EventManager.on(window, 'unload', function(){
4104     delete El.cache;
4105     delete El._flyweights;
4106 });
4107 })();
4108
4109 Ext.enableFx = true;
4110
4111
4112 Ext.Fx = {
4113         
4114     slideIn : function(anchor, o){
4115         var el = this.getFxEl();
4116         o = o || {};
4117
4118         el.queueFx(o, function(){
4119
4120             anchor = anchor || "t";
4121
4122                         this.fixDisplay();
4123
4124                         var r = this.getFxRestore();
4125             var b = this.getBox();
4126                         this.setSize(b);
4127
4128                         var wrap = this.fxWrap(r.pos, o, "hidden");
4129
4130             var st = this.dom.style;
4131             st.visibility = "visible";
4132             st.position = "absolute";
4133
4134                         var after = function(){
4135                 el.fxUnwrap(wrap, r.pos, o);
4136                 st.width = r.width;
4137                 st.height = r.height;
4138                 el.afterFx(o);
4139             };
4140                         var a, pt = {to: [b.x, b.y]}, bw = {to: b.width}, bh = {to: b.height};
4141
4142             switch(anchor.toLowerCase()){
4143                 case "t":
4144                     wrap.setSize(b.width, 0);
4145                     st.left = st.bottom = "0";
4146                     a = {height: bh};
4147                 break;
4148                 case "l":
4149                     wrap.setSize(0, b.height);
4150                     st.right = st.top = "0";
4151                     a = {width: bw};
4152                 break;
4153                 case "r":
4154                     wrap.setSize(0, b.height);
4155                     wrap.setX(b.right);
4156                     st.left = st.top = "0";
4157                     a = {width: bw, points: pt};
4158                 break;
4159                 case "b":
4160                     wrap.setSize(b.width, 0);
4161                     wrap.setY(b.bottom);
4162                     st.left = st.top = "0";
4163                     a = {height: bh, points: pt};
4164                 break;
4165                 case "tl":
4166                     wrap.setSize(0, 0);
4167                     st.right = st.bottom = "0";
4168                     a = {width: bw, height: bh};
4169                 break;
4170                 case "bl":
4171                     wrap.setSize(0, 0);
4172                     wrap.setY(b.y+b.height);
4173                     st.right = st.top = "0";
4174                     a = {width: bw, height: bh, points: pt};
4175                 break;
4176                 case "br":
4177                     wrap.setSize(0, 0);
4178                     wrap.setXY([b.right, b.bottom]);
4179                     st.left = st.top = "0";
4180                     a = {width: bw, height: bh, points: pt};
4181                 break;
4182                 case "tr":
4183                     wrap.setSize(0, 0);
4184                     wrap.setX(b.x+b.width);
4185                     st.left = st.bottom = "0";
4186                     a = {width: bw, height: bh, points: pt};
4187                 break;
4188             }
4189             this.dom.style.visibility = "visible";
4190             wrap.show();
4191
4192             arguments.callee.anim = wrap.fxanim(a,
4193                 o,
4194                 'motion',
4195                 .5,
4196                 'easeOut', after);
4197         });
4198         return this;
4199     },
4200     
4201         
4202     slideOut : function(anchor, o){
4203         var el = this.getFxEl();
4204         o = o || {};
4205
4206         el.queueFx(o, function(){
4207
4208             anchor = anchor || "t";
4209
4210                         var r = this.getFxRestore();
4211             
4212             var b = this.getBox();
4213                         this.setSize(b);
4214
4215                         var wrap = this.fxWrap(r.pos, o, "visible");
4216
4217             var st = this.dom.style;
4218             st.visibility = "visible";
4219             st.position = "absolute";
4220
4221             wrap.setSize(b);
4222
4223             var after = function(){
4224                 if(o.useDisplay){
4225                     el.setDisplayed(false);
4226                 }else{
4227                     el.hide();
4228                 }
4229
4230                 el.fxUnwrap(wrap, r.pos, o);
4231
4232                 st.width = r.width;
4233                 st.height = r.height;
4234
4235                 el.afterFx(o);
4236             };
4237
4238             var a, zero = {to: 0};
4239             switch(anchor.toLowerCase()){
4240                 case "t":
4241                     st.left = st.bottom = "0";
4242                     a = {height: zero};
4243                 break;
4244                 case "l":
4245                     st.right = st.top = "0";
4246                     a = {width: zero};
4247                 break;
4248                 case "r":
4249                     st.left = st.top = "0";
4250                     a = {width: zero, points: {to:[b.right, b.y]}};
4251                 break;
4252                 case "b":
4253                     st.left = st.top = "0";
4254                     a = {height: zero, points: {to:[b.x, b.bottom]}};
4255                 break;
4256                 case "tl":
4257                     st.right = st.bottom = "0";
4258                     a = {width: zero, height: zero};
4259                 break;
4260                 case "bl":
4261                     st.right = st.top = "0";
4262                     a = {width: zero, height: zero, points: {to:[b.x, b.bottom]}};
4263                 break;
4264                 case "br":
4265                     st.left = st.top = "0";
4266                     a = {width: zero, height: zero, points: {to:[b.x+b.width, b.bottom]}};
4267                 break;
4268                 case "tr":
4269                     st.left = st.bottom = "0";
4270                     a = {width: zero, height: zero, points: {to:[b.right, b.y]}};
4271                 break;
4272             }
4273
4274             arguments.callee.anim = wrap.fxanim(a,
4275                 o,
4276                 'motion',
4277                 .5,
4278                 "easeOut", after);
4279         });
4280         return this;
4281     },
4282
4283         
4284     puff : function(o){
4285         var el = this.getFxEl();
4286         o = o || {};
4287
4288         el.queueFx(o, function(){
4289             this.clearOpacity();
4290             this.show();
4291
4292                         var r = this.getFxRestore();
4293             var st = this.dom.style;
4294
4295             var after = function(){
4296                 if(o.useDisplay){
4297                     el.setDisplayed(false);
4298                 }else{
4299                     el.hide();
4300                 }
4301
4302                 el.clearOpacity();
4303
4304                 el.setPositioning(r.pos);
4305                 st.width = r.width;
4306                 st.height = r.height;
4307                 st.fontSize = '';
4308                 el.afterFx(o);
4309             };
4310
4311             var width = this.getWidth();
4312             var height = this.getHeight();
4313
4314             arguments.callee.anim = this.fxanim({
4315                     width : {to: this.adjustWidth(width * 2)},
4316                     height : {to: this.adjustHeight(height * 2)},
4317                     points : {by: [-(width * .5), -(height * .5)]},
4318                     opacity : {to: 0},
4319                     fontSize: {to:200, unit: "%"}
4320                 },
4321                 o,
4322                 'motion',
4323                 .5,
4324                 "easeOut", after);
4325         });
4326         return this;
4327     },
4328
4329         
4330     switchOff : function(o){
4331         var el = this.getFxEl();
4332         o = o || {};
4333
4334         el.queueFx(o, function(){
4335             this.clearOpacity();
4336             this.clip();
4337
4338                         var r = this.getFxRestore();
4339             var st = this.dom.style;
4340
4341             var after = function(){
4342                 if(o.useDisplay){
4343                     el.setDisplayed(false);
4344                 }else{
4345                     el.hide();
4346                 }
4347
4348                 el.clearOpacity();
4349                 el.setPositioning(r.pos);
4350                 st.width = r.width;
4351                 st.height = r.height;
4352
4353                 el.afterFx(o);
4354             };
4355
4356             this.fxanim({opacity:{to:0.3}}, null, null, .1, null, function(){
4357                 this.clearOpacity();
4358                 (function(){
4359                     this.fxanim({
4360                         height:{to:1},
4361                         points:{by:[0, this.getHeight() * .5]}
4362                     }, o, 'motion', 0.3, 'easeIn', after);
4363                 }).defer(100, this);
4364             });
4365         });
4366         return this;
4367     },
4368
4369         
4370     highlight : function(color, o){
4371         var el = this.getFxEl();
4372         o = o || {};
4373
4374         el.queueFx(o, function(){
4375             color = color || "ffff9c";
4376             var attr = o.attr || "backgroundColor";
4377
4378             this.clearOpacity();
4379             this.show();
4380
4381             var origColor = this.getColor(attr);
4382             var restoreColor = this.dom.style[attr];
4383             var endColor = (o.endColor || origColor) || "ffffff";
4384
4385             var after = function(){
4386                 el.dom.style[attr] = restoreColor;
4387                 el.afterFx(o);
4388             };
4389
4390             var a = {};
4391             a[attr] = {from: color, to: endColor};
4392             arguments.callee.anim = this.fxanim(a,
4393                 o,
4394                 'color',
4395                 1,
4396                 'easeIn', after);
4397         });
4398         return this;
4399     },
4400
4401    
4402     frame : function(color, count, o){
4403         var el = this.getFxEl();
4404         o = o || {};
4405
4406         el.queueFx(o, function(){
4407             color = color || "#C3DAF9";
4408             if(color.length == 6){
4409                 color = "#" + color;
4410             }
4411             count = count || 1;
4412             var duration = o.duration || 1;
4413             this.show();
4414
4415             var b = this.getBox();
4416             var animFn = function(){
4417                 var proxy = Ext.getBody().createChild({
4418                      style:{
4419                         visbility:"hidden",
4420                         position:"absolute",
4421                         "z-index":"35000",                         border:"0px solid " + color
4422                      }
4423                   });
4424                 var scale = Ext.isBorderBox ? 2 : 1;
4425                 proxy.animate({
4426                     top:{from:b.y, to:b.y - 20},
4427                     left:{from:b.x, to:b.x - 20},
4428                     borderWidth:{from:0, to:10},
4429                     opacity:{from:1, to:0},
4430                     height:{from:b.height, to:(b.height + (20*scale))},
4431                     width:{from:b.width, to:(b.width + (20*scale))}
4432                 }, duration, function(){
4433                     proxy.remove();
4434                     if(--count > 0){
4435                          animFn();
4436                     }else{
4437                         el.afterFx(o);
4438                     }
4439                 });
4440             };
4441             animFn.call(this);
4442         });
4443         return this;
4444     },
4445
4446    
4447     pause : function(seconds){
4448         var el = this.getFxEl();
4449         var o = {};
4450
4451         el.queueFx(o, function(){
4452             setTimeout(function(){
4453                 el.afterFx(o);
4454             }, seconds * 1000);
4455         });
4456         return this;
4457     },
4458
4459    
4460     fadeIn : function(o){
4461         var el = this.getFxEl();
4462         o = o || {};
4463         el.queueFx(o, function(){
4464             this.setOpacity(0);
4465             this.fixDisplay();
4466             this.dom.style.visibility = 'visible';
4467             var to = o.endOpacity || 1;
4468             arguments.callee.anim = this.fxanim({opacity:{to:to}},
4469                 o, null, .5, "easeOut", function(){
4470                 if(to == 1){
4471                     this.clearOpacity();
4472                 }
4473                 el.afterFx(o);
4474             });
4475         });
4476         return this;
4477     },
4478
4479    
4480     fadeOut : function(o){
4481         var el = this.getFxEl();
4482         o = o || {};
4483         el.queueFx(o, function(){
4484             arguments.callee.anim = this.fxanim({opacity:{to:o.endOpacity || 0}},
4485                 o, null, .5, "easeOut", function(){
4486                 if(this.visibilityMode == Ext.Element.DISPLAY || o.useDisplay){
4487                      this.dom.style.display = "none";
4488                 }else{
4489                      this.dom.style.visibility = "hidden";
4490                 }
4491                 this.clearOpacity();
4492                 el.afterFx(o);
4493             });
4494         });
4495         return this;
4496     },
4497
4498    
4499     scale : function(w, h, o){
4500         this.shift(Ext.apply({}, o, {
4501             width: w,
4502             height: h
4503         }));
4504         return this;
4505     },
4506
4507    
4508     shift : function(o){
4509         var el = this.getFxEl();
4510         o = o || {};
4511         el.queueFx(o, function(){
4512             var a = {}, w = o.width, h = o.height, x = o.x, y = o.y,  op = o.opacity;
4513             if(w !== undefined){
4514                 a.width = {to: this.adjustWidth(w)};
4515             }
4516             if(h !== undefined){
4517                 a.height = {to: this.adjustHeight(h)};
4518             }
4519             if(x !== undefined || y !== undefined){
4520                 a.points = {to: [
4521                     x !== undefined ? x : this.getX(),
4522                     y !== undefined ? y : this.getY()
4523                 ]};
4524             }
4525             if(op !== undefined){
4526                 a.opacity = {to: op};
4527             }
4528             if(o.xy !== undefined){
4529                 a.points = {to: o.xy};
4530             }
4531             arguments.callee.anim = this.fxanim(a,
4532                 o, 'motion', .35, "easeOut", function(){
4533                 el.afterFx(o);
4534             });
4535         });
4536         return this;
4537     },
4538
4539         
4540     ghost : function(anchor, o){
4541         var el = this.getFxEl();
4542         o = o || {};
4543
4544         el.queueFx(o, function(){
4545             anchor = anchor || "b";
4546
4547                         var r = this.getFxRestore();
4548             var w = this.getWidth(),
4549                 h = this.getHeight();
4550
4551             var st = this.dom.style;
4552
4553             var after = function(){
4554                 if(o.useDisplay){
4555                     el.setDisplayed(false);
4556                 }else{
4557                     el.hide();
4558                 }
4559
4560                 el.clearOpacity();
4561                 el.setPositioning(r.pos);
4562                 st.width = r.width;
4563                 st.height = r.height;
4564
4565                 el.afterFx(o);
4566             };
4567
4568             var a = {opacity: {to: 0}, points: {}}, pt = a.points;
4569             switch(anchor.toLowerCase()){
4570                 case "t":
4571                     pt.by = [0, -h];
4572                 break;
4573                 case "l":
4574                     pt.by = [-w, 0];
4575                 break;
4576                 case "r":
4577                     pt.by = [w, 0];
4578                 break;
4579                 case "b":
4580                     pt.by = [0, h];
4581                 break;
4582                 case "tl":
4583                     pt.by = [-w, -h];
4584                 break;
4585                 case "bl":
4586                     pt.by = [-w, h];
4587                 break;
4588                 case "br":
4589                     pt.by = [w, h];
4590                 break;
4591                 case "tr":
4592                     pt.by = [w, -h];
4593                 break;
4594             }
4595
4596             arguments.callee.anim = this.fxanim(a,
4597                 o,
4598                 'motion',
4599                 .5,
4600                 "easeOut", after);
4601         });
4602         return this;
4603     },
4604
4605         
4606     syncFx : function(){
4607         this.fxDefaults = Ext.apply(this.fxDefaults || {}, {
4608             block : false,
4609             concurrent : true,
4610             stopFx : false
4611         });
4612         return this;
4613     },
4614
4615         
4616     sequenceFx : function(){
4617         this.fxDefaults = Ext.apply(this.fxDefaults || {}, {
4618             block : false,
4619             concurrent : false,
4620             stopFx : false
4621         });
4622         return this;
4623     },
4624
4625         
4626     nextFx : function(){
4627         var ef = this.fxQueue[0];
4628         if(ef){
4629             ef.call(this);
4630         }
4631     },
4632
4633         
4634     hasActiveFx : function(){
4635         return this.fxQueue && this.fxQueue[0];
4636     },
4637
4638         
4639     stopFx : function(){
4640         if(this.hasActiveFx()){
4641             var cur = this.fxQueue[0];
4642             if(cur && cur.anim && cur.anim.isAnimated()){
4643                 this.fxQueue = [cur];                 cur.anim.stop(true);
4644             }
4645         }
4646         return this;
4647     },
4648
4649         
4650     beforeFx : function(o){
4651         if(this.hasActiveFx() && !o.concurrent){
4652            if(o.stopFx){
4653                this.stopFx();
4654                return true;
4655            }
4656            return false;
4657         }
4658         return true;
4659     },
4660
4661         
4662     hasFxBlock : function(){
4663         var q = this.fxQueue;
4664         return q && q[0] && q[0].block;
4665     },
4666
4667         
4668     queueFx : function(o, fn){
4669         if(!this.fxQueue){
4670             this.fxQueue = [];
4671         }
4672         if(!this.hasFxBlock()){
4673             Ext.applyIf(o, this.fxDefaults);
4674             if(!o.concurrent){
4675                 var run = this.beforeFx(o);
4676                 fn.block = o.block;
4677                 this.fxQueue.push(fn);
4678                 if(run){
4679                     this.nextFx();
4680                 }
4681             }else{
4682                 fn.call(this);
4683             }
4684         }
4685         return this;
4686     },
4687
4688         
4689     fxWrap : function(pos, o, vis){
4690         var wrap;
4691         if(!o.wrap || !(wrap = Ext.get(o.wrap))){
4692             var wrapXY;
4693             if(o.fixPosition){
4694                 wrapXY = this.getXY();
4695             }
4696             var div = document.createElement("div");
4697             div.style.visibility = vis;
4698             wrap = Ext.get(this.dom.parentNode.insertBefore(div, this.dom));
4699             wrap.setPositioning(pos);
4700             if(wrap.getStyle("position") == "static"){
4701                 wrap.position("relative");
4702             }
4703             this.clearPositioning('auto');
4704             wrap.clip();
4705             wrap.dom.appendChild(this.dom);
4706             if(wrapXY){
4707                 wrap.setXY(wrapXY);
4708             }
4709         }
4710         return wrap;
4711     },
4712
4713         
4714     fxUnwrap : function(wrap, pos, o){
4715         this.clearPositioning();
4716         this.setPositioning(pos);
4717         if(!o.wrap){
4718             wrap.dom.parentNode.insertBefore(this.dom, wrap.dom);
4719             wrap.remove();
4720         }
4721     },
4722
4723         
4724     getFxRestore : function(){
4725         var st = this.dom.style;
4726         return {pos: this.getPositioning(), width: st.width, height : st.height};
4727     },
4728
4729         
4730     afterFx : function(o){
4731         if(o.afterStyle){
4732             this.applyStyles(o.afterStyle);
4733         }
4734         if(o.afterCls){
4735             this.addClass(o.afterCls);
4736         }
4737         if(o.remove === true){
4738             this.remove();
4739         }
4740         Ext.callback(o.callback, o.scope, [this]);
4741         if(!o.concurrent){
4742             this.fxQueue.shift();
4743             this.nextFx();
4744         }
4745     },
4746
4747         
4748     getFxEl : function(){         return Ext.get(this.dom);
4749     },
4750
4751         
4752     fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
4753         animType = animType || 'run';
4754         opt = opt || {};
4755         var anim = Ext.lib.Anim[animType](
4756             this.dom, args,
4757             (opt.duration || defaultDur) || .35,
4758             (opt.easing || defaultEase) || 'easeOut',
4759             function(){
4760                 Ext.callback(cb, this);
4761             },
4762             this
4763         );
4764         opt.anim = anim;
4765         return anim;
4766     }
4767 };
4768
4769 Ext.Fx.resize = Ext.Fx.scale;
4770
4771 Ext.apply(Ext.Element.prototype, Ext.Fx);
4772
4773 \r
4774 Ext.CompositeElement = function(els){\r
4775     this.elements = [];\r
4776     this.addElements(els);\r
4777 };\r
4778 Ext.CompositeElement.prototype = {\r
4779     isComposite: true,\r
4780     addElements : function(els){\r
4781         if(!els) return this;\r
4782         if(typeof els == "string"){\r
4783             els = Ext.Element.selectorFunction(els);\r
4784         }\r
4785         var yels = this.elements;\r
4786         var index = yels.length-1;\r
4787         for(var i = 0, len = els.length; i < len; i++) {\r
4788                 yels[++index] = Ext.get(els[i]);\r
4789         }\r
4790         return this;\r
4791     },\r
4792 \r
4793     \r
4794     fill : function(els){\r
4795         this.elements = [];\r
4796         this.add(els);\r
4797         return this;\r
4798     },\r
4799 \r
4800     \r
4801     filter : function(selector){\r
4802         var els = [];\r
4803         this.each(function(el){\r
4804             if(el.is(selector)){\r
4805                 els[els.length] = el.dom;\r
4806             }\r
4807         });\r
4808         this.fill(els);\r
4809         return this;\r
4810     },\r
4811 \r
4812     invoke : function(fn, args){\r
4813         var els = this.elements;\r
4814         for(var i = 0, len = els.length; i < len; i++) {\r
4815                 Ext.Element.prototype[fn].apply(els[i], args);\r
4816         }\r
4817         return this;\r
4818     },\r
4819     \r
4820     add : function(els){\r
4821         if(typeof els == "string"){\r
4822             this.addElements(Ext.Element.selectorFunction(els));\r
4823         }else if(els.length !== undefined){\r
4824             this.addElements(els);\r
4825         }else{\r
4826             this.addElements([els]);\r
4827         }\r
4828         return this;\r
4829     },\r
4830     \r
4831     each : function(fn, scope){\r
4832         var els = this.elements;\r
4833         for(var i = 0, len = els.length; i < len; i++){\r
4834             if(fn.call(scope || els[i], els[i], this, i) === false) {\r
4835                 break;\r
4836             }\r
4837         }\r
4838         return this;\r
4839     },\r
4840 \r
4841     \r
4842     item : function(index){\r
4843         return this.elements[index] || null;\r
4844     },\r
4845 \r
4846     \r
4847     first : function(){\r
4848         return this.item(0);\r
4849     },\r
4850 \r
4851     \r
4852     last : function(){\r
4853         return this.item(this.elements.length-1);\r
4854     },\r
4855 \r
4856     \r
4857     getCount : function(){\r
4858         return this.elements.length;\r
4859     },\r
4860 \r
4861     \r
4862     contains : function(el){\r
4863         return this.indexOf(el) !== -1;\r
4864     },\r
4865 \r
4866     \r
4867     indexOf : function(el){\r
4868         return this.elements.indexOf(Ext.get(el));\r
4869     },\r
4870 \r
4871 \r
4872     \r
4873     removeElement : function(el, removeDom){\r
4874         if(Ext.isArray(el)){\r
4875             for(var i = 0, len = el.length; i < len; i++){\r
4876                 this.removeElement(el[i]);\r
4877             }\r
4878             return this;\r
4879         }\r
4880         var index = typeof el == 'number' ? el : this.indexOf(el);\r
4881         if(index !== -1 && this.elements[index]){\r
4882             if(removeDom){\r
4883                 var d = this.elements[index];\r
4884                 if(d.dom){\r
4885                     d.remove();\r
4886                 }else{\r
4887                     Ext.removeNode(d);\r
4888                 }\r
4889             }\r
4890             this.elements.splice(index, 1);\r
4891         }\r
4892         return this;\r
4893     },\r
4894 \r
4895     \r
4896     replaceElement : function(el, replacement, domReplace){\r
4897         var index = typeof el == 'number' ? el : this.indexOf(el);\r
4898         if(index !== -1){\r
4899             if(domReplace){\r
4900                 this.elements[index].replaceWith(replacement);\r
4901             }else{\r
4902                 this.elements.splice(index, 1, Ext.get(replacement))\r
4903             }\r
4904         }\r
4905         return this;\r
4906     },\r
4907 \r
4908     \r
4909     clear : function(){\r
4910         this.elements = [];\r
4911     }\r
4912 };\r
4913 (function(){\r
4914 Ext.CompositeElement.createCall = function(proto, fnName){\r
4915     if(!proto[fnName]){\r
4916         proto[fnName] = function(){\r
4917             return this.invoke(fnName, arguments);\r
4918         };\r
4919     }\r
4920 };\r
4921 for(var fnName in Ext.Element.prototype){\r
4922     if(typeof Ext.Element.prototype[fnName] == "function"){\r
4923         Ext.CompositeElement.createCall(Ext.CompositeElement.prototype, fnName);\r
4924     }\r
4925 };\r
4926 })();\r
4927 \r
4928 \r
4929 Ext.CompositeElementLite = function(els){\r
4930     Ext.CompositeElementLite.superclass.constructor.call(this, els);\r
4931     this.el = new Ext.Element.Flyweight();\r
4932 };\r
4933 Ext.extend(Ext.CompositeElementLite, Ext.CompositeElement, {\r
4934     addElements : function(els){\r
4935         if(els){\r
4936             if(Ext.isArray(els)){\r
4937                 this.elements = this.elements.concat(els);\r
4938             }else{\r
4939                 var yels = this.elements;\r
4940                 var index = yels.length-1;\r
4941                 for(var i = 0, len = els.length; i < len; i++) {\r
4942                     yels[++index] = els[i];\r
4943                 }\r
4944             }\r
4945         }\r
4946         return this;\r
4947     },\r
4948     invoke : function(fn, args){\r
4949         var els = this.elements;\r
4950         var el = this.el;\r
4951         for(var i = 0, len = els.length; i < len; i++) {\r
4952             el.dom = els[i];\r
4953                 Ext.Element.prototype[fn].apply(el, args);\r
4954         }\r
4955         return this;\r
4956     },\r
4957     \r
4958     item : function(index){\r
4959         if(!this.elements[index]){\r
4960             return null;\r
4961         }\r
4962         this.el.dom = this.elements[index];\r
4963         return this.el;\r
4964     },\r
4965 \r
4966     
4967     addListener : function(eventName, handler, scope, opt){\r
4968         var els = this.elements;\r
4969         for(var i = 0, len = els.length; i < len; i++) {\r
4970             Ext.EventManager.on(els[i], eventName, handler, scope || els[i], opt);\r
4971         }\r
4972         return this;\r
4973     },\r
4974 \r
4975     \r
4976     each : function(fn, scope){\r
4977         var els = this.elements;\r
4978         var el = this.el;\r
4979         for(var i = 0, len = els.length; i < len; i++){\r
4980             el.dom = els[i];\r
4981                 if(fn.call(scope || el, el, this, i) === false){\r
4982                 break;\r
4983             }\r
4984         }\r
4985         return this;\r
4986     },\r
4987 \r
4988     indexOf : function(el){\r
4989         return this.elements.indexOf(Ext.getDom(el));\r
4990     },\r
4991 \r
4992     replaceElement : function(el, replacement, domReplace){\r
4993         var index = typeof el == 'number' ? el : this.indexOf(el);\r
4994         if(index !== -1){\r
4995             replacement = Ext.getDom(replacement);\r
4996             if(domReplace){\r
4997                 var d = this.elements[index];\r
4998                 d.parentNode.insertBefore(replacement, d);\r
4999                 Ext.removeNode(d);\r
5000             }\r
5001             this.elements.splice(index, 1, replacement);\r
5002         }\r
5003         return this;\r
5004     }\r
5005 });\r
5006 Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;\r
5007 if(Ext.DomQuery){\r
5008     Ext.Element.selectorFunction = Ext.DomQuery.select;\r
5009 }\r
5010 \r
5011 Ext.Element.select = function(selector, unique, root){\r
5012     var els;\r
5013     if(typeof selector == "string"){\r
5014         els = Ext.Element.selectorFunction(selector, root);\r
5015     }else if(selector.length !== undefined){\r
5016         els = selector;\r
5017     }else{\r
5018         throw "Invalid selector";\r
5019     }\r
5020     if(unique === true){\r
5021         return new Ext.CompositeElement(els);\r
5022     }else{\r
5023         return new Ext.CompositeElementLite(els);\r
5024     }\r
5025 };\r
5026 \r
5027 Ext.select = Ext.Element.select;
5028 \r
5029 Ext.data.Connection = function(config){\r
5030     Ext.apply(this, config);\r
5031     this.addEvents(\r
5032         \r
5033         "beforerequest",\r
5034         \r
5035         "requestcomplete",\r
5036         \r
5037         "requestexception"\r
5038     );\r
5039     Ext.data.Connection.superclass.constructor.call(this);\r
5040 };\r
5041 \r
5042 Ext.extend(Ext.data.Connection, Ext.util.Observable, {\r
5043     \r
5044     \r
5045     \r
5046     \r
5047     \r
5048     timeout : 30000,\r
5049     \r
5050     autoAbort:false,\r
5051 \r
5052     \r
5053     disableCaching: true,\r
5054 \r
5055     \r
5056     request : function(o){\r
5057         if(this.fireEvent("beforerequest", this, o) !== false){\r
5058             var p = o.params;\r
5059 \r
5060             if(typeof p == "function"){\r
5061                 p = p.call(o.scope||window, o);\r
5062             }\r
5063             if(typeof p == "object"){\r
5064                 p = Ext.urlEncode(p);\r
5065             }\r
5066             if(this.extraParams){\r
5067                 var extras = Ext.urlEncode(this.extraParams);\r
5068                 p = p ? (p + '&' + extras) : extras;\r
5069             }\r
5070 \r
5071             var url = o.url || this.url;\r
5072             if(typeof url == 'function'){\r
5073                 url = url.call(o.scope||window, o);\r
5074             }\r
5075 \r
5076             if(o.form){\r
5077                 var form = Ext.getDom(o.form);\r
5078                 url = url || form.action;\r
5079 \r
5080                 var enctype = form.getAttribute("enctype");\r
5081                 if(o.isUpload || (enctype && enctype.toLowerCase() == 'multipart/form-data')){\r
5082                     return this.doFormUpload(o, p, url);\r
5083                 }\r
5084                 var f = Ext.lib.Ajax.serializeForm(form);\r
5085                 p = p ? (p + '&' + f) : f;\r
5086             }\r
5087 \r
5088             var hs = o.headers;\r
5089             if(this.defaultHeaders){\r
5090                 hs = Ext.apply(hs || {}, this.defaultHeaders);\r
5091                 if(!o.headers){\r
5092                     o.headers = hs;\r
5093                 }\r
5094             }\r
5095 \r
5096             var cb = {\r
5097                 success: this.handleResponse,\r
5098                 failure: this.handleFailure,\r
5099                 scope: this,\r
5100                 argument: {options: o},\r
5101                 timeout : o.timeout || this.timeout\r
5102             };\r
5103 \r
5104             var method = o.method||this.method||(p ? "POST" : "GET");\r
5105 \r
5106             if(method == 'GET' && (this.disableCaching && o.disableCaching !== false) || o.disableCaching === true){\r
5107                 url += (url.indexOf('?') != -1 ? '&' : '?') + '_dc=' + (new Date().getTime());\r
5108             }\r
5109 \r
5110             if(typeof o.autoAbort == 'boolean'){ 
5111                 if(o.autoAbort){\r
5112                     this.abort();\r
5113                 }\r
5114             }else if(this.autoAbort !== false){\r
5115                 this.abort();\r
5116             }\r
5117             if((method == 'GET' && p) || o.xmlData || o.jsonData){\r
5118                 url += (url.indexOf('?') != -1 ? '&' : '?') + p;\r
5119                 p = '';\r
5120             }\r
5121             this.transId = Ext.lib.Ajax.request(method, url, cb, p, o);\r
5122             return this.transId;\r
5123         }else{\r
5124             Ext.callback(o.callback, o.scope, [o, null, null]);\r
5125             return null;\r
5126         }\r
5127     },\r
5128 \r
5129     \r
5130     isLoading : function(transId){\r
5131         if(transId){\r
5132             return Ext.lib.Ajax.isCallInProgress(transId);\r
5133         }else{\r
5134             return this.transId ? true : false;\r
5135         }\r
5136     },\r
5137 \r
5138     \r
5139     abort : function(transId){\r
5140         if(transId || this.isLoading()){\r
5141             Ext.lib.Ajax.abort(transId || this.transId);\r
5142         }\r
5143     },\r
5144 \r
5145     
5146     handleResponse : function(response){\r
5147         this.transId = false;\r
5148         var options = response.argument.options;\r
5149         response.argument = options ? options.argument : null;\r
5150         this.fireEvent("requestcomplete", this, response, options);\r
5151         Ext.callback(options.success, options.scope, [response, options]);\r
5152         Ext.callback(options.callback, options.scope, [options, true, response]);\r
5153     },\r
5154 \r
5155     
5156     handleFailure : function(response, e){\r
5157         this.transId = false;\r
5158         var options = response.argument.options;\r
5159         response.argument = options ? options.argument : null;\r
5160         this.fireEvent("requestexception", this, response, options, e);\r
5161         Ext.callback(options.failure, options.scope, [response, options]);\r
5162         Ext.callback(options.callback, options.scope, [options, false, response]);\r
5163     },\r
5164 \r
5165     
5166     doFormUpload : function(o, ps, url){\r
5167         var id = Ext.id();\r
5168         var frame = document.createElement('iframe');\r
5169         frame.id = id;\r
5170         frame.name = id;\r
5171         frame.className = 'x-hidden';\r
5172         if(Ext.isIE){\r
5173             frame.src = Ext.SSL_SECURE_URL;\r
5174         }\r
5175         document.body.appendChild(frame);\r
5176 \r
5177         if(Ext.isIE){\r
5178            document.frames[id].name = id;\r
5179         }\r
5180 \r
5181         var form = Ext.getDom(o.form);\r
5182         form.target = id;\r
5183         form.method = 'POST';\r
5184         form.enctype = form.encoding = 'multipart/form-data';\r
5185         if(url){\r
5186             form.action = url;\r
5187         }\r
5188 \r
5189         var hiddens, hd;\r
5190         if(ps){ 
5191             hiddens = [];\r
5192             ps = Ext.urlDecode(ps, false);\r
5193             for(var k in ps){\r
5194                 if(ps.hasOwnProperty(k)){\r
5195                     hd = document.createElement('input');\r
5196                     hd.type = 'hidden';\r
5197                     hd.name = k;\r
5198                     hd.value = ps[k];\r
5199                     form.appendChild(hd);\r
5200                     hiddens.push(hd);\r
5201                 }\r
5202             }\r
5203         }\r
5204 \r
5205         function cb(){\r
5206             var r = {  
5207                 responseText : '',\r
5208                 responseXML : null\r
5209             };\r
5210 \r
5211             r.argument = o ? o.argument : null;\r
5212 \r
5213             try { 
5214                 var doc;\r
5215                 if(Ext.isIE){\r
5216                     doc = frame.contentWindow.document;\r
5217                 }else {\r
5218                     doc = (frame.contentDocument || window.frames[id].document);\r
5219                 }\r
5220                 if(doc && doc.body){\r
5221                     r.responseText = doc.body.innerHTML;\r
5222                 }\r
5223                 if(doc && doc.XMLDocument){\r
5224                     r.responseXML = doc.XMLDocument;\r
5225                 }else {\r
5226                     r.responseXML = doc;\r
5227                 }\r
5228             }\r
5229             catch(e) {\r
5230                 
5231             }\r
5232 \r
5233             Ext.EventManager.removeListener(frame, 'load', cb, this);\r
5234 \r
5235             this.fireEvent("requestcomplete", this, r, o);\r
5236 \r
5237             Ext.callback(o.success, o.scope, [r, o]);\r
5238             Ext.callback(o.callback, o.scope, [o, true, r]);\r
5239 \r
5240             setTimeout(function(){Ext.removeNode(frame);}, 100);\r
5241         }\r
5242 \r
5243         Ext.EventManager.on(frame, 'load', cb, this);\r
5244         form.submit();\r
5245 \r
5246         if(hiddens){ 
5247             for(var i = 0, len = hiddens.length; i < len; i++){\r
5248                 Ext.removeNode(hiddens[i]);\r
5249             }\r
5250         }\r
5251     }\r
5252 });\r
5253 \r
5254 \r
5255 Ext.Ajax = new Ext.data.Connection({\r
5256     \r
5257     \r
5258     \r
5259     \r
5260     \r
5261     \r
5262 \r
5263     \r
5264 \r
5265     \r
5266     \r
5267     \r
5268     \r
5269     \r
5270     \r
5271 \r
5272     \r
5273     autoAbort : false,\r
5274 \r
5275     \r
5276     serializeForm : function(form){\r
5277         return Ext.lib.Ajax.serializeForm(form);\r
5278     }\r
5279 });
5280 \r
5281 Ext.Updater = function(el, forceNew){\r
5282     el = Ext.get(el);\r
5283     if(!forceNew && el.updateManager){\r
5284         return el.updateManager;\r
5285     }\r
5286     \r
5287     this.el = el;\r
5288     \r
5289     this.defaultUrl = null;\r
5290 \r
5291     this.addEvents(\r
5292         \r
5293         "beforeupdate",\r
5294         \r
5295         "update",\r
5296         \r
5297         "failure"\r
5298     );\r
5299     var d = Ext.Updater.defaults;\r
5300     \r
5301     this.sslBlankUrl = d.sslBlankUrl;\r
5302     \r
5303     this.disableCaching = d.disableCaching;\r
5304     \r
5305     this.indicatorText = d.indicatorText;\r
5306     \r
5307     this.showLoadIndicator = d.showLoadIndicator;\r
5308     \r
5309     this.timeout = d.timeout;\r
5310 \r
5311     \r
5312     this.loadScripts = d.loadScripts;\r
5313 \r
5314     \r
5315     this.transaction = null;\r
5316 \r
5317     \r
5318     this.autoRefreshProcId = null;\r
5319     \r
5320     this.refreshDelegate = this.refresh.createDelegate(this);\r
5321     \r
5322     this.updateDelegate = this.update.createDelegate(this);\r
5323     \r
5324     this.formUpdateDelegate = this.formUpdate.createDelegate(this);\r
5325 \r
5326     if(!this.renderer){\r
5327      \r
5328     this.renderer = new Ext.Updater.BasicRenderer();\r
5329     }\r
5330     Ext.Updater.superclass.constructor.call(this);\r
5331 };\r
5332 \r
5333 Ext.extend(Ext.Updater, Ext.util.Observable, {\r
5334     \r
5335     getEl : function(){\r
5336         return this.el;\r
5337     },\r
5338     \r
5339     update : function(url, params, callback, discardUrl){\r
5340         if(this.fireEvent("beforeupdate", this.el, url, params) !== false){\r
5341             var method = this.method, cfg, callerScope;\r
5342             if(typeof url == "object"){ 
5343                 cfg = url;\r
5344                 url = cfg.url;\r
5345                 params = params || cfg.params;\r
5346                 callback = callback || cfg.callback;\r
5347                 discardUrl = discardUrl || cfg.discardUrl;\r
5348                     callerScope = cfg.scope;\r
5349                 if(typeof cfg.method != "undefined"){method = cfg.method;};\r
5350                 if(typeof cfg.nocache != "undefined"){this.disableCaching = cfg.nocache;};\r
5351                 if(typeof cfg.text != "undefined"){this.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};\r
5352                 if(typeof cfg.scripts != "undefined"){this.loadScripts = cfg.scripts;};\r
5353                 if(typeof cfg.timeout != "undefined"){this.timeout = cfg.timeout;};\r
5354             }\r
5355             this.showLoading();\r
5356             if(!discardUrl){\r
5357                 this.defaultUrl = url;\r
5358             }\r
5359             if(typeof url == "function"){\r
5360                 url = url.call(this);\r
5361             }\r
5362 \r
5363             method = method || (params ? "POST" : "GET");\r
5364             if(method == "GET"){\r
5365                 url = this.prepareUrl(url);\r
5366             }\r
5367 \r
5368             var o = Ext.apply(cfg ||{}, {\r
5369                 url : url,\r
5370                 params: (typeof params == "function" && callerScope) ? params.createDelegate(callerScope) : params,\r
5371                 success: this.processSuccess,\r
5372                 failure: this.processFailure,\r
5373                 scope: this,\r
5374                 callback: undefined,\r
5375                 timeout: (this.timeout*1000),\r
5376                 argument: {\r
5377                         "options": cfg,\r
5378                         "url": url,\r
5379                         "form": null,\r
5380                         "callback": callback,\r
5381                         "scope": callerScope || window,\r
5382                         "params": params\r
5383                 }\r
5384             });\r
5385 \r
5386             this.transaction = Ext.Ajax.request(o);\r
5387         }\r
5388     },\r
5389 \r
5390     \r
5391     formUpdate : function(form, url, reset, callback){\r
5392         if(this.fireEvent("beforeupdate", this.el, form, url) !== false){\r
5393             if(typeof url == "function"){\r
5394                 url = url.call(this);\r
5395             }\r
5396             form = Ext.getDom(form)\r
5397             this.transaction = Ext.Ajax.request({\r
5398                 form: form,\r
5399                 url:url,\r
5400                 success: this.processSuccess,\r
5401                 failure: this.processFailure,\r
5402                 scope: this,\r
5403                 timeout: (this.timeout*1000),\r
5404                 argument: {\r
5405                         "url": url,\r
5406                         "form": form,\r
5407                         "callback": callback,\r
5408                         "reset": reset\r
5409                 }\r
5410             });\r
5411             this.showLoading.defer(1, this);\r
5412         }\r
5413     },\r
5414 \r
5415     \r
5416     refresh : function(callback){\r
5417         if(this.defaultUrl == null){\r
5418             return;\r
5419         }\r
5420         this.update(this.defaultUrl, null, callback, true);\r
5421     },\r
5422 \r
5423     \r
5424     startAutoRefresh : function(interval, url, params, callback, refreshNow){\r
5425         if(refreshNow){\r
5426             this.update(url || this.defaultUrl, params, callback, true);\r
5427         }\r
5428         if(this.autoRefreshProcId){\r
5429             clearInterval(this.autoRefreshProcId);\r
5430         }\r
5431         this.autoRefreshProcId = setInterval(this.update.createDelegate(this, [url || this.defaultUrl, params, callback, true]), interval*1000);\r
5432     },\r
5433 \r
5434     \r
5435      stopAutoRefresh : function(){\r
5436         if(this.autoRefreshProcId){\r
5437             clearInterval(this.autoRefreshProcId);\r
5438             delete this.autoRefreshProcId;\r
5439         }\r
5440     },\r
5441 \r
5442     isAutoRefreshing : function(){\r
5443        return this.autoRefreshProcId ? true : false;\r
5444     },\r
5445     \r
5446     showLoading : function(){\r
5447         if(this.showLoadIndicator){\r
5448             this.el.update(this.indicatorText);\r
5449         }\r
5450     },\r
5451 \r
5452     \r
5453     prepareUrl : function(url){\r
5454         if(this.disableCaching){\r
5455             var append = "_dc=" + (new Date().getTime());\r
5456             if(url.indexOf("?") !== -1){\r
5457                 url += "&" + append;\r
5458             }else{\r
5459                 url += "?" + append;\r
5460             }\r
5461         }\r
5462         return url;\r
5463     },\r
5464 \r
5465     \r
5466     processSuccess : function(response){\r
5467         this.transaction = null;\r
5468         if(response.argument.form && response.argument.reset){\r
5469             try{ 
5470                 response.argument.form.reset();\r
5471             }catch(e){}\r
5472         }\r
5473         if(this.loadScripts){\r
5474             this.renderer.render(this.el, response, this,\r
5475                 this.updateComplete.createDelegate(this, [response]));\r
5476         }else{\r
5477             this.renderer.render(this.el, response, this);\r
5478             this.updateComplete(response);\r
5479         }\r
5480     },\r
5481 \r
5482     updateComplete : function(response){\r
5483         this.fireEvent("update", this.el, response);\r
5484         if(typeof response.argument.callback == "function"){\r
5485             response.argument.callback.call(response.argument.scope, this.el, true, response, response.argument.options);\r
5486         }\r
5487     },\r
5488 \r
5489     \r
5490     processFailure : function(response){\r
5491         this.transaction = null;\r
5492         this.fireEvent("failure", this.el, response);\r
5493         if(typeof response.argument.callback == "function"){\r
5494             response.argument.callback.call(response.argument.scope, this.el, false, response, response.argument.options);\r
5495         }\r
5496     },\r
5497 \r
5498     \r
5499     setRenderer : function(renderer){\r
5500         this.renderer = renderer;\r
5501     },\r
5502 \r
5503     getRenderer : function(){\r
5504        return this.renderer;\r
5505     },\r
5506 \r
5507     \r
5508     setDefaultUrl : function(defaultUrl){\r
5509         this.defaultUrl = defaultUrl;\r
5510     },\r
5511 \r
5512     \r
5513     abort : function(){\r
5514         if(this.transaction){\r
5515             Ext.Ajax.abort(this.transaction);\r
5516         }\r
5517     },\r
5518 \r
5519     \r
5520     isUpdating : function(){\r
5521         if(this.transaction){\r
5522             return Ext.Ajax.isLoading(this.transaction);\r
5523         }\r
5524         return false;\r
5525     }\r
5526 });\r
5527 \r
5528 \r
5529    Ext.Updater.defaults = {\r
5530        \r
5531          timeout : 30,\r
5532 \r
5533          \r
5534         loadScripts : false,\r
5535 \r
5536         \r
5537         sslBlankUrl : (Ext.SSL_SECURE_URL || "javascript:false"),\r
5538         \r
5539         disableCaching : false,\r
5540         \r
5541         showLoadIndicator : true,\r
5542         \r
5543         indicatorText : '<div class="loading-indicator">Loading...</div>'\r
5544    };\r
5545 \r
5546 \r
5547 Ext.Updater.updateElement = function(el, url, params, options){\r
5548     var um = Ext.get(el).getUpdater();\r
5549     Ext.apply(um, options);\r
5550     um.update(url, params, options ? options.callback : null);\r
5551 };\r
5552
5553 Ext.Updater.update = Ext.Updater.updateElement;\r
5554 \r
5555 Ext.Updater.BasicRenderer = function(){};\r
5556 \r
5557 Ext.Updater.BasicRenderer.prototype = {\r
5558     \r
5559      render : function(el, response, updateManager, callback){\r
5560         el.update(response.responseText, updateManager.loadScripts, callback);\r
5561     }\r
5562 };\r
5563 \r
5564 Ext.UpdateManager = Ext.Updater;\r
5565
5566
5567
5568
5569
5570 Date.parseFunctions = {count:0};
5571 Date.parseRegexes = [];
5572 Date.formatFunctions = {count:0};
5573
5574 Date.prototype.dateFormat = function(format) {
5575     if (Date.formatFunctions[format] == null) {
5576         Date.createNewFormat(format);
5577     }
5578     var func = Date.formatFunctions[format];
5579     return this[func]();
5580 };
5581
5582
5583
5584 Date.prototype.format = Date.prototype.dateFormat;
5585
5586 Date.createNewFormat = function(format) {
5587     var funcName = "format" + Date.formatFunctions.count++;
5588     Date.formatFunctions[format] = funcName;
5589     var code = "Date.prototype." + funcName + " = function(){return ";
5590     var special = false;
5591     var ch = '';
5592     for (var i = 0; i < format.length; ++i) {
5593         ch = format.charAt(i);
5594         if (!special && ch == "\\") {
5595             special = true;
5596         }
5597         else if (special) {
5598             special = false;
5599             code += "'" + String.escape(ch) + "' + ";
5600         }
5601         else {
5602             code += Date.getFormatCode(ch);
5603         }
5604     }
5605     eval(code.substring(0, code.length - 3) + ";}");
5606 };
5607
5608 Date.getFormatCode = function(character) {
5609     switch (character) {
5610     case "d":
5611         return "String.leftPad(this.getDate(), 2, '0') + ";
5612     case "D":
5613         return "Date.getShortDayName(this.getDay()) + ";     case "j":
5614         return "this.getDate() + ";
5615     case "l":
5616         return "Date.dayNames[this.getDay()] + ";
5617     case "N":
5618         return "(this.getDay() ? this.getDay() : 7) + ";
5619     case "S":
5620         return "this.getSuffix() + ";
5621     case "w":
5622         return "this.getDay() + ";
5623     case "z":
5624         return "this.getDayOfYear() + ";
5625     case "W":
5626         return "String.leftPad(this.getWeekOfYear(), 2, '0') + ";
5627     case "F":
5628         return "Date.monthNames[this.getMonth()] + ";
5629     case "m":
5630         return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
5631     case "M":
5632         return "Date.getShortMonthName(this.getMonth()) + ";     case "n":
5633         return "(this.getMonth() + 1) + ";
5634     case "t":
5635         return "this.getDaysInMonth() + ";
5636     case "L":
5637         return "(this.isLeapYear() ? 1 : 0) + ";
5638     case "o":
5639         return "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0))) + ";
5640     case "Y":
5641         return "this.getFullYear() + ";
5642     case "y":
5643         return "('' + this.getFullYear()).substring(2, 4) + ";
5644     case "a":
5645         return "(this.getHours() < 12 ? 'am' : 'pm') + ";
5646     case "A":
5647         return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
5648     case "g":
5649         return "((this.getHours() % 12) ? this.getHours() % 12 : 12) + ";
5650     case "G":
5651         return "this.getHours() + ";
5652     case "h":
5653         return "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0') + ";
5654     case "H":
5655         return "String.leftPad(this.getHours(), 2, '0') + ";
5656     case "i":
5657         return "String.leftPad(this.getMinutes(), 2, '0') + ";
5658     case "s":
5659         return "String.leftPad(this.getSeconds(), 2, '0') + ";
5660     case "u":
5661         return "String.leftPad(this.getMilliseconds(), 3, '0') + ";
5662     case "O":
5663         return "this.getGMTOffset() + ";
5664     case "P":
5665         return "this.getGMTOffset(true) + ";
5666     case "T":
5667         return "this.getTimezone() + ";
5668     case "Z":
5669         return "(this.getTimezoneOffset() * -60) + ";
5670     case "c":
5671         for (var df = Date.getFormatCode, c = "Y-m-dTH:i:sP", code = "", i = 0, l = c.length; i < l; ++i) {
5672           var e = c.charAt(i);
5673           code += e == "T" ? "'T' + " : df(e);         }
5674         return code;
5675     case "U":
5676         return "Math.round(this.getTime() / 1000) + ";
5677     default:
5678         return "'" + String.escape(character) + "' + ";
5679     }
5680 };
5681
5682
5683 Date.parseDate = function(input, format) {
5684     if (Date.parseFunctions[format] == null) {
5685         Date.createParser(format);
5686     }
5687     var func = Date.parseFunctions[format];
5688     return Date[func](input);
5689 };
5690
5691 Date.createParser = function(format) {
5692     var funcName = "parse" + Date.parseFunctions.count++;
5693     var regexNum = Date.parseRegexes.length;
5694     var currentGroup = 1;
5695     Date.parseFunctions[format] = funcName;
5696
5697     var code = "Date." + funcName + " = function(input){\n"
5698         + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, ms = -1, o, z, u, v;\n"
5699         + "input = String(input);var d = new Date();\n"
5700         + "y = d.getFullYear();\n"
5701         + "m = d.getMonth();\n"
5702         + "d = d.getDate();\n"
5703         + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
5704         + "if (results && results.length > 0) {";
5705     var regex = "";
5706
5707     var special = false;
5708     var ch = '';
5709     for (var i = 0; i < format.length; ++i) {
5710         ch = format.charAt(i);
5711         if (!special && ch == "\\") {
5712             special = true;
5713         }
5714         else if (special) {
5715             special = false;
5716             regex += String.escape(ch);
5717         }
5718         else {
5719             var obj = Date.formatCodeToRegex(ch, currentGroup);
5720             currentGroup += obj.g;
5721             regex += obj.s;
5722             if (obj.g && obj.c) {
5723                 code += obj.c;
5724             }
5725         }
5726     }
5727
5728     code += "if (u)\n"
5729         + "{v = new Date(u * 1000);}"         + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0 && ms >= 0)\n"
5730         + "{v = new Date(y, m, d, h, i, s, ms);}\n"
5731         + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
5732         + "{v = new Date(y, m, d, h, i, s);}\n"
5733         + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
5734         + "{v = new Date(y, m, d, h, i);}\n"
5735         + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0)\n"
5736         + "{v = new Date(y, m, d, h);}\n"
5737         + "else if (y >= 0 && m >= 0 && d > 0)\n"
5738         + "{v = new Date(y, m, d);}\n"
5739         + "else if (y >= 0 && m >= 0)\n"
5740         + "{v = new Date(y, m);}\n"
5741         + "else if (y >= 0)\n"
5742         + "{v = new Date(y);}\n"
5743         + "}return (v && (z || o))?\n"         + "    (z ? v.add(Date.SECOND, (v.getTimezoneOffset() * 60) + (z*1)) :\n"         + "        v.add(Date.HOUR, (v.getGMTOffset() / 100) + (o / -100))) : v\n"         + ";}";
5744
5745     Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$", "i");
5746     eval(code);
5747 };
5748
5749 Date.formatCodeToRegex = function(character, currentGroup) {
5750     
5751     switch (character) {
5752     case "d":
5753         return {g:1,
5754             c:"d = parseInt(results[" + currentGroup + "], 10);\n",
5755             s:"(\\d{2})"};     case "D":
5756         for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i);         return {g:0,
5757             c:null,
5758             s:"(?:" + a.join("|") +")"};
5759     case "j":
5760         return {g:1,
5761             c:"d = parseInt(results[" + currentGroup + "], 10);\n",
5762             s:"(\\d{1,2})"};     case "l":
5763         return {g:0,
5764             c:null,
5765             s:"(?:" + Date.dayNames.join("|") + ")"};
5766     case "N":
5767         return {g:0,
5768             c:null,
5769             s:"[1-7]"};     case "S":
5770         return {g:0,
5771             c:null,
5772             s:"(?:st|nd|rd|th)"};
5773     case "w":
5774         return {g:0,
5775             c:null,
5776             s:"[0-6]"};     case "z":
5777         return {g:0,
5778             c:null,
5779             s:"(?:\\d{1,3}"};     case "W":
5780         return {g:0,
5781             c:null,
5782             s:"(?:\\d{2})"};     case "F":
5783         return {g:1,
5784             c:"m = parseInt(Date.getMonthNumber(results[" + currentGroup + "]), 10);\n",             s:"(" + Date.monthNames.join("|") + ")"};
5785     case "m":
5786         return {g:1,
5787             c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
5788             s:"(\\d{2})"};     case "M":
5789         for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i);         return {g:1,
5790             c:"m = parseInt(Date.getMonthNumber(results[" + currentGroup + "]), 10);\n",             s:"(" + a.join("|") + ")"};
5791     case "n":
5792         return {g:1,
5793             c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
5794             s:"(\\d{1,2})"};     case "t":
5795         return {g:0,
5796             c:null,
5797             s:"(?:\\d{2})"};     case "L":
5798         return {g:0,
5799             c:null,
5800             s:"(?:1|0)"};
5801     case "o":
5802     case "Y":
5803         return {g:1,
5804             c:"y = parseInt(results[" + currentGroup + "], 10);\n",
5805             s:"(\\d{4})"};     case "y":
5806         return {g:1,
5807             c:"var ty = parseInt(results[" + currentGroup + "], 10);\n"
5808                 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
5809             s:"(\\d{1,2})"};     case "a":
5810         return {g:1,
5811             c:"if (results[" + currentGroup + "] == 'am') {\n"
5812                 + "if (h == 12) { h = 0; }\n"
5813                 + "} else { if (h < 12) { h += 12; }}",
5814             s:"(am|pm)"};
5815     case "A":
5816         return {g:1,
5817             c:"if (results[" + currentGroup + "] == 'AM') {\n"
5818                 + "if (h == 12) { h = 0; }\n"
5819                 + "} else { if (h < 12) { h += 12; }}",
5820             s:"(AM|PM)"};
5821     case "g":
5822     case "G":
5823         return {g:1,
5824             c:"h = parseInt(results[" + currentGroup + "], 10);\n",
5825             s:"(\\d{1,2})"};     case "h":
5826     case "H":
5827         return {g:1,
5828             c:"h = parseInt(results[" + currentGroup + "], 10);\n",
5829             s:"(\\d{2})"};     case "i":
5830         return {g:1,
5831             c:"i = parseInt(results[" + currentGroup + "], 10);\n",
5832             s:"(\\d{2})"};     case "s":
5833         return {g:1,
5834             c:"s = parseInt(results[" + currentGroup + "], 10);\n",
5835             s:"(\\d{2})"};     case "u":
5836         return {g:1,
5837             c:"ms = parseInt(results[" + currentGroup + "], 10);\n",
5838             s:"(\\d{3})"};     case "O":
5839         return {g:1,
5840             c:[
5841                 "o = results[", currentGroup, "];\n",
5842                 "var sn = o.substring(0,1);\n",                 "var hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60);\n",                 "var mn = o.substring(3,5) % 60;\n",                 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))?\n",                 "    (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
5843             ].join(""),
5844             s: "([+\-]\\d{4})"};     case "P":
5845         return {g:1,
5846             c:[
5847                 "o = results[", currentGroup, "];\n",
5848                 "var sn = o.substring(0,1);\n",                 "var hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60);\n",                 "var mn = o.substring(4,6) % 60;\n",                 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))?\n",                 "    (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
5849             ].join(""),
5850             s: "([+\-]\\d{2}:\\d{2})"};     case "T":
5851         return {g:0,
5852             c:null,
5853             s:"[A-Z]{1,4}"};     case "Z":
5854         return {g:1,
5855             c:"z = results[" + currentGroup + "] * 1;\n"                   + "z = (-43200 <= z && z <= 50400)? z : null;\n",
5856             s:"([+\-]?\\d{1,5})"};     case "c":
5857         var df = Date.formatCodeToRegex, calc = [];
5858         var arr = [df("Y", 1), df("m", 2), df("d", 3), df("h", 4), df("i", 5), df("s", 6), df("P", 7)];
5859         for (var i = 0, l = arr.length; i < l; ++i) {
5860           calc.push(arr[i].c);
5861         }
5862         return {g:1,
5863             c:calc.join(""),
5864             s:arr[0].s + "-" + arr[1].s + "-" + arr[2].s + "T" + arr[3].s + ":" + arr[4].s + ":" + arr[5].s + arr[6].s};
5865     case "U":
5866         return {g:1,
5867             c:"u = parseInt(results[" + currentGroup + "], 10);\n",
5868             s:"(-?\\d+)"};     default:
5869         return {g:0,
5870             c:null,
5871             s:Ext.escapeRe(character)};
5872     }
5873 };
5874
5875
5876 Date.prototype.getTimezone = function() {
5877                                                     return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
5878 };
5879
5880
5881 Date.prototype.getGMTOffset = function(colon) {
5882     return (this.getTimezoneOffset() > 0 ? "-" : "+")
5883         + String.leftPad(Math.abs(Math.floor(this.getTimezoneOffset() / 60)), 2, "0")
5884         + (colon ? ":" : "")
5885         + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
5886 };
5887
5888
5889 Date.prototype.getDayOfYear = function() {
5890     var num = 0;
5891     Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
5892     for (var i = 0; i < this.getMonth(); ++i) {
5893         num += Date.daysInMonth[i];
5894     }
5895     return num + this.getDate() - 1;
5896 };
5897
5898
5899 Date.prototype.getWeekOfYear = function() {
5900         var ms1d = 864e5;     var ms7d = 7 * ms1d;     var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d;     var AWN = Math.floor(DC3 / 7);     var Wyr = new Date(AWN * ms7d).getUTCFullYear();
5901     return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
5902 };
5903
5904
5905 Date.prototype.isLeapYear = function() {
5906     var year = this.getFullYear();
5907     return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
5908 };
5909
5910
5911 Date.prototype.getFirstDayOfMonth = function() {
5912     var day = (this.getDay() - (this.getDate() - 1)) % 7;
5913     return (day < 0) ? (day + 7) : day;
5914 };
5915
5916
5917 Date.prototype.getLastDayOfMonth = function() {
5918     var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
5919     return (day < 0) ? (day + 7) : day;
5920 };
5921
5922
5923
5924 Date.prototype.getFirstDateOfMonth = function() {
5925     return new Date(this.getFullYear(), this.getMonth(), 1);
5926 };
5927
5928
5929 Date.prototype.getLastDateOfMonth = function() {
5930     return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
5931 };
5932
5933 Date.prototype.getDaysInMonth = function() {
5934     Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
5935     return Date.daysInMonth[this.getMonth()];
5936 };
5937
5938
5939 Date.prototype.getSuffix = function() {
5940     switch (this.getDate()) {
5941         case 1:
5942         case 21:
5943         case 31:
5944             return "st";
5945         case 2:
5946         case 22:
5947             return "nd";
5948         case 3:
5949         case 23:
5950             return "rd";
5951         default:
5952             return "th";
5953     }
5954 };
5955
5956 Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
5957
5958
5959 Date.monthNames =
5960    ["January",
5961     "February",
5962     "March",
5963     "April",
5964     "May",
5965     "June",
5966     "July",
5967     "August",
5968     "September",
5969     "October",
5970     "November",
5971     "December"];
5972
5973
5974 Date.getShortMonthName = function(month) {
5975     return Date.monthNames[month].substring(0, 3);
5976 }
5977
5978
5979 Date.dayNames =
5980    ["Sunday",
5981     "Monday",
5982     "Tuesday",
5983     "Wednesday",
5984     "Thursday",
5985     "Friday",
5986     "Saturday"];
5987
5988
5989 Date.getShortDayName = function(day) {
5990     return Date.dayNames[day].substring(0, 3);
5991 }
5992
5993 Date.y2kYear = 50;
5994
5995
5996 Date.monthNumbers = {
5997     Jan:0,
5998     Feb:1,
5999     Mar:2,
6000     Apr:3,
6001     May:4,
6002     Jun:5,
6003     Jul:6,
6004     Aug:7,
6005     Sep:8,
6006     Oct:9,
6007     Nov:10,
6008     Dec:11};
6009
6010
6011 Date.getMonthNumber = function(name) {
6012         return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
6013 }
6014
6015
6016 Date.prototype.clone = function() {
6017   return new Date(this.getTime());
6018 };
6019
6020
6021 Date.prototype.clearTime = function(clone){
6022     if(clone){
6023         return this.clone().clearTime();
6024     }
6025     this.setHours(0);
6026     this.setMinutes(0);
6027     this.setSeconds(0);
6028     this.setMilliseconds(0);
6029     return this;
6030 };
6031
6032 if(Ext.isSafari){
6033     Date.brokenSetMonth = Date.prototype.setMonth;
6034   Date.prototype.setMonth = function(num){
6035     if(num <= -1){
6036       var n = Math.ceil(-num);
6037       var back_year = Math.ceil(n/12);
6038       var month = (n % 12) ? 12 - n % 12 : 0 ;
6039       this.setFullYear(this.getFullYear() - back_year);
6040       return Date.brokenSetMonth.call(this, month);
6041     } else {
6042       return Date.brokenSetMonth.apply(this, arguments);
6043     }
6044   };
6045 }
6046
6047
6048 Date.MILLI = "ms";
6049
6050 Date.SECOND = "s";
6051
6052 Date.MINUTE = "mi";
6053
6054 Date.HOUR = "h";
6055
6056 Date.DAY = "d";
6057
6058 Date.MONTH = "mo";
6059
6060 Date.YEAR = "y";
6061
6062
6063 Date.prototype.add = function(interval, value){
6064   var d = this.clone();
6065   if (!interval || value === 0) return d;
6066   switch(interval.toLowerCase()){
6067     case Date.MILLI:
6068       d.setMilliseconds(this.getMilliseconds() + value);
6069       break;
6070     case Date.SECOND:
6071       d.setSeconds(this.getSeconds() + value);
6072       break;
6073     case Date.MINUTE:
6074       d.setMinutes(this.getMinutes() + value);
6075       break;
6076     case Date.HOUR:
6077       d.setHours(this.getHours() + value);
6078       break;
6079     case Date.DAY:
6080       d.setDate(this.getDate() + value);
6081       break;
6082     case Date.MONTH:
6083       var day = this.getDate();
6084       if(day > 28){
6085           day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
6086       }
6087       d.setDate(day);
6088       d.setMonth(this.getMonth() + value);
6089       break;
6090     case Date.YEAR:
6091       d.setFullYear(this.getFullYear() + value);
6092       break;
6093   }
6094   return d;
6095 };
6096
6097
6098 Date.prototype.between = function(start, end){
6099     var t = this.getTime();
6100     return start.getTime() <= t && t <= end.getTime();
6101 }
6102
6103 Ext.util.DelayedTask = function(fn, scope, args){
6104     var id = null, d, t;
6105
6106     var call = function(){
6107         var now = new Date().getTime();
6108         if(now - t >= d){
6109             clearInterval(id);
6110             id = null;
6111             fn.apply(scope, args || []);
6112         }
6113     };
6114     
6115     this.delay = function(delay, newFn, newScope, newArgs){
6116         if(id && delay != d){
6117             this.cancel();
6118         }
6119         d = delay;
6120         t = new Date().getTime();
6121         fn = newFn || fn;
6122         scope = newScope || scope;
6123         args = newArgs || args;
6124         if(!id){
6125             id = setInterval(call, d);
6126         }
6127     };
6128
6129     
6130     this.cancel = function(){
6131         if(id){
6132             clearInterval(id);
6133             id = null;
6134         }
6135     };
6136 };
6137
6138 Ext.util.TaskRunner = function(interval){
6139     interval = interval || 10;
6140     var tasks = [], removeQueue = [];
6141     var id = 0;
6142     var running = false;
6143
6144         var stopThread = function(){
6145         running = false;
6146         clearInterval(id);
6147         id = 0;
6148     };
6149
6150         var startThread = function(){
6151         if(!running){
6152             running = true;
6153             id = setInterval(runTasks, interval);
6154         }
6155     };
6156
6157         var removeTask = function(t){
6158         removeQueue.push(t);
6159         if(t.onStop){
6160             t.onStop.apply(t.scope || t);
6161         }
6162     };
6163
6164         var runTasks = function(){
6165         if(removeQueue.length > 0){
6166             for(var i = 0, len = removeQueue.length; i < len; i++){
6167                 tasks.remove(removeQueue[i]);
6168             }
6169             removeQueue = [];
6170             if(tasks.length < 1){
6171                 stopThread();
6172                 return;
6173             }
6174         }
6175         var now = new Date().getTime();
6176         for(var i = 0, len = tasks.length; i < len; ++i){
6177             var t = tasks[i];
6178             var itime = now - t.taskRunTime;
6179             if(t.interval <= itime){
6180                 var rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
6181                 t.taskRunTime = now;
6182                 if(rt === false || t.taskRunCount === t.repeat){
6183                     removeTask(t);
6184                     return;
6185                 }
6186             }
6187             if(t.duration && t.duration <= (now - t.taskStartTime)){
6188                 removeTask(t);
6189             }
6190         }
6191     };
6192
6193     
6194     this.start = function(task){
6195         tasks.push(task);
6196         task.taskStartTime = new Date().getTime();
6197         task.taskRunTime = 0;
6198         task.taskRunCount = 0;
6199         startThread();
6200         return task;
6201     };
6202
6203     
6204     this.stop = function(task){
6205         removeTask(task);
6206         return task;
6207     };
6208
6209     
6210     this.stopAll = function(){
6211         stopThread();
6212         for(var i = 0, len = tasks.length; i < len; i++){
6213             if(tasks[i].onStop){
6214                 tasks[i].onStop();
6215             }
6216         }
6217         tasks = [];
6218         removeQueue = [];
6219     };
6220 };
6221
6222
6223 Ext.TaskMgr = new Ext.util.TaskRunner();
6224 \r
6225 Ext.util.MixedCollection = function(allowFunctions, keyFn){\r
6226     this.items = [];\r
6227     this.map = {};\r
6228     this.keys = [];\r
6229     this.length = 0;\r
6230     this.addEvents(\r
6231         \r
6232         "clear",\r
6233         \r
6234         "add",\r
6235         \r
6236         "replace",\r
6237         \r
6238         "remove",\r
6239         "sort"\r
6240     );\r
6241     this.allowFunctions = allowFunctions === true;\r
6242     if(keyFn){\r
6243         this.getKey = keyFn;\r
6244     }\r
6245     Ext.util.MixedCollection.superclass.constructor.call(this);\r
6246 };\r
6247 \r
6248 Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {\r
6249     allowFunctions : false,\r
6250 \r
6251 \r
6252     add : function(key, o){\r
6253         if(arguments.length == 1){\r
6254             o = arguments[0];\r
6255             key = this.getKey(o);\r
6256         }\r
6257         if(typeof key == "undefined" || key === null){\r
6258             this.length++;\r
6259             this.items.push(o);\r
6260             this.keys.push(null);\r
6261         }else{\r
6262             var old = this.map[key];\r
6263             if(old){\r
6264                 return this.replace(key, o);\r
6265             }\r
6266             this.length++;\r
6267             this.items.push(o);\r
6268             this.map[key] = o;\r
6269             this.keys.push(key);\r
6270         }\r
6271         this.fireEvent("add", this.length-1, o, key);\r
6272         return o;\r
6273     },\r
6274 \r
6275 \r
6276     getKey : function(o){\r
6277          return o.id;\r
6278     },\r
6279 \r
6280 \r
6281     replace : function(key, o){\r
6282         if(arguments.length == 1){\r
6283             o = arguments[0];\r
6284             key = this.getKey(o);\r
6285         }\r
6286         var old = this.item(key);\r
6287         if(typeof key == "undefined" || key === null || typeof old == "undefined"){\r
6288              return this.add(key, o);\r
6289         }\r
6290         var index = this.indexOfKey(key);\r
6291         this.items[index] = o;\r
6292         this.map[key] = o;\r
6293         this.fireEvent("replace", key, old, o);\r
6294         return o;\r
6295     },\r
6296 \r
6297 \r
6298     addAll : function(objs){\r
6299         if(arguments.length > 1 || Ext.isArray(objs)){\r
6300             var args = arguments.length > 1 ? arguments : objs;\r
6301             for(var i = 0, len = args.length; i < len; i++){\r
6302                 this.add(args[i]);\r
6303             }\r
6304         }else{\r
6305             for(var key in objs){\r
6306                 if(this.allowFunctions || typeof objs[key] != "function"){\r
6307                     this.add(key, objs[key]);\r
6308                 }\r
6309             }\r
6310         }\r
6311     },\r
6312 \r
6313 \r
6314     each : function(fn, scope){\r
6315         var items = [].concat(this.items); 
6316         for(var i = 0, len = items.length; i < len; i++){\r
6317             if(fn.call(scope || items[i], items[i], i, len) === false){\r
6318                 break;\r
6319             }\r
6320         }\r
6321     },\r
6322 \r
6323 \r
6324     eachKey : function(fn, scope){\r
6325         for(var i = 0, len = this.keys.length; i < len; i++){\r
6326             fn.call(scope || window, this.keys[i], this.items[i], i, len);\r
6327         }\r
6328     },\r
6329 \r
6330     \r
6331     find : function(fn, scope){\r
6332         for(var i = 0, len = this.items.length; i < len; i++){\r
6333             if(fn.call(scope || window, this.items[i], this.keys[i])){\r
6334                 return this.items[i];\r
6335             }\r
6336         }\r
6337         return null;\r
6338     },\r
6339 \r
6340 \r
6341     insert : function(index, key, o){\r
6342         if(arguments.length == 2){\r
6343             o = arguments[1];\r
6344             key = this.getKey(o);\r
6345         }\r
6346         if(index >= this.length){\r
6347             return this.add(key, o);\r
6348         }\r
6349         this.length++;\r
6350         this.items.splice(index, 0, o);\r
6351         if(typeof key != "undefined" && key != null){\r
6352             this.map[key] = o;\r
6353         }\r
6354         this.keys.splice(index, 0, key);\r
6355         this.fireEvent("add", index, o, key);\r
6356         return o;\r
6357     },\r
6358 \r
6359 \r
6360     remove : function(o){\r
6361         return this.removeAt(this.indexOf(o));\r
6362     },\r
6363 \r
6364 \r
6365     removeAt : function(index){\r
6366         if(index < this.length && index >= 0){\r
6367             this.length--;\r
6368             var o = this.items[index];\r
6369             this.items.splice(index, 1);\r
6370             var key = this.keys[index];\r
6371             if(typeof key != "undefined"){\r
6372                 delete this.map[key];\r
6373             }\r
6374             this.keys.splice(index, 1);\r
6375             this.fireEvent("remove", o, key);\r
6376             return o;\r
6377         }\r
6378         return false;\r
6379     },\r
6380 \r
6381 \r
6382     removeKey : function(key){\r
6383         return this.removeAt(this.indexOfKey(key));\r
6384     },\r
6385 \r
6386 \r
6387     getCount : function(){\r
6388         return this.length;\r
6389     },\r
6390 \r
6391 \r
6392     indexOf : function(o){\r
6393         return this.items.indexOf(o);\r
6394     },\r
6395 \r
6396 \r
6397     indexOfKey : function(key){\r
6398         return this.keys.indexOf(key);\r
6399     },\r
6400 \r
6401 \r
6402     item : function(key){\r
6403         var item = typeof this.map[key] != "undefined" ? this.map[key] : this.items[key];\r
6404         return typeof item != 'function' || this.allowFunctions ? item : null; 
6405     },\r
6406 \r
6407 \r
6408     itemAt : function(index){\r
6409         return this.items[index];\r
6410     },\r
6411 \r
6412 \r
6413     key : function(key){\r
6414         return this.map[key];\r
6415     },\r
6416 \r
6417 \r
6418     contains : function(o){\r
6419         return this.indexOf(o) != -1;\r
6420     },\r
6421 \r
6422 \r
6423     containsKey : function(key){\r
6424         return typeof this.map[key] != "undefined";\r
6425     },\r
6426 \r
6427 \r
6428     clear : function(){\r
6429         this.length = 0;\r
6430         this.items = [];\r
6431         this.keys = [];\r
6432         this.map = {};\r
6433         this.fireEvent("clear");\r
6434     },\r
6435 \r
6436 \r
6437     first : function(){\r
6438         return this.items[0];\r
6439     },\r
6440 \r
6441 \r
6442     last : function(){\r
6443         return this.items[this.length-1];\r
6444     },\r
6445 \r
6446     
6447     _sort : function(property, dir, fn){\r
6448         var dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1;\r
6449         fn = fn || function(a, b){\r
6450             return a-b;\r
6451         };\r
6452         var c = [], k = this.keys, items = this.items;\r
6453         for(var i = 0, len = items.length; i < len; i++){\r
6454             c[c.length] = {key: k[i], value: items[i], index: i};\r
6455         }\r
6456         c.sort(function(a, b){\r
6457             var v = fn(a[property], b[property]) * dsc;\r
6458             if(v == 0){\r
6459                 v = (a.index < b.index ? -1 : 1);\r
6460             }\r
6461             return v;\r
6462         });\r
6463         for(var i = 0, len = c.length; i < len; i++){\r
6464             items[i] = c[i].value;\r
6465             k[i] = c[i].key;\r
6466         }\r
6467         this.fireEvent("sort", this);\r
6468     },\r
6469 \r
6470     \r
6471     sort : function(dir, fn){\r
6472         this._sort("value", dir, fn);\r
6473     },\r
6474 \r
6475     \r
6476     keySort : function(dir, fn){\r
6477         this._sort("key", dir, fn || function(a, b){\r
6478             return String(a).toUpperCase()-String(b).toUpperCase();\r
6479         });\r
6480     },\r
6481 \r
6482     \r
6483     getRange : function(start, end){\r
6484         var items = this.items;\r
6485         if(items.length < 1){\r
6486             return [];\r
6487         }\r
6488         start = start || 0;\r
6489         end = Math.min(typeof end == "undefined" ? this.length-1 : end, this.length-1);\r
6490         var r = [];\r
6491         if(start <= end){\r
6492             for(var i = start; i <= end; i++) {\r
6493                     r[r.length] = items[i];\r
6494             }\r
6495         }else{\r
6496             for(var i = start; i >= end; i--) {\r
6497                     r[r.length] = items[i];\r
6498             }\r
6499         }\r
6500         return r;\r
6501     },\r
6502 \r
6503     \r
6504     filter : function(property, value, anyMatch, caseSensitive){\r
6505         if(Ext.isEmpty(value, false)){\r
6506             return this.clone();\r
6507         }\r
6508         value = this.createValueMatcher(value, anyMatch, caseSensitive);\r
6509         return this.filterBy(function(o){\r
6510             return o && value.test(o[property]);\r
6511         });\r
6512         },\r
6513 \r
6514     \r
6515     filterBy : function(fn, scope){\r
6516         var r = new Ext.util.MixedCollection();\r
6517         r.getKey = this.getKey;\r
6518         var k = this.keys, it = this.items;\r
6519         for(var i = 0, len = it.length; i < len; i++){\r
6520             if(fn.call(scope||this, it[i], k[i])){\r
6521                                 r.add(k[i], it[i]);\r
6522                         }\r
6523         }\r
6524         return r;\r
6525     },\r
6526 \r
6527     \r
6528     findIndex : function(property, value, start, anyMatch, caseSensitive){\r
6529         if(Ext.isEmpty(value, false)){\r
6530             return -1;\r
6531         }\r
6532         value = this.createValueMatcher(value, anyMatch, caseSensitive);\r
6533         return this.findIndexBy(function(o){\r
6534             return o && value.test(o[property]);\r
6535         }, null, start);\r
6536         },\r
6537 \r
6538     \r
6539     findIndexBy : function(fn, scope, start){\r
6540         var k = this.keys, it = this.items;\r
6541         for(var i = (start||0), len = it.length; i < len; i++){\r
6542             if(fn.call(scope||this, it[i], k[i])){\r
6543                                 return i;\r
6544             }\r
6545         }\r
6546         if(typeof start == 'number' && start > 0){\r
6547             for(var i = 0; i < start; i++){\r
6548                 if(fn.call(scope||this, it[i], k[i])){\r
6549                     return i;\r
6550                 }\r
6551             }\r
6552         }\r
6553         return -1;\r
6554     },\r
6555 \r
6556     
6557     createValueMatcher : function(value, anyMatch, caseSensitive){\r
6558         if(!value.exec){ 
6559             value = String(value);\r
6560             value = new RegExp((anyMatch === true ? '' : '^') + Ext.escapeRe(value), caseSensitive ? '' : 'i');\r
6561         }\r
6562         return value;\r
6563     },\r
6564 \r
6565     \r
6566     clone : function(){\r
6567         var r = new Ext.util.MixedCollection();\r
6568         var k = this.keys, it = this.items;\r
6569         for(var i = 0, len = it.length; i < len; i++){\r
6570             r.add(k[i], it[i]);\r
6571         }\r
6572         r.getKey = this.getKey;\r
6573         return r;\r
6574     }\r
6575 });\r
6576 \r
6577 Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
6578 \r
6579 Ext.util.JSON = new (function(){\r
6580     var useHasOwn = {}.hasOwnProperty ? true : false;\r
6581     \r
6582     
6583     
6584     \r
6585     var pad = function(n) {\r
6586         return n < 10 ? "0" + n : n;\r
6587     };\r
6588     \r
6589     var m = {\r
6590         "\b": '\\b',\r
6591         "\t": '\\t',\r
6592         "\n": '\\n',\r
6593         "\f": '\\f',\r
6594         "\r": '\\r',\r
6595         '"' : '\\"',\r
6596         "\\": '\\\\'\r
6597     };\r
6598 \r
6599     var encodeString = function(s){\r
6600         if (/["\\\x00-\x1f]/.test(s)) {\r
6601             return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {\r
6602                 var c = m[b];\r
6603                 if(c){\r
6604                     return c;\r
6605                 }\r
6606                 c = b.charCodeAt();\r
6607                 return "\\u00" +\r
6608                     Math.floor(c / 16).toString(16) +\r
6609                     (c % 16).toString(16);\r
6610             }) + '"';\r
6611         }\r
6612         return '"' + s + '"';\r
6613     };\r
6614     \r
6615     var encodeArray = function(o){\r
6616         var a = ["["], b, i, l = o.length, v;\r
6617             for (i = 0; i < l; i += 1) {\r
6618                 v = o[i];\r
6619                 switch (typeof v) {\r
6620                     case "undefined":\r
6621                     case "function":\r
6622                     case "unknown":\r
6623                         break;\r
6624                     default:\r
6625                         if (b) {\r
6626                             a.push(',');\r
6627                         }\r
6628                         a.push(v === null ? "null" : Ext.util.JSON.encode(v));\r
6629                         b = true;\r
6630                 }\r
6631             }\r
6632             a.push("]");\r
6633             return a.join("");\r
6634     };\r
6635     \r
6636     var encodeDate = function(o){\r
6637         return '"' + o.getFullYear() + "-" +\r
6638                 pad(o.getMonth() + 1) + "-" +\r
6639                 pad(o.getDate()) + "T" +\r
6640                 pad(o.getHours()) + ":" +\r
6641                 pad(o.getMinutes()) + ":" +\r
6642                 pad(o.getSeconds()) + '"';\r
6643     };\r
6644     \r
6645     \r
6646     this.encode = function(o){\r
6647         if(typeof o == "undefined" || o === null){\r
6648             return "null";\r
6649         }else if(Ext.isArray(o)){\r
6650             return encodeArray(o);\r
6651         }else if(Ext.isDate(o)){\r
6652             return encodeDate(o);\r
6653         }else if(typeof o == "string"){\r
6654             return encodeString(o);\r
6655         }else if(typeof o == "number"){\r
6656             return isFinite(o) ? String(o) : "null";\r
6657         }else if(typeof o == "boolean"){\r
6658             return String(o);\r
6659         }else {\r
6660             var a = ["{"], b, i, v;\r
6661             for (i in o) {\r
6662                 if(!useHasOwn || o.hasOwnProperty(i)) {\r
6663                     v = o[i];\r
6664                     switch (typeof v) {\r
6665                     case "undefined":\r
6666                     case "function":\r
6667                     case "unknown":\r
6668                         break;\r
6669                     default:\r
6670                         if(b){\r
6671                             a.push(',');\r
6672                         }\r
6673                         a.push(this.encode(i), ":",\r
6674                                 v === null ? "null" : this.encode(v));\r
6675                         b = true;\r
6676                     }\r
6677                 }\r
6678             }\r
6679             a.push("}");\r
6680             return a.join("");\r
6681         }\r
6682     };\r
6683     \r
6684     \r
6685     this.decode = function(json){\r
6686         return eval("(" + json + ')');\r
6687     };\r
6688 })();\r
6689 \r
6690 Ext.encode = Ext.util.JSON.encode;\r
6691 \r
6692 Ext.decode = Ext.util.JSON.decode;\r
6693
6694 \r
6695 Ext.util.Format = function(){\r
6696     var trimRe = /^\s+|\s+$/g;\r
6697     return {\r
6698         \r
6699         ellipsis : function(value, len){\r
6700             if(value && value.length > len){\r
6701                 return value.substr(0, len-3)+"...";\r
6702             }\r
6703             return value;\r
6704         },\r
6705 \r
6706         \r
6707         undef : function(value){\r
6708             return value !== undefined ? value : "";\r
6709         },\r
6710 \r
6711         \r
6712         defaultValue : function(value, defaultValue){\r
6713             return value !== undefined && value !== '' ? value : defaultValue;\r
6714         },\r
6715 \r
6716         \r
6717         htmlEncode : function(value){\r
6718             return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");\r
6719         },\r
6720 \r
6721         \r
6722         htmlDecode : function(value){\r
6723             return !value ? value : String(value).replace(/&amp;/g, "&").replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"');\r
6724         },\r
6725 \r
6726         \r
6727         trim : function(value){\r
6728             return String(value).replace(trimRe, "");\r
6729         },\r
6730 \r
6731         \r
6732         substr : function(value, start, length){\r
6733             return String(value).substr(start, length);\r
6734         },\r
6735 \r
6736         \r
6737         lowercase : function(value){\r
6738             return String(value).toLowerCase();\r
6739         },\r
6740 \r
6741         \r
6742         uppercase : function(value){\r
6743             return String(value).toUpperCase();\r
6744         },\r
6745 \r
6746         \r
6747         capitalize : function(value){\r
6748             return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();\r
6749         },\r
6750 \r
6751         
6752         call : function(value, fn){\r
6753             if(arguments.length > 2){\r
6754                 var args = Array.prototype.slice.call(arguments, 2);\r
6755                 args.unshift(value);\r
6756                 return eval(fn).apply(window, args);\r
6757             }else{\r
6758                 return eval(fn).call(window, value);\r
6759             }\r
6760         },\r
6761 \r
6762         \r
6763         usMoney : function(v){\r
6764             v = (Math.round((v-0)*100))/100;\r
6765             v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);\r
6766             v = String(v);\r
6767             var ps = v.split('.');\r
6768             var whole = ps[0];\r
6769             var sub = ps[1] ? '.'+ ps[1] : '.00';\r
6770             var r = /(\d+)(\d{3})/;\r
6771             while (r.test(whole)) {\r
6772                 whole = whole.replace(r, '$1' + ',' + '$2');\r
6773             }\r
6774             v = whole + sub;\r
6775             if(v.charAt(0) == '-'){\r
6776                 return '-$' + v.substr(1);\r
6777             }\r
6778             return "$" +  v;\r
6779         },\r
6780 \r
6781         \r
6782         date : function(v, format){\r
6783             if(!v){\r
6784                 return "";\r
6785             }\r
6786             if(!Ext.isDate(v)){\r
6787                 v = new Date(Date.parse(v));\r
6788             }\r
6789             return v.dateFormat(format || "m/d/Y");\r
6790         },\r
6791 \r
6792         \r
6793         dateRenderer : function(format){\r
6794             return function(v){\r
6795                 return Ext.util.Format.date(v, format);\r
6796             };\r
6797         },\r
6798 \r
6799         
6800         stripTagsRE : /<\/?[^>]+>/gi,\r
6801         \r
6802         \r
6803         stripTags : function(v){\r
6804             return !v ? v : String(v).replace(this.stripTagsRE, "");\r
6805         },\r
6806 \r
6807         stripScriptsRe : /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,\r
6808 \r
6809         \r
6810         stripScripts : function(v){\r
6811             return !v ? v : String(v).replace(this.stripScriptsRe, "");\r
6812         },\r
6813 \r
6814         \r
6815         fileSize : function(size){\r
6816             if(size < 1024) {\r
6817                 return size + " bytes";\r
6818             } else if(size < 1048576) {\r
6819                 return (Math.round(((size*10) / 1024))/10) + " KB";\r
6820             } else {\r
6821                 return (Math.round(((size*10) / 1048576))/10) + " MB";\r
6822             }\r
6823         },\r
6824 \r
6825         math : function(){\r
6826             var fns = {};\r
6827             return function(v, a){\r
6828                 if(!fns[a]){\r
6829                     fns[a] = new Function('v', 'return v ' + a + ';');\r
6830                 }\r
6831                 return fns[a](v);\r
6832             }\r
6833         }()\r
6834     };\r
6835 }();
6836 \r
6837 Ext.XTemplate = function(){\r
6838     Ext.XTemplate.superclass.constructor.apply(this, arguments);\r
6839     var s = this.html;\r
6840 \r
6841     s = ['<tpl>', s, '</tpl>'].join('');\r
6842 \r
6843     var re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/;\r
6844 \r
6845     var nameRe = /^<tpl\b[^>]*?for="(.*?)"/;\r
6846     var ifRe = /^<tpl\b[^>]*?if="(.*?)"/;\r
6847     var execRe = /^<tpl\b[^>]*?exec="(.*?)"/;\r
6848     var m, id = 0;\r
6849     var tpls = [];\r
6850 \r
6851     while(m = s.match(re)){\r
6852        var m2 = m[0].match(nameRe);\r
6853        var m3 = m[0].match(ifRe);\r
6854        var m4 = m[0].match(execRe);\r
6855        var exp = null, fn = null, exec = null;\r
6856        var name = m2 && m2[1] ? m2[1] : '';\r
6857        if(m3){\r
6858            exp = m3 && m3[1] ? m3[1] : null;\r
6859            if(exp){\r
6860                fn = new Function('values', 'parent', 'xindex', 'xcount', 'with(values){ return '+(Ext.util.Format.htmlDecode(exp))+'; }');\r
6861            }\r
6862        }\r
6863        if(m4){\r
6864            exp = m4 && m4[1] ? m4[1] : null;\r
6865            if(exp){\r
6866                exec = new Function('values', 'parent', 'xindex', 'xcount', 'with(values){ '+(Ext.util.Format.htmlDecode(exp))+'; }');\r
6867            }\r
6868        }\r
6869        if(name){\r
6870            switch(name){\r
6871                case '.': name = new Function('values', 'parent', 'with(values){ return values; }'); break;\r
6872                case '..': name = new Function('values', 'parent', 'with(values){ return parent; }'); break;\r
6873                default: name = new Function('values', 'parent', 'with(values){ return '+name+'; }');\r
6874            }\r
6875        }\r
6876        tpls.push({\r
6877             id: id,\r
6878             target: name,\r
6879             exec: exec,\r
6880             test: fn,\r
6881             body: m[1]||''\r
6882         });\r
6883        s = s.replace(m[0], '{xtpl'+ id + '}');\r
6884        ++id;\r
6885     }\r
6886     for(var i = tpls.length-1; i >= 0; --i){\r
6887         this.compileTpl(tpls[i]);\r
6888     }\r
6889     this.master = tpls[tpls.length-1];\r
6890     this.tpls = tpls;\r
6891 };\r
6892 Ext.extend(Ext.XTemplate, Ext.Template, {\r
6893     
6894     re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,\r
6895     
6896     codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,\r
6897 \r
6898     
6899     applySubTemplate : function(id, values, parent, xindex, xcount){\r
6900         var t = this.tpls[id];\r
6901         if(t.test && !t.test.call(this, values, parent, xindex, xcount)){\r
6902             return '';\r
6903         }\r
6904         if(t.exec && t.exec.call(this, values, parent, xindex, xcount)){\r
6905             return '';\r
6906         }\r
6907         var vs = t.target ? t.target.call(this, values, parent) : values;\r
6908         parent = t.target ? values : parent;\r
6909         if(t.target && Ext.isArray(vs)){\r
6910             var buf = [];\r
6911             for(var i = 0, len = vs.length; i < len; i++){\r
6912                 buf[buf.length] = t.compiled.call(this, vs[i], parent, i+1, len);\r
6913             }\r
6914             return buf.join('');\r
6915         }\r
6916         return t.compiled.call(this, vs, parent, xindex, xcount);\r
6917     },\r
6918 \r
6919     
6920     compileTpl : function(tpl){\r
6921         var fm = Ext.util.Format;\r
6922         var useF = this.disableFormats !== true;\r
6923         var sep = Ext.isGecko ? "+" : ",";\r
6924         var fn = function(m, name, format, args, math){\r
6925             if(name.substr(0, 4) == 'xtpl'){\r
6926                 return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";\r
6927             }\r
6928             var v;\r
6929             if(name === '.'){\r
6930                 v = 'values';\r
6931             }else if(name === '#'){\r
6932                 v = 'xindex';\r
6933             }else if(name.indexOf('.') != -1){\r
6934                 v = name;\r
6935             }else{\r
6936                 v = "values['" + name + "']";\r
6937             }\r
6938             if(math){\r
6939                 v = '(' + v + math + ')';\r
6940             }\r
6941             if(format && useF){\r
6942                 args = args ? ',' + args : "";\r
6943                 if(format.substr(0, 5) != "this."){\r
6944                     format = "fm." + format + '(';\r
6945                 }else{\r
6946                     format = 'this.call("'+ format.substr(5) + '", ';\r
6947                     args = ", values";\r
6948                 }\r
6949             }else{\r
6950                 args= ''; format = "("+v+" === undefined ? '' : ";\r
6951             }\r
6952             return "'"+ sep + format + v + args + ")"+sep+"'";\r
6953         };\r
6954         var codeFn = function(m, code){\r
6955             return "'"+ sep +'('+code+')'+sep+"'";\r
6956         };\r
6957 \r
6958         var body;\r
6959         
6960         if(Ext.isGecko){\r
6961             body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +\r
6962                    tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +\r
6963                     "';};";\r
6964         }else{\r
6965             body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];\r
6966             body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));\r
6967             body.push("'].join('');};");\r
6968             body = body.join('');\r
6969         }\r
6970         eval(body);\r
6971         return this;\r
6972     },\r
6973 \r
6974     \r
6975     apply : function(values){\r
6976         return this.master.compiled.call(this, values, {}, 1, 1);\r
6977     },\r
6978 \r
6979     \r
6980     applyTemplate : function(values){\r
6981         return this.master.compiled.call(this, values, {}, 1, 1);\r
6982     },\r
6983 \r
6984     \r
6985     compile : function(){return this;}\r
6986 \r
6987     \r
6988     \r
6989     \r
6990     \r
6991 });\r
6992 \r
6993 \r
6994 Ext.XTemplate.from = function(el){\r
6995     el = Ext.getDom(el);\r
6996     return new Ext.XTemplate(el.value || el.innerHTML);\r
6997 };
6998 \r
6999 Ext.util.CSS = function(){\r
7000         var rules = null;\r
7001         var doc = document;\r
7002 \r
7003     var camelRe = /(-[a-z])/gi;\r
7004     var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };\r
7005 \r
7006    return {\r
7007    \r
7008    createStyleSheet : function(cssText, id){\r
7009        var ss;\r
7010        var head = doc.getElementsByTagName("head")[0];\r
7011        var rules = doc.createElement("style");\r
7012        rules.setAttribute("type", "text/css");\r
7013        if(id){\r
7014            rules.setAttribute("id", id);\r
7015        }\r
7016        if(Ext.isIE){\r
7017            head.appendChild(rules);\r
7018            ss = rules.styleSheet;\r
7019            ss.cssText = cssText;\r
7020        }else{\r
7021            try{\r
7022                 rules.appendChild(doc.createTextNode(cssText));\r
7023            }catch(e){\r
7024                rules.cssText = cssText;\r
7025            }\r
7026            head.appendChild(rules);\r
7027            ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);\r
7028        }\r
7029        this.cacheStyleSheet(ss);\r
7030        return ss;\r
7031    },\r
7032 \r
7033    \r
7034    removeStyleSheet : function(id){\r
7035        var existing = doc.getElementById(id);\r
7036        if(existing){\r
7037            existing.parentNode.removeChild(existing);\r
7038        }\r
7039    },\r
7040 \r
7041    \r
7042    swapStyleSheet : function(id, url){\r
7043        this.removeStyleSheet(id);\r
7044        var ss = doc.createElement("link");\r
7045        ss.setAttribute("rel", "stylesheet");\r
7046        ss.setAttribute("type", "text/css");\r
7047        ss.setAttribute("id", id);\r
7048        ss.setAttribute("href", url);\r
7049        doc.getElementsByTagName("head")[0].appendChild(ss);\r
7050    },\r
7051    \r
7052    \r
7053    refreshCache : function(){\r
7054        return this.getRules(true);\r
7055    },\r
7056 \r
7057    
7058    cacheStyleSheet : function(ss){\r
7059        if(!rules){\r
7060            rules = {};\r
7061        }\r
7062        try{
7063            var ssRules = ss.cssRules || ss.rules;\r
7064            for(var j = ssRules.length-1; j >= 0; --j){\r
7065                rules[ssRules[j].selectorText] = ssRules[j];\r
7066            }\r
7067        }catch(e){}\r
7068    },\r
7069    \r
7070    \r
7071    getRules : function(refreshCache){\r
7072                 if(rules == null || refreshCache){\r
7073                         rules = {};\r
7074                         var ds = doc.styleSheets;\r
7075                         for(var i =0, len = ds.length; i < len; i++){\r
7076                             try{\r
7077                         this.cacheStyleSheet(ds[i]);\r
7078                     }catch(e){} \r
7079                 }\r
7080                 }\r
7081                 return rules;\r
7082         },\r
7083         \r
7084         \r
7085    getRule : function(selector, refreshCache){\r
7086                 var rs = this.getRules(refreshCache);\r
7087                 if(!Ext.isArray(selector)){\r
7088                     return rs[selector];\r
7089                 }\r
7090                 for(var i = 0; i < selector.length; i++){\r
7091                         if(rs[selector[i]]){\r
7092                                 return rs[selector[i]];\r
7093                         }\r
7094                 }\r
7095                 return null;\r
7096         },\r
7097         \r
7098         \r
7099         \r
7100    updateRule : function(selector, property, value){\r
7101                 if(!Ext.isArray(selector)){\r
7102                         var rule = this.getRule(selector);\r
7103                         if(rule){\r
7104                                 rule.style[property.replace(camelRe, camelFn)] = value;\r
7105                                 return true;\r
7106                         }\r
7107                 }else{\r
7108                         for(var i = 0; i < selector.length; i++){\r
7109                                 if(this.updateRule(selector[i], property, value)){\r
7110                                         return true;\r
7111                                 }\r
7112                         }\r
7113                 }\r
7114                 return false;\r
7115         }\r
7116    };   \r
7117 }();
7118
7119 Ext.util.ClickRepeater = function(el, config)
7120 {
7121     this.el = Ext.get(el);
7122     this.el.unselectable();
7123
7124     Ext.apply(this, config);
7125
7126     this.addEvents(
7127     
7128         "mousedown",
7129     
7130         "click",
7131     
7132         "mouseup"
7133     );
7134
7135     this.el.on("mousedown", this.handleMouseDown, this);
7136     if(this.preventDefault || this.stopDefault){
7137         this.el.on("click", function(e){
7138             if(this.preventDefault){
7139                 e.preventDefault();
7140             }
7141             if(this.stopDefault){
7142                 e.stopEvent();
7143             }
7144         }, this);
7145     }
7146
7147         if(this.handler){
7148         this.on("click", this.handler,  this.scope || this);
7149     }
7150
7151     Ext.util.ClickRepeater.superclass.constructor.call(this);
7152 };
7153
7154 Ext.extend(Ext.util.ClickRepeater, Ext.util.Observable, {
7155     interval : 20,
7156     delay: 250,
7157     preventDefault : true,
7158     stopDefault : false,
7159     timer : 0,
7160
7161         handleMouseDown : function(){
7162         clearTimeout(this.timer);
7163         this.el.blur();
7164         if(this.pressClass){
7165             this.el.addClass(this.pressClass);
7166         }
7167         this.mousedownTime = new Date();
7168
7169         Ext.getDoc().on("mouseup", this.handleMouseUp, this);
7170         this.el.on("mouseout", this.handleMouseOut, this);
7171
7172         this.fireEvent("mousedown", this);
7173         this.fireEvent("click", this);
7174
7175         if (this.accelerate) {
7176             this.delay = 400;
7177             }
7178         this.timer = this.click.defer(this.delay || this.interval, this);
7179     },
7180
7181         click : function(){
7182         this.fireEvent("click", this);
7183         this.timer = this.click.defer(this.accelerate ?
7184             this.easeOutExpo(this.mousedownTime.getElapsed(),
7185                 400,
7186                 -390,
7187                 12000) :
7188             this.interval, this);
7189     },
7190
7191     easeOutExpo : function (t, b, c, d) {
7192         return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
7193     },
7194
7195         handleMouseOut : function(){
7196         clearTimeout(this.timer);
7197         if(this.pressClass){
7198             this.el.removeClass(this.pressClass);
7199         }
7200         this.el.on("mouseover", this.handleMouseReturn, this);
7201     },
7202
7203         handleMouseReturn : function(){
7204         this.el.un("mouseover", this.handleMouseReturn);
7205         if(this.pressClass){
7206             this.el.addClass(this.pressClass);
7207         }
7208         this.click();
7209     },
7210
7211         handleMouseUp : function(){
7212         clearTimeout(this.timer);
7213         this.el.un("mouseover", this.handleMouseReturn);
7214         this.el.un("mouseout", this.handleMouseOut);
7215         Ext.getDoc().un("mouseup", this.handleMouseUp);
7216         this.el.removeClass(this.pressClass);
7217         this.fireEvent("mouseup", this);
7218     }
7219 });
7220
7221 Ext.KeyNav = function(el, config){
7222     this.el = Ext.get(el);
7223     Ext.apply(this, config);
7224     if(!this.disabled){
7225         this.disabled = true;
7226         this.enable();
7227     }
7228 };
7229
7230 Ext.KeyNav.prototype = {
7231     
7232     disabled : false,
7233     
7234     defaultEventAction: "stopEvent",
7235     
7236     forceKeyDown : false,
7237
7238         prepareEvent : function(e){
7239         var k = e.getKey();
7240         var h = this.keyToHandler[k];
7241                                 if(Ext.isSafari && h && k >= 37 && k <= 40){
7242             e.stopEvent();
7243         }
7244     },
7245
7246         relay : function(e){
7247         var k = e.getKey();
7248         var h = this.keyToHandler[k];
7249         if(h && this[h]){
7250             if(this.doRelay(e, this[h], h) !== true){
7251                 e[this.defaultEventAction]();
7252             }
7253         }
7254     },
7255
7256         doRelay : function(e, h, hname){
7257         return h.call(this.scope || this, e);
7258     },
7259
7260         enter : false,
7261     left : false,
7262     right : false,
7263     up : false,
7264     down : false,
7265     tab : false,
7266     esc : false,
7267     pageUp : false,
7268     pageDown : false,
7269     del : false,
7270     home : false,
7271     end : false,
7272
7273         keyToHandler : {
7274         37 : "left",
7275         39 : "right",
7276         38 : "up",
7277         40 : "down",
7278         33 : "pageUp",
7279         34 : "pageDown",
7280         46 : "del",
7281         36 : "home",
7282         35 : "end",
7283         13 : "enter",
7284         27 : "esc",
7285         9  : "tab"
7286     },
7287
7288         
7289         enable: function(){
7290                 if(this.disabled){
7291                                     if(this.forceKeyDown || Ext.isIE || Ext.isAir){
7292                 this.el.on("keydown", this.relay,  this);
7293             }else{
7294                 this.el.on("keydown", this.prepareEvent,  this);
7295                 this.el.on("keypress", this.relay,  this);
7296             }
7297                     this.disabled = false;
7298                 }
7299         },
7300
7301         
7302         disable: function(){
7303                 if(!this.disabled){
7304                     if(this.forceKeyDown || Ext.isIE || Ext.isAir){
7305                 this.el.un("keydown", this.relay);
7306             }else{
7307                 this.el.un("keydown", this.prepareEvent);
7308                 this.el.un("keypress", this.relay);
7309             }
7310                     this.disabled = true;
7311                 }
7312         }
7313 };
7314 \r
7315 Ext.KeyMap = function(el, config, eventName){\r
7316     this.el  = Ext.get(el);\r
7317     this.eventName = eventName || "keydown";\r
7318     this.bindings = [];\r
7319     if(config){\r
7320         this.addBinding(config);\r
7321     }\r
7322     this.enable();\r
7323 };\r
7324 \r
7325 Ext.KeyMap.prototype = {\r
7326     \r
7327     stopEvent : false,\r
7328 \r
7329     \r
7330         addBinding : function(config){\r
7331         if(Ext.isArray(config)){\r
7332             for(var i = 0, len = config.length; i < len; i++){\r
7333                 this.addBinding(config[i]);\r
7334             }\r
7335             return;\r
7336         }\r
7337         var keyCode = config.key,\r
7338             shift = config.shift,\r
7339             ctrl = config.ctrl,\r
7340             alt = config.alt,\r
7341             fn = config.fn || config.handler,\r
7342             scope = config.scope;\r
7343 \r
7344         if(typeof keyCode == "string"){\r
7345             var ks = [];\r
7346             var keyString = keyCode.toUpperCase();\r
7347             for(var j = 0, len = keyString.length; j < len; j++){\r
7348                 ks.push(keyString.charCodeAt(j));\r
7349             }\r
7350             keyCode = ks;\r
7351         }\r
7352         var keyArray = Ext.isArray(keyCode);\r
7353         \r
7354         var handler = function(e){\r
7355             if((!shift || e.shiftKey) && (!ctrl || e.ctrlKey) &&  (!alt || e.altKey)){\r
7356                 var k = e.getKey();\r
7357                 if(keyArray){\r
7358                     for(var i = 0, len = keyCode.length; i < len; i++){\r
7359                         if(keyCode[i] == k){\r
7360                           if(this.stopEvent){\r
7361                               e.stopEvent();\r
7362                           }\r
7363                           fn.call(scope || window, k, e);\r
7364                           return;\r
7365                         }\r
7366                     }\r
7367                 }else{\r
7368                     if(k == keyCode){\r
7369                         if(this.stopEvent){\r
7370                            e.stopEvent();\r
7371                         }\r
7372                         fn.call(scope || window, k, e);\r
7373                     }\r
7374                 }\r
7375             }\r
7376         };\r
7377         this.bindings.push(handler);\r
7378         },\r
7379 \r
7380     \r
7381     on : function(key, fn, scope){\r
7382         var keyCode, shift, ctrl, alt;\r
7383         if(typeof key == "object" && !Ext.isArray(key)){\r
7384             keyCode = key.key;\r
7385             shift = key.shift;\r
7386             ctrl = key.ctrl;\r
7387             alt = key.alt;\r
7388         }else{\r
7389             keyCode = key;\r
7390         }\r
7391         this.addBinding({\r
7392             key: keyCode,\r
7393             shift: shift,\r
7394             ctrl: ctrl,\r
7395             alt: alt,\r
7396             fn: fn,\r
7397             scope: scope\r
7398         })\r
7399     },\r
7400 \r
7401     
7402     handleKeyDown : function(e){\r
7403             if(this.enabled){ 
7404             var b = this.bindings;\r
7405             for(var i = 0, len = b.length; i < len; i++){\r
7406                 b[i].call(this, e);\r
7407             }\r
7408             }\r
7409         },\r
7410 \r
7411         \r
7412         isEnabled : function(){\r
7413             return this.enabled;\r
7414         },\r
7415 \r
7416         \r
7417         enable: function(){\r
7418                 if(!this.enabled){\r
7419                     this.el.on(this.eventName, this.handleKeyDown, this);\r
7420                     this.enabled = true;\r
7421                 }\r
7422         },\r
7423 \r
7424         \r
7425         disable: function(){\r
7426                 if(this.enabled){\r
7427                     this.el.removeListener(this.eventName, this.handleKeyDown, this);\r
7428                     this.enabled = false;\r
7429                 }\r
7430         }\r
7431 };
7432
7433 Ext.util.TextMetrics = function(){
7434     var shared;
7435     return {
7436         
7437         measure : function(el, text, fixedWidth){
7438             if(!shared){
7439                 shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
7440             }
7441             shared.bind(el);
7442             shared.setFixedWidth(fixedWidth || 'auto');
7443             return shared.getSize(text);
7444         },
7445
7446         
7447         createInstance : function(el, fixedWidth){
7448             return Ext.util.TextMetrics.Instance(el, fixedWidth);
7449         }
7450     };
7451 }();
7452
7453 Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
7454     var ml = new Ext.Element(document.createElement('div'));
7455     document.body.appendChild(ml.dom);
7456     ml.position('absolute');
7457     ml.setLeftTop(-1000, -1000);
7458     ml.hide();
7459
7460     if(fixedWidth){
7461         ml.setWidth(fixedWidth);
7462     }
7463
7464     var instance = {
7465         
7466         getSize : function(text){
7467             ml.update(text);
7468             var s = ml.getSize();
7469             ml.update('');
7470             return s;
7471         },
7472
7473         
7474         bind : function(el){
7475             ml.setStyle(
7476                 Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height')
7477             );
7478         },
7479
7480         
7481         setFixedWidth : function(width){
7482             ml.setWidth(width);
7483         },
7484
7485         
7486         getWidth : function(text){
7487             ml.dom.style.width = 'auto';
7488             return this.getSize(text).width;
7489         },
7490
7491         
7492         getHeight : function(text){
7493             return this.getSize(text).height;
7494         }
7495     };
7496
7497     instance.bind(bindTo);
7498
7499     return instance;
7500 };
7501
7502 Ext.Element.measureText = Ext.util.TextMetrics.measure;
7503 \r
7504 \r
7505 (function() {\r
7506 \r
7507 var Event=Ext.EventManager;\r
7508 var Dom=Ext.lib.Dom;\r
7509 \r
7510 \r
7511 Ext.dd.DragDrop = function(id, sGroup, config) {\r
7512     if(id) {\r
7513         this.init(id, sGroup, config);\r
7514     }\r
7515 };\r
7516 \r
7517 Ext.dd.DragDrop.prototype = {\r
7518 \r
7519     \r
7520     id: null,\r
7521 \r
7522     \r
7523     config: null,\r
7524 \r
7525     \r
7526     dragElId: null,\r
7527 \r
7528     \r
7529     handleElId: null,\r
7530 \r
7531     \r
7532     invalidHandleTypes: null,\r
7533 \r
7534     \r
7535     invalidHandleIds: null,\r
7536 \r
7537     \r
7538     invalidHandleClasses: null,\r
7539 \r
7540     \r
7541     startPageX: 0,\r
7542 \r
7543     \r
7544     startPageY: 0,\r
7545 \r
7546     \r
7547     groups: null,\r
7548 \r
7549     \r
7550     locked: false,\r
7551 \r
7552     \r
7553     lock: function() { this.locked = true; },\r
7554 \r
7555     \r
7556     unlock: function() { this.locked = false; },\r
7557 \r
7558     \r
7559     isTarget: true,\r
7560 \r
7561     \r
7562     padding: null,\r
7563 \r
7564     \r
7565     _domRef: null,\r
7566 \r
7567     \r
7568     __ygDragDrop: true,\r
7569 \r
7570     \r
7571     constrainX: false,\r
7572 \r
7573     \r
7574     constrainY: false,\r
7575 \r
7576     \r
7577     minX: 0,\r
7578 \r
7579     \r
7580     maxX: 0,\r
7581 \r
7582     \r
7583     minY: 0,\r
7584 \r
7585     \r
7586     maxY: 0,\r
7587 \r
7588     \r
7589     maintainOffset: false,\r
7590 \r
7591     \r
7592     xTicks: null,\r
7593 \r
7594     \r
7595     yTicks: null,\r
7596 \r
7597     \r
7598     primaryButtonOnly: true,\r
7599 \r
7600     \r
7601     available: false,\r
7602 \r
7603     \r
7604     hasOuterHandles: false,\r
7605 \r
7606     \r
7607     b4StartDrag: function(x, y) { },\r
7608 \r
7609     \r
7610     startDrag: function(x, y) {  },\r
7611 \r
7612     \r
7613     b4Drag: function(e) { },\r
7614 \r
7615     \r
7616     onDrag: function(e) {  },\r
7617 \r
7618     \r
7619     onDragEnter: function(e, id) {  },\r
7620 \r
7621     \r
7622     b4DragOver: function(e) { },\r
7623 \r
7624     \r
7625     onDragOver: function(e, id) {  },\r
7626 \r
7627     \r
7628     b4DragOut: function(e) { },\r
7629 \r
7630     \r
7631     onDragOut: function(e, id) {  },\r
7632 \r
7633     \r
7634     b4DragDrop: function(e) { },\r
7635 \r
7636     \r
7637     onDragDrop: function(e, id) {  },\r
7638 \r
7639     \r
7640     onInvalidDrop: function(e) {  },\r
7641 \r
7642     \r
7643     b4EndDrag: function(e) { },\r
7644 \r
7645     \r
7646     endDrag: function(e) {  },\r
7647 \r
7648     \r
7649     b4MouseDown: function(e) {  },\r
7650 \r
7651     \r
7652     onMouseDown: function(e) {  },\r
7653 \r
7654     \r
7655     onMouseUp: function(e) {  },\r
7656 \r
7657     \r
7658     onAvailable: function () {\r
7659     },\r
7660 \r
7661     \r
7662     defaultPadding : {left:0, right:0, top:0, bottom:0},\r
7663 \r
7664     \r
7665     constrainTo : function(constrainTo, pad, inContent){\r
7666         if(typeof pad == "number"){\r
7667             pad = {left: pad, right:pad, top:pad, bottom:pad};\r
7668         }\r
7669         pad = pad || this.defaultPadding;\r
7670         var b = Ext.get(this.getEl()).getBox();\r
7671         var ce = Ext.get(constrainTo);\r
7672         var s = ce.getScroll();\r
7673         var c, cd = ce.dom;\r
7674         if(cd == document.body){\r
7675             c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};\r
7676         }else{\r
7677             var xy = ce.getXY();\r
7678             c = {x : xy[0]+s.left, y: xy[1]+s.top, width: cd.clientWidth, height: cd.clientHeight};\r
7679         }\r
7680 \r
7681 \r
7682         var topSpace = b.y - c.y;\r
7683         var leftSpace = b.x - c.x;\r
7684 \r
7685         this.resetConstraints();\r
7686         this.setXConstraint(leftSpace - (pad.left||0), 
7687                 c.width - leftSpace - b.width - (pad.right||0), 
7688                                 this.xTickSize\r
7689         );\r
7690         this.setYConstraint(topSpace - (pad.top||0), 
7691                 c.height - topSpace - b.height - (pad.bottom||0), 
7692                                 this.yTickSize\r
7693         );\r
7694     },\r
7695 \r
7696     \r
7697     getEl: function() {\r
7698         if (!this._domRef) {\r
7699             this._domRef = Ext.getDom(this.id);\r
7700         }\r
7701 \r
7702         return this._domRef;\r
7703     },\r
7704 \r
7705     \r
7706     getDragEl: function() {\r
7707         return Ext.getDom(this.dragElId);\r
7708     },\r
7709 \r
7710     \r
7711     init: function(id, sGroup, config) {\r
7712         this.initTarget(id, sGroup, config);\r
7713         Event.on(this.id, "mousedown", this.handleMouseDown, this);\r
7714         
7715     },\r
7716 \r
7717     \r
7718     initTarget: function(id, sGroup, config) {\r
7719 \r
7720         
7721         this.config = config || {};\r
7722 \r
7723         
7724         this.DDM = Ext.dd.DDM;\r
7725         
7726         this.groups = {};\r
7727 \r
7728         
7729         
7730         if (typeof id !== "string") {\r
7731             id = Ext.id(id);\r
7732         }\r
7733 \r
7734         
7735         this.id = id;\r
7736 \r
7737         
7738         this.addToGroup((sGroup) ? sGroup : "default");\r
7739 \r
7740         
7741         
7742         this.handleElId = id;\r
7743 \r
7744         
7745         this.setDragElId(id);\r
7746 \r
7747         
7748         this.invalidHandleTypes = { A: "A" };\r
7749         this.invalidHandleIds = {};\r
7750         this.invalidHandleClasses = [];\r
7751 \r
7752         this.applyConfig();\r
7753 \r
7754         this.handleOnAvailable();\r
7755     },\r
7756 \r
7757     \r
7758     applyConfig: function() {\r
7759 \r
7760         
7761         
7762         this.padding           = this.config.padding || [0, 0, 0, 0];\r
7763         this.isTarget          = (this.config.isTarget !== false);\r
7764         this.maintainOffset    = (this.config.maintainOffset);\r
7765         this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);\r
7766 \r
7767     },\r
7768 \r
7769     \r
7770     handleOnAvailable: function() {\r
7771         this.available = true;\r
7772         this.resetConstraints();\r
7773         this.onAvailable();\r
7774     },\r
7775 \r
7776      \r
7777     setPadding: function(iTop, iRight, iBot, iLeft) {\r
7778         
7779         if (!iRight && 0 !== iRight) {\r
7780             this.padding = [iTop, iTop, iTop, iTop];\r
7781         } else if (!iBot && 0 !== iBot) {\r
7782             this.padding = [iTop, iRight, iTop, iRight];\r
7783         } else {\r
7784             this.padding = [iTop, iRight, iBot, iLeft];\r
7785         }\r
7786     },\r
7787 \r
7788     \r
7789     setInitPosition: function(diffX, diffY) {\r
7790         var el = this.getEl();\r
7791 \r
7792         if (!this.DDM.verifyEl(el)) {\r
7793             return;\r
7794         }\r
7795 \r
7796         var dx = diffX || 0;\r
7797         var dy = diffY || 0;\r
7798 \r
7799         var p = Dom.getXY( el );\r
7800 \r
7801         this.initPageX = p[0] - dx;\r
7802         this.initPageY = p[1] - dy;\r
7803 \r
7804         this.lastPageX = p[0];\r
7805         this.lastPageY = p[1];\r
7806 \r
7807 \r
7808         this.setStartPosition(p);\r
7809     },\r
7810 \r
7811     \r
7812     setStartPosition: function(pos) {\r
7813         var p = pos || Dom.getXY( this.getEl() );\r
7814         this.deltaSetXY = null;\r
7815 \r
7816         this.startPageX = p[0];\r
7817         this.startPageY = p[1];\r
7818     },\r
7819 \r
7820     \r
7821     addToGroup: function(sGroup) {\r
7822         this.groups[sGroup] = true;\r
7823         this.DDM.regDragDrop(this, sGroup);\r
7824     },\r
7825 \r
7826     \r
7827     removeFromGroup: function(sGroup) {\r
7828         if (this.groups[sGroup]) {\r
7829             delete this.groups[sGroup];\r
7830         }\r
7831 \r
7832         this.DDM.removeDDFromGroup(this, sGroup);\r
7833     },\r
7834 \r
7835     \r
7836     setDragElId: function(id) {\r
7837         this.dragElId = id;\r
7838     },\r
7839 \r
7840     \r
7841     setHandleElId: function(id) {\r
7842         if (typeof id !== "string") {\r
7843             id = Ext.id(id);\r
7844         }\r
7845         this.handleElId = id;\r
7846         this.DDM.regHandle(this.id, id);\r
7847     },\r
7848 \r
7849     \r
7850     setOuterHandleElId: function(id) {\r
7851         if (typeof id !== "string") {\r
7852             id = Ext.id(id);\r
7853         }\r
7854         Event.on(id, "mousedown",\r
7855                 this.handleMouseDown, this);\r
7856         this.setHandleElId(id);\r
7857 \r
7858         this.hasOuterHandles = true;\r
7859     },\r
7860 \r
7861     \r
7862     unreg: function() {\r
7863         Event.un(this.id, "mousedown",\r
7864                 this.handleMouseDown);\r
7865         this._domRef = null;\r
7866         this.DDM._remove(this);\r
7867     },\r
7868 \r
7869     destroy : function(){\r
7870         this.unreg();\r
7871     },\r
7872 \r
7873     \r
7874     isLocked: function() {\r
7875         return (this.DDM.isLocked() || this.locked);\r
7876     },\r
7877 \r
7878     \r
7879     handleMouseDown: function(e, oDD){\r
7880         if (this.primaryButtonOnly && e.button != 0) {\r
7881             return;\r
7882         }\r
7883 \r
7884         if (this.isLocked()) {\r
7885             return;\r
7886         }\r
7887 \r
7888         this.DDM.refreshCache(this.groups);\r
7889 \r
7890         var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));\r
7891         if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) )  {\r
7892         } else {\r
7893             if (this.clickValidator(e)) {\r
7894 \r
7895                 
7896                 this.setStartPosition();\r
7897 \r
7898 \r
7899                 this.b4MouseDown(e);\r
7900                 this.onMouseDown(e);\r
7901 \r
7902                 this.DDM.handleMouseDown(e, this);\r
7903 \r
7904                 this.DDM.stopEvent(e);\r
7905             } else {\r
7906 \r
7907 \r
7908             }\r
7909         }\r
7910     },\r
7911 \r
7912     clickValidator: function(e) {\r
7913         var target = e.getTarget();\r
7914         return ( this.isValidHandleChild(target) &&\r
7915                     (this.id == this.handleElId ||\r
7916                         this.DDM.handleWasClicked(target, this.id)) );\r
7917     },\r
7918 \r
7919     \r
7920     addInvalidHandleType: function(tagName) {\r
7921         var type = tagName.toUpperCase();\r
7922         this.invalidHandleTypes[type] = type;\r
7923     },\r
7924 \r
7925     \r
7926     addInvalidHandleId: function(id) {\r
7927         if (typeof id !== "string") {\r
7928             id = Ext.id(id);\r
7929         }\r
7930         this.invalidHandleIds[id] = id;\r
7931     },\r
7932 \r
7933     \r
7934     addInvalidHandleClass: function(cssClass) {\r
7935         this.invalidHandleClasses.push(cssClass);\r
7936     },\r
7937 \r
7938     \r
7939     removeInvalidHandleType: function(tagName) {\r
7940         var type = tagName.toUpperCase();\r
7941         
7942         delete this.invalidHandleTypes[type];\r
7943     },\r
7944 \r
7945     \r
7946     removeInvalidHandleId: function(id) {\r
7947         if (typeof id !== "string") {\r
7948             id = Ext.id(id);\r
7949         }\r
7950         delete this.invalidHandleIds[id];\r
7951     },\r
7952 \r
7953     \r
7954     removeInvalidHandleClass: function(cssClass) {\r
7955         for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {\r
7956             if (this.invalidHandleClasses[i] == cssClass) {\r
7957                 delete this.invalidHandleClasses[i];\r
7958             }\r
7959         }\r
7960     },\r
7961 \r
7962     \r
7963     isValidHandleChild: function(node) {\r
7964 \r
7965         var valid = true;\r
7966         
7967         var nodeName;\r
7968         try {\r
7969             nodeName = node.nodeName.toUpperCase();\r
7970         } catch(e) {\r
7971             nodeName = node.nodeName;\r
7972         }\r
7973         valid = valid && !this.invalidHandleTypes[nodeName];\r
7974         valid = valid && !this.invalidHandleIds[node.id];\r
7975 \r
7976         for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {\r
7977             valid = !Dom.hasClass(node, this.invalidHandleClasses[i]);\r
7978         }\r
7979 \r
7980 \r
7981         return valid;\r
7982 \r
7983     },\r
7984 \r
7985     \r
7986     setXTicks: function(iStartX, iTickSize) {\r
7987         this.xTicks = [];\r
7988         this.xTickSize = iTickSize;\r
7989 \r
7990         var tickMap = {};\r
7991 \r
7992         for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {\r
7993             if (!tickMap[i]) {\r
7994                 this.xTicks[this.xTicks.length] = i;\r
7995                 tickMap[i] = true;\r
7996             }\r
7997         }\r
7998 \r
7999         for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {\r
8000             if (!tickMap[i]) {\r
8001                 this.xTicks[this.xTicks.length] = i;\r
8002                 tickMap[i] = true;\r
8003             }\r
8004         }\r
8005 \r
8006         this.xTicks.sort(this.DDM.numericSort) ;\r
8007     },\r
8008 \r
8009     \r
8010     setYTicks: function(iStartY, iTickSize) {\r
8011         this.yTicks = [];\r
8012         this.yTickSize = iTickSize;\r
8013 \r
8014         var tickMap = {};\r
8015 \r
8016         for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {\r
8017             if (!tickMap[i]) {\r
8018                 this.yTicks[this.yTicks.length] = i;\r
8019                 tickMap[i] = true;\r
8020             }\r
8021         }\r
8022 \r
8023         for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {\r
8024             if (!tickMap[i]) {\r
8025                 this.yTicks[this.yTicks.length] = i;\r
8026                 tickMap[i] = true;\r
8027             }\r
8028         }\r
8029 \r
8030         this.yTicks.sort(this.DDM.numericSort) ;\r
8031     },\r
8032 \r
8033     \r
8034     setXConstraint: function(iLeft, iRight, iTickSize) {\r
8035         this.leftConstraint = iLeft;\r
8036         this.rightConstraint = iRight;\r
8037 \r
8038         this.minX = this.initPageX - iLeft;\r
8039         this.maxX = this.initPageX + iRight;\r
8040         if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }\r
8041 \r
8042         this.constrainX = true;\r
8043     },\r
8044 \r
8045     \r
8046     clearConstraints: function() {\r
8047         this.constrainX = false;\r
8048         this.constrainY = false;\r
8049         this.clearTicks();\r
8050     },\r
8051 \r
8052     \r
8053     clearTicks: function() {\r
8054         this.xTicks = null;\r
8055         this.yTicks = null;\r
8056         this.xTickSize = 0;\r
8057         this.yTickSize = 0;\r
8058     },\r
8059 \r
8060     \r
8061     setYConstraint: function(iUp, iDown, iTickSize) {\r
8062         this.topConstraint = iUp;\r
8063         this.bottomConstraint = iDown;\r
8064 \r
8065         this.minY = this.initPageY - iUp;\r
8066         this.maxY = this.initPageY + iDown;\r
8067         if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }\r
8068 \r
8069         this.constrainY = true;\r
8070 \r
8071     },\r
8072 \r
8073     \r
8074     resetConstraints: function() {\r
8075 \r
8076 \r
8077         
8078         if (this.initPageX || this.initPageX === 0) {\r
8079             
8080             var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;\r
8081             var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;\r
8082 \r
8083             this.setInitPosition(dx, dy);\r
8084 \r
8085         
8086         } else {\r
8087             this.setInitPosition();\r
8088         }\r
8089 \r
8090         if (this.constrainX) {\r
8091             this.setXConstraint( this.leftConstraint,\r
8092                                  this.rightConstraint,\r
8093                                  this.xTickSize        );\r
8094         }\r
8095 \r
8096         if (this.constrainY) {\r
8097             this.setYConstraint( this.topConstraint,\r
8098                                  this.bottomConstraint,\r
8099                                  this.yTickSize         );\r
8100         }\r
8101     },\r
8102 \r
8103     \r
8104     getTick: function(val, tickArray) {\r
8105 \r
8106         if (!tickArray) {\r
8107             
8108             
8109             return val;\r
8110         } else if (tickArray[0] >= val) {\r
8111             
8112             
8113             return tickArray[0];\r
8114         } else {\r
8115             for (var i=0, len=tickArray.length; i<len; ++i) {\r
8116                 var next = i + 1;\r
8117                 if (tickArray[next] && tickArray[next] >= val) {\r
8118                     var diff1 = val - tickArray[i];\r
8119                     var diff2 = tickArray[next] - val;\r
8120                     return (diff2 > diff1) ? tickArray[i] : tickArray[next];\r
8121                 }\r
8122             }\r
8123 \r
8124             
8125             
8126             return tickArray[tickArray.length - 1];\r
8127         }\r
8128     },\r
8129 \r
8130     \r
8131     toString: function() {\r
8132         return ("DragDrop " + this.id);\r
8133     }\r
8134 \r
8135 };\r
8136 \r
8137 })();\r
8138 \r
8139 \r
8140
8141
8142 if (!Ext.dd.DragDropMgr) {\r
8143 \r
8144 \r
8145 Ext.dd.DragDropMgr = function() {\r
8146 \r
8147     var Event = Ext.EventManager;\r
8148 \r
8149     return {\r
8150 \r
8151         \r
8152         ids: {},\r
8153 \r
8154         \r
8155         handleIds: {},\r
8156 \r
8157         \r
8158         dragCurrent: null,\r
8159 \r
8160         \r
8161         dragOvers: {},\r
8162 \r
8163         \r
8164         deltaX: 0,\r
8165 \r
8166         \r
8167         deltaY: 0,\r
8168 \r
8169         \r
8170         preventDefault: true,\r
8171 \r
8172         \r
8173         stopPropagation: true,\r
8174 \r
8175         \r
8176         initalized: false,\r
8177 \r
8178         \r
8179         locked: false,\r
8180 \r
8181         \r
8182         init: function() {\r
8183             this.initialized = true;\r
8184         },\r
8185 \r
8186         \r
8187         POINT: 0,\r
8188 \r
8189         \r
8190         INTERSECT: 1,\r
8191 \r
8192         \r
8193         mode: 0,\r
8194 \r
8195         \r
8196         _execOnAll: function(sMethod, args) {\r
8197             for (var i in this.ids) {\r
8198                 for (var j in this.ids[i]) {\r
8199                     var oDD = this.ids[i][j];\r
8200                     if (! this.isTypeOfDD(oDD)) {\r
8201                         continue;\r
8202                     }\r
8203                     oDD[sMethod].apply(oDD, args);\r
8204                 }\r
8205             }\r
8206         },\r
8207 \r
8208         \r
8209         _onLoad: function() {\r
8210 \r
8211             this.init();\r
8212 \r
8213 \r
8214             Event.on(document, "mouseup",   this.handleMouseUp, this, true);\r
8215             Event.on(document, "mousemove", this.handleMouseMove, this, true);\r
8216             Event.on(window,   "unload",    this._onUnload, this, true);\r
8217             Event.on(window,   "resize",    this._onResize, this, true);\r
8218             
8219 \r
8220         },\r
8221 \r
8222         \r
8223         _onResize: function(e) {\r
8224             this._execOnAll("resetConstraints", []);\r
8225         },\r
8226 \r
8227         \r
8228         lock: function() { this.locked = true; },\r
8229 \r
8230         \r
8231         unlock: function() { this.locked = false; },\r
8232 \r
8233         \r
8234         isLocked: function() { return this.locked; },\r
8235 \r
8236         \r
8237         locationCache: {},\r
8238 \r
8239         \r
8240         useCache: true,\r
8241 \r
8242         \r
8243         clickPixelThresh: 3,\r
8244 \r
8245         \r
8246         clickTimeThresh: 350,\r
8247 \r
8248         \r
8249         dragThreshMet: false,\r
8250 \r
8251         \r
8252         clickTimeout: null,\r
8253 \r
8254         \r
8255         startX: 0,\r
8256 \r
8257         \r
8258         startY: 0,\r
8259 \r
8260         \r
8261         regDragDrop: function(oDD, sGroup) {\r
8262             if (!this.initialized) { this.init(); }\r
8263 \r
8264             if (!this.ids[sGroup]) {\r
8265                 this.ids[sGroup] = {};\r
8266             }\r
8267             this.ids[sGroup][oDD.id] = oDD;\r
8268         },\r
8269 \r
8270         \r
8271         removeDDFromGroup: function(oDD, sGroup) {\r
8272             if (!this.ids[sGroup]) {\r
8273                 this.ids[sGroup] = {};\r
8274             }\r
8275 \r
8276             var obj = this.ids[sGroup];\r
8277             if (obj && obj[oDD.id]) {\r
8278                 delete obj[oDD.id];\r
8279             }\r
8280         },\r
8281 \r
8282         \r
8283         _remove: function(oDD) {\r
8284             for (var g in oDD.groups) {\r
8285                 if (g && this.ids[g][oDD.id]) {\r
8286                     delete this.ids[g][oDD.id];\r
8287                 }\r
8288             }\r
8289             delete this.handleIds[oDD.id];\r
8290         },\r
8291 \r
8292         \r
8293         regHandle: function(sDDId, sHandleId) {\r
8294             if (!this.handleIds[sDDId]) {\r
8295                 this.handleIds[sDDId] = {};\r
8296             }\r
8297             this.handleIds[sDDId][sHandleId] = sHandleId;\r
8298         },\r
8299 \r
8300         \r
8301         isDragDrop: function(id) {\r
8302             return ( this.getDDById(id) ) ? true : false;\r
8303         },\r
8304 \r
8305         \r
8306         getRelated: function(p_oDD, bTargetsOnly) {\r
8307             var oDDs = [];\r
8308             for (var i in p_oDD.groups) {\r
8309                 for (j in this.ids[i]) {\r
8310                     var dd = this.ids[i][j];\r
8311                     if (! this.isTypeOfDD(dd)) {\r
8312                         continue;\r
8313                     }\r
8314                     if (!bTargetsOnly || dd.isTarget) {\r
8315                         oDDs[oDDs.length] = dd;\r
8316                     }\r
8317                 }\r
8318             }\r
8319 \r
8320             return oDDs;\r
8321         },\r
8322 \r
8323         \r
8324         isLegalTarget: function (oDD, oTargetDD) {\r
8325             var targets = this.getRelated(oDD, true);\r
8326             for (var i=0, len=targets.length;i<len;++i) {\r
8327                 if (targets[i].id == oTargetDD.id) {\r
8328                     return true;\r
8329                 }\r
8330             }\r
8331 \r
8332             return false;\r
8333         },\r
8334 \r
8335         \r
8336         isTypeOfDD: function (oDD) {\r
8337             return (oDD && oDD.__ygDragDrop);\r
8338         },\r
8339 \r
8340         \r
8341         isHandle: function(sDDId, sHandleId) {\r
8342             return ( this.handleIds[sDDId] &&\r
8343                             this.handleIds[sDDId][sHandleId] );\r
8344         },\r
8345 \r
8346         \r
8347         getDDById: function(id) {\r
8348             for (var i in this.ids) {\r
8349                 if (this.ids[i][id]) {\r
8350                     return this.ids[i][id];\r
8351                 }\r
8352             }\r
8353             return null;\r
8354         },\r
8355 \r
8356         \r
8357         handleMouseDown: function(e, oDD) {\r
8358             if(Ext.QuickTips){\r
8359                 Ext.QuickTips.disable();\r
8360             }\r
8361             this.currentTarget = e.getTarget();\r
8362 \r
8363             this.dragCurrent = oDD;\r
8364 \r
8365             var el = oDD.getEl();\r
8366 \r
8367             
8368             this.startX = e.getPageX();\r
8369             this.startY = e.getPageY();\r
8370 \r
8371             this.deltaX = this.startX - el.offsetLeft;\r
8372             this.deltaY = this.startY - el.offsetTop;\r
8373 \r
8374             this.dragThreshMet = false;\r
8375 \r
8376             this.clickTimeout = setTimeout(\r
8377                     function() {\r
8378                         var DDM = Ext.dd.DDM;\r
8379                         DDM.startDrag(DDM.startX, DDM.startY);\r
8380                     },\r
8381                     this.clickTimeThresh );\r
8382         },\r
8383 \r
8384         \r
8385         startDrag: function(x, y) {\r
8386             clearTimeout(this.clickTimeout);\r
8387             if (this.dragCurrent) {\r
8388                 this.dragCurrent.b4StartDrag(x, y);\r
8389                 this.dragCurrent.startDrag(x, y);\r
8390             }\r
8391             this.dragThreshMet = true;\r
8392         },\r
8393 \r
8394         \r
8395         handleMouseUp: function(e) {\r
8396 \r
8397             if(Ext.QuickTips){\r
8398                 Ext.QuickTips.enable();\r
8399             }\r
8400             if (! this.dragCurrent) {\r
8401                 return;\r
8402             }\r
8403 \r
8404             clearTimeout(this.clickTimeout);\r
8405 \r
8406             if (this.dragThreshMet) {\r
8407                 this.fireEvents(e, true);\r
8408             } else {\r
8409             }\r
8410 \r
8411             this.stopDrag(e);\r
8412 \r
8413             this.stopEvent(e);\r
8414         },\r
8415 \r
8416         \r
8417         stopEvent: function(e){\r
8418             if(this.stopPropagation) {\r
8419                 e.stopPropagation();\r
8420             }\r
8421 \r
8422             if (this.preventDefault) {\r
8423                 e.preventDefault();\r
8424             }\r
8425         },\r
8426 \r
8427         \r
8428         stopDrag: function(e) {\r
8429             
8430             if (this.dragCurrent) {\r
8431                 if (this.dragThreshMet) {\r
8432                     this.dragCurrent.b4EndDrag(e);\r
8433                     this.dragCurrent.endDrag(e);\r
8434                 }\r
8435 \r
8436                 this.dragCurrent.onMouseUp(e);\r
8437             }\r
8438 \r
8439             this.dragCurrent = null;\r
8440             this.dragOvers = {};\r
8441         },\r
8442 \r
8443         \r
8444         handleMouseMove: function(e) {\r
8445             if (! this.dragCurrent) {\r
8446                 return true;\r
8447             }\r
8448 \r
8449             
8450 \r
8451             
8452             if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {\r
8453                 this.stopEvent(e);\r
8454                 return this.handleMouseUp(e);\r
8455             }\r
8456 \r
8457             if (!this.dragThreshMet) {\r
8458                 var diffX = Math.abs(this.startX - e.getPageX());\r
8459                 var diffY = Math.abs(this.startY - e.getPageY());\r
8460                 if (diffX > this.clickPixelThresh ||\r
8461                             diffY > this.clickPixelThresh) {\r
8462                     this.startDrag(this.startX, this.startY);\r
8463                 }\r
8464             }\r
8465 \r
8466             if (this.dragThreshMet) {\r
8467                 this.dragCurrent.b4Drag(e);\r
8468                 this.dragCurrent.onDrag(e);\r
8469                 if(!this.dragCurrent.moveOnly){\r
8470                     this.fireEvents(e, false);\r
8471                 }\r
8472             }\r
8473 \r
8474             this.stopEvent(e);\r
8475 \r
8476             return true;\r
8477         },\r
8478 \r
8479         \r
8480         fireEvents: function(e, isDrop) {\r
8481             var dc = this.dragCurrent;\r
8482 \r
8483             
8484             
8485             if (!dc || dc.isLocked()) {\r
8486                 return;\r
8487             }\r
8488 \r
8489             var pt = e.getPoint();\r
8490 \r
8491             
8492             var oldOvers = [];\r
8493 \r
8494             var outEvts   = [];\r
8495             var overEvts  = [];\r
8496             var dropEvts  = [];\r
8497             var enterEvts = [];\r
8498 \r
8499             
8500             
8501             for (var i in this.dragOvers) {\r
8502 \r
8503                 var ddo = this.dragOvers[i];\r
8504 \r
8505                 if (! this.isTypeOfDD(ddo)) {\r
8506                     continue;\r
8507                 }\r
8508 \r
8509                 if (! this.isOverTarget(pt, ddo, this.mode)) {\r
8510                     outEvts.push( ddo );\r
8511                 }\r
8512 \r
8513                 oldOvers[i] = true;\r
8514                 delete this.dragOvers[i];\r
8515             }\r
8516 \r
8517             for (var sGroup in dc.groups) {\r
8518 \r
8519                 if ("string" != typeof sGroup) {\r
8520                     continue;\r
8521                 }\r
8522 \r
8523                 for (i in this.ids[sGroup]) {\r
8524                     var oDD = this.ids[sGroup][i];\r
8525                     if (! this.isTypeOfDD(oDD)) {\r
8526                         continue;\r
8527                     }\r
8528 \r
8529                     if (oDD.isTarget && !oDD.isLocked() && oDD != dc) {\r
8530                         if (this.isOverTarget(pt, oDD, this.mode)) {\r
8531                             
8532                             if (isDrop) {\r
8533                                 dropEvts.push( oDD );\r
8534                             
8535                             } else {\r
8536 \r
8537                                 
8538                                 if (!oldOvers[oDD.id]) {\r
8539                                     enterEvts.push( oDD );\r
8540                                 
8541                                 } else {\r
8542                                     overEvts.push( oDD );\r
8543                                 }\r
8544 \r
8545                                 this.dragOvers[oDD.id] = oDD;\r
8546                             }\r
8547                         }\r
8548                     }\r
8549                 }\r
8550             }\r
8551 \r
8552             if (this.mode) {\r
8553                 if (outEvts.length) {\r
8554                     dc.b4DragOut(e, outEvts);\r
8555                     dc.onDragOut(e, outEvts);\r
8556                 }\r
8557 \r
8558                 if (enterEvts.length) {\r
8559                     dc.onDragEnter(e, enterEvts);\r
8560                 }\r
8561 \r
8562                 if (overEvts.length) {\r
8563                     dc.b4DragOver(e, overEvts);\r
8564                     dc.onDragOver(e, overEvts);\r
8565                 }\r
8566 \r
8567                 if (dropEvts.length) {\r
8568                     dc.b4DragDrop(e, dropEvts);\r
8569                     dc.onDragDrop(e, dropEvts);\r
8570                 }\r
8571 \r
8572             } else {\r
8573                 
8574                 var len = 0;\r
8575                 for (i=0, len=outEvts.length; i<len; ++i) {\r
8576                     dc.b4DragOut(e, outEvts[i].id);\r
8577                     dc.onDragOut(e, outEvts[i].id);\r
8578                 }\r
8579 \r
8580                 
8581                 for (i=0,len=enterEvts.length; i<len; ++i) {\r
8582                     
8583                     dc.onDragEnter(e, enterEvts[i].id);\r
8584                 }\r
8585 \r
8586                 
8587                 for (i=0,len=overEvts.length; i<len; ++i) {\r
8588                     dc.b4DragOver(e, overEvts[i].id);\r
8589                     dc.onDragOver(e, overEvts[i].id);\r
8590                 }\r
8591 \r
8592                 
8593                 for (i=0, len=dropEvts.length; i<len; ++i) {\r
8594                     dc.b4DragDrop(e, dropEvts[i].id);\r
8595                     dc.onDragDrop(e, dropEvts[i].id);\r
8596                 }\r
8597 \r
8598             }\r
8599 \r
8600             
8601             if (isDrop && !dropEvts.length) {\r
8602                 dc.onInvalidDrop(e);\r
8603             }\r
8604 \r
8605         },\r
8606 \r
8607         \r
8608         getBestMatch: function(dds) {\r
8609             var winner = null;\r
8610             
8611             
8612                
8613             
8614             
8615 \r
8616             var len = dds.length;\r
8617 \r
8618             if (len == 1) {\r
8619                 winner = dds[0];\r
8620             } else {\r
8621                 
8622                 for (var i=0; i<len; ++i) {\r
8623                     var dd = dds[i];\r
8624                     
8625                     
8626                     
8627                     if (dd.cursorIsOver) {\r
8628                         winner = dd;\r
8629                         break;\r
8630                     
8631                     } else {\r
8632                         if (!winner ||\r
8633                             winner.overlap.getArea() < dd.overlap.getArea()) {\r
8634                             winner = dd;\r
8635                         }\r
8636                     }\r
8637                 }\r
8638             }\r
8639 \r
8640             return winner;\r
8641         },\r
8642 \r
8643         \r
8644         refreshCache: function(groups) {\r
8645             for (var sGroup in groups) {\r
8646                 if ("string" != typeof sGroup) {\r
8647                     continue;\r
8648                 }\r
8649                 for (var i in this.ids[sGroup]) {\r
8650                     var oDD = this.ids[sGroup][i];\r
8651 \r
8652                     if (this.isTypeOfDD(oDD)) {\r
8653                     
8654                         var loc = this.getLocation(oDD);\r
8655                         if (loc) {\r
8656                             this.locationCache[oDD.id] = loc;\r
8657                         } else {\r
8658                             delete this.locationCache[oDD.id];\r
8659                             
8660                             
8661                             
8662                         }\r
8663                     }\r
8664                 }\r
8665             }\r
8666         },\r
8667 \r
8668         \r
8669         verifyEl: function(el) {\r
8670             if (el) {\r
8671                 var parent;\r
8672                 if(Ext.isIE){\r
8673                     try{\r
8674                         parent = el.offsetParent;\r
8675                     }catch(e){}\r
8676                 }else{\r
8677                     parent = el.offsetParent;\r
8678                 }\r
8679                 if (parent) {\r
8680                     return true;\r
8681                 }\r
8682             }\r
8683 \r
8684             return false;\r
8685         },\r
8686 \r
8687         \r
8688         getLocation: function(oDD) {\r
8689             if (! this.isTypeOfDD(oDD)) {\r
8690                 return null;\r
8691             }\r
8692 \r
8693             var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;\r
8694 \r
8695             try {\r
8696                 pos= Ext.lib.Dom.getXY(el);\r
8697             } catch (e) { }\r
8698 \r
8699             if (!pos) {\r
8700                 return null;\r
8701             }\r
8702 \r
8703             x1 = pos[0];\r
8704             x2 = x1 + el.offsetWidth;\r
8705             y1 = pos[1];\r
8706             y2 = y1 + el.offsetHeight;\r
8707 \r
8708             t = y1 - oDD.padding[0];\r
8709             r = x2 + oDD.padding[1];\r
8710             b = y2 + oDD.padding[2];\r
8711             l = x1 - oDD.padding[3];\r
8712 \r
8713             return new Ext.lib.Region( t, r, b, l );\r
8714         },\r
8715 \r
8716         \r
8717         isOverTarget: function(pt, oTarget, intersect) {\r
8718             
8719             var loc = this.locationCache[oTarget.id];\r
8720             if (!loc || !this.useCache) {\r
8721                 loc = this.getLocation(oTarget);\r
8722                 this.locationCache[oTarget.id] = loc;\r
8723 \r
8724             }\r
8725 \r
8726             if (!loc) {\r
8727                 return false;\r
8728             }\r
8729 \r
8730             oTarget.cursorIsOver = loc.contains( pt );\r
8731 \r
8732             
8733             
8734             
8735             
8736             
8737             var dc = this.dragCurrent;\r
8738             if (!dc || !dc.getTargetCoord ||\r
8739                     (!intersect && !dc.constrainX && !dc.constrainY)) {\r
8740                 return oTarget.cursorIsOver;\r
8741             }\r
8742 \r
8743             oTarget.overlap = null;\r
8744 \r
8745             
8746             
8747             
8748             
8749             var pos = dc.getTargetCoord(pt.x, pt.y);\r
8750 \r
8751             var el = dc.getDragEl();\r
8752             var curRegion = new Ext.lib.Region( pos.y,\r
8753                                                    pos.x + el.offsetWidth,\r
8754                                                    pos.y + el.offsetHeight,\r
8755                                                    pos.x );\r
8756 \r
8757             var overlap = curRegion.intersect(loc);\r
8758 \r
8759             if (overlap) {\r
8760                 oTarget.overlap = overlap;\r
8761                 return (intersect) ? true : oTarget.cursorIsOver;\r
8762             } else {\r
8763                 return false;\r
8764             }\r
8765         },\r
8766 \r
8767         \r
8768         _onUnload: function(e, me) {\r
8769             Ext.dd.DragDropMgr.unregAll();\r
8770         },\r
8771 \r
8772         \r
8773         unregAll: function() {\r
8774 \r
8775             if (this.dragCurrent) {\r
8776                 this.stopDrag();\r
8777                 this.dragCurrent = null;\r
8778             }\r
8779 \r
8780             this._execOnAll("unreg", []);\r
8781 \r
8782             for (var i in this.elementCache) {\r
8783                 delete this.elementCache[i];\r
8784             }\r
8785 \r
8786             this.elementCache = {};\r
8787             this.ids = {};\r
8788         },\r
8789 \r
8790         \r
8791         elementCache: {},\r
8792 \r
8793         \r
8794         getElWrapper: function(id) {\r
8795             var oWrapper = this.elementCache[id];\r
8796             if (!oWrapper || !oWrapper.el) {\r
8797                 oWrapper = this.elementCache[id] =\r
8798                     new this.ElementWrapper(Ext.getDom(id));\r
8799             }\r
8800             return oWrapper;\r
8801         },\r
8802 \r
8803         \r
8804         getElement: function(id) {\r
8805             return Ext.getDom(id);\r
8806         },\r
8807 \r
8808         \r
8809         getCss: function(id) {\r
8810             var el = Ext.getDom(id);\r
8811             return (el) ? el.style : null;\r
8812         },\r
8813 \r
8814         \r
8815         ElementWrapper: function(el) {\r
8816                 \r
8817                 this.el = el || null;\r
8818                 \r
8819                 this.id = this.el && el.id;\r
8820                 \r
8821                 this.css = this.el && el.style;\r
8822             },\r
8823 \r
8824         \r
8825         getPosX: function(el) {\r
8826             return Ext.lib.Dom.getX(el);\r
8827         },\r
8828 \r
8829         \r
8830         getPosY: function(el) {\r
8831             return Ext.lib.Dom.getY(el);\r
8832         },\r
8833 \r
8834         \r
8835         swapNode: function(n1, n2) {\r
8836             if (n1.swapNode) {\r
8837                 n1.swapNode(n2);\r
8838             } else {\r
8839                 var p = n2.parentNode;\r
8840                 var s = n2.nextSibling;\r
8841 \r
8842                 if (s == n1) {\r
8843                     p.insertBefore(n1, n2);\r
8844                 } else if (n2 == n1.nextSibling) {\r
8845                     p.insertBefore(n2, n1);\r
8846                 } else {\r
8847                     n1.parentNode.replaceChild(n2, n1);\r
8848                     p.insertBefore(n1, s);\r
8849                 }\r
8850             }\r
8851         },\r
8852 \r
8853         \r
8854         getScroll: function () {\r
8855             var t, l, dde=document.documentElement, db=document.body;\r
8856             if (dde && (dde.scrollTop || dde.scrollLeft)) {\r
8857                 t = dde.scrollTop;\r
8858                 l = dde.scrollLeft;\r
8859             } else if (db) {\r
8860                 t = db.scrollTop;\r
8861                 l = db.scrollLeft;\r
8862             } else {\r
8863 \r
8864             }\r
8865             return { top: t, left: l };\r
8866         },\r
8867 \r
8868         \r
8869         getStyle: function(el, styleProp) {\r
8870             return Ext.fly(el).getStyle(styleProp);\r
8871         },\r
8872 \r
8873         \r
8874         getScrollTop: function () { return this.getScroll().top; },\r
8875 \r
8876         \r
8877         getScrollLeft: function () { return this.getScroll().left; },\r
8878 \r
8879         \r
8880         moveToEl: function (moveEl, targetEl) {\r
8881             var aCoord = Ext.lib.Dom.getXY(targetEl);\r
8882             Ext.lib.Dom.setXY(moveEl, aCoord);\r
8883         },\r
8884 \r
8885         \r
8886         numericSort: function(a, b) { return (a - b); },\r
8887 \r
8888         \r
8889         _timeoutCount: 0,\r
8890 \r
8891         \r
8892         _addListeners: function() {\r
8893             var DDM = Ext.dd.DDM;\r
8894             if ( Ext.lib.Event && document ) {\r
8895                 DDM._onLoad();\r
8896             } else {\r
8897                 if (DDM._timeoutCount > 2000) {\r
8898                 } else {\r
8899                     setTimeout(DDM._addListeners, 10);\r
8900                     if (document && document.body) {\r
8901                         DDM._timeoutCount += 1;\r
8902                     }\r
8903                 }\r
8904             }\r
8905         },\r
8906 \r
8907         \r
8908         handleWasClicked: function(node, id) {\r
8909             if (this.isHandle(id, node.id)) {\r
8910                 return true;\r
8911             } else {\r
8912                 
8913                 var p = node.parentNode;\r
8914 \r
8915                 while (p) {\r
8916                     if (this.isHandle(id, p.id)) {\r
8917                         return true;\r
8918                     } else {\r
8919                         p = p.parentNode;\r
8920                     }\r
8921                 }\r
8922             }\r
8923 \r
8924             return false;\r
8925         }\r
8926 \r
8927     };\r
8928 \r
8929 }();\r
8930 \r
8931
8932 Ext.dd.DDM = Ext.dd.DragDropMgr;\r
8933 Ext.dd.DDM._addListeners();\r
8934 \r
8935 }\r
8936 \r
8937 \r
8938 Ext.dd.DD = function(id, sGroup, config) {\r
8939     if (id) {\r
8940         this.init(id, sGroup, config);\r
8941     }\r
8942 };\r
8943 \r
8944 Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {\r
8945 \r
8946     \r
8947     scroll: true,\r
8948 \r
8949     \r
8950     autoOffset: function(iPageX, iPageY) {\r
8951         var x = iPageX - this.startPageX;\r
8952         var y = iPageY - this.startPageY;\r
8953         this.setDelta(x, y);\r
8954     },\r
8955 \r
8956     \r
8957     setDelta: function(iDeltaX, iDeltaY) {\r
8958         this.deltaX = iDeltaX;\r
8959         this.deltaY = iDeltaY;\r
8960     },\r
8961 \r
8962     \r
8963     setDragElPos: function(iPageX, iPageY) {\r
8964         
8965         
8966 \r
8967         var el = this.getDragEl();\r
8968         this.alignElWithMouse(el, iPageX, iPageY);\r
8969     },\r
8970 \r
8971     \r
8972     alignElWithMouse: function(el, iPageX, iPageY) {\r
8973         var oCoord = this.getTargetCoord(iPageX, iPageY);\r
8974         var fly = el.dom ? el : Ext.fly(el, '_dd');\r
8975         if (!this.deltaSetXY) {\r
8976             var aCoord = [oCoord.x, oCoord.y];\r
8977             fly.setXY(aCoord);\r
8978             var newLeft = fly.getLeft(true);\r
8979             var newTop  = fly.getTop(true);\r
8980             this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];\r
8981         } else {\r
8982             fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);\r
8983         }\r
8984 \r
8985         this.cachePosition(oCoord.x, oCoord.y);\r
8986         this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);\r
8987         return oCoord;\r
8988     },\r
8989 \r
8990     \r
8991     cachePosition: function(iPageX, iPageY) {\r
8992         if (iPageX) {\r
8993             this.lastPageX = iPageX;\r
8994             this.lastPageY = iPageY;\r
8995         } else {\r
8996             var aCoord = Ext.lib.Dom.getXY(this.getEl());\r
8997             this.lastPageX = aCoord[0];\r
8998             this.lastPageY = aCoord[1];\r
8999         }\r
9000     },\r
9001 \r
9002     \r
9003     autoScroll: function(x, y, h, w) {\r
9004 \r
9005         if (this.scroll) {\r
9006             
9007             var clientH = Ext.lib.Dom.getViewHeight();\r
9008 \r
9009             
9010             var clientW = Ext.lib.Dom.getViewWidth();\r
9011 \r
9012             
9013             var st = this.DDM.getScrollTop();\r
9014 \r
9015             
9016             var sl = this.DDM.getScrollLeft();\r
9017 \r
9018             
9019             var bot = h + y;\r
9020 \r
9021             
9022             var right = w + x;\r
9023 \r
9024             
9025             
9026             
9027             var toBot = (clientH + st - y - this.deltaY);\r
9028 \r
9029             
9030             var toRight = (clientW + sl - x - this.deltaX);\r
9031 \r
9032 \r
9033             
9034             
9035             var thresh = 40;\r
9036 \r
9037             
9038             
9039             
9040             var scrAmt = (document.all) ? 80 : 30;\r
9041 \r
9042             
9043             
9044             if ( bot > clientH && toBot < thresh ) {\r
9045                 window.scrollTo(sl, st + scrAmt);\r
9046             }\r
9047 \r
9048             
9049             
9050             if ( y < st && st > 0 && y - st < thresh ) {\r
9051                 window.scrollTo(sl, st - scrAmt);\r
9052             }\r
9053 \r
9054             
9055             
9056             if ( right > clientW && toRight < thresh ) {\r
9057                 window.scrollTo(sl + scrAmt, st);\r
9058             }\r
9059 \r
9060             
9061             
9062             if ( x < sl && sl > 0 && x - sl < thresh ) {\r
9063                 window.scrollTo(sl - scrAmt, st);\r
9064             }\r
9065         }\r
9066     },\r
9067 \r
9068     \r
9069     getTargetCoord: function(iPageX, iPageY) {\r
9070 \r
9071 \r
9072         var x = iPageX - this.deltaX;\r
9073         var y = iPageY - this.deltaY;\r
9074 \r
9075         if (this.constrainX) {\r
9076             if (x < this.minX) { x = this.minX; }\r
9077             if (x > this.maxX) { x = this.maxX; }\r
9078         }\r
9079 \r
9080         if (this.constrainY) {\r
9081             if (y < this.minY) { y = this.minY; }\r
9082             if (y > this.maxY) { y = this.maxY; }\r
9083         }\r
9084 \r
9085         x = this.getTick(x, this.xTicks);\r
9086         y = this.getTick(y, this.yTicks);\r
9087 \r
9088 \r
9089         return {x:x, y:y};\r
9090     },\r
9091 \r
9092     \r
9093     applyConfig: function() {\r
9094         Ext.dd.DD.superclass.applyConfig.call(this);\r
9095         this.scroll = (this.config.scroll !== false);\r
9096     },\r
9097 \r
9098     \r
9099     b4MouseDown: function(e) {\r
9100         
9101         this.autoOffset(e.getPageX(),\r
9102                             e.getPageY());\r
9103     },\r
9104 \r
9105     \r
9106     b4Drag: function(e) {\r
9107         this.setDragElPos(e.getPageX(),\r
9108                             e.getPageY());\r
9109     },\r
9110 \r
9111     toString: function() {\r
9112         return ("DD " + this.id);\r
9113     }\r
9114 \r
9115     
9116     
9117     
9118     \r
9119 \r
9120 });\r
9121 \r
9122 Ext.dd.DDProxy = function(id, sGroup, config) {\r
9123     if (id) {\r
9124         this.init(id, sGroup, config);\r
9125         this.initFrame();\r
9126     }\r
9127 };\r
9128 \r
9129 \r
9130 Ext.dd.DDProxy.dragElId = "ygddfdiv";\r
9131 \r
9132 Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {\r
9133 \r
9134     \r
9135     resizeFrame: true,\r
9136 \r
9137     \r
9138     centerFrame: false,\r
9139 \r
9140     \r
9141     createFrame: function() {\r
9142         var self = this;\r
9143         var body = document.body;\r
9144 \r
9145         if (!body || !body.firstChild) {\r
9146             setTimeout( function() { self.createFrame(); }, 50 );\r
9147             return;\r
9148         }\r
9149 \r
9150         var div = this.getDragEl();\r
9151 \r
9152         if (!div) {\r
9153             div    = document.createElement("div");\r
9154             div.id = this.dragElId;\r
9155             var s  = div.style;\r
9156 \r
9157             s.position   = "absolute";\r
9158             s.visibility = "hidden";\r
9159             s.cursor     = "move";\r
9160             s.border     = "2px solid #aaa";\r
9161             s.zIndex     = 999;\r
9162 \r
9163             
9164             
9165             
9166             body.insertBefore(div, body.firstChild);\r
9167         }\r
9168     },\r
9169 \r
9170     \r
9171     initFrame: function() {\r
9172         this.createFrame();\r
9173     },\r
9174 \r
9175     applyConfig: function() {\r
9176         Ext.dd.DDProxy.superclass.applyConfig.call(this);\r
9177 \r
9178         this.resizeFrame = (this.config.resizeFrame !== false);\r
9179         this.centerFrame = (this.config.centerFrame);\r
9180         this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);\r
9181     },\r
9182 \r
9183     \r
9184     showFrame: function(iPageX, iPageY) {\r
9185         var el = this.getEl();\r
9186         var dragEl = this.getDragEl();\r
9187         var s = dragEl.style;\r
9188 \r
9189         this._resizeProxy();\r
9190 \r
9191         if (this.centerFrame) {\r
9192             this.setDelta( Math.round(parseInt(s.width,  10)/2),\r
9193                            Math.round(parseInt(s.height, 10)/2) );\r
9194         }\r
9195 \r
9196         this.setDragElPos(iPageX, iPageY);\r
9197 \r
9198         Ext.fly(dragEl).show();\r
9199     },\r
9200 \r
9201     \r
9202     _resizeProxy: function() {\r
9203         if (this.resizeFrame) {\r
9204             var el = this.getEl();\r
9205             Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);\r
9206         }\r
9207     },\r
9208 \r
9209     
9210     b4MouseDown: function(e) {\r
9211         var x = e.getPageX();\r
9212         var y = e.getPageY();\r
9213         this.autoOffset(x, y);\r
9214         this.setDragElPos(x, y);\r
9215     },\r
9216 \r
9217     
9218     b4StartDrag: function(x, y) {\r
9219         
9220         this.showFrame(x, y);\r
9221     },\r
9222 \r
9223     
9224     b4EndDrag: function(e) {\r
9225         Ext.fly(this.getDragEl()).hide();\r
9226     },\r
9227 \r
9228     
9229     
9230     
9231     endDrag: function(e) {\r
9232 \r
9233         var lel = this.getEl();\r
9234         var del = this.getDragEl();\r
9235 \r
9236         
9237         del.style.visibility = "";\r
9238 \r
9239         this.beforeMove();\r
9240         
9241         
9242         lel.style.visibility = "hidden";\r
9243         Ext.dd.DDM.moveToEl(lel, del);\r
9244         del.style.visibility = "hidden";\r
9245         lel.style.visibility = "";\r
9246 \r
9247         this.afterDrag();\r
9248     },\r
9249 \r
9250     beforeMove : function(){\r
9251 \r
9252     },\r
9253 \r
9254     afterDrag : function(){\r
9255 \r
9256     },\r
9257 \r
9258     toString: function() {\r
9259         return ("DDProxy " + this.id);\r
9260     }\r
9261 \r
9262 });\r
9263 \r
9264 Ext.dd.DDTarget = function(id, sGroup, config) {\r
9265     if (id) {\r
9266         this.initTarget(id, sGroup, config);\r
9267     }\r
9268 };\r
9269 \r
9270
9271 Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {\r
9272     toString: function() {\r
9273         return ("DDTarget " + this.id);\r
9274     }\r
9275 });\r
9276
9277 Ext.dd.DragTracker = function(config){\r
9278     Ext.apply(this, config);\r
9279     this.addEvents(\r
9280         'mousedown',\r
9281         'mouseup',\r
9282         'mousemove',\r
9283         'dragstart',\r
9284         'dragend',\r
9285         'drag'\r
9286     );\r
9287 \r
9288     this.dragRegion = new Ext.lib.Region(0,0,0,0);\r
9289 \r
9290     if(this.el){\r
9291         this.initEl(this.el);\r
9292     }\r
9293 }\r
9294 \r
9295 Ext.extend(Ext.dd.DragTracker, Ext.util.Observable,  {\r
9296     active: false,\r
9297     tolerance: 5,\r
9298     autoStart: false,\r
9299 \r
9300     initEl: function(el){\r
9301         this.el = Ext.get(el);\r
9302         el.on('mousedown', this.onMouseDown, this,\r
9303                 this.delegate ? {delegate: this.delegate} : undefined);\r
9304     },\r
9305 \r
9306     destroy : function(){\r
9307         this.el.un('mousedown', this.onMouseDown, this);\r
9308     },\r
9309 \r
9310     onMouseDown: function(e, target){\r
9311         if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){\r
9312             this.startXY = this.lastXY = e.getXY();\r
9313             this.dragTarget = this.delegate ? target : this.el.dom;\r
9314             e.preventDefault();\r
9315             var doc = Ext.getDoc();\r
9316             doc.on('mouseup', this.onMouseUp, this);\r
9317             doc.on('mousemove', this.onMouseMove, this);\r
9318             doc.on('selectstart', this.stopSelect, this);\r
9319             if(this.autoStart){\r
9320                 this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this);\r
9321             }\r
9322         }\r
9323     },\r
9324 \r
9325     onMouseMove: function(e, target){\r
9326         e.preventDefault();\r
9327         var xy = e.getXY(), s = this.startXY;\r
9328         this.lastXY = xy;\r
9329         if(!this.active){\r
9330             if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){\r
9331                 this.triggerStart();\r
9332             }else{\r
9333                 return;\r
9334             }\r
9335         }\r
9336         this.fireEvent('mousemove', this, e);\r
9337         this.onDrag(e);\r
9338         this.fireEvent('drag', this, e);\r
9339     },\r
9340 \r
9341     onMouseUp: function(e){\r
9342         var doc = Ext.getDoc();\r
9343         doc.un('mousemove', this.onMouseMove, this);\r
9344         doc.un('mouseup', this.onMouseUp, this);\r
9345         doc.un('selectstart', this.stopSelect, this);\r
9346         e.preventDefault();\r
9347         this.clearStart();\r
9348         this.active = false;\r
9349         delete this.elRegion;\r
9350         this.fireEvent('mouseup', this, e);\r
9351         this.onEnd(e);\r
9352         this.fireEvent('dragend', this, e);\r
9353     },\r
9354 \r
9355     triggerStart: function(isTimer){\r
9356         this.clearStart();\r
9357         this.active = true;\r
9358         this.onStart(this.startXY);\r
9359         this.fireEvent('dragstart', this, this.startXY);\r
9360     },\r
9361 \r
9362     clearStart : function(){\r
9363         if(this.timer){\r
9364             clearTimeout(this.timer);\r
9365             delete this.timer;\r
9366         }\r
9367     },\r
9368 \r
9369     stopSelect : function(e){\r
9370         e.stopEvent();\r
9371         return false;\r
9372     },\r
9373 \r
9374     onBeforeStart : function(e){\r
9375 \r
9376     },\r
9377 \r
9378     onStart : function(xy){\r
9379 \r
9380     },\r
9381 \r
9382     onDrag : function(e){\r
9383 \r
9384     },\r
9385 \r
9386     onEnd : function(e){\r
9387 \r
9388     },\r
9389 \r
9390     getDragTarget : function(){\r
9391         return this.dragTarget;\r
9392     },\r
9393 \r
9394     getDragCt : function(){\r
9395         return this.el;\r
9396     },\r
9397 \r
9398     getXY : function(constrain){\r
9399         return constrain ?\r
9400                this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;\r
9401     },\r
9402 \r
9403     getOffset : function(constrain){\r
9404         var xy = this.getXY(constrain);\r
9405         var s = this.startXY;\r
9406         return [s[0]-xy[0], s[1]-xy[1]];\r
9407     },\r
9408 \r
9409     constrainModes: {\r
9410         'point' : function(xy){\r
9411 \r
9412             if(!this.elRegion){\r
9413                 this.elRegion = this.getDragCt().getRegion();\r
9414             }\r
9415 \r
9416             var dr = this.dragRegion;\r
9417 \r
9418             dr.left = xy[0];\r
9419             dr.top = xy[1];\r
9420             dr.right = xy[0];\r
9421             dr.bottom = xy[1];\r
9422 \r
9423             dr.constrainTo(this.elRegion);\r
9424 \r
9425             return [dr.left, dr.top];\r
9426         }\r
9427     }\r
9428 });
9429 \r
9430 Ext.dd.ScrollManager = function(){\r
9431     var ddm = Ext.dd.DragDropMgr;\r
9432     var els = {};\r
9433     var dragEl = null;\r
9434     var proc = {};\r
9435     \r
9436     var onStop = function(e){\r
9437         dragEl = null;\r
9438         clearProc();\r
9439     };\r
9440     \r
9441     var triggerRefresh = function(){\r
9442         if(ddm.dragCurrent){\r
9443              ddm.refreshCache(ddm.dragCurrent.groups);\r
9444         }\r
9445     };\r
9446     \r
9447     var doScroll = function(){\r
9448         if(ddm.dragCurrent){\r
9449             var dds = Ext.dd.ScrollManager;\r
9450             var inc = proc.el.ddScrollConfig ?\r
9451                       proc.el.ddScrollConfig.increment : dds.increment;\r
9452             if(!dds.animate){\r
9453                 if(proc.el.scroll(proc.dir, inc)){\r
9454                     triggerRefresh();\r
9455                 }\r
9456             }else{\r
9457                 proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);\r
9458             }\r
9459         }\r
9460     };\r
9461     \r
9462     var clearProc = function(){\r
9463         if(proc.id){\r
9464             clearInterval(proc.id);\r
9465         }\r
9466         proc.id = 0;\r
9467         proc.el = null;\r
9468         proc.dir = "";\r
9469     };\r
9470     \r
9471     var startProc = function(el, dir){\r
9472         clearProc();\r
9473         proc.el = el;\r
9474         proc.dir = dir;\r
9475         proc.id = setInterval(doScroll, Ext.dd.ScrollManager.frequency);\r
9476     };\r
9477     \r
9478     var onFire = function(e, isDrop){\r
9479         if(isDrop || !ddm.dragCurrent){ return; }\r
9480         var dds = Ext.dd.ScrollManager;\r
9481         if(!dragEl || dragEl != ddm.dragCurrent){\r
9482             dragEl = ddm.dragCurrent;\r
9483             
9484             dds.refreshCache();\r
9485         }\r
9486         \r
9487         var xy = Ext.lib.Event.getXY(e);\r
9488         var pt = new Ext.lib.Point(xy[0], xy[1]);\r
9489         for(var id in els){\r
9490             var el = els[id], r = el._region;\r
9491             var c = el.ddScrollConfig ? el.ddScrollConfig : dds;\r
9492             if(r && r.contains(pt) && el.isScrollable()){\r
9493                 if(r.bottom - pt.y <= c.vthresh){\r
9494                     if(proc.el != el){\r
9495                         startProc(el, "down");\r
9496                     }\r
9497                     return;\r
9498                 }else if(r.right - pt.x <= c.hthresh){\r
9499                     if(proc.el != el){\r
9500                         startProc(el, "left");\r
9501                     }\r
9502                     return;\r
9503                 }else if(pt.y - r.top <= c.vthresh){\r
9504                     if(proc.el != el){\r
9505                         startProc(el, "up");\r
9506                     }\r
9507                     return;\r
9508                 }else if(pt.x - r.left <= c.hthresh){\r
9509                     if(proc.el != el){\r
9510                         startProc(el, "right");\r
9511                     }\r
9512                     return;\r
9513                 }\r
9514             }\r
9515         }\r
9516         clearProc();\r
9517     };\r
9518     \r
9519     ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);\r
9520     ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);\r
9521     \r
9522     return {\r
9523         \r
9524         register : function(el){\r
9525             if(Ext.isArray(el)){\r
9526                 for(var i = 0, len = el.length; i < len; i++) {\r
9527                         this.register(el[i]);\r
9528                 }\r
9529             }else{\r
9530                 el = Ext.get(el);\r
9531                 els[el.id] = el;\r
9532             }\r
9533         },\r
9534         \r
9535         \r
9536         unregister : function(el){\r
9537             if(Ext.isArray(el)){\r
9538                 for(var i = 0, len = el.length; i < len; i++) {\r
9539                         this.unregister(el[i]);\r
9540                 }\r
9541             }else{\r
9542                 el = Ext.get(el);\r
9543                 delete els[el.id];\r
9544             }\r
9545         },\r
9546         \r
9547         \r
9548         vthresh : 25,\r
9549         \r
9550         hthresh : 25,\r
9551 \r
9552         \r
9553         increment : 100,\r
9554         \r
9555         \r
9556         frequency : 500,\r
9557         \r
9558         \r
9559         animate: true,\r
9560         \r
9561         \r
9562         animDuration: .4,\r
9563         \r
9564         \r
9565         refreshCache : function(){\r
9566             for(var id in els){\r
9567                 if(typeof els[id] == 'object'){ 
9568                     els[id]._region = els[id].getRegion();\r
9569                 }\r
9570             }\r
9571         }\r
9572     };\r
9573 }();
9574 \r
9575 Ext.dd.Registry = function(){\r
9576     var elements = {}; \r
9577     var handles = {}; \r
9578     var autoIdSeed = 0;\r
9579 \r
9580     var getId = function(el, autogen){\r
9581         if(typeof el == "string"){\r
9582             return el;\r
9583         }\r
9584         var id = el.id;\r
9585         if(!id && autogen !== false){\r
9586             id = "extdd-" + (++autoIdSeed);\r
9587             el.id = id;\r
9588         }\r
9589         return id;\r
9590     };\r
9591     \r
9592     return {\r
9593     \r
9594         register : function(el, data){\r
9595             data = data || {};\r
9596             if(typeof el == "string"){\r
9597                 el = document.getElementById(el);\r
9598             }\r
9599             data.ddel = el;\r
9600             elements[getId(el)] = data;\r
9601             if(data.isHandle !== false){\r
9602                 handles[data.ddel.id] = data;\r
9603             }\r
9604             if(data.handles){\r
9605                 var hs = data.handles;\r
9606                 for(var i = 0, len = hs.length; i < len; i++){\r
9607                         handles[getId(hs[i])] = data;\r
9608                 }\r
9609             }\r
9610         },\r
9611 \r
9612     \r
9613         unregister : function(el){\r
9614             var id = getId(el, false);\r
9615             var data = elements[id];\r
9616             if(data){\r
9617                 delete elements[id];\r
9618                 if(data.handles){\r
9619                     var hs = data.handles;\r
9620                     for(var i = 0, len = hs.length; i < len; i++){\r
9621                         delete handles[getId(hs[i], false)];\r
9622                     }\r
9623                 }\r
9624             }\r
9625         },\r
9626 \r
9627     \r
9628         getHandle : function(id){\r
9629             if(typeof id != "string"){ 
9630                 id = id.id;\r
9631             }\r
9632             return handles[id];\r
9633         },\r
9634 \r
9635     \r
9636         getHandleFromEvent : function(e){\r
9637             var t = Ext.lib.Event.getTarget(e);\r
9638             return t ? handles[t.id] : null;\r
9639         },\r
9640 \r
9641     \r
9642         getTarget : function(id){\r
9643             if(typeof id != "string"){ 
9644                 id = id.id;\r
9645             }\r
9646             return elements[id];\r
9647         },\r
9648 \r
9649     \r
9650         getTargetFromEvent : function(e){\r
9651             var t = Ext.lib.Event.getTarget(e);\r
9652             return t ? elements[t.id] || handles[t.id] : null;\r
9653         }\r
9654     };\r
9655 }();
9656 \r
9657 Ext.dd.StatusProxy = function(config){\r
9658     Ext.apply(this, config);\r
9659     this.id = this.id || Ext.id();\r
9660     this.el = new Ext.Layer({\r
9661         dh: {\r
9662             id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [\r
9663                 {tag: "div", cls: "x-dd-drop-icon"},\r
9664                 {tag: "div", cls: "x-dd-drag-ghost"}\r
9665             ]\r
9666         }, \r
9667         shadow: !config || config.shadow !== false\r
9668     });\r
9669     this.ghost = Ext.get(this.el.dom.childNodes[1]);\r
9670     this.dropStatus = this.dropNotAllowed;\r
9671 };\r
9672 \r
9673 Ext.dd.StatusProxy.prototype = {\r
9674     \r
9675     dropAllowed : "x-dd-drop-ok",\r
9676     \r
9677     dropNotAllowed : "x-dd-drop-nodrop",\r
9678 \r
9679     \r
9680     setStatus : function(cssClass){\r
9681         cssClass = cssClass || this.dropNotAllowed;\r
9682         if(this.dropStatus != cssClass){\r
9683             this.el.replaceClass(this.dropStatus, cssClass);\r
9684             this.dropStatus = cssClass;\r
9685         }\r
9686     },\r
9687 \r
9688     \r
9689     reset : function(clearGhost){\r
9690         this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;\r
9691         this.dropStatus = this.dropNotAllowed;\r
9692         if(clearGhost){\r
9693             this.ghost.update("");\r
9694         }\r
9695     },\r
9696 \r
9697     \r
9698     update : function(html){\r
9699         if(typeof html == "string"){\r
9700             this.ghost.update(html);\r
9701         }else{\r
9702             this.ghost.update("");\r
9703             html.style.margin = "0";\r
9704             this.ghost.dom.appendChild(html);\r
9705         }        \r
9706     },\r
9707 \r
9708     \r
9709     getEl : function(){\r
9710         return this.el;\r
9711     },\r
9712 \r
9713     \r
9714     getGhost : function(){\r
9715         return this.ghost;\r
9716     },\r
9717 \r
9718     \r
9719     hide : function(clear){\r
9720         this.el.hide();\r
9721         if(clear){\r
9722             this.reset(true);\r
9723         }\r
9724     },\r
9725 \r
9726     \r
9727     stop : function(){\r
9728         if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){\r
9729             this.anim.stop();\r
9730         }\r
9731     },\r
9732 \r
9733     \r
9734     show : function(){\r
9735         this.el.show();\r
9736     },\r
9737 \r
9738     \r
9739     sync : function(){\r
9740         this.el.sync();\r
9741     },\r
9742 \r
9743     \r
9744     repair : function(xy, callback, scope){\r
9745         this.callback = callback;\r
9746         this.scope = scope;\r
9747         if(xy && this.animRepair !== false){\r
9748             this.el.addClass("x-dd-drag-repair");\r
9749             this.el.hideUnders(true);\r
9750             this.anim = this.el.shift({\r
9751                 duration: this.repairDuration || .5,\r
9752                 easing: 'easeOut',\r
9753                 xy: xy,\r
9754                 stopFx: true,\r
9755                 callback: this.afterRepair,\r
9756                 scope: this\r
9757             });\r
9758         }else{\r
9759             this.afterRepair();\r
9760         }\r
9761     },\r
9762 \r
9763     
9764     afterRepair : function(){\r
9765         this.hide(true);\r
9766         if(typeof this.callback == "function"){\r
9767             this.callback.call(this.scope || this);\r
9768         }\r
9769         this.callback = null;\r
9770         this.scope = null;\r
9771     }\r
9772 };
9773 \r
9774 Ext.dd.DragSource = function(el, config){\r
9775     this.el = Ext.get(el);\r
9776     if(!this.dragData){\r
9777         this.dragData = {};\r
9778     }\r
9779     \r
9780     Ext.apply(this, config);\r
9781     \r
9782     if(!this.proxy){\r
9783         this.proxy = new Ext.dd.StatusProxy();\r
9784     }\r
9785     Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, \r
9786           {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});\r
9787     \r
9788     this.dragging = false;\r
9789 };\r
9790 \r
9791 Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {\r
9792     \r
9793     \r
9794     dropAllowed : "x-dd-drop-ok",\r
9795     \r
9796     dropNotAllowed : "x-dd-drop-nodrop",\r
9797 \r
9798     \r
9799     getDragData : function(e){\r
9800         return this.dragData;\r
9801     },\r
9802 \r
9803     
9804     onDragEnter : function(e, id){\r
9805         var target = Ext.dd.DragDropMgr.getDDById(id);\r
9806         this.cachedTarget = target;\r
9807         if(this.beforeDragEnter(target, e, id) !== false){\r
9808             if(target.isNotifyTarget){\r
9809                 var status = target.notifyEnter(this, e, this.dragData);\r
9810                 this.proxy.setStatus(status);\r
9811             }else{\r
9812                 this.proxy.setStatus(this.dropAllowed);\r
9813             }\r
9814             \r
9815             if(this.afterDragEnter){\r
9816                 \r
9817                 this.afterDragEnter(target, e, id);\r
9818             }\r
9819         }\r
9820     },\r
9821 \r
9822     \r
9823     beforeDragEnter : function(target, e, id){\r
9824         return true;\r
9825     },\r
9826 \r
9827     
9828     alignElWithMouse: function() {\r
9829         Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);\r
9830         this.proxy.sync();\r
9831     },\r
9832 \r
9833     
9834     onDragOver : function(e, id){\r
9835         var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);\r
9836         if(this.beforeDragOver(target, e, id) !== false){\r
9837             if(target.isNotifyTarget){\r
9838                 var status = target.notifyOver(this, e, this.dragData);\r
9839                 this.proxy.setStatus(status);\r
9840             }\r
9841 \r
9842             if(this.afterDragOver){\r
9843                 \r
9844                 this.afterDragOver(target, e, id);\r
9845             }\r
9846         }\r
9847     },\r
9848 \r
9849     \r
9850     beforeDragOver : function(target, e, id){\r
9851         return true;\r
9852     },\r
9853 \r
9854     
9855     onDragOut : function(e, id){\r
9856         var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);\r
9857         if(this.beforeDragOut(target, e, id) !== false){\r
9858             if(target.isNotifyTarget){\r
9859                 target.notifyOut(this, e, this.dragData);\r
9860             }\r
9861             this.proxy.reset();\r
9862             if(this.afterDragOut){\r
9863                 \r
9864                 this.afterDragOut(target, e, id);\r
9865             }\r
9866         }\r
9867         this.cachedTarget = null;\r
9868     },\r
9869 \r
9870     \r
9871     beforeDragOut : function(target, e, id){\r
9872         return true;\r
9873     },\r
9874     \r
9875     
9876     onDragDrop : function(e, id){\r
9877         var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);\r
9878         if(this.beforeDragDrop(target, e, id) !== false){\r
9879             if(target.isNotifyTarget){\r
9880                 if(target.notifyDrop(this, e, this.dragData)){ 
9881                     this.onValidDrop(target, e, id);\r
9882                 }else{\r
9883                     this.onInvalidDrop(target, e, id);\r
9884                 }\r
9885             }else{\r
9886                 this.onValidDrop(target, e, id);\r
9887             }\r
9888             \r
9889             if(this.afterDragDrop){\r
9890                 \r
9891                 this.afterDragDrop(target, e, id);\r
9892             }\r
9893         }\r
9894         delete this.cachedTarget;\r
9895     },\r
9896 \r
9897     \r
9898     beforeDragDrop : function(target, e, id){\r
9899         return true;\r
9900     },\r
9901 \r
9902     
9903     onValidDrop : function(target, e, id){\r
9904         this.hideProxy();\r
9905         if(this.afterValidDrop){\r
9906             \r
9907             this.afterValidDrop(target, e, id);\r
9908         }\r
9909     },\r
9910 \r
9911     
9912     getRepairXY : function(e, data){\r
9913         return this.el.getXY();  \r
9914     },\r
9915 \r
9916     
9917     onInvalidDrop : function(target, e, id){\r
9918         this.beforeInvalidDrop(target, e, id);\r
9919         if(this.cachedTarget){\r
9920             if(this.cachedTarget.isNotifyTarget){\r
9921                 this.cachedTarget.notifyOut(this, e, this.dragData);\r
9922             }\r
9923             this.cacheTarget = null;\r
9924         }\r
9925         this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);\r
9926 \r
9927         if(this.afterInvalidDrop){\r
9928             \r
9929             this.afterInvalidDrop(e, id);\r
9930         }\r
9931     },\r
9932 \r
9933     
9934     afterRepair : function(){\r
9935         if(Ext.enableFx){\r
9936             this.el.highlight(this.hlColor || "c3daf9");\r
9937         }\r
9938         this.dragging = false;\r
9939     },\r
9940 \r
9941     \r
9942     beforeInvalidDrop : function(target, e, id){\r
9943         return true;\r
9944     },\r
9945 \r
9946     
9947     handleMouseDown : function(e){\r
9948         if(this.dragging) {\r
9949             return;\r
9950         }\r
9951         var data = this.getDragData(e);\r
9952         if(data && this.onBeforeDrag(data, e) !== false){\r
9953             this.dragData = data;\r
9954             this.proxy.stop();\r
9955             Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);\r
9956         } \r
9957     },\r
9958 \r
9959     \r
9960     onBeforeDrag : function(data, e){\r
9961         return true;\r
9962     },\r
9963 \r
9964     \r
9965     onStartDrag : Ext.emptyFn,\r
9966 \r
9967     
9968     startDrag : function(x, y){\r
9969         this.proxy.reset();\r
9970         this.dragging = true;\r
9971         this.proxy.update("");\r
9972         this.onInitDrag(x, y);\r
9973         this.proxy.show();\r
9974     },\r
9975 \r
9976     
9977     onInitDrag : function(x, y){\r
9978         var clone = this.el.dom.cloneNode(true);\r
9979         clone.id = Ext.id(); 
9980         this.proxy.update(clone);\r
9981         this.onStartDrag(x, y);\r
9982         return true;\r
9983     },\r
9984 \r
9985     \r
9986     getProxy : function(){\r
9987         return this.proxy;  \r
9988     },\r
9989 \r
9990     \r
9991     hideProxy : function(){\r
9992         this.proxy.hide();  \r
9993         this.proxy.reset(true);\r
9994         this.dragging = false;\r
9995     },\r
9996 \r
9997     
9998     triggerCacheRefresh : function(){\r
9999         Ext.dd.DDM.refreshCache(this.groups);\r
10000     },\r
10001 \r
10002     
10003     b4EndDrag: function(e) {\r
10004     },\r
10005 \r
10006     
10007     endDrag : function(e){\r
10008         this.onEndDrag(this.dragData, e);\r
10009     },\r
10010 \r
10011     
10012     onEndDrag : function(data, e){\r
10013     },\r
10014     \r
10015     
10016     autoOffset : function(x, y) {\r
10017         this.setDelta(-12, -20);\r
10018     }    \r
10019 });
10020 \r
10021 Ext.dd.DropTarget = function(el, config){\r
10022     this.el = Ext.get(el);\r
10023     \r
10024     Ext.apply(this, config);\r
10025     \r
10026     if(this.containerScroll){\r
10027         Ext.dd.ScrollManager.register(this.el);\r
10028     }\r
10029     \r
10030     Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, \r
10031           {isTarget: true});\r
10032 \r
10033 };\r
10034 \r
10035 Ext.extend(Ext.dd.DropTarget, Ext.dd.DDTarget, {\r
10036     \r
10037     \r
10038     \r
10039     dropAllowed : "x-dd-drop-ok",\r
10040     \r
10041     dropNotAllowed : "x-dd-drop-nodrop",\r
10042 \r
10043     
10044     isTarget : true,\r
10045 \r
10046     
10047     isNotifyTarget : true,\r
10048 \r
10049     \r
10050     notifyEnter : function(dd, e, data){\r
10051         if(this.overClass){\r
10052             this.el.addClass(this.overClass);\r
10053         }\r
10054         return this.dropAllowed;\r
10055     },\r
10056 \r
10057     \r
10058     notifyOver : function(dd, e, data){\r
10059         return this.dropAllowed;\r
10060     },\r
10061 \r
10062     \r
10063     notifyOut : function(dd, e, data){\r
10064         if(this.overClass){\r
10065             this.el.removeClass(this.overClass);\r
10066         }\r
10067     },\r
10068 \r
10069     \r
10070     notifyDrop : function(dd, e, data){\r
10071         return false;\r
10072     }\r
10073 });
10074 \r
10075 Ext.dd.DragZone = function(el, config){\r
10076     Ext.dd.DragZone.superclass.constructor.call(this, el, config);\r
10077     if(this.containerScroll){\r
10078         Ext.dd.ScrollManager.register(this.el);\r
10079     }\r
10080 };\r
10081 \r
10082 Ext.extend(Ext.dd.DragZone, Ext.dd.DragSource, {\r
10083     \r
10084     \r
10085 \r
10086     \r
10087     getDragData : function(e){\r
10088         return Ext.dd.Registry.getHandleFromEvent(e);\r
10089     },\r
10090     \r
10091     \r
10092     onInitDrag : function(x, y){\r
10093         this.proxy.update(this.dragData.ddel.cloneNode(true));\r
10094         this.onStartDrag(x, y);\r
10095         return true;\r
10096     },\r
10097     \r
10098     \r
10099     afterRepair : function(){\r
10100         if(Ext.enableFx){\r
10101             Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");\r
10102         }\r
10103         this.dragging = false;\r
10104     },\r
10105 \r
10106     \r
10107     getRepairXY : function(e){\r
10108         return Ext.Element.fly(this.dragData.ddel).getXY();  \r
10109     }\r
10110 });
10111 \r
10112 Ext.dd.DropZone = function(el, config){\r
10113     Ext.dd.DropZone.superclass.constructor.call(this, el, config);\r
10114 };\r
10115 \r
10116 Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {\r
10117     \r
10118     getTargetFromEvent : function(e){\r
10119         return Ext.dd.Registry.getTargetFromEvent(e);\r
10120     },\r
10121 \r
10122     \r
10123     onNodeEnter : function(n, dd, e, data){\r
10124         \r
10125     },\r
10126 \r
10127     \r
10128     onNodeOver : function(n, dd, e, data){\r
10129         return this.dropAllowed;\r
10130     },\r
10131 \r
10132     \r
10133     onNodeOut : function(n, dd, e, data){\r
10134         \r
10135     },\r
10136 \r
10137     \r
10138     onNodeDrop : function(n, dd, e, data){\r
10139         return false;\r
10140     },\r
10141 \r
10142     \r
10143     onContainerOver : function(dd, e, data){\r
10144         return this.dropNotAllowed;\r
10145     },\r
10146 \r
10147     \r
10148     onContainerDrop : function(dd, e, data){\r
10149         return false;\r
10150     },\r
10151 \r
10152     \r
10153     notifyEnter : function(dd, e, data){\r
10154         return this.dropNotAllowed;\r
10155     },\r
10156 \r
10157     \r
10158     notifyOver : function(dd, e, data){\r
10159         var n = this.getTargetFromEvent(e);\r
10160         if(!n){ 
10161             if(this.lastOverNode){\r
10162                 this.onNodeOut(this.lastOverNode, dd, e, data);\r
10163                 this.lastOverNode = null;\r
10164             }\r
10165             return this.onContainerOver(dd, e, data);\r
10166         }\r
10167         if(this.lastOverNode != n){\r
10168             if(this.lastOverNode){\r
10169                 this.onNodeOut(this.lastOverNode, dd, e, data);\r
10170             }\r
10171             this.onNodeEnter(n, dd, e, data);\r
10172             this.lastOverNode = n;\r
10173         }\r
10174         return this.onNodeOver(n, dd, e, data);\r
10175     },\r
10176 \r
10177     \r
10178     notifyOut : function(dd, e, data){\r
10179         if(this.lastOverNode){\r
10180             this.onNodeOut(this.lastOverNode, dd, e, data);\r
10181             this.lastOverNode = null;\r
10182         }\r
10183     },\r
10184 \r
10185     \r
10186     notifyDrop : function(dd, e, data){\r
10187         if(this.lastOverNode){\r
10188             this.onNodeOut(this.lastOverNode, dd, e, data);\r
10189             this.lastOverNode = null;\r
10190         }\r
10191         var n = this.getTargetFromEvent(e);\r
10192         return n ?\r
10193             this.onNodeDrop(n, dd, e, data) :\r
10194             this.onContainerDrop(dd, e, data);\r
10195     },\r
10196 \r
10197     
10198     triggerCacheRefresh : function(){\r
10199         Ext.dd.DDM.refreshCache(this.groups);\r
10200     }  \r
10201 });
10202 \r
10203 \r
10204 Ext.data.SortTypes = {\r
10205     \r
10206     none : function(s){\r
10207         return s;\r
10208     },\r
10209     \r
10210     \r
10211     stripTagsRE : /<\/?[^>]+>/gi,\r
10212     \r
10213     \r
10214     asText : function(s){\r
10215         return String(s).replace(this.stripTagsRE, "");\r
10216     },\r
10217     \r
10218     \r
10219     asUCText : function(s){\r
10220         return String(s).toUpperCase().replace(this.stripTagsRE, "");\r
10221     },\r
10222     \r
10223     \r
10224     asUCString : function(s) {\r
10225         return String(s).toUpperCase();\r
10226     },\r
10227     \r
10228     \r
10229     asDate : function(s) {\r
10230         if(!s){\r
10231             return 0;\r
10232         }\r
10233         if(Ext.isDate(s)){\r
10234             return s.getTime();\r
10235         }\r
10236         return Date.parse(String(s));\r
10237     },\r
10238     \r
10239     \r
10240     asFloat : function(s) {\r
10241         var val = parseFloat(String(s).replace(/,/g, ""));\r
10242         if(isNaN(val)) val = 0;\r
10243         return val;\r
10244     },\r
10245     \r
10246     \r
10247     asInt : function(s) {\r
10248         var val = parseInt(String(s).replace(/,/g, ""));\r
10249         if(isNaN(val)) val = 0;\r
10250         return val;\r
10251     }\r
10252 };
10253 \r
10254 Ext.data.Record = function(data, id){\r
10255     this.id = (id || id === 0) ? id : ++Ext.data.Record.AUTO_ID;\r
10256     this.data = data;\r
10257 };\r
10258 \r
10259 \r
10260 Ext.data.Record.create = function(o){\r
10261     var f = Ext.extend(Ext.data.Record, {});\r
10262         var p = f.prototype;\r
10263     p.fields = new Ext.util.MixedCollection(false, function(field){\r
10264         return field.name;\r
10265     });\r
10266     for(var i = 0, len = o.length; i < len; i++){\r
10267         p.fields.add(new Ext.data.Field(o[i]));\r
10268     }\r
10269     f.getField = function(name){\r
10270         return p.fields.get(name);\r
10271     };\r
10272     return f;\r
10273 };\r
10274 \r
10275 Ext.data.Record.AUTO_ID = 1000;\r
10276 Ext.data.Record.EDIT = 'edit';\r
10277 Ext.data.Record.REJECT = 'reject';\r
10278 Ext.data.Record.COMMIT = 'commit';\r
10279 \r
10280 Ext.data.Record.prototype = {\r
10281         \r
10282     \r
10283     \r
10284     dirty : false,\r
10285     editing : false,\r
10286     error: null,\r
10287     \r
10288     modified: null,\r
10289 \r
10290     
10291     join : function(store){\r
10292         this.store = store;\r
10293     },\r
10294 \r
10295     \r
10296     set : function(name, value){\r
10297         if(String(this.data[name]) == String(value)){\r
10298             return;\r
10299         }\r
10300         this.dirty = true;\r
10301         if(!this.modified){\r
10302             this.modified = {};\r
10303         }\r
10304         if(typeof this.modified[name] == 'undefined'){\r
10305             this.modified[name] = this.data[name];\r
10306         }\r
10307         this.data[name] = value;\r
10308         if(!this.editing && this.store){\r
10309             this.store.afterEdit(this);\r
10310         }\r
10311     },\r
10312 \r
10313     \r
10314     get : function(name){\r
10315         return this.data[name];\r
10316     },\r
10317 \r
10318     \r
10319     beginEdit : function(){\r
10320         this.editing = true;\r
10321         this.modified = {};\r
10322     },\r
10323 \r
10324     \r
10325     cancelEdit : function(){\r
10326         this.editing = false;\r
10327         delete this.modified;\r
10328     },\r
10329 \r
10330     \r
10331     endEdit : function(){\r
10332         this.editing = false;\r
10333         if(this.dirty && this.store){\r
10334             this.store.afterEdit(this);\r
10335         }\r
10336     },\r
10337 \r
10338     \r
10339     reject : function(silent){\r
10340         var m = this.modified;\r
10341         for(var n in m){\r
10342             if(typeof m[n] != "function"){\r
10343                 this.data[n] = m[n];\r
10344             }\r
10345         }\r
10346         this.dirty = false;\r
10347         delete this.modified;\r
10348         this.editing = false;\r
10349         if(this.store && silent !== true){\r
10350             this.store.afterReject(this);\r
10351         }\r
10352     },\r
10353 \r
10354     \r
10355     commit : function(silent){\r
10356         this.dirty = false;\r
10357         delete this.modified;\r
10358         this.editing = false;\r
10359         if(this.store && silent !== true){\r
10360             this.store.afterCommit(this);\r
10361         }\r
10362     },\r
10363 \r
10364     \r
10365     getChanges : function(){\r
10366         var m = this.modified, cs = {};\r
10367         for(var n in m){\r
10368             if(m.hasOwnProperty(n)){\r
10369                 cs[n] = this.data[n];\r
10370             }\r
10371         }\r
10372         return cs;\r
10373     },\r
10374 \r
10375     
10376     hasError : function(){\r
10377         return this.error != null;\r
10378     },\r
10379 \r
10380     
10381     clearError : function(){\r
10382         this.error = null;\r
10383     },\r
10384 \r
10385     \r
10386     copy : function(newId) {\r
10387         return new this.constructor(Ext.apply({}, this.data), newId || this.id);\r
10388     },\r
10389 \r
10390     \r
10391     isModified : function(fieldName){\r
10392         return this.modified && this.modified.hasOwnProperty(fieldName);\r
10393     }\r
10394 };
10395 \r
10396 Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {\r
10397     register : function(){\r
10398         for(var i = 0, s; s = arguments[i]; i++){\r
10399             this.add(s);\r
10400         }\r
10401     },\r
10402 \r
10403     unregister : function(){\r
10404         for(var i = 0, s; s = arguments[i]; i++){\r
10405             this.remove(this.lookup(s));\r
10406         }\r
10407     },\r
10408 \r
10409     \r
10410     lookup : function(id){\r
10411         return typeof id == "object" ? id : this.get(id);\r
10412     },\r
10413 \r
10414     
10415     getKey : function(o){\r
10416          return o.storeId || o.id; \r
10417     }\r
10418 });
10419 \r
10420 Ext.data.Store = function(config){\r
10421     this.data = new Ext.util.MixedCollection(false);\r
10422     this.data.getKey = function(o){\r
10423         return o.id;\r
10424     };\r
10425     \r
10426     this.baseParams = {};\r
10427     
10428     this.paramNames = {\r
10429         "start" : "start",\r
10430         "limit" : "limit",\r
10431         "sort" : "sort",\r
10432         "dir" : "dir"\r
10433     };\r
10434 \r
10435     if(config && config.data){\r
10436         this.inlineData = config.data;\r
10437         delete config.data;\r
10438     }\r
10439 \r
10440     Ext.apply(this, config);\r
10441 \r
10442     if(this.url && !this.proxy){\r
10443         this.proxy = new Ext.data.HttpProxy({url: this.url});\r
10444     }\r
10445 \r
10446     if(this.reader){ 
10447         if(!this.recordType){\r
10448             this.recordType = this.reader.recordType;\r
10449         }\r
10450         if(this.reader.onMetaChange){\r
10451             this.reader.onMetaChange = this.onMetaChange.createDelegate(this);\r
10452         }\r
10453     }\r
10454 \r
10455     if(this.recordType){\r
10456         this.fields = this.recordType.prototype.fields;\r
10457     }\r
10458     this.modified = [];\r
10459 \r
10460     this.addEvents(\r
10461         \r
10462         'datachanged',\r
10463         \r
10464         'metachange',\r
10465         \r
10466         'add',\r
10467         \r
10468         'remove',\r
10469         \r
10470         'update',\r
10471         \r
10472         'clear',\r
10473         \r
10474         'beforeload',\r
10475         \r
10476         'load',\r
10477         \r
10478         'loadexception'\r
10479     );\r
10480 \r
10481     if(this.proxy){\r
10482         this.relayEvents(this.proxy,  ["loadexception"]);\r
10483     }\r
10484     \r
10485     this.sortToggle = {};\r
10486         if(this.sortInfo){\r
10487                 this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);\r
10488         }\r
10489         \r
10490     Ext.data.Store.superclass.constructor.call(this);\r
10491 \r
10492     if(this.storeId || this.id){\r
10493         Ext.StoreMgr.register(this);\r
10494     }\r
10495     if(this.inlineData){\r
10496         this.loadData(this.inlineData);\r
10497         delete this.inlineData;\r
10498     }else if(this.autoLoad){\r
10499         this.load.defer(10, this, [\r
10500             typeof this.autoLoad == 'object' ?\r
10501                 this.autoLoad : undefined]);\r
10502     }\r
10503 };\r
10504 Ext.extend(Ext.data.Store, Ext.util.Observable, {\r
10505     \r
10506     \r
10507     \r
10508     \r
10509     \r
10510     \r
10511     \r
10512     \r
10513     \r
10514     remoteSort : false,\r
10515 \r
10516     \r
10517     pruneModifiedRecords : false,\r
10518 \r
10519     \r
10520    lastOptions : null,\r
10521 \r
10522     destroy : function(){\r
10523         if(this.id){\r
10524             Ext.StoreMgr.unregister(this);\r
10525         }\r
10526         this.data = null;\r
10527         this.purgeListeners();\r
10528     },\r
10529 \r
10530     \r
10531     add : function(records){\r
10532         records = [].concat(records);\r
10533         if(records.length < 1){\r
10534             return;\r
10535         }\r
10536         for(var i = 0, len = records.length; i < len; i++){\r
10537             records[i].join(this);\r
10538         }\r
10539         var index = this.data.length;\r
10540         this.data.addAll(records);\r
10541         if(this.snapshot){\r
10542             this.snapshot.addAll(records);\r
10543         }\r
10544         this.fireEvent("add", this, records, index);\r
10545     },\r
10546 \r
10547     \r
10548     addSorted : function(record){\r
10549         var index = this.findInsertIndex(record);\r
10550         this.insert(index, record);\r
10551     },\r
10552 \r
10553     \r
10554     remove : function(record){\r
10555         var index = this.data.indexOf(record);\r
10556         this.data.removeAt(index);\r
10557         if(this.pruneModifiedRecords){\r
10558             this.modified.remove(record);\r
10559         }\r
10560         if(this.snapshot){\r
10561             this.snapshot.remove(record);\r
10562         }\r
10563         this.fireEvent("remove", this, record, index);\r
10564     },\r
10565 \r
10566     \r
10567     removeAll : function(){\r
10568         this.data.clear();\r
10569         if(this.snapshot){\r
10570             this.snapshot.clear();\r
10571         }\r
10572         if(this.pruneModifiedRecords){\r
10573             this.modified = [];\r
10574         }\r
10575         this.fireEvent("clear", this);\r
10576     },\r
10577 \r
10578     \r
10579     insert : function(index, records){\r
10580         records = [].concat(records);\r
10581         for(var i = 0, len = records.length; i < len; i++){\r
10582             this.data.insert(index, records[i]);\r
10583             records[i].join(this);\r
10584         }\r
10585         this.fireEvent("add", this, records, index);\r
10586     },\r
10587 \r
10588     \r
10589     indexOf : function(record){\r
10590         return this.data.indexOf(record);\r
10591     },\r
10592 \r
10593     \r
10594     indexOfId : function(id){\r
10595         return this.data.indexOfKey(id);\r
10596     },\r
10597 \r
10598     \r
10599     getById : function(id){\r
10600         return this.data.key(id);\r
10601     },\r
10602 \r
10603     \r
10604     getAt : function(index){\r
10605         return this.data.itemAt(index);\r
10606     },\r
10607 \r
10608     \r
10609     getRange : function(start, end){\r
10610         return this.data.getRange(start, end);\r
10611     },\r
10612 \r
10613     
10614     storeOptions : function(o){\r
10615         o = Ext.apply({}, o);\r
10616         delete o.callback;\r
10617         delete o.scope;\r
10618         this.lastOptions = o;\r
10619     },\r
10620 \r
10621     \r
10622     load : function(options){\r
10623         options = options || {};\r
10624         if(this.fireEvent("beforeload", this, options) !== false){\r
10625             this.storeOptions(options);\r
10626             var p = Ext.apply(options.params || {}, this.baseParams);\r
10627             if(this.sortInfo && this.remoteSort){\r
10628                 var pn = this.paramNames;\r
10629                 p[pn["sort"]] = this.sortInfo.field;\r
10630                 p[pn["dir"]] = this.sortInfo.direction;\r
10631             }\r
10632             this.proxy.load(p, this.reader, this.loadRecords, this, options);\r
10633             return true;\r
10634         } else {\r
10635           return false;\r
10636         }\r
10637     },\r
10638 \r
10639     \r
10640     reload : function(options){\r
10641         this.load(Ext.applyIf(options||{}, this.lastOptions));\r
10642     },\r
10643 \r
10644     
10645     
10646     loadRecords : function(o, options, success){\r
10647         if(!o || success === false){\r
10648             if(success !== false){\r
10649                 this.fireEvent("load", this, [], options);\r
10650             }\r
10651             if(options.callback){\r
10652                 options.callback.call(options.scope || this, [], options, false);\r
10653             }\r
10654             return;\r
10655         }\r
10656         var r = o.records, t = o.totalRecords || r.length;\r
10657         if(!options || options.add !== true){\r
10658             if(this.pruneModifiedRecords){\r
10659                 this.modified = [];\r
10660             }\r
10661             for(var i = 0, len = r.length; i < len; i++){\r
10662                 r[i].join(this);\r
10663             }\r
10664             if(this.snapshot){\r
10665                 this.data = this.snapshot;\r
10666                 delete this.snapshot;\r
10667             }\r
10668             this.data.clear();\r
10669             this.data.addAll(r);\r
10670             this.totalLength = t;\r
10671             this.applySort();\r
10672             this.fireEvent("datachanged", this);\r
10673         }else{\r
10674             this.totalLength = Math.max(t, this.data.length+r.length);\r
10675             this.add(r);\r
10676         }\r
10677         this.fireEvent("load", this, r, options);\r
10678         if(options.callback){\r
10679             options.callback.call(options.scope || this, r, options, true);\r
10680         }\r
10681     },\r
10682 \r
10683     \r
10684     loadData : function(o, append){\r
10685         var r = this.reader.readRecords(o);\r
10686         this.loadRecords(r, {add: append}, true);\r
10687     },\r
10688 \r
10689     \r
10690     getCount : function(){\r
10691         return this.data.length || 0;\r
10692     },\r
10693 \r
10694     \r
10695     getTotalCount : function(){\r
10696         return this.totalLength || 0;\r
10697     },\r
10698 \r
10699     \r
10700     getSortState : function(){\r
10701         return this.sortInfo;\r
10702     },\r
10703 \r
10704     
10705     applySort : function(){\r
10706         if(this.sortInfo && !this.remoteSort){\r
10707             var s = this.sortInfo, f = s.field;\r
10708             this.sortData(f, s.direction);\r
10709         }\r
10710     },\r
10711 \r
10712     
10713     sortData : function(f, direction){\r
10714         direction = direction || 'ASC';\r
10715         var st = this.fields.get(f).sortType;\r
10716         var fn = function(r1, r2){\r
10717             var v1 = st(r1.data[f]), v2 = st(r2.data[f]);\r
10718             return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);\r
10719         };\r
10720         this.data.sort(direction, fn);\r
10721         if(this.snapshot && this.snapshot != this.data){\r
10722             this.snapshot.sort(direction, fn);\r
10723         }\r
10724     },\r
10725 \r
10726     \r
10727     setDefaultSort : function(field, dir){\r
10728         dir = dir ? dir.toUpperCase() : "ASC";\r
10729         this.sortInfo = {field: field, direction: dir};\r
10730         this.sortToggle[field] = dir;\r
10731     },\r
10732 \r
10733     \r
10734     sort : function(fieldName, dir){\r
10735         var f = this.fields.get(fieldName);\r
10736         if(!f){\r
10737             return false;\r
10738         }\r
10739         if(!dir){\r
10740             if(this.sortInfo && this.sortInfo.field == f.name){ 
10741                 dir = (this.sortToggle[f.name] || "ASC").toggle("ASC", "DESC");\r
10742             }else{\r
10743                 dir = f.sortDir;\r
10744             }\r
10745         }\r
10746         var st = (this.sortToggle) ? this.sortToggle[f.name] : null;\r
10747         var si = (this.sortInfo) ? this.sortInfo : null;\r
10748         \r
10749         this.sortToggle[f.name] = dir;\r
10750         this.sortInfo = {field: f.name, direction: dir};\r
10751         if(!this.remoteSort){\r
10752             this.applySort();\r
10753             this.fireEvent("datachanged", this);\r
10754         }else{\r
10755             if (!this.load(this.lastOptions)) {\r
10756                 if (st) {\r
10757                     this.sortToggle[f.name] = st;\r
10758                 }\r
10759                 if (si) {\r
10760                     this.sortInfo = si;\r
10761                 }\r
10762             }\r
10763         }\r
10764     },\r
10765 \r
10766     \r
10767     each : function(fn, scope){\r
10768         this.data.each(fn, scope);\r
10769     },\r
10770 \r
10771     \r
10772     getModifiedRecords : function(){\r
10773         return this.modified;\r
10774     },\r
10775 \r
10776     
10777     createFilterFn : function(property, value, anyMatch, caseSensitive){\r
10778         if(Ext.isEmpty(value, false)){\r
10779             return false;\r
10780         }\r
10781         value = this.data.createValueMatcher(value, anyMatch, caseSensitive);\r
10782         return function(r){\r
10783             return value.test(r.data[property]);\r
10784         };\r
10785     },\r
10786 \r
10787     \r
10788     sum : function(property, start, end){\r
10789         var rs = this.data.items, v = 0;\r
10790         start = start || 0;\r
10791         end = (end || end === 0) ? end : rs.length-1;\r
10792 \r
10793         for(var i = start; i <= end; i++){\r
10794             v += (rs[i].data[property] || 0);\r
10795         }\r
10796         return v;\r
10797     },\r
10798 \r
10799     \r
10800     filter : function(property, value, anyMatch, caseSensitive){\r
10801         var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);\r
10802         return fn ? this.filterBy(fn) : this.clearFilter();\r
10803     },\r
10804 \r
10805     \r
10806     filterBy : function(fn, scope){\r
10807         this.snapshot = this.snapshot || this.data;\r
10808         this.data = this.queryBy(fn, scope||this);\r
10809         this.fireEvent("datachanged", this);\r
10810     },\r
10811 \r
10812     \r
10813     query : function(property, value, anyMatch, caseSensitive){\r
10814         var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);\r
10815         return fn ? this.queryBy(fn) : this.data.clone();\r
10816     },\r
10817 \r
10818     \r
10819     queryBy : function(fn, scope){\r
10820         var data = this.snapshot || this.data;\r
10821         return data.filterBy(fn, scope||this);\r
10822     },\r
10823 \r
10824     \r
10825     find : function(property, value, start, anyMatch, caseSensitive){\r
10826         var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);\r
10827         return fn ? this.data.findIndexBy(fn, null, start) : -1;\r
10828     },\r
10829 \r
10830     \r
10831     findBy : function(fn, scope, start){\r
10832         return this.data.findIndexBy(fn, scope, start);\r
10833     },\r
10834 \r
10835     \r
10836     collect : function(dataIndex, allowNull, bypassFilter){\r
10837         var d = (bypassFilter === true && this.snapshot) ?\r
10838                 this.snapshot.items : this.data.items;\r
10839         var v, sv, r = [], l = {};\r
10840         for(var i = 0, len = d.length; i < len; i++){\r
10841             v = d[i].data[dataIndex];\r
10842             sv = String(v);\r
10843             if((allowNull || !Ext.isEmpty(v)) && !l[sv]){\r
10844                 l[sv] = true;\r
10845                 r[r.length] = v;\r
10846             }\r
10847         }\r
10848         return r;\r
10849     },\r
10850 \r
10851     \r
10852     clearFilter : function(suppressEvent){\r
10853         if(this.isFiltered()){\r
10854             this.data = this.snapshot;\r
10855             delete this.snapshot;\r
10856             if(suppressEvent !== true){\r
10857                 this.fireEvent("datachanged", this);\r
10858             }\r
10859         }\r
10860     },\r
10861 \r
10862     \r
10863     isFiltered : function(){\r
10864         return this.snapshot && this.snapshot != this.data;\r
10865     },\r
10866 \r
10867     
10868     afterEdit : function(record){\r
10869         if(this.modified.indexOf(record) == -1){\r
10870             this.modified.push(record);\r
10871         }\r
10872         this.fireEvent("update", this, record, Ext.data.Record.EDIT);\r
10873     },\r
10874 \r
10875     
10876     afterReject : function(record){\r
10877         this.modified.remove(record);\r
10878         this.fireEvent("update", this, record, Ext.data.Record.REJECT);\r
10879     },\r
10880 \r
10881     
10882     afterCommit : function(record){\r
10883         this.modified.remove(record);\r
10884         this.fireEvent("update", this, record, Ext.data.Record.COMMIT);\r
10885     },\r
10886 \r
10887     \r
10888     commitChanges : function(){\r
10889         var m = this.modified.slice(0);\r
10890         this.modified = [];\r
10891         for(var i = 0, len = m.length; i < len; i++){\r
10892             m[i].commit();\r
10893         }\r
10894     },\r
10895 \r
10896     \r
10897     rejectChanges : function(){\r
10898         var m = this.modified.slice(0);\r
10899         this.modified = [];\r
10900         for(var i = 0, len = m.length; i < len; i++){\r
10901             m[i].reject();\r
10902         }\r
10903     },\r
10904 \r
10905     
10906     onMetaChange : function(meta, rtype, o){\r
10907         this.recordType = rtype;\r
10908         this.fields = rtype.prototype.fields;\r
10909         delete this.snapshot;\r
10910         this.sortInfo = meta.sortInfo;\r
10911         this.modified = [];\r
10912         this.fireEvent('metachange', this, this.reader.meta);\r
10913     },\r
10914 \r
10915     
10916     findInsertIndex : function(record){\r
10917         this.suspendEvents();\r
10918         var data = this.data.clone();\r
10919         this.data.add(record);\r
10920         this.applySort();\r
10921         var index = this.data.indexOf(record);\r
10922         this.data = data;\r
10923         this.resumeEvents();\r
10924         return index;\r
10925     }\r
10926 });
10927
10928 Ext.data.SimpleStore = function(config){
10929     Ext.data.SimpleStore.superclass.constructor.call(this, Ext.apply(config, {
10930         reader: new Ext.data.ArrayReader({
10931                 id: config.id
10932             },
10933             Ext.data.Record.create(config.fields)
10934         )
10935     }));
10936 };
10937 Ext.extend(Ext.data.SimpleStore, Ext.data.Store, {
10938     loadData : function(data, append){
10939         if(this.expandData === true){
10940             var r = [];
10941             for(var i = 0, len = data.length; i < len; i++){
10942                 r[r.length] = [data[i]];
10943             }
10944             data = r;
10945         }
10946         Ext.data.SimpleStore.superclass.loadData.call(this, data, append);
10947     }
10948 });
10949 \r
10950 Ext.data.JsonStore = function(c){\r
10951     Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(c, {\r
10952         proxy: !c.data ? new Ext.data.HttpProxy({url: c.url}) : undefined,\r
10953         reader: new Ext.data.JsonReader(c, c.fields)\r
10954     }));\r
10955 };\r
10956 Ext.extend(Ext.data.JsonStore, Ext.data.Store);
10957
10958
10959
10960 Ext.data.Field = function(config){\r
10961     if(typeof config == "string"){\r
10962         config = {name: config};\r
10963     }\r
10964     Ext.apply(this, config);\r
10965     \r
10966     if(!this.type){\r
10967         this.type = "auto";\r
10968     }\r
10969     \r
10970     var st = Ext.data.SortTypes;\r
10971     
10972     if(typeof this.sortType == "string"){\r
10973         this.sortType = st[this.sortType];\r
10974     }\r
10975     \r
10976     
10977     if(!this.sortType){\r
10978         switch(this.type){\r
10979             case "string":\r
10980                 this.sortType = st.asUCString;\r
10981                 break;\r
10982             case "date":\r
10983                 this.sortType = st.asDate;\r
10984                 break;\r
10985             default:\r
10986                 this.sortType = st.none;\r
10987         }\r
10988     }\r
10989 \r
10990     
10991     var stripRe = /[\$,%]/g;\r
10992 \r
10993     
10994     
10995     if(!this.convert){\r
10996         var cv, dateFormat = this.dateFormat;\r
10997         switch(this.type){\r
10998             case "":\r
10999             case "auto":\r
11000             case undefined:\r
11001                 cv = function(v){ return v; };\r
11002                 break;\r
11003             case "string":\r
11004                 cv = function(v){ return (v === undefined || v === null) ? '' : String(v); };\r
11005                 break;\r
11006             case "int":\r
11007                 cv = function(v){\r
11008                     return v !== undefined && v !== null && v !== '' ?\r
11009                            parseInt(String(v).replace(stripRe, ""), 10) : '';\r
11010                     };\r
11011                 break;\r
11012             case "float":\r
11013                 cv = function(v){\r
11014                     return v !== undefined && v !== null && v !== '' ?\r
11015                            parseFloat(String(v).replace(stripRe, ""), 10) : ''; \r
11016                     };\r
11017                 break;\r
11018             case "bool":\r
11019             case "boolean":\r
11020                 cv = function(v){ return v === true || v === "true" || v == 1; };\r
11021                 break;\r
11022             case "date":\r
11023                 cv = function(v){\r
11024                     if(!v){\r
11025                         return '';\r
11026                     }\r
11027                     if(Ext.isDate(v)){\r
11028                         return v;\r
11029                     }\r
11030                     if(dateFormat){\r
11031                         if(dateFormat == "timestamp"){\r
11032                             return new Date(v*1000);\r
11033                         }\r
11034                         if(dateFormat == "time"){\r
11035                             return new Date(parseInt(v, 10));\r
11036                         }\r
11037                         return Date.parseDate(v, dateFormat);\r
11038                     }\r
11039                     var parsed = Date.parse(v);\r
11040                     return parsed ? new Date(parsed) : null;\r
11041                 };\r
11042              break;\r
11043             \r
11044         }\r
11045         this.convert = cv;\r
11046     }\r
11047 };\r
11048 \r
11049 Ext.data.Field.prototype = {\r
11050     dateFormat: null,\r
11051     defaultValue: "",\r
11052     mapping: null,\r
11053     sortType : null,\r
11054     sortDir : "ASC"\r
11055 };
11056 \r
11057 Ext.data.DataReader = function(meta, recordType){\r
11058     \r
11059     this.meta = meta;\r
11060     this.recordType = Ext.isArray(recordType) ? \r
11061         Ext.data.Record.create(recordType) : recordType;\r
11062 };\r
11063 \r
11064 Ext.data.DataReader.prototype = {\r
11065     \r
11066 };
11067 \r
11068 Ext.data.DataProxy = function(){\r
11069     this.addEvents(\r
11070         \r
11071         'beforeload',\r
11072         \r
11073         'load',\r
11074         \r
11075         'loadexception'\r
11076     );\r
11077     Ext.data.DataProxy.superclass.constructor.call(this);\r
11078 };\r
11079 \r
11080 Ext.extend(Ext.data.DataProxy, Ext.util.Observable);
11081 \r
11082 Ext.data.MemoryProxy = function(data){\r
11083     Ext.data.MemoryProxy.superclass.constructor.call(this);\r
11084     this.data = data;\r
11085 };\r
11086 \r
11087 Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {\r
11088     \r
11089     load : function(params, reader, callback, scope, arg){\r
11090         params = params || {};\r
11091         var result;\r
11092         try {\r
11093             result = reader.readRecords(this.data);\r
11094         }catch(e){\r
11095             this.fireEvent("loadexception", this, arg, null, e);\r
11096             callback.call(scope, null, arg, false);\r
11097             return;\r
11098         }\r
11099         callback.call(scope, result, arg, true);\r
11100     },\r
11101     \r
11102     
11103     update : function(params, records){\r
11104         \r
11105     }\r
11106 });
11107 \r
11108 Ext.data.HttpProxy = function(conn){\r
11109     Ext.data.HttpProxy.superclass.constructor.call(this);\r
11110     \r
11111     this.conn = conn;\r
11112     this.useAjax = !conn || !conn.events;\r
11113 };\r
11114 \r
11115 Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {\r
11116     \r
11117     getConnection : function(){\r
11118         return this.useAjax ? Ext.Ajax : this.conn;\r
11119     },\r
11120 \r
11121     \r
11122     load : function(params, reader, callback, scope, arg){\r
11123         if(this.fireEvent("beforeload", this, params) !== false){\r
11124             var  o = {\r
11125                 params : params || {},\r
11126                 request: {\r
11127                     callback : callback,\r
11128                     scope : scope,\r
11129                     arg : arg\r
11130                 },\r
11131                 reader: reader,\r
11132                 callback : this.loadResponse,\r
11133                 scope: this\r
11134             };\r
11135             if(this.useAjax){\r
11136                 Ext.applyIf(o, this.conn);\r
11137                 if(this.activeRequest){\r
11138                     Ext.Ajax.abort(this.activeRequest);\r
11139                 }\r
11140                 this.activeRequest = Ext.Ajax.request(o);\r
11141             }else{\r
11142                 this.conn.request(o);\r
11143             }\r
11144         }else{\r
11145             callback.call(scope||this, null, arg, false);\r
11146         }\r
11147     },\r
11148 \r
11149     
11150     loadResponse : function(o, success, response){\r
11151         delete this.activeRequest;\r
11152         if(!success){\r
11153             this.fireEvent("loadexception", this, o, response);\r
11154             o.request.callback.call(o.request.scope, null, o.request.arg, false);\r
11155             return;\r
11156         }\r
11157         var result;\r
11158         try {\r
11159             result = o.reader.read(response);\r
11160         }catch(e){\r
11161             this.fireEvent("loadexception", this, o, response, e);\r
11162             o.request.callback.call(o.request.scope, null, o.request.arg, false);\r
11163             return;\r
11164         }\r
11165         this.fireEvent("load", this, o, o.request.arg);\r
11166         o.request.callback.call(o.request.scope, result, o.request.arg, true);\r
11167     },\r
11168     \r
11169     
11170     update : function(dataSet){\r
11171         \r
11172     },\r
11173     \r
11174     
11175     updateResponse : function(dataSet){\r
11176         \r
11177     }\r
11178 });
11179 \r
11180 Ext.data.ScriptTagProxy = function(config){\r
11181     Ext.data.ScriptTagProxy.superclass.constructor.call(this);\r
11182     Ext.apply(this, config);\r
11183     this.head = document.getElementsByTagName("head")[0];\r
11184 };\r
11185 \r
11186 Ext.data.ScriptTagProxy.TRANS_ID = 1000;\r
11187 \r
11188 Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {\r
11189     \r
11190     \r
11191     timeout : 30000,\r
11192     \r
11193     callbackParam : "callback",\r
11194     \r
11195     nocache : true,\r
11196 \r
11197     \r
11198     load : function(params, reader, callback, scope, arg){\r
11199         if(this.fireEvent("beforeload", this, params) !== false){\r
11200 \r
11201             var p = Ext.urlEncode(Ext.apply(params, this.extraParams));\r
11202 \r
11203             var url = this.url;\r
11204             url += (url.indexOf("?") != -1 ? "&" : "?") + p;\r
11205             if(this.nocache){\r
11206                 url += "&_dc=" + (new Date().getTime());\r
11207             }\r
11208             var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;\r
11209             var trans = {\r
11210                 id : transId,\r
11211                 cb : "stcCallback"+transId,\r
11212                 scriptId : "stcScript"+transId,\r
11213                 params : params,\r
11214                 arg : arg,\r
11215                 url : url,\r
11216                 callback : callback,\r
11217                 scope : scope,\r
11218                 reader : reader\r
11219             };\r
11220             var conn = this;\r
11221 \r
11222             window[trans.cb] = function(o){\r
11223                 conn.handleResponse(o, trans);\r
11224             };\r
11225 \r
11226             url += String.format("&{0}={1}", this.callbackParam, trans.cb);\r
11227 \r
11228             if(this.autoAbort !== false){\r
11229                 this.abort();\r
11230             }\r
11231 \r
11232             trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);\r
11233 \r
11234             var script = document.createElement("script");\r
11235             script.setAttribute("src", url);\r
11236             script.setAttribute("type", "text/javascript");\r
11237             script.setAttribute("id", trans.scriptId);\r
11238             this.head.appendChild(script);\r
11239 \r
11240             this.trans = trans;\r
11241         }else{\r
11242             callback.call(scope||this, null, arg, false);\r
11243         }\r
11244     },\r
11245 \r
11246     
11247     isLoading : function(){\r
11248         return this.trans ? true : false;\r
11249     },\r
11250 \r
11251     \r
11252     abort : function(){\r
11253         if(this.isLoading()){\r
11254             this.destroyTrans(this.trans);\r
11255         }\r
11256     },\r
11257 \r
11258     
11259     destroyTrans : function(trans, isLoaded){\r
11260         this.head.removeChild(document.getElementById(trans.scriptId));\r
11261         clearTimeout(trans.timeoutId);\r
11262         if(isLoaded){\r
11263             window[trans.cb] = undefined;\r
11264             try{\r
11265                 delete window[trans.cb];\r
11266             }catch(e){}\r
11267         }else{\r
11268             
11269             window[trans.cb] = function(){\r
11270                 window[trans.cb] = undefined;\r
11271                 try{\r
11272                     delete window[trans.cb];\r
11273                 }catch(e){}\r
11274             };\r
11275         }\r
11276     },\r
11277 \r
11278     
11279     handleResponse : function(o, trans){\r
11280         this.trans = false;\r
11281         this.destroyTrans(trans, true);\r
11282         var result;\r
11283         try {\r
11284             result = trans.reader.readRecords(o);\r
11285         }catch(e){\r
11286             this.fireEvent("loadexception", this, o, trans.arg, e);\r
11287             trans.callback.call(trans.scope||window, null, trans.arg, false);\r
11288             return;\r
11289         }\r
11290         this.fireEvent("load", this, o, trans.arg);\r
11291         trans.callback.call(trans.scope||window, result, trans.arg, true);\r
11292     },\r
11293 \r
11294     
11295     handleFailure : function(trans){\r
11296         this.trans = false;\r
11297         this.destroyTrans(trans, false);\r
11298         this.fireEvent("loadexception", this, null, trans.arg);\r
11299         trans.callback.call(trans.scope||window, null, trans.arg, false);\r
11300     }\r
11301 });
11302 \r
11303 Ext.data.JsonReader = function(meta, recordType){\r
11304     meta = meta || {};\r
11305     Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);\r
11306 };\r
11307 Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {\r
11308     \r
11309     \r
11310     read : function(response){\r
11311         var json = response.responseText;\r
11312         var o = eval("("+json+")");\r
11313         if(!o) {\r
11314             throw {message: "JsonReader.read: Json object not found"};\r
11315         }\r
11316         if(o.metaData){\r
11317             delete this.ef;\r
11318             this.meta = o.metaData;\r
11319             this.recordType = Ext.data.Record.create(o.metaData.fields);\r
11320             this.onMetaChange(this.meta, this.recordType, o);\r
11321         }\r
11322         return this.readRecords(o);\r
11323     },\r
11324 \r
11325     
11326     onMetaChange : function(meta, recordType, o){\r
11327 \r
11328     },\r
11329 \r
11330     \r
11331     simpleAccess: function(obj, subsc) {\r
11332         return obj[subsc];\r
11333     },\r
11334 \r
11335         \r
11336     getJsonAccessor: function(){\r
11337         var re = /[\[\.]/;\r
11338         return function(expr) {\r
11339             try {\r
11340                 return(re.test(expr))\r
11341                     ? new Function("obj", "return obj." + expr)\r
11342                     : function(obj){\r
11343                         return obj[expr];\r
11344                     };\r
11345             } catch(e){}\r
11346             return Ext.emptyFn;\r
11347         };\r
11348     }(),\r
11349 \r
11350     \r
11351     readRecords : function(o){\r
11352         \r
11353         this.jsonData = o;\r
11354         var s = this.meta, Record = this.recordType,\r
11355             f = Record.prototype.fields, fi = f.items, fl = f.length;\r
11356 \r
11357
11358         if (!this.ef) {\r
11359             if(s.totalProperty) {\r
11360                     this.getTotal = this.getJsonAccessor(s.totalProperty);\r
11361                 }\r
11362                 if(s.successProperty) {\r
11363                     this.getSuccess = this.getJsonAccessor(s.successProperty);\r
11364                 }\r
11365                 this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};\r
11366                 if (s.id) {\r
11367                         var g = this.getJsonAccessor(s.id);\r
11368                         this.getId = function(rec) {\r
11369                                 var r = g(rec);\r
11370                                 return (r === undefined || r === "") ? null : r;\r
11371                         };\r
11372                 } else {\r
11373                         this.getId = function(){return null;};\r
11374                 }\r
11375             this.ef = [];\r
11376             for(var i = 0; i < fl; i++){\r
11377                 f = fi[i];\r
11378                 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;\r
11379                 this.ef[i] = this.getJsonAccessor(map);\r
11380             }\r
11381         }\r
11382 \r
11383         var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;\r
11384         if(s.totalProperty){\r
11385             var v = parseInt(this.getTotal(o), 10);\r
11386             if(!isNaN(v)){\r
11387                 totalRecords = v;\r
11388             }\r
11389         }\r
11390         if(s.successProperty){\r
11391             var v = this.getSuccess(o);\r
11392             if(v === false || v === 'false'){\r
11393                 success = false;\r
11394             }\r
11395         }\r
11396         var records = [];\r
11397             for(var i = 0; i < c; i++){\r
11398                     var n = root[i];\r
11399                 var values = {};\r
11400                 var id = this.getId(n);\r
11401                 for(var j = 0; j < fl; j++){\r
11402                     f = fi[j];\r
11403                 var v = this.ef[j](n);\r
11404                 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, n);\r
11405                 }\r
11406                 var record = new Record(values, id);\r
11407                 record.json = n;\r
11408                 records[i] = record;\r
11409             }\r
11410             return {\r
11411                 success : success,\r
11412                 records : records,\r
11413                 totalRecords : totalRecords\r
11414             };\r
11415     }\r
11416 });
11417 \r
11418 Ext.data.XmlReader = function(meta, recordType){\r
11419     meta = meta || {};\r
11420     Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);\r
11421 };\r
11422 Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {\r
11423     \r
11424     read : function(response){\r
11425         var doc = response.responseXML;\r
11426         if(!doc) {\r
11427             throw {message: "XmlReader.read: XML Document not available"};\r
11428         }\r
11429         return this.readRecords(doc);\r
11430     },\r
11431 \r
11432     \r
11433     readRecords : function(doc){\r
11434         \r
11435         this.xmlData = doc;\r
11436         var root = doc.documentElement || doc;\r
11437         var q = Ext.DomQuery;\r
11438         var recordType = this.recordType, fields = recordType.prototype.fields;\r
11439         var sid = this.meta.id;\r
11440         var totalRecords = 0, success = true;\r
11441         if(this.meta.totalRecords){\r
11442             totalRecords = q.selectNumber(this.meta.totalRecords, root, 0);\r
11443         }\r
11444 \r
11445         if(this.meta.success){\r
11446             var sv = q.selectValue(this.meta.success, root, true);\r
11447             success = sv !== false && sv !== 'false';\r
11448         }\r
11449         var records = [];\r
11450         var ns = q.select(this.meta.record, root);\r
11451         for(var i = 0, len = ns.length; i < len; i++) {\r
11452                 var n = ns[i];\r
11453                 var values = {};\r
11454                 var id = sid ? q.selectValue(sid, n) : undefined;\r
11455                 for(var j = 0, jlen = fields.length; j < jlen; j++){\r
11456                     var f = fields.items[j];\r
11457                 var v = q.selectValue(f.mapping || f.name, n, f.defaultValue);\r
11458                     v = f.convert(v, n);\r
11459                     values[f.name] = v;\r
11460                 }\r
11461                 var record = new recordType(values, id);\r
11462                 record.node = n;\r
11463                 records[records.length] = record;\r
11464             }\r
11465 \r
11466             return {\r
11467                 success : success,\r
11468                 records : records,\r
11469                 totalRecords : totalRecords || records.length\r
11470             };\r
11471     }\r
11472 });
11473 \r
11474 Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {\r
11475     \r
11476     readRecords : function(o){\r
11477         var sid = this.meta ? this.meta.id : null;\r
11478         var recordType = this.recordType, fields = recordType.prototype.fields;\r
11479         var records = [];\r
11480         var root = o;\r
11481             for(var i = 0; i < root.length; i++){\r
11482                     var n = root[i];\r
11483                 var values = {};\r
11484                 var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);\r
11485                 for(var j = 0, jlen = fields.length; j < jlen; j++){\r
11486                 var f = fields.items[j];\r
11487                 var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;\r
11488                 var v = n[k] !== undefined ? n[k] : f.defaultValue;\r
11489                 v = f.convert(v, n);\r
11490                 values[f.name] = v;\r
11491             }\r
11492                 var record = new recordType(values, id);\r
11493                 record.json = n;\r
11494                 records[records.length] = record;\r
11495             }\r
11496             return {\r
11497                 records : records,\r
11498                 totalRecords : records.length\r
11499             };\r
11500     }\r
11501 });
11502 \r
11503 Ext.data.Tree = function(root){\r
11504    this.nodeHash = {};\r
11505    \r
11506    this.root = null;\r
11507    if(root){\r
11508        this.setRootNode(root);\r
11509    }\r
11510    this.addEvents(\r
11511        \r
11512        "append",\r
11513        \r
11514        "remove",\r
11515        \r
11516        "move",\r
11517        \r
11518        "insert",\r
11519        \r
11520        "beforeappend",\r
11521        \r
11522        "beforeremove",\r
11523        \r
11524        "beforemove",\r
11525        \r
11526        "beforeinsert"\r
11527    );\r
11528 \r
11529     Ext.data.Tree.superclass.constructor.call(this);\r
11530 };\r
11531 \r
11532 Ext.extend(Ext.data.Tree, Ext.util.Observable, {\r
11533     \r
11534     pathSeparator: "/",\r
11535 \r
11536     
11537     proxyNodeEvent : function(){\r
11538         return this.fireEvent.apply(this, arguments);\r
11539     },\r
11540 \r
11541     \r
11542     getRootNode : function(){\r
11543         return this.root;\r
11544     },\r
11545 \r
11546     \r
11547     setRootNode : function(node){\r
11548         this.root = node;\r
11549         node.ownerTree = this;\r
11550         node.isRoot = true;\r
11551         this.registerNode(node);\r
11552         return node;\r
11553     },\r
11554 \r
11555     \r
11556     getNodeById : function(id){\r
11557         return this.nodeHash[id];\r
11558     },\r
11559 \r
11560     
11561     registerNode : function(node){\r
11562         this.nodeHash[node.id] = node;\r
11563     },\r
11564 \r
11565     
11566     unregisterNode : function(node){\r
11567         delete this.nodeHash[node.id];\r
11568     },\r
11569 \r
11570     toString : function(){\r
11571         return "[Tree"+(this.id?" "+this.id:"")+"]";\r
11572     }\r
11573 });\r
11574 \r
11575 \r
11576 Ext.data.Node = function(attributes){\r
11577     \r
11578     this.attributes = attributes || {};\r
11579     this.leaf = this.attributes.leaf;\r
11580     \r
11581     this.id = this.attributes.id;\r
11582     if(!this.id){\r
11583         this.id = Ext.id(null, "ynode-");\r
11584         this.attributes.id = this.id;\r
11585     }\r
11586     \r
11587     this.childNodes = [];\r
11588     if(!this.childNodes.indexOf){ 
11589         this.childNodes.indexOf = function(o){\r
11590             for(var i = 0, len = this.length; i < len; i++){\r
11591                 if(this[i] == o) return i;\r
11592             }\r
11593             return -1;\r
11594         };\r
11595     }\r
11596     \r
11597     this.parentNode = null;\r
11598     \r
11599     this.firstChild = null;\r
11600     \r
11601     this.lastChild = null;\r
11602     \r
11603     this.previousSibling = null;\r
11604     \r
11605     this.nextSibling = null;\r
11606 \r
11607     this.addEvents({\r
11608        \r
11609        "append" : true,\r
11610        \r
11611        "remove" : true,\r
11612        \r
11613        "move" : true,\r
11614        \r
11615        "insert" : true,\r
11616        \r
11617        "beforeappend" : true,\r
11618        \r
11619        "beforeremove" : true,\r
11620        \r
11621        "beforemove" : true,\r
11622        \r
11623        "beforeinsert" : true\r
11624    });\r
11625     this.listeners = this.attributes.listeners;\r
11626     Ext.data.Node.superclass.constructor.call(this);\r
11627 };\r
11628 \r
11629 Ext.extend(Ext.data.Node, Ext.util.Observable, {\r
11630     
11631     fireEvent : function(evtName){\r
11632         
11633         if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){\r
11634             return false;\r
11635         }\r
11636         
11637         var ot = this.getOwnerTree();\r
11638         if(ot){\r
11639             if(ot.proxyNodeEvent.apply(ot, arguments) === false){\r
11640                 return false;\r
11641             }\r
11642         }\r
11643         return true;\r
11644     },\r
11645 \r
11646     \r
11647     isLeaf : function(){\r
11648         return this.leaf === true;\r
11649     },\r
11650 \r
11651     
11652     setFirstChild : function(node){\r
11653         this.firstChild = node;\r
11654     },\r
11655 \r
11656     
11657     setLastChild : function(node){\r
11658         this.lastChild = node;\r
11659     },\r
11660 \r
11661 \r
11662     \r
11663     isLast : function(){\r
11664        return (!this.parentNode ? true : this.parentNode.lastChild == this);\r
11665     },\r
11666 \r
11667     \r
11668     isFirst : function(){\r
11669        return (!this.parentNode ? true : this.parentNode.firstChild == this);\r
11670     },\r
11671 \r
11672     hasChildNodes : function(){\r
11673         return !this.isLeaf() && this.childNodes.length > 0;\r
11674     },\r
11675 \r
11676     \r
11677     appendChild : function(node){\r
11678         var multi = false;\r
11679         if(Ext.isArray(node)){\r
11680             multi = node;\r
11681         }else if(arguments.length > 1){\r
11682             multi = arguments;\r
11683         }\r
11684         
11685         if(multi){\r
11686             for(var i = 0, len = multi.length; i < len; i++) {\r
11687                 this.appendChild(multi[i]);\r
11688             }\r
11689         }else{\r
11690             if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){\r
11691                 return false;\r
11692             }\r
11693             var index = this.childNodes.length;\r
11694             var oldParent = node.parentNode;\r
11695             
11696             if(oldParent){\r
11697                 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){\r
11698                     return false;\r
11699                 }\r
11700                 oldParent.removeChild(node);\r
11701             }\r
11702             index = this.childNodes.length;\r
11703             if(index == 0){\r
11704                 this.setFirstChild(node);\r
11705             }\r
11706             this.childNodes.push(node);\r
11707             node.parentNode = this;\r
11708             var ps = this.childNodes[index-1];\r
11709             if(ps){\r
11710                 node.previousSibling = ps;\r
11711                 ps.nextSibling = node;\r
11712             }else{\r
11713                 node.previousSibling = null;\r
11714             }\r
11715             node.nextSibling = null;\r
11716             this.setLastChild(node);\r
11717             node.setOwnerTree(this.getOwnerTree());\r
11718             this.fireEvent("append", this.ownerTree, this, node, index);\r
11719             if(oldParent){\r
11720                 node.fireEvent("move", this.ownerTree, node, oldParent, this, index);\r
11721             }\r
11722             return node;\r
11723         }\r
11724     },\r
11725 \r
11726     \r
11727     removeChild : function(node){\r
11728         var index = this.childNodes.indexOf(node);\r
11729         if(index == -1){\r
11730             return false;\r
11731         }\r
11732         if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){\r
11733             return false;\r
11734         }\r
11735 \r
11736         
11737         this.childNodes.splice(index, 1);\r
11738 \r
11739         
11740         if(node.previousSibling){\r
11741             node.previousSibling.nextSibling = node.nextSibling;\r
11742         }\r
11743         if(node.nextSibling){\r
11744             node.nextSibling.previousSibling = node.previousSibling;\r
11745         }\r
11746 \r
11747         
11748         if(this.firstChild == node){\r
11749             this.setFirstChild(node.nextSibling);\r
11750         }\r
11751         if(this.lastChild == node){\r
11752             this.setLastChild(node.previousSibling);\r
11753         }\r
11754 \r
11755         node.setOwnerTree(null);\r
11756         
11757         node.parentNode = null;\r
11758         node.previousSibling = null;\r
11759         node.nextSibling = null;\r
11760         this.fireEvent("remove", this.ownerTree, this, node);\r
11761         return node;\r
11762     },\r
11763 \r
11764     \r
11765     insertBefore : function(node, refNode){\r
11766         if(!refNode){ 
11767             return this.appendChild(node);\r
11768         }\r
11769         
11770         if(node == refNode){\r
11771             return false;\r
11772         }\r
11773 \r
11774         if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){\r
11775             return false;\r
11776         }\r
11777         var index = this.childNodes.indexOf(refNode);\r
11778         var oldParent = node.parentNode;\r
11779         var refIndex = index;\r
11780 \r
11781         
11782         if(oldParent == this && this.childNodes.indexOf(node) < index){\r
11783             refIndex--;\r
11784         }\r
11785 \r
11786         
11787         if(oldParent){\r
11788             if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){\r
11789                 return false;\r
11790             }\r
11791             oldParent.removeChild(node);\r
11792         }\r
11793         if(refIndex == 0){\r
11794             this.setFirstChild(node);\r
11795         }\r
11796         this.childNodes.splice(refIndex, 0, node);\r
11797         node.parentNode = this;\r
11798         var ps = this.childNodes[refIndex-1];\r
11799         if(ps){\r
11800             node.previousSibling = ps;\r
11801             ps.nextSibling = node;\r
11802         }else{\r
11803             node.previousSibling = null;\r
11804         }\r
11805         node.nextSibling = refNode;\r
11806         refNode.previousSibling = node;\r
11807         node.setOwnerTree(this.getOwnerTree());\r
11808         this.fireEvent("insert", this.ownerTree, this, node, refNode);\r
11809         if(oldParent){\r
11810             node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);\r
11811         }\r
11812         return node;\r
11813     },\r
11814 \r
11815     \r
11816     remove : function(){\r
11817         this.parentNode.removeChild(this);\r
11818         return this;\r
11819     },\r
11820 \r
11821     \r
11822     item : function(index){\r
11823         return this.childNodes[index];\r
11824     },\r
11825 \r
11826     \r
11827     replaceChild : function(newChild, oldChild){\r
11828         this.insertBefore(newChild, oldChild);\r
11829         this.removeChild(oldChild);\r
11830         return oldChild;\r
11831     },\r
11832 \r
11833     \r
11834     indexOf : function(child){\r
11835         return this.childNodes.indexOf(child);\r
11836     },\r
11837 \r
11838     \r
11839     getOwnerTree : function(){\r
11840         
11841         if(!this.ownerTree){\r
11842             var p = this;\r
11843             while(p){\r
11844                 if(p.ownerTree){\r
11845                     this.ownerTree = p.ownerTree;\r
11846                     break;\r
11847                 }\r
11848                 p = p.parentNode;\r
11849             }\r
11850         }\r
11851         return this.ownerTree;\r
11852     },\r
11853 \r
11854     \r
11855     getDepth : function(){\r
11856         var depth = 0;\r
11857         var p = this;\r
11858         while(p.parentNode){\r
11859             ++depth;\r
11860             p = p.parentNode;\r
11861         }\r
11862         return depth;\r
11863     },\r
11864 \r
11865     
11866     setOwnerTree : function(tree){\r
11867         
11868         if(tree != this.ownerTree){\r
11869             if(this.ownerTree){\r
11870                 this.ownerTree.unregisterNode(this);\r
11871             }\r
11872             this.ownerTree = tree;\r
11873             var cs = this.childNodes;\r
11874             for(var i = 0, len = cs.length; i < len; i++) {\r
11875                 cs[i].setOwnerTree(tree);\r
11876             }\r
11877             if(tree){\r
11878                 tree.registerNode(this);\r
11879             }\r
11880         }\r
11881     },\r
11882 \r
11883     \r
11884     getPath : function(attr){\r
11885         attr = attr || "id";\r
11886         var p = this.parentNode;\r
11887         var b = [this.attributes[attr]];\r
11888         while(p){\r
11889             b.unshift(p.attributes[attr]);\r
11890             p = p.parentNode;\r
11891         }\r
11892         var sep = this.getOwnerTree().pathSeparator;\r
11893         return sep + b.join(sep);\r
11894     },\r
11895 \r
11896     \r
11897     bubble : function(fn, scope, args){\r
11898         var p = this;\r
11899         while(p){\r
11900             if(fn.apply(scope || p, args || [p]) === false){\r
11901                 break;\r
11902             }\r
11903             p = p.parentNode;\r
11904         }\r
11905     },\r
11906 \r
11907     \r
11908     cascade : function(fn, scope, args){\r
11909         if(fn.apply(scope || this, args || [this]) !== false){\r
11910             var cs = this.childNodes;\r
11911             for(var i = 0, len = cs.length; i < len; i++) {\r
11912                 cs[i].cascade(fn, scope, args);\r
11913             }\r
11914         }\r
11915     },\r
11916 \r
11917     \r
11918     eachChild : function(fn, scope, args){\r
11919         var cs = this.childNodes;\r
11920         for(var i = 0, len = cs.length; i < len; i++) {\r
11921                 if(fn.apply(scope || this, args || [cs[i]]) === false){\r
11922                     break;\r
11923                 }\r
11924         }\r
11925     },\r
11926 \r
11927     \r
11928     findChild : function(attribute, value){\r
11929         var cs = this.childNodes;\r
11930         for(var i = 0, len = cs.length; i < len; i++) {\r
11931                 if(cs[i].attributes[attribute] == value){\r
11932                     return cs[i];\r
11933                 }\r
11934         }\r
11935         return null;\r
11936     },\r
11937 \r
11938     \r
11939     findChildBy : function(fn, scope){\r
11940         var cs = this.childNodes;\r
11941         for(var i = 0, len = cs.length; i < len; i++) {\r
11942                 if(fn.call(scope||cs[i], cs[i]) === true){\r
11943                     return cs[i];\r
11944                 }\r
11945         }\r
11946         return null;\r
11947     },\r
11948 \r
11949     \r
11950     sort : function(fn, scope){\r
11951         var cs = this.childNodes;\r
11952         var len = cs.length;\r
11953         if(len > 0){\r
11954             var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;\r
11955             cs.sort(sortFn);\r
11956             for(var i = 0; i < len; i++){\r
11957                 var n = cs[i];\r
11958                 n.previousSibling = cs[i-1];\r
11959                 n.nextSibling = cs[i+1];\r
11960                 if(i == 0){\r
11961                     this.setFirstChild(n);\r
11962                 }\r
11963                 if(i == len-1){\r
11964                     this.setLastChild(n);\r
11965                 }\r
11966             }\r
11967         }\r
11968     },\r
11969 \r
11970     \r
11971     contains : function(node){\r
11972         return node.isAncestor(this);\r
11973     },\r
11974 \r
11975     \r
11976     isAncestor : function(node){\r
11977         var p = this.parentNode;\r
11978         while(p){\r
11979             if(p == node){\r
11980                 return true;\r
11981             }\r
11982             p = p.parentNode;\r
11983         }\r
11984         return false;\r
11985     },\r
11986 \r
11987     toString : function(){\r
11988         return "[Node"+(this.id?" "+this.id:"")+"]";\r
11989     }\r
11990 });
11991 \r
11992 Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {\r
11993     \r
11994     \r
11995     remoteGroup : false,\r
11996     \r
11997     groupOnSort:false,\r
11998 \r
11999     \r
12000     clearGrouping : function(){\r
12001         this.groupField = false;\r
12002         if(this.remoteGroup){\r
12003             if(this.baseParams){\r
12004                 delete this.baseParams.groupBy;\r
12005             }\r
12006             this.reload();\r
12007         }else{\r
12008             this.applySort();\r
12009             this.fireEvent('datachanged', this);\r
12010         }\r
12011     },\r
12012 \r
12013     \r
12014     groupBy : function(field, forceRegroup){\r
12015         if(this.groupField == field && !forceRegroup){\r
12016             return; 
12017         }\r
12018         this.groupField = field;\r
12019         if(this.remoteGroup){\r
12020             if(!this.baseParams){\r
12021                 this.baseParams = {};\r
12022             }\r
12023             this.baseParams['groupBy'] = field;\r
12024         }\r
12025         if(this.groupOnSort){\r
12026             this.sort(field);\r
12027             return;\r
12028         }\r
12029         if(this.remoteGroup){\r
12030             this.reload();\r
12031         }else{\r
12032             var si = this.sortInfo || {};\r
12033             if(si.field != field){\r
12034                 this.applySort();\r
12035             }else{\r
12036                 this.sortData(field);\r
12037             }\r
12038             this.fireEvent('datachanged', this);\r
12039         }\r
12040     },\r
12041 \r
12042     
12043     applySort : function(){\r
12044         Ext.data.GroupingStore.superclass.applySort.call(this);\r
12045         if(!this.groupOnSort && !this.remoteGroup){\r
12046             var gs = this.getGroupState();\r
12047             if(gs && gs != this.sortInfo.field){\r
12048                 this.sortData(this.groupField);\r
12049             }\r
12050         }\r
12051     },\r
12052 \r
12053     
12054     applyGrouping : function(alwaysFireChange){\r
12055         if(this.groupField !== false){\r
12056             this.groupBy(this.groupField, true);\r
12057             return true;\r
12058         }else{\r
12059             if(alwaysFireChange === true){\r
12060                 this.fireEvent('datachanged', this);\r
12061             }\r
12062             return false;\r
12063         }\r
12064     },\r
12065 \r
12066     
12067     getGroupState : function(){\r
12068         return this.groupOnSort && this.groupField !== false ?\r
12069                (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;\r
12070     }\r
12071 });
12072 \r
12073 Ext.ComponentMgr = function(){\r
12074     var all = new Ext.util.MixedCollection();\r
12075     var types = {};\r
12076 \r
12077     return {\r
12078         \r
12079         register : function(c){\r
12080             all.add(c);\r
12081         },\r
12082 \r
12083         \r
12084         unregister : function(c){\r
12085             all.remove(c);\r
12086         },\r
12087 \r
12088         \r
12089         get : function(id){\r
12090             return all.get(id);\r
12091         },\r
12092 \r
12093         \r
12094         onAvailable : function(id, fn, scope){\r
12095             all.on("add", function(index, o){\r
12096                 if(o.id == id){\r
12097                     fn.call(scope || o, o);\r
12098                     all.un("add", fn, scope);\r
12099                 }\r
12100             });\r
12101         },\r
12102 \r
12103         \r
12104         all : all,\r
12105 \r
12106         \r
12107         registerType : function(xtype, cls){\r
12108             types[xtype] = cls;\r
12109             cls.xtype = xtype;\r
12110         },\r
12111 \r
12112         
12113         create : function(config, defaultType){\r
12114             return new types[config.xtype || defaultType](config);\r
12115         }\r
12116     };\r
12117 }();\r
12118 \r
12119
12120
12121 Ext.reg = Ext.ComponentMgr.registerType;
12122
12123 Ext.Component = function(config){
12124     config = config || {};
12125     if(config.initialConfig){
12126         if(config.isAction){                       this.baseAction = config;
12127         }
12128         config = config.initialConfig;     }else if(config.tagName || config.dom || typeof config == "string"){         config = {applyTo: config, id: config.id || config};
12129     }
12130
12131     
12132     this.initialConfig = config;
12133
12134     Ext.apply(this, config);
12135     this.addEvents(
12136         
12137         'disable',
12138         
12139         'enable',
12140         
12141         'beforeshow',
12142         
12143         'show',
12144         
12145         'beforehide',
12146         
12147         'hide',
12148         
12149         'beforerender',
12150         
12151         'render',
12152         
12153         'beforedestroy',
12154         
12155         'destroy',
12156         
12157         'beforestaterestore',
12158         
12159         'staterestore',
12160         
12161         'beforestatesave',
12162         
12163         'statesave'
12164     );
12165     this.getId();
12166     Ext.ComponentMgr.register(this);
12167     Ext.Component.superclass.constructor.call(this);
12168
12169     if(this.baseAction){
12170         this.baseAction.addComponent(this);
12171     }
12172
12173     this.initComponent();
12174
12175     if(this.plugins){
12176         if(Ext.isArray(this.plugins)){
12177             for(var i = 0, len = this.plugins.length; i < len; i++){
12178                 this.plugins[i].init(this);
12179             }
12180         }else{
12181             this.plugins.init(this);
12182         }
12183     }
12184
12185     if(this.stateful !== false){
12186         this.initState(config);
12187     }
12188
12189     if(this.applyTo){
12190         this.applyToMarkup(this.applyTo);
12191         delete this.applyTo;
12192     }else if(this.renderTo){
12193         this.render(this.renderTo);
12194         delete this.renderTo;
12195     }
12196 };
12197
12198 Ext.Component.AUTO_ID = 1000;
12199
12200 Ext.extend(Ext.Component, Ext.util.Observable, {
12201     
12202     
12203     
12204     
12205     
12206     
12207     
12208     
12209     
12210
12211     
12212     
12213     
12214
12215     
12216     disabledClass : "x-item-disabled",
12217         
12218     allowDomMove : true,
12219         
12220     autoShow : false,
12221     
12222     hideMode: 'display',
12223     
12224     hideParent: false,
12225
12226     
12227     
12228     hidden : false,
12229     
12230     disabled : false,
12231     
12232     rendered : false,
12233
12234         ctype : "Ext.Component",
12235
12236         actionMode : "el",
12237
12238         getActionEl : function(){
12239         return this[this.actionMode];
12240     },
12241
12242     
12243     initComponent : Ext.emptyFn,
12244
12245     
12246     render : function(container, position){
12247         if(!this.rendered && this.fireEvent("beforerender", this) !== false){
12248             if(!container && this.el){
12249                 this.el = Ext.get(this.el);
12250                 container = this.el.dom.parentNode;
12251                 this.allowDomMove = false;
12252             }
12253             this.container = Ext.get(container);
12254             if(this.ctCls){
12255                 this.container.addClass(this.ctCls);
12256             }
12257             this.rendered = true;
12258             if(position !== undefined){
12259                 if(typeof position == 'number'){
12260                     position = this.container.dom.childNodes[position];
12261                 }else{
12262                     position = Ext.getDom(position);
12263                 }
12264             }
12265             this.onRender(this.container, position || null);
12266             if(this.autoShow){
12267                 this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
12268             }
12269             if(this.cls){
12270                 this.el.addClass(this.cls);
12271                 delete this.cls;
12272             }
12273             if(this.style){
12274                 this.el.applyStyles(this.style);
12275                 delete this.style;
12276             }
12277             this.fireEvent("render", this);
12278             this.afterRender(this.container);
12279             if(this.hidden){
12280                 this.hide();
12281             }
12282             if(this.disabled){
12283                 this.disable();
12284             }
12285
12286             this.initStateEvents();
12287         }
12288         return this;
12289     },
12290
12291         initState : function(config){
12292         if(Ext.state.Manager){
12293             var state = Ext.state.Manager.get(this.stateId || this.id);
12294             if(state){
12295                 if(this.fireEvent('beforestaterestore', this, state) !== false){
12296                     this.applyState(state);
12297                     this.fireEvent('staterestore', this, state);
12298                 }
12299             }
12300         }
12301     },
12302
12303         initStateEvents : function(){
12304         if(this.stateEvents){
12305             for(var i = 0, e; e = this.stateEvents[i]; i++){
12306                 this.on(e, this.saveState, this, {delay:100});
12307             }
12308         }
12309     },
12310
12311         applyState : function(state, config){
12312         if(state){
12313             Ext.apply(this, state);
12314         }
12315     },
12316
12317         getState : function(){
12318         return null;
12319     },
12320
12321         saveState : function(){
12322         if(Ext.state.Manager){
12323             var state = this.getState();
12324             if(this.fireEvent('beforestatesave', this, state) !== false){
12325                 Ext.state.Manager.set(this.stateId || this.id, state);
12326                 this.fireEvent('statesave', this, state);
12327             }
12328         }
12329     },
12330
12331     
12332     applyToMarkup : function(el){
12333         this.allowDomMove = false;
12334         this.el = Ext.get(el);
12335         this.render(this.el.dom.parentNode);
12336     },
12337
12338     
12339     addClass : function(cls){
12340         if(this.el){
12341             this.el.addClass(cls);
12342         }else{
12343             this.cls = this.cls ? this.cls + ' ' + cls : cls;
12344         }
12345     },
12346
12347     
12348     removeClass : function(cls){
12349         if(this.el){
12350             this.el.removeClass(cls);
12351         }else if(this.cls){
12352             this.cls = this.cls.split(' ').remove(cls).join(' ');
12353         }
12354     },
12355
12356             onRender : function(ct, position){
12357         if(this.autoEl){
12358             if(typeof this.autoEl == 'string'){
12359                 this.el = document.createElement(this.autoEl);
12360             }else{
12361                 var div = document.createElement('div');
12362                 Ext.DomHelper.overwrite(div, this.autoEl);
12363                 this.el = div.firstChild;
12364             }
12365             if (!this.el.id) {
12366                 this.el.id = this.getId();
12367             }
12368         }
12369         if(this.el){
12370             this.el = Ext.get(this.el);
12371             if(this.allowDomMove !== false){
12372                 ct.dom.insertBefore(this.el.dom, position);
12373             }
12374         }
12375     },
12376
12377         getAutoCreate : function(){
12378         var cfg = typeof this.autoCreate == "object" ?
12379                       this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
12380         if(this.id && !cfg.id){
12381             cfg.id = this.id;
12382         }
12383         return cfg;
12384     },
12385
12386         afterRender : Ext.emptyFn,
12387
12388     
12389     destroy : function(){
12390         if(this.fireEvent("beforedestroy", this) !== false){
12391             this.beforeDestroy();
12392             if(this.rendered){
12393                 this.el.removeAllListeners();
12394                 this.el.remove();
12395                 if(this.actionMode == "container"){
12396                     this.container.remove();
12397                 }
12398             }
12399             this.onDestroy();
12400             Ext.ComponentMgr.unregister(this);
12401             this.fireEvent("destroy", this);
12402             this.purgeListeners();
12403         }
12404     },
12405
12406             beforeDestroy : Ext.emptyFn,
12407
12408             onDestroy  : Ext.emptyFn,
12409
12410     
12411     getEl : function(){
12412         return this.el;
12413     },
12414
12415     
12416     getId : function(){
12417         return this.id || (this.id = "ext-comp-" + (++Ext.Component.AUTO_ID));
12418     },
12419
12420     
12421     getItemId : function(){
12422         return this.itemId || this.getId();
12423     },
12424
12425     
12426     focus : function(selectText, delay){
12427         if(delay){
12428             this.focus.defer(typeof delay == 'number' ? delay : 10, this, [selectText, false]);
12429             return;
12430         }
12431         if(this.rendered){
12432             this.el.focus();
12433             if(selectText === true){
12434                 this.el.dom.select();
12435             }
12436         }
12437         return this;
12438     },
12439
12440         blur : function(){
12441         if(this.rendered){
12442             this.el.blur();
12443         }
12444         return this;
12445     },
12446
12447     
12448     disable : function(){
12449         if(this.rendered){
12450             this.onDisable();
12451         }
12452         this.disabled = true;
12453         this.fireEvent("disable", this);
12454         return this;
12455     },
12456
12457             onDisable : function(){
12458         this.getActionEl().addClass(this.disabledClass);
12459         this.el.dom.disabled = true;
12460     },
12461
12462     
12463     enable : function(){
12464         if(this.rendered){
12465             this.onEnable();
12466         }
12467         this.disabled = false;
12468         this.fireEvent("enable", this);
12469         return this;
12470     },
12471
12472             onEnable : function(){
12473         this.getActionEl().removeClass(this.disabledClass);
12474         this.el.dom.disabled = false;
12475     },
12476
12477     
12478     setDisabled : function(disabled){
12479         this[disabled ? "disable" : "enable"]();
12480     },
12481
12482     
12483     show: function(){
12484         if(this.fireEvent("beforeshow", this) !== false){
12485             this.hidden = false;
12486             if(this.autoRender){
12487                 this.render(typeof this.autoRender == 'boolean' ? Ext.getBody() : this.autoRender);
12488             }
12489             if(this.rendered){
12490                 this.onShow();
12491             }
12492             this.fireEvent("show", this);
12493         }
12494         return this;
12495     },
12496
12497         onShow : function(){
12498         if(this.hideParent){
12499             this.container.removeClass('x-hide-' + this.hideMode);
12500         }else{
12501             this.getActionEl().removeClass('x-hide-' + this.hideMode);
12502         }
12503
12504     },
12505
12506     
12507     hide: function(){
12508         if(this.fireEvent("beforehide", this) !== false){
12509             this.hidden = true;
12510             if(this.rendered){
12511                 this.onHide();
12512             }
12513             this.fireEvent("hide", this);
12514         }
12515         return this;
12516     },
12517
12518         onHide : function(){
12519         if(this.hideParent){
12520             this.container.addClass('x-hide-' + this.hideMode);
12521         }else{
12522             this.getActionEl().addClass('x-hide-' + this.hideMode);
12523         }
12524     },
12525
12526     
12527     setVisible: function(visible){
12528         if(visible) {
12529             this.show();
12530         }else{
12531             this.hide();
12532         }
12533         return this;
12534     },
12535
12536     
12537     isVisible : function(){
12538         return this.rendered && this.getActionEl().isVisible();
12539     },
12540
12541     
12542     cloneConfig : function(overrides){
12543         overrides = overrides || {};
12544         var id = overrides.id || Ext.id();
12545         var cfg = Ext.applyIf(overrides, this.initialConfig);
12546         cfg.id = id;         return new this.constructor(cfg);
12547     },
12548
12549     
12550     getXType : function(){
12551         return this.constructor.xtype;
12552     },
12553
12554     
12555     isXType : function(xtype, shallow){
12556         return !shallow ?
12557                ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 :
12558                 this.constructor.xtype == xtype;
12559     },
12560
12561     
12562     getXTypes : function(){
12563         var tc = this.constructor;
12564         if(!tc.xtypes){
12565             var c = [], sc = this;
12566             while(sc && sc.constructor.xtype){
12567                 c.unshift(sc.constructor.xtype);
12568                 sc = sc.constructor.superclass;
12569             }
12570             tc.xtypeChain = c;
12571             tc.xtypes = c.join('/');
12572         }
12573         return tc.xtypes;
12574     },
12575
12576     
12577     findParentBy: function(fn) {
12578         for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
12579         return p || null;
12580     },
12581
12582     
12583     findParentByType: function(xtype) {
12584         return typeof xtype == 'function' ?
12585             this.findParentBy(function(p){
12586                 return p.constructor === xtype;
12587             }) :
12588             this.findParentBy(function(p){
12589                 return p.constructor.xtype === xtype;
12590             });
12591     }
12592 });
12593
12594 Ext.reg('component', Ext.Component);
12595
12596 \r
12597 Ext.Action = function(config){\r
12598     this.initialConfig = config;\r
12599     this.items = [];\r
12600 }\r
12601 \r
12602 Ext.Action.prototype = {\r
12603     \r
12604     \r
12605     \r
12606     \r
12607     \r
12608     \r
12609 \r
12610     
12611     isAction : true,\r
12612 \r
12613     \r
12614     setText : function(text){\r
12615         this.initialConfig.text = text;\r
12616         this.callEach('setText', [text]);\r
12617     },\r
12618 \r
12619     \r
12620     getText : function(){\r
12621         return this.initialConfig.text;\r
12622     },\r
12623 \r
12624     \r
12625     setIconClass : function(cls){\r
12626         this.initialConfig.iconCls = cls;\r
12627         this.callEach('setIconClass', [cls]);\r
12628     },\r
12629 \r
12630     \r
12631     getIconClass : function(){\r
12632         return this.initialConfig.iconCls;\r
12633     },\r
12634 \r
12635     \r
12636     setDisabled : function(v){\r
12637         this.initialConfig.disabled = v;\r
12638         this.callEach('setDisabled', [v]);\r
12639     },\r
12640 \r
12641     \r
12642     enable : function(){\r
12643         this.setDisabled(false);\r
12644     },\r
12645 \r
12646     \r
12647     disable : function(){\r
12648         this.setDisabled(true);\r
12649     },\r
12650 \r
12651     \r
12652     isDisabled : function(){\r
12653         return this.initialConfig.disabled;\r
12654     },\r
12655 \r
12656     \r
12657     setHidden : function(v){\r
12658         this.initialConfig.hidden = v;\r
12659         this.callEach('setVisible', [!v]);\r
12660     },\r
12661 \r
12662     \r
12663     show : function(){\r
12664         this.setHidden(false);\r
12665     },\r
12666 \r
12667     \r
12668     hide : function(){\r
12669         this.setHidden(true);\r
12670     },\r
12671 \r
12672     \r
12673     isHidden : function(){\r
12674         return this.initialConfig.hidden;\r
12675     },\r
12676 \r
12677     \r
12678     setHandler : function(fn, scope){\r
12679         this.initialConfig.handler = fn;\r
12680         this.initialConfig.scope = scope;\r
12681         this.callEach('setHandler', [fn, scope]);\r
12682     },\r
12683 \r
12684     \r
12685     each : function(fn, scope){\r
12686         Ext.each(this.items, fn, scope);\r
12687     },\r
12688 \r
12689     
12690     callEach : function(fnName, args){\r
12691         var cs = this.items;\r
12692         for(var i = 0, len = cs.length; i < len; i++){\r
12693             cs[i][fnName].apply(cs[i], args);\r
12694         }\r
12695     },\r
12696 \r
12697     
12698     addComponent : function(comp){\r
12699         this.items.push(comp);\r
12700         comp.on('destroy', this.removeComponent, this);\r
12701     },\r
12702 \r
12703     
12704     removeComponent : function(comp){\r
12705         this.items.remove(comp);\r
12706     },\r
12707 \r
12708     execute : function(){\r
12709         this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);\r
12710     }\r
12711 };
12712 \r
12713 (function(){ \r
12714 Ext.Layer = function(config, existingEl){\r
12715     config = config || {};\r
12716     var dh = Ext.DomHelper;\r
12717     var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;\r
12718     if(existingEl){\r
12719         this.dom = Ext.getDom(existingEl);\r
12720     }\r
12721     if(!this.dom){\r
12722         var o = config.dh || {tag: "div", cls: "x-layer"};\r
12723         this.dom = dh.append(pel, o);\r
12724     }\r
12725     if(config.cls){\r
12726         this.addClass(config.cls);\r
12727     }\r
12728     this.constrain = config.constrain !== false;\r
12729     this.visibilityMode = Ext.Element.VISIBILITY;\r
12730     if(config.id){\r
12731         this.id = this.dom.id = config.id;\r
12732     }else{\r
12733         this.id = Ext.id(this.dom);\r
12734     }\r
12735     this.zindex = config.zindex || this.getZIndex();\r
12736     this.position("absolute", this.zindex);\r
12737     if(config.shadow){\r
12738         this.shadowOffset = config.shadowOffset || 4;\r
12739         this.shadow = new Ext.Shadow({\r
12740             offset : this.shadowOffset,\r
12741             mode : config.shadow\r
12742         });\r
12743     }else{\r
12744         this.shadowOffset = 0;\r
12745     }\r
12746     this.useShim = config.shim !== false && Ext.useShims;\r
12747     this.useDisplay = config.useDisplay;\r
12748     this.hide();\r
12749 };\r
12750 \r
12751 var supr = Ext.Element.prototype;\r
12752 \r
12753
12754 var shims = [];\r
12755 \r
12756 Ext.extend(Ext.Layer, Ext.Element, {\r
12757 \r
12758     getZIndex : function(){\r
12759         return this.zindex || parseInt(this.getStyle("z-index"), 10) || 11000;\r
12760     },\r
12761 \r
12762     getShim : function(){\r
12763         if(!this.useShim){\r
12764             return null;\r
12765         }\r
12766         if(this.shim){\r
12767             return this.shim;\r
12768         }\r
12769         var shim = shims.shift();\r
12770         if(!shim){\r
12771             shim = this.createShim();\r
12772             shim.enableDisplayMode('block');\r
12773             shim.dom.style.display = 'none';\r
12774             shim.dom.style.visibility = 'visible';\r
12775         }\r
12776         var pn = this.dom.parentNode;\r
12777         if(shim.dom.parentNode != pn){\r
12778             pn.insertBefore(shim.dom, this.dom);\r
12779         }\r
12780         shim.setStyle('z-index', this.getZIndex()-2);\r
12781         this.shim = shim;\r
12782         return shim;\r
12783     },\r
12784 \r
12785     hideShim : function(){\r
12786         if(this.shim){\r
12787             this.shim.setDisplayed(false);\r
12788             shims.push(this.shim);\r
12789             delete this.shim;\r
12790         }\r
12791     },\r
12792 \r
12793     disableShadow : function(){\r
12794         if(this.shadow){\r
12795             this.shadowDisabled = true;\r
12796             this.shadow.hide();\r
12797             this.lastShadowOffset = this.shadowOffset;\r
12798             this.shadowOffset = 0;\r
12799         }\r
12800     },\r
12801 \r
12802     enableShadow : function(show){\r
12803         if(this.shadow){\r
12804             this.shadowDisabled = false;\r
12805             this.shadowOffset = this.lastShadowOffset;\r
12806             delete this.lastShadowOffset;\r
12807             if(show){\r
12808                 this.sync(true);\r
12809             }\r
12810         }\r
12811     },\r
12812 \r
12813     
12814     
12815     
12816     sync : function(doShow){\r
12817         var sw = this.shadow;\r
12818         if(!this.updating && this.isVisible() && (sw || this.useShim)){\r
12819             var sh = this.getShim();\r
12820 \r
12821             var w = this.getWidth(),\r
12822                 h = this.getHeight();\r
12823 \r
12824             var l = this.getLeft(true),\r
12825                 t = this.getTop(true);\r
12826 \r
12827             if(sw && !this.shadowDisabled){\r
12828                 if(doShow && !sw.isVisible()){\r
12829                     sw.show(this);\r
12830                 }else{\r
12831                     sw.realign(l, t, w, h);\r
12832                 }\r
12833                 if(sh){\r
12834                     if(doShow){\r
12835                        sh.show();\r
12836                     }\r
12837                     
12838                     var a = sw.adjusts, s = sh.dom.style;\r
12839                     s.left = (Math.min(l, l+a.l))+"px";\r
12840                     s.top = (Math.min(t, t+a.t))+"px";\r
12841                     s.width = (w+a.w)+"px";\r
12842                     s.height = (h+a.h)+"px";\r
12843                 }\r
12844             }else if(sh){\r
12845                 if(doShow){\r
12846                    sh.show();\r
12847                 }\r
12848                 sh.setSize(w, h);\r
12849                 sh.setLeftTop(l, t);\r
12850             }\r
12851             \r
12852         }\r
12853     },\r
12854 \r
12855     
12856     destroy : function(){\r
12857         this.hideShim();\r
12858         if(this.shadow){\r
12859             this.shadow.hide();\r
12860         }\r
12861         this.removeAllListeners();\r
12862         Ext.removeNode(this.dom);\r
12863         Ext.Element.uncache(this.id);\r
12864     },\r
12865 \r
12866     remove : function(){\r
12867         this.destroy();\r
12868     },\r
12869 \r
12870     
12871     beginUpdate : function(){\r
12872         this.updating = true;\r
12873     },\r
12874 \r
12875     
12876     endUpdate : function(){\r
12877         this.updating = false;\r
12878         this.sync(true);\r
12879     },\r
12880 \r
12881     
12882     hideUnders : function(negOffset){\r
12883         if(this.shadow){\r
12884             this.shadow.hide();\r
12885         }\r
12886         this.hideShim();\r
12887     },\r
12888 \r
12889     
12890     constrainXY : function(){\r
12891         if(this.constrain){\r
12892             var vw = Ext.lib.Dom.getViewWidth(),\r
12893                 vh = Ext.lib.Dom.getViewHeight();\r
12894             var s = Ext.getDoc().getScroll();\r
12895 \r
12896             var xy = this.getXY();\r
12897             var x = xy[0], y = xy[1];   \r
12898             var w = this.dom.offsetWidth+this.shadowOffset, h = this.dom.offsetHeight+this.shadowOffset;\r
12899             
12900             var moved = false;\r
12901             
12902             if((x + w) > vw+s.left){\r
12903                 x = vw - w - this.shadowOffset;\r
12904                 moved = true;\r
12905             }\r
12906             if((y + h) > vh+s.top){\r
12907                 y = vh - h - this.shadowOffset;\r
12908                 moved = true;\r
12909             }\r
12910             
12911             if(x < s.left){\r
12912                 x = s.left;\r
12913                 moved = true;\r
12914             }\r
12915             if(y < s.top){\r
12916                 y = s.top;\r
12917                 moved = true;\r
12918             }\r
12919             if(moved){\r
12920                 if(this.avoidY){\r
12921                     var ay = this.avoidY;\r
12922                     if(y <= ay && (y+h) >= ay){\r
12923                         y = ay-h-5;   \r
12924                     }\r
12925                 }\r
12926                 xy = [x, y];\r
12927                 this.storeXY(xy);\r
12928                 supr.setXY.call(this, xy);\r
12929                 this.sync();\r
12930             }\r
12931         }\r
12932     },\r
12933 \r
12934     isVisible : function(){\r
12935         return this.visible;    \r
12936     },\r
12937 \r
12938     
12939     showAction : function(){\r
12940         this.visible = true; 
12941         if(this.useDisplay === true){\r
12942             this.setDisplayed("");\r
12943         }else if(this.lastXY){\r
12944             supr.setXY.call(this, this.lastXY);\r
12945         }else if(this.lastLT){\r
12946             supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);\r
12947         }\r
12948     },\r
12949 \r
12950     
12951     hideAction : function(){\r
12952         this.visible = false;\r
12953         if(this.useDisplay === true){\r
12954             this.setDisplayed(false);\r
12955         }else{\r
12956             this.setLeftTop(-10000,-10000);\r
12957         }\r
12958     },\r
12959 \r
12960     
12961     setVisible : function(v, a, d, c, e){\r
12962         if(v){\r
12963             this.showAction();\r
12964         }\r
12965         if(a && v){\r
12966             var cb = function(){\r
12967                 this.sync(true);\r
12968                 if(c){\r
12969                     c();\r
12970                 }\r
12971             }.createDelegate(this);\r
12972             supr.setVisible.call(this, true, true, d, cb, e);\r
12973         }else{\r
12974             if(!v){\r
12975                 this.hideUnders(true);\r
12976             }\r
12977             var cb = c;\r
12978             if(a){\r
12979                 cb = function(){\r
12980                     this.hideAction();\r
12981                     if(c){\r
12982                         c();\r
12983                     }\r
12984                 }.createDelegate(this);\r
12985             }\r
12986             supr.setVisible.call(this, v, a, d, cb, e);\r
12987             if(v){\r
12988                 this.sync(true);\r
12989             }else if(!a){\r
12990                 this.hideAction();\r
12991             }\r
12992         }\r
12993     },\r
12994 \r
12995     storeXY : function(xy){\r
12996         delete this.lastLT;\r
12997         this.lastXY = xy;\r
12998     },\r
12999 \r
13000     storeLeftTop : function(left, top){\r
13001         delete this.lastXY;\r
13002         this.lastLT = [left, top];\r
13003     },\r
13004 \r
13005     
13006     beforeFx : function(){\r
13007         this.beforeAction();\r
13008         return Ext.Layer.superclass.beforeFx.apply(this, arguments);\r
13009     },\r
13010 \r
13011     
13012     afterFx : function(){\r
13013         Ext.Layer.superclass.afterFx.apply(this, arguments);\r
13014         this.sync(this.isVisible());\r
13015     },\r
13016 \r
13017     
13018     beforeAction : function(){\r
13019         if(!this.updating && this.shadow){\r
13020             this.shadow.hide();\r
13021         }\r
13022     },\r
13023 \r
13024     
13025     setLeft : function(left){\r
13026         this.storeLeftTop(left, this.getTop(true));\r
13027         supr.setLeft.apply(this, arguments);\r
13028         this.sync();\r
13029     },\r
13030 \r
13031     setTop : function(top){\r
13032         this.storeLeftTop(this.getLeft(true), top);\r
13033         supr.setTop.apply(this, arguments);\r
13034         this.sync();\r
13035     },\r
13036 \r
13037     setLeftTop : function(left, top){\r
13038         this.storeLeftTop(left, top);\r
13039         supr.setLeftTop.apply(this, arguments);\r
13040         this.sync();\r
13041     },\r
13042 \r
13043     setXY : function(xy, a, d, c, e){\r
13044         this.fixDisplay();\r
13045         this.beforeAction();\r
13046         this.storeXY(xy);\r
13047         var cb = this.createCB(c);\r
13048         supr.setXY.call(this, xy, a, d, cb, e);\r
13049         if(!a){\r
13050             cb();\r
13051         }\r
13052     },\r
13053 \r
13054     
13055     createCB : function(c){\r
13056         var el = this;\r
13057         return function(){\r
13058             el.constrainXY();\r
13059             el.sync(true);\r
13060             if(c){\r
13061                 c();\r
13062             }\r
13063         };\r
13064     },\r
13065 \r
13066     
13067     setX : function(x, a, d, c, e){\r
13068         this.setXY([x, this.getY()], a, d, c, e);\r
13069     },\r
13070 \r
13071     
13072     setY : function(y, a, d, c, e){\r
13073         this.setXY([this.getX(), y], a, d, c, e);\r
13074     },\r
13075 \r
13076     
13077     setSize : function(w, h, a, d, c, e){\r
13078         this.beforeAction();\r
13079         var cb = this.createCB(c);\r
13080         supr.setSize.call(this, w, h, a, d, cb, e);\r
13081         if(!a){\r
13082             cb();\r
13083         }\r
13084     },\r
13085 \r
13086     
13087     setWidth : function(w, a, d, c, e){\r
13088         this.beforeAction();\r
13089         var cb = this.createCB(c);\r
13090         supr.setWidth.call(this, w, a, d, cb, e);\r
13091         if(!a){\r
13092             cb();\r
13093         }\r
13094     },\r
13095 \r
13096     
13097     setHeight : function(h, a, d, c, e){\r
13098         this.beforeAction();\r
13099         var cb = this.createCB(c);\r
13100         supr.setHeight.call(this, h, a, d, cb, e);\r
13101         if(!a){\r
13102             cb();\r
13103         }\r
13104     },\r
13105 \r
13106     
13107     setBounds : function(x, y, w, h, a, d, c, e){\r
13108         this.beforeAction();\r
13109         var cb = this.createCB(c);\r
13110         if(!a){\r
13111             this.storeXY([x, y]);\r
13112             supr.setXY.call(this, [x, y]);\r
13113             supr.setSize.call(this, w, h, a, d, cb, e);\r
13114             cb();\r
13115         }else{\r
13116             supr.setBounds.call(this, x, y, w, h, a, d, cb, e);\r
13117         }\r
13118         return this;\r
13119     },\r
13120     \r
13121     \r
13122     setZIndex : function(zindex){\r
13123         this.zindex = zindex;\r
13124         this.setStyle("z-index", zindex + 2);\r
13125         if(this.shadow){\r
13126             this.shadow.setZIndex(zindex + 1);\r
13127         }\r
13128         if(this.shim){\r
13129             this.shim.setStyle("z-index", zindex);\r
13130         }\r
13131     }\r
13132 });\r
13133 })();
13134
13135 Ext.Shadow = function(config){
13136     Ext.apply(this, config);
13137     if(typeof this.mode != "string"){
13138         this.mode = this.defaultMode;
13139     }
13140     var o = this.offset, a = {h: 0};
13141     var rad = Math.floor(this.offset/2);
13142     switch(this.mode.toLowerCase()){         case "drop":
13143             a.w = 0;
13144             a.l = a.t = o;
13145             a.t -= 1;
13146             if(Ext.isIE){
13147                 a.l -= this.offset + rad;
13148                 a.t -= this.offset + rad;
13149                 a.w -= rad;
13150                 a.h -= rad;
13151                 a.t += 1;
13152             }
13153         break;
13154         case "sides":
13155             a.w = (o*2);
13156             a.l = -o;
13157             a.t = o-1;
13158             if(Ext.isIE){
13159                 a.l -= (this.offset - rad);
13160                 a.t -= this.offset + rad;
13161                 a.l += 1;
13162                 a.w -= (this.offset - rad)*2;
13163                 a.w -= rad + 1;
13164                 a.h -= 1;
13165             }
13166         break;
13167         case "frame":
13168             a.w = a.h = (o*2);
13169             a.l = a.t = -o;
13170             a.t += 1;
13171             a.h -= 2;
13172             if(Ext.isIE){
13173                 a.l -= (this.offset - rad);
13174                 a.t -= (this.offset - rad);
13175                 a.l += 1;
13176                 a.w -= (this.offset + rad + 1);
13177                 a.h -= (this.offset + rad);
13178                 a.h += 1;
13179             }
13180         break;
13181     };
13182
13183     this.adjusts = a;
13184 };
13185
13186 Ext.Shadow.prototype = {
13187     
13188     
13189     offset: 4,
13190
13191         defaultMode: "drop",
13192
13193     
13194     show : function(target){
13195         target = Ext.get(target);
13196         if(!this.el){
13197             this.el = Ext.Shadow.Pool.pull();
13198             if(this.el.dom.nextSibling != target.dom){
13199                 this.el.insertBefore(target);
13200             }
13201         }
13202         this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);
13203         if(Ext.isIE){
13204             this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";
13205         }
13206         this.realign(
13207             target.getLeft(true),
13208             target.getTop(true),
13209             target.getWidth(),
13210             target.getHeight()
13211         );
13212         this.el.dom.style.display = "block";
13213     },
13214
13215     
13216     isVisible : function(){
13217         return this.el ? true : false;  
13218     },
13219
13220     
13221     realign : function(l, t, w, h){
13222         if(!this.el){
13223             return;
13224         }
13225         var a = this.adjusts, d = this.el.dom, s = d.style;
13226         var iea = 0;
13227         s.left = (l+a.l)+"px";
13228         s.top = (t+a.t)+"px";
13229         var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
13230         if(s.width != sws || s.height != shs){
13231             s.width = sws;
13232             s.height = shs;
13233             if(!Ext.isIE){
13234                 var cn = d.childNodes;
13235                 var sww = Math.max(0, (sw-12))+"px";
13236                 cn[0].childNodes[1].style.width = sww;
13237                 cn[1].childNodes[1].style.width = sww;
13238                 cn[2].childNodes[1].style.width = sww;
13239                 cn[1].style.height = Math.max(0, (sh-12))+"px";
13240             }
13241         }
13242     },
13243
13244     
13245     hide : function(){
13246         if(this.el){
13247             this.el.dom.style.display = "none";
13248             Ext.Shadow.Pool.push(this.el);
13249             delete this.el;
13250         }
13251     },
13252
13253     
13254     setZIndex : function(z){
13255         this.zIndex = z;
13256         if(this.el){
13257             this.el.setStyle("z-index", z);
13258         }
13259     }
13260 };
13261
13262 Ext.Shadow.Pool = function(){
13263     var p = [];
13264     var markup = Ext.isIE ?
13265                  '<div class="x-ie-shadow"></div>' :
13266                  '<div class="x-shadow"><div class="xst"><div class="xstl"></div><div class="xstc"></div><div class="xstr"></div></div><div class="xsc"><div class="xsml"></div><div class="xsmc"></div><div class="xsmr"></div></div><div class="xsb"><div class="xsbl"></div><div class="xsbc"></div><div class="xsbr"></div></div></div>';
13267     return {
13268         pull : function(){
13269             var sh = p.shift();
13270             if(!sh){
13271                 sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
13272                 sh.autoBoxAdjust = false;
13273             }
13274             return sh;
13275         },
13276
13277         push : function(sh){
13278             p.push(sh);
13279         }
13280     };
13281 }();
13282
13283 Ext.BoxComponent = Ext.extend(Ext.Component, {
13284     
13285     
13286     
13287     
13288     
13289     
13290     
13291     
13292     
13293
13294     initComponent : function(){
13295         Ext.BoxComponent.superclass.initComponent.call(this);
13296         this.addEvents(
13297             
13298             'resize',
13299             
13300             'move'
13301         );
13302     },
13303
13304         boxReady : false,
13305         deferHeight: false,
13306
13307     
13308     setSize : function(w, h){
13309                 if(typeof w == 'object'){
13310             h = w.height;
13311             w = w.width;
13312         }
13313                 if(!this.boxReady){
13314             this.width = w;
13315             this.height = h;
13316             return this;
13317         }
13318
13319                 if(this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
13320             return this;
13321         }
13322         this.lastSize = {width: w, height: h};
13323         var adj = this.adjustSize(w, h);
13324         var aw = adj.width, ah = adj.height;
13325         if(aw !== undefined || ah !== undefined){             var rz = this.getResizeEl();
13326             if(!this.deferHeight && aw !== undefined && ah !== undefined){
13327                 rz.setSize(aw, ah);
13328             }else if(!this.deferHeight && ah !== undefined){
13329                 rz.setHeight(ah);
13330             }else if(aw !== undefined){
13331                 rz.setWidth(aw);
13332             }
13333             this.onResize(aw, ah, w, h);
13334             this.fireEvent('resize', this, aw, ah, w, h);
13335         }
13336         return this;
13337     },
13338
13339     
13340     setWidth : function(width){
13341         return this.setSize(width);
13342     },
13343
13344     
13345     setHeight : function(height){
13346         return this.setSize(undefined, height);
13347     },
13348
13349     
13350     getSize : function(){
13351         return this.el.getSize();
13352     },
13353
13354     
13355     getPosition : function(local){
13356         if(local === true){
13357             return [this.el.getLeft(true), this.el.getTop(true)];
13358         }
13359         return this.xy || this.el.getXY();
13360     },
13361
13362     
13363     getBox : function(local){
13364         var s = this.el.getSize();
13365         if(local === true){
13366             s.x = this.el.getLeft(true);
13367             s.y = this.el.getTop(true);
13368         }else{
13369             var xy = this.xy || this.el.getXY();
13370             s.x = xy[0];
13371             s.y = xy[1];
13372         }
13373         return s;
13374     },
13375
13376     
13377     updateBox : function(box){
13378         this.setSize(box.width, box.height);
13379         this.setPagePosition(box.x, box.y);
13380         return this;
13381     },
13382
13383         getResizeEl : function(){
13384         return this.resizeEl || this.el;
13385     },
13386
13387         getPositionEl : function(){
13388         return this.positionEl || this.el;
13389     },
13390
13391     
13392     setPosition : function(x, y){
13393         if(x && typeof x[1] == 'number'){
13394             y = x[1];
13395             x = x[0];
13396         }
13397         this.x = x;
13398         this.y = y;
13399         if(!this.boxReady){
13400             return this;
13401         }
13402         var adj = this.adjustPosition(x, y);
13403         var ax = adj.x, ay = adj.y;
13404
13405         var el = this.getPositionEl();
13406         if(ax !== undefined || ay !== undefined){
13407             if(ax !== undefined && ay !== undefined){
13408                 el.setLeftTop(ax, ay);
13409             }else if(ax !== undefined){
13410                 el.setLeft(ax);
13411             }else if(ay !== undefined){
13412                 el.setTop(ay);
13413             }
13414             this.onPosition(ax, ay);
13415             this.fireEvent('move', this, ax, ay);
13416         }
13417         return this;
13418     },
13419
13420     
13421     setPagePosition : function(x, y){
13422         if(x && typeof x[1] == 'number'){
13423             y = x[1];
13424             x = x[0];
13425         }
13426         this.pageX = x;
13427         this.pageY = y;
13428         if(!this.boxReady){
13429             return;
13430         }
13431         if(x === undefined || y === undefined){             return;
13432         }
13433         var p = this.el.translatePoints(x, y);
13434         this.setPosition(p.left, p.top);
13435         return this;
13436     },
13437
13438         onRender : function(ct, position){
13439         Ext.BoxComponent.superclass.onRender.call(this, ct, position);
13440         if(this.resizeEl){
13441             this.resizeEl = Ext.get(this.resizeEl);
13442         }
13443         if(this.positionEl){
13444             this.positionEl = Ext.get(this.positionEl);
13445         }
13446     },
13447
13448         afterRender : function(){
13449         Ext.BoxComponent.superclass.afterRender.call(this);
13450         this.boxReady = true;
13451         this.setSize(this.width, this.height);
13452         if(this.x || this.y){
13453             this.setPosition(this.x, this.y);
13454         }else if(this.pageX || this.pageY){
13455             this.setPagePosition(this.pageX, this.pageY);
13456         }
13457     },
13458
13459     
13460     syncSize : function(){
13461         delete this.lastSize;
13462         this.setSize(this.autoWidth ? undefined : this.el.getWidth(), this.autoHeight ? undefined : this.el.getHeight());
13463         return this;
13464     },
13465
13466     
13467     onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
13468
13469     },
13470
13471     
13472     onPosition : function(x, y){
13473
13474     },
13475
13476         adjustSize : function(w, h){
13477         if(this.autoWidth){
13478             w = 'auto';
13479         }
13480         if(this.autoHeight){
13481             h = 'auto';
13482         }
13483         return {width : w, height: h};
13484     },
13485
13486         adjustPosition : function(x, y){
13487         return {x : x, y: y};
13488     }
13489 });
13490 Ext.reg('box', Ext.BoxComponent);
13491 \r
13492 Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){\r
13493     \r
13494     \r
13495     this.el = Ext.get(dragElement, true);\r
13496     this.el.dom.unselectable = "on";\r
13497     \r
13498     this.resizingEl = Ext.get(resizingElement, true);\r
13499 \r
13500     \r
13501     this.orientation = orientation || Ext.SplitBar.HORIZONTAL;\r
13502     \r
13503     \r
13504     this.minSize = 0;\r
13505     \r
13506     \r
13507     this.maxSize = 2000;\r
13508     \r
13509     \r
13510     this.animate = false;\r
13511     \r
13512     \r
13513     this.useShim = false;\r
13514     \r
13515     \r
13516     this.shim = null;\r
13517     \r
13518     if(!existingProxy){\r
13519         \r
13520         this.proxy = Ext.SplitBar.createProxy(this.orientation);\r
13521     }else{\r
13522         this.proxy = Ext.get(existingProxy).dom;\r
13523     }\r
13524     \r
13525     this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});\r
13526     \r
13527     \r
13528     this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);\r
13529     \r
13530     \r
13531     this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);\r
13532     \r
13533     \r
13534     this.dragSpecs = {};\r
13535     \r
13536     \r
13537     this.adapter = new Ext.SplitBar.BasicLayoutAdapter();\r
13538     this.adapter.init(this);\r
13539     \r
13540     if(this.orientation == Ext.SplitBar.HORIZONTAL){\r
13541         \r
13542         this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);\r
13543         this.el.addClass("x-splitbar-h");\r
13544     }else{\r
13545         \r
13546         this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);\r
13547         this.el.addClass("x-splitbar-v");\r
13548     }\r
13549     \r
13550     this.addEvents(\r
13551         \r
13552         "resize",\r
13553         \r
13554         "moved",\r
13555         \r
13556         "beforeresize",\r
13557 \r
13558         "beforeapply"\r
13559     );\r
13560 \r
13561     Ext.SplitBar.superclass.constructor.call(this);\r
13562 };\r
13563 \r
13564 Ext.extend(Ext.SplitBar, Ext.util.Observable, {\r
13565     onStartProxyDrag : function(x, y){\r
13566         this.fireEvent("beforeresize", this);\r
13567         this.overlay =  Ext.DomHelper.append(document.body,  {cls: "x-drag-overlay", html: "&#160;"}, true);\r
13568         this.overlay.unselectable();\r
13569         this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));\r
13570         this.overlay.show();\r
13571         Ext.get(this.proxy).setDisplayed("block");\r
13572         var size = this.adapter.getElementSize(this);\r
13573         this.activeMinSize = this.getMinimumSize();;\r
13574         this.activeMaxSize = this.getMaximumSize();;\r
13575         var c1 = size - this.activeMinSize;\r
13576         var c2 = Math.max(this.activeMaxSize - size, 0);\r
13577         if(this.orientation == Ext.SplitBar.HORIZONTAL){\r
13578             this.dd.resetConstraints();\r
13579             this.dd.setXConstraint(\r
13580                 this.placement == Ext.SplitBar.LEFT ? c1 : c2, \r
13581                 this.placement == Ext.SplitBar.LEFT ? c2 : c1\r
13582             );\r
13583             this.dd.setYConstraint(0, 0);\r
13584         }else{\r
13585             this.dd.resetConstraints();\r
13586             this.dd.setXConstraint(0, 0);\r
13587             this.dd.setYConstraint(\r
13588                 this.placement == Ext.SplitBar.TOP ? c1 : c2, \r
13589                 this.placement == Ext.SplitBar.TOP ? c2 : c1\r
13590             );\r
13591          }\r
13592         this.dragSpecs.startSize = size;\r
13593         this.dragSpecs.startPoint = [x, y];\r
13594         Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);\r
13595     },\r
13596     \r
13597     \r
13598     onEndProxyDrag : function(e){\r
13599         Ext.get(this.proxy).setDisplayed(false);\r
13600         var endPoint = Ext.lib.Event.getXY(e);\r
13601         if(this.overlay){\r
13602             this.overlay.remove();\r
13603             delete this.overlay;\r
13604         }\r
13605         var newSize;\r
13606         if(this.orientation == Ext.SplitBar.HORIZONTAL){\r
13607             newSize = this.dragSpecs.startSize + \r
13608                 (this.placement == Ext.SplitBar.LEFT ?\r
13609                     endPoint[0] - this.dragSpecs.startPoint[0] :\r
13610                     this.dragSpecs.startPoint[0] - endPoint[0]\r
13611                 );\r
13612         }else{\r
13613             newSize = this.dragSpecs.startSize + \r
13614                 (this.placement == Ext.SplitBar.TOP ?\r
13615                     endPoint[1] - this.dragSpecs.startPoint[1] :\r
13616                     this.dragSpecs.startPoint[1] - endPoint[1]\r
13617                 );\r
13618         }\r
13619         newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);\r
13620         if(newSize != this.dragSpecs.startSize){\r
13621             if(this.fireEvent('beforeapply', this, newSize) !== false){\r
13622                 this.adapter.setElementSize(this, newSize);\r
13623                 this.fireEvent("moved", this, newSize);\r
13624                 this.fireEvent("resize", this, newSize);\r
13625             }\r
13626         }\r
13627     },\r
13628     \r
13629     \r
13630     getAdapter : function(){\r
13631         return this.adapter;\r
13632     },\r
13633     \r
13634     \r
13635     setAdapter : function(adapter){\r
13636         this.adapter = adapter;\r
13637         this.adapter.init(this);\r
13638     },\r
13639     \r
13640     \r
13641     getMinimumSize : function(){\r
13642         return this.minSize;\r
13643     },\r
13644     \r
13645     \r
13646     setMinimumSize : function(minSize){\r
13647         this.minSize = minSize;\r
13648     },\r
13649     \r
13650     \r
13651     getMaximumSize : function(){\r
13652         return this.maxSize;\r
13653     },\r
13654     \r
13655     \r
13656     setMaximumSize : function(maxSize){\r
13657         this.maxSize = maxSize;\r
13658     },\r
13659     \r
13660     \r
13661     setCurrentSize : function(size){\r
13662         var oldAnimate = this.animate;\r
13663         this.animate = false;\r
13664         this.adapter.setElementSize(this, size);\r
13665         this.animate = oldAnimate;\r
13666     },\r
13667     \r
13668     \r
13669     destroy : function(removeEl){\r
13670         if(this.shim){\r
13671             this.shim.remove();\r
13672         }\r
13673         this.dd.unreg();\r
13674         Ext.removeNode(this.proxy);\r
13675         if(removeEl){\r
13676             this.el.remove();\r
13677         }\r
13678     }\r
13679 });\r
13680 \r
13681 \r
13682 Ext.SplitBar.createProxy = function(dir){\r
13683     var proxy = new Ext.Element(document.createElement("div"));\r
13684     proxy.unselectable();\r
13685     var cls = 'x-splitbar-proxy';\r
13686     proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));\r
13687     document.body.appendChild(proxy.dom);\r
13688     return proxy.dom;\r
13689 };\r
13690 \r
13691 \r
13692 Ext.SplitBar.BasicLayoutAdapter = function(){\r
13693 };\r
13694 \r
13695 Ext.SplitBar.BasicLayoutAdapter.prototype = {\r
13696     
13697     init : function(s){\r
13698     \r
13699     },\r
13700     \r
13701      getElementSize : function(s){\r
13702         if(s.orientation == Ext.SplitBar.HORIZONTAL){\r
13703             return s.resizingEl.getWidth();\r
13704         }else{\r
13705             return s.resizingEl.getHeight();\r
13706         }\r
13707     },\r
13708     \r
13709     \r
13710     setElementSize : function(s, newSize, onComplete){\r
13711         if(s.orientation == Ext.SplitBar.HORIZONTAL){\r
13712             if(!s.animate){\r
13713                 s.resizingEl.setWidth(newSize);\r
13714                 if(onComplete){\r
13715                     onComplete(s, newSize);\r
13716                 }\r
13717             }else{\r
13718                 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');\r
13719             }\r
13720         }else{\r
13721             \r
13722             if(!s.animate){\r
13723                 s.resizingEl.setHeight(newSize);\r
13724                 if(onComplete){\r
13725                     onComplete(s, newSize);\r
13726                 }\r
13727             }else{\r
13728                 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');\r
13729             }\r
13730         }\r
13731     }\r
13732 };\r
13733 \r
13734 \r
13735 Ext.SplitBar.AbsoluteLayoutAdapter = function(container){\r
13736     this.basic = new Ext.SplitBar.BasicLayoutAdapter();\r
13737     this.container = Ext.get(container);\r
13738 };\r
13739 \r
13740 Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {\r
13741     init : function(s){\r
13742         this.basic.init(s);\r
13743     },\r
13744     \r
13745     getElementSize : function(s){\r
13746         return this.basic.getElementSize(s);\r
13747     },\r
13748     \r
13749     setElementSize : function(s, newSize, onComplete){\r
13750         this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));\r
13751     },\r
13752     \r
13753     moveSplitter : function(s){\r
13754         var yes = Ext.SplitBar;\r
13755         switch(s.placement){\r
13756             case yes.LEFT:\r
13757                 s.el.setX(s.resizingEl.getRight());\r
13758                 break;\r
13759             case yes.RIGHT:\r
13760                 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");\r
13761                 break;\r
13762             case yes.TOP:\r
13763                 s.el.setY(s.resizingEl.getBottom());\r
13764                 break;\r
13765             case yes.BOTTOM:\r
13766                 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());\r
13767                 break;\r
13768         }\r
13769     }\r
13770 };\r
13771 \r
13772 \r
13773 Ext.SplitBar.VERTICAL = 1;\r
13774 \r
13775 \r
13776 Ext.SplitBar.HORIZONTAL = 2;\r
13777 \r
13778 \r
13779 Ext.SplitBar.LEFT = 1;\r
13780 \r
13781 \r
13782 Ext.SplitBar.RIGHT = 2;\r
13783 \r
13784 \r
13785 Ext.SplitBar.TOP = 3;\r
13786 \r
13787 \r
13788 Ext.SplitBar.BOTTOM = 4;\r
13789
13790
13791 Ext.Container = Ext.extend(Ext.BoxComponent, {
13792     
13793     
13794     
13795     
13796     
13797     
13798     
13799
13800     
13801     autoDestroy: true,
13802     
13803     
13804     defaultType: 'panel',
13805
13806         initComponent : function(){
13807         Ext.Container.superclass.initComponent.call(this);
13808
13809         this.addEvents(
13810             
13811             'afterlayout',
13812             
13813             'beforeadd',
13814             
13815             'beforeremove',
13816             
13817             'add',
13818             
13819             'remove'
13820         );
13821
13822         
13823         var items = this.items;
13824         if(items){
13825             delete this.items;
13826             if(Ext.isArray(items)){
13827                 this.add.apply(this, items);
13828             }else{
13829                 this.add(items);
13830             }
13831         }
13832     },
13833
13834         initItems : function(){
13835         if(!this.items){
13836             this.items = new Ext.util.MixedCollection(false, this.getComponentId);
13837             this.getLayout();         }
13838     },
13839
13840         setLayout : function(layout){
13841         if(this.layout && this.layout != layout){
13842             this.layout.setContainer(null);
13843         }
13844         this.initItems();
13845         this.layout = layout;
13846         layout.setContainer(this);
13847     },
13848
13849         render : function(){
13850         Ext.Container.superclass.render.apply(this, arguments);
13851         if(this.layout){
13852             if(typeof this.layout == 'string'){
13853                 this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
13854             }
13855             this.setLayout(this.layout);
13856
13857             if(this.activeItem !== undefined){
13858                 var item = this.activeItem;
13859                 delete this.activeItem;
13860                 this.layout.setActiveItem(item);
13861                 return;
13862             }
13863         }
13864         if(!this.ownerCt){
13865             this.doLayout();
13866         }
13867         if(this.monitorResize === true){
13868             Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
13869         }
13870     },
13871
13872         getLayoutTarget : function(){
13873         return this.el;
13874     },
13875
13876         getComponentId : function(comp){
13877         return comp.itemId || comp.id;
13878     },
13879
13880     
13881     add : function(comp){
13882         if(!this.items){
13883             this.initItems();
13884         }
13885         var a = arguments, len = a.length;
13886         if(len > 1){
13887             for(var i = 0; i < len; i++) {
13888                 this.add(a[i]);
13889             }
13890             return;
13891         }
13892         var c = this.lookupComponent(this.applyDefaults(comp));
13893         var pos = this.items.length;
13894         if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){
13895             this.items.add(c);
13896             c.ownerCt = this;
13897             this.fireEvent('add', this, c, pos);
13898         }
13899         return c;
13900     },
13901
13902     
13903     insert : function(index, comp){
13904         if(!this.items){
13905             this.initItems();
13906         }
13907         var a = arguments, len = a.length;
13908         if(len > 2){
13909             for(var i = len-1; i >= 1; --i) {
13910                 this.insert(index, a[i]);
13911             }
13912             return;
13913         }
13914         var c = this.lookupComponent(this.applyDefaults(comp));
13915
13916         if(c.ownerCt == this && this.items.indexOf(c) < index){
13917             --index;
13918         }
13919
13920         if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
13921             this.items.insert(index, c);
13922             c.ownerCt = this;
13923             this.fireEvent('add', this, c, index);
13924         }
13925         return c;
13926     },
13927
13928         applyDefaults : function(c){
13929         if(this.defaults){
13930             if(typeof c == 'string'){
13931                 c = Ext.ComponentMgr.get(c);
13932                 Ext.apply(c, this.defaults);
13933             }else if(!c.events){
13934                 Ext.applyIf(c, this.defaults);
13935             }else{
13936                 Ext.apply(c, this.defaults);
13937             }
13938         }
13939         return c;
13940     },
13941
13942         onBeforeAdd : function(item){
13943         if(item.ownerCt){
13944             item.ownerCt.remove(item, false);
13945         }
13946         if(this.hideBorders === true){
13947             item.border = (item.border === true);
13948         }
13949     },
13950
13951     
13952     remove : function(comp, autoDestroy){
13953         var c = this.getComponent(comp);
13954         if(c && this.fireEvent('beforeremove', this, c) !== false){
13955             this.items.remove(c);
13956             delete c.ownerCt;
13957             if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
13958                 c.destroy();
13959             }
13960             if(this.layout && this.layout.activeItem == c){
13961                 delete this.layout.activeItem;
13962             }
13963             this.fireEvent('remove', this, c);
13964         }
13965         return c;
13966     },
13967
13968     
13969     getComponent : function(comp){
13970         if(typeof comp == 'object'){
13971             return comp;
13972         }
13973         return this.items.get(comp);
13974     },
13975
13976         lookupComponent : function(comp){
13977         if(typeof comp == 'string'){
13978             return Ext.ComponentMgr.get(comp);
13979         }else if(!comp.events){
13980             return this.createComponent(comp);
13981         }
13982         return comp;
13983     },
13984
13985         createComponent : function(config){
13986         return Ext.ComponentMgr.create(config, this.defaultType);
13987     },
13988
13989     
13990     doLayout : function(shallow){
13991         if(this.rendered && this.layout){
13992             this.layout.layout();
13993         }
13994         if(shallow !== false && this.items){
13995             var cs = this.items.items;
13996             for(var i = 0, len = cs.length; i < len; i++) {
13997                 var c  = cs[i];
13998                 if(c.doLayout){
13999                     c.doLayout();
14000                 }
14001             }
14002         }
14003     },
14004
14005     
14006     getLayout : function(){
14007         if(!this.layout){
14008             var layout = new Ext.layout.ContainerLayout(this.layoutConfig);
14009             this.setLayout(layout);
14010         }
14011         return this.layout;
14012     },
14013
14014         onDestroy : function(){
14015         if(this.items){
14016             var cs = this.items.items;
14017             for(var i = 0, len = cs.length; i < len; i++) {
14018                 Ext.destroy(cs[i]);
14019             }
14020         }
14021         if(this.monitorResize){
14022             Ext.EventManager.removeResizeListener(this.doLayout, this);
14023         }
14024         Ext.Container.superclass.onDestroy.call(this);
14025     },
14026
14027     
14028     bubble : function(fn, scope, args){
14029         var p = this;
14030         while(p){
14031             if(fn.apply(scope || p, args || [p]) === false){
14032                 break;
14033             }
14034             p = p.ownerCt;
14035         }
14036     },
14037
14038     
14039     cascade : function(fn, scope, args){
14040         if(fn.apply(scope || this, args || [this]) !== false){
14041             if(this.items){
14042                 var cs = this.items.items;
14043                 for(var i = 0, len = cs.length; i < len; i++){
14044                     if(cs[i].cascade){
14045                         cs[i].cascade(fn, scope, args);
14046                     }else{
14047                         fn.apply(scope || this, args || [cs[i]]);
14048                     }
14049                 }
14050             }
14051         }
14052     },
14053
14054     
14055     findById : function(id){
14056         var m, ct = this;
14057         this.cascade(function(c){
14058             if(ct != c && c.id === id){
14059                 m = c;
14060                 return false;
14061             }
14062         });
14063         return m || null;
14064     },
14065
14066     
14067     findByType : function(xtype){
14068         return typeof xtype == 'function' ?
14069             this.findBy(function(c){
14070                 return c.constructor === xtype;
14071             }) :
14072             this.findBy(function(c){
14073                 return c.constructor.xtype === xtype;
14074             });
14075     },
14076
14077     
14078     find : function(prop, value){
14079         return this.findBy(function(c){
14080             return c[prop] === value;
14081         });
14082     },
14083
14084     
14085     findBy : function(fn, scope){
14086         var m = [], ct = this;
14087         this.cascade(function(c){
14088             if(ct != c && fn.call(scope || c, c, ct) === true){
14089                 m.push(c);
14090             }
14091         });
14092         return m;
14093     }
14094 });
14095
14096 Ext.Container.LAYOUTS = {};
14097 Ext.reg('container', Ext.Container);
14098
14099 Ext.layout.ContainerLayout = function(config){
14100     Ext.apply(this, config);
14101 };
14102
14103 Ext.layout.ContainerLayout.prototype = {
14104     
14105     
14106
14107     
14108
14109         monitorResize:false,
14110         activeItem : null,
14111
14112         layout : function(){
14113         var target = this.container.getLayoutTarget();
14114         this.onLayout(this.container, target);
14115         this.container.fireEvent('afterlayout', this.container, this);
14116     },
14117
14118         onLayout : function(ct, target){
14119         this.renderAll(ct, target);
14120     },
14121
14122         isValidParent : function(c, target){
14123                 var el = c.getPositionEl ? c.getPositionEl() : c.getEl();
14124                 return el.dom.parentNode == target.dom;
14125     },
14126
14127         renderAll : function(ct, target){
14128         var items = ct.items.items;
14129         for(var i = 0, len = items.length; i < len; i++) {
14130             var c = items[i];
14131             if(c && (!c.rendered || !this.isValidParent(c, target))){
14132                 this.renderItem(c, i, target);
14133             }
14134         }
14135     },
14136
14137         renderItem : function(c, position, target){
14138         if(c && !c.rendered){
14139             c.render(target, position);
14140             if(this.extraCls){
14141                 var t = c.getPositionEl ? c.getPositionEl() : c;
14142                 t.addClass(this.extraCls);
14143             }
14144             if (this.renderHidden && c != this.activeItem) {
14145                 c.hide();
14146             }
14147         }else if(c && !this.isValidParent(c, target)){
14148             if(this.extraCls){
14149                 c.addClass(this.extraCls);
14150             }
14151             if(typeof position == 'number'){
14152                 position = target.dom.childNodes[position];
14153             }
14154             target.dom.insertBefore(c.getEl().dom, position || null);
14155             if (this.renderHidden && c != this.activeItem) {
14156                 c.hide();
14157             }
14158         }
14159     },
14160
14161         onResize: function(){
14162         if(this.container.collapsed){
14163             return;
14164         }
14165         var b = this.container.bufferResize;
14166         if(b){
14167             if(!this.resizeTask){
14168                 this.resizeTask = new Ext.util.DelayedTask(this.layout, this);
14169                 this.resizeBuffer = typeof b == 'number' ? b : 100;
14170             }
14171             this.resizeTask.delay(this.resizeBuffer);
14172         }else{
14173             this.layout();
14174         }
14175     },
14176
14177         setContainer : function(ct){
14178         if(this.monitorResize && ct != this.container){
14179             if(this.container){
14180                 this.container.un('resize', this.onResize, this);
14181             }
14182             if(ct){
14183                 ct.on('resize', this.onResize, this);
14184             }
14185         }
14186         this.container = ct;
14187     },
14188
14189         parseMargins : function(v){
14190         var ms = v.split(' ');
14191         var len = ms.length;
14192         if(len == 1){
14193             ms[1] = ms[0];
14194             ms[2] = ms[0];
14195             ms[3] = ms[0];
14196         }
14197         if(len == 2){
14198             ms[2] = ms[0];
14199             ms[3] = ms[1];
14200         }
14201         return {
14202             top:parseInt(ms[0], 10) || 0,
14203             right:parseInt(ms[1], 10) || 0,
14204             bottom:parseInt(ms[2], 10) || 0,
14205             left:parseInt(ms[3], 10) || 0
14206         };
14207     }
14208 };
14209 Ext.Container.LAYOUTS['auto'] = Ext.layout.ContainerLayout;
14210 \r
14211 Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {\r
14212     
14213     monitorResize:true,\r
14214 \r
14215     
14216     onLayout : function(ct, target){\r
14217         Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);\r
14218         if(!this.container.collapsed){\r
14219             this.setItemSize(this.activeItem || ct.items.itemAt(0), target.getStyleSize());\r
14220         }\r
14221     },\r
14222 \r
14223     
14224     setItemSize : function(item, size){\r
14225         if(item && size.height > 0){ 
14226             item.setSize(size);\r
14227         }\r
14228     }\r
14229 });\r
14230 Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
14231 \r
14232 Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {\r
14233     \r
14234     deferredRender : false,\r
14235 \r
14236     
14237     renderHidden : true,\r
14238 \r
14239     \r
14240     setActiveItem : function(item){\r
14241         item = this.container.getComponent(item);\r
14242         if(this.activeItem != item){\r
14243             if(this.activeItem){\r
14244                 this.activeItem.hide();\r
14245             }\r
14246             this.activeItem = item;\r
14247             item.show();\r
14248             this.layout();\r
14249         }\r
14250     },\r
14251 \r
14252     
14253     renderAll : function(ct, target){\r
14254         if(this.deferredRender){\r
14255             this.renderItem(this.activeItem, undefined, target);\r
14256         }else{\r
14257             Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);\r
14258         }\r
14259     }\r
14260 });\r
14261 Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
14262 \r
14263 Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {\r
14264     
14265     monitorResize:true,\r
14266 \r
14267     
14268     getAnchorViewSize : function(ct, target){\r
14269         return target.dom == document.body ?\r
14270                    target.getViewSize() : target.getStyleSize();\r
14271     },\r
14272 \r
14273     
14274     onLayout : function(ct, target){\r
14275         Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);\r
14276 \r
14277         var size = this.getAnchorViewSize(ct, target);\r
14278 \r
14279         var w = size.width, h = size.height;\r
14280 \r
14281         if(w < 20 || h < 20){\r
14282             return;\r
14283         }\r
14284 \r
14285         
14286         var aw, ah;\r
14287         if(ct.anchorSize){\r
14288             if(typeof ct.anchorSize == 'number'){\r
14289                 aw = ct.anchorSize;\r
14290             }else{\r
14291                 aw = ct.anchorSize.width;\r
14292                 ah = ct.anchorSize.height;\r
14293             }\r
14294         }else{\r
14295             aw = ct.initialConfig.width;\r
14296             ah = ct.initialConfig.height;\r
14297         }\r
14298 \r
14299         var cs = ct.items.items, len = cs.length, i, c, a, cw, ch;\r
14300         for(i = 0; i < len; i++){\r
14301             c = cs[i];\r
14302             if(c.anchor){\r
14303                 a = c.anchorSpec;\r
14304                 if(!a){ 
14305                     var vs = c.anchor.split(' ');\r
14306                     c.anchorSpec = a = {\r
14307                         right: this.parseAnchor(vs[0], c.initialConfig.width, aw),\r
14308                         bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)\r
14309                     };\r
14310                 }\r
14311                 cw = a.right ? this.adjustWidthAnchor(a.right(w), c) : undefined;\r
14312                 ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;\r
14313 \r
14314                 if(cw || ch){\r
14315                     c.setSize(cw || undefined, ch || undefined);\r
14316                 }\r
14317             }\r
14318         }\r
14319     },\r
14320 \r
14321     
14322     parseAnchor : function(a, start, cstart){\r
14323         if(a && a != 'none'){\r
14324             var last;\r
14325             if(/^(r|right|b|bottom)$/i.test(a)){   
14326                 var diff = cstart - start;\r
14327                 return function(v){\r
14328                     if(v !== last){\r
14329                         last = v;\r
14330                         return v - diff;\r
14331                     }\r
14332                 }\r
14333             }else if(a.indexOf('%') != -1){\r
14334                 var ratio = parseFloat(a.replace('%', ''))*.01;   
14335                 return function(v){\r
14336                     if(v !== last){\r
14337                         last = v;\r
14338                         return Math.floor(v*ratio);\r
14339                     }\r
14340                 }\r
14341             }else{\r
14342                 a = parseInt(a, 10);\r
14343                 if(!isNaN(a)){                            
14344                     return function(v){\r
14345                         if(v !== last){\r
14346                             last = v;\r
14347                             return v + a;\r
14348                         }\r
14349                     }\r
14350                 }\r
14351             }\r
14352         }\r
14353         return false;\r
14354     },\r
14355 \r
14356     
14357     adjustWidthAnchor : function(value, comp){\r
14358         return value;\r
14359     },\r
14360 \r
14361     
14362     adjustHeightAnchor : function(value, comp){\r
14363         return value;\r
14364     }\r
14365     \r
14366     \r
14367 });\r
14368 Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
14369 \r
14370 Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {\r
14371     
14372     monitorResize:true,\r
14373     
14374     extraCls: 'x-column',\r
14375 \r
14376     scrollOffset : 0,\r
14377 \r
14378     
14379     isValidParent : function(c, target){\r
14380         return c.getEl().dom.parentNode == this.innerCt.dom;\r
14381     },\r
14382 \r
14383     
14384     onLayout : function(ct, target){\r
14385         var cs = ct.items.items, len = cs.length, c, i;\r
14386 \r
14387         if(!this.innerCt){\r
14388             target.addClass('x-column-layout-ct');\r
14389 \r
14390             
14391             
14392             this.innerCt = target.createChild({cls:'x-column-inner'});\r
14393             this.innerCt.createChild({cls:'x-clear'});\r
14394         }\r
14395         this.renderAll(ct, this.innerCt);\r
14396 \r
14397         var size = target.getViewSize();\r
14398 \r
14399         if(size.width < 1 && size.height < 1){ 
14400             return;\r
14401         }\r
14402 \r
14403         var w = size.width - target.getPadding('lr') - this.scrollOffset,\r
14404             h = size.height - target.getPadding('tb'),\r
14405             pw = w;\r
14406 \r
14407         this.innerCt.setWidth(w);\r
14408         \r
14409         
14410         
14411 \r
14412         for(i = 0; i < len; i++){\r
14413             c = cs[i];\r
14414             if(!c.columnWidth){\r
14415                 pw -= (c.getSize().width + c.getEl().getMargins('lr'));\r
14416             }\r
14417         }\r
14418 \r
14419         pw = pw < 0 ? 0 : pw;\r
14420 \r
14421         for(i = 0; i < len; i++){\r
14422             c = cs[i];\r
14423             if(c.columnWidth){\r
14424                 c.setSize(Math.floor(c.columnWidth*pw) - c.getEl().getMargins('lr'));\r
14425             }\r
14426         }\r
14427     }\r
14428     \r
14429     \r
14430 });\r
14431 \r
14432 Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
14433
14434 Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
14435         monitorResize:true,
14436         rendered : false,
14437
14438         onLayout : function(ct, target){
14439         var collapsed;
14440         if(!this.rendered){
14441             target.position();
14442             target.addClass('x-border-layout-ct');
14443             var items = ct.items.items;
14444             collapsed = [];
14445             for(var i = 0, len = items.length; i < len; i++) {
14446                 var c = items[i];
14447                 var pos = c.region;
14448                 if(c.collapsed){
14449                     collapsed.push(c);
14450                 }
14451                 c.collapsed = false;
14452                 if(!c.rendered){
14453                     c.cls = c.cls ? c.cls +' x-border-panel' : 'x-border-panel';
14454                     c.render(target, i);
14455                 }
14456                 this[pos] = pos != 'center' && c.split ?
14457                     new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
14458                     new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
14459                 this[pos].render(target, c);
14460             }
14461             this.rendered = true;
14462         }
14463
14464         var size = target.getViewSize();
14465         if(size.width < 20 || size.height < 20){             if(collapsed){
14466                 this.restoreCollapsed = collapsed;
14467             }
14468             return;
14469         }else if(this.restoreCollapsed){
14470             collapsed = this.restoreCollapsed;
14471             delete this.restoreCollapsed;
14472         }
14473
14474         var w = size.width, h = size.height;
14475         var centerW = w, centerH = h, centerY = 0, centerX = 0;
14476
14477         var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
14478         if(!c){
14479             throw 'No center region defined in BorderLayout ' + ct.id;
14480         }
14481
14482         if(n && n.isVisible()){
14483             var b = n.getSize();
14484             var m = n.getMargins();
14485             b.width = w - (m.left+m.right);
14486             b.x = m.left;
14487             b.y = m.top;
14488             centerY = b.height + b.y + m.bottom;
14489             centerH -= centerY;
14490             n.applyLayout(b);
14491         }
14492         if(s && s.isVisible()){
14493             var b = s.getSize();
14494             var m = s.getMargins();
14495             b.width = w - (m.left+m.right);
14496             b.x = m.left;
14497             var totalHeight = (b.height + m.top + m.bottom);
14498             b.y = h - totalHeight + m.top;
14499             centerH -= totalHeight;
14500             s.applyLayout(b);
14501         }
14502         if(west && west.isVisible()){
14503             var b = west.getSize();
14504             var m = west.getMargins();
14505             b.height = centerH - (m.top+m.bottom);
14506             b.x = m.left;
14507             b.y = centerY + m.top;
14508             var totalWidth = (b.width + m.left + m.right);
14509             centerX += totalWidth;
14510             centerW -= totalWidth;
14511             west.applyLayout(b);
14512         }
14513         if(e && e.isVisible()){
14514             var b = e.getSize();
14515             var m = e.getMargins();
14516             b.height = centerH - (m.top+m.bottom);
14517             var totalWidth = (b.width + m.left + m.right);
14518             b.x = w - totalWidth + m.left;
14519             b.y = centerY + m.top;
14520             centerW -= totalWidth;
14521             e.applyLayout(b);
14522         }
14523
14524         var m = c.getMargins();
14525         var centerBox = {
14526             x: centerX + m.left,
14527             y: centerY + m.top,
14528             width: centerW - (m.left+m.right),
14529             height: centerH - (m.top+m.bottom)
14530         };
14531         c.applyLayout(centerBox);
14532
14533         if(collapsed){
14534             for(var i = 0, len = collapsed.length; i < len; i++){
14535                 collapsed[i].collapse(false);
14536             }
14537         }
14538
14539         if(Ext.isIE && Ext.isStrict){             target.repaint();
14540         }
14541     }
14542     
14543     
14544 });
14545
14546
14547 Ext.layout.BorderLayout.Region = function(layout, config, pos){
14548     Ext.apply(this, config);
14549     this.layout = layout;
14550     this.position = pos;
14551     this.state = {};
14552     if(typeof this.margins == 'string'){
14553         this.margins = this.layout.parseMargins(this.margins);
14554     }
14555     this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
14556     if(this.collapsible){
14557         if(typeof this.cmargins == 'string'){
14558             this.cmargins = this.layout.parseMargins(this.cmargins);
14559         }
14560         if(this.collapseMode == 'mini' && !this.cmargins){
14561             this.cmargins = {left:0,top:0,right:0,bottom:0};
14562         }else{
14563             this.cmargins = Ext.applyIf(this.cmargins || {},
14564                 pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
14565         }
14566     }
14567 };
14568
14569 Ext.layout.BorderLayout.Region.prototype = {
14570     
14571     
14572     
14573     
14574     
14575     
14576     collapsible : false,
14577     
14578     split:false,
14579     
14580     floatable: true,
14581     
14582     minWidth:50,
14583     
14584     minHeight:50,
14585
14586         defaultMargins : {left:0,top:0,right:0,bottom:0},
14587         defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
14588         defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
14589
14590     
14591     isCollapsed : false,
14592
14593     
14594     
14595     
14596
14597         render : function(ct, p){
14598         this.panel = p;
14599         p.el.enableDisplayMode();
14600         this.targetEl = ct;
14601         this.el = p.el;
14602
14603         var gs = p.getState, ps = this.position;
14604         p.getState = function(){
14605             return Ext.apply(gs.call(p) || {}, this.state);
14606         }.createDelegate(this);
14607
14608         if(ps != 'center'){
14609             p.allowQueuedExpand = false;
14610             p.on({
14611                 beforecollapse: this.beforeCollapse,
14612                 collapse: this.onCollapse,
14613                 beforeexpand: this.beforeExpand,
14614                 expand: this.onExpand,
14615                 hide: this.onHide,
14616                 show: this.onShow,
14617                 scope: this
14618             });
14619             if(this.collapsible){
14620                 p.collapseEl = 'el';
14621                 p.slideAnchor = this.getSlideAnchor();
14622             }
14623             if(p.tools && p.tools.toggle){
14624                 p.tools.toggle.addClass('x-tool-collapse-'+ps);
14625                 p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
14626             }
14627         }
14628     },
14629
14630         getCollapsedEl : function(){
14631         if(!this.collapsedEl){
14632             if(!this.toolTemplate){
14633                 var tt = new Ext.Template(
14634                      '<div class="x-tool x-tool-{id}">&#160;</div>'
14635                 );
14636                 tt.disableFormats = true;
14637                 tt.compile();
14638                 Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
14639             }
14640             this.collapsedEl = this.targetEl.createChild({
14641                 cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
14642                 id: this.panel.id + '-xcollapsed'
14643             });
14644             this.collapsedEl.enableDisplayMode('block');
14645
14646             if(this.collapseMode == 'mini'){
14647                 this.collapsedEl.addClass('x-layout-cmini-'+this.position);
14648                 this.miniCollapsedEl = this.collapsedEl.createChild({
14649                     cls: "x-layout-mini x-layout-mini-"+this.position, html: "&#160;"
14650                 });
14651                 this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
14652                 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14653                 this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
14654             }else {
14655                 var t = this.toolTemplate.append(
14656                         this.collapsedEl.dom,
14657                         {id:'expand-'+this.position}, true);
14658                 t.addClassOnOver('x-tool-expand-'+this.position+'-over');
14659                 t.on('click', this.onExpandClick, this, {stopEvent:true});
14660                 
14661                 if(this.floatable !== false){
14662                    this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14663                    this.collapsedEl.on("click", this.collapseClick, this);
14664                 }
14665             }
14666         }
14667         return this.collapsedEl;
14668     },
14669
14670         onExpandClick : function(e){
14671         if(this.isSlid){
14672             this.afterSlideIn();
14673             this.panel.expand(false);
14674         }else{
14675             this.panel.expand();
14676         }
14677     },
14678
14679         onCollapseClick : function(e){
14680         this.panel.collapse();
14681     },
14682
14683         beforeCollapse : function(p, animate){
14684         this.lastAnim = animate;
14685         if(this.splitEl){
14686             this.splitEl.hide();
14687         }
14688         this.getCollapsedEl().show();
14689         this.panel.el.setStyle('z-index', 100);
14690         this.isCollapsed = true;
14691         this.layout.layout();
14692     },
14693
14694         onCollapse : function(animate){
14695         this.panel.el.setStyle('z-index', 1);
14696         if(this.lastAnim === false || this.panel.animCollapse === false){
14697             this.getCollapsedEl().dom.style.visibility = 'visible';
14698         }else{
14699             this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
14700         }
14701         this.state.collapsed = true;
14702         this.panel.saveState();
14703     },
14704
14705         beforeExpand : function(animate){
14706         var c = this.getCollapsedEl();
14707         this.el.show();
14708         if(this.position == 'east' || this.position == 'west'){
14709             this.panel.setSize(undefined, c.getHeight());
14710         }else{
14711             this.panel.setSize(c.getWidth(), undefined);
14712         }
14713         c.hide();
14714         c.dom.style.visibility = 'hidden';
14715         this.panel.el.setStyle('z-index', 100);
14716     },
14717
14718         onExpand : function(){
14719         this.isCollapsed = false;
14720         if(this.splitEl){
14721             this.splitEl.show();
14722         }
14723         this.layout.layout();
14724         this.panel.el.setStyle('z-index', 1);
14725         this.state.collapsed = false;
14726         this.panel.saveState();
14727     },
14728
14729         collapseClick : function(e){
14730         if(this.isSlid){
14731            e.stopPropagation();
14732            this.slideIn();
14733         }else{
14734            e.stopPropagation();
14735            this.slideOut();
14736         }
14737     },
14738
14739         onHide : function(){
14740         if(this.isCollapsed){
14741             this.getCollapsedEl().hide();
14742         }else if(this.splitEl){
14743             this.splitEl.hide();
14744         }
14745     },
14746
14747         onShow : function(){
14748         if(this.isCollapsed){
14749             this.getCollapsedEl().show();
14750         }else if(this.splitEl){
14751             this.splitEl.show();
14752         }
14753     },
14754
14755     
14756     isVisible : function(){
14757         return !this.panel.hidden;
14758     },
14759
14760     
14761     getMargins : function(){
14762         return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
14763     },
14764
14765     
14766     getSize : function(){
14767         return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
14768     },
14769
14770     
14771     setPanel : function(panel){
14772         this.panel = panel;
14773     },
14774
14775     
14776     getMinWidth: function(){
14777         return this.minWidth;
14778     },
14779
14780     
14781     getMinHeight: function(){
14782         return this.minHeight;
14783     },
14784
14785         applyLayoutCollapsed : function(box){
14786         var ce = this.getCollapsedEl();
14787         ce.setLeftTop(box.x, box.y);
14788         ce.setSize(box.width, box.height);
14789     },
14790
14791         applyLayout : function(box){
14792         if(this.isCollapsed){
14793             this.applyLayoutCollapsed(box);
14794         }else{
14795             this.panel.setPosition(box.x, box.y);
14796             this.panel.setSize(box.width, box.height);
14797         }
14798     },
14799
14800         beforeSlide: function(){
14801         this.panel.beforeEffect();
14802     },
14803
14804         afterSlide : function(){
14805         this.panel.afterEffect();
14806     },
14807
14808         initAutoHide : function(){
14809         if(this.autoHide !== false){
14810             if(!this.autoHideHd){
14811                 var st = new Ext.util.DelayedTask(this.slideIn, this);
14812                 this.autoHideHd = {
14813                     "mouseout": function(e){
14814                         if(!e.within(this.el, true)){
14815                             st.delay(500);
14816                         }
14817                     },
14818                     "mouseover" : function(e){
14819                         st.cancel();
14820                     },
14821                     scope : this
14822                 };
14823             }
14824             this.el.on(this.autoHideHd);
14825         }
14826     },
14827
14828         clearAutoHide : function(){
14829         if(this.autoHide !== false){
14830             this.el.un("mouseout", this.autoHideHd.mouseout);
14831             this.el.un("mouseover", this.autoHideHd.mouseover);
14832         }
14833     },
14834
14835         clearMonitor : function(){
14836         Ext.getDoc().un("click", this.slideInIf, this);
14837     },
14838
14839             slideOut : function(){
14840         if(this.isSlid || this.el.hasActiveFx()){
14841             return;
14842         }
14843         this.isSlid = true;
14844         var ts = this.panel.tools;
14845         if(ts && ts.toggle){
14846             ts.toggle.hide();
14847         }
14848         this.el.show();
14849         if(this.position == 'east' || this.position == 'west'){
14850             this.panel.setSize(undefined, this.collapsedEl.getHeight());
14851         }else{
14852             this.panel.setSize(this.collapsedEl.getWidth(), undefined);
14853         }
14854         this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
14855         this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
14856         this.el.setStyle("z-index", 102);
14857         if(this.animFloat !== false){
14858             this.beforeSlide();
14859             this.el.slideIn(this.getSlideAnchor(), {
14860                 callback: function(){
14861                     this.afterSlide();
14862                     this.initAutoHide();
14863                     Ext.getDoc().on("click", this.slideInIf, this);
14864                 },
14865                 scope: this,
14866                 block: true
14867             });
14868         }else{
14869             this.initAutoHide();
14870              Ext.getDoc().on("click", this.slideInIf, this);
14871         }
14872     },
14873
14874         afterSlideIn : function(){
14875         this.clearAutoHide();
14876         this.isSlid = false;
14877         this.clearMonitor();
14878         this.el.setStyle("z-index", "");
14879         this.el.dom.style.left = this.restoreLT[0];
14880         this.el.dom.style.top = this.restoreLT[1];
14881
14882         var ts = this.panel.tools;
14883         if(ts && ts.toggle){
14884             ts.toggle.show();
14885         }
14886     },
14887
14888         slideIn : function(cb){
14889         if(!this.isSlid || this.el.hasActiveFx()){
14890             Ext.callback(cb);
14891             return;
14892         }
14893         this.isSlid = false;
14894         if(this.animFloat !== false){
14895             this.beforeSlide();
14896             this.el.slideOut(this.getSlideAnchor(), {
14897                 callback: function(){
14898                     this.el.hide();
14899                     this.afterSlide();
14900                     this.afterSlideIn();
14901                     Ext.callback(cb);
14902                 },
14903                 scope: this,
14904                 block: true
14905             });
14906         }else{
14907             this.el.hide();
14908             this.afterSlideIn();
14909         }
14910     },
14911
14912         slideInIf : function(e){
14913         if(!e.within(this.el)){
14914             this.slideIn();
14915         }
14916     },
14917
14918         anchors : {
14919         "west" : "left",
14920         "east" : "right",
14921         "north" : "top",
14922         "south" : "bottom"
14923     },
14924
14925         sanchors : {
14926         "west" : "l",
14927         "east" : "r",
14928         "north" : "t",
14929         "south" : "b"
14930     },
14931
14932         canchors : {
14933         "west" : "tl-tr",
14934         "east" : "tr-tl",
14935         "north" : "tl-bl",
14936         "south" : "bl-tl"
14937     },
14938
14939         getAnchor : function(){
14940         return this.anchors[this.position];
14941     },
14942
14943         getCollapseAnchor : function(){
14944         return this.canchors[this.position];
14945     },
14946
14947         getSlideAnchor : function(){
14948         return this.sanchors[this.position];
14949     },
14950
14951         getAlignAdj : function(){
14952         var cm = this.cmargins;
14953         switch(this.position){
14954             case "west":
14955                 return [0, 0];
14956             break;
14957             case "east":
14958                 return [0, 0];
14959             break;
14960             case "north":
14961                 return [0, 0];
14962             break;
14963             case "south":
14964                 return [0, 0];
14965             break;
14966         }
14967     },
14968
14969         getExpandAdj : function(){
14970         var c = this.collapsedEl, cm = this.cmargins;
14971         switch(this.position){
14972             case "west":
14973                 return [-(cm.right+c.getWidth()+cm.left), 0];
14974             break;
14975             case "east":
14976                 return [cm.right+c.getWidth()+cm.left, 0];
14977             break;
14978             case "north":
14979                 return [0, -(cm.top+cm.bottom+c.getHeight())];
14980             break;
14981             case "south":
14982                 return [0, cm.top+cm.bottom+c.getHeight()];
14983             break;
14984         }
14985     }
14986 };
14987
14988
14989 Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
14990     Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
14991         this.applyLayout = this.applyFns[pos];
14992 };
14993
14994 Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
14995     
14996     splitTip : "Drag to resize.",
14997     
14998     collapsibleSplitTip : "Drag to resize. Double click to hide.",
14999     
15000     useSplitTips : false,
15001
15002         splitSettings : {
15003         north : {
15004             orientation: Ext.SplitBar.VERTICAL,
15005             placement: Ext.SplitBar.TOP,
15006             maxFn : 'getVMaxSize',
15007             minProp: 'minHeight',
15008             maxProp: 'maxHeight'
15009         },
15010         south : {
15011             orientation: Ext.SplitBar.VERTICAL,
15012             placement: Ext.SplitBar.BOTTOM,
15013             maxFn : 'getVMaxSize',
15014             minProp: 'minHeight',
15015             maxProp: 'maxHeight'
15016         },
15017         east : {
15018             orientation: Ext.SplitBar.HORIZONTAL,
15019             placement: Ext.SplitBar.RIGHT,
15020             maxFn : 'getHMaxSize',
15021             minProp: 'minWidth',
15022             maxProp: 'maxWidth'
15023         },
15024         west : {
15025             orientation: Ext.SplitBar.HORIZONTAL,
15026             placement: Ext.SplitBar.LEFT,
15027             maxFn : 'getHMaxSize',
15028             minProp: 'minWidth',
15029             maxProp: 'maxWidth'
15030         }
15031     },
15032
15033         applyFns : {
15034         west : function(box){
15035             if(this.isCollapsed){
15036                 return this.applyLayoutCollapsed(box);
15037             }
15038             var sd = this.splitEl.dom, s = sd.style;
15039             this.panel.setPosition(box.x, box.y);
15040             var sw = sd.offsetWidth;
15041             s.left = (box.x+box.width-sw)+'px';
15042             s.top = (box.y)+'px';
15043             s.height = Math.max(0, box.height)+'px';
15044             this.panel.setSize(box.width-sw, box.height);
15045         },
15046         east : function(box){
15047             if(this.isCollapsed){
15048                 return this.applyLayoutCollapsed(box);
15049             }
15050             var sd = this.splitEl.dom, s = sd.style;
15051             var sw = sd.offsetWidth;
15052             this.panel.setPosition(box.x+sw, box.y);
15053             s.left = (box.x)+'px';
15054             s.top = (box.y)+'px';
15055             s.height = Math.max(0, box.height)+'px';
15056             this.panel.setSize(box.width-sw, box.height);
15057         },
15058         north : function(box){
15059             if(this.isCollapsed){
15060                 return this.applyLayoutCollapsed(box);
15061             }
15062             var sd = this.splitEl.dom, s = sd.style;
15063             var sh = sd.offsetHeight;
15064             this.panel.setPosition(box.x, box.y);
15065             s.left = (box.x)+'px';
15066             s.top = (box.y+box.height-sh)+'px';
15067             s.width = Math.max(0, box.width)+'px';
15068             this.panel.setSize(box.width, box.height-sh);
15069         },
15070         south : function(box){
15071             if(this.isCollapsed){
15072                 return this.applyLayoutCollapsed(box);
15073             }
15074             var sd = this.splitEl.dom, s = sd.style;
15075             var sh = sd.offsetHeight;
15076             this.panel.setPosition(box.x, box.y+sh);
15077             s.left = (box.x)+'px';
15078             s.top = (box.y)+'px';
15079             s.width = Math.max(0, box.width)+'px';
15080             this.panel.setSize(box.width, box.height-sh);
15081         }
15082     },
15083
15084         render : function(ct, p){
15085         Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
15086
15087         var ps = this.position;
15088
15089         this.splitEl = ct.createChild({
15090             cls: "x-layout-split x-layout-split-"+ps, html: "&#160;",
15091             id: this.panel.id + '-xsplit'
15092         });
15093
15094         if(this.collapseMode == 'mini'){
15095             this.miniSplitEl = this.splitEl.createChild({
15096                 cls: "x-layout-mini x-layout-mini-"+ps, html: "&#160;"
15097             });
15098             this.miniSplitEl.addClassOnOver('x-layout-mini-over');
15099             this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
15100         }
15101
15102         var s = this.splitSettings[ps];
15103
15104         this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
15105         this.split.placement = s.placement;
15106         this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
15107         this.split.minSize = this.minSize || this[s.minProp];
15108         this.split.on("beforeapply", this.onSplitMove, this);
15109         this.split.useShim = this.useShim === true;
15110         this.maxSize = this.maxSize || this[s.maxProp];
15111
15112         if(p.hidden){
15113             this.splitEl.hide();
15114         }
15115
15116         if(this.useSplitTips){
15117             this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
15118         }
15119         if(this.collapsible){
15120             this.splitEl.on("dblclick", this.onCollapseClick,  this);
15121         }
15122     },
15123
15124         getSize : function(){
15125         if(this.isCollapsed){
15126             return this.collapsedEl.getSize();
15127         }
15128         var s = this.panel.getSize();
15129         if(this.position == 'north' || this.position == 'south'){
15130             s.height += this.splitEl.dom.offsetHeight;
15131         }else{
15132             s.width += this.splitEl.dom.offsetWidth;
15133         }
15134         return s;
15135     },
15136
15137         getHMaxSize : function(){
15138          var cmax = this.maxSize || 10000;
15139          var center = this.layout.center;
15140          return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
15141     },
15142
15143         getVMaxSize : function(){
15144         var cmax = this.maxSize || 10000;
15145         var center = this.layout.center;
15146         return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
15147     },
15148
15149         onSplitMove : function(split, newSize){
15150         var s = this.panel.getSize();
15151         this.lastSplitSize = newSize;
15152         if(this.position == 'north' || this.position == 'south'){
15153             this.panel.setSize(s.width, newSize);
15154             this.state.height = newSize;
15155         }else{
15156             this.panel.setSize(newSize, s.height);
15157             this.state.width = newSize;
15158         }
15159         this.layout.layout();
15160         this.panel.saveState();
15161         return false;
15162     },
15163
15164     
15165     getSplitBar : function(){
15166         return this.split;
15167     }
15168 });
15169
15170 Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
15171
15172 Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
15173     
15174     
15175     
15176     labelSeparator : ':',
15177
15178         getAnchorViewSize : function(ct, target){
15179         return ct.body.getStyleSize();
15180     },
15181
15182         setContainer : function(ct){
15183         Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
15184
15185         if(ct.labelAlign){
15186             ct.addClass('x-form-label-'+ct.labelAlign);
15187         }
15188
15189         if(ct.hideLabels){
15190             this.labelStyle = "display:none";
15191             this.elementStyle = "padding-left:0;";
15192             this.labelAdjust = 0;
15193         }else{
15194             this.labelSeparator = ct.labelSeparator || this.labelSeparator;
15195             ct.labelWidth = ct.labelWidth || 100;
15196             if(typeof ct.labelWidth == 'number'){
15197                 var pad = (typeof ct.labelPad == 'number' ? ct.labelPad : 5);
15198                 this.labelAdjust = ct.labelWidth+pad;
15199                 this.labelStyle = "width:"+ct.labelWidth+"px;";
15200                 this.elementStyle = "padding-left:"+(ct.labelWidth+pad)+'px';
15201             }
15202             if(ct.labelAlign == 'top'){
15203                 this.labelStyle = "width:auto;";
15204                 this.labelAdjust = 0;
15205                 this.elementStyle = "padding-left:0;";
15206             }
15207         }
15208
15209         if(!this.fieldTpl){
15210                         var t = new Ext.Template(
15211                 '<div class="x-form-item {5}" tabIndex="-1">',
15212                     '<label for="{0}" style="{2}" class="x-form-item-label">{1}{4}</label>',
15213                     '<div class="x-form-element" id="x-form-el-{0}" style="{3}">',
15214                     '</div><div class="{6}"></div>',
15215                 '</div>'
15216             );
15217             t.disableFormats = true;
15218             t.compile();
15219             Ext.layout.FormLayout.prototype.fieldTpl = t;
15220         }
15221     },
15222
15223         renderItem : function(c, position, target){
15224         if(c && !c.rendered && c.isFormField && c.inputType != 'hidden'){
15225             var args = [
15226                    c.id, c.fieldLabel,
15227                    c.labelStyle||this.labelStyle||'',
15228                    this.elementStyle||'',
15229                    typeof c.labelSeparator == 'undefined' ? this.labelSeparator : c.labelSeparator,
15230                    (c.itemCls||this.container.itemCls||'') + (c.hideLabel ? ' x-hide-label' : ''),
15231                    c.clearCls || 'x-form-clear-left' 
15232             ];
15233             if(typeof position == 'number'){
15234                 position = target.dom.childNodes[position] || null;
15235             }
15236             if(position){
15237                 this.fieldTpl.insertBefore(position, args);
15238             }else{
15239                 this.fieldTpl.append(target, args);
15240             }
15241             c.render('x-form-el-'+c.id);
15242         }else {
15243             Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
15244         }
15245     },
15246
15247         adjustWidthAnchor : function(value, comp){
15248         return value - (comp.isFormField  ? (comp.hideLabel ? 0 : this.labelAdjust) : 0);
15249     },
15250
15251         isValidParent : function(c, target){
15252         return true;
15253     }
15254
15255     
15256 });
15257
15258 Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
15259 \r
15260 Ext.layout.Accordion = Ext.extend(Ext.layout.FitLayout, {\r
15261     \r
15262     fill : true,\r
15263     \r
15264     autoWidth : true,\r
15265     \r
15266     titleCollapse : true,\r
15267     \r
15268     hideCollapseTool : false,\r
15269     \r
15270     collapseFirst : false,\r
15271     \r
15272     animate : false,\r
15273     \r
15274     sequence : false,\r
15275     \r
15276     activeOnTop : false,\r
15277 \r
15278     renderItem : function(c){\r
15279         if(this.animate === false){\r
15280             c.animCollapse = false;\r
15281         }\r
15282         c.collapsible = true;\r
15283         if(this.autoWidth){\r
15284             c.autoWidth = true;\r
15285         }\r
15286         if(this.titleCollapse){\r
15287             c.titleCollapse = true;\r
15288         }\r
15289         if(this.hideCollapseTool){\r
15290             c.hideCollapseTool = true;\r
15291         }\r
15292         if(this.collapseFirst !== undefined){\r
15293             c.collapseFirst = this.collapseFirst;\r
15294         }\r
15295         if(!this.activeItem && !c.collapsed){\r
15296             this.activeItem = c;\r
15297         }else if(this.activeItem){\r
15298             c.collapsed = true;\r
15299         }\r
15300         Ext.layout.Accordion.superclass.renderItem.apply(this, arguments);\r
15301         c.header.addClass('x-accordion-hd');\r
15302         c.on('beforeexpand', this.beforeExpand, this);\r
15303     },\r
15304 \r
15305     
15306     beforeExpand : function(p, anim){\r
15307         var ai = this.activeItem;\r
15308         if(ai){\r
15309             if(this.sequence){\r
15310                 delete this.activeItem;\r
15311                 ai.collapse({callback:function(){\r
15312                     p.expand(anim || true);\r
15313                 }, scope: this});\r
15314                 return false;\r
15315             }else{\r
15316                 ai.collapse(this.animate);\r
15317             }\r
15318         }\r
15319         this.activeItem = p;\r
15320         if(this.activeOnTop){\r
15321             p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);\r
15322         }\r
15323         this.layout();\r
15324     },\r
15325 \r
15326     
15327     setItemSize : function(item, size){\r
15328         if(this.fill && item){\r
15329             var items = this.container.items.items;\r
15330             var hh = 0;\r
15331             for(var i = 0, len = items.length; i < len; i++){\r
15332                 var p = items[i];\r
15333                 if(p != item){\r
15334                     hh += (p.getSize().height - p.bwrap.getHeight());\r
15335                 }\r
15336             }\r
15337             size.height -= hh;\r
15338             item.setSize(size);\r
15339         }\r
15340     }\r
15341 });\r
15342 Ext.Container.LAYOUTS['accordion'] = Ext.layout.Accordion;
15343 \r
15344 Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {\r
15345     \r
15346 \r
15347     
15348     monitorResize:false,\r
15349 \r
15350     
15351     setContainer : function(ct){\r
15352         Ext.layout.TableLayout.superclass.setContainer.call(this, ct);\r
15353 \r
15354         this.currentRow = 0;\r
15355         this.currentColumn = 0;\r
15356         this.cells = [];\r
15357     },\r
15358 \r
15359     
15360     onLayout : function(ct, target){\r
15361         var cs = ct.items.items, len = cs.length, c, i;\r
15362 \r
15363         if(!this.table){\r
15364             target.addClass('x-table-layout-ct');\r
15365 \r
15366             this.table = target.createChild(\r
15367                 {tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, null, true);\r
15368 \r
15369             this.renderAll(ct, target);\r
15370         }\r
15371     },\r
15372 \r
15373     
15374     getRow : function(index){\r
15375         var row = this.table.tBodies[0].childNodes[index];\r
15376         if(!row){\r
15377             row = document.createElement('tr');\r
15378             this.table.tBodies[0].appendChild(row);\r
15379         }\r
15380         return row;\r
15381     },\r
15382 \r
15383     
15384         getNextCell : function(c){\r
15385                 var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);\r
15386                 var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];\r
15387                 for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){\r
15388                         if(!this.cells[rowIndex]){\r
15389                                 this.cells[rowIndex] = [];\r
15390                         }\r
15391                         for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){\r
15392                                 this.cells[rowIndex][colIndex] = true;\r
15393                         }\r
15394                 }\r
15395                 var td = document.createElement('td');\r
15396                 if(c.cellId){\r
15397                         td.id = c.cellId;\r
15398                 }\r
15399                 var cls = 'x-table-layout-cell';\r
15400                 if(c.cellCls){\r
15401                         cls += ' ' + c.cellCls;\r
15402                 }\r
15403                 td.className = cls;\r
15404                 if(c.colspan){\r
15405                         td.colSpan = c.colspan;\r
15406                 }\r
15407                 if(c.rowspan){\r
15408                         td.rowSpan = c.rowspan;\r
15409                 }\r
15410                 this.getRow(curRow).appendChild(td);\r
15411                 return td;\r
15412         },\r
15413     \r
15414     
15415         getNextNonSpan: function(colIndex, rowIndex){\r
15416                 var cols = this.columns;\r
15417                 while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {\r
15418                         if(cols && colIndex >= cols){\r
15419                                 rowIndex++;\r
15420                                 colIndex = 0;\r
15421                         }else{\r
15422                                 colIndex++;\r
15423                         }\r
15424                 }\r
15425                 return [colIndex, rowIndex];\r
15426         },\r
15427 \r
15428     
15429     renderItem : function(c, position, target){\r
15430         if(c && !c.rendered){\r
15431             c.render(this.getNextCell(c));\r
15432         }\r
15433     },\r
15434 \r
15435     
15436     isValidParent : function(c, target){\r
15437         return true;\r
15438     }\r
15439 \r
15440     \r
15441 });\r
15442 \r
15443 Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
15444 \r
15445 Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {\r
15446     extraCls: 'x-abs-layout-item',\r
15447     isForm: false,\r
15448     
15449     setContainer : function(ct){\r
15450         Ext.layout.AbsoluteLayout.superclass.setContainer.call(this, ct);\r
15451         if(ct.isXType('form')){\r
15452             this.isForm = true;\r
15453         }\r
15454     },\r
15455 \r
15456     onLayout : function(ct, target){\r
15457         if(this.isForm){ ct.body.position(); } else { target.position(); }\r
15458         Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);\r
15459     },\r
15460 \r
15461     
15462     getAnchorViewSize : function(ct, target){\r
15463         return this.isForm ? ct.body.getStyleSize() : Ext.layout.AbsoluteLayout.superclass.getAnchorViewSize.call(this, ct, target);\r
15464     },\r
15465 \r
15466     
15467     isValidParent : function(c, target){\r
15468         return this.isForm ? true : Ext.layout.AbsoluteLayout.superclass.isValidParent.call(this, c, target);\r
15469     },\r
15470 \r
15471     
15472     adjustWidthAnchor : function(value, comp){\r
15473         return value ? value - comp.getPosition(true)[0] : value;\r
15474     },\r
15475 \r
15476     
15477     adjustHeightAnchor : function(value, comp){\r
15478         return  value ? value - comp.getPosition(true)[1] : value;\r
15479     }\r
15480     \r
15481 });\r
15482 Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
15483 \r
15484 Ext.Viewport = Ext.extend(Ext.Container, {\r
15485         \r
15486     \r
15487     \r
15488     \r
15489     \r
15490     \r
15491     \r
15492     \r
15493     \r
15494     \r
15495     \r
15496     \r
15497     initComponent : function() {\r
15498         Ext.Viewport.superclass.initComponent.call(this);\r
15499         document.getElementsByTagName('html')[0].className += ' x-viewport';\r
15500         this.el = Ext.getBody();\r
15501         this.el.setHeight = Ext.emptyFn;\r
15502         this.el.setWidth = Ext.emptyFn;\r
15503         this.el.setSize = Ext.emptyFn;\r
15504         this.el.dom.scroll = 'no';\r
15505         this.allowDomMove = false;\r
15506         this.autoWidth = true;\r
15507         this.autoHeight = true;\r
15508         Ext.EventManager.onWindowResize(this.fireResize, this);\r
15509         this.renderTo = this.el;\r
15510     },\r
15511 \r
15512     fireResize : function(w, h){\r
15513         this.fireEvent('resize', this, w, h, w, h);\r
15514     }\r
15515 });\r
15516 Ext.reg('viewport', Ext.Viewport);
15517
15518 Ext.Panel = Ext.extend(Ext.Container, {
15519     
15520     
15521     
15522     
15523     
15524     
15525     
15526     
15527     
15528     
15529     
15530     
15531     
15532     
15533     
15534     
15535     
15536     
15537     
15538     
15539     
15540     
15541     
15542     
15543     
15544     
15545     
15546     
15547         
15548         
15549
15550
15551     
15552     baseCls : 'x-panel',
15553     
15554     collapsedCls : 'x-panel-collapsed',
15555     
15556     maskDisabled: true,
15557     
15558     animCollapse: Ext.enableFx,
15559     
15560     headerAsText: true,
15561     
15562     buttonAlign: 'right',
15563     
15564     collapsed : false,
15565     
15566     collapseFirst: true,
15567     
15568     minButtonWidth:75,
15569     
15570     elements : 'body',
15571
15572                 toolTarget : 'header',
15573     collapseEl : 'bwrap',
15574     slideAnchor : 't',
15575
15576         deferHeight: true,
15577         expandDefaults: {
15578         duration:.25
15579     },
15580         collapseDefaults: {
15581         duration:.25
15582     },
15583
15584         initComponent : function(){
15585         Ext.Panel.superclass.initComponent.call(this);
15586
15587         this.addEvents(
15588             
15589             'bodyresize',
15590             
15591             'titlechange',
15592             
15593             'collapse',
15594             
15595             'expand',
15596             
15597             'beforecollapse',
15598             
15599             'beforeexpand',
15600             
15601             'beforeclose',
15602             
15603             'close',
15604             
15605             'activate',
15606             
15607             'deactivate'
15608         );
15609
15610                 if(this.tbar){
15611             this.elements += ',tbar';
15612             if(typeof this.tbar == 'object'){
15613                 this.topToolbar = this.tbar;
15614             }
15615             delete this.tbar;
15616         }
15617         if(this.bbar){
15618             this.elements += ',bbar';
15619             if(typeof this.bbar == 'object'){
15620                 this.bottomToolbar = this.bbar;
15621             }
15622             delete this.bbar;
15623         }
15624
15625         if(this.header === true){
15626             this.elements += ',header';
15627             delete this.header;
15628         }else if(this.title && this.header !== false){
15629             this.elements += ',header';
15630         }
15631
15632         if(this.footer === true){
15633             this.elements += ',footer';
15634             delete this.footer;
15635         }
15636
15637         if(this.buttons){
15638             var btns = this.buttons;
15639             
15640             this.buttons = [];
15641             for(var i = 0, len = btns.length; i < len; i++) {
15642                 if(btns[i].render){                     this.buttons.push(btns[i]);
15643                 }else{
15644                     this.addButton(btns[i]);
15645                 }
15646             }
15647         }
15648         if(this.autoLoad){
15649             this.on('render', this.doAutoLoad, this, {delay:10});
15650         }
15651     },
15652
15653         createElement : function(name, pnode){
15654         if(this[name]){
15655             pnode.appendChild(this[name].dom);
15656             return;
15657         }
15658
15659         if(name === 'bwrap' || this.elements.indexOf(name) != -1){
15660             if(this[name+'Cfg']){
15661                 this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
15662             }else{
15663                 var el = document.createElement('div');
15664                 el.className = this[name+'Cls'];
15665                 this[name] = Ext.get(pnode.appendChild(el));
15666             }
15667         }
15668     },
15669
15670         onRender : function(ct, position){
15671         Ext.Panel.superclass.onRender.call(this, ct, position);
15672
15673         this.createClasses();
15674
15675         if(this.el){             this.el.addClass(this.baseCls);
15676             this.header = this.el.down('.'+this.headerCls);
15677             this.bwrap = this.el.down('.'+this.bwrapCls);
15678             var cp = this.bwrap ? this.bwrap : this.el;
15679             this.tbar = cp.down('.'+this.tbarCls);
15680             this.body = cp.down('.'+this.bodyCls);
15681             this.bbar = cp.down('.'+this.bbarCls);
15682             this.footer = cp.down('.'+this.footerCls);
15683             this.fromMarkup = true;
15684         }else{
15685             this.el = ct.createChild({
15686                 id: this.id,
15687                 cls: this.baseCls
15688             }, position);
15689         }
15690         var el = this.el, d = el.dom;
15691
15692         if(this.cls){
15693             this.el.addClass(this.cls);
15694         }
15695
15696         if(this.buttons){
15697             this.elements += ',footer';
15698         }
15699
15700         
15701                 if(this.frame){
15702             el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
15703
15704             this.createElement('header', d.firstChild.firstChild.firstChild);
15705             this.createElement('bwrap', d);
15706
15707                         var bw = this.bwrap.dom;
15708             var ml = d.childNodes[1], bl = d.childNodes[2];
15709             bw.appendChild(ml);
15710             bw.appendChild(bl);
15711
15712             var mc = bw.firstChild.firstChild.firstChild;
15713             this.createElement('tbar', mc);
15714             this.createElement('body', mc);
15715             this.createElement('bbar', mc);
15716             this.createElement('footer', bw.lastChild.firstChild.firstChild);
15717
15718             if(!this.footer){
15719                 this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
15720             }
15721         }else{
15722             this.createElement('header', d);
15723             this.createElement('bwrap', d);
15724
15725                         var bw = this.bwrap.dom;
15726             this.createElement('tbar', bw);
15727             this.createElement('body', bw);
15728             this.createElement('bbar', bw);
15729             this.createElement('footer', bw);
15730
15731             if(!this.header){
15732                 this.body.addClass(this.bodyCls + '-noheader');
15733                 if(this.tbar){
15734                     this.tbar.addClass(this.tbarCls + '-noheader');
15735                 }
15736             }
15737         }
15738
15739         if(this.border === false){
15740             this.el.addClass(this.baseCls + '-noborder');
15741             this.body.addClass(this.bodyCls + '-noborder');
15742             if(this.header){
15743                 this.header.addClass(this.headerCls + '-noborder');
15744             }
15745             if(this.footer){
15746                 this.footer.addClass(this.footerCls + '-noborder');
15747             }
15748             if(this.tbar){
15749                 this.tbar.addClass(this.tbarCls + '-noborder');
15750             }
15751             if(this.bbar){
15752                 this.bbar.addClass(this.bbarCls + '-noborder');
15753             }
15754         }
15755
15756         if(this.bodyBorder === false){
15757            this.body.addClass(this.bodyCls + '-noborder');
15758         }
15759
15760         if(this.bodyStyle){
15761            this.body.applyStyles(this.bodyStyle);
15762         }
15763
15764         this.bwrap.enableDisplayMode('block');
15765
15766         if(this.header){
15767             this.header.unselectable();
15768
15769                         if(this.headerAsText){
15770                 this.header.dom.innerHTML =
15771                     '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
15772
15773                 if(this.iconCls){
15774                     this.setIconClass(this.iconCls);
15775                 }
15776             }
15777         }
15778
15779         if(this.floating){
15780             this.makeFloating(this.floating);
15781         }
15782
15783         if(this.collapsible){
15784             this.tools = this.tools ? this.tools.slice(0) : [];
15785             if(!this.hideCollapseTool){
15786                 this.tools[this.collapseFirst?'unshift':'push']({
15787                     id: 'toggle',
15788                     handler : this.toggleCollapse,
15789                     scope: this
15790                 });
15791             }
15792             if(this.titleCollapse && this.header){
15793                 this.header.on('click', this.toggleCollapse, this);
15794                 this.header.setStyle('cursor', 'pointer');
15795             }
15796         }
15797         if(this.tools){
15798             var ts = this.tools;
15799             this.tools = {};
15800             this.addTool.apply(this, ts);
15801         }else{
15802             this.tools = {};
15803         }
15804
15805         if(this.buttons && this.buttons.length > 0){
15806                         var tb = this.footer.createChild({cls:'x-panel-btns-ct', cn: {
15807                 cls:"x-panel-btns x-panel-btns-"+this.buttonAlign,
15808                 html:'<table cellspacing="0"><tbody><tr></tr></tbody></table><div class="x-clear"></div>'
15809             }}, null, true);
15810             var tr = tb.getElementsByTagName('tr')[0];
15811             for(var i = 0, len = this.buttons.length; i < len; i++) {
15812                 var b = this.buttons[i];
15813                 var td = document.createElement('td');
15814                 td.className = 'x-panel-btn-td';
15815                 b.render(tr.appendChild(td));
15816             }
15817         }
15818
15819         if(this.tbar && this.topToolbar){
15820             if(Ext.isArray(this.topToolbar)){
15821                 this.topToolbar = new Ext.Toolbar(this.topToolbar);
15822             }
15823             this.topToolbar.render(this.tbar);
15824         }
15825         if(this.bbar && this.bottomToolbar){
15826             if(Ext.isArray(this.bottomToolbar)){
15827                 this.bottomToolbar = new Ext.Toolbar(this.bottomToolbar);
15828             }
15829             this.bottomToolbar.render(this.bbar);
15830         }
15831     },
15832
15833     
15834     setIconClass : function(cls){
15835         var old = this.iconCls;
15836         this.iconCls = cls;
15837         if(this.rendered && this.header){
15838             if(this.frame){
15839                 this.header.addClass('x-panel-icon');
15840                 this.header.replaceClass(old, this.iconCls);
15841             }else{
15842                 var hd = this.header.dom;
15843                 var img = hd.firstChild && String(hd.firstChild.tagName).toLowerCase() == 'img' ? hd.firstChild : null;
15844                 if(img){
15845                     Ext.fly(img).replaceClass(old, this.iconCls);
15846                 }else{
15847                     Ext.DomHelper.insertBefore(hd.firstChild, {
15848                         tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
15849                     });
15850                  }
15851             }
15852         }
15853     },
15854
15855         makeFloating : function(cfg){
15856         this.floating = true;
15857         this.el = new Ext.Layer(
15858             typeof cfg == 'object' ? cfg : {
15859                 shadow: this.shadow !== undefined ? this.shadow : 'sides',
15860                 shadowOffset: this.shadowOffset,
15861                 constrain:false,
15862                 shim: this.shim === false ? false : undefined
15863             }, this.el
15864         );
15865     },
15866
15867     
15868     getTopToolbar : function(){
15869         return this.topToolbar;
15870     },
15871
15872     
15873     getBottomToolbar : function(){
15874         return this.bottomToolbar;
15875     },
15876
15877     
15878     addButton : function(config, handler, scope){
15879         var bc = {
15880             handler: handler,
15881             scope: scope,
15882             minWidth: this.minButtonWidth,
15883             hideParent:true
15884         };
15885         if(typeof config == "string"){
15886             bc.text = config;
15887         }else{
15888             Ext.apply(bc, config);
15889         }
15890         var btn = new Ext.Button(bc);
15891         btn.ownerCt = this;
15892         if(!this.buttons){
15893             this.buttons = [];
15894         }
15895         this.buttons.push(btn);
15896         return btn;
15897     },
15898
15899         addTool : function(){
15900         if(!this[this.toolTarget]) {             return;
15901         }
15902         if(!this.toolTemplate){
15903                         var tt = new Ext.Template(
15904                  '<div class="x-tool x-tool-{id}">&#160;</div>'
15905             );
15906             tt.disableFormats = true;
15907             tt.compile();
15908             Ext.Panel.prototype.toolTemplate = tt;
15909         }
15910         for(var i = 0, a = arguments, len = a.length; i < len; i++) {
15911             var tc = a[i], overCls = 'x-tool-'+tc.id+'-over';
15912             var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
15913             this.tools[tc.id] = t;
15914             t.enableDisplayMode('block');
15915             t.on('click', this.createToolHandler(t, tc, overCls, this));
15916             if(tc.on){
15917                 t.on(tc.on);
15918             }
15919             if(tc.hidden){
15920                 t.hide();
15921             }
15922             if(tc.qtip){
15923                 if(typeof tc.qtip == 'object'){
15924                     Ext.QuickTips.register(Ext.apply({
15925                           target: t.id
15926                     }, tc.qtip));
15927                 } else {
15928                     t.dom.qtip = tc.qtip;
15929                 }
15930             }
15931             t.addClassOnOver(overCls);
15932         }
15933     },
15934
15935         onShow : function(){
15936         if(this.floating){
15937             return this.el.show();
15938         }
15939         Ext.Panel.superclass.onShow.call(this);
15940     },
15941
15942         onHide : function(){
15943         if(this.floating){
15944             return this.el.hide();
15945         }
15946         Ext.Panel.superclass.onHide.call(this);
15947     },
15948
15949         createToolHandler : function(t, tc, overCls, panel){
15950         return function(e){
15951             t.removeClass(overCls);
15952             e.stopEvent();
15953             if(tc.handler){
15954                 tc.handler.call(tc.scope || t, e, t, panel);
15955             }
15956         };
15957     },
15958
15959         afterRender : function(){
15960         if(this.fromMarkup && this.height === undefined && !this.autoHeight){
15961             this.height = this.el.getHeight();
15962         }
15963         if(this.floating && !this.hidden && !this.initHidden){
15964             this.el.show();
15965         }
15966         if(this.title){
15967             this.setTitle(this.title);
15968         }
15969                 this.setAutoScroll();
15970         if(this.html){
15971             this.body.update(typeof this.html == 'object' ?
15972                              Ext.DomHelper.markup(this.html) :
15973                              this.html);
15974             delete this.html;
15975         }
15976         if(this.contentEl){
15977             var ce = Ext.getDom(this.contentEl);
15978             Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
15979             this.body.dom.appendChild(ce);
15980         }
15981         if(this.collapsed){
15982             this.collapsed = false;
15983             this.collapse(false);
15984         }
15985         Ext.Panel.superclass.afterRender.call(this);         this.initEvents();
15986     },
15987     
15988         setAutoScroll : function(){
15989         if(this.rendered && this.autoScroll){
15990                         this.body.setOverflow('auto');
15991         }
15992     },
15993
15994         getKeyMap : function(){
15995         if(!this.keyMap){
15996             this.keyMap = new Ext.KeyMap(this.el, this.keys);
15997         }
15998         return this.keyMap;
15999     },
16000
16001         initEvents : function(){
16002         if(this.keys){
16003             this.getKeyMap();
16004         }
16005         if(this.draggable){
16006             this.initDraggable();
16007         }
16008     },
16009
16010         initDraggable : function(){
16011         this.dd = new Ext.Panel.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
16012     },
16013
16014         beforeEffect : function(){
16015         if(this.floating){
16016             this.el.beforeAction();
16017         }
16018         this.el.addClass('x-panel-animated');
16019     },
16020
16021         afterEffect : function(){
16022         this.syncShadow();
16023         this.el.removeClass('x-panel-animated');
16024     },
16025
16026         createEffect : function(a, cb, scope){
16027         var o = {
16028             scope:scope,
16029             block:true
16030         };
16031         if(a === true){
16032             o.callback = cb;
16033             return o;
16034         }else if(!a.callback){
16035             o.callback = cb;
16036         }else {             o.callback = function(){
16037                 cb.call(scope);
16038                 Ext.callback(a.callback, a.scope);
16039             };
16040         }
16041         return Ext.applyIf(o, a);
16042     },
16043
16044     
16045     collapse : function(animate){
16046         if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
16047             return;
16048         }
16049         var doAnim = animate === true || (animate !== false && this.animCollapse);
16050         this.beforeEffect();
16051         this.onCollapse(doAnim, animate);
16052         return this;
16053     },
16054
16055         onCollapse : function(doAnim, animArg){
16056         if(doAnim){
16057             this[this.collapseEl].slideOut(this.slideAnchor,
16058                     Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
16059                         this.collapseDefaults));
16060         }else{
16061             this[this.collapseEl].hide();
16062             this.afterCollapse();
16063         }
16064     },
16065
16066         afterCollapse : function(){
16067         this.collapsed = true;
16068         this.el.addClass(this.collapsedCls);
16069         this.afterEffect();
16070         this.fireEvent('collapse', this);
16071     },
16072
16073     
16074     expand : function(animate){
16075         if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
16076             return;
16077         }
16078         var doAnim = animate === true || (animate !== false && this.animCollapse);
16079         this.el.removeClass(this.collapsedCls);
16080         this.beforeEffect();
16081         this.onExpand(doAnim, animate);
16082         return this;
16083     },
16084
16085         onExpand : function(doAnim, animArg){
16086         if(doAnim){
16087             this[this.collapseEl].slideIn(this.slideAnchor,
16088                     Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
16089                         this.expandDefaults));
16090         }else{
16091             this[this.collapseEl].show();
16092             this.afterExpand();
16093         }
16094     },
16095
16096         afterExpand : function(){
16097         this.collapsed = false;
16098         this.afterEffect();
16099         this.fireEvent('expand', this);
16100     },
16101
16102     
16103     toggleCollapse : function(animate){
16104         this[this.collapsed ? 'expand' : 'collapse'](animate);
16105         return this;
16106     },
16107
16108         onDisable : function(){
16109         if(this.rendered && this.maskDisabled){
16110             this.el.mask();
16111         }
16112         Ext.Panel.superclass.onDisable.call(this);
16113     },
16114
16115         onEnable : function(){
16116         if(this.rendered && this.maskDisabled){
16117             this.el.unmask();
16118         }
16119         Ext.Panel.superclass.onEnable.call(this);
16120     },
16121
16122         onResize : function(w, h){
16123         if(w !== undefined || h !== undefined){
16124             if(!this.collapsed){
16125                 if(typeof w == 'number'){
16126                     this.body.setWidth(
16127                             this.adjustBodyWidth(w - this.getFrameWidth()));
16128                 }else if(w == 'auto'){
16129                     this.body.setWidth(w);
16130                 }
16131
16132                 if(typeof h == 'number'){
16133                     this.body.setHeight(
16134                             this.adjustBodyHeight(h - this.getFrameHeight()));
16135                 }else if(h == 'auto'){
16136                     this.body.setHeight(h);
16137                 }
16138             }else{
16139                 this.queuedBodySize = {width: w, height: h};
16140                 if(!this.queuedExpand && this.allowQueuedExpand !== false){
16141                     this.queuedExpand = true;
16142                     this.on('expand', function(){
16143                         delete this.queuedExpand;
16144                         this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
16145                         this.doLayout();
16146                     }, this, {single:true});
16147                 }
16148             }
16149             this.fireEvent('bodyresize', this, w, h);
16150         }
16151         this.syncShadow();
16152     },
16153
16154         adjustBodyHeight : function(h){
16155         return h;
16156     },
16157
16158         adjustBodyWidth : function(w){
16159         return w;
16160     },
16161
16162         onPosition : function(){
16163         this.syncShadow();
16164     },
16165
16166         onDestroy : function(){
16167         if(this.tools){
16168             for(var k in this.tools){
16169                 Ext.destroy(this.tools[k]);
16170             }
16171         }
16172         if(this.buttons){
16173             for(var b in this.buttons){
16174                 Ext.destroy(this.buttons[b]);
16175             }
16176         }
16177         Ext.destroy(
16178             this.topToolbar,
16179             this.bottomToolbar
16180         );
16181         Ext.Panel.superclass.onDestroy.call(this);
16182     },
16183
16184     
16185     getFrameWidth : function(){
16186         var w = this.el.getFrameWidth('lr');
16187
16188         if(this.frame){
16189             var l = this.bwrap.dom.firstChild;
16190             w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
16191             var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
16192             w += Ext.fly(mc).getFrameWidth('lr');
16193         }
16194         return w;
16195     },
16196
16197     
16198     getFrameHeight : function(){
16199         var h  = this.el.getFrameWidth('tb');
16200         h += (this.tbar ? this.tbar.getHeight() : 0) +
16201              (this.bbar ? this.bbar.getHeight() : 0);
16202
16203         if(this.frame){
16204             var hd = this.el.dom.firstChild;
16205             var ft = this.bwrap.dom.lastChild;
16206             h += (hd.offsetHeight + ft.offsetHeight);
16207             var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
16208             h += Ext.fly(mc).getFrameWidth('tb');
16209         }else{
16210             h += (this.header ? this.header.getHeight() : 0) +
16211                 (this.footer ? this.footer.getHeight() : 0);
16212         }
16213         return h;
16214     },
16215
16216     
16217     getInnerWidth : function(){
16218         return this.getSize().width - this.getFrameWidth();
16219     },
16220
16221     
16222     getInnerHeight : function(){
16223         return this.getSize().height - this.getFrameHeight();
16224     },
16225
16226         syncShadow : function(){
16227         if(this.floating){
16228             this.el.sync(true);
16229         }
16230     },
16231
16232         getLayoutTarget : function(){
16233         return this.body;
16234     },
16235
16236     
16237     setTitle : function(title, iconCls){
16238         this.title = title;
16239         if(this.header && this.headerAsText){
16240             this.header.child('span').update(title);
16241         }
16242         if(iconCls){
16243             this.setIconClass(iconCls);
16244         }
16245         this.fireEvent('titlechange', this, title);
16246         return this;
16247     },
16248
16249     
16250     getUpdater : function(){
16251         return this.body.getUpdater();
16252     },
16253
16254      
16255     load : function(){
16256         var um = this.body.getUpdater();
16257         um.update.apply(um, arguments);
16258         return this;
16259     },
16260
16261         beforeDestroy : function(){
16262         Ext.Element.uncache(
16263             this.header,
16264             this.tbar,
16265             this.bbar,
16266             this.footer,
16267             this.body
16268         );
16269     },
16270
16271         createClasses : function(){
16272         this.headerCls = this.baseCls + '-header';
16273         this.headerTextCls = this.baseCls + '-header-text';
16274         this.bwrapCls = this.baseCls + '-bwrap';
16275         this.tbarCls = this.baseCls + '-tbar';
16276         this.bodyCls = this.baseCls + '-body';
16277         this.bbarCls = this.baseCls + '-bbar';
16278         this.footerCls = this.baseCls + '-footer';
16279     },
16280
16281         createGhost : function(cls, useShim, appendTo){
16282         var el = document.createElement('div');
16283         el.className = 'x-panel-ghost ' + (cls ? cls : '');
16284         if(this.header){
16285             el.appendChild(this.el.dom.firstChild.cloneNode(true));
16286         }
16287         Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
16288         el.style.width = this.el.dom.offsetWidth + 'px';;
16289         if(!appendTo){
16290             this.container.dom.appendChild(el);
16291         }else{
16292             Ext.getDom(appendTo).appendChild(el);
16293         }
16294         if(useShim !== false && this.el.useShim !== false){
16295             var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);
16296             layer.show();
16297             return layer;
16298         }else{
16299             return new Ext.Element(el);
16300         }
16301     },
16302
16303         doAutoLoad : function(){
16304         this.body.load(
16305             typeof this.autoLoad == 'object' ?
16306                 this.autoLoad : {url: this.autoLoad});
16307     }
16308
16309
16310 });
16311 Ext.reg('panel', Ext.Panel);
16312
16313
16314 Ext.Window = Ext.extend(Ext.Panel, {
16315     
16316     
16317     
16318     
16319     
16320     
16321     
16322     baseCls : 'x-window',
16323     
16324     resizable:true,
16325     
16326     draggable:true,
16327     
16328     closable : true,
16329     
16330     constrain:false,
16331     
16332     constrainHeader:false,
16333     
16334     plain:false,
16335     
16336     minimizable : false,
16337     
16338     maximizable : false,
16339     
16340     minHeight: 100,
16341     
16342     minWidth: 200,
16343     
16344     expandOnShow: true,
16345     
16346     closeAction: 'close',
16347
16348         collapsible:false,
16349
16350         initHidden : true,
16351     
16352     monitorResize : true,
16353
16354                     
16355     elements: 'header,body',
16356     
16357     frame:true,
16358     
16359     floating:true,
16360
16361         initComponent : function(){
16362         Ext.Window.superclass.initComponent.call(this);
16363         this.addEvents(
16364             
16365             
16366             
16367             'resize',
16368             
16369             'maximize',
16370             
16371             'minimize',
16372             
16373             'restore'
16374         );
16375     },
16376
16377         getState : function(){
16378         return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox());
16379     },
16380
16381         onRender : function(ct, position){
16382         Ext.Window.superclass.onRender.call(this, ct, position);
16383
16384         if(this.plain){
16385             this.el.addClass('x-window-plain');
16386         }
16387
16388                 this.focusEl = this.el.createChild({
16389                     tag: "a", href:"#", cls:"x-dlg-focus",
16390                     tabIndex:"-1", html: "&#160;"});
16391         this.focusEl.swallowEvent('click', true);
16392
16393         this.proxy = this.el.createProxy("x-window-proxy");
16394         this.proxy.enableDisplayMode('block');
16395
16396         if(this.modal){
16397             this.mask = this.container.createChild({cls:"ext-el-mask"}, this.el.dom);
16398             this.mask.enableDisplayMode("block");
16399             this.mask.hide();
16400         }
16401     },
16402
16403         initEvents : function(){
16404         Ext.Window.superclass.initEvents.call(this);
16405         if(this.animateTarget){
16406             this.setAnimateTarget(this.animateTarget);
16407         }
16408
16409         if(this.resizable){
16410             this.resizer = new Ext.Resizable(this.el, {
16411                 minWidth: this.minWidth,
16412                 minHeight:this.minHeight,
16413                 handles: this.resizeHandles || "all",
16414                 pinned: true,
16415                 resizeElement : this.resizerAction
16416             });
16417             this.resizer.window = this;
16418             this.resizer.on("beforeresize", this.beforeResize, this);
16419         }
16420
16421         if(this.draggable){
16422             this.header.addClass("x-window-draggable");
16423         }
16424         this.initTools();
16425
16426         this.el.on("mousedown", this.toFront, this);
16427         this.manager = this.manager || Ext.WindowMgr;
16428         this.manager.register(this);
16429         this.hidden = true;
16430         if(this.maximized){
16431             this.maximized = false;
16432             this.maximize();
16433         }
16434         if(this.closable){
16435             var km = this.getKeyMap();
16436             km.on(27, this.onEsc, this);
16437             km.disable();
16438         }
16439     },
16440
16441     initDraggable : function(){
16442         this.dd = new Ext.Window.DD(this);  
16443     },
16444
16445        onEsc : function(){
16446         this[this.closeAction]();  
16447     },
16448
16449         beforeDestroy : function(){
16450         Ext.destroy(
16451             this.resizer,
16452             this.dd,
16453             this.proxy,
16454             this.mask
16455         );
16456         Ext.Window.superclass.beforeDestroy.call(this);
16457     },
16458     
16459         onDestroy : function(){
16460         if(this.manager){
16461             this.manager.unregister(this);
16462         }
16463         Ext.Window.superclass.onDestroy.call(this);
16464     },
16465
16466         initTools : function(){
16467         if(this.minimizable){
16468             this.addTool({
16469                 id: 'minimize',
16470                 handler: this.minimize.createDelegate(this, [])
16471             });
16472         }
16473         if(this.maximizable){
16474             this.addTool({
16475                 id: 'maximize',
16476                 handler: this.maximize.createDelegate(this, [])
16477             });
16478             this.addTool({
16479                 id: 'restore',
16480                 handler: this.restore.createDelegate(this, []),
16481                 hidden:true
16482             });
16483             this.header.on('dblclick', this.toggleMaximize, this);
16484         }
16485         if(this.closable){
16486             this.addTool({
16487                 id: 'close',
16488                 handler: this[this.closeAction].createDelegate(this, [])
16489             });
16490         }
16491     },
16492
16493         resizerAction : function(){
16494         var box = this.proxy.getBox();
16495         this.proxy.hide();
16496         this.window.handleResize(box);
16497         return box;
16498     },
16499
16500         beforeResize : function(){
16501         this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40);         this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
16502         this.resizeBox = this.el.getBox();
16503     },
16504
16505         updateHandles : function(){
16506         if(Ext.isIE && this.resizer){
16507             this.resizer.syncHandleHeight();
16508             this.el.repaint();
16509         }
16510     },
16511
16512         handleResize : function(box){
16513         var rz = this.resizeBox;
16514         if(rz.x != box.x || rz.y != box.y){
16515             this.updateBox(box);
16516         }else{
16517             this.setSize(box);
16518         }
16519         this.focus();
16520         this.updateHandles();
16521         this.saveState();
16522         this.fireEvent("resize", this, box.width, box.height);
16523     },
16524
16525     
16526     focus : function(){
16527         var f = this.focusEl, db = this.defaultButton, t = typeof db;
16528         if(t != 'undefined'){
16529             if(t == 'number'){
16530                 f = this.buttons[db];
16531             }else if(t == 'string'){
16532                 f = Ext.getCmp(db);
16533             }else{
16534                 f = db;
16535             }
16536         }
16537         f.focus.defer(10, f);
16538     },
16539
16540     
16541     setAnimateTarget : function(el){
16542         el = Ext.get(el);
16543         this.animateTarget = el;
16544     },
16545
16546         beforeShow : function(){
16547         delete this.el.lastXY;
16548         delete this.el.lastLT;
16549         if(this.x === undefined || this.y === undefined){
16550             var xy = this.el.getAlignToXY(this.container, 'c-c');
16551             var pos = this.el.translatePoints(xy[0], xy[1]);
16552             this.x = this.x === undefined? pos.left : this.x;
16553             this.y = this.y === undefined? pos.top : this.y;
16554         }
16555         this.el.setLeftTop(this.x, this.y);
16556
16557         if(this.expandOnShow){
16558             this.expand(false);
16559         }
16560
16561         if(this.modal){
16562             Ext.getBody().addClass("x-body-masked");
16563             this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
16564             this.mask.show();
16565         }
16566     },
16567
16568     
16569     show : function(animateTarget, cb, scope){
16570         if(!this.rendered){
16571             this.render(Ext.getBody());
16572         }
16573         if(this.hidden === false){
16574             this.toFront();
16575             return;
16576         }
16577         if(this.fireEvent("beforeshow", this) === false){
16578             return;
16579         }
16580         if(cb){
16581             this.on('show', cb, scope, {single:true});
16582         }
16583         this.hidden = false;
16584         if(animateTarget !== undefined){
16585             this.setAnimateTarget(animateTarget);
16586         }
16587         this.beforeShow();
16588         if(this.animateTarget){
16589             this.animShow();
16590         }else{
16591             this.afterShow();
16592         }
16593     },
16594
16595         afterShow : function(){
16596         this.proxy.hide();
16597         this.el.setStyle('display', 'block');
16598         this.el.show();
16599         if(this.maximized){
16600             this.fitContainer();
16601         }
16602         if(Ext.isMac && Ext.isGecko){           this.cascade(this.setAutoScroll);
16603         }
16604
16605         if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
16606             Ext.EventManager.onWindowResize(this.onWindowResize, this);
16607         }
16608         this.doConstrain();
16609         if(this.layout){
16610             this.doLayout();
16611         }
16612         if(this.keyMap){
16613             this.keyMap.enable();
16614         }
16615         this.toFront();
16616         this.updateHandles();
16617         this.fireEvent("show", this);
16618     },
16619
16620         animShow : function(){
16621         this.proxy.show();
16622         this.proxy.setBox(this.animateTarget.getBox());
16623         this.proxy.setOpacity(0);
16624         var b = this.getBox(false);
16625         b.callback = this.afterShow;
16626         b.scope = this;
16627         b.duration = .25;
16628         b.easing = 'easeNone';
16629         b.opacity = .5;
16630         b.block = true;
16631         this.el.setStyle('display', 'none');
16632         this.proxy.shift(b);
16633     },
16634
16635     
16636     hide : function(animateTarget, cb, scope){
16637         if(this.hidden || this.fireEvent("beforehide", this) === false){
16638             return;
16639         }
16640         if(cb){
16641             this.on('hide', cb, scope, {single:true});
16642         }
16643         this.hidden = true;
16644         if(animateTarget !== undefined){
16645             this.setAnimateTarget(animateTarget);
16646         }
16647         if(this.animateTarget){
16648             this.animHide();
16649         }else{
16650             this.el.hide();
16651             this.afterHide();
16652         }
16653     },
16654
16655         afterHide : function(){
16656         this.proxy.hide();
16657         if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
16658             Ext.EventManager.removeResizeListener(this.onWindowResize, this);
16659         }
16660         if(this.modal){
16661             this.mask.hide();
16662             Ext.getBody().removeClass("x-body-masked");
16663         }
16664         if(this.keyMap){
16665             this.keyMap.disable();
16666         }
16667         this.fireEvent("hide", this);
16668     },
16669
16670         animHide : function(){
16671         this.proxy.setOpacity(.5);
16672         this.proxy.show();
16673         var tb = this.getBox(false);
16674         this.proxy.setBox(tb);
16675         this.el.hide();
16676         var b = this.animateTarget.getBox();
16677         b.callback = this.afterHide;
16678         b.scope = this;
16679         b.duration = .25;
16680         b.easing = 'easeNone';
16681         b.block = true;
16682         b.opacity = 0;
16683         this.proxy.shift(b);
16684     },
16685
16686         onWindowResize : function(){
16687         if(this.maximized){
16688             this.fitContainer();
16689         }
16690         if(this.modal){
16691             this.mask.setSize('100%', '100%');
16692             var force = this.mask.dom.offsetHeight;
16693             this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
16694         }
16695         this.doConstrain();
16696     },
16697
16698         doConstrain : function(){
16699         if(this.constrain || this.constrainHeader){
16700             var offsets;
16701             if(this.constrain){
16702                 offsets = {
16703                     right:this.el.shadowOffset,
16704                     left:this.el.shadowOffset,
16705                     bottom:this.el.shadowOffset
16706                 };
16707             }else {
16708                 var s = this.getSize();
16709                 offsets = {
16710                     right:-(s.width - 100),
16711                     bottom:-(s.height - 25)
16712                 };
16713             }
16714
16715             var xy = this.el.getConstrainToXY(this.container, true, offsets);
16716             if(xy){
16717                 this.setPosition(xy[0], xy[1]);
16718             }
16719         }
16720     },
16721
16722         ghost : function(cls){
16723         var ghost = this.createGhost(cls);
16724         var box = this.getBox(true);
16725         ghost.setLeftTop(box.x, box.y);
16726         ghost.setWidth(box.width);
16727         this.el.hide();
16728         this.activeGhost = ghost;
16729         return ghost;
16730     },
16731
16732         unghost : function(show, matchPosition){
16733         if(show !== false){
16734             this.el.show();
16735             this.focus();
16736                 if(Ext.isMac && Ext.isGecko){                   this.cascade(this.setAutoScroll);
16737                 }
16738         }
16739         if(matchPosition !== false){
16740             this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
16741         }
16742         this.activeGhost.hide();
16743         this.activeGhost.remove();
16744         delete this.activeGhost;
16745     },
16746
16747     
16748     minimize : function(){
16749         this.fireEvent('minimize', this);
16750     },
16751
16752     
16753     close : function(){
16754         if(this.fireEvent("beforeclose", this) !== false){
16755             this.hide(null, function(){
16756                 this.fireEvent('close', this);
16757                 this.destroy();
16758             }, this);
16759         }
16760     },
16761
16762     
16763     maximize : function(){
16764         if(!this.maximized){
16765             this.expand(false);
16766             this.restoreSize = this.getSize();
16767             this.restorePos = this.getPosition(true);
16768             this.tools.maximize.hide();
16769             this.tools.restore.show();
16770             this.maximized = true;
16771             this.el.disableShadow();
16772
16773             if(this.dd){
16774                 this.dd.lock();
16775             }
16776             if(this.collapsible){
16777                 this.tools.toggle.hide();
16778             }
16779             this.el.addClass('x-window-maximized');
16780             this.container.addClass('x-window-maximized-ct');
16781
16782             this.setPosition(0, 0);
16783             this.fitContainer();
16784             this.fireEvent('maximize', this);
16785         }
16786     },
16787
16788     
16789     restore : function(){
16790         if(this.maximized){
16791             this.el.removeClass('x-window-maximized');
16792             this.tools.restore.hide();
16793             this.tools.maximize.show();
16794             this.setPosition(this.restorePos[0], this.restorePos[1]);
16795             this.setSize(this.restoreSize.width, this.restoreSize.height);
16796             delete this.restorePos;
16797             delete this.restoreSize;
16798             this.maximized = false;
16799             this.el.enableShadow(true);
16800
16801             if(this.dd){
16802                 this.dd.unlock();
16803             }
16804             if(this.collapsible){
16805                 this.tools.toggle.show();
16806             }
16807             this.container.removeClass('x-window-maximized-ct');
16808
16809             this.doConstrain();
16810             this.fireEvent('restore', this);
16811         }
16812     },
16813
16814     
16815     toggleMaximize : function(){
16816         this[this.maximized ? 'restore' : 'maximize']();
16817     },
16818
16819         fitContainer : function(){
16820         var vs = this.container.getViewSize();
16821         this.setSize(vs.width, vs.height);
16822     },
16823
16824             setZIndex : function(index){
16825         if(this.modal){
16826             this.mask.setStyle("z-index", index);
16827         }
16828         this.el.setZIndex(++index);
16829         index += 5;
16830
16831         if(this.resizer){
16832             this.resizer.proxy.setStyle("z-index", ++index);
16833         }
16834
16835         this.lastZIndex = index;
16836     },
16837
16838     
16839     alignTo : function(element, position, offsets){
16840         var xy = this.el.getAlignToXY(element, position, offsets);
16841         this.setPagePosition(xy[0], xy[1]);
16842         return this;
16843     },
16844
16845     
16846     anchorTo : function(el, alignment, offsets, monitorScroll, _pname){
16847         var action = function(){
16848             this.alignTo(el, alignment, offsets);
16849         };
16850         Ext.EventManager.onWindowResize(action, this);
16851         var tm = typeof monitorScroll;
16852         if(tm != 'undefined'){
16853             Ext.EventManager.on(window, 'scroll', action, this,
16854                 {buffer: tm == 'number' ? monitorScroll : 50});
16855         }
16856         action.call(this);
16857         this[_pname] = action;
16858         return this;
16859     },
16860
16861     
16862     toFront : function(){
16863         if(this.manager.bringToFront(this)){
16864             this.focus();
16865         }
16866         return this;
16867     },
16868
16869     
16870     setActive : function(active){
16871         if(active){
16872             if(!this.maximized){
16873                 this.el.enableShadow(true);
16874             }
16875             this.fireEvent('activate', this);
16876         }else{
16877             this.el.disableShadow();
16878             this.fireEvent('deactivate', this);
16879         }
16880     },
16881
16882     
16883     toBack : function(){
16884         this.manager.sendToBack(this);
16885         return this;
16886     },
16887
16888     
16889     center : function(){
16890         var xy = this.el.getAlignToXY(this.container, 'c-c');
16891         this.setPagePosition(xy[0], xy[1]);
16892         return this;
16893     }
16894 });
16895 Ext.reg('window', Ext.Window);
16896
16897 Ext.Window.DD = function(win){
16898     this.win = win;
16899     Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
16900     this.setHandleElId(win.header.id);
16901     this.scroll = false;
16902 };
16903
16904 Ext.extend(Ext.Window.DD, Ext.dd.DD, {
16905     moveOnly:true,
16906     headerOffsets:[100, 25],
16907     startDrag : function(){
16908         var w = this.win;
16909         this.proxy = w.ghost();
16910         if(w.constrain !== false){
16911             var so = w.el.shadowOffset;
16912             this.constrainTo(w.container, {right: so, left: so, bottom: so});
16913         }else if(w.constrainHeader !== false){
16914             var s = this.proxy.getSize();
16915             this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
16916         }
16917     },
16918     b4Drag : Ext.emptyFn,
16919
16920     onDrag : function(e){
16921         this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
16922     },
16923
16924     endDrag : function(e){
16925         this.win.unghost();
16926         this.win.saveState();
16927     }
16928 });
16929
16930 Ext.WindowGroup = function(){
16931     var list = {};
16932     var accessList = [];
16933     var front = null;
16934
16935         var sortWindows = function(d1, d2){
16936         return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
16937     };
16938
16939         var orderWindows = function(){
16940         var a = accessList, len = a.length;
16941         if(len > 0){
16942             a.sort(sortWindows);
16943             var seed = a[0].manager.zseed;
16944             for(var i = 0; i < len; i++){
16945                 var win = a[i];
16946                 if(win && !win.hidden){
16947                     win.setZIndex(seed + (i*10));
16948                 }
16949             }
16950         }
16951         activateLast();
16952     };
16953
16954         var setActiveWin = function(win){
16955         if(win != front){
16956             if(front){
16957                 front.setActive(false);
16958             }
16959             front = win;
16960             if(win){
16961                 win.setActive(true);
16962             }
16963         }
16964     };
16965
16966         var activateLast = function(){
16967         for(var i = accessList.length-1; i >=0; --i) {
16968             if(!accessList[i].hidden){
16969                 setActiveWin(accessList[i]);
16970                 return;
16971             }
16972         }
16973                 setActiveWin(null);
16974     };
16975
16976     return {
16977         
16978         zseed : 9000,
16979
16980                 register : function(win){
16981             list[win.id] = win;
16982             accessList.push(win);
16983             win.on('hide', activateLast);
16984         },
16985
16986                 unregister : function(win){
16987             delete list[win.id];
16988             win.un('hide', activateLast);
16989             accessList.remove(win);
16990         },
16991
16992         
16993         get : function(id){
16994             return typeof id == "object" ? id : list[id];
16995         },
16996
16997         
16998         bringToFront : function(win){
16999             win = this.get(win);
17000             if(win != front){
17001                 win._lastAccess = new Date().getTime();
17002                 orderWindows();
17003                 return true;
17004             }
17005             return false;
17006         },
17007
17008         
17009         sendToBack : function(win){
17010             win = this.get(win);
17011             win._lastAccess = -(new Date().getTime());
17012             orderWindows();
17013             return win;
17014         },
17015
17016         
17017         hideAll : function(){
17018             for(var id in list){
17019                 if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
17020                     list[id].hide();
17021                 }
17022             }
17023         },
17024
17025         
17026         getActive : function(){
17027             return front;
17028         },
17029
17030         
17031         getBy : function(fn, scope){
17032             var r = [];
17033             for(var i = accessList.length-1; i >=0; --i) {
17034                 var win = accessList[i];
17035                 if(fn.call(scope||win, win) !== false){
17036                     r.push(win);
17037                 }
17038             }
17039             return r;
17040         },
17041
17042         
17043         each : function(fn, scope){
17044             for(var id in list){
17045                 if(list[id] && typeof list[id] != "function"){
17046                     if(fn.call(scope || list[id], list[id]) === false){
17047                         return;
17048                     }
17049                 }
17050             }
17051         }
17052     };
17053 };
17054
17055
17056
17057 Ext.WindowMgr = new Ext.WindowGroup();
17058 \r
17059 Ext.dd.PanelProxy = function(panel, config){\r
17060     this.panel = panel;\r
17061     this.id = this.panel.id +'-ddproxy';\r
17062     Ext.apply(this, config);\r
17063 };\r
17064 \r
17065 Ext.dd.PanelProxy.prototype = {\r
17066     \r
17067     insertProxy : true,\r
17068 \r
17069     
17070     setStatus : Ext.emptyFn,\r
17071     reset : Ext.emptyFn,\r
17072     update : Ext.emptyFn,\r
17073     stop : Ext.emptyFn,\r
17074     sync: Ext.emptyFn,\r
17075 \r
17076     \r
17077     getEl : function(){\r
17078         return this.ghost;\r
17079     },\r
17080 \r
17081     \r
17082     getGhost : function(){\r
17083         return this.ghost;\r
17084     },\r
17085 \r
17086     \r
17087     getProxy : function(){\r
17088         return this.proxy;\r
17089     },\r
17090 \r
17091     \r
17092     hide : function(){\r
17093         if(this.ghost){\r
17094             if(this.proxy){\r
17095                 this.proxy.remove();\r
17096                 delete this.proxy;\r
17097             }\r
17098             this.panel.el.dom.style.display = '';\r
17099             this.ghost.remove();\r
17100             delete this.ghost;\r
17101         }\r
17102     },\r
17103 \r
17104     \r
17105     show : function(){\r
17106         if(!this.ghost){\r
17107             this.ghost = this.panel.createGhost(undefined, undefined, Ext.getBody());\r
17108             this.ghost.setXY(this.panel.el.getXY())\r
17109             if(this.insertProxy){\r
17110                 this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});\r
17111                 this.proxy.setSize(this.panel.getSize());\r
17112             }\r
17113             this.panel.el.dom.style.display = 'none';\r
17114         }\r
17115     },\r
17116 \r
17117     
17118     repair : function(xy, callback, scope){\r
17119         this.hide();\r
17120         if(typeof callback == "function"){\r
17121             callback.call(scope || this);\r
17122         }\r
17123     },\r
17124 \r
17125     \r
17126     moveProxy : function(parentNode, before){\r
17127         if(this.proxy){\r
17128             parentNode.insertBefore(this.proxy.dom, before);\r
17129         }\r
17130     }\r
17131 };\r
17132 \r
17133
17134 Ext.Panel.DD = function(panel, cfg){\r
17135     this.panel = panel;\r
17136     this.dragData = {panel: panel};\r
17137     this.proxy = new Ext.dd.PanelProxy(panel, cfg);\r
17138     Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);\r
17139     this.setHandleElId(panel.header.id);\r
17140     panel.header.setStyle('cursor', 'move');\r
17141     this.scroll = false;\r
17142 };\r
17143 \r
17144 Ext.extend(Ext.Panel.DD, Ext.dd.DragSource, {\r
17145     showFrame: Ext.emptyFn,\r
17146     startDrag: Ext.emptyFn,\r
17147     b4StartDrag: function(x, y) {\r
17148         this.proxy.show();\r
17149     },\r
17150     b4MouseDown: function(e) {\r
17151         var x = e.getPageX();\r
17152         var y = e.getPageY();\r
17153         this.autoOffset(x, y);\r
17154     },\r
17155     onInitDrag : function(x, y){\r
17156         this.onStartDrag(x, y);\r
17157         return true;\r
17158     },\r
17159     createFrame : Ext.emptyFn,\r
17160     getDragEl : function(e){\r
17161         return this.proxy.ghost.dom;\r
17162     },\r
17163     endDrag : function(e){\r
17164         this.proxy.hide();\r
17165         this.panel.saveState();\r
17166     },\r
17167 \r
17168     autoOffset : function(x, y) {\r
17169         x -= this.startPageX;\r
17170         y -= this.startPageY;\r
17171         this.setDelta(x, y);\r
17172     }\r
17173 });
17174 \r
17175 Ext.state.Provider = function(){\r
17176     \r
17177     this.addEvents("statechange");\r
17178     this.state = {};\r
17179     Ext.state.Provider.superclass.constructor.call(this);\r
17180 };\r
17181 Ext.extend(Ext.state.Provider, Ext.util.Observable, {\r
17182     \r
17183     get : function(name, defaultValue){\r
17184         return typeof this.state[name] == "undefined" ?\r
17185             defaultValue : this.state[name];\r
17186     },\r
17187     \r
17188     \r
17189     clear : function(name){\r
17190         delete this.state[name];\r
17191         this.fireEvent("statechange", this, name, null);\r
17192     },\r
17193     \r
17194     \r
17195     set : function(name, value){\r
17196         this.state[name] = value;\r
17197         
17198         this.fireEvent("statechange", this, name, value);\r
17199     },\r
17200     \r
17201     \r
17202     decodeValue : function(cookie){\r
17203         var re = /^(a|n|d|b|s|o)\:(.*)$/;\r
17204         var matches = re.exec(unescape(cookie));\r
17205         if(!matches || !matches[1]) return; 
17206         var type = matches[1];\r
17207         var v = matches[2];\r
17208         switch(type){\r
17209             case "n":\r
17210                 return parseFloat(v);\r
17211             case "d":\r
17212                 return new Date(Date.parse(v));\r
17213             case "b":\r
17214                 return (v == "1");\r
17215             case "a":\r
17216                 var all = [];\r
17217                 var values = v.split("^");\r
17218                 for(var i = 0, len = values.length; i < len; i++){\r
17219                     all.push(this.decodeValue(values[i]));\r
17220                 }\r
17221                 return all;\r
17222            case "o":\r
17223                 var all = {};\r
17224                 var values = v.split("^");\r
17225                 for(var i = 0, len = values.length; i < len; i++){\r
17226                     var kv = values[i].split("=");\r
17227                     all[kv[0]] = this.decodeValue(kv[1]);\r
17228                 }\r
17229                 return all;\r
17230            default:\r
17231                 return v;\r
17232         }\r
17233     },\r
17234     \r
17235     \r
17236     encodeValue : function(v){\r
17237         var enc;\r
17238         if(typeof v == "number"){\r
17239             enc = "n:" + v;\r
17240         }else if(typeof v == "boolean"){\r
17241             enc = "b:" + (v ? "1" : "0");\r
17242         }else if(Ext.isDate(v)){\r
17243             enc = "d:" + v.toGMTString();\r
17244         }else if(Ext.isArray(v)){\r
17245             var flat = "";\r
17246             for(var i = 0, len = v.length; i < len; i++){\r
17247                 flat += this.encodeValue(v[i]);\r
17248                 if(i != len-1) flat += "^";\r
17249             }\r
17250             enc = "a:" + flat;\r
17251         }else if(typeof v == "object"){\r
17252             var flat = "";\r
17253             for(var key in v){\r
17254                 if(typeof v[key] != "function" && v[key] !== undefined){\r
17255                     flat += key + "=" + this.encodeValue(v[key]) + "^";\r
17256                 }\r
17257             }\r
17258             enc = "o:" + flat.substring(0, flat.length-1);\r
17259         }else{\r
17260             enc = "s:" + v;\r
17261         }\r
17262         return escape(enc);        \r
17263     }\r
17264 });\r
17265
17266 \r
17267 Ext.state.Manager = function(){\r
17268     var provider = new Ext.state.Provider();\r
17269 \r
17270     return {\r
17271         \r
17272         setProvider : function(stateProvider){\r
17273             provider = stateProvider;\r
17274         },\r
17275 \r
17276         \r
17277         get : function(key, defaultValue){\r
17278             return provider.get(key, defaultValue);\r
17279         },\r
17280 \r
17281         \r
17282          set : function(key, value){\r
17283             provider.set(key, value);\r
17284         },\r
17285 \r
17286         \r
17287         clear : function(key){\r
17288             provider.clear(key);\r
17289         },\r
17290 \r
17291         \r
17292         getProvider : function(){\r
17293             return provider;\r
17294         }\r
17295     };\r
17296 }();
17297 \r
17298 \r
17299 Ext.state.CookieProvider = function(config){\r
17300     Ext.state.CookieProvider.superclass.constructor.call(this);\r
17301     this.path = "/";\r
17302     this.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); 
17303     this.domain = null;\r
17304     this.secure = false;\r
17305     Ext.apply(this, config);\r
17306     this.state = this.readCookies();\r
17307 };\r
17308 \r
17309 Ext.extend(Ext.state.CookieProvider, Ext.state.Provider, {\r
17310     
17311     set : function(name, value){\r
17312         if(typeof value == "undefined" || value === null){\r
17313             this.clear(name);\r
17314             return;\r
17315         }\r
17316         this.setCookie(name, value);\r
17317         Ext.state.CookieProvider.superclass.set.call(this, name, value);\r
17318     },\r
17319 \r
17320     
17321     clear : function(name){\r
17322         this.clearCookie(name);\r
17323         Ext.state.CookieProvider.superclass.clear.call(this, name);\r
17324     },\r
17325 \r
17326     
17327     readCookies : function(){\r
17328         var cookies = {};\r
17329         var c = document.cookie + ";";\r
17330         var re = /\s?(.*?)=(.*?);/g;\r
17331         var matches;\r
17332         while((matches = re.exec(c)) != null){\r
17333             var name = matches[1];\r
17334             var value = matches[2];\r
17335             if(name && name.substring(0,3) == "ys-"){\r
17336                 cookies[name.substr(3)] = this.decodeValue(value);\r
17337             }\r
17338         }\r
17339         return cookies;\r
17340     },\r
17341 \r
17342     
17343     setCookie : function(name, value){\r
17344         document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +\r
17345            ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +\r
17346            ((this.path == null) ? "" : ("; path=" + this.path)) +\r
17347            ((this.domain == null) ? "" : ("; domain=" + this.domain)) +\r
17348            ((this.secure == true) ? "; secure" : "");\r
17349     },\r
17350 \r
17351     
17352     clearCookie : function(name){\r
17353         document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +\r
17354            ((this.path == null) ? "" : ("; path=" + this.path)) +\r
17355            ((this.domain == null) ? "" : ("; domain=" + this.domain)) +\r
17356            ((this.secure == true) ? "; secure" : "");\r
17357     }\r
17358 });
17359 \r
17360 Ext.DataView = Ext.extend(Ext.BoxComponent, {\r
17361     \r
17362     \r
17363     \r
17364     \r
17365     \r
17366     \r
17367     \r
17368     \r
17369     \r
17370     selectedClass : "x-view-selected",\r
17371     \r
17372     emptyText : "",\r
17373 \r
17374     
17375     last: false,\r
17376 \r
17377     
17378     initComponent : function(){\r
17379         Ext.DataView.superclass.initComponent.call(this);\r
17380         if(typeof this.tpl == "string"){\r
17381             this.tpl = new Ext.XTemplate(this.tpl);\r
17382         }\r
17383 \r
17384         this.addEvents(\r
17385             \r
17386             "beforeclick",\r
17387             \r
17388             "click",\r
17389             \r
17390             "containerclick",\r
17391             \r
17392             "dblclick",\r
17393             \r
17394             "contextmenu",\r
17395             \r
17396             "selectionchange",\r
17397 \r
17398             \r
17399             "beforeselect"\r
17400         );\r
17401 \r
17402         this.all = new Ext.CompositeElementLite();\r
17403         this.selected = new Ext.CompositeElementLite();\r
17404     },\r
17405 \r
17406     
17407     onRender : function(){\r
17408         if(!this.el){\r
17409             this.el = document.createElement('div');\r
17410         }\r
17411         Ext.DataView.superclass.onRender.apply(this, arguments);\r
17412     },\r
17413 \r
17414     
17415     afterRender : function(){\r
17416         Ext.DataView.superclass.afterRender.call(this);\r
17417 \r
17418         this.el.on({\r
17419             "click": this.onClick,\r
17420             "dblclick": this.onDblClick,\r
17421             "contextmenu": this.onContextMenu,\r
17422             scope:this\r
17423         });\r
17424 \r
17425         if(this.overClass){\r
17426             this.el.on({\r
17427                 "mouseover": this.onMouseOver,\r
17428                 "mouseout": this.onMouseOut,\r
17429                 scope:this\r
17430             });\r
17431         }\r
17432 \r
17433         if(this.store){\r
17434             this.setStore(this.store, true);\r
17435         }\r
17436     },\r
17437 \r
17438     \r
17439     refresh : function(){\r
17440         this.clearSelections(false, true);\r
17441         this.el.update("");\r
17442         var html = [];\r
17443         var records = this.store.getRange();\r
17444         if(records.length < 1){\r
17445             this.el.update(this.emptyText);\r
17446             this.all.clear();\r
17447             return;\r
17448         }\r
17449         this.tpl.overwrite(this.el, this.collectData(records, 0));\r
17450         this.all.fill(Ext.query(this.itemSelector, this.el.dom));\r
17451         this.updateIndexes(0);\r
17452     },\r
17453 \r
17454     \r
17455     prepareData : function(data){\r
17456         return data;\r
17457     },\r
17458 \r
17459     
17460     collectData : function(records, startIndex){\r
17461         var r = [];\r
17462         for(var i = 0, len = records.length; i < len; i++){\r
17463             r[r.length] = this.prepareData(records[i].data, startIndex+i, records[i]);\r
17464         }\r
17465         return r;\r
17466     },\r
17467 \r
17468     
17469     bufferRender : function(records){\r
17470         var div = document.createElement('div');\r
17471         this.tpl.overwrite(div, this.collectData(records));\r
17472         return Ext.query(this.itemSelector, div);\r
17473     },\r
17474 \r
17475     
17476     onUpdate : function(ds, record){\r
17477         var index = this.store.indexOf(record);\r
17478         var sel = this.isSelected(index);\r
17479         var original = this.all.elements[index];\r
17480         var node = this.bufferRender([record], index)[0];\r
17481 \r
17482         this.all.replaceElement(index, node, true);\r
17483         if(sel){\r
17484             this.selected.replaceElement(original, node);\r
17485             this.all.item(index).addClass(this.selectedClass);\r
17486         }\r
17487         this.updateIndexes(index, index);\r
17488     },\r
17489 \r
17490     
17491     onAdd : function(ds, records, index){\r
17492         if(this.all.getCount() == 0){\r
17493             this.refresh();\r
17494             return;\r
17495         }\r
17496         var nodes = this.bufferRender(records, index), n;\r
17497         if(index < this.all.getCount()){\r
17498             n = this.all.item(index).insertSibling(nodes, 'before', true);\r
17499             this.all.elements.splice(index, 0, n);\r
17500         }else{\r
17501             n = this.all.last().insertSibling(nodes, 'after', true);\r
17502             this.all.elements.push(n);\r
17503         }\r
17504         this.updateIndexes(index);\r
17505     },\r
17506 \r
17507     
17508     onRemove : function(ds, record, index){\r
17509         this.deselect(index);\r
17510         this.all.removeElement(index, true);\r
17511         this.updateIndexes(index);\r
17512     },\r
17513 \r
17514     \r
17515     refreshNode : function(index){\r
17516         this.onUpdate(this.store, this.store.getAt(index));\r
17517     },\r
17518 \r
17519     
17520     updateIndexes : function(startIndex, endIndex){\r
17521         var ns = this.all.elements;\r
17522         startIndex = startIndex || 0;\r
17523         endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));\r
17524         for(var i = startIndex; i <= endIndex; i++){\r
17525             ns[i].viewIndex = i;\r
17526         }\r
17527     },\r
17528 \r
17529     \r
17530     setStore : function(store, initial){\r
17531         if(!initial && this.store){\r
17532             this.store.un("beforeload", this.onBeforeLoad, this);\r
17533             this.store.un("datachanged", this.refresh, this);\r
17534             this.store.un("add", this.onAdd, this);\r
17535             this.store.un("remove", this.onRemove, this);\r
17536             this.store.un("update", this.onUpdate, this);\r
17537             this.store.un("clear", this.refresh, this);\r
17538         }\r
17539         if(store){\r
17540             store = Ext.StoreMgr.lookup(store);\r
17541             store.on("beforeload", this.onBeforeLoad, this);\r
17542             store.on("datachanged", this.refresh, this);\r
17543             store.on("add", this.onAdd, this);\r
17544             store.on("remove", this.onRemove, this);\r
17545             store.on("update", this.onUpdate, this);\r
17546             store.on("clear", this.refresh, this);\r
17547         }\r
17548         this.store = store;\r
17549         if(store){\r
17550             this.refresh();\r
17551         }\r
17552     },\r
17553 \r
17554     \r
17555     findItemFromChild : function(node){\r
17556         return Ext.fly(node).findParent(this.itemSelector, this.el);\r
17557     },\r
17558 \r
17559     
17560     onClick : function(e){\r
17561         var item = e.getTarget(this.itemSelector, this.el);\r
17562         if(item){\r
17563             var index = this.indexOf(item);\r
17564             if(this.onItemClick(item, index, e) !== false){\r
17565                 this.fireEvent("click", this, index, item, e);\r
17566             }\r
17567         }else{\r
17568             if(this.fireEvent("containerclick", this, e) !== false){\r
17569                 this.clearSelections();\r
17570             }\r
17571         }\r
17572     },\r
17573 \r
17574     
17575     onContextMenu : function(e){\r
17576         var item = e.getTarget(this.itemSelector, this.el);\r
17577         if(item){\r
17578             this.fireEvent("contextmenu", this, this.indexOf(item), item, e);\r
17579         }\r
17580     },\r
17581 \r
17582     
17583     onDblClick : function(e){\r
17584         var item = e.getTarget(this.itemSelector, this.el);\r
17585         if(item){\r
17586             this.fireEvent("dblclick", this, this.indexOf(item), item, e);\r
17587         }\r
17588     },\r
17589 \r
17590     
17591     onMouseOver : function(e){\r
17592         var item = e.getTarget(this.itemSelector, this.el);\r
17593         if(item && item !== this.lastItem){\r
17594             this.lastItem = item;\r
17595             Ext.fly(item).addClass(this.overClass);\r
17596         }\r
17597     },\r
17598 \r
17599     
17600     onMouseOut : function(e){\r
17601         if(this.lastItem){\r
17602             if(!e.within(this.lastItem, true)){\r
17603                 Ext.fly(this.lastItem).removeClass(this.overClass);\r
17604                 delete this.lastItem;\r
17605             }\r
17606         }\r
17607     },\r
17608 \r
17609     
17610     onItemClick : function(item, index, e){\r
17611         if(this.fireEvent("beforeclick", this, index, item, e) === false){\r
17612             return false;\r
17613         }\r
17614         if(this.multiSelect){\r
17615             this.doMultiSelection(item, index, e);\r
17616             e.preventDefault();\r
17617         }else if(this.singleSelect){\r
17618             this.doSingleSelection(item, index, e);\r
17619             e.preventDefault();\r
17620         }\r
17621         return true;\r
17622     },\r
17623 \r
17624     
17625     doSingleSelection : function(item, index, e){\r
17626         if(e.ctrlKey && this.isSelected(index)){\r
17627             this.deselect(index);\r
17628         }else{\r
17629             this.select(index, false);\r
17630         }\r
17631     },\r
17632 \r
17633     
17634     doMultiSelection : function(item, index, e){\r
17635         if(e.shiftKey && this.last !== false){\r
17636             var last = this.last;\r
17637             this.selectRange(last, index, e.ctrlKey);\r
17638             this.last = last; 
17639         }else{\r
17640             if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){\r
17641                 this.deselect(index);\r
17642             }else{\r
17643                 this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);\r
17644             }\r
17645         }\r
17646     },\r
17647 \r
17648     \r
17649     getSelectionCount : function(){\r
17650         return this.selected.getCount()\r
17651     },\r
17652 \r
17653     \r
17654     getSelectedNodes : function(){\r
17655         return this.selected.elements;\r
17656     },\r
17657 \r
17658     \r
17659     getSelectedIndexes : function(){\r
17660         var indexes = [], s = this.selected.elements;\r
17661         for(var i = 0, len = s.length; i < len; i++){\r
17662             indexes.push(s[i].viewIndex);\r
17663         }\r
17664         return indexes;\r
17665     },\r
17666 \r
17667     \r
17668     getSelectedRecords : function(){\r
17669         var r = [], s = this.selected.elements;\r
17670         for(var i = 0, len = s.length; i < len; i++){\r
17671             r[r.length] = this.store.getAt(s[i].viewIndex);\r
17672         }\r
17673         return r;\r
17674     },\r
17675 \r
17676     \r
17677     getRecords : function(nodes){\r
17678         var r = [], s = nodes;\r
17679         for(var i = 0, len = s.length; i < len; i++){\r
17680             r[r.length] = this.store.getAt(s[i].viewIndex);\r
17681         }\r
17682         return r;\r
17683     },\r
17684 \r
17685     \r
17686     getRecord : function(node){\r
17687         return this.store.getAt(node.viewIndex);\r
17688     },\r
17689 \r
17690     \r
17691     clearSelections : function(suppressEvent, skipUpdate){\r
17692         if(this.multiSelect || this.singleSelect){\r
17693             if(!skipUpdate){\r
17694                 this.selected.removeClass(this.selectedClass);\r
17695             }\r
17696             this.selected.clear();\r
17697             this.last = false;\r
17698             if(!suppressEvent){\r
17699                 this.fireEvent("selectionchange", this, this.selected.elements);\r
17700             }\r
17701         }\r
17702     },\r
17703 \r
17704     \r
17705     isSelected : function(node){\r
17706         return this.selected.contains(this.getNode(node));\r
17707     },\r
17708 \r
17709     \r
17710     deselect : function(node){\r
17711         if(this.isSelected(node)){\r
17712             var node = this.getNode(node);\r
17713             this.selected.removeElement(node);\r
17714             if(this.last == node.viewIndex){\r
17715                 this.last = false;\r
17716             }\r
17717             Ext.fly(node).removeClass(this.selectedClass);\r
17718             this.fireEvent("selectionchange", this, this.selected.elements);\r
17719         }\r
17720     },\r
17721 \r
17722     \r
17723     select : function(nodeInfo, keepExisting, suppressEvent){\r
17724         if(Ext.isArray(nodeInfo)){\r
17725             if(!keepExisting){\r
17726                 this.clearSelections(true);\r
17727             }\r
17728             for(var i = 0, len = nodeInfo.length; i < len; i++){\r
17729                 this.select(nodeInfo[i], true, true);\r
17730             }\r
17731         } else{\r
17732             var node = this.getNode(nodeInfo);\r
17733             if(!keepExisting){\r
17734                 this.clearSelections(true);\r
17735             }\r
17736             if(node && !this.isSelected(node)){\r
17737                 if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){\r
17738                     Ext.fly(node).addClass(this.selectedClass);\r
17739                     this.selected.add(node);\r
17740                     this.last = node.viewIndex;\r
17741                     if(!suppressEvent){\r
17742                         this.fireEvent("selectionchange", this, this.selected.elements);\r
17743                     }\r
17744                 }\r
17745             }\r
17746         }\r
17747     },\r
17748 \r
17749     \r
17750     selectRange : function(start, end, keepExisting){\r
17751         if(!keepExisting){\r
17752             this.clearSelections(true);\r
17753         }\r
17754         this.select(this.getNodes(start, end), true);\r
17755     },\r
17756 \r
17757     \r
17758     getNode : function(nodeInfo){\r
17759         if(typeof nodeInfo == "string"){\r
17760             return document.getElementById(nodeInfo);\r
17761         }else if(typeof nodeInfo == "number"){\r
17762             return this.all.elements[nodeInfo];\r
17763         }\r
17764         return nodeInfo;\r
17765     },\r
17766 \r
17767     \r
17768     getNodes : function(start, end){\r
17769         var ns = this.all.elements;\r
17770         start = start || 0;\r
17771         end = typeof end == "undefined" ? ns.length - 1 : end;\r
17772         var nodes = [], i;\r
17773         if(start <= end){\r
17774             for(i = start; i <= end; i++){\r
17775                 nodes.push(ns[i]);\r
17776             }\r
17777         } else{\r
17778             for(i = start; i >= end; i--){\r
17779                 nodes.push(ns[i]);\r
17780             }\r
17781         }\r
17782         return nodes;\r
17783     },\r
17784 \r
17785     \r
17786     indexOf : function(node){\r
17787         node = this.getNode(node);\r
17788         if(typeof node.viewIndex == "number"){\r
17789             return node.viewIndex;\r
17790         }\r
17791         return this.all.indexOf(node);\r
17792     },\r
17793 \r
17794     
17795     onBeforeLoad : function(){\r
17796         if(this.loadingText){\r
17797             this.clearSelections(false, true);\r
17798             this.el.update('<div class="loading-indicator">'+this.loadingText+'</div>');\r
17799             this.all.clear();\r
17800         }\r
17801     }\r
17802 });\r
17803 \r
17804 Ext.reg('dataview', Ext.DataView);
17805
17806 Ext.ColorPalette = function(config){
17807     Ext.ColorPalette.superclass.constructor.call(this, config);
17808     this.addEvents(
17809         
17810         'select'
17811     );
17812
17813     if(this.handler){
17814         this.on("select", this.handler, this.scope, true);
17815     }
17816 };
17817 Ext.extend(Ext.ColorPalette, Ext.Component, {
17818     
17819     itemCls : "x-color-palette",
17820     
17821     value : null,
17822     clickEvent:'click',
17823         ctype: "Ext.ColorPalette",
17824
17825     
17826     allowReselect : false,
17827
17828     
17829     colors : [
17830         "000000", "993300", "333300", "003300", "003366", "000080", "333399", "333333",
17831         "800000", "FF6600", "808000", "008000", "008080", "0000FF", "666699", "808080",
17832         "FF0000", "FF9900", "99CC00", "339966", "33CCCC", "3366FF", "800080", "969696",
17833         "FF00FF", "FFCC00", "FFFF00", "00FF00", "00FFFF", "00CCFF", "993366", "C0C0C0",
17834         "FF99CC", "FFCC99", "FFFF99", "CCFFCC", "CCFFFF", "99CCFF", "CC99FF", "FFFFFF"
17835     ],
17836
17837         onRender : function(container, position){
17838         var t = this.tpl || new Ext.XTemplate(
17839             '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on">&#160;</span></em></a></tpl>'
17840         );
17841         var el = document.createElement("div");
17842         el.className = this.itemCls;
17843         t.overwrite(el, this.colors);
17844         container.dom.insertBefore(el, position);
17845         this.el = Ext.get(el);
17846         this.el.on(this.clickEvent, this.handleClick,  this, {delegate: "a"});
17847         if(this.clickEvent != 'click'){
17848             this.el.on('click', Ext.emptyFn,  this, {delegate: "a", preventDefault:true});
17849         }
17850     },
17851
17852         afterRender : function(){
17853         Ext.ColorPalette.superclass.afterRender.call(this);
17854         if(this.value){
17855             var s = this.value;
17856             this.value = null;
17857             this.select(s);
17858         }
17859     },
17860
17861         handleClick : function(e, t){
17862         e.preventDefault();
17863         if(!this.disabled){
17864             var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
17865             this.select(c.toUpperCase());
17866         }
17867     },
17868
17869     
17870     select : function(color){
17871         color = color.replace("#", "");
17872         if(color != this.value || this.allowReselect){
17873             var el = this.el;
17874             if(this.value){
17875                 el.child("a.color-"+this.value).removeClass("x-color-palette-sel");
17876             }
17877             el.child("a.color-"+color).addClass("x-color-palette-sel");
17878             this.value = color;
17879             this.fireEvent("select", this, color);
17880         }
17881     }
17882
17883     
17884 });
17885 Ext.reg('colorpalette', Ext.ColorPalette);
17886 \r
17887 Ext.DatePicker = Ext.extend(Ext.Component, {\r
17888     \r
17889     todayText : "Today",\r
17890     \r
17891     okText : "&#160;OK&#160;", 
17892     \r
17893     cancelText : "Cancel",\r
17894     \r
17895     todayTip : "{0} (Spacebar)",\r
17896     \r
17897     minDate : null,\r
17898     \r
17899     maxDate : null,\r
17900     \r
17901     minText : "This date is before the minimum date",\r
17902     \r
17903     maxText : "This date is after the maximum date",\r
17904     \r
17905     format : "m/d/y",\r
17906     \r
17907     disabledDays : null,\r
17908     \r
17909     disabledDaysText : "",\r
17910     \r
17911     disabledDatesRE : null,\r
17912     \r
17913     disabledDatesText : "",\r
17914     \r
17915     constrainToViewport : true,\r
17916     \r
17917     monthNames : Date.monthNames,\r
17918     \r
17919     dayNames : Date.dayNames,\r
17920     \r
17921     nextText: 'Next Month (Control+Right)',\r
17922     \r
17923     prevText: 'Previous Month (Control+Left)',\r
17924     \r
17925     monthYearText: 'Choose a month (Control+Up/Down to move years)',\r
17926     \r
17927     startDay : 0,\r
17928 \r
17929     initComponent : function(){\r
17930         Ext.DatePicker.superclass.initComponent.call(this);\r
17931 \r
17932         this.value = this.value ?\r
17933                  this.value.clearTime() : new Date().clearTime();\r
17934 \r
17935         this.addEvents(\r
17936             \r
17937             'select'\r
17938         );\r
17939 \r
17940         if(this.handler){\r
17941             this.on("select", this.handler,  this.scope || this);\r
17942         }\r
17943 \r
17944         this.initDisabledDays();\r
17945     },\r
17946 \r
17947     
17948     initDisabledDays : function(){\r
17949         if(!this.disabledDatesRE && this.disabledDates){\r
17950             var dd = this.disabledDates;\r
17951             var re = "(?:";\r
17952             for(var i = 0; i < dd.length; i++){\r
17953                 re += dd[i];\r
17954                 if(i != dd.length-1) re += "|";\r
17955             }\r
17956             this.disabledDatesRE = new RegExp(re + ")");\r
17957         }\r
17958     },\r
17959 \r
17960     \r
17961     setValue : function(value){\r
17962         var old = this.value;\r
17963         this.value = value.clearTime(true);\r
17964         if(this.el){\r
17965             this.update(this.value);\r
17966         }\r
17967     },\r
17968 \r
17969     \r
17970     getValue : function(){\r
17971         return this.value;\r
17972     },\r
17973 \r
17974     
17975     focus : function(){\r
17976         if(this.el){\r
17977             this.update(this.activeDate);\r
17978         }\r
17979     },\r
17980 \r
17981     
17982     onRender : function(container, position){\r
17983         var m = [\r
17984              '<table cellspacing="0">',\r
17985                 '<tr><td class="x-date-left"><a href="#" title="', this.prevText ,'">&#160;</a></td><td class="x-date-middle" align="center"></td><td class="x-date-right"><a href="#" title="', this.nextText ,'">&#160;</a></td></tr>',\r
17986                 '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'];\r
17987         var dn = this.dayNames;\r
17988         for(var i = 0; i < 7; i++){\r
17989             var d = this.startDay+i;\r
17990             if(d > 6){\r
17991                 d = d-7;\r
17992             }\r
17993             m.push("<th><span>", dn[d].substr(0,1), "</span></th>");\r
17994         }\r
17995         m[m.length] = "</tr></thead><tbody><tr>";\r
17996         for(var i = 0; i < 42; i++) {\r
17997             if(i % 7 == 0 && i != 0){\r
17998                 m[m.length] = "</tr><tr>";\r
17999             }\r
18000             m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';\r
18001         }\r
18002         m[m.length] = '</tr></tbody></table></td></tr><tr><td colspan="3" class="x-date-bottom" align="center"></td></tr></table><div class="x-date-mp"></div>';\r
18003 \r
18004         var el = document.createElement("div");\r
18005         el.className = "x-date-picker";\r
18006         el.innerHTML = m.join("");\r
18007 \r
18008         container.dom.insertBefore(el, position);\r
18009 \r
18010         this.el = Ext.get(el);\r
18011         this.eventEl = Ext.get(el.firstChild);\r
18012 \r
18013         new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"), {\r
18014             handler: this.showPrevMonth,\r
18015             scope: this,\r
18016             preventDefault:true,\r
18017             stopDefault:true\r
18018         });\r
18019 \r
18020         new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"), {\r
18021             handler: this.showNextMonth,\r
18022             scope: this,\r
18023             preventDefault:true,\r
18024             stopDefault:true\r
18025         });\r
18026 \r
18027         this.eventEl.on("mousewheel", this.handleMouseWheel,  this);\r
18028 \r
18029         this.monthPicker = this.el.down('div.x-date-mp');\r
18030         this.monthPicker.enableDisplayMode('block');\r
18031         \r
18032         var kn = new Ext.KeyNav(this.eventEl, {\r
18033             "left" : function(e){\r
18034                 e.ctrlKey ?\r
18035                     this.showPrevMonth() :\r
18036                     this.update(this.activeDate.add("d", -1));\r
18037             },\r
18038 \r
18039             "right" : function(e){\r
18040                 e.ctrlKey ?\r
18041                     this.showNextMonth() :\r
18042                     this.update(this.activeDate.add("d", 1));\r
18043             },\r
18044 \r
18045             "up" : function(e){\r
18046                 e.ctrlKey ?\r
18047                     this.showNextYear() :\r
18048                     this.update(this.activeDate.add("d", -7));\r
18049             },\r
18050 \r
18051             "down" : function(e){\r
18052                 e.ctrlKey ?\r
18053                     this.showPrevYear() :\r
18054                     this.update(this.activeDate.add("d", 7));\r
18055             },\r
18056 \r
18057             "pageUp" : function(e){\r
18058                 this.showNextMonth();\r
18059             },\r
18060 \r
18061             "pageDown" : function(e){\r
18062                 this.showPrevMonth();\r
18063             },\r
18064 \r
18065             "enter" : function(e){\r
18066                 e.stopPropagation();\r
18067                 return true;\r
18068             },\r
18069 \r
18070             scope : this\r
18071         });\r
18072 \r
18073         this.eventEl.on("click", this.handleDateClick,  this, {delegate: "a.x-date-date"});\r
18074 \r
18075         this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday,  this);\r
18076 \r
18077         this.el.unselectable();\r
18078         \r
18079         this.cells = this.el.select("table.x-date-inner tbody td");\r
18080         this.textNodes = this.el.query("table.x-date-inner tbody span");\r
18081 \r
18082         this.mbtn = new Ext.Button({\r
18083             text: "&#160;",\r
18084             tooltip: this.monthYearText,\r
18085             renderTo: this.el.child("td.x-date-middle", true)\r
18086         });\r
18087 \r
18088         this.mbtn.on('click', this.showMonthPicker, this);\r
18089         this.mbtn.el.child(this.mbtn.menuClassTarget).addClass("x-btn-with-menu");\r
18090 \r
18091 \r
18092         var today = (new Date()).dateFormat(this.format);\r
18093         this.todayBtn = new Ext.Button({\r
18094             renderTo: this.el.child("td.x-date-bottom", true),\r
18095             text: String.format(this.todayText, today),\r
18096             tooltip: String.format(this.todayTip, today),\r
18097             handler: this.selectToday,\r
18098             scope: this\r
18099         });\r
18100         \r
18101         if(Ext.isIE){\r
18102             this.el.repaint();\r
18103         }\r
18104         this.update(this.value);\r
18105     },\r
18106 \r
18107     createMonthPicker : function(){\r
18108         if(!this.monthPicker.dom.firstChild){\r
18109             var buf = ['<table border="0" cellspacing="0">'];\r
18110             for(var i = 0; i < 6; i++){\r
18111                 buf.push(\r
18112                     '<tr><td class="x-date-mp-month"><a href="#">', this.monthNames[i].substr(0, 3), '</a></td>',\r
18113                     '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', this.monthNames[i+6].substr(0, 3), '</a></td>',\r
18114                     i == 0 ?\r
18115                     '<td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-prev"></a></td><td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-next"></a></td></tr>' :\r
18116                     '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'\r
18117                 );\r
18118             }\r
18119             buf.push(\r
18120                 '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',\r
18121                     this.okText,\r
18122                     '</button><button type="button" class="x-date-mp-cancel">',\r
18123                     this.cancelText,\r
18124                     '</button></td></tr>',\r
18125                 '</table>'\r
18126             );\r
18127             this.monthPicker.update(buf.join(''));\r
18128             this.monthPicker.on('click', this.onMonthClick, this);\r
18129             this.monthPicker.on('dblclick', this.onMonthDblClick, this);\r
18130 \r
18131             this.mpMonths = this.monthPicker.select('td.x-date-mp-month');\r
18132             this.mpYears = this.monthPicker.select('td.x-date-mp-year');\r
18133 \r
18134             this.mpMonths.each(function(m, a, i){\r
18135                 i += 1;\r
18136                 if((i%2) == 0){\r
18137                     m.dom.xmonth = 5 + Math.round(i * .5);\r
18138                 }else{\r
18139                     m.dom.xmonth = Math.round((i-1) * .5);\r
18140                 }\r
18141             });\r
18142         }\r
18143     },\r
18144 \r
18145     showMonthPicker : function(){\r
18146         this.createMonthPicker();\r
18147         var size = this.el.getSize();\r
18148         this.monthPicker.setSize(size);\r
18149         this.monthPicker.child('table').setSize(size);\r
18150 \r
18151         this.mpSelMonth = (this.activeDate || this.value).getMonth();\r
18152         this.updateMPMonth(this.mpSelMonth);\r
18153         this.mpSelYear = (this.activeDate || this.value).getFullYear();\r
18154         this.updateMPYear(this.mpSelYear);\r
18155 \r
18156         this.monthPicker.slideIn('t', {duration:.2});\r
18157     },\r
18158 \r
18159     updateMPYear : function(y){\r
18160         this.mpyear = y;\r
18161         var ys = this.mpYears.elements;\r
18162         for(var i = 1; i <= 10; i++){\r
18163             var td = ys[i-1], y2;\r
18164             if((i%2) == 0){\r
18165                 y2 = y + Math.round(i * .5);\r
18166                 td.firstChild.innerHTML = y2;\r
18167                 td.xyear = y2;\r
18168             }else{\r
18169                 y2 = y - (5-Math.round(i * .5));\r
18170                 td.firstChild.innerHTML = y2;\r
18171                 td.xyear = y2;\r
18172             }\r
18173             this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');\r
18174         }\r
18175     },\r
18176 \r
18177     updateMPMonth : function(sm){\r
18178         this.mpMonths.each(function(m, a, i){\r
18179             m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');\r
18180         });\r
18181     },\r
18182 \r
18183     selectMPMonth: function(m){\r
18184         \r
18185     },\r
18186 \r
18187     onMonthClick : function(e, t){\r
18188         e.stopEvent();\r
18189         var el = new Ext.Element(t), pn;\r
18190         if(el.is('button.x-date-mp-cancel')){\r
18191             this.hideMonthPicker();\r
18192         }\r
18193         else if(el.is('button.x-date-mp-ok')){\r
18194             this.update(new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate()));\r
18195             this.hideMonthPicker();\r
18196         }\r
18197         else if(pn = el.up('td.x-date-mp-month', 2)){\r
18198             this.mpMonths.removeClass('x-date-mp-sel');\r
18199             pn.addClass('x-date-mp-sel');\r
18200             this.mpSelMonth = pn.dom.xmonth;\r
18201         }\r
18202         else if(pn = el.up('td.x-date-mp-year', 2)){\r
18203             this.mpYears.removeClass('x-date-mp-sel');\r
18204             pn.addClass('x-date-mp-sel');\r
18205             this.mpSelYear = pn.dom.xyear;\r
18206         }\r
18207         else if(el.is('a.x-date-mp-prev')){\r
18208             this.updateMPYear(this.mpyear-10);\r
18209         }\r
18210         else if(el.is('a.x-date-mp-next')){\r
18211             this.updateMPYear(this.mpyear+10);\r
18212         }\r
18213     },\r
18214 \r
18215     onMonthDblClick : function(e, t){\r
18216         e.stopEvent();\r
18217         var el = new Ext.Element(t), pn;\r
18218         if(pn = el.up('td.x-date-mp-month', 2)){\r
18219             this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));\r
18220             this.hideMonthPicker();\r
18221         }\r
18222         else if(pn = el.up('td.x-date-mp-year', 2)){\r
18223             this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));\r
18224             this.hideMonthPicker();\r
18225         }\r
18226     },\r
18227 \r
18228     hideMonthPicker : function(disableAnim){\r
18229         if(this.monthPicker){\r
18230             if(disableAnim === true){\r
18231                 this.monthPicker.hide();\r
18232             }else{\r
18233                 this.monthPicker.slideOut('t', {duration:.2});\r
18234             }\r
18235         }\r
18236     },\r
18237 \r
18238     
18239     showPrevMonth : function(e){\r
18240         this.update(this.activeDate.add("mo", -1));\r
18241     },\r
18242 \r
18243     
18244     showNextMonth : function(e){\r
18245         this.update(this.activeDate.add("mo", 1));\r
18246     },\r
18247 \r
18248     
18249     showPrevYear : function(){\r
18250         this.update(this.activeDate.add("y", -1));\r
18251     },\r
18252 \r
18253     
18254     showNextYear : function(){\r
18255         this.update(this.activeDate.add("y", 1));\r
18256     },\r
18257 \r
18258     
18259     handleMouseWheel : function(e){\r
18260         var delta = e.getWheelDelta();\r
18261         if(delta > 0){\r
18262             this.showPrevMonth();\r
18263             e.stopEvent();\r
18264         } else if(delta < 0){\r
18265             this.showNextMonth();\r
18266             e.stopEvent();\r
18267         }\r
18268     },\r
18269 \r
18270     
18271     handleDateClick : function(e, t){\r
18272         e.stopEvent();\r
18273         if(t.dateValue && !Ext.fly(t.parentNode).hasClass("x-date-disabled")){\r
18274             this.setValue(new Date(t.dateValue));\r
18275             this.fireEvent("select", this, this.value);\r
18276         }\r
18277     },\r
18278 \r
18279     
18280     selectToday : function(){\r
18281         this.setValue(new Date().clearTime());\r
18282         this.fireEvent("select", this, this.value);\r
18283     },\r
18284 \r
18285     
18286     update : function(date){\r
18287         var vd = this.activeDate;\r
18288         this.activeDate = date;\r
18289         if(vd && this.el){\r
18290             var t = date.getTime();\r
18291             if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){\r
18292                 this.cells.removeClass("x-date-selected");\r
18293                 this.cells.each(function(c){\r
18294                    if(c.dom.firstChild.dateValue == t){\r
18295                        c.addClass("x-date-selected");\r
18296                        setTimeout(function(){\r
18297                             try{c.dom.firstChild.focus();}catch(e){}\r
18298                        }, 50);\r
18299                        return false;\r
18300                    }\r
18301                 });\r
18302                 return;\r
18303             }\r
18304         }\r
18305         var days = date.getDaysInMonth();\r
18306         var firstOfMonth = date.getFirstDateOfMonth();\r
18307         var startingPos = firstOfMonth.getDay()-this.startDay;\r
18308 \r
18309         if(startingPos <= this.startDay){\r
18310             startingPos += 7;\r
18311         }\r
18312 \r
18313         var pm = date.add("mo", -1);\r
18314         var prevStart = pm.getDaysInMonth()-startingPos;\r
18315 \r
18316         var cells = this.cells.elements;\r
18317         var textEls = this.textNodes;\r
18318         days += startingPos;\r
18319 \r
18320         
18321         var day = 86400000;\r
18322         var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();\r
18323         var today = new Date().clearTime().getTime();\r
18324         var sel = date.clearTime().getTime();\r
18325         var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;\r
18326         var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;\r
18327         var ddMatch = this.disabledDatesRE;\r
18328         var ddText = this.disabledDatesText;\r
18329         var ddays = this.disabledDays ? this.disabledDays.join("") : false;\r
18330         var ddaysText = this.disabledDaysText;\r
18331         var format = this.format;\r
18332 \r
18333         var setCellClass = function(cal, cell){\r
18334             cell.title = "";\r
18335             var t = d.getTime();\r
18336             cell.firstChild.dateValue = t;\r
18337             if(t == today){\r
18338                 cell.className += " x-date-today";\r
18339                 cell.title = cal.todayText;\r
18340             }\r
18341             if(t == sel){\r
18342                 cell.className += " x-date-selected";\r
18343                 setTimeout(function(){\r
18344                     try{cell.firstChild.focus();}catch(e){}\r
18345                 }, 50);\r
18346             }\r
18347             
18348             if(t < min) {\r
18349                 cell.className = " x-date-disabled";\r
18350                 cell.title = cal.minText;\r
18351                 return;\r
18352             }\r
18353             if(t > max) {\r
18354                 cell.className = " x-date-disabled";\r
18355                 cell.title = cal.maxText;\r
18356                 return;\r
18357             }\r
18358             if(ddays){\r
18359                 if(ddays.indexOf(d.getDay()) != -1){\r
18360                     cell.title = ddaysText;\r
18361                     cell.className = " x-date-disabled";\r
18362                 }\r
18363             }\r
18364             if(ddMatch && format){\r
18365                 var fvalue = d.dateFormat(format);\r
18366                 if(ddMatch.test(fvalue)){\r
18367                     cell.title = ddText.replace("%0", fvalue);\r
18368                     cell.className = " x-date-disabled";\r
18369                 }\r
18370             }\r
18371         };\r
18372 \r
18373         var i = 0;\r
18374         for(; i < startingPos; i++) {\r
18375             textEls[i].innerHTML = (++prevStart);\r
18376             d.setDate(d.getDate()+1);\r
18377             cells[i].className = "x-date-prevday";\r
18378             setCellClass(this, cells[i]);\r
18379         }\r
18380         for(; i < days; i++){\r
18381             intDay = i - startingPos + 1;\r
18382             textEls[i].innerHTML = (intDay);\r
18383             d.setDate(d.getDate()+1);\r
18384             cells[i].className = "x-date-active";\r
18385             setCellClass(this, cells[i]);\r
18386         }\r
18387         var extraDays = 0;\r
18388         for(; i < 42; i++) {\r
18389              textEls[i].innerHTML = (++extraDays);\r
18390              d.setDate(d.getDate()+1);\r
18391              cells[i].className = "x-date-nextday";\r
18392              setCellClass(this, cells[i]);\r
18393         }\r
18394 \r
18395         this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());\r
18396 \r
18397         if(!this.internalRender){\r
18398             var main = this.el.dom.firstChild;\r
18399             var w = main.offsetWidth;\r
18400             this.el.setWidth(w + this.el.getBorderWidth("lr"));\r
18401             Ext.fly(main).setWidth(w);\r
18402             this.internalRender = true;\r
18403             
18404             
18405             
18406             if(Ext.isOpera && !this.secondPass){\r
18407                 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";\r
18408                 this.secondPass = true;\r
18409                 this.update.defer(10, this, [date]);\r
18410             }\r
18411         }\r
18412     },\r
18413 \r
18414     
18415     beforeDestroy : function() {\r
18416         this.mbtn.destroy();\r
18417         this.todayBtn.destroy();\r
18418     }\r
18419 \r
18420     \r
18421 });\r
18422 Ext.reg('datepicker', Ext.DatePicker);
18423
18424 Ext.TabPanel = Ext.extend(Ext.Panel,  {
18425     
18426     
18427     monitorResize : true,
18428     
18429     deferredRender : true,
18430     
18431     tabWidth: 120,
18432     
18433     minTabWidth: 30,
18434     
18435     resizeTabs:false,
18436     
18437     enableTabScroll: false,
18438     
18439     scrollIncrement : 0,
18440     
18441     scrollRepeatInterval : 400,
18442     
18443     scrollDuration : .35,
18444     
18445     animScroll : true,
18446     
18447     tabPosition: 'top',
18448     
18449     baseCls: 'x-tab-panel',
18450     
18451     autoTabs : false,
18452     
18453     autoTabSelector:'div.x-tab',
18454     
18455     activeTab : null,
18456     
18457     tabMargin : 2,
18458     
18459     plain: false,
18460     
18461     wheelIncrement : 20,
18462
18463     
18464     idDelimiter : '__',
18465
18466         itemCls : 'x-tab-item',
18467
18468         elements: 'body',
18469     headerAsText: false,
18470     frame: false,
18471     hideBorders:true,
18472
18473         initComponent : function(){
18474         this.frame = false;
18475         Ext.TabPanel.superclass.initComponent.call(this);
18476         this.addEvents(
18477             
18478             'beforetabchange',
18479             
18480             'tabchange',
18481             
18482             'contextmenu'
18483         );
18484         this.setLayout(new Ext.layout.CardLayout({
18485             deferredRender: this.deferredRender
18486         }));
18487         if(this.tabPosition == 'top'){
18488             this.elements += ',header';
18489             this.stripTarget = 'header';
18490         }else {
18491             this.elements += ',footer';
18492             this.stripTarget = 'footer';
18493         }
18494         if(!this.stack){
18495             this.stack = Ext.TabPanel.AccessStack();
18496         }
18497         this.initItems();
18498     },
18499
18500         render : function(){
18501         Ext.TabPanel.superclass.render.apply(this, arguments);
18502         if(this.activeTab !== undefined){
18503             var item = this.activeTab;
18504             delete this.activeTab;
18505             this.setActiveTab(item);
18506         }
18507     },
18508
18509         onRender : function(ct, position){
18510         Ext.TabPanel.superclass.onRender.call(this, ct, position);
18511
18512         if(this.plain){
18513             var pos = this.tabPosition == 'top' ? 'header' : 'footer';
18514             this[pos].addClass('x-tab-panel-'+pos+'-plain');
18515         }
18516
18517         var st = this[this.stripTarget];
18518
18519         this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
18520             tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
18521         this.stripSpacer = st.createChild({cls:'x-tab-strip-spacer'});
18522         this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
18523
18524         this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge'});
18525         this.strip.createChild({cls:'x-clear'});
18526
18527         this.body.addClass('x-tab-panel-body-'+this.tabPosition);
18528
18529         if(!this.itemTpl){
18530             var tt = new Ext.Template(
18531                  '<li class="{cls}" id="{id}"><a class="x-tab-strip-close" onclick="return false;"></a>',
18532                  '<a class="x-tab-right" href="#" onclick="return false;"><em class="x-tab-left">',
18533                  '<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
18534                  '</em></a></li>'
18535             );
18536             tt.disableFormats = true;
18537             tt.compile();
18538             Ext.TabPanel.prototype.itemTpl = tt;
18539         }
18540
18541         this.items.each(this.initTab, this);
18542     },
18543
18544         afterRender : function(){
18545         Ext.TabPanel.superclass.afterRender.call(this);
18546         if(this.autoTabs){
18547             this.readTabs(false);
18548         }
18549     },
18550
18551         initEvents : function(){
18552         Ext.TabPanel.superclass.initEvents.call(this);
18553         this.on('add', this.onAdd, this);
18554         this.on('remove', this.onRemove, this);
18555
18556         this.strip.on('mousedown', this.onStripMouseDown, this);
18557         this.strip.on('click', this.onStripClick, this);
18558         this.strip.on('contextmenu', this.onStripContextMenu, this);
18559         if(this.enableTabScroll){
18560             this.strip.on('mousewheel', this.onWheel, this);
18561         }
18562     },
18563
18564         findTargets : function(e){
18565         var item = null;
18566         var itemEl = e.getTarget('li', this.strip);
18567         if(itemEl){
18568             item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
18569             if(item.disabled){
18570                 return {
18571                     close : null,
18572                     item : null,
18573                     el : null
18574                 };
18575             }
18576         }
18577         return {
18578             close : e.getTarget('.x-tab-strip-close', this.strip),
18579             item : item,
18580             el : itemEl
18581         };
18582     },
18583
18584         onStripMouseDown : function(e){
18585         e.preventDefault();
18586         if(e.button != 0){
18587             return;
18588         }
18589         var t = this.findTargets(e);
18590         if(t.close){
18591             this.remove(t.item);
18592             return;
18593         }
18594         if(t.item && t.item != this.activeTab){
18595             this.setActiveTab(t.item);
18596         }
18597     },
18598
18599         onStripClick : function(e){
18600         var t = this.findTargets(e);
18601         if(!t.close && t.item && t.item != this.activeTab){
18602             this.setActiveTab(t.item);
18603         }
18604     },
18605
18606         onStripContextMenu : function(e){
18607         e.preventDefault();
18608         var t = this.findTargets(e);
18609         if(t.item){
18610             this.fireEvent('contextmenu', this, t.item, e);
18611         }
18612     },
18613
18614     
18615     readTabs : function(removeExisting){
18616         if(removeExisting === true){
18617             this.items.each(function(item){
18618                 this.remove(item);
18619             }, this);
18620         }
18621         var tabs = this.el.query(this.autoTabSelector);
18622         for(var i = 0, len = tabs.length; i < len; i++){
18623             var tab = tabs[i];
18624             var title = tab.getAttribute('title');
18625             tab.removeAttribute('title');
18626             this.add({
18627                 title: title,
18628                 el: tab
18629             });
18630         }
18631     },
18632
18633         initTab : function(item, index){
18634         var before = this.strip.dom.childNodes[index];
18635         var cls = item.closable ? 'x-tab-strip-closable' : '';
18636         if(item.disabled){
18637             cls += ' x-item-disabled';
18638         }
18639         if(item.iconCls){
18640             cls += ' x-tab-with-icon';
18641         }
18642         if(item.tabCls){
18643             cls += ' ' + item.tabCls;
18644         }
18645         
18646         var p = {
18647             id: this.id + this.idDelimiter + item.getItemId(),
18648             text: item.title,
18649             cls: cls,
18650             iconCls: item.iconCls || ''
18651         };
18652         var el = before ?
18653                  this.itemTpl.insertBefore(before, p) :
18654                  this.itemTpl.append(this.strip, p);
18655
18656         Ext.fly(el).addClassOnOver('x-tab-strip-over');
18657
18658         if(item.tabTip){
18659             Ext.fly(el).child('span.x-tab-strip-text', true).qtip = item.tabTip;
18660         }
18661         item.on('disable', this.onItemDisabled, this);
18662         item.on('enable', this.onItemEnabled, this);
18663         item.on('titlechange', this.onItemTitleChanged, this);
18664         item.on('beforeshow', this.onBeforeShowItem, this);
18665     },
18666
18667         onAdd : function(tp, item, index){
18668         this.initTab(item, index);
18669         if(this.items.getCount() == 1){
18670             this.syncSize();
18671         }
18672         this.delegateUpdates();
18673     },
18674
18675         onBeforeAdd : function(item){
18676         var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
18677         if(existing){
18678             this.setActiveTab(item);
18679             return false;
18680         }
18681         Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
18682         var es = item.elements;
18683         item.elements = es ? es.replace(',header', '') : es;
18684         item.border = (item.border === true);
18685     },
18686
18687         onRemove : function(tp, item){
18688         Ext.removeNode(this.getTabEl(item));
18689         this.stack.remove(item);
18690         if(item == this.activeTab){
18691             var next = this.stack.next();
18692             if(next){
18693                 this.setActiveTab(next);
18694             }else{
18695                 this.setActiveTab(0);
18696             }
18697         }
18698         this.delegateUpdates();
18699     },
18700
18701         onBeforeShowItem : function(item){
18702         if(item != this.activeTab){
18703             this.setActiveTab(item);
18704             return false;
18705         }
18706     },
18707
18708         onItemDisabled : function(item){
18709         var el = this.getTabEl(item);
18710         if(el){
18711             Ext.fly(el).addClass('x-item-disabled');
18712         }
18713         this.stack.remove(item);
18714     },
18715
18716         onItemEnabled : function(item){
18717         var el = this.getTabEl(item);
18718         if(el){
18719             Ext.fly(el).removeClass('x-item-disabled');
18720         }
18721     },
18722
18723         onItemTitleChanged : function(item){
18724         var el = this.getTabEl(item);
18725         if(el){
18726             Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
18727         }
18728     },
18729
18730     
18731     getTabEl : function(item){
18732         var itemId = (typeof item === 'number')?this.items.items[item].getItemId() : item.getItemId();
18733         return document.getElementById(this.id+this.idDelimiter+itemId);
18734     },
18735
18736         onResize : function(){
18737         Ext.TabPanel.superclass.onResize.apply(this, arguments);
18738         this.delegateUpdates();
18739     },
18740
18741     
18742     beginUpdate : function(){
18743         this.suspendUpdates = true;
18744     },
18745
18746     
18747     endUpdate : function(){
18748         this.suspendUpdates = false;
18749         this.delegateUpdates();
18750     },
18751
18752     
18753     hideTabStripItem : function(item){
18754         item = this.getComponent(item);
18755         var el = this.getTabEl(item);
18756         if(el){
18757             el.style.display = 'none';
18758             this.delegateUpdates();
18759         }
18760     },
18761
18762     
18763     unhideTabStripItem : function(item){
18764         item = this.getComponent(item);
18765         var el = this.getTabEl(item);
18766         if(el){
18767             el.style.display = '';
18768             this.delegateUpdates();
18769         }
18770     },
18771
18772         delegateUpdates : function(){
18773         if(this.suspendUpdates){
18774             return;
18775         }
18776         if(this.resizeTabs && this.rendered){
18777             this.autoSizeTabs();
18778         }
18779         if(this.enableTabScroll && this.rendered){
18780             this.autoScrollTabs();
18781         }
18782     },
18783
18784         autoSizeTabs : function(){
18785         var count = this.items.length;
18786         var ce = this.tabPosition != 'bottom' ? 'header' : 'footer';
18787         var ow = this[ce].dom.offsetWidth;
18788         var aw = this[ce].dom.clientWidth;
18789
18790         if(!this.resizeTabs || count < 1 || !aw){             return;
18791         }
18792
18793         var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth);         this.lastTabWidth = each;
18794         var lis = this.stripWrap.dom.getElementsByTagName('li');
18795         for(var i = 0, len = lis.length-1; i < len; i++) {             var li = lis[i];
18796             var inner = li.childNodes[1].firstChild.firstChild;
18797             var tw = li.offsetWidth;
18798             var iw = inner.offsetWidth;
18799             inner.style.width = (each - (tw-iw)) + 'px';
18800         }
18801     },
18802
18803         adjustBodyWidth : function(w){
18804         if(this.header){
18805             this.header.setWidth(w);
18806         }
18807         if(this.footer){
18808             this.footer.setWidth(w);
18809         }
18810         return w;
18811     },
18812
18813     
18814     setActiveTab : function(item){
18815         item = this.getComponent(item);
18816         if(!item || this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
18817             return;
18818         }
18819         if(!this.rendered){
18820             this.activeTab = item;
18821             return;
18822         }
18823         if(this.activeTab != item){
18824             if(this.activeTab){
18825                 var oldEl = this.getTabEl(this.activeTab);
18826                 if(oldEl){
18827                     Ext.fly(oldEl).removeClass('x-tab-strip-active');
18828                 }
18829                 this.activeTab.fireEvent('deactivate', this.activeTab);
18830             }
18831             var el = this.getTabEl(item);
18832             Ext.fly(el).addClass('x-tab-strip-active');
18833             this.activeTab = item;
18834             this.stack.add(item);
18835
18836             this.layout.setActiveItem(item);
18837             if(this.layoutOnTabChange && item.doLayout){
18838                 item.doLayout();
18839             }
18840             if(this.scrolling){
18841                 this.scrollToTab(item, this.animScroll);
18842             }
18843
18844             item.fireEvent('activate', item);
18845             this.fireEvent('tabchange', this, item);
18846         }
18847     },
18848
18849     
18850     getActiveTab : function(){
18851         return this.activeTab || null;
18852     },
18853
18854     
18855     getItem : function(item){
18856         return this.getComponent(item);
18857     },
18858
18859         autoScrollTabs : function(){
18860         var count = this.items.length;
18861         var ow = this.header.dom.offsetWidth;
18862         var tw = this.header.dom.clientWidth;
18863
18864         var wrap = this.stripWrap;
18865         var wd = wrap.dom;
18866         var cw = wd.offsetWidth;
18867         var pos = this.getScrollPos();
18868         var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
18869
18870         if(!this.enableTabScroll || count < 1 || cw < 20){             return;
18871         }
18872         if(l <= tw){
18873             wd.scrollLeft = 0;
18874             wrap.setWidth(tw);
18875             if(this.scrolling){
18876                 this.scrolling = false;
18877                 this.header.removeClass('x-tab-scrolling');
18878                 this.scrollLeft.hide();
18879                 this.scrollRight.hide();
18880                 if(Ext.isAir){
18881                     wd.style.marginLeft = '';
18882                     wd.style.marginRight = '';
18883                 }
18884             }
18885         }else{
18886             if(!this.scrolling){
18887                 this.header.addClass('x-tab-scrolling');
18888                 if(Ext.isAir){
18889                     wd.style.marginLeft = '18px';
18890                     wd.style.marginRight = '18px';
18891                 }
18892             }
18893             tw -= wrap.getMargins('lr');
18894             wrap.setWidth(tw > 20 ? tw : 20);
18895             if(!this.scrolling){
18896                 if(!this.scrollLeft){
18897                     this.createScrollers();
18898                 }else{
18899                     this.scrollLeft.show();
18900                     this.scrollRight.show();
18901                 }
18902             }
18903             this.scrolling = true;
18904             if(pos > (l-tw)){                 wd.scrollLeft = l-tw;
18905             }else{                 this.scrollToTab(this.activeTab, false);
18906             }
18907             this.updateScrollButtons();
18908         }
18909     },
18910
18911         createScrollers : function(){
18912         var h = this.stripWrap.dom.offsetHeight;
18913
18914                 var sl = this.header.insertFirst({
18915             cls:'x-tab-scroller-left'
18916         });
18917         sl.setHeight(h);
18918         sl.addClassOnOver('x-tab-scroller-left-over');
18919         this.leftRepeater = new Ext.util.ClickRepeater(sl, {
18920             interval : this.scrollRepeatInterval,
18921             handler: this.onScrollLeft,
18922             scope: this
18923         });
18924         this.scrollLeft = sl;
18925
18926                 var sr = this.header.insertFirst({
18927             cls:'x-tab-scroller-right'
18928         });
18929         sr.setHeight(h);
18930         sr.addClassOnOver('x-tab-scroller-right-over');
18931         this.rightRepeater = new Ext.util.ClickRepeater(sr, {
18932             interval : this.scrollRepeatInterval,
18933             handler: this.onScrollRight,
18934             scope: this
18935         });
18936         this.scrollRight = sr;
18937     },
18938
18939         getScrollWidth : function(){
18940         return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
18941     },
18942
18943         getScrollPos : function(){
18944         return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
18945     },
18946
18947         getScrollArea : function(){
18948         return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
18949     },
18950
18951         getScrollAnim : function(){
18952         return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
18953     },
18954
18955         getScrollIncrement : function(){
18956         return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
18957     },
18958
18959     
18960
18961     scrollToTab : function(item, animate){
18962         if(!item){ return; }
18963         var el = this.getTabEl(item);
18964         var pos = this.getScrollPos(), area = this.getScrollArea();
18965         var left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos;
18966         var right = left + el.offsetWidth;
18967         if(left < pos){
18968             this.scrollTo(left, animate);
18969         }else if(right > (pos + area)){
18970             this.scrollTo(right - area, animate);
18971         }
18972     },
18973
18974         scrollTo : function(pos, animate){
18975         this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
18976         if(!animate){
18977             this.updateScrollButtons();
18978         }
18979     },
18980
18981     onWheel : function(e){
18982         var d = e.getWheelDelta()*this.wheelIncrement*-1;
18983         e.stopEvent();
18984
18985         var pos = this.getScrollPos();
18986         var newpos = pos + d;
18987         var sw = this.getScrollWidth()-this.getScrollArea();
18988
18989         var s = Math.max(0, Math.min(sw, newpos));
18990         if(s != pos){
18991             this.scrollTo(s, false);
18992         }
18993     },
18994
18995         onScrollRight : function(){
18996         var sw = this.getScrollWidth()-this.getScrollArea();
18997         var pos = this.getScrollPos();
18998         var s = Math.min(sw, pos + this.getScrollIncrement());
18999         if(s != pos){
19000             this.scrollTo(s, this.animScroll);
19001         }
19002     },
19003
19004         onScrollLeft : function(){
19005         var pos = this.getScrollPos();
19006         var s = Math.max(0, pos - this.getScrollIncrement());
19007         if(s != pos){
19008             this.scrollTo(s, this.animScroll);
19009         }
19010     },
19011
19012         updateScrollButtons : function(){
19013         var pos = this.getScrollPos();
19014         this.scrollLeft[pos == 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
19015         this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
19016     }
19017
19018     
19019     
19020     
19021     
19022     
19023     
19024     
19025     
19026     
19027
19028 });
19029 Ext.reg('tabpanel', Ext.TabPanel);
19030
19031
19032 Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
19033
19034 Ext.TabPanel.AccessStack = function(){
19035     var items = [];
19036     return {
19037         add : function(item){
19038             items.push(item);
19039             if(items.length > 10){
19040                 items.shift();
19041             }
19042         },
19043
19044         remove : function(item){
19045             var s = [];
19046             for(var i = 0, len = items.length; i < len; i++) {
19047                 if(items[i] != item){
19048                     s.push(items[i]);
19049                 }
19050             }
19051             items = s;
19052         },
19053
19054         next : function(){
19055             return items.pop();
19056         }
19057     };
19058 };
19059
19060
19061
19062
19063 Ext.Button = Ext.extend(Ext.Component, {
19064     
19065     hidden : false,
19066     
19067     disabled : false,
19068     
19069     pressed : false,
19070     
19071
19072     
19073
19074     
19075     enableToggle: false,
19076     
19077     
19078     menuAlign : "tl-bl?",
19079
19080     
19081     
19082     type : 'button',
19083
19084         menuClassTarget: 'tr',
19085
19086     
19087     clickEvent : 'click',
19088
19089     
19090     handleMouseEvents : true,
19091
19092     
19093     tooltipType : 'qtip',
19094
19095     buttonSelector : "button:first",
19096
19097     
19098
19099     
19100     initComponent : function(){
19101         Ext.Button.superclass.initComponent.call(this);
19102
19103         this.addEvents(
19104             
19105             "click",
19106             
19107             "toggle",
19108             
19109             'mouseover',
19110             
19111             'mouseout',
19112             
19113             'menushow',
19114             
19115             'menuhide',
19116             
19117             'menutriggerover',
19118             
19119             'menutriggerout'
19120         );
19121         if(this.menu){
19122             this.menu = Ext.menu.MenuMgr.get(this.menu);
19123         }
19124         if(typeof this.toggleGroup === 'string'){
19125             this.enableToggle = true;
19126         }
19127     },
19128
19129         onRender : function(ct, position){
19130         if(!this.template){
19131             if(!Ext.Button.buttonTemplate){
19132                                 Ext.Button.buttonTemplate = new Ext.Template(
19133                     '<table border="0" cellpadding="0" cellspacing="0" class="x-btn-wrap"><tbody><tr>',
19134                     '<td class="x-btn-left"><i>&#160;</i></td><td class="x-btn-center"><em unselectable="on"><button class="x-btn-text" type="{1}">{0}</button></em></td><td class="x-btn-right"><i>&#160;</i></td>',
19135                     "</tr></tbody></table>");
19136             }
19137             this.template = Ext.Button.buttonTemplate;
19138         }
19139         var btn, targs = [this.text || '&#160;', this.type];
19140
19141         if(position){
19142             btn = this.template.insertBefore(position, targs, true);
19143         }else{
19144             btn = this.template.append(ct, targs, true);
19145         }
19146         var btnEl = btn.child(this.buttonSelector);
19147         btnEl.on('focus', this.onFocus, this);
19148         btnEl.on('blur', this.onBlur, this);
19149
19150         this.initButtonEl(btn, btnEl);
19151
19152         if(this.menu){
19153             this.el.child(this.menuClassTarget).addClass("x-btn-with-menu");
19154         }
19155         Ext.ButtonToggleMgr.register(this);
19156     },
19157
19158         initButtonEl : function(btn, btnEl){
19159
19160         this.el = btn;
19161         btn.addClass("x-btn");
19162
19163         if(this.icon){
19164             btnEl.setStyle('background-image', 'url(' +this.icon +')');
19165         }
19166         if(this.iconCls){
19167             btnEl.addClass(this.iconCls);
19168             if(!this.cls){
19169                 btn.addClass(this.text ? 'x-btn-text-icon' : 'x-btn-icon');
19170             }
19171         }
19172         if(this.tabIndex !== undefined){
19173             btnEl.dom.tabIndex = this.tabIndex;
19174         }
19175         if(this.tooltip){
19176             if(typeof this.tooltip == 'object'){
19177                 Ext.QuickTips.register(Ext.apply({
19178                       target: btnEl.id
19179                 }, this.tooltip));
19180             } else {
19181                 btnEl.dom[this.tooltipType] = this.tooltip;
19182             }
19183         }
19184
19185         if(this.pressed){
19186             this.el.addClass("x-btn-pressed");
19187         }
19188
19189         if(this.handleMouseEvents){
19190             btn.on("mouseover", this.onMouseOver, this);
19191                                     btn.on("mousedown", this.onMouseDown, this);
19192         }
19193
19194         if(this.menu){
19195             this.menu.on("show", this.onMenuShow, this);
19196             this.menu.on("hide", this.onMenuHide, this);
19197         }
19198
19199         if(this.id){
19200             this.el.dom.id = this.el.id = this.id;
19201         }
19202
19203         if(this.repeat){
19204             var repeater = new Ext.util.ClickRepeater(btn,
19205                 typeof this.repeat == "object" ? this.repeat : {}
19206             );
19207             repeater.on("click", this.onClick,  this);
19208         }
19209
19210         btn.on(this.clickEvent, this.onClick, this);
19211     },
19212
19213         afterRender : function(){
19214         Ext.Button.superclass.afterRender.call(this);
19215         if(Ext.isIE6){
19216             this.autoWidth.defer(1, this);
19217         }else{
19218             this.autoWidth();
19219         }
19220     },
19221
19222     
19223     setIconClass : function(cls){
19224         if(this.el){
19225             this.el.child(this.buttonSelector).replaceClass(this.iconCls, cls);
19226         }
19227         this.iconCls = cls;
19228     },
19229
19230         beforeDestroy: function(){
19231         if(this.rendered){
19232                 var btn = this.el.child(this.buttonSelector);
19233                 if(btn){
19234                     btn.removeAllListeners();
19235                 }
19236             }
19237         if(this.menu){
19238             Ext.destroy(this.menu);
19239         }
19240     },
19241
19242         onDestroy : function(){
19243         if(this.rendered){
19244             Ext.ButtonToggleMgr.unregister(this);
19245         }
19246     },
19247
19248         autoWidth : function(){
19249         if(this.el){
19250             this.el.setWidth("auto");
19251             if(Ext.isIE7 && Ext.isStrict){
19252                 var ib = this.el.child(this.buttonSelector);
19253                 if(ib && ib.getWidth() > 20){
19254                     ib.clip();
19255                     ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
19256                 }
19257             }
19258             if(this.minWidth){
19259                 if(this.el.getWidth() < this.minWidth){
19260                     this.el.setWidth(this.minWidth);
19261                 }
19262             }
19263         }
19264     },
19265
19266     
19267     setHandler : function(handler, scope){
19268         this.handler = handler;
19269         this.scope = scope;
19270     },
19271
19272     
19273     setText : function(text){
19274         this.text = text;
19275         if(this.el){
19276             this.el.child("td.x-btn-center " + this.buttonSelector).update(text);
19277         }
19278         this.autoWidth();
19279     },
19280
19281     
19282     getText : function(){
19283         return this.text;
19284     },
19285
19286     
19287     toggle : function(state){
19288         state = state === undefined ? !this.pressed : state;
19289         if(state != this.pressed){
19290             if(state){
19291                 this.el.addClass("x-btn-pressed");
19292                 this.pressed = true;
19293                 this.fireEvent("toggle", this, true);
19294             }else{
19295                 this.el.removeClass("x-btn-pressed");
19296                 this.pressed = false;
19297                 this.fireEvent("toggle", this, false);
19298             }
19299             if(this.toggleHandler){
19300                 this.toggleHandler.call(this.scope || this, this, state);
19301             }
19302         }
19303     },
19304
19305     
19306     focus : function(){
19307         this.el.child(this.buttonSelector).focus();
19308     },
19309
19310         onDisable : function(){
19311         if(this.el){
19312             if(!Ext.isIE6 || !this.text){
19313                 this.el.addClass(this.disabledClass);
19314             }
19315             this.el.dom.disabled = true;
19316         }
19317         this.disabled = true;
19318     },
19319
19320         onEnable : function(){
19321         if(this.el){
19322             if(!Ext.isIE6 || !this.text){
19323                 this.el.removeClass(this.disabledClass);
19324             }
19325             this.el.dom.disabled = false;
19326         }
19327         this.disabled = false;
19328     },
19329
19330     
19331     showMenu : function(){
19332         if(this.menu){
19333             this.menu.show(this.el, this.menuAlign);
19334         }
19335         return this;
19336     },
19337
19338     
19339     hideMenu : function(){
19340         if(this.menu){
19341             this.menu.hide();
19342         }
19343         return this;
19344     },
19345
19346     
19347     hasVisibleMenu : function(){
19348         return this.menu && this.menu.isVisible();
19349     },
19350
19351         onClick : function(e){
19352         if(e){
19353             e.preventDefault();
19354         }
19355         if(e.button != 0){
19356             return;
19357         }
19358         if(!this.disabled){
19359             if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
19360                 this.toggle();
19361             }
19362             if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
19363                 this.showMenu();
19364             }
19365             this.fireEvent("click", this, e);
19366             if(this.handler){
19367                                 this.handler.call(this.scope || this, this, e);
19368             }
19369         }
19370     },
19371
19372         isMenuTriggerOver : function(e, internal){
19373         return this.menu && !internal;
19374     },
19375
19376         isMenuTriggerOut : function(e, internal){
19377         return this.menu && !internal;
19378     },
19379
19380         onMouseOver : function(e){
19381         if(!this.disabled){
19382             var internal = e.within(this.el,  true);
19383             if(!internal){
19384                 this.el.addClass("x-btn-over");
19385                 Ext.getDoc().on('mouseover', this.monitorMouseOver, this);
19386                 this.fireEvent('mouseover', this, e);
19387             }
19388             if(this.isMenuTriggerOver(e, internal)){
19389                 this.fireEvent('menutriggerover', this, this.menu, e);
19390             }
19391         }
19392     },
19393
19394         monitorMouseOver : function(e){
19395         if(e.target != this.el.dom && !e.within(this.el)){
19396             Ext.getDoc().un('mouseover', this.monitorMouseOver, this);
19397             this.onMouseOut(e);
19398         }
19399     },
19400
19401         onMouseOut : function(e){
19402         var internal = e.within(this.el) && e.target != this.el.dom;
19403         this.el.removeClass("x-btn-over");
19404         this.fireEvent('mouseout', this, e);
19405         if(this.isMenuTriggerOut(e, internal)){
19406             this.fireEvent('menutriggerout', this, this.menu, e);
19407         }
19408     },
19409         onFocus : function(e){
19410         if(!this.disabled){
19411             this.el.addClass("x-btn-focus");
19412         }
19413     },
19414         onBlur : function(e){
19415         this.el.removeClass("x-btn-focus");
19416     },
19417
19418         getClickEl : function(e, isUp){
19419        return this.el;
19420     },
19421
19422         onMouseDown : function(e){
19423         if(!this.disabled && e.button == 0){
19424             this.getClickEl(e).addClass("x-btn-click");
19425             Ext.getDoc().on('mouseup', this.onMouseUp, this);
19426         }
19427     },
19428         onMouseUp : function(e){
19429         if(e.button == 0){
19430             this.getClickEl(e, true).removeClass("x-btn-click");
19431             Ext.getDoc().un('mouseup', this.onMouseUp, this);
19432         }
19433     },
19434         onMenuShow : function(e){
19435         this.ignoreNextClick = 0;
19436         this.el.addClass("x-btn-menu-active");
19437         this.fireEvent('menushow', this, this.menu);
19438     },
19439         onMenuHide : function(e){
19440         this.el.removeClass("x-btn-menu-active");
19441         this.ignoreNextClick = this.restoreClick.defer(250, this);
19442         this.fireEvent('menuhide', this, this.menu);
19443     },
19444
19445         restoreClick : function(){
19446         this.ignoreNextClick = 0;
19447     }
19448
19449
19450
19451     
19452 });
19453 Ext.reg('button', Ext.Button);
19454
19455 Ext.ButtonToggleMgr = function(){
19456    var groups = {};
19457
19458    function toggleGroup(btn, state){
19459        if(state){
19460            var g = groups[btn.toggleGroup];
19461            for(var i = 0, l = g.length; i < l; i++){
19462                if(g[i] != btn){
19463                    g[i].toggle(false);
19464                }
19465            }
19466        }
19467    }
19468
19469    return {
19470        register : function(btn){
19471            if(!btn.toggleGroup){
19472                return;
19473            }
19474            var g = groups[btn.toggleGroup];
19475            if(!g){
19476                g = groups[btn.toggleGroup] = [];
19477            }
19478            g.push(btn);
19479            btn.on("toggle", toggleGroup);
19480        },
19481
19482        unregister : function(btn){
19483            if(!btn.toggleGroup){
19484                return;
19485            }
19486            var g = groups[btn.toggleGroup];
19487            if(g){
19488                g.remove(btn);
19489                btn.un("toggle", toggleGroup);
19490            }
19491        }
19492    };
19493 }();
19494 \r
19495 Ext.SplitButton = Ext.extend(Ext.Button, {\r
19496         
19497     arrowSelector : 'button:last',\r
19498 \r
19499     
19500     initComponent : function(){\r
19501         Ext.SplitButton.superclass.initComponent.call(this);\r
19502         \r
19503         this.addEvents("arrowclick");\r
19504     },\r
19505 \r
19506     
19507     onRender : function(ct, position){\r
19508         
19509         var tpl = new Ext.Template(\r
19510             '<table cellspacing="0" class="x-btn-menu-wrap x-btn"><tr><td>',\r
19511             '<table cellspacing="0" class="x-btn-wrap x-btn-menu-text-wrap"><tbody>',\r
19512             '<tr><td class="x-btn-left"><i>&#160;</i></td><td class="x-btn-center"><button class="x-btn-text" type="{1}">{0}</button></td></tr>',\r
19513             "</tbody></table></td><td>",\r
19514             '<table cellspacing="0" class="x-btn-wrap x-btn-menu-arrow-wrap"><tbody>',\r
19515             '<tr><td class="x-btn-center"><button class="x-btn-menu-arrow-el" type="button">&#160;</button></td><td class="x-btn-right"><i>&#160;</i></td></tr>',\r
19516             "</tbody></table></td></tr></table>"\r
19517         );\r
19518         var btn, targs = [this.text || '&#160;', this.type];\r
19519         if(position){\r
19520             btn = tpl.insertBefore(position, targs, true);\r
19521         }else{\r
19522             btn = tpl.append(ct, targs, true);\r
19523         }\r
19524         var btnEl = btn.child(this.buttonSelector);\r
19525 \r
19526         this.initButtonEl(btn, btnEl);\r
19527         this.arrowBtnTable = btn.child("table:last");\r
19528         if(this.arrowTooltip){\r
19529             btn.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;\r
19530         }\r
19531     },\r
19532 \r
19533     
19534     autoWidth : function(){\r
19535         if(this.el){\r
19536             var tbl = this.el.child("table:first");\r
19537             var tbl2 = this.el.child("table:last");\r
19538             this.el.setWidth("auto");\r
19539             tbl.setWidth("auto");\r
19540             if(Ext.isIE7 && Ext.isStrict){\r
19541                 var ib = this.el.child(this.buttonSelector);\r
19542                 if(ib && ib.getWidth() > 20){\r
19543                     ib.clip();\r
19544                     ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));\r
19545                 }\r
19546             }\r
19547             if(this.minWidth){\r
19548                 if((tbl.getWidth()+tbl2.getWidth()) < this.minWidth){\r
19549                     tbl.setWidth(this.minWidth-tbl2.getWidth());\r
19550                 }\r
19551             }\r
19552             this.el.setWidth(tbl.getWidth()+tbl2.getWidth());\r
19553         } \r
19554     },\r
19555 \r
19556     \r
19557     setArrowHandler : function(handler, scope){\r
19558         this.arrowHandler = handler;\r
19559         this.scope = scope;  \r
19560     },\r
19561 \r
19562     
19563     onClick : function(e){\r
19564         e.preventDefault();\r
19565         if(!this.disabled){\r
19566             if(e.getTarget(".x-btn-menu-arrow-wrap")){\r
19567                 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){\r
19568                     this.showMenu();\r
19569                 }\r
19570                 this.fireEvent("arrowclick", this, e);\r
19571                 if(this.arrowHandler){\r
19572                     this.arrowHandler.call(this.scope || this, this, e);\r
19573                 }\r
19574             }else{\r
19575                 if(this.enableToggle){\r
19576                     this.toggle();\r
19577                 }\r
19578                 this.fireEvent("click", this, e);\r
19579                 if(this.handler){\r
19580                     this.handler.call(this.scope || this, this, e);\r
19581                 }\r
19582             }\r
19583         }\r
19584     },\r
19585 \r
19586     
19587     getClickEl : function(e, isUp){\r
19588         if(!isUp){\r
19589             return (this.lastClickEl = e.getTarget("table", 10, true));\r
19590         }\r
19591         return this.lastClickEl;\r
19592     },\r
19593 \r
19594     
19595     onDisable : function(){\r
19596         if(this.el){\r
19597             if(!Ext.isIE6){\r
19598                 this.el.addClass("x-item-disabled");\r
19599             }\r
19600             this.el.child(this.buttonSelector).dom.disabled = true;\r
19601             this.el.child(this.arrowSelector).dom.disabled = true;\r
19602         }\r
19603         this.disabled = true;\r
19604     },\r
19605 \r
19606     
19607     onEnable : function(){\r
19608         if(this.el){\r
19609             if(!Ext.isIE6){\r
19610                 this.el.removeClass("x-item-disabled");\r
19611             }\r
19612             this.el.child(this.buttonSelector).dom.disabled = false;\r
19613             this.el.child(this.arrowSelector).dom.disabled = false;\r
19614         }\r
19615         this.disabled = false;\r
19616     },\r
19617 \r
19618     
19619     isMenuTriggerOver : function(e){\r
19620         return this.menu && e.within(this.arrowBtnTable) && !e.within(this.arrowBtnTable, true);\r
19621     },\r
19622 \r
19623     
19624     isMenuTriggerOut : function(e, internal){\r
19625         return this.menu && !e.within(this.arrowBtnTable);\r
19626     },\r
19627 \r
19628     
19629     onDestroy : function(){\r
19630         Ext.destroy(this.arrowBtnTable);\r
19631         Ext.SplitButton.superclass.onDestroy.call(this);\r
19632     }\r
19633 });\r
19634 \r
19635
19636 Ext.MenuButton = Ext.SplitButton;\r
19637 \r
19638 \r
19639 Ext.reg('splitbutton', Ext.SplitButton);
19640 \r
19641 Ext.CycleButton = Ext.extend(Ext.SplitButton, {\r
19642     \r
19643     \r
19644     \r
19645     \r
19646 \r
19647     
19648     getItemText : function(item){\r
19649         if(item && this.showText === true){\r
19650             var text = '';\r
19651             if(this.prependText){\r
19652                 text += this.prependText;\r
19653             }\r
19654             text += item.text;\r
19655             return text;\r
19656         }\r
19657         return undefined;\r
19658     },\r
19659 \r
19660     \r
19661     setActiveItem : function(item, suppressEvent){\r
19662         if(typeof item != 'object'){\r
19663             item = this.menu.items.get(item);\r
19664         }\r
19665         if(item){\r
19666             if(!this.rendered){\r
19667                 this.text = this.getItemText(item);\r
19668                 this.iconCls = item.iconCls;\r
19669             }else{\r
19670                 var t = this.getItemText(item);\r
19671                 if(t){\r
19672                     this.setText(t);\r
19673                 }\r
19674                 this.setIconClass(item.iconCls);\r
19675             }\r
19676             this.activeItem = item;\r
19677             if(!item.checked){\r
19678                 item.setChecked(true, true);\r
19679             }\r
19680             if(this.forceIcon){\r
19681                 this.setIconClass(this.forceIcon);\r
19682             }\r
19683             if(!suppressEvent){\r
19684                 this.fireEvent('change', this, item);\r
19685             }\r
19686         }\r
19687     },\r
19688 \r
19689     \r
19690     getActiveItem : function(){\r
19691         return this.activeItem;\r
19692     },\r
19693 \r
19694     
19695     initComponent : function(){\r
19696         this.addEvents(\r
19697             \r
19698             "change"\r
19699         );\r
19700 \r
19701         if(this.changeHandler){\r
19702             this.on('change', this.changeHandler, this.scope||this);\r
19703             delete this.changeHandler;\r
19704         }\r
19705 \r
19706         this.itemCount = this.items.length;\r
19707 \r
19708         this.menu = {cls:'x-cycle-menu', items:[]};\r
19709         var checked;\r
19710         for(var i = 0, len = this.itemCount; i < len; i++){\r
19711             var item = this.items[i];\r
19712             item.group = item.group || this.id;\r
19713             item.itemIndex = i;\r
19714             item.checkHandler = this.checkHandler;\r
19715             item.scope = this;\r
19716             item.checked = item.checked || false;\r
19717             this.menu.items.push(item);\r
19718             if(item.checked){\r
19719                 checked = item;\r
19720             }\r
19721         }\r
19722         this.setActiveItem(checked, true);\r
19723         Ext.CycleButton.superclass.initComponent.call(this);\r
19724 \r
19725         this.on('click', this.toggleSelected, this);\r
19726     },\r
19727 \r
19728     
19729     checkHandler : function(item, pressed){\r
19730         if(pressed){\r
19731             this.setActiveItem(item);\r
19732         }\r
19733     },\r
19734 \r
19735     \r
19736     toggleSelected : function(){\r
19737         this.menu.render();\r
19738                 \r
19739                 var nextIdx, checkItem;\r
19740                 for (var i = 1; i < this.itemCount; i++) {\r
19741                         nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;\r
19742                         
19743                         checkItem = this.menu.items.itemAt(nextIdx);\r
19744                         
19745                         if (!checkItem.disabled) {\r
19746                                 checkItem.setChecked(true);\r
19747                                 break;\r
19748                         }\r
19749                 }\r
19750     }\r
19751 });\r
19752 Ext.reg('cycle', Ext.CycleButton);
19753  \r
19754  Ext.Toolbar = function(config){\r
19755     if(Ext.isArray(config)){\r
19756         config = {buttons:config};\r
19757     }\r
19758     Ext.Toolbar.superclass.constructor.call(this, config);\r
19759 };\r
19760 \r
19761 (function(){\r
19762 \r
19763 var T = Ext.Toolbar;\r
19764 \r
19765 Ext.extend(T, Ext.BoxComponent, {\r
19766 \r
19767     trackMenus : true,\r
19768 \r
19769     
19770     initComponent : function(){\r
19771         T.superclass.initComponent.call(this);\r
19772 \r
19773         if(this.items){\r
19774             this.buttons = this.items;\r
19775         }\r
19776         \r
19777         this.items = new Ext.util.MixedCollection(false, function(o){\r
19778             return o.itemId || o.id || Ext.id();\r
19779         });\r
19780     },\r
19781 \r
19782     
19783     autoCreate: {\r
19784         cls:'x-toolbar x-small-editor',\r
19785         html:'<table cellspacing="0"><tr></tr></table>'\r
19786     },\r
19787 \r
19788     
19789     onRender : function(ct, position){\r
19790         this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);\r
19791         this.tr = this.el.child("tr", true);\r
19792     },\r
19793 \r
19794     
19795     afterRender : function(){\r
19796         T.superclass.afterRender.call(this);\r
19797         if(this.buttons){\r
19798             this.add.apply(this, this.buttons);\r
19799             delete this.buttons;\r
19800         }\r
19801     },\r
19802 \r
19803     \r
19804     add : function(){\r
19805         var a = arguments, l = a.length;\r
19806         for(var i = 0; i < l; i++){\r
19807             var el = a[i];\r
19808             if(el.isFormField){ 
19809                 this.addField(el);\r
19810             }else if(el.render){ 
19811                 this.addItem(el);\r
19812             }else if(typeof el == "string"){ 
19813                 if(el == "separator" || el == "-"){\r
19814                     this.addSeparator();\r
19815                 }else if(el == " "){\r
19816                     this.addSpacer();\r
19817                 }else if(el == "->"){\r
19818                     this.addFill();\r
19819                 }else{\r
19820                     this.addText(el);\r
19821                 }\r
19822             }else if(el.tagName){ 
19823                 this.addElement(el);\r
19824             }else if(typeof el == "object"){ 
19825                 if(el.xtype){\r
19826                     this.addField(Ext.ComponentMgr.create(el, 'button'));\r
19827                 }else{\r
19828                     this.addButton(el);\r
19829                 }\r
19830             }\r
19831         }\r
19832     },\r
19833     \r
19834     \r
19835     addSeparator : function(){\r
19836         return this.addItem(new T.Separator());\r
19837     },\r
19838 \r
19839     \r
19840     addSpacer : function(){\r
19841         return this.addItem(new T.Spacer());\r
19842     },\r
19843 \r
19844     \r
19845     addFill : function(){\r
19846         return this.addItem(new T.Fill());\r
19847     },\r
19848 \r
19849     \r
19850     addElement : function(el){\r
19851         return this.addItem(new T.Item(el));\r
19852     },\r
19853     \r
19854     \r
19855     addItem : function(item){\r
19856         var td = this.nextBlock();\r
19857         this.initMenuTracking(item);\r
19858         item.render(td);\r
19859         this.items.add(item);\r
19860         return item;\r
19861     },\r
19862     \r
19863     \r
19864     addButton : function(config){\r
19865         if(Ext.isArray(config)){\r
19866             var buttons = [];\r
19867             for(var i = 0, len = config.length; i < len; i++) {\r
19868                 buttons.push(this.addButton(config[i]));\r
19869             }\r
19870             return buttons;\r
19871         }\r
19872         var b = config;\r
19873         if(!(config instanceof T.Button)){\r
19874             b = config.split ? \r
19875                 new T.SplitButton(config) :\r
19876                 new T.Button(config);\r
19877         }\r
19878         var td = this.nextBlock();\r
19879         this.initMenuTracking(b);\r
19880         b.render(td);\r
19881         this.items.add(b);\r
19882         return b;\r
19883     },\r
19884 \r
19885     
19886     initMenuTracking : function(item){\r
19887         if(this.trackMenus && item.menu){\r
19888             item.on({\r
19889                 'menutriggerover' : this.onButtonTriggerOver,\r
19890                 'menushow' : this.onButtonMenuShow,\r
19891                 'menuhide' : this.onButtonMenuHide,\r
19892                 scope: this\r
19893             })\r
19894         }\r
19895     },\r
19896 \r
19897     \r
19898     addText : function(text){\r
19899         return this.addItem(new T.TextItem(text));\r
19900     },\r
19901     \r
19902     \r
19903     insertButton : function(index, item){\r
19904         if(Ext.isArray(item)){\r
19905             var buttons = [];\r
19906             for(var i = 0, len = item.length; i < len; i++) {\r
19907                buttons.push(this.insertButton(index + i, item[i]));\r
19908             }\r
19909             return buttons;\r
19910         }\r
19911         if (!(item instanceof T.Button)){\r
19912            item = new T.Button(item);\r
19913         }\r
19914         var td = document.createElement("td");\r
19915         this.tr.insertBefore(td, this.tr.childNodes[index]);\r
19916         this.initMenuTracking(item);\r
19917         item.render(td);\r
19918         this.items.insert(index, item);\r
19919         return item;\r
19920     },\r
19921     \r
19922     \r
19923     addDom : function(config, returnEl){\r
19924         var td = this.nextBlock();\r
19925         Ext.DomHelper.overwrite(td, config);\r
19926         var ti = new T.Item(td.firstChild);\r
19927         ti.render(td);\r
19928         this.items.add(ti);\r
19929         return ti;\r
19930     },\r
19931 \r
19932     \r
19933     addField : function(field){\r
19934         var td = this.nextBlock();\r
19935         field.render(td);\r
19936         var ti = new T.Item(td.firstChild);\r
19937         ti.render(td);\r
19938         this.items.add(ti);\r
19939         return ti;\r
19940     },\r
19941 \r
19942     
19943     nextBlock : function(){\r
19944         var td = document.createElement("td");\r
19945         this.tr.appendChild(td);\r
19946         return td;\r
19947     },\r
19948 \r
19949     
19950     onDestroy : function(){\r
19951         Ext.Toolbar.superclass.onDestroy.call(this);\r
19952         if(this.rendered){\r
19953             if(this.items){ 
19954                 Ext.destroy.apply(Ext, this.items.items);\r
19955             }\r
19956             Ext.Element.uncache(this.tr);\r
19957         }\r
19958     },\r
19959 \r
19960     
19961     onDisable : function(){\r
19962         this.items.each(function(item){\r
19963              if(item.disable){\r
19964                  item.disable();\r
19965              }\r
19966         });\r
19967     },\r
19968 \r
19969     
19970     onEnable : function(){\r
19971         this.items.each(function(item){\r
19972              if(item.enable){\r
19973                  item.enable();\r
19974              }\r
19975         });\r
19976     },\r
19977 \r
19978     
19979     onButtonTriggerOver : function(btn){\r
19980         if(this.activeMenuBtn && this.activeMenuBtn != btn){\r
19981             this.activeMenuBtn.hideMenu();\r
19982             btn.showMenu();\r
19983             this.activeMenuBtn = btn;\r
19984         }\r
19985     },\r
19986 \r
19987     
19988     onButtonMenuShow : function(btn){\r
19989         this.activeMenuBtn = btn;\r
19990     },\r
19991 \r
19992     
19993     onButtonMenuHide : function(btn){\r
19994         delete this.activeMenuBtn;\r
19995     }\r
19996 \r
19997     \r
19998 });\r
19999 Ext.reg('toolbar', Ext.Toolbar);\r
20000 \r
20001 \r
20002 T.Item = function(el){\r
20003     this.el = Ext.getDom(el);\r
20004     this.id = Ext.id(this.el);\r
20005     this.hidden = false;\r
20006 };\r
20007 \r
20008 T.Item.prototype = {\r
20009     \r
20010     \r
20011     getEl : function(){\r
20012        return this.el;  \r
20013     },\r
20014 \r
20015     
20016     render : function(td){\r
20017         this.td = td;\r
20018         td.appendChild(this.el);\r
20019     },\r
20020     \r
20021     \r
20022     destroy : function(){\r
20023         if(this.td && this.td.parentNode){\r
20024             this.td.parentNode.removeChild(this.td);\r
20025         }\r
20026     },\r
20027     \r
20028     \r
20029     show: function(){\r
20030         this.hidden = false;\r
20031         this.td.style.display = "";\r
20032     },\r
20033     \r
20034     \r
20035     hide: function(){\r
20036         this.hidden = true;\r
20037         this.td.style.display = "none";\r
20038     },\r
20039     \r
20040     \r
20041     setVisible: function(visible){\r
20042         if(visible) {\r
20043             this.show();\r
20044         }else{\r
20045             this.hide();\r
20046         }\r
20047     },\r
20048     \r
20049     \r
20050     focus : function(){\r
20051         Ext.fly(this.el).focus();\r
20052     },\r
20053     \r
20054     \r
20055     disable : function(){\r
20056         Ext.fly(this.td).addClass("x-item-disabled");\r
20057         this.disabled = true;\r
20058         this.el.disabled = true;\r
20059     },\r
20060     \r
20061     \r
20062     enable : function(){\r
20063         Ext.fly(this.td).removeClass("x-item-disabled");\r
20064         this.disabled = false;\r
20065         this.el.disabled = false;\r
20066     }\r
20067 };\r
20068 Ext.reg('tbitem', T.Item);\r
20069 \r
20070 \r
20071 \r
20072 T.Separator = function(){\r
20073     var s = document.createElement("span");\r
20074     s.className = "ytb-sep";\r
20075     T.Separator.superclass.constructor.call(this, s);\r
20076 };\r
20077 Ext.extend(T.Separator, T.Item, {\r
20078     enable:Ext.emptyFn,\r
20079     disable:Ext.emptyFn,\r
20080     focus:Ext.emptyFn\r
20081 });\r
20082 Ext.reg('tbseparator', T.Separator);\r
20083 \r
20084 \r
20085 T.Spacer = function(){\r
20086     var s = document.createElement("div");\r
20087     s.className = "ytb-spacer";\r
20088     T.Spacer.superclass.constructor.call(this, s);\r
20089 };\r
20090 Ext.extend(T.Spacer, T.Item, {\r
20091     enable:Ext.emptyFn,\r
20092     disable:Ext.emptyFn,\r
20093     focus:Ext.emptyFn\r
20094 });\r
20095 \r
20096 Ext.reg('tbspacer', T.Spacer);\r
20097 \r
20098 \r
20099 T.Fill = Ext.extend(T.Spacer, {\r
20100     
20101     render : function(td){\r
20102         td.style.width = '100%';\r
20103         T.Fill.superclass.render.call(this, td);\r
20104     }\r
20105 });\r
20106 Ext.reg('tbfill', T.Fill);\r
20107 \r
20108 \r
20109 T.TextItem = function(t){\r
20110     var s = document.createElement("span");\r
20111     s.className = "ytb-text";\r
20112     s.innerHTML = t.text ? t.text : t;\r
20113     T.TextItem.superclass.constructor.call(this, s);\r
20114 };\r
20115 Ext.extend(T.TextItem, T.Item, {\r
20116     enable:Ext.emptyFn,\r
20117     disable:Ext.emptyFn,\r
20118     focus:Ext.emptyFn\r
20119 });\r
20120 Ext.reg('tbtext', T.TextItem);\r
20121 \r
20122 \r
20123 \r
20124 T.Button = Ext.extend(Ext.Button, {\r
20125     hideParent : true,\r
20126 \r
20127     onDestroy : function(){\r
20128         T.Button.superclass.onDestroy.call(this);\r
20129         if(this.container){\r
20130             this.container.remove();\r
20131         }\r
20132     }\r
20133 });\r
20134 Ext.reg('tbbutton', T.Button);\r
20135 \r
20136 \r
20137 T.SplitButton = Ext.extend(Ext.SplitButton, {\r
20138     hideParent : true,\r
20139 \r
20140     onDestroy : function(){\r
20141         T.SplitButton.superclass.onDestroy.call(this);\r
20142         if(this.container){\r
20143             this.container.remove();\r
20144         }\r
20145     }\r
20146 });\r
20147 \r
20148 Ext.reg('tbsplit', T.SplitButton);\r
20149
20150 T.MenuButton = T.SplitButton;\r
20151 \r
20152 })();\r
20153
20154
20155 Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
20156     
20157     
20158     
20159     pageSize: 20,
20160     
20161     displayMsg : 'Displaying {0} - {1} of {2}',
20162     
20163     emptyMsg : 'No data to display',
20164     
20165     beforePageText : "Page",
20166     
20167     afterPageText : "of {0}",
20168     
20169     firstText : "First Page",
20170     
20171     prevText : "Previous Page",
20172     
20173     nextText : "Next Page",
20174     
20175     lastText : "Last Page",
20176     
20177     refreshText : "Refresh",
20178
20179     
20180     paramNames : {start: 'start', limit: 'limit'},
20181
20182     initComponent : function(){
20183         Ext.PagingToolbar.superclass.initComponent.call(this);
20184         this.cursor = 0;
20185         this.bind(this.store);
20186     },
20187
20188         onRender : function(ct, position){
20189         Ext.PagingToolbar.superclass.onRender.call(this, ct, position);
20190         this.first = this.addButton({
20191             tooltip: this.firstText,
20192             iconCls: "x-tbar-page-first",
20193             disabled: true,
20194             handler: this.onClick.createDelegate(this, ["first"])
20195         });
20196         this.prev = this.addButton({
20197             tooltip: this.prevText,
20198             iconCls: "x-tbar-page-prev",
20199             disabled: true,
20200             handler: this.onClick.createDelegate(this, ["prev"])
20201         });
20202         this.addSeparator();
20203         this.add(this.beforePageText);
20204         this.field = Ext.get(this.addDom({
20205            tag: "input",
20206            type: "text",
20207            size: "3",
20208            value: "1",
20209            cls: "x-tbar-page-number"
20210         }).el);
20211         this.field.on("keydown", this.onPagingKeydown, this);
20212         this.field.on("focus", function(){this.dom.select();});
20213         this.afterTextEl = this.addText(String.format(this.afterPageText, 1));
20214         this.field.setHeight(18);
20215         this.addSeparator();
20216         this.next = this.addButton({
20217             tooltip: this.nextText,
20218             iconCls: "x-tbar-page-next",
20219             disabled: true,
20220             handler: this.onClick.createDelegate(this, ["next"])
20221         });
20222         this.last = this.addButton({
20223             tooltip: this.lastText,
20224             iconCls: "x-tbar-page-last",
20225             disabled: true,
20226             handler: this.onClick.createDelegate(this, ["last"])
20227         });
20228         this.addSeparator();
20229         this.loading = this.addButton({
20230             tooltip: this.refreshText,
20231             iconCls: "x-tbar-loading",
20232             handler: this.onClick.createDelegate(this, ["refresh"])
20233         });
20234
20235         if(this.displayInfo){
20236             this.displayEl = Ext.fly(this.el.dom).createChild({cls:'x-paging-info'});
20237         }
20238         if(this.dsLoaded){
20239             this.onLoad.apply(this, this.dsLoaded);
20240         }
20241     },
20242
20243         updateInfo : function(){
20244         if(this.displayEl){
20245             var count = this.store.getCount();
20246             var msg = count == 0 ?
20247                 this.emptyMsg :
20248                 String.format(
20249                     this.displayMsg,
20250                     this.cursor+1, this.cursor+count, this.store.getTotalCount()
20251                 );
20252             this.displayEl.update(msg);
20253         }
20254     },
20255
20256         onLoad : function(store, r, o){
20257         if(!this.rendered){
20258             this.dsLoaded = [store, r, o];
20259             return;
20260         }
20261        this.cursor = o.params ? o.params[this.paramNames.start] : 0;
20262        var d = this.getPageData(), ap = d.activePage, ps = d.pages;
20263
20264        this.afterTextEl.el.innerHTML = String.format(this.afterPageText, d.pages);
20265        this.field.dom.value = ap;
20266        this.first.setDisabled(ap == 1);
20267        this.prev.setDisabled(ap == 1);
20268        this.next.setDisabled(ap == ps);
20269        this.last.setDisabled(ap == ps);
20270        this.loading.enable();
20271        this.updateInfo();
20272     },
20273
20274         getPageData : function(){
20275         var total = this.store.getTotalCount();
20276         return {
20277             total : total,
20278             activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
20279             pages :  total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
20280         };
20281     },
20282
20283         onLoadError : function(){
20284         if(!this.rendered){
20285             return;
20286         }
20287         this.loading.enable();
20288     },
20289
20290     readPage : function(d){
20291         var v = this.field.dom.value, pageNum;
20292         if (!v || isNaN(pageNum = parseInt(v, 10))) {
20293             this.field.dom.value = d.activePage;
20294             return false;
20295         }
20296         return pageNum;
20297     },
20298
20299         onPagingKeydown : function(e){
20300         var k = e.getKey(), d = this.getPageData(), pageNum;
20301         if (k == e.RETURN) {
20302             e.stopEvent();
20303             if(pageNum = this.readPage(d)){
20304                 pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
20305                 this.doLoad(pageNum * this.pageSize);
20306             }
20307         }else if (k == e.HOME || k == e.END){
20308             e.stopEvent();
20309             pageNum = k == e.HOME ? 1 : d.pages;
20310             this.field.dom.value = pageNum;
20311         }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
20312             e.stopEvent();
20313             if(pageNum = this.readPage(d)){
20314                 var increment = e.shiftKey ? 10 : 1;
20315                 if(k == e.DOWN || k == e.PAGEDOWN){
20316                     increment *= -1;
20317                 }
20318                 pageNum += increment;
20319                 if(pageNum >= 1 & pageNum <= d.pages){
20320                     this.field.dom.value = pageNum;
20321                 }
20322             }
20323         }
20324     },
20325
20326         beforeLoad : function(){
20327         if(this.rendered && this.loading){
20328             this.loading.disable();
20329         }
20330     },
20331
20332     doLoad : function(start){
20333         var o = {}, pn = this.paramNames;
20334         o[pn.start] = start;
20335         o[pn.limit] = this.pageSize;
20336         this.store.load({params:o});
20337     },
20338
20339         onClick : function(which){
20340         var store = this.store;
20341         switch(which){
20342             case "first":
20343                 this.doLoad(0);
20344             break;
20345             case "prev":
20346                 this.doLoad(Math.max(0, this.cursor-this.pageSize));
20347             break;
20348             case "next":
20349                 this.doLoad(this.cursor+this.pageSize);
20350             break;
20351             case "last":
20352                 var total = store.getTotalCount();
20353                 var extra = total % this.pageSize;
20354                 var lastStart = extra ? (total - extra) : total-this.pageSize;
20355                 this.doLoad(lastStart);
20356             break;
20357             case "refresh":
20358                 this.doLoad(this.cursor);
20359             break;
20360         }
20361     },
20362
20363     
20364     unbind : function(store){
20365         store = Ext.StoreMgr.lookup(store);
20366         store.un("beforeload", this.beforeLoad, this);
20367         store.un("load", this.onLoad, this);
20368         store.un("loadexception", this.onLoadError, this);
20369         this.store = undefined;
20370     },
20371
20372     
20373     bind : function(store){
20374         store = Ext.StoreMgr.lookup(store);
20375         store.on("beforeload", this.beforeLoad, this);
20376         store.on("load", this.onLoad, this);
20377         store.on("loadexception", this.onLoadError, this);
20378         this.store = store;
20379     }
20380 });
20381 Ext.reg('paging', Ext.PagingToolbar);
20382 \r
20383 Ext.Resizable = function(el, config){\r
20384     this.el = Ext.get(el);\r
20385     \r
20386     if(config && config.wrap){\r
20387         config.resizeChild = this.el;\r
20388         this.el = this.el.wrap(typeof config.wrap == "object" ? config.wrap : {cls:"xresizable-wrap"});\r
20389         this.el.id = this.el.dom.id = config.resizeChild.id + "-rzwrap";\r
20390         this.el.setStyle("overflow", "hidden");\r
20391         this.el.setPositioning(config.resizeChild.getPositioning());\r
20392         config.resizeChild.clearPositioning();\r
20393         if(!config.width || !config.height){\r
20394             var csize = config.resizeChild.getSize();\r
20395             this.el.setSize(csize.width, csize.height);\r
20396         }\r
20397         if(config.pinned && !config.adjustments){\r
20398             config.adjustments = "auto";\r
20399         }\r
20400     }\r
20401 \r
20402     this.proxy = this.el.createProxy({tag: "div", cls: "x-resizable-proxy", id: this.el.id + "-rzproxy"});\r
20403     this.proxy.unselectable();\r
20404     this.proxy.enableDisplayMode('block');\r
20405 \r
20406     Ext.apply(this, config);\r
20407     \r
20408     if(this.pinned){\r
20409         this.disableTrackOver = true;\r
20410         this.el.addClass("x-resizable-pinned");\r
20411     }\r
20412     
20413     var position = this.el.getStyle("position");\r
20414     if(position != "absolute" && position != "fixed"){\r
20415         this.el.setStyle("position", "relative");\r
20416     }\r
20417     if(!this.handles){ 
20418         this.handles = 's,e,se';\r
20419         if(this.multiDirectional){\r
20420             this.handles += ',n,w';\r
20421         }\r
20422     }\r
20423     if(this.handles == "all"){\r
20424         this.handles = "n s e w ne nw se sw";\r
20425     }\r
20426     var hs = this.handles.split(/\s*?[,;]\s*?| /);\r
20427     var ps = Ext.Resizable.positions;\r
20428     for(var i = 0, len = hs.length; i < len; i++){\r
20429         if(hs[i] && ps[hs[i]]){\r
20430             var pos = ps[hs[i]];\r
20431             this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent);\r
20432         }\r
20433     }\r
20434     
20435     this.corner = this.southeast;\r
20436     \r
20437     if(this.handles.indexOf("n") != -1 || this.handles.indexOf("w") != -1){\r
20438         this.updateBox = true;\r
20439     }   \r
20440    \r
20441     this.activeHandle = null;\r
20442     \r
20443     if(this.resizeChild){\r
20444         if(typeof this.resizeChild == "boolean"){\r
20445             this.resizeChild = Ext.get(this.el.dom.firstChild, true);\r
20446         }else{\r
20447             this.resizeChild = Ext.get(this.resizeChild, true);\r
20448         }\r
20449     }\r
20450     \r
20451     if(this.adjustments == "auto"){\r
20452         var rc = this.resizeChild;\r
20453         var hw = this.west, he = this.east, hn = this.north, hs = this.south;\r
20454         if(rc && (hw || hn)){\r
20455             rc.position("relative");\r
20456             rc.setLeft(hw ? hw.el.getWidth() : 0);\r
20457             rc.setTop(hn ? hn.el.getHeight() : 0);\r
20458         }\r
20459         this.adjustments = [\r
20460             (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),\r
20461             (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1 \r
20462         ];\r
20463     }\r
20464     \r
20465     if(this.draggable){\r
20466         this.dd = this.dynamic ? \r
20467             this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});\r
20468         this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);\r
20469     }\r
20470     \r
20471     
20472     this.addEvents(\r
20473         "beforeresize",\r
20474         "resize"\r
20475     );\r
20476     \r
20477     if(this.width !== null && this.height !== null){\r
20478         this.resizeTo(this.width, this.height);\r
20479     }else{\r
20480         this.updateChildSize();\r
20481     }\r
20482     if(Ext.isIE){\r
20483         this.el.dom.style.zoom = 1;\r
20484     }\r
20485     Ext.Resizable.superclass.constructor.call(this);\r
20486 };\r
20487 \r
20488 Ext.extend(Ext.Resizable, Ext.util.Observable, {\r
20489         resizeChild : false,\r
20490         adjustments : [0, 0],\r
20491         minWidth : 5,\r
20492         minHeight : 5,\r
20493         maxWidth : 10000,\r
20494         maxHeight : 10000,\r
20495         enabled : true,\r
20496         animate : false,\r
20497         duration : .35,\r
20498         dynamic : false,\r
20499         handles : false,\r
20500         multiDirectional : false,\r
20501         disableTrackOver : false,\r
20502         easing : 'easeOutStrong',\r
20503         widthIncrement : 0,\r
20504         heightIncrement : 0,\r
20505         pinned : false,\r
20506         width : null,\r
20507         height : null,\r
20508         preserveRatio : false,\r
20509         transparent: false,\r
20510         minX: 0,\r
20511         minY: 0,\r
20512         draggable: false,\r
20513 \r
20514         \r
20515         \r
20516 \r
20517         \r
20518         \r
20519     \r
20520     \r
20521     resizeTo : function(width, height){\r
20522         this.el.setSize(width, height);\r
20523         this.updateChildSize();\r
20524         this.fireEvent("resize", this, width, height, null);\r
20525     },\r
20526 \r
20527     
20528     startSizing : function(e, handle){\r
20529         this.fireEvent("beforeresize", this, e);\r
20530         if(this.enabled){ 
20531 \r
20532             if(!this.overlay){\r
20533                 this.overlay = this.el.createProxy({tag: "div", cls: "x-resizable-overlay", html: "&#160;"}, Ext.getBody());\r
20534                 this.overlay.unselectable();\r
20535                 this.overlay.enableDisplayMode("block");\r
20536                 this.overlay.on("mousemove", this.onMouseMove, this);\r
20537                 this.overlay.on("mouseup", this.onMouseUp, this);\r
20538             }\r
20539             this.overlay.setStyle("cursor", handle.el.getStyle("cursor"));\r
20540 \r
20541             this.resizing = true;\r
20542             this.startBox = this.el.getBox();\r
20543             this.startPoint = e.getXY();\r
20544             this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],\r
20545                             (this.startBox.y + this.startBox.height) - this.startPoint[1]];\r
20546 \r
20547             this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));\r
20548             this.overlay.show();\r
20549 \r
20550             if(this.constrainTo) {\r
20551                 var ct = Ext.get(this.constrainTo);\r
20552                 this.resizeRegion = ct.getRegion().adjust(\r
20553                     ct.getFrameWidth('t'),\r
20554                     ct.getFrameWidth('l'),\r
20555                     -ct.getFrameWidth('b'),\r
20556                     -ct.getFrameWidth('r')\r
20557                 );\r
20558             }\r
20559 \r
20560             this.proxy.setStyle('visibility', 'hidden'); 
20561             this.proxy.show();\r
20562             this.proxy.setBox(this.startBox);\r
20563             if(!this.dynamic){\r
20564                 this.proxy.setStyle('visibility', 'visible');\r
20565             }\r
20566         }\r
20567     },\r
20568 \r
20569     
20570     onMouseDown : function(handle, e){\r
20571         if(this.enabled){\r
20572             e.stopEvent();\r
20573             this.activeHandle = handle;\r
20574             this.startSizing(e, handle);\r
20575         }          \r
20576     },\r
20577 \r
20578     
20579     onMouseUp : function(e){\r
20580         var size = this.resizeElement();\r
20581         this.resizing = false;\r
20582         this.handleOut();\r
20583         this.overlay.hide();\r
20584         this.proxy.hide();\r
20585         this.fireEvent("resize", this, size.width, size.height, e);\r
20586     },\r
20587 \r
20588     
20589     updateChildSize : function(){\r
20590         if(this.resizeChild){\r
20591             var el = this.el;\r
20592             var child = this.resizeChild;\r
20593             var adj = this.adjustments;\r
20594             if(el.dom.offsetWidth){\r
20595                 var b = el.getSize(true);\r
20596                 child.setSize(b.width+adj[0], b.height+adj[1]);\r
20597             }\r
20598             
20599             
20600             
20601             
20602             if(Ext.isIE){\r
20603                 setTimeout(function(){\r
20604                     if(el.dom.offsetWidth){\r
20605                         var b = el.getSize(true);\r
20606                         child.setSize(b.width+adj[0], b.height+adj[1]);\r
20607                     }\r
20608                 }, 10);\r
20609             }\r
20610         }\r
20611     },\r
20612 \r
20613     
20614     snap : function(value, inc, min){\r
20615         if(!inc || !value) return value;\r
20616         var newValue = value;\r
20617         var m = value % inc;\r
20618         if(m > 0){\r
20619             if(m > (inc/2)){\r
20620                 newValue = value + (inc-m);\r
20621             }else{\r
20622                 newValue = value - m;\r
20623             }\r
20624         }\r
20625         return Math.max(min, newValue);\r
20626     },\r
20627 \r
20628     
20629     resizeElement : function(){\r
20630         var box = this.proxy.getBox();\r
20631         if(this.updateBox){\r
20632             this.el.setBox(box, false, this.animate, this.duration, null, this.easing);\r
20633         }else{\r
20634             this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);\r
20635         }\r
20636         this.updateChildSize();\r
20637         if(!this.dynamic){\r
20638             this.proxy.hide();\r
20639         }\r
20640         return box;\r
20641     },\r
20642 \r
20643     
20644     constrain : function(v, diff, m, mx){\r
20645         if(v - diff < m){\r
20646             diff = v - m;    \r
20647         }else if(v - diff > mx){\r
20648             diff = mx - v; \r
20649         }\r
20650         return diff;                \r
20651     },\r
20652 \r
20653     
20654     onMouseMove : function(e){\r
20655         if(this.enabled){\r
20656             try{
20657 \r
20658             if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {\r
20659                 return;\r
20660             }\r
20661 \r
20662             
20663             var curSize = this.curSize || this.startBox;\r
20664             var x = this.startBox.x, y = this.startBox.y;\r
20665             var ox = x, oy = y;\r
20666             var w = curSize.width, h = curSize.height;\r
20667             var ow = w, oh = h;\r
20668             var mw = this.minWidth, mh = this.minHeight;\r
20669             var mxw = this.maxWidth, mxh = this.maxHeight;\r
20670             var wi = this.widthIncrement;\r
20671             var hi = this.heightIncrement;\r
20672             \r
20673             var eventXY = e.getXY();\r
20674             var diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0]));\r
20675             var diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1]));\r
20676             \r
20677             var pos = this.activeHandle.position;\r
20678             \r
20679             switch(pos){\r
20680                 case "east":\r
20681                     w += diffX; \r
20682                     w = Math.min(Math.max(mw, w), mxw);\r
20683                     break;\r
20684                 case "south":\r
20685                     h += diffY;\r
20686                     h = Math.min(Math.max(mh, h), mxh);\r
20687                     break;\r
20688                 case "southeast":\r
20689                     w += diffX; \r
20690                     h += diffY;\r
20691                     w = Math.min(Math.max(mw, w), mxw);\r
20692                     h = Math.min(Math.max(mh, h), mxh);\r
20693                     break;\r
20694                 case "north":\r
20695                     diffY = this.constrain(h, diffY, mh, mxh);\r
20696                     y += diffY;\r
20697                     h -= diffY;\r
20698                     break;\r
20699                 case "west":\r
20700                     diffX = this.constrain(w, diffX, mw, mxw);\r
20701                     x += diffX;\r
20702                     w -= diffX;\r
20703                     break;\r
20704                 case "northeast":\r
20705                     w += diffX; \r
20706                     w = Math.min(Math.max(mw, w), mxw);\r
20707                     diffY = this.constrain(h, diffY, mh, mxh);\r
20708                     y += diffY;\r
20709                     h -= diffY;\r
20710                     break;\r
20711                 case "northwest":\r
20712                     diffX = this.constrain(w, diffX, mw, mxw);\r
20713                     diffY = this.constrain(h, diffY, mh, mxh);\r
20714                     y += diffY;\r
20715                     h -= diffY;\r
20716                     x += diffX;\r
20717                     w -= diffX;\r
20718                     break;\r
20719                case "southwest":\r
20720                     diffX = this.constrain(w, diffX, mw, mxw);\r
20721                     h += diffY;\r
20722                     h = Math.min(Math.max(mh, h), mxh);\r
20723                     x += diffX;\r
20724                     w -= diffX;\r
20725                     break;\r
20726             }\r
20727             \r
20728             var sw = this.snap(w, wi, mw);\r
20729             var sh = this.snap(h, hi, mh);\r
20730             if(sw != w || sh != h){\r
20731                 switch(pos){\r
20732                     case "northeast":\r
20733                         y -= sh - h;\r
20734                     break;\r
20735                     case "north":\r
20736                         y -= sh - h;\r
20737                         break;\r
20738                     case "southwest":\r
20739                         x -= sw - w;\r
20740                     break;\r
20741                     case "west":\r
20742                         x -= sw - w;\r
20743                         break;\r
20744                     case "northwest":\r
20745                         x -= sw - w;\r
20746                         y -= sh - h;\r
20747                     break;\r
20748                 }\r
20749                 w = sw;\r
20750                 h = sh;\r
20751             }\r
20752             \r
20753             if(this.preserveRatio){\r
20754                 switch(pos){\r
20755                     case "southeast":\r
20756                     case "east":\r
20757                         h = oh * (w/ow);\r
20758                         h = Math.min(Math.max(mh, h), mxh);\r
20759                         w = ow * (h/oh);\r
20760                        break;\r
20761                     case "south":\r
20762                         w = ow * (h/oh);\r
20763                         w = Math.min(Math.max(mw, w), mxw);\r
20764                         h = oh * (w/ow);\r
20765                         break;\r
20766                     case "northeast":\r
20767                         w = ow * (h/oh);\r
20768                         w = Math.min(Math.max(mw, w), mxw);\r
20769                         h = oh * (w/ow);\r
20770                     break;\r
20771                     case "north":\r
20772                         var tw = w;\r
20773                         w = ow * (h/oh);\r
20774                         w = Math.min(Math.max(mw, w), mxw);\r
20775                         h = oh * (w/ow);\r
20776                         x += (tw - w) / 2;\r
20777                         break;\r
20778                     case "southwest":\r
20779                         h = oh * (w/ow);\r
20780                         h = Math.min(Math.max(mh, h), mxh);\r
20781                         var tw = w;\r
20782                         w = ow * (h/oh);\r
20783                         x += tw - w;\r
20784                         break;\r
20785                     case "west":\r
20786                         var th = h;\r
20787                         h = oh * (w/ow);\r
20788                         h = Math.min(Math.max(mh, h), mxh);\r
20789                         y += (th - h) / 2;\r
20790                         var tw = w;\r
20791                         w = ow * (h/oh);\r
20792                         x += tw - w;\r
20793                        break;\r
20794                     case "northwest":\r
20795                         var tw = w;\r
20796                         var th = h;\r
20797                         h = oh * (w/ow);\r
20798                         h = Math.min(Math.max(mh, h), mxh);\r
20799                         w = ow * (h/oh);\r
20800                         y += th - h;\r
20801                          x += tw - w;\r
20802                        break;\r
20803                         \r
20804                 }\r
20805             }\r
20806             this.proxy.setBounds(x, y, w, h);\r
20807             if(this.dynamic){\r
20808                 this.resizeElement();\r
20809             }\r
20810             }catch(e){}\r
20811         }\r
20812     },\r
20813 \r
20814     
20815     handleOver : function(){\r
20816         if(this.enabled){\r
20817             this.el.addClass("x-resizable-over");\r
20818         }\r
20819     },\r
20820 \r
20821     
20822     handleOut : function(){\r
20823         if(!this.resizing){\r
20824             this.el.removeClass("x-resizable-over");\r
20825         }\r
20826     },\r
20827     \r
20828     \r
20829     getEl : function(){\r
20830         return this.el;\r
20831     },\r
20832     \r
20833     \r
20834     getResizeChild : function(){\r
20835         return this.resizeChild;\r
20836     },\r
20837     \r
20838     \r
20839     destroy : function(removeEl){\r
20840         this.proxy.remove();\r
20841         if(this.overlay){\r
20842             this.overlay.removeAllListeners();\r
20843             this.overlay.remove();\r
20844         }\r
20845         var ps = Ext.Resizable.positions;\r
20846         for(var k in ps){\r
20847             if(typeof ps[k] != "function" && this[ps[k]]){\r
20848                 var h = this[ps[k]];\r
20849                 h.el.removeAllListeners();\r
20850                 h.el.remove();\r
20851             }\r
20852         }\r
20853         if(removeEl){\r
20854             this.el.update("");\r
20855             this.el.remove();\r
20856         }\r
20857     },\r
20858 \r
20859     syncHandleHeight : function(){\r
20860         var h = this.el.getHeight(true);\r
20861         if(this.west){\r
20862             this.west.el.setHeight(h);\r
20863         }\r
20864         if(this.east){\r
20865             this.east.el.setHeight(h);\r
20866         }\r
20867     }\r
20868 });\r
20869 \r
20870
20871
20872 Ext.Resizable.positions = {\r
20873     n: "north", s: "south", e: "east", w: "west", se: "southeast", sw: "southwest", nw: "northwest", ne: "northeast"\r
20874 };\r
20875 \r
20876
20877 Ext.Resizable.Handle = function(rz, pos, disableTrackOver, transparent){\r
20878     if(!this.tpl){\r
20879         
20880         var tpl = Ext.DomHelper.createTemplate(\r
20881             {tag: "div", cls: "x-resizable-handle x-resizable-handle-{0}"}\r
20882         );\r
20883         tpl.compile();\r
20884         Ext.Resizable.Handle.prototype.tpl = tpl;\r
20885     }\r
20886     this.position = pos;\r
20887     this.rz = rz;\r
20888     this.el = this.tpl.append(rz.el.dom, [this.position], true);\r
20889     this.el.unselectable();\r
20890     if(transparent){\r
20891         this.el.setOpacity(0);\r
20892     }\r
20893     this.el.on("mousedown", this.onMouseDown, this);\r
20894     if(!disableTrackOver){\r
20895         this.el.on("mouseover", this.onMouseOver, this);\r
20896         this.el.on("mouseout", this.onMouseOut, this);\r
20897     }\r
20898 };\r
20899 \r
20900
20901 Ext.Resizable.Handle.prototype = {\r
20902     afterResize : function(rz){\r
20903         
20904     },\r
20905     
20906     onMouseDown : function(e){\r
20907         this.rz.onMouseDown(this, e);\r
20908     },\r
20909     
20910     onMouseOver : function(e){\r
20911         this.rz.handleOver(this, e);\r
20912     },\r
20913     
20914     onMouseOut : function(e){\r
20915         this.rz.handleOut(this, e);\r
20916     }  \r
20917 };\r
20918 \r
20919 \r
20920 \r
20921
20922
20923 Ext.Editor = function(field, config){
20924     this.field = field;
20925     Ext.Editor.superclass.constructor.call(this, config);
20926 };
20927
20928 Ext.extend(Ext.Editor, Ext.Component, {
20929     
20930     
20931     
20932     
20933     
20934     value : "",
20935     
20936     alignment: "c-c?",
20937     
20938     shadow : "frame",
20939     
20940     constrain : false,
20941     
20942     swallowKeys : true,
20943     
20944     completeOnEnter : false,
20945     
20946     cancelOnEsc : false,
20947     
20948     updateEl : false,
20949
20950     initComponent : function(){
20951         Ext.Editor.superclass.initComponent.call(this);
20952         this.addEvents(
20953             
20954             "beforestartedit",
20955             
20956             "startedit",
20957             
20958             "beforecomplete",
20959             
20960             "complete",
20961             
20962             "specialkey"
20963         );
20964     },
20965
20966         onRender : function(ct, position){
20967         this.el = new Ext.Layer({
20968             shadow: this.shadow,
20969             cls: "x-editor",
20970             parentEl : ct,
20971             shim : this.shim,
20972             shadowOffset:4,
20973             id: this.id,
20974             constrain: this.constrain
20975         });
20976         this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
20977         if(this.field.msgTarget != 'title'){
20978             this.field.msgTarget = 'qtip';
20979         }
20980         this.field.inEditor = true;
20981         this.field.render(this.el);
20982         if(Ext.isGecko){
20983             this.field.el.dom.setAttribute('autocomplete', 'off');
20984         }
20985         this.field.on("specialkey", this.onSpecialKey, this);
20986         if(this.swallowKeys){
20987             this.field.el.swallowEvent(['keydown','keypress']);
20988         }
20989         this.field.show();
20990         this.field.on("blur", this.onBlur, this);
20991         if(this.field.grow){
20992             this.field.on("autosize", this.el.sync,  this.el, {delay:1});
20993         }
20994     },
20995
20996     onSpecialKey : function(field, e){
20997         if(this.completeOnEnter && e.getKey() == e.ENTER){
20998             e.stopEvent();
20999             this.completeEdit();
21000         }else if(this.cancelOnEsc && e.getKey() == e.ESC){
21001             this.cancelEdit();
21002         }else{
21003             this.fireEvent('specialkey', field, e);
21004         }
21005     },
21006
21007     
21008     startEdit : function(el, value){
21009         if(this.editing){
21010             this.completeEdit();
21011         }
21012         this.boundEl = Ext.get(el);
21013         var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
21014         if(!this.rendered){
21015             this.render(this.parentEl || document.body);
21016         }
21017         if(this.fireEvent("beforestartedit", this, this.boundEl, v) === false){
21018             return;
21019         }
21020         this.startValue = v;
21021         this.field.setValue(v);
21022         this.doAutoSize();
21023         this.el.alignTo(this.boundEl, this.alignment);
21024         this.editing = true;
21025         this.show();
21026     },
21027
21028         doAutoSize : function(){
21029         if(this.autoSize){
21030             var sz = this.boundEl.getSize();
21031             switch(this.autoSize){
21032                 case "width":
21033                     this.setSize(sz.width,  "");
21034                 break;
21035                 case "height":
21036                     this.setSize("",  sz.height);
21037                 break;
21038                 default:
21039                     this.setSize(sz.width,  sz.height);
21040             }
21041         }
21042     },
21043
21044     
21045     setSize : function(w, h){
21046         delete this.field.lastSize;
21047         this.field.setSize(w, h);
21048         if(this.el){
21049             this.el.sync();
21050         }
21051     },
21052
21053     
21054     realign : function(){
21055         this.el.alignTo(this.boundEl, this.alignment);
21056     },
21057
21058     
21059     completeEdit : function(remainVisible){
21060         if(!this.editing){
21061             return;
21062         }
21063         var v = this.getValue();
21064         if(this.revertInvalid !== false && !this.field.isValid()){
21065             v = this.startValue;
21066             this.cancelEdit(true);
21067         }
21068         if(String(v) === String(this.startValue) && this.ignoreNoChange){
21069             this.editing = false;
21070             this.hide();
21071             return;
21072         }
21073         if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
21074             this.editing = false;
21075             if(this.updateEl && this.boundEl){
21076                 this.boundEl.update(v);
21077             }
21078             if(remainVisible !== true){
21079                 this.hide();
21080             }
21081             this.fireEvent("complete", this, v, this.startValue);
21082         }
21083     },
21084
21085         onShow : function(){
21086         this.el.show();
21087         if(this.hideEl !== false){
21088             this.boundEl.hide();
21089         }
21090         this.field.show();
21091         if(Ext.isIE && !this.fixIEFocus){             this.fixIEFocus = true;
21092             this.deferredFocus.defer(50, this);
21093         }else{
21094             this.field.focus();
21095         }
21096         this.fireEvent("startedit", this.boundEl, this.startValue);
21097     },
21098
21099     deferredFocus : function(){
21100         if(this.editing){
21101             this.field.focus();
21102         }
21103     },
21104
21105     
21106     cancelEdit : function(remainVisible){
21107         if(this.editing){
21108             this.setValue(this.startValue);
21109             if(remainVisible !== true){
21110                 this.hide();
21111             }
21112         }
21113     },
21114
21115         onBlur : function(){
21116         if(this.allowBlur !== true && this.editing){
21117             this.completeEdit();
21118         }
21119     },
21120
21121         onHide : function(){
21122         if(this.editing){
21123             this.completeEdit();
21124             return;
21125         }
21126         this.field.blur();
21127         if(this.field.collapse){
21128             this.field.collapse();
21129         }
21130         this.el.hide();
21131         if(this.hideEl !== false){
21132             this.boundEl.show();
21133         }
21134     },
21135
21136     
21137     setValue : function(v){
21138         this.field.setValue(v);
21139     },
21140
21141     
21142     getValue : function(){
21143         return this.field.getValue();
21144     },
21145
21146     beforeDestroy : function(){
21147         this.field.destroy();
21148         this.field = null;
21149     }
21150 });
21151 Ext.reg('editor', Ext.Editor);
21152 \r
21153 Ext.MessageBox = function(){\r
21154     var dlg, opt, mask, waitTimer;\r
21155     var bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl;\r
21156     var buttons, activeTextEl, bwidth, iconCls = '';\r
21157 \r
21158     
21159     var handleButton = function(button){\r
21160         dlg.hide();\r
21161         Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value], 1);\r
21162     };\r
21163 \r
21164     
21165     var handleHide = function(){\r
21166         if(opt && opt.cls){\r
21167             dlg.el.removeClass(opt.cls);\r
21168         }\r
21169         progressBar.reset();\r
21170     };\r
21171 \r
21172     
21173     var handleEsc = function(d, k, e){\r
21174         if(opt && opt.closable !== false){\r
21175             dlg.hide();\r
21176         }\r
21177         if(e){\r
21178             e.stopEvent();\r
21179         }\r
21180     };\r
21181 \r
21182     
21183     var updateButtons = function(b){\r
21184         var width = 0;\r
21185         if(!b){\r
21186             buttons["ok"].hide();\r
21187             buttons["cancel"].hide();\r
21188             buttons["yes"].hide();\r
21189             buttons["no"].hide();\r
21190             return width;\r
21191         }\r
21192         dlg.footer.dom.style.display = '';\r
21193         for(var k in buttons){\r
21194             if(typeof buttons[k] != "function"){\r
21195                 if(b[k]){\r
21196                     buttons[k].show();\r
21197                     buttons[k].setText(typeof b[k] == "string" ? b[k] : Ext.MessageBox.buttonText[k]);\r
21198                     width += buttons[k].el.getWidth()+15;\r
21199                 }else{\r
21200                     buttons[k].hide();\r
21201                 }\r
21202             }\r
21203         }\r
21204         return width;\r
21205     };\r
21206 \r
21207     return {\r
21208         \r
21209         getDialog : function(titleText){\r
21210            if(!dlg){\r
21211                 dlg = new Ext.Window({\r
21212                     autoCreate : true,\r
21213                     title:titleText,\r
21214                     resizable:false,\r
21215                     constrain:true,\r
21216                     constrainHeader:true,\r
21217                     minimizable : false,\r
21218                     maximizable : false,\r
21219                     stateful: false,\r
21220                     modal: true,\r
21221                     shim:true,\r
21222                     buttonAlign:"center",\r
21223                     width:400,\r
21224                     height:100,\r
21225                     minHeight: 80,\r
21226                     plain:true,\r
21227                     footer:true,\r
21228                     closable:true,\r
21229                     close : function(){\r
21230                         if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){\r
21231                             handleButton("no");\r
21232                         }else{\r
21233                             handleButton("cancel");\r
21234                         }\r
21235                     }\r
21236                 });\r
21237                 buttons = {};\r
21238                 var bt = this.buttonText;\r
21239                 
21240                 buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));\r
21241                 buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));\r
21242                 buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));\r
21243                 buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));\r
21244                 buttons["ok"].hideMode = buttons["yes"].hideMode = buttons["no"].hideMode = buttons["cancel"].hideMode = 'offsets';\r
21245                 dlg.render(document.body);\r
21246                 dlg.getEl().addClass('x-window-dlg');\r
21247                 mask = dlg.mask;\r
21248                 bodyEl = dlg.body.createChild({\r
21249                     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>'\r
21250                 });\r
21251                 iconEl = Ext.get(bodyEl.dom.firstChild);\r
21252                 var contentEl = bodyEl.dom.childNodes[1];\r
21253                 msgEl = Ext.get(contentEl.firstChild);\r
21254                 textboxEl = Ext.get(contentEl.childNodes[2]);\r
21255                 textboxEl.enableDisplayMode();\r
21256                 textboxEl.addKeyListener([10,13], function(){\r
21257                     if(dlg.isVisible() && opt && opt.buttons){\r
21258                         if(opt.buttons.ok){\r
21259                             handleButton("ok");\r
21260                         }else if(opt.buttons.yes){\r
21261                             handleButton("yes");\r
21262                         }\r
21263                     }\r
21264                 });\r
21265                 textareaEl = Ext.get(contentEl.childNodes[3]);\r
21266                 textareaEl.enableDisplayMode();\r
21267                 progressBar = new Ext.ProgressBar({\r
21268                     renderTo:bodyEl\r
21269                 });\r
21270                bodyEl.createChild({cls:'x-clear'});\r
21271             }\r
21272             return dlg;\r
21273         },\r
21274 \r
21275         \r
21276         updateText : function(text){\r
21277             if(!dlg.isVisible() && !opt.width){\r
21278                 dlg.setSize(this.maxWidth, 100); 
21279             }\r
21280             msgEl.update(text || '&#160;');\r
21281 \r
21282             var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0;\r
21283             var mw = msgEl.getWidth() + msgEl.getMargins('lr');\r
21284             var fw = dlg.getFrameWidth('lr');\r
21285             var bw = dlg.body.getFrameWidth('lr');\r
21286             if (Ext.isIE && iw > 0){\r
21287                 
21288                 
21289                 iw += 3;\r
21290             }\r
21291             var w = Math.max(Math.min(opt.width || iw+mw+fw+bw, this.maxWidth),\r
21292                         Math.max(opt.minWidth || this.minWidth, bwidth || 0));\r
21293 \r
21294             if(opt.prompt === true){\r
21295                 activeTextEl.setWidth(w-iw-fw-bw);\r
21296             }\r
21297             if(opt.progress === true || opt.wait === true){\r
21298                 progressBar.setSize(w-iw-fw-bw);\r
21299             }\r
21300             dlg.setSize(w, 'auto').center();\r
21301             return this;\r
21302         },\r
21303 \r
21304         \r
21305         updateProgress : function(value, progressText, msg){\r
21306             progressBar.updateProgress(value, progressText);\r
21307             if(msg){\r
21308                 this.updateText(msg);\r
21309             }\r
21310             return this;\r
21311         },\r
21312 \r
21313         \r
21314         isVisible : function(){\r
21315             return dlg && dlg.isVisible();\r
21316         },\r
21317 \r
21318         \r
21319         hide : function(){\r
21320             if(this.isVisible()){\r
21321                 dlg.hide();\r
21322                 handleHide();\r
21323             }\r
21324             return this;\r
21325         },\r
21326 \r
21327         \r
21328         show : function(options){\r
21329             if(this.isVisible()){\r
21330                 this.hide();\r
21331             }\r
21332             opt = options;\r
21333             var d = this.getDialog(opt.title || "&#160;");\r
21334 \r
21335             d.setTitle(opt.title || "&#160;");\r
21336             var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);\r
21337             d.tools.close.setDisplayed(allowClose);\r
21338             activeTextEl = textboxEl;\r
21339             opt.prompt = opt.prompt || (opt.multiline ? true : false);\r
21340             if(opt.prompt){\r
21341                 if(opt.multiline){\r
21342                     textboxEl.hide();\r
21343                     textareaEl.show();\r
21344                     textareaEl.setHeight(typeof opt.multiline == "number" ?\r
21345                         opt.multiline : this.defaultTextHeight);\r
21346                     activeTextEl = textareaEl;\r
21347                 }else{\r
21348                     textboxEl.show();\r
21349                     textareaEl.hide();\r
21350                 }\r
21351             }else{\r
21352                 textboxEl.hide();\r
21353                 textareaEl.hide();\r
21354             }\r
21355             activeTextEl.dom.value = opt.value || "";\r
21356             if(opt.prompt){\r
21357                 d.focusEl = activeTextEl;\r
21358             }else{\r
21359                 var bs = opt.buttons;\r
21360                 var db = null;\r
21361                 if(bs && bs.ok){\r
21362                     db = buttons["ok"];\r
21363                 }else if(bs && bs.yes){\r
21364                     db = buttons["yes"];\r
21365                 }\r
21366                 if (db){\r
21367                     d.focusEl = db;\r
21368                 }\r
21369             }\r
21370             this.setIcon(opt.icon);\r
21371             bwidth = updateButtons(opt.buttons);\r
21372             progressBar.setVisible(opt.progress === true || opt.wait === true);\r
21373             this.updateProgress(0, opt.progressText);\r
21374             this.updateText(opt.msg);\r
21375             if(opt.cls){\r
21376                 d.el.addClass(opt.cls);\r
21377             }\r
21378             d.proxyDrag = opt.proxyDrag === true;\r
21379             d.modal = opt.modal !== false;\r
21380             d.mask = opt.modal !== false ? mask : false;\r
21381             if(!d.isVisible()){\r
21382                 
21383                 document.body.appendChild(dlg.el.dom);\r
21384                 d.setAnimateTarget(opt.animEl);\r
21385                 d.show(opt.animEl);\r
21386             }\r
21387 \r
21388             
21389             d.on('show', function(){\r
21390                 if(allowClose === true){\r
21391                     d.keyMap.enable();\r
21392                 }else{\r
21393                     d.keyMap.disable();\r
21394                 }\r
21395             }, this, {single:true});\r
21396 \r
21397             if(opt.wait === true){\r
21398                 progressBar.wait(opt.waitConfig);\r
21399             }\r
21400             return this;\r
21401         },\r
21402 \r
21403         \r
21404         setIcon : function(icon){\r
21405             if(icon && icon != ''){\r
21406                 iconEl.removeClass('x-hidden');\r
21407                 iconEl.replaceClass(iconCls, icon);\r
21408                 iconCls = icon;\r
21409             }else{\r
21410                 iconEl.replaceClass(iconCls, 'x-hidden');\r
21411                 iconCls = '';\r
21412             }\r
21413             return this;\r
21414         },\r
21415 \r
21416         \r
21417         progress : function(title, msg, progressText){\r
21418             this.show({\r
21419                 title : title,\r
21420                 msg : msg,\r
21421                 buttons: false,\r
21422                 progress:true,\r
21423                 closable:false,\r
21424                 minWidth: this.minProgressWidth,\r
21425                 progressText: progressText\r
21426             });\r
21427             return this;\r
21428         },\r
21429 \r
21430         \r
21431         wait : function(msg, title, config){\r
21432             this.show({\r
21433                 title : title,\r
21434                 msg : msg,\r
21435                 buttons: false,\r
21436                 closable:false,\r
21437                 wait:true,\r
21438                 modal:true,\r
21439                 minWidth: this.minProgressWidth,\r
21440                 waitConfig: config\r
21441             });\r
21442             return this;\r
21443         },\r
21444 \r
21445         \r
21446         alert : function(title, msg, fn, scope){\r
21447             this.show({\r
21448                 title : title,\r
21449                 msg : msg,\r
21450                 buttons: this.OK,\r
21451                 fn: fn,\r
21452                 scope : scope\r
21453             });\r
21454             return this;\r
21455         },\r
21456 \r
21457         \r
21458         confirm : function(title, msg, fn, scope){\r
21459             this.show({\r
21460                 title : title,\r
21461                 msg : msg,\r
21462                 buttons: this.YESNO,\r
21463                 fn: fn,\r
21464                 scope : scope,\r
21465                 icon: this.QUESTION\r
21466             });\r
21467             return this;\r
21468         },\r
21469 \r
21470         \r
21471         prompt : function(title, msg, fn, scope, multiline){\r
21472             this.show({\r
21473                 title : title,\r
21474                 msg : msg,\r
21475                 buttons: this.OKCANCEL,\r
21476                 fn: fn,\r
21477                 minWidth:250,\r
21478                 scope : scope,\r
21479                 prompt:true,\r
21480                 multiline: multiline\r
21481             });\r
21482             return this;\r
21483         },\r
21484 \r
21485         \r
21486         OK : {ok:true},\r
21487         \r
21488         CANCEL : {cancel:true},\r
21489         \r
21490         OKCANCEL : {ok:true, cancel:true},\r
21491         \r
21492         YESNO : {yes:true, no:true},\r
21493         \r
21494         YESNOCANCEL : {yes:true, no:true, cancel:true},\r
21495         \r
21496         INFO : 'ext-mb-info',\r
21497         \r
21498         WARNING : 'ext-mb-warning',\r
21499         \r
21500         QUESTION : 'ext-mb-question',\r
21501         \r
21502         ERROR : 'ext-mb-error',\r
21503 \r
21504         \r
21505         defaultTextHeight : 75,\r
21506         \r
21507         maxWidth : 600,\r
21508         \r
21509         minWidth : 100,\r
21510         \r
21511         minProgressWidth : 250,\r
21512         \r
21513         buttonText : {\r
21514             ok : "OK",\r
21515             cancel : "Cancel",\r
21516             yes : "Yes",\r
21517             no : "No"\r
21518         }\r
21519     };\r
21520 }();\r
21521 \r
21522 \r
21523 Ext.Msg = Ext.MessageBox;
21524 \r
21525 Ext.Tip = Ext.extend(Ext.Panel, {\r
21526     \r
21527     \r
21528     \r
21529     minWidth : 40,\r
21530     \r
21531     maxWidth : 300,\r
21532     \r
21533     shadow : "sides",\r
21534     \r
21535     defaultAlign : "tl-bl?",\r
21536     autoRender: true,\r
21537     quickShowInterval : 250,\r
21538 \r
21539     
21540     frame:true,\r
21541     hidden:true,\r
21542     baseCls: 'x-tip',\r
21543     floating:{shadow:true,shim:true,useDisplay:true,constrain:false},\r
21544     autoHeight:true,\r
21545 \r
21546     
21547     initComponent : function(){\r
21548         Ext.Tip.superclass.initComponent.call(this);\r
21549         if(this.closable && !this.title){\r
21550             this.elements += ',header';\r
21551         }\r
21552     },\r
21553 \r
21554     
21555     afterRender : function(){\r
21556         Ext.Tip.superclass.afterRender.call(this);\r
21557         if(this.closable){\r
21558             this.addTool({\r
21559                 id: 'close',\r
21560                 handler: this.hide,\r
21561                 scope: this\r
21562             });\r
21563         }\r
21564     },\r
21565 \r
21566     \r
21567     showAt : function(xy){\r
21568         Ext.Tip.superclass.show.call(this);\r
21569         if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){\r
21570             var bw = this.body.getTextWidth();\r
21571             if(this.title){\r
21572                 bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));\r
21573             }\r
21574             bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr");\r
21575             this.setWidth(bw.constrain(this.minWidth, this.maxWidth));\r
21576         }\r
21577         if(this.constrainPosition){\r
21578             xy = this.el.adjustForConstraints(xy);\r
21579         }\r
21580         this.setPagePosition(xy[0], xy[1]);\r
21581     },\r
21582 \r
21583     \r
21584     showBy : function(el, pos){\r
21585         if(!this.rendered){\r
21586             this.render(Ext.getBody());\r
21587         }\r
21588         this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));\r
21589     },\r
21590 \r
21591     initDraggable : function(){\r
21592         this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);\r
21593         this.header.addClass('x-tip-draggable');\r
21594     }\r
21595 });\r
21596 \r
21597
21598 Ext.Tip.DD = function(tip, config){\r
21599     Ext.apply(this, config);\r
21600     this.tip = tip;\r
21601     Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);\r
21602     this.setHandleElId(tip.header.id);\r
21603     this.scroll = false;\r
21604 };\r
21605 \r
21606 Ext.extend(Ext.Tip.DD, Ext.dd.DD, {\r
21607     moveOnly:true,\r
21608     scroll:false,\r
21609     headerOffsets:[100, 25],\r
21610     startDrag : function(){\r
21611         this.tip.el.disableShadow();\r
21612     },\r
21613     endDrag : function(e){\r
21614         this.tip.el.enableShadow(true);\r
21615     }\r
21616 });
21617 \r
21618 Ext.ToolTip = Ext.extend(Ext.Tip, {\r
21619     \r
21620     \r
21621     \r
21622     showDelay: 500,\r
21623     \r
21624     hideDelay: 200,\r
21625     \r
21626     dismissDelay: 5000,\r
21627     \r
21628     mouseOffset: [15,18],\r
21629     \r
21630     trackMouse : false,\r
21631     constrainPosition: true,\r
21632 \r
21633     
21634     initComponent: function(){\r
21635         Ext.ToolTip.superclass.initComponent.call(this);\r
21636         this.lastActive = new Date();\r
21637         this.initTarget();\r
21638     },\r
21639 \r
21640     
21641     initTarget : function(){\r
21642         if(this.target){\r
21643             this.target = Ext.get(this.target);\r
21644             this.target.on('mouseover', this.onTargetOver, this);\r
21645             this.target.on('mouseout', this.onTargetOut, this);\r
21646             this.target.on('mousemove', this.onMouseMove, this);\r
21647         }\r
21648     },\r
21649 \r
21650     
21651     onMouseMove : function(e){\r
21652         this.targetXY = e.getXY();\r
21653         if(!this.hidden && this.trackMouse){\r
21654             this.setPagePosition(this.getTargetXY());\r
21655         }\r
21656     },\r
21657 \r
21658     
21659     getTargetXY : function(){\r
21660         return [this.targetXY[0]+this.mouseOffset[0], this.targetXY[1]+this.mouseOffset[1]];\r
21661     },\r
21662 \r
21663     
21664     onTargetOver : function(e){\r
21665         if(this.disabled || e.within(this.target.dom, true)){\r
21666             return;\r
21667         }\r
21668         this.clearTimer('hide');\r
21669         this.targetXY = e.getXY();\r
21670         this.delayShow();\r
21671     },\r
21672 \r
21673     
21674     delayShow : function(){\r
21675         if(this.hidden && !this.showTimer){\r
21676             if(this.lastActive.getElapsed() < this.quickShowInterval){\r
21677                 this.show();\r
21678             }else{\r
21679                 this.showTimer = this.show.defer(this.showDelay, this);\r
21680             }\r
21681         }else if(!this.hidden && this.autoHide !== false){\r
21682             this.show();\r
21683         }\r
21684     },\r
21685 \r
21686     
21687     onTargetOut : function(e){\r
21688         if(this.disabled || e.within(this.target.dom, true)){\r
21689             return;\r
21690         }\r
21691         this.clearTimer('show');\r
21692         if(this.autoHide !== false){\r
21693             this.delayHide();\r
21694         }\r
21695     },\r
21696 \r
21697     
21698     delayHide : function(){\r
21699         if(!this.hidden && !this.hideTimer){\r
21700             this.hideTimer = this.hide.defer(this.hideDelay, this);\r
21701         }\r
21702     },\r
21703 \r
21704     \r
21705     hide: function(){\r
21706         this.clearTimer('dismiss');\r
21707         this.lastActive = new Date();\r
21708         Ext.ToolTip.superclass.hide.call(this);\r
21709     },\r
21710 \r
21711     \r
21712     show : function(){\r
21713         this.showAt(this.getTargetXY());\r
21714     },\r
21715 \r
21716     
21717     showAt : function(xy){\r
21718         this.lastActive = new Date();\r
21719         this.clearTimers();\r
21720         Ext.ToolTip.superclass.showAt.call(this, xy);\r
21721         if(this.dismissDelay && this.autoHide !== false){\r
21722             this.dismissTimer = this.hide.defer(this.dismissDelay, this);\r
21723         }\r
21724     },\r
21725 \r
21726     
21727     clearTimer : function(name){\r
21728         name = name + 'Timer';\r
21729         clearTimeout(this[name]);\r
21730         delete this[name];\r
21731     },\r
21732 \r
21733     
21734     clearTimers : function(){\r
21735         this.clearTimer('show');\r
21736         this.clearTimer('dismiss');\r
21737         this.clearTimer('hide');\r
21738     },\r
21739 \r
21740     
21741     onShow : function(){\r
21742         Ext.ToolTip.superclass.onShow.call(this);\r
21743         Ext.getDoc().on('mousedown', this.onDocMouseDown, this);\r
21744     },\r
21745 \r
21746     
21747     onHide : function(){\r
21748         Ext.ToolTip.superclass.onHide.call(this);\r
21749         Ext.getDoc().un('mousedown', this.onDocMouseDown, this);\r
21750     },\r
21751 \r
21752     
21753     onDocMouseDown : function(e){\r
21754         if(this.autoHide !== false && !e.within(this.el.dom)){\r
21755             this.disable();\r
21756             this.enable.defer(100, this);\r
21757         }\r
21758     },\r
21759 \r
21760     
21761     onDisable : function(){\r
21762         this.clearTimers();\r
21763         this.hide();\r
21764     },\r
21765 \r
21766     
21767     adjustPosition : function(x, y){\r
21768         
21769         var ay = this.targetXY[1], h = this.getSize().height;\r
21770         if(this.constrainPosition && y <= ay && (y+h) >= ay){\r
21771             y = ay-h-5;\r
21772         }\r
21773         return {x : x, y: y};\r
21774     },\r
21775 \r
21776     
21777     onDestroy : function(){\r
21778         Ext.ToolTip.superclass.onDestroy.call(this);\r
21779         if(this.target){\r
21780             this.target.un('mouseover', this.onTargetOver, this);\r
21781             this.target.un('mouseout', this.onTargetOut, this);\r
21782             this.target.un('mousemove', this.onMouseMove, this);\r
21783         }\r
21784     }\r
21785 });
21786 \r
21787 Ext.QuickTip = Ext.extend(Ext.ToolTip, {\r
21788     \r
21789     \r
21790     interceptTitles : false,\r
21791 \r
21792     
21793     tagConfig : {\r
21794         namespace : "ext",\r
21795         attribute : "qtip",\r
21796         width : "qwidth",\r
21797         target : "target",\r
21798         title : "qtitle",\r
21799         hide : "hide",\r
21800         cls : "qclass",\r
21801         align : "qalign"\r
21802     },\r
21803 \r
21804     
21805     initComponent : function(){\r
21806         this.target = this.target || Ext.getDoc();\r
21807         this.targets = this.targets || {};\r
21808         Ext.QuickTip.superclass.initComponent.call(this);\r
21809     },\r
21810 \r
21811     \r
21812     register : function(config){\r
21813         var cs = Ext.isArray(config) ? config : arguments;\r
21814         for(var i = 0, len = cs.length; i < len; i++){\r
21815             var c = cs[i];\r
21816             var target = c.target;\r
21817             if(target){\r
21818                 if(Ext.isArray(target)){\r
21819                     for(var j = 0, jlen = target.length; j < jlen; j++){\r
21820                         this.targets[Ext.id(target[j])] = c;\r
21821                     }\r
21822                 } else{\r
21823                     this.targets[Ext.id(target)] = c;\r
21824                 }\r
21825             }\r
21826         }\r
21827     },\r
21828 \r
21829     \r
21830     unregister : function(el){\r
21831         delete this.targets[Ext.id(el)];\r
21832     },\r
21833 \r
21834     
21835     onTargetOver : function(e){\r
21836         if(this.disabled){\r
21837             return;\r
21838         }\r
21839         this.targetXY = e.getXY();\r
21840         var t = e.getTarget();\r
21841         if(!t || t.nodeType !== 1 || t == document || t == document.body){\r
21842             return;\r
21843         }\r
21844         if(this.activeTarget && t == this.activeTarget.el){\r
21845             this.clearTimer('hide');\r
21846             this.show();\r
21847             return;\r
21848         }\r
21849         if(t && this.targets[t.id]){\r
21850             this.activeTarget = this.targets[t.id];\r
21851             this.activeTarget.el = t;\r
21852             this.delayShow();\r
21853             return;\r
21854         }\r
21855         var ttp, et = Ext.fly(t), cfg = this.tagConfig;\r
21856         var ns = cfg.namespace;\r
21857         if(this.interceptTitles && t.title){\r
21858             ttp = t.title;\r
21859             t.qtip = ttp;\r
21860             t.removeAttribute("title");\r
21861             e.preventDefault();\r
21862         } else{\r
21863             ttp = t.qtip || et.getAttributeNS(ns, cfg.attribute);\r
21864         }\r
21865         if(ttp){\r
21866             var autoHide = et.getAttributeNS(ns, cfg.hide);\r
21867             this.activeTarget = {\r
21868                 el: t,\r
21869                 text: ttp,\r
21870                 width: et.getAttributeNS(ns, cfg.width),\r
21871                 autoHide: autoHide != "user" && autoHide !== 'false',\r
21872                 title: et.getAttributeNS(ns, cfg.title),\r
21873                 cls: et.getAttributeNS(ns, cfg.cls),\r
21874                 align: et.getAttributeNS(ns, cfg.align)\r
21875             };\r
21876             this.delayShow();\r
21877         }\r
21878     },\r
21879 \r
21880     
21881     onTargetOut : function(e){\r
21882         this.clearTimer('show');\r
21883         if(this.autoHide !== false){\r
21884             this.delayHide();\r
21885         }\r
21886     },\r
21887 \r
21888     
21889     showAt : function(xy){\r
21890         var t = this.activeTarget;\r
21891         if(t){\r
21892             if(!this.rendered){\r
21893                 this.render(Ext.getBody());\r
21894                 this.activeTarget = t;\r
21895             }\r
21896             if(t.width){\r
21897                 this.setWidth(t.width);\r
21898                 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));\r
21899                 this.measureWidth = false;\r
21900             } else{\r
21901                 this.measureWidth = true;\r
21902             }\r
21903             this.setTitle(t.title || '');\r
21904             this.body.update(t.text);\r
21905             this.autoHide = t.autoHide;\r
21906             this.dismissDelay = t.dismissDelay || this.dismissDelay;\r
21907             if(this.lastCls){\r
21908                 this.el.removeClass(this.lastCls);\r
21909                 delete this.lastCls;\r
21910             }\r
21911             if(t.cls){\r
21912                 this.el.addClass(t.cls);\r
21913                 this.lastCls = t.cls;\r
21914             }\r
21915             if(t.align){ 
21916                 xy = this.el.getAlignToXY(t.el, t.align);\r
21917                 this.constrainPosition = false;\r
21918             } else{\r
21919                 this.constrainPosition = true;\r
21920             }\r
21921         }\r
21922         Ext.QuickTip.superclass.showAt.call(this, xy);\r
21923     },\r
21924 \r
21925     
21926     hide: function(){\r
21927         delete this.activeTarget;\r
21928         Ext.QuickTip.superclass.hide.call(this);\r
21929     }\r
21930 });
21931 \r
21932 Ext.QuickTips = function(){\r
21933     var tip, locks = [];\r
21934     return {\r
21935         \r
21936         init : function(){\r
21937             if(!tip){\r
21938                 tip = new Ext.QuickTip({elements:'header,body'});\r
21939             }\r
21940         },\r
21941 \r
21942         \r
21943         enable : function(){\r
21944             if(tip){\r
21945                 locks.pop();\r
21946                 if(locks.length < 1){\r
21947                     tip.enable();\r
21948                 }\r
21949             }\r
21950         },\r
21951 \r
21952         \r
21953         disable : function(){\r
21954             if(tip){\r
21955                 tip.disable();\r
21956             }\r
21957             locks.push(1);\r
21958         },\r
21959 \r
21960         \r
21961         isEnabled : function(){\r
21962             return tip && !tip.disabled;\r
21963         },\r
21964 \r
21965         \r
21966         getQuickTip : function(){\r
21967             return tip;\r
21968         },\r
21969 \r
21970         \r
21971         register : function(){\r
21972             tip.register.apply(tip, arguments);\r
21973         },\r
21974 \r
21975         \r
21976         unregister : function(){\r
21977             tip.unregister.apply(tip, arguments);\r
21978         },\r
21979 \r
21980         \r
21981         tips :function(){\r
21982             tip.register.apply(tip, arguments);\r
21983         }\r
21984     }\r
21985 }();
21986 \r
21987 Ext.tree.TreePanel = Ext.extend(Ext.Panel, {\r
21988     rootVisible : true,\r
21989     animate: Ext.enableFx,\r
21990     lines : true,\r
21991     enableDD : false,\r
21992     hlDrop : Ext.enableFx,\r
21993     pathSeparator: "/",\r
21994 \r
21995     initComponent : function(){\r
21996         Ext.tree.TreePanel.superclass.initComponent.call(this);\r
21997 \r
21998         if(!this.eventModel){\r
21999             this.eventModel = new Ext.tree.TreeEventModel(this);\r
22000         }\r
22001         \r
22002         this.nodeHash = {};\r
22003 \r
22004         \r
22005         if(this.root){\r
22006            this.setRootNode(this.root);\r
22007         }\r
22008 \r
22009         this.addEvents(\r
22010 \r
22011             \r
22012            "append",\r
22013            \r
22014            "remove",\r
22015            \r
22016            "movenode",\r
22017            \r
22018            "insert",\r
22019            \r
22020            "beforeappend",\r
22021            \r
22022            "beforeremove",\r
22023            \r
22024            "beforemovenode",\r
22025            \r
22026             "beforeinsert",\r
22027 \r
22028             \r
22029             "beforeload",\r
22030             \r
22031             "load",\r
22032             \r
22033             "textchange",\r
22034             \r
22035             "beforeexpandnode",\r
22036             \r
22037             "beforecollapsenode",\r
22038             \r
22039             "expandnode",\r
22040             \r
22041             "disabledchange",\r
22042             \r
22043             "collapsenode",\r
22044             \r
22045             "beforeclick",\r
22046             \r
22047             "click",\r
22048             \r
22049             "checkchange",\r
22050             \r
22051             "dblclick",\r
22052             \r
22053             "contextmenu",\r
22054             \r
22055             "beforechildrenrendered",\r
22056            \r
22057             "startdrag",\r
22058             \r
22059             "enddrag",\r
22060             \r
22061             "dragdrop",\r
22062             \r
22063             "beforenodedrop",\r
22064             \r
22065             "nodedrop",\r
22066              \r
22067             "nodedragover"\r
22068         );\r
22069         if(this.singleExpand){\r
22070             this.on("beforeexpandnode", this.restrictExpand, this);\r
22071         }\r
22072     },\r
22073 \r
22074     
22075     proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){\r
22076         if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){\r
22077             ename = ename+'node';\r
22078         }\r
22079         
22080         return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);\r
22081     },\r
22082 \r
22083 \r
22084     \r
22085     getRootNode : function(){\r
22086         return this.root;\r
22087     },\r
22088 \r
22089     \r
22090     setRootNode : function(node){\r
22091         this.root = node;\r
22092         node.ownerTree = this;\r
22093         node.isRoot = true;\r
22094         this.registerNode(node);\r
22095         if(!this.rootVisible){\r
22096                 var uiP = node.attributes.uiProvider;\r
22097                 node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node); \r
22098         }\r
22099         return node;\r
22100     },\r
22101 \r
22102     \r
22103     getNodeById : function(id){\r
22104         return this.nodeHash[id];\r
22105     },\r
22106 \r
22107     
22108     registerNode : function(node){\r
22109         this.nodeHash[node.id] = node;\r
22110     },\r
22111 \r
22112     
22113     unregisterNode : function(node){\r
22114         delete this.nodeHash[node.id];\r
22115     },\r
22116 \r
22117     
22118     toString : function(){\r
22119         return "[Tree"+(this.id?" "+this.id:"")+"]";\r
22120     },\r
22121 \r
22122     
22123     restrictExpand : function(node){\r
22124         var p = node.parentNode;\r
22125         if(p){\r
22126             if(p.expandedChild && p.expandedChild.parentNode == p){\r
22127                 p.expandedChild.collapse();\r
22128             }\r
22129             p.expandedChild = node;\r
22130         }\r
22131     },\r
22132 \r
22133     \r
22134     getChecked : function(a, startNode){\r
22135         startNode = startNode || this.root;\r
22136         var r = [];\r
22137         var f = function(){\r
22138             if(this.attributes.checked){\r
22139                 r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));\r
22140             }\r
22141         }\r
22142         startNode.cascade(f);\r
22143         return r;\r
22144     },\r
22145 \r
22146     \r
22147     getEl : function(){\r
22148         return this.el;\r
22149     },\r
22150 \r
22151     \r
22152     getLoader : function(){\r
22153         return this.loader;\r
22154     },\r
22155 \r
22156     \r
22157     expandAll : function(){\r
22158         this.root.expand(true);\r
22159     },\r
22160 \r
22161     \r
22162     collapseAll : function(){\r
22163         this.root.collapse(true);\r
22164     },\r
22165 \r
22166     \r
22167     getSelectionModel : function(){\r
22168         if(!this.selModel){\r
22169             this.selModel = new Ext.tree.DefaultSelectionModel();\r
22170         }\r
22171         return this.selModel;\r
22172     },\r
22173 \r
22174     \r
22175     expandPath : function(path, attr, callback){\r
22176         attr = attr || "id";\r
22177         var keys = path.split(this.pathSeparator);\r
22178         var curNode = this.root;\r
22179         if(curNode.attributes[attr] != keys[1]){ 
22180             if(callback){\r
22181                 callback(false, null);\r
22182             }\r
22183             return;\r
22184         }\r
22185         var index = 1;\r
22186         var f = function(){\r
22187             if(++index == keys.length){\r
22188                 if(callback){\r
22189                     callback(true, curNode);\r
22190                 }\r
22191                 return;\r
22192             }\r
22193             var c = curNode.findChild(attr, keys[index]);\r
22194             if(!c){\r
22195                 if(callback){\r
22196                     callback(false, curNode);\r
22197                 }\r
22198                 return;\r
22199             }\r
22200             curNode = c;\r
22201             c.expand(false, false, f);\r
22202         };\r
22203         curNode.expand(false, false, f);\r
22204     },\r
22205 \r
22206     \r
22207     selectPath : function(path, attr, callback){\r
22208         attr = attr || "id";\r
22209         var keys = path.split(this.pathSeparator);\r
22210         var v = keys.pop();\r
22211         if(keys.length > 0){\r
22212             var f = function(success, node){\r
22213                 if(success && node){\r
22214                     var n = node.findChild(attr, v);\r
22215                     if(n){\r
22216                         n.select();\r
22217                         if(callback){\r
22218                             callback(true, n);\r
22219                         }\r
22220                     }else if(callback){\r
22221                         callback(false, n);\r
22222                     }\r
22223                 }else{\r
22224                     if(callback){\r
22225                         callback(false, n);\r
22226                     }\r
22227                 }\r
22228             };\r
22229             this.expandPath(keys.join(this.pathSeparator), attr, f);\r
22230         }else{\r
22231             this.root.select();\r
22232             if(callback){\r
22233                 callback(true, this.root);\r
22234             }\r
22235         }\r
22236     },\r
22237 \r
22238     \r
22239     getTreeEl : function(){\r
22240         return this.body;\r
22241     },\r
22242 \r
22243     
22244     onRender : function(ct, position){\r
22245         Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);\r
22246         this.el.addClass('x-tree');\r
22247         this.innerCt = this.body.createChild({tag:"ul",\r
22248                cls:"x-tree-root-ct " +\r
22249                (this.useArrows ? 'x-tree-arrows' : this.lines ? "x-tree-lines" : "x-tree-no-lines")});\r
22250     },\r
22251 \r
22252     
22253     initEvents : function(){\r
22254         Ext.tree.TreePanel.superclass.initEvents.call(this);\r
22255 \r
22256         if(this.containerScroll){\r
22257             Ext.dd.ScrollManager.register(this.body);\r
22258         }\r
22259         if((this.enableDD || this.enableDrop) && !this.dropZone){\r
22260            \r
22261              this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {\r
22262                ddGroup: this.ddGroup || "TreeDD", appendOnly: this.ddAppendOnly === true\r
22263            });\r
22264         }\r
22265         if((this.enableDD || this.enableDrag) && !this.dragZone){\r
22266            \r
22267             this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {\r
22268                ddGroup: this.ddGroup || "TreeDD",\r
22269                scroll: this.ddScroll\r
22270            });\r
22271         }\r
22272         this.getSelectionModel().init(this);\r
22273     },\r
22274 \r
22275     
22276     afterRender : function(){\r
22277         Ext.tree.TreePanel.superclass.afterRender.call(this);\r
22278         this.root.render();\r
22279         if(!this.rootVisible){\r
22280             this.root.renderChildren();\r
22281         }\r
22282     },\r
22283 \r
22284     onDestroy : function(){\r
22285         if(this.rendered){\r
22286             this.body.removeAllListeners();\r
22287             Ext.dd.ScrollManager.unregister(this.body);\r
22288             if(this.dropZone){\r
22289                 this.dropZone.unreg();\r
22290             }\r
22291             if(this.dragZone){\r
22292                this.dragZone.unreg();\r
22293             }\r
22294         }\r
22295         this.root.destroy();\r
22296         this.nodeHash = null;\r
22297         Ext.tree.TreePanel.superclass.onDestroy.call(this);\r
22298     }\r
22299     \r
22300     \r
22301     \r
22302     \r
22303     \r
22304     \r
22305     \r
22306     \r
22307     \r
22308     \r
22309     \r
22310     \r
22311     \r
22312     \r
22313     \r
22314     \r
22315     \r
22316     \r
22317     \r
22318     \r
22319     \r
22320     \r
22321     \r
22322     \r
22323     \r
22324     \r
22325     \r
22326     \r
22327     \r
22328     \r
22329     \r
22330     \r
22331 \r
22332 \r
22333 \r
22334     \r
22335     \r
22336     \r
22337     \r
22338     \r
22339     \r
22340     \r
22341     \r
22342     \r
22343     \r
22344     \r
22345     \r
22346 });\r
22347 Ext.reg('treepanel', Ext.tree.TreePanel);
22348 Ext.tree.TreeEventModel = function(tree){\r
22349     this.tree = tree;\r
22350     this.tree.on('render', this.initEvents, this);\r
22351 }\r
22352 \r
22353 Ext.tree.TreeEventModel.prototype = {\r
22354     initEvents : function(){\r
22355         var el = this.tree.getTreeEl();\r
22356         el.on('click', this.delegateClick, this);\r
22357         if(this.tree.trackMouseOver !== false){\r
22358             el.on('mouseover', this.delegateOver, this);\r
22359             el.on('mouseout', this.delegateOut, this);\r
22360         }\r
22361         el.on('dblclick', this.delegateDblClick, this);\r
22362         el.on('contextmenu', this.delegateContextMenu, this);\r
22363     },\r
22364 \r
22365     getNode : function(e){\r
22366         var t;\r
22367         if(t = e.getTarget('.x-tree-node-el', 10)){\r
22368             var id = Ext.fly(t, '_treeEvents').getAttributeNS('ext', 'tree-node-id');\r
22369             if(id){\r
22370                 return this.tree.getNodeById(id);\r
22371             }\r
22372         }\r
22373         return null;\r
22374     },\r
22375 \r
22376     getNodeTarget : function(e){\r
22377         var t = e.getTarget('.x-tree-node-icon', 1);\r
22378         if(!t){\r
22379             t = e.getTarget('.x-tree-node-el', 6);\r
22380         }\r
22381         return t;\r
22382     },\r
22383 \r
22384     delegateOut : function(e, t){\r
22385         if(!this.beforeEvent(e)){\r
22386             return;\r
22387         }\r
22388         if(e.getTarget('.x-tree-ec-icon', 1)){\r
22389             var n = this.getNode(e);\r
22390             this.onIconOut(e, n);\r
22391             if(n == this.lastEcOver){\r
22392                 delete this.lastEcOver;\r
22393             }\r
22394         }\r
22395         if((t = this.getNodeTarget(e)) && !e.within(t, true)){\r
22396             this.onNodeOut(e, this.getNode(e));\r
22397         }\r
22398     },\r
22399 \r
22400     delegateOver : function(e, t){\r
22401         if(!this.beforeEvent(e)){\r
22402             return;\r
22403         }\r
22404         if(this.lastEcOver){ 
22405             this.onIconOut(e, this.lastEcOver);\r
22406             delete this.lastEcOver;\r
22407         }\r
22408         if(e.getTarget('.x-tree-ec-icon', 1)){\r
22409             this.lastEcOver = this.getNode(e);\r
22410             this.onIconOver(e, this.lastEcOver);\r
22411         }\r
22412         if(t = this.getNodeTarget(e)){\r
22413             this.onNodeOver(e, this.getNode(e));\r
22414         }\r
22415     },\r
22416 \r
22417     delegateClick : function(e, t){\r
22418         if(!this.beforeEvent(e)){\r
22419             return;\r
22420         }\r
22421 \r
22422         if(e.getTarget('input[type=checkbox]', 1)){\r
22423             this.onCheckboxClick(e, this.getNode(e));\r
22424         }\r
22425         else if(e.getTarget('.x-tree-ec-icon', 1)){\r
22426             this.onIconClick(e, this.getNode(e));\r
22427         }\r
22428         else if(this.getNodeTarget(e)){\r
22429             this.onNodeClick(e, this.getNode(e));\r
22430         }\r
22431     },\r
22432 \r
22433     delegateDblClick : function(e, t){\r
22434         if(this.beforeEvent(e) && this.getNodeTarget(e)){\r
22435             this.onNodeDblClick(e, this.getNode(e));\r
22436         }\r
22437     },\r
22438 \r
22439     delegateContextMenu : function(e, t){\r
22440         if(this.beforeEvent(e) && this.getNodeTarget(e)){\r
22441             this.onNodeContextMenu(e, this.getNode(e));\r
22442         }\r
22443     },\r
22444 \r
22445     onNodeClick : function(e, node){\r
22446         node.ui.onClick(e);\r
22447     },\r
22448 \r
22449     onNodeOver : function(e, node){\r
22450         node.ui.onOver(e);\r
22451     },\r
22452 \r
22453     onNodeOut : function(e, node){\r
22454         node.ui.onOut(e);\r
22455     },\r
22456 \r
22457     onIconOver : function(e, node){\r
22458         node.ui.addClass('x-tree-ec-over');\r
22459     },\r
22460 \r
22461     onIconOut : function(e, node){\r
22462         node.ui.removeClass('x-tree-ec-over');\r
22463     },\r
22464 \r
22465     onIconClick : function(e, node){\r
22466         node.ui.ecClick(e);\r
22467     },\r
22468 \r
22469     onCheckboxClick : function(e, node){\r
22470         node.ui.onCheckChange(e);\r
22471     },\r
22472 \r
22473     onNodeDblClick : function(e, node){\r
22474         node.ui.onDblClick(e);\r
22475     },\r
22476 \r
22477     onNodeContextMenu : function(e, node){\r
22478         node.ui.onContextMenu(e);\r
22479     },\r
22480 \r
22481     beforeEvent : function(e){\r
22482         if(this.disabled){\r
22483             e.stopEvent();\r
22484             return false;\r
22485         }\r
22486         return true;\r
22487     },\r
22488 \r
22489     disable: function(){\r
22490         this.disabled = true;\r
22491     },\r
22492 \r
22493     enable: function(){\r
22494         this.disabled = false;\r
22495     }\r
22496 };
22497 \r
22498 Ext.tree.DefaultSelectionModel = function(config){\r
22499    this.selNode = null;\r
22500    \r
22501    this.addEvents(\r
22502        \r
22503        "selectionchange",\r
22504 \r
22505        \r
22506        "beforeselect"\r
22507    );\r
22508 \r
22509     Ext.apply(this, config);\r
22510     Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);\r
22511 };\r
22512 \r
22513 Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {\r
22514     init : function(tree){\r
22515         this.tree = tree;\r
22516         tree.getTreeEl().on("keydown", this.onKeyDown, this);\r
22517         tree.on("click", this.onNodeClick, this);\r
22518     },\r
22519     \r
22520     onNodeClick : function(node, e){\r
22521         this.select(node);\r
22522     },\r
22523     \r
22524     \r
22525     select : function(node){\r
22526         var last = this.selNode;\r
22527         if(last != node && this.fireEvent('beforeselect', this, node, last) !== false){\r
22528             if(last){\r
22529                 last.ui.onSelectedChange(false);\r
22530             }\r
22531             this.selNode = node;\r
22532             node.ui.onSelectedChange(true);\r
22533             this.fireEvent("selectionchange", this, node, last);\r
22534         }\r
22535         return node;\r
22536     },\r
22537     \r
22538     \r
22539     unselect : function(node){\r
22540         if(this.selNode == node){\r
22541             this.clearSelections();\r
22542         }    \r
22543     },\r
22544     \r
22545     \r
22546     clearSelections : function(){\r
22547         var n = this.selNode;\r
22548         if(n){\r
22549             n.ui.onSelectedChange(false);\r
22550             this.selNode = null;\r
22551             this.fireEvent("selectionchange", this, null);\r
22552         }\r
22553         return n;\r
22554     },\r
22555     \r
22556     \r
22557     getSelectedNode : function(){\r
22558         return this.selNode;    \r
22559     },\r
22560     \r
22561     \r
22562     isSelected : function(node){\r
22563         return this.selNode == node;  \r
22564     },\r
22565 \r
22566     \r
22567     selectPrevious : function(){\r
22568         var s = this.selNode || this.lastSelNode;\r
22569         if(!s){\r
22570             return null;\r
22571         }\r
22572         var ps = s.previousSibling;\r
22573         if(ps){\r
22574             if(!ps.isExpanded() || ps.childNodes.length < 1){\r
22575                 return this.select(ps);\r
22576             } else{\r
22577                 var lc = ps.lastChild;\r
22578                 while(lc && lc.isExpanded() && lc.childNodes.length > 0){\r
22579                     lc = lc.lastChild;\r
22580                 }\r
22581                 return this.select(lc);\r
22582             }\r
22583         } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){\r
22584             return this.select(s.parentNode);\r
22585         }\r
22586         return null;\r
22587     },\r
22588 \r
22589     \r
22590     selectNext : function(){\r
22591         var s = this.selNode || this.lastSelNode;\r
22592         if(!s){\r
22593             return null;\r
22594         }\r
22595         if(s.firstChild && s.isExpanded()){\r
22596              return this.select(s.firstChild);\r
22597          }else if(s.nextSibling){\r
22598              return this.select(s.nextSibling);\r
22599          }else if(s.parentNode){\r
22600             var newS = null;\r
22601             s.parentNode.bubble(function(){\r
22602                 if(this.nextSibling){\r
22603                     newS = this.getOwnerTree().selModel.select(this.nextSibling);\r
22604                     return false;\r
22605                 }\r
22606             });\r
22607             return newS;\r
22608          }\r
22609         return null;\r
22610     },\r
22611 \r
22612     onKeyDown : function(e){\r
22613         var s = this.selNode || this.lastSelNode;\r
22614         
22615         var sm = this;\r
22616         if(!s){\r
22617             return;\r
22618         }\r
22619         var k = e.getKey();\r
22620         switch(k){\r
22621              case e.DOWN:\r
22622                  e.stopEvent();\r
22623                  this.selectNext();\r
22624              break;\r
22625              case e.UP:\r
22626                  e.stopEvent();\r
22627                  this.selectPrevious();\r
22628              break;\r
22629              case e.RIGHT:\r
22630                  e.preventDefault();\r
22631                  if(s.hasChildNodes()){\r
22632                      if(!s.isExpanded()){\r
22633                          s.expand();\r
22634                      }else if(s.firstChild){\r
22635                          this.select(s.firstChild, e);\r
22636                      }\r
22637                  }\r
22638              break;\r
22639              case e.LEFT:\r
22640                  e.preventDefault();\r
22641                  if(s.hasChildNodes() && s.isExpanded()){\r
22642                      s.collapse();\r
22643                  }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){\r
22644                      this.select(s.parentNode, e);\r
22645                  }\r
22646              break;\r
22647         };\r
22648     }\r
22649 });\r
22650 \r
22651 \r
22652 Ext.tree.MultiSelectionModel = function(config){\r
22653    this.selNodes = [];\r
22654    this.selMap = {};\r
22655    this.addEvents(\r
22656        \r
22657        "selectionchange"\r
22658    );\r
22659     Ext.apply(this, config);\r
22660     Ext.tree.MultiSelectionModel.superclass.constructor.call(this);\r
22661 };\r
22662 \r
22663 Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {\r
22664     init : function(tree){\r
22665         this.tree = tree;\r
22666         tree.getTreeEl().on("keydown", this.onKeyDown, this);\r
22667         tree.on("click", this.onNodeClick, this);\r
22668     },\r
22669     \r
22670     onNodeClick : function(node, e){\r
22671         this.select(node, e, e.ctrlKey);\r
22672     },\r
22673     \r
22674     \r
22675     select : function(node, e, keepExisting){\r
22676         if(keepExisting !== true){\r
22677             this.clearSelections(true);\r
22678         }\r
22679         if(this.isSelected(node)){\r
22680             this.lastSelNode = node;\r
22681             return node;\r
22682         }\r
22683         this.selNodes.push(node);\r
22684         this.selMap[node.id] = node;\r
22685         this.lastSelNode = node;\r
22686         node.ui.onSelectedChange(true);\r
22687         this.fireEvent("selectionchange", this, this.selNodes);\r
22688         return node;\r
22689     },\r
22690     \r
22691     \r
22692     unselect : function(node){\r
22693         if(this.selMap[node.id]){\r
22694             node.ui.onSelectedChange(false);\r
22695             var sn = this.selNodes;\r
22696             var index = sn.indexOf(node);\r
22697             if(index != -1){\r
22698                 this.selNodes.splice(index, 1);\r
22699             }\r
22700             delete this.selMap[node.id];\r
22701             this.fireEvent("selectionchange", this, this.selNodes);\r
22702         }\r
22703     },\r
22704     \r
22705     \r
22706     clearSelections : function(suppressEvent){\r
22707         var sn = this.selNodes;\r
22708         if(sn.length > 0){\r
22709             for(var i = 0, len = sn.length; i < len; i++){\r
22710                 sn[i].ui.onSelectedChange(false);\r
22711             }\r
22712             this.selNodes = [];\r
22713             this.selMap = {};\r
22714             if(suppressEvent !== true){\r
22715                 this.fireEvent("selectionchange", this, this.selNodes);\r
22716             }\r
22717         }\r
22718     },\r
22719     \r
22720     \r
22721     isSelected : function(node){\r
22722         return this.selMap[node.id] ? true : false;  \r
22723     },\r
22724     \r
22725     \r
22726     getSelectedNodes : function(){\r
22727         return this.selNodes;    \r
22728     },\r
22729 \r
22730     onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,\r
22731 \r
22732     selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,\r
22733 \r
22734     selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious\r
22735 });
22736 \r
22737 Ext.tree.TreeNode = function(attributes){\r
22738     attributes = attributes || {};\r
22739     if(typeof attributes == "string"){\r
22740         attributes = {text: attributes};\r
22741     }\r
22742     this.childrenRendered = false;\r
22743     this.rendered = false;\r
22744     Ext.tree.TreeNode.superclass.constructor.call(this, attributes);\r
22745     this.expanded = attributes.expanded === true;\r
22746     this.isTarget = attributes.isTarget !== false;\r
22747     this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;\r
22748     this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;\r
22749 \r
22750     \r
22751     this.text = attributes.text;\r
22752     \r
22753     this.disabled = attributes.disabled === true;\r
22754 \r
22755     this.addEvents(\r
22756         \r
22757         "textchange",\r
22758         \r
22759         "beforeexpand",\r
22760         \r
22761         "beforecollapse",\r
22762         \r
22763         "expand",\r
22764         \r
22765         "disabledchange",\r
22766         \r
22767         "collapse",\r
22768         \r
22769         "beforeclick",\r
22770         \r
22771         "click",\r
22772         \r
22773         "checkchange",\r
22774         \r
22775         "dblclick",\r
22776         \r
22777         "contextmenu",\r
22778         \r
22779         "beforechildrenrendered"\r
22780     );\r
22781 \r
22782     var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;\r
22783 \r
22784     \r
22785     this.ui = new uiClass(this);\r
22786 };\r
22787 Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {\r
22788     preventHScroll: true,\r
22789     \r
22790     isExpanded : function(){\r
22791         return this.expanded;\r
22792     },\r
22793 \r
22794 \r
22795     getUI : function(){\r
22796         return this.ui;\r
22797     },\r
22798 \r
22799     
22800     setFirstChild : function(node){\r
22801         var of = this.firstChild;\r
22802         Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);\r
22803         if(this.childrenRendered && of && node != of){\r
22804             of.renderIndent(true, true);\r
22805         }\r
22806         if(this.rendered){\r
22807             this.renderIndent(true, true);\r
22808         }\r
22809     },\r
22810 \r
22811     
22812     setLastChild : function(node){\r
22813         var ol = this.lastChild;\r
22814         Ext.tree.TreeNode.superclass.setLastChild.call(this, node);\r
22815         if(this.childrenRendered && ol && node != ol){\r
22816             ol.renderIndent(true, true);\r
22817         }\r
22818         if(this.rendered){\r
22819             this.renderIndent(true, true);\r
22820         }\r
22821     },\r
22822 \r
22823     
22824     
22825     appendChild : function(){\r
22826         var node = Ext.tree.TreeNode.superclass.appendChild.apply(this, arguments);\r
22827         if(node && this.childrenRendered){\r
22828             node.render();\r
22829         }\r
22830         this.ui.updateExpandIcon();\r
22831         return node;\r
22832     },\r
22833 \r
22834     
22835     removeChild : function(node){\r
22836         this.ownerTree.getSelectionModel().unselect(node);\r
22837         Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);\r
22838         
22839         if(this.childrenRendered){\r
22840             node.ui.remove();\r
22841         }\r
22842         if(this.childNodes.length < 1){\r
22843             this.collapse(false, false);\r
22844         }else{\r
22845             this.ui.updateExpandIcon();\r
22846         }\r
22847         if(!this.firstChild && !this.isHiddenRoot()) {\r
22848             this.childrenRendered = false;\r
22849         }\r
22850         return node;\r
22851     },\r
22852 \r
22853     
22854     insertBefore : function(node, refNode){\r
22855         var newNode = Ext.tree.TreeNode.superclass.insertBefore.apply(this, arguments);\r
22856         if(newNode && refNode && this.childrenRendered){\r
22857             node.render();\r
22858         }\r
22859         this.ui.updateExpandIcon();\r
22860         return newNode;\r
22861     },\r
22862 \r
22863     \r
22864     setText : function(text){\r
22865         var oldText = this.text;\r
22866         this.text = text;\r
22867         this.attributes.text = text;\r
22868         if(this.rendered){ 
22869             this.ui.onTextChange(this, text, oldText);\r
22870         }\r
22871         this.fireEvent("textchange", this, text, oldText);\r
22872     },\r
22873 \r
22874     \r
22875     select : function(){\r
22876         this.getOwnerTree().getSelectionModel().select(this);\r
22877     },\r
22878 \r
22879     \r
22880     unselect : function(){\r
22881         this.getOwnerTree().getSelectionModel().unselect(this);\r
22882     },\r
22883 \r
22884     \r
22885     isSelected : function(){\r
22886         return this.getOwnerTree().getSelectionModel().isSelected(this);\r
22887     },\r
22888 \r
22889     \r
22890     expand : function(deep, anim, callback){\r
22891         if(!this.expanded){\r
22892             if(this.fireEvent("beforeexpand", this, deep, anim) === false){\r
22893                 return;\r
22894             }\r
22895             if(!this.childrenRendered){\r
22896                 this.renderChildren();\r
22897             }\r
22898             this.expanded = true;\r
22899             if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){\r
22900                 this.ui.animExpand(function(){\r
22901                     this.fireEvent("expand", this);\r
22902                     if(typeof callback == "function"){\r
22903                         callback(this);\r
22904                     }\r
22905                     if(deep === true){\r
22906                         this.expandChildNodes(true);\r
22907                     }\r
22908                 }.createDelegate(this));\r
22909                 return;\r
22910             }else{\r
22911                 this.ui.expand();\r
22912                 this.fireEvent("expand", this);\r
22913                 if(typeof callback == "function"){\r
22914                     callback(this);\r
22915                 }\r
22916             }\r
22917         }else{\r
22918            if(typeof callback == "function"){\r
22919                callback(this);\r
22920            }\r
22921         }\r
22922         if(deep === true){\r
22923             this.expandChildNodes(true);\r
22924         }\r
22925     },\r
22926 \r
22927     isHiddenRoot : function(){\r
22928         return this.isRoot && !this.getOwnerTree().rootVisible;\r
22929     },\r
22930 \r
22931     \r
22932     collapse : function(deep, anim){\r
22933         if(this.expanded && !this.isHiddenRoot()){\r
22934             if(this.fireEvent("beforecollapse", this, deep, anim) === false){\r
22935                 return;\r
22936             }\r
22937             this.expanded = false;\r
22938             if((this.getOwnerTree().animate && anim !== false) || anim){\r
22939                 this.ui.animCollapse(function(){\r
22940                     this.fireEvent("collapse", this);\r
22941                     if(deep === true){\r
22942                         this.collapseChildNodes(true);\r
22943                     }\r
22944                 }.createDelegate(this));\r
22945                 return;\r
22946             }else{\r
22947                 this.ui.collapse();\r
22948                 this.fireEvent("collapse", this);\r
22949             }\r
22950         }\r
22951         if(deep === true){\r
22952             var cs = this.childNodes;\r
22953             for(var i = 0, len = cs.length; i < len; i++) {\r
22954                 cs[i].collapse(true, false);\r
22955             }\r
22956         }\r
22957     },\r
22958 \r
22959     
22960     delayedExpand : function(delay){\r
22961         if(!this.expandProcId){\r
22962             this.expandProcId = this.expand.defer(delay, this);\r
22963         }\r
22964     },\r
22965 \r
22966     
22967     cancelExpand : function(){\r
22968         if(this.expandProcId){\r
22969             clearTimeout(this.expandProcId);\r
22970         }\r
22971         this.expandProcId = false;\r
22972     },\r
22973 \r
22974     \r
22975     toggle : function(){\r
22976         if(this.expanded){\r
22977             this.collapse();\r
22978         }else{\r
22979             this.expand();\r
22980         }\r
22981     },\r
22982 \r
22983     \r
22984     ensureVisible : function(callback){\r
22985         var tree = this.getOwnerTree();\r
22986         tree.expandPath(this.parentNode.getPath(), false, function(){\r
22987             var node = tree.getNodeById(this.id);  
22988             tree.getTreeEl().scrollChildIntoView(node.ui.anchor);\r
22989             Ext.callback(callback);\r
22990         }.createDelegate(this));\r
22991     },\r
22992 \r
22993     \r
22994     expandChildNodes : function(deep){\r
22995         var cs = this.childNodes;\r
22996         for(var i = 0, len = cs.length; i < len; i++) {\r
22997                 cs[i].expand(deep);\r
22998         }\r
22999     },\r
23000 \r
23001     \r
23002     collapseChildNodes : function(deep){\r
23003         var cs = this.childNodes;\r
23004         for(var i = 0, len = cs.length; i < len; i++) {\r
23005                 cs[i].collapse(deep);\r
23006         }\r
23007     },\r
23008 \r
23009     \r
23010     disable : function(){\r
23011         this.disabled = true;\r
23012         this.unselect();\r
23013         if(this.rendered && this.ui.onDisableChange){ 
23014             this.ui.onDisableChange(this, true);\r
23015         }\r
23016         this.fireEvent("disabledchange", this, true);\r
23017     },\r
23018 \r
23019     \r
23020     enable : function(){\r
23021         this.disabled = false;\r
23022         if(this.rendered && this.ui.onDisableChange){ 
23023             this.ui.onDisableChange(this, false);\r
23024         }\r
23025         this.fireEvent("disabledchange", this, false);\r
23026     },\r
23027 \r
23028     
23029     renderChildren : function(suppressEvent){\r
23030         if(suppressEvent !== false){\r
23031             this.fireEvent("beforechildrenrendered", this);\r
23032         }\r
23033         var cs = this.childNodes;\r
23034         for(var i = 0, len = cs.length; i < len; i++){\r
23035             cs[i].render(true);\r
23036         }\r
23037         this.childrenRendered = true;\r
23038     },\r
23039 \r
23040     
23041     sort : function(fn, scope){\r
23042         Ext.tree.TreeNode.superclass.sort.apply(this, arguments);\r
23043         if(this.childrenRendered){\r
23044             var cs = this.childNodes;\r
23045             for(var i = 0, len = cs.length; i < len; i++){\r
23046                 cs[i].render(true);\r
23047             }\r
23048         }\r
23049     },\r
23050 \r
23051     
23052     render : function(bulkRender){\r
23053         this.ui.render(bulkRender);\r
23054         if(!this.rendered){\r
23055             
23056             this.getOwnerTree().registerNode(this);\r
23057             this.rendered = true;\r
23058             if(this.expanded){\r
23059                 this.expanded = false;\r
23060                 this.expand(false, false);\r
23061             }\r
23062         }\r
23063     },\r
23064 \r
23065     
23066     renderIndent : function(deep, refresh){\r
23067         if(refresh){\r
23068             this.ui.childIndent = null;\r
23069         }\r
23070         this.ui.renderIndent();\r
23071         if(deep === true && this.childrenRendered){\r
23072             var cs = this.childNodes;\r
23073             for(var i = 0, len = cs.length; i < len; i++){\r
23074                 cs[i].renderIndent(true, refresh);\r
23075             }\r
23076         }\r
23077     },\r
23078 \r
23079     beginUpdate : function(){\r
23080         this.childrenRendered = false;\r
23081     },\r
23082 \r
23083     endUpdate : function(){\r
23084         if(this.expanded){\r
23085             this.renderChildren();\r
23086         }\r
23087     },\r
23088 \r
23089     destroy : function(){\r
23090         for(var i = 0,l = this.childNodes.length; i < l; i++){\r
23091             this.childNodes[i].destroy();\r
23092         }\r
23093         this.childNodes = null;\r
23094         if(this.ui.destroy){\r
23095             this.ui.destroy();\r
23096         }\r
23097     }\r
23098 });
23099 \r
23100  Ext.tree.AsyncTreeNode = function(config){\r
23101     this.loaded = false;\r
23102     this.loading = false;\r
23103     Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);\r
23104     \r
23105     this.addEvents('beforeload', 'load');\r
23106     \r
23107     \r
23108 };\r
23109 Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {\r
23110     expand : function(deep, anim, callback){\r
23111         if(this.loading){ 
23112             var timer;\r
23113             var f = function(){\r
23114                 if(!this.loading){ 
23115                     clearInterval(timer);\r
23116                     this.expand(deep, anim, callback);\r
23117                 }\r
23118             }.createDelegate(this);\r
23119             timer = setInterval(f, 200);\r
23120             return;\r
23121         }\r
23122         if(!this.loaded){\r
23123             if(this.fireEvent("beforeload", this) === false){\r
23124                 return;\r
23125             }\r
23126             this.loading = true;\r
23127             this.ui.beforeLoad(this);\r
23128             var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();\r
23129             if(loader){\r
23130                 loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback]));\r
23131                 return;\r
23132             }\r
23133         }\r
23134         Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback);\r
23135     },\r
23136     \r
23137     \r
23138     isLoading : function(){\r
23139         return this.loading;  \r
23140     },\r
23141     \r
23142     loadComplete : function(deep, anim, callback){\r
23143         this.loading = false;\r
23144         this.loaded = true;\r
23145         this.ui.afterLoad(this);\r
23146         this.fireEvent("load", this);\r
23147         this.expand(deep, anim, callback);\r
23148     },\r
23149     \r
23150     \r
23151     isLoaded : function(){\r
23152         return this.loaded;\r
23153     },\r
23154     \r
23155     hasChildNodes : function(){\r
23156         if(!this.isLeaf() && !this.loaded){\r
23157             return true;\r
23158         }else{\r
23159             return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);\r
23160         }\r
23161     },\r
23162 \r
23163     \r
23164     reload : function(callback){\r
23165         this.collapse(false, false);\r
23166         while(this.firstChild){\r
23167             this.removeChild(this.firstChild);\r
23168         }\r
23169         this.childrenRendered = false;\r
23170         this.loaded = false;\r
23171         if(this.isHiddenRoot()){\r
23172             this.expanded = false;\r
23173         }\r
23174         this.expand(false, false, callback);\r
23175     }\r
23176 });
23177 \r
23178 Ext.tree.TreeNodeUI = function(node){\r
23179     this.node = node;\r
23180     this.rendered = false;\r
23181     this.animating = false;\r
23182     this.wasLeaf = true;\r
23183     this.ecc = 'x-tree-ec-icon x-tree-elbow';\r
23184     this.emptyIcon = Ext.BLANK_IMAGE_URL;\r
23185 };\r
23186 \r
23187 Ext.tree.TreeNodeUI.prototype = {\r
23188     
23189     removeChild : function(node){\r
23190         if(this.rendered){\r
23191             this.ctNode.removeChild(node.ui.getEl());\r
23192         } \r
23193     },\r
23194 \r
23195     
23196     beforeLoad : function(){\r
23197          this.addClass("x-tree-node-loading");\r
23198     },\r
23199 \r
23200     
23201     afterLoad : function(){\r
23202          this.removeClass("x-tree-node-loading");\r
23203     },\r
23204 \r
23205     
23206     onTextChange : function(node, text, oldText){\r
23207         if(this.rendered){\r
23208             this.textNode.innerHTML = text;\r
23209         }\r
23210     },\r
23211 \r
23212     
23213     onDisableChange : function(node, state){\r
23214         this.disabled = state;\r
23215                 if (this.checkbox) {\r
23216                         this.checkbox.disabled = state;\r
23217                 }        \r
23218         if(state){\r
23219             this.addClass("x-tree-node-disabled");\r
23220         }else{\r
23221             this.removeClass("x-tree-node-disabled");\r
23222         } \r
23223     },\r
23224 \r
23225     
23226     onSelectedChange : function(state){\r
23227         if(state){\r
23228             this.focus();\r
23229             this.addClass("x-tree-selected");\r
23230         }else{\r
23231             
23232             this.removeClass("x-tree-selected");\r
23233         }\r
23234     },\r
23235 \r
23236     
23237     onMove : function(tree, node, oldParent, newParent, index, refNode){\r
23238         this.childIndent = null;\r
23239         if(this.rendered){\r
23240             var targetNode = newParent.ui.getContainer();\r
23241             if(!targetNode){
23242                 this.holder = document.createElement("div");\r
23243                 this.holder.appendChild(this.wrap);\r
23244                 return;\r
23245             }\r
23246             var insertBefore = refNode ? refNode.ui.getEl() : null;\r
23247             if(insertBefore){\r
23248                 targetNode.insertBefore(this.wrap, insertBefore);\r
23249             }else{\r
23250                 targetNode.appendChild(this.wrap);\r
23251             }\r
23252             this.node.renderIndent(true);\r
23253         }\r
23254     },\r
23255 \r
23256 \r
23257     addClass : function(cls){\r
23258         if(this.elNode){\r
23259             Ext.fly(this.elNode).addClass(cls);\r
23260         }\r
23261     },\r
23262 \r
23263 \r
23264     removeClass : function(cls){\r
23265         if(this.elNode){\r
23266             Ext.fly(this.elNode).removeClass(cls);  \r
23267         }\r
23268     },\r
23269 \r
23270     
23271     remove : function(){\r
23272         if(this.rendered){\r
23273             this.holder = document.createElement("div");\r
23274             this.holder.appendChild(this.wrap);\r
23275         }  \r
23276     },\r
23277 \r
23278     
23279     fireEvent : function(){\r
23280         return this.node.fireEvent.apply(this.node, arguments);  \r
23281     },\r
23282 \r
23283     
23284     initEvents : function(){\r
23285         this.node.on("move", this.onMove, this);\r
23286 \r
23287         if(this.node.disabled){\r
23288             this.addClass("x-tree-node-disabled");\r
23289                         if (this.checkbox) {\r
23290                                 this.checkbox.disabled = true;\r
23291                         }            \r
23292         }\r
23293         if(this.node.hidden){\r
23294             this.hide();\r
23295         }\r
23296         var ot = this.node.getOwnerTree();\r
23297         var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;\r
23298         if(dd && (!this.node.isRoot || ot.rootVisible)){\r
23299             Ext.dd.Registry.register(this.elNode, {\r
23300                 node: this.node,\r
23301                 handles: this.getDDHandles(),\r
23302                 isHandle: false\r
23303             });\r
23304         }\r
23305     },\r
23306 \r
23307     
23308     getDDHandles : function(){\r
23309         return [this.iconNode, this.textNode, this.elNode];\r
23310     },\r
23311 \r
23312 \r
23313     hide : function(){\r
23314         this.node.hidden = true;\r
23315         if(this.wrap){\r
23316             this.wrap.style.display = "none";\r
23317         }\r
23318     },\r
23319 \r
23320 \r
23321     show : function(){\r
23322         this.node.hidden = false;\r
23323         if(this.wrap){\r
23324             this.wrap.style.display = "";\r
23325         } \r
23326     },\r
23327 \r
23328     
23329     onContextMenu : function(e){\r
23330         if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {\r
23331             e.preventDefault();\r
23332             this.focus();\r
23333             this.fireEvent("contextmenu", this.node, e);\r
23334         }\r
23335     },\r
23336 \r
23337     
23338     onClick : function(e){\r
23339         if(this.dropping){\r
23340             e.stopEvent();\r
23341             return;\r
23342         }\r
23343         if(this.fireEvent("beforeclick", this.node, e) !== false){\r
23344             var a = e.getTarget('a');\r
23345             if(!this.disabled && this.node.attributes.href && a){\r
23346                 this.fireEvent("click", this.node, e);\r
23347                 return;\r
23348             }else if(a && e.ctrlKey){\r
23349                 e.stopEvent();\r
23350             }\r
23351             e.preventDefault();\r
23352             if(this.disabled){\r
23353                 return;\r
23354             }\r
23355 \r
23356             if(this.node.attributes.singleClickExpand && !this.animating && this.node.hasChildNodes()){\r
23357                 this.node.toggle();\r
23358             }\r
23359 \r
23360             this.fireEvent("click", this.node, e);\r
23361         }else{\r
23362             e.stopEvent();\r
23363         }\r
23364     },\r
23365 \r
23366     
23367     onDblClick : function(e){\r
23368         e.preventDefault();\r
23369         if(this.disabled){\r
23370             return;\r
23371         }\r
23372         if(this.checkbox){\r
23373             this.toggleCheck();\r
23374         }\r
23375         if(!this.animating && this.node.hasChildNodes()){\r
23376             this.node.toggle();\r
23377         }\r
23378         this.fireEvent("dblclick", this.node, e);\r
23379     },\r
23380 \r
23381     onOver : function(e){\r
23382         this.addClass('x-tree-node-over');\r
23383     },\r
23384 \r
23385     onOut : function(e){\r
23386         this.removeClass('x-tree-node-over');\r
23387     },\r
23388 \r
23389     
23390     onCheckChange : function(){\r
23391         var checked = this.checkbox.checked;\r
23392         this.node.attributes.checked = checked;\r
23393         this.fireEvent('checkchange', this.node, checked);\r
23394     },\r
23395 \r
23396     
23397     ecClick : function(e){\r
23398         if(!this.animating && (this.node.hasChildNodes() || this.node.attributes.expandable)){\r
23399             this.node.toggle();\r
23400         }\r
23401     },\r
23402 \r
23403     
23404     startDrop : function(){\r
23405         this.dropping = true;\r
23406     },\r
23407     \r
23408     
23409     endDrop : function(){ \r
23410        setTimeout(function(){\r
23411            this.dropping = false;\r
23412        }.createDelegate(this), 50); \r
23413     },\r
23414 \r
23415     
23416     expand : function(){\r
23417         this.updateExpandIcon();\r
23418         this.ctNode.style.display = "";\r
23419     },\r
23420 \r
23421     
23422     focus : function(){\r
23423         if(!this.node.preventHScroll){\r
23424             try{this.anchor.focus();\r
23425             }catch(e){}\r
23426         }else if(!Ext.isIE){\r
23427             try{\r
23428                 var noscroll = this.node.getOwnerTree().getTreeEl().dom;\r
23429                 var l = noscroll.scrollLeft;\r
23430                 this.anchor.focus();\r
23431                 noscroll.scrollLeft = l;\r
23432             }catch(e){}\r
23433         }\r
23434     },\r
23435 \r
23436 \r
23437     toggleCheck : function(value){\r
23438         var cb = this.checkbox;\r
23439         if(cb){\r
23440             cb.checked = (value === undefined ? !cb.checked : value);\r
23441         }\r
23442     },\r
23443 \r
23444     
23445     blur : function(){\r
23446         try{\r
23447             this.anchor.blur();\r
23448         }catch(e){} \r
23449     },\r
23450 \r
23451     
23452     animExpand : function(callback){\r
23453         var ct = Ext.get(this.ctNode);\r
23454         ct.stopFx();\r
23455         if(!this.node.hasChildNodes()){\r
23456             this.updateExpandIcon();\r
23457             this.ctNode.style.display = "";\r
23458             Ext.callback(callback);\r
23459             return;\r
23460         }\r
23461         this.animating = true;\r
23462         this.updateExpandIcon();\r
23463         \r
23464         ct.slideIn('t', {\r
23465            callback : function(){\r
23466                this.animating = false;\r
23467                Ext.callback(callback);\r
23468             },\r
23469             scope: this,\r
23470             duration: this.node.ownerTree.duration || .25\r
23471         });\r
23472     },\r
23473 \r
23474     
23475     highlight : function(){\r
23476         var tree = this.node.getOwnerTree();\r
23477         Ext.fly(this.wrap).highlight(\r
23478             tree.hlColor || "C3DAF9",\r
23479             {endColor: tree.hlBaseColor}\r
23480         );\r
23481     },\r
23482 \r
23483     
23484     collapse : function(){\r
23485         this.updateExpandIcon();\r
23486         this.ctNode.style.display = "none";\r
23487     },\r
23488 \r
23489     
23490     animCollapse : function(callback){\r
23491         var ct = Ext.get(this.ctNode);\r
23492         ct.enableDisplayMode('block');\r
23493         ct.stopFx();\r
23494 \r
23495         this.animating = true;\r
23496         this.updateExpandIcon();\r
23497 \r
23498         ct.slideOut('t', {\r
23499             callback : function(){\r
23500                this.animating = false;\r
23501                Ext.callback(callback);\r
23502             },\r
23503             scope: this,\r
23504             duration: this.node.ownerTree.duration || .25\r
23505         });\r
23506     },\r
23507 \r
23508     
23509     getContainer : function(){\r
23510         return this.ctNode;  \r
23511     },\r
23512 \r
23513     
23514     getEl : function(){\r
23515         return this.wrap;  \r
23516     },\r
23517 \r
23518     
23519     appendDDGhost : function(ghostNode){\r
23520         ghostNode.appendChild(this.elNode.cloneNode(true));\r
23521     },\r
23522 \r
23523     
23524     getDDRepairXY : function(){\r
23525         return Ext.lib.Dom.getXY(this.iconNode);\r
23526     },\r
23527 \r
23528     
23529     onRender : function(){\r
23530         this.render();    \r
23531     },\r
23532 \r
23533     
23534     render : function(bulkRender){\r
23535         var n = this.node, a = n.attributes;\r
23536         var targetNode = n.parentNode ? \r
23537               n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;\r
23538         \r
23539         if(!this.rendered){\r
23540             this.rendered = true;\r
23541 \r
23542             this.renderElements(n, a, targetNode, bulkRender);\r
23543 \r
23544             if(a.qtip){\r
23545                if(this.textNode.setAttributeNS){\r
23546                    this.textNode.setAttributeNS("ext", "qtip", a.qtip);\r
23547                    if(a.qtipTitle){\r
23548                        this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);\r
23549                    }\r
23550                }else{\r
23551                    this.textNode.setAttribute("ext:qtip", a.qtip);\r
23552                    if(a.qtipTitle){\r
23553                        this.textNode.setAttribute("ext:qtitle", a.qtipTitle);\r
23554                    }\r
23555                } \r
23556             }else if(a.qtipCfg){\r
23557                 a.qtipCfg.target = Ext.id(this.textNode);\r
23558                 Ext.QuickTips.register(a.qtipCfg);\r
23559             }\r
23560             this.initEvents();\r
23561             if(!this.node.expanded){\r
23562                 this.updateExpandIcon(true);\r
23563             }\r
23564         }else{\r
23565             if(bulkRender === true) {\r
23566                 targetNode.appendChild(this.wrap);\r
23567             }\r
23568         }\r
23569     },\r
23570 \r
23571     
23572     renderElements : function(n, a, targetNode, bulkRender){\r
23573         
23574         this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';\r
23575 \r
23576         var cb = typeof a.checked == 'boolean';\r
23577 \r
23578         var href = a.href ? a.href : Ext.isGecko ? "" : "#";\r
23579         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">',\r
23580             '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",\r
23581             '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',\r
23582             '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',\r
23583             cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',\r
23584             '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',\r
23585              a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",\r
23586             '<ul class="x-tree-node-ct" style="display:none;"></ul>',\r
23587             "</li>"].join('');\r
23588 \r
23589         var nel;\r
23590         if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){\r
23591             this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);\r
23592         }else{\r
23593             this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);\r
23594         }\r
23595         \r
23596         this.elNode = this.wrap.childNodes[0];\r
23597         this.ctNode = this.wrap.childNodes[1];\r
23598         var cs = this.elNode.childNodes;\r
23599         this.indentNode = cs[0];\r
23600         this.ecNode = cs[1];\r
23601         this.iconNode = cs[2];\r
23602         var index = 3;\r
23603         if(cb){\r
23604             this.checkbox = cs[3];\r
23605             index++;\r
23606         }\r
23607         this.anchor = cs[index];\r
23608         this.textNode = cs[index].firstChild;\r
23609     },\r
23610 \r
23611 \r
23612     getAnchor : function(){\r
23613         return this.anchor;\r
23614     },\r
23615     \r
23616 \r
23617     getTextEl : function(){\r
23618         return this.textNode;\r
23619     },\r
23620     \r
23621 \r
23622     getIconEl : function(){\r
23623         return this.iconNode;\r
23624     },\r
23625 \r
23626 \r
23627     isChecked : function(){\r
23628         return this.checkbox ? this.checkbox.checked : false; \r
23629     },\r
23630 \r
23631     
23632     updateExpandIcon : function(){\r
23633         if(this.rendered){\r
23634             var n = this.node, c1, c2;\r
23635             var cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow";\r
23636             var hasChild = n.hasChildNodes();\r
23637             if(hasChild || n.attributes.expandable){\r
23638                 if(n.expanded){\r
23639                     cls += "-minus";\r
23640                     c1 = "x-tree-node-collapsed";\r
23641                     c2 = "x-tree-node-expanded";\r
23642                 }else{\r
23643                     cls += "-plus";\r
23644                     c1 = "x-tree-node-expanded";\r
23645                     c2 = "x-tree-node-collapsed";\r
23646                 }\r
23647                 if(this.wasLeaf){\r
23648                     this.removeClass("x-tree-node-leaf");\r
23649                     this.wasLeaf = false;\r
23650                 }\r
23651                 if(this.c1 != c1 || this.c2 != c2){\r
23652                     Ext.fly(this.elNode).replaceClass(c1, c2);\r
23653                     this.c1 = c1; this.c2 = c2;\r
23654                 }\r
23655             }else{\r
23656                 if(!this.wasLeaf){\r
23657                     Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");\r
23658                     delete this.c1;\r
23659                     delete this.c2;\r
23660                     this.wasLeaf = true;\r
23661                 }\r
23662             }\r
23663             var ecc = "x-tree-ec-icon "+cls;\r
23664             if(this.ecc != ecc){\r
23665                 this.ecNode.className = ecc;\r
23666                 this.ecc = ecc;\r
23667             }\r
23668         }\r
23669     },\r
23670 \r
23671     
23672     getChildIndent : function(){\r
23673         if(!this.childIndent){\r
23674             var buf = [];\r
23675             var p = this.node;\r
23676             while(p){\r
23677                 if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){\r
23678                     if(!p.isLast()) {\r
23679                         buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');\r
23680                     } else {\r
23681                         buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');\r
23682                     }\r
23683                 }\r
23684                 p = p.parentNode;\r
23685             }\r
23686             this.childIndent = buf.join("");\r
23687         }\r
23688         return this.childIndent;\r
23689     },\r
23690 \r
23691     
23692     renderIndent : function(){\r
23693         if(this.rendered){\r
23694             var indent = "";\r
23695             var p = this.node.parentNode;\r
23696             if(p){\r
23697                 indent = p.ui.getChildIndent();\r
23698             }\r
23699             if(this.indentMarkup != indent){ 
23700                 this.indentNode.innerHTML = indent;\r
23701                 this.indentMarkup = indent;\r
23702             }\r
23703             this.updateExpandIcon();\r
23704         }\r
23705     },\r
23706 \r
23707     destroy : function(){\r
23708         if(this.elNode){\r
23709             Ext.dd.Registry.unregister(this.elNode.id);\r
23710         }\r
23711         delete this.elNode;\r
23712         delete this.ctNode;\r
23713         delete this.indentNode;\r
23714         delete this.ecNode;\r
23715         delete this.iconNode;\r
23716         delete this.checkbox;\r
23717         delete this.anchor;\r
23718         delete this.textNode;\r
23719         Ext.removeNode(this.ctNode);\r
23720     }\r
23721 };\r
23722 \r
23723 \r
23724 Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {\r
23725     
23726     render : function(){\r
23727         if(!this.rendered){\r
23728             var targetNode = this.node.ownerTree.innerCt.dom;\r
23729             this.node.expanded = true;\r
23730             targetNode.innerHTML = '<div class="x-tree-root-node"></div>';\r
23731             this.wrap = this.ctNode = targetNode.firstChild;\r
23732         }\r
23733     },\r
23734     collapse : Ext.emptyFn,\r
23735     expand : Ext.emptyFn\r
23736 });
23737 \r
23738 Ext.tree.TreeLoader = function(config){\r
23739     this.baseParams = {};\r
23740     this.requestMethod = "POST";\r
23741     Ext.apply(this, config);\r
23742 \r
23743     this.addEvents(\r
23744         \r
23745         "beforeload",\r
23746         \r
23747         "load",\r
23748         \r
23749         "loadexception"\r
23750     );\r
23751 \r
23752     Ext.tree.TreeLoader.superclass.constructor.call(this);\r
23753 };\r
23754 \r
23755 Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {\r
23756     \r
23757     \r
23758     \r
23759     \r
23760     \r
23761     \r
23762     \r
23763     uiProviders : {},\r
23764 \r
23765     \r
23766     clearOnLoad : true,\r
23767 \r
23768     \r
23769     load : function(node, callback){\r
23770         if(this.clearOnLoad){\r
23771             while(node.firstChild){\r
23772                 node.removeChild(node.firstChild);\r
23773             }\r
23774         }\r
23775         if(this.doPreload(node)){ 
23776             if(typeof callback == "function"){\r
23777                 callback();\r
23778             }\r
23779         }else if(this.dataUrl||this.url){\r
23780             this.requestData(node, callback);\r
23781         }\r
23782     },\r
23783 \r
23784     doPreload : function(node){\r
23785         if(node.attributes.children){\r
23786             if(node.childNodes.length < 1){ 
23787                 var cs = node.attributes.children;\r
23788                 node.beginUpdate();\r
23789                 for(var i = 0, len = cs.length; i < len; i++){\r
23790                     var cn = node.appendChild(this.createNode(cs[i]));\r
23791                     if(this.preloadChildren){\r
23792                         this.doPreload(cn);\r
23793                     }\r
23794                 }\r
23795                 node.endUpdate();\r
23796             }\r
23797             return true;\r
23798         }else {\r
23799             return false;\r
23800         }\r
23801     },\r
23802 \r
23803     getParams: function(node){\r
23804         var buf = [], bp = this.baseParams;\r
23805         for(var key in bp){\r
23806             if(typeof bp[key] != "function"){\r
23807                 buf.push(encodeURIComponent(key), "=", encodeURIComponent(bp[key]), "&");\r
23808             }\r
23809         }\r
23810         buf.push("node=", encodeURIComponent(node.id));\r
23811         return buf.join("");\r
23812     },\r
23813 \r
23814     requestData : function(node, callback){\r
23815         if(this.fireEvent("beforeload", this, node, callback) !== false){\r
23816             this.transId = Ext.Ajax.request({\r
23817                 method:this.requestMethod,\r
23818                 url: this.dataUrl||this.url,\r
23819                 success: this.handleResponse,\r
23820                 failure: this.handleFailure,\r
23821                 scope: this,\r
23822                 argument: {callback: callback, node: node},\r
23823                 params: this.getParams(node)\r
23824             });\r
23825         }else{\r
23826             
23827             
23828             if(typeof callback == "function"){\r
23829                 callback();\r
23830             }\r
23831         }\r
23832     },\r
23833 \r
23834     isLoading : function(){\r
23835         return this.transId ? true : false;\r
23836     },\r
23837 \r
23838     abort : function(){\r
23839         if(this.isLoading()){\r
23840             Ext.Ajax.abort(this.transId);\r
23841         }\r
23842     },\r
23843 \r
23844     \r
23845     createNode : function(attr){\r
23846         
23847         if(this.baseAttrs){\r
23848             Ext.applyIf(attr, this.baseAttrs);\r
23849         }\r
23850         if(this.applyLoader !== false){\r
23851             attr.loader = this;\r
23852         }\r
23853         if(typeof attr.uiProvider == 'string'){\r
23854            attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);\r
23855         }\r
23856         return(attr.leaf ?\r
23857                         new Ext.tree.TreeNode(attr) :\r
23858                         new Ext.tree.AsyncTreeNode(attr));\r
23859     },\r
23860 \r
23861     processResponse : function(response, node, callback){\r
23862         var json = response.responseText;\r
23863         try {\r
23864             var o = eval("("+json+")");\r
23865             node.beginUpdate();\r
23866             for(var i = 0, len = o.length; i < len; i++){\r
23867                 var n = this.createNode(o[i]);\r
23868                 if(n){\r
23869                     node.appendChild(n);\r
23870                 }\r
23871             }\r
23872             node.endUpdate();\r
23873             if(typeof callback == "function"){\r
23874                 callback(this, node);\r
23875             }\r
23876         }catch(e){\r
23877             this.handleFailure(response);\r
23878         }\r
23879     },\r
23880 \r
23881     handleResponse : function(response){\r
23882         this.transId = false;\r
23883         var a = response.argument;\r
23884         this.processResponse(response, a.node, a.callback);\r
23885         this.fireEvent("load", this, a.node, response);\r
23886     },\r
23887 \r
23888     handleFailure : function(response){\r
23889         this.transId = false;\r
23890         var a = response.argument;\r
23891         this.fireEvent("loadexception", this, a.node, response);\r
23892         if(typeof a.callback == "function"){\r
23893             a.callback(this, a.node);\r
23894         }\r
23895     }\r
23896 });
23897 \r
23898 Ext.tree.TreeFilter = function(tree, config){\r
23899     this.tree = tree;\r
23900     this.filtered = {};\r
23901     Ext.apply(this, config);\r
23902 };\r
23903 \r
23904 Ext.tree.TreeFilter.prototype = {\r
23905     clearBlank:false,\r
23906     reverse:false,\r
23907     autoClear:false,\r
23908     remove:false,\r
23909 \r
23910      \r
23911     filter : function(value, attr, startNode){\r
23912         attr = attr || "text";\r
23913         var f;\r
23914         if(typeof value == "string"){\r
23915             var vlen = value.length;\r
23916             
23917             if(vlen == 0 && this.clearBlank){\r
23918                 this.clear();\r
23919                 return;\r
23920             }\r
23921             value = value.toLowerCase();\r
23922             f = function(n){\r
23923                 return n.attributes[attr].substr(0, vlen).toLowerCase() == value;\r
23924             };\r
23925         }else if(value.exec){ 
23926             f = function(n){\r
23927                 return value.test(n.attributes[attr]);\r
23928             };\r
23929         }else{\r
23930             throw 'Illegal filter type, must be string or regex';\r
23931         }\r
23932         this.filterBy(f, null, startNode);\r
23933         },\r
23934     \r
23935     \r
23936     filterBy : function(fn, scope, startNode){\r
23937         startNode = startNode || this.tree.root;\r
23938         if(this.autoClear){\r
23939             this.clear();\r
23940         }\r
23941         var af = this.filtered, rv = this.reverse;\r
23942         var f = function(n){\r
23943             if(n == startNode){\r
23944                 return true;\r
23945             }\r
23946             if(af[n.id]){\r
23947                 return false;\r
23948             }\r
23949             var m = fn.call(scope || n, n);\r
23950             if(!m || rv){\r
23951                 af[n.id] = n;\r
23952                 n.ui.hide();\r
23953                 return false;\r
23954             }\r
23955             return true;\r
23956         };\r
23957         startNode.cascade(f);\r
23958         if(this.remove){\r
23959            for(var id in af){\r
23960                if(typeof id != "function"){\r
23961                    var n = af[id];\r
23962                    if(n && n.parentNode){\r
23963                        n.parentNode.removeChild(n);\r
23964                    }\r
23965                }\r
23966            } \r
23967         }\r
23968     },\r
23969     \r
23970     \r
23971     clear : function(){\r
23972         var t = this.tree;\r
23973         var af = this.filtered;\r
23974         for(var id in af){\r
23975             if(typeof id != "function"){\r
23976                 var n = af[id];\r
23977                 if(n){\r
23978                     n.ui.show();\r
23979                 }\r
23980             }\r
23981         }\r
23982         this.filtered = {}; \r
23983     }\r
23984 };\r
23985
23986 \r
23987 Ext.tree.TreeSorter = function(tree, config){\r
23988     Ext.apply(this, config);\r
23989     tree.on("beforechildrenrendered", this.doSort, this);\r
23990     tree.on("append", this.updateSort, this);\r
23991     tree.on("insert", this.updateSort, this);\r
23992     tree.on("textchange", this.updateSortParent, this);\r
23993     \r
23994     var dsc = this.dir && this.dir.toLowerCase() == "desc";\r
23995     var p = this.property || "text";\r
23996     var sortType = this.sortType;\r
23997     var fs = this.folderSort;\r
23998     var cs = this.caseSensitive === true;\r
23999     var leafAttr = this.leafAttr || 'leaf';\r
24000 \r
24001     this.sortFn = function(n1, n2){\r
24002         if(fs){\r
24003             if(n1.attributes[leafAttr] && !n2.attributes[leafAttr]){\r
24004                 return 1;\r
24005             }\r
24006             if(!n1.attributes[leafAttr] && n2.attributes[leafAttr]){\r
24007                 return -1;\r
24008             }\r
24009         }\r
24010         var v1 = sortType ? sortType(n1) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());\r
24011         var v2 = sortType ? sortType(n2) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());\r
24012         if(v1 < v2){\r
24013                         return dsc ? +1 : -1;\r
24014                 }else if(v1 > v2){\r
24015                         return dsc ? -1 : +1;\r
24016         }else{\r
24017                 return 0;\r
24018         }\r
24019     };\r
24020 };\r
24021 \r
24022 Ext.tree.TreeSorter.prototype = {\r
24023     doSort : function(node){\r
24024         node.sort(this.sortFn);\r
24025     },\r
24026     \r
24027     compareNodes : function(n1, n2){\r
24028         return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);\r
24029     },\r
24030     \r
24031     updateSort : function(tree, node){\r
24032         if(node.childrenRendered){\r
24033             this.doSort.defer(1, this, [node]);\r
24034         }\r
24035     },\r
24036     \r
24037     updateSortParent : function(node){\r
24038                 var p = node.parentNode;\r
24039                 if(p && p.childrenRendered){\r
24040             this.doSort.defer(1, this, [p]);\r
24041         }\r
24042     }\r
24043 };
24044 \r
24045 if(Ext.dd.DropZone){\r
24046     \r
24047 Ext.tree.TreeDropZone = function(tree, config){\r
24048     \r
24049     this.allowParentInsert = false;\r
24050     \r
24051     this.allowContainerDrop = false;\r
24052     \r
24053     this.appendOnly = false;\r
24054     Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.innerCt, config);\r
24055     \r
24056     this.tree = tree;\r
24057     \r
24058     this.dragOverData = {};\r
24059     
24060     this.lastInsertClass = "x-tree-no-status";\r
24061 };\r
24062 \r
24063 Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {\r
24064     \r
24065     ddGroup : "TreeDD",\r
24066 \r
24067     \r
24068     expandDelay : 1000,\r
24069 \r
24070     
24071     expandNode : function(node){\r
24072         if(node.hasChildNodes() && !node.isExpanded()){\r
24073             node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));\r
24074         }\r
24075     },\r
24076 \r
24077     
24078     queueExpand : function(node){\r
24079         this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);\r
24080     },\r
24081 \r
24082     
24083     cancelExpand : function(){\r
24084         if(this.expandProcId){\r
24085             clearTimeout(this.expandProcId);\r
24086             this.expandProcId = false;\r
24087         }\r
24088     },\r
24089 \r
24090     
24091     isValidDropPoint : function(n, pt, dd, e, data){\r
24092         if(!n || !data){ return false; }\r
24093         var targetNode = n.node;\r
24094         var dropNode = data.node;\r
24095         
24096         if(!(targetNode && targetNode.isTarget && pt)){\r
24097             return false;\r
24098         }\r
24099         if(pt == "append" && targetNode.allowChildren === false){\r
24100             return false;\r
24101         }\r
24102         if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){\r
24103             return false;\r
24104         }\r
24105         if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){\r
24106             return false;\r
24107         }\r
24108         
24109         var overEvent = this.dragOverData;\r
24110         overEvent.tree = this.tree;\r
24111         overEvent.target = targetNode;\r
24112         overEvent.data = data;\r
24113         overEvent.point = pt;\r
24114         overEvent.source = dd;\r
24115         overEvent.rawEvent = e;\r
24116         overEvent.dropNode = dropNode;\r
24117         overEvent.cancel = false;  \r
24118         var result = this.tree.fireEvent("nodedragover", overEvent);\r
24119         return overEvent.cancel === false && result !== false;\r
24120     },\r
24121 \r
24122     
24123     getDropPoint : function(e, n, dd){\r
24124         var tn = n.node;\r
24125         if(tn.isRoot){\r
24126             return tn.allowChildren !== false ? "append" : false; 
24127         }\r
24128         var dragEl = n.ddel;\r
24129         var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;\r
24130         var y = Ext.lib.Event.getPageY(e);\r
24131         var noAppend = tn.allowChildren === false || tn.isLeaf();\r
24132         if(this.appendOnly || tn.parentNode.allowChildren === false){\r
24133             return noAppend ? false : "append";\r
24134         }\r
24135         var noBelow = false;\r
24136         if(!this.allowParentInsert){\r
24137             noBelow = tn.hasChildNodes() && tn.isExpanded();\r
24138         }\r
24139         var q = (b - t) / (noAppend ? 2 : 3);\r
24140         if(y >= t && y < (t + q)){\r
24141             return "above";\r
24142         }else if(!noBelow && (noAppend || y >= b-q && y <= b)){\r
24143             return "below";\r
24144         }else{\r
24145             return "append";\r
24146         }\r
24147     },\r
24148 \r
24149     
24150     onNodeEnter : function(n, dd, e, data){\r
24151         this.cancelExpand();\r
24152     },\r
24153 \r
24154     
24155     onNodeOver : function(n, dd, e, data){\r
24156         var pt = this.getDropPoint(e, n, dd);\r
24157         var node = n.node;\r
24158         \r
24159         
24160         if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){\r
24161             this.queueExpand(node);\r
24162         }else if(pt != "append"){\r
24163             this.cancelExpand();\r
24164         }\r
24165         \r
24166         
24167         var returnCls = this.dropNotAllowed;\r
24168         if(this.isValidDropPoint(n, pt, dd, e, data)){\r
24169            if(pt){\r
24170                var el = n.ddel;\r
24171                var cls;\r
24172                if(pt == "above"){\r
24173                    returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";\r
24174                    cls = "x-tree-drag-insert-above";\r
24175                }else if(pt == "below"){\r
24176                    returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";\r
24177                    cls = "x-tree-drag-insert-below";\r
24178                }else{\r
24179                    returnCls = "x-tree-drop-ok-append";\r
24180                    cls = "x-tree-drag-append";\r
24181                }\r
24182                if(this.lastInsertClass != cls){\r
24183                    Ext.fly(el).replaceClass(this.lastInsertClass, cls);\r
24184                    this.lastInsertClass = cls;\r
24185                }\r
24186            }\r
24187        }\r
24188        return returnCls;\r
24189     },\r
24190 \r
24191     
24192     onNodeOut : function(n, dd, e, data){\r
24193         this.cancelExpand();\r
24194         this.removeDropIndicators(n);\r
24195     },\r
24196 \r
24197     
24198     onNodeDrop : function(n, dd, e, data){\r
24199         var point = this.getDropPoint(e, n, dd);\r
24200         var targetNode = n.node;\r
24201         targetNode.ui.startDrop();\r
24202         if(!this.isValidDropPoint(n, point, dd, e, data)){\r
24203             targetNode.ui.endDrop();\r
24204             return false;\r
24205         }\r
24206         
24207         var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);\r
24208         var dropEvent = {\r
24209             tree : this.tree,\r
24210             target: targetNode,\r
24211             data: data,\r
24212             point: point,\r
24213             source: dd,\r
24214             rawEvent: e,\r
24215             dropNode: dropNode,\r
24216             cancel: !dropNode,\r
24217             dropStatus: false\r
24218         };\r
24219         var retval = this.tree.fireEvent("beforenodedrop", dropEvent);\r
24220         if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){\r
24221             targetNode.ui.endDrop();\r
24222             return dropEvent.dropStatus;\r
24223         }\r
24224         
24225         targetNode = dropEvent.target;\r
24226         if(point == "append" && !targetNode.isExpanded()){\r
24227             targetNode.expand(false, null, function(){\r
24228                 this.completeDrop(dropEvent);\r
24229             }.createDelegate(this));\r
24230         }else{\r
24231             this.completeDrop(dropEvent);\r
24232         }\r
24233         return true;\r
24234     },\r
24235 \r
24236     
24237     completeDrop : function(de){\r
24238         var ns = de.dropNode, p = de.point, t = de.target;\r
24239         if(!Ext.isArray(ns)){\r
24240             ns = [ns];\r
24241         }\r
24242         var n;\r
24243         for(var i = 0, len = ns.length; i < len; i++){\r
24244             n = ns[i];\r
24245             if(p == "above"){\r
24246                 t.parentNode.insertBefore(n, t);\r
24247             }else if(p == "below"){\r
24248                 t.parentNode.insertBefore(n, t.nextSibling);\r
24249             }else{\r
24250                 t.appendChild(n);\r
24251             }\r
24252         }\r
24253         n.ui.focus();\r
24254         if(this.tree.hlDrop){\r
24255             n.ui.highlight();\r
24256         }\r
24257         t.ui.endDrop();\r
24258         this.tree.fireEvent("nodedrop", de);\r
24259     },\r
24260 \r
24261     
24262     afterNodeMoved : function(dd, data, e, targetNode, dropNode){\r
24263         if(this.tree.hlDrop){\r
24264             dropNode.ui.focus();\r
24265             dropNode.ui.highlight();\r
24266         }\r
24267         this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);\r
24268     },\r
24269 \r
24270     
24271     getTree : function(){\r
24272         return this.tree;\r
24273     },\r
24274 \r
24275     
24276     removeDropIndicators : function(n){\r
24277         if(n && n.ddel){\r
24278             var el = n.ddel;\r
24279             Ext.fly(el).removeClass([\r
24280                     "x-tree-drag-insert-above",\r
24281                     "x-tree-drag-insert-below",\r
24282                     "x-tree-drag-append"]);\r
24283             this.lastInsertClass = "_noclass";\r
24284         }\r
24285     },\r
24286 \r
24287     
24288     beforeDragDrop : function(target, e, id){\r
24289         this.cancelExpand();\r
24290         return true;\r
24291     },\r
24292 \r
24293     
24294     afterRepair : function(data){\r
24295         if(data && Ext.enableFx){\r
24296             data.node.ui.highlight();\r
24297         }\r
24298         this.hideProxy();\r
24299     }    \r
24300 });\r
24301 \r
24302 }
24303 \r
24304 if(Ext.dd.DragZone){\r
24305 Ext.tree.TreeDragZone = function(tree, config){\r
24306     Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.getTreeEl(), config);\r
24307     \r
24308     this.tree = tree;\r
24309 };\r
24310 \r
24311 Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {\r
24312     \r
24313     ddGroup : "TreeDD",\r
24314 \r
24315     
24316     onBeforeDrag : function(data, e){\r
24317         var n = data.node;\r
24318         return n && n.draggable && !n.disabled;\r
24319     },\r
24320 \r
24321     
24322     onInitDrag : function(e){\r
24323         var data = this.dragData;\r
24324         this.tree.getSelectionModel().select(data.node);\r
24325         this.tree.eventModel.disable();\r
24326         this.proxy.update("");\r
24327         data.node.ui.appendDDGhost(this.proxy.ghost.dom);\r
24328         this.tree.fireEvent("startdrag", this.tree, data.node, e);\r
24329     },\r
24330 \r
24331     
24332     getRepairXY : function(e, data){\r
24333         return data.node.ui.getDDRepairXY();\r
24334     },\r
24335 \r
24336     
24337     onEndDrag : function(data, e){\r
24338         this.tree.eventModel.enable.defer(100, this.tree.eventModel);\r
24339         this.tree.fireEvent("enddrag", this.tree, data.node, e);\r
24340     },\r
24341 \r
24342     
24343     onValidDrop : function(dd, e, id){\r
24344         this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);\r
24345         this.hideProxy();\r
24346     },\r
24347 \r
24348     
24349     beforeInvalidDrop : function(e, id){\r
24350         
24351         var sm = this.tree.getSelectionModel();\r
24352         sm.clearSelections();\r
24353         sm.select(this.dragData.node);\r
24354     }\r
24355 });\r
24356 }
24357
24358 Ext.tree.TreeEditor = function(tree, config){
24359     config = config || {};
24360     var field = config.events ? config : new Ext.form.TextField(config);
24361     Ext.tree.TreeEditor.superclass.constructor.call(this, field);
24362
24363     this.tree = tree;
24364
24365     if(!tree.rendered){
24366         tree.on('render', this.initEditor, this);
24367     }else{
24368         this.initEditor(tree);
24369     }
24370 };
24371
24372 Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
24373     
24374     alignment: "l-l",
24375         autoSize: false,
24376     
24377     hideEl : false,
24378     
24379     cls: "x-small-editor x-tree-editor",
24380     
24381     shim:false,
24382         shadow:"frame",
24383     
24384     maxWidth: 250,
24385     
24386     editDelay : 350,
24387
24388     initEditor : function(tree){
24389         tree.on('beforeclick', this.beforeNodeClick, this);
24390         tree.on('dblclick', this.onNodeDblClick, this);
24391         this.on('complete', this.updateNode, this);
24392         this.on('beforestartedit', this.fitToTree, this);
24393         this.on('startedit', this.bindScroll, this, {delay:10});
24394         this.on('specialkey', this.onSpecialKey, this);
24395     },
24396
24397         fitToTree : function(ed, el){
24398         var td = this.tree.getTreeEl().dom, nd = el.dom;
24399         if(td.scrollLeft >  nd.offsetLeft){             td.scrollLeft = nd.offsetLeft;
24400         }
24401         var w = Math.min(
24402                 this.maxWidth,
24403                 (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
24404         this.setSize(w, '');
24405     },
24406
24407         triggerEdit : function(node, defer){
24408         this.completeEdit();
24409                 if(node.attributes.editable !== false){
24410                         this.editNode = node;
24411             this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, node.text]);
24412             return false;
24413         }
24414     },
24415
24416         bindScroll : function(){
24417         this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
24418     },
24419
24420         beforeNodeClick : function(node, e){
24421         clearTimeout(this.autoEditTimer);
24422         if(this.tree.getSelectionModel().isSelected(node)){
24423             e.stopEvent();
24424             return this.triggerEdit(node);
24425         }
24426     },
24427
24428     onNodeDblClick : function(node, e){
24429         clearTimeout(this.autoEditTimer);
24430     },
24431
24432         updateNode : function(ed, value){
24433         this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
24434         this.editNode.setText(value);
24435     },
24436
24437         onHide : function(){
24438         Ext.tree.TreeEditor.superclass.onHide.call(this);
24439         if(this.editNode){
24440             this.editNode.ui.focus.defer(50, this.editNode.ui);
24441         }
24442     },
24443
24444         onSpecialKey : function(field, e){
24445         var k = e.getKey();
24446         if(k == e.ESC){
24447             e.stopEvent();
24448             this.cancelEdit();
24449         }else if(k == e.ENTER && !e.hasModifier()){
24450             e.stopEvent();
24451             this.completeEdit();
24452         }
24453     }
24454 });
24455
24456 Ext.menu.Menu = function(config){
24457     if(Ext.isArray(config)){
24458         config = {items:config};
24459     }
24460     Ext.apply(this, config);
24461     this.id = this.id || Ext.id();
24462     this.addEvents(
24463         
24464         'beforeshow',
24465         
24466         'beforehide',
24467         
24468         'show',
24469         
24470         'hide',
24471         
24472         'click',
24473         
24474         'mouseover',
24475         
24476         'mouseout',
24477         
24478         'itemclick'
24479     );
24480     Ext.menu.MenuMgr.register(this);
24481     Ext.menu.Menu.superclass.constructor.call(this);
24482     var mis = this.items;
24483     
24484
24485     this.items = new Ext.util.MixedCollection();
24486     if(mis){
24487         this.add.apply(this, mis);
24488     }
24489 };
24490
24491 Ext.extend(Ext.menu.Menu, Ext.util.Observable, {
24492     
24493     
24494     
24495     minWidth : 120,
24496     
24497     shadow : "sides",
24498     
24499     subMenuAlign : "tl-tr?",
24500     
24501     defaultAlign : "tl-bl?",
24502     
24503     allowOtherMenus : false,
24504
24505     hidden:true,
24506
24507     createEl : function(){
24508         return new Ext.Layer({
24509             cls: "x-menu",
24510             shadow:this.shadow,
24511             constrain: false,
24512             parentEl: this.parentEl || document.body,
24513             zindex:15000
24514         });
24515     },
24516
24517         render : function(){
24518         if(this.el){
24519             return;
24520         }
24521         var el = this.el = this.createEl();
24522
24523         if(!this.keyNav){
24524             this.keyNav = new Ext.menu.MenuNav(this);
24525         }
24526         if(this.plain){
24527             el.addClass("x-menu-plain");
24528         }
24529         if(this.cls){
24530             el.addClass(this.cls);
24531         }
24532                 this.focusEl = el.createChild({
24533             tag: "a", cls: "x-menu-focus", href: "#", onclick: "return false;", tabIndex:"-1"
24534         });
24535         var ul = el.createChild({tag: "ul", cls: "x-menu-list"});
24536         ul.on("click", this.onClick, this);
24537         ul.on("mouseover", this.onMouseOver, this);
24538         ul.on("mouseout", this.onMouseOut, this);
24539         this.items.each(function(item){
24540             var li = document.createElement("li");
24541             li.className = "x-menu-list-item";
24542             ul.dom.appendChild(li);
24543             item.render(li, this);
24544         }, this);
24545         this.ul = ul;
24546         this.autoWidth();
24547     },
24548
24549         autoWidth : function(){
24550         var el = this.el, ul = this.ul;
24551         if(!el){
24552             return;
24553         }
24554         var w = this.width;
24555         if(w){
24556             el.setWidth(w);
24557         }else if(Ext.isIE){
24558             el.setWidth(this.minWidth);
24559             var t = el.dom.offsetWidth;             el.setWidth(ul.getWidth()+el.getFrameWidth("lr"));
24560         }
24561     },
24562
24563         delayAutoWidth : function(){
24564         if(this.el){
24565             if(!this.awTask){
24566                 this.awTask = new Ext.util.DelayedTask(this.autoWidth, this);
24567             }
24568             this.awTask.delay(20);
24569         }
24570     },
24571
24572         findTargetItem : function(e){
24573         var t = e.getTarget(".x-menu-list-item", this.ul,  true);
24574         if(t && t.menuItemId){
24575             return this.items.get(t.menuItemId);
24576         }
24577     },
24578
24579         onClick : function(e){
24580         var t;
24581         if(t = this.findTargetItem(e)){
24582             t.onClick(e);
24583             this.fireEvent("click", this, t, e);
24584         }
24585     },
24586
24587         setActiveItem : function(item, autoExpand){
24588         if(item != this.activeItem){
24589             if(this.activeItem){
24590                 this.activeItem.deactivate();
24591             }
24592             this.activeItem = item;
24593             item.activate(autoExpand);
24594         }else if(autoExpand){
24595             item.expandMenu();
24596         }
24597     },
24598
24599         tryActivate : function(start, step){
24600         var items = this.items;
24601         for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
24602             var item = items.get(i);
24603             if(!item.disabled && item.canActivate){
24604                 this.setActiveItem(item, false);
24605                 return item;
24606             }
24607         }
24608         return false;
24609     },
24610
24611         onMouseOver : function(e){
24612         var t;
24613         if(t = this.findTargetItem(e)){
24614             if(t.canActivate && !t.disabled){
24615                 this.setActiveItem(t, true);
24616             }
24617         }
24618         this.fireEvent("mouseover", this, e, t);
24619     },
24620
24621         onMouseOut : function(e){
24622         var t;
24623         if(t = this.findTargetItem(e)){
24624             if(t == this.activeItem && t.shouldDeactivate(e)){
24625                 this.activeItem.deactivate();
24626                 delete this.activeItem;
24627             }
24628         }
24629         this.fireEvent("mouseout", this, e, t);
24630     },
24631
24632     
24633     isVisible : function(){
24634         return this.el && !this.hidden;
24635     },
24636
24637     
24638     show : function(el, pos, parentMenu){
24639         this.parentMenu = parentMenu;
24640         if(!this.el){
24641             this.render();
24642         }
24643         this.fireEvent("beforeshow", this);
24644         this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
24645     },
24646
24647     
24648     showAt : function(xy, parentMenu, _e){
24649         this.parentMenu = parentMenu;
24650         if(!this.el){
24651             this.render();
24652         }
24653         if(_e !== false){
24654             this.fireEvent("beforeshow", this);
24655             xy = this.el.adjustForConstraints(xy);
24656         }
24657         this.el.setXY(xy);
24658         this.el.show();
24659         this.hidden = false;
24660         this.focus();
24661         this.fireEvent("show", this);
24662     },
24663
24664     
24665
24666     focus : function(){
24667         if(!this.hidden){
24668             this.doFocus.defer(50, this);
24669         }
24670     },
24671
24672     doFocus : function(){
24673         if(!this.hidden){
24674             this.focusEl.focus();
24675         }
24676     },
24677
24678     
24679     hide : function(deep){
24680         if(this.el && this.isVisible()){
24681             this.fireEvent("beforehide", this);
24682             if(this.activeItem){
24683                 this.activeItem.deactivate();
24684                 this.activeItem = null;
24685             }
24686             this.el.hide();
24687             this.hidden = true;
24688             this.fireEvent("hide", this);
24689         }
24690         if(deep === true && this.parentMenu){
24691             this.parentMenu.hide(true);
24692         }
24693     },
24694
24695     
24696     add : function(){
24697         var a = arguments, l = a.length, item;
24698         for(var i = 0; i < l; i++){
24699             var el = a[i];
24700             if(el.render){                 item = this.addItem(el);
24701             }else if(typeof el == "string"){                 if(el == "separator" || el == "-"){
24702                     item = this.addSeparator();
24703                 }else{
24704                     item = this.addText(el);
24705                 }
24706             }else if(el.tagName || el.el){                 item = this.addElement(el);
24707             }else if(typeof el == "object"){                 Ext.applyIf(el, this.defaults);
24708                 item = this.addMenuItem(el);
24709             }
24710         }
24711         return item;
24712     },
24713
24714     
24715     getEl : function(){
24716         if(!this.el){
24717             this.render();
24718         }
24719         return this.el;
24720     },
24721
24722     
24723     addSeparator : function(){
24724         return this.addItem(new Ext.menu.Separator());
24725     },
24726
24727     
24728     addElement : function(el){
24729         return this.addItem(new Ext.menu.BaseItem(el));
24730     },
24731
24732     
24733     addItem : function(item){
24734         this.items.add(item);
24735         if(this.ul){
24736             var li = document.createElement("li");
24737             li.className = "x-menu-list-item";
24738             this.ul.dom.appendChild(li);
24739             item.render(li, this);
24740             this.delayAutoWidth();
24741         }
24742         return item;
24743     },
24744
24745     
24746     addMenuItem : function(config){
24747         if(!(config instanceof Ext.menu.Item)){
24748             if(typeof config.checked == "boolean"){                 config = new Ext.menu.CheckItem(config);
24749             }else{
24750                 config = new Ext.menu.Item(config);
24751             }
24752         }
24753         return this.addItem(config);
24754     },
24755
24756     
24757     addText : function(text){
24758         return this.addItem(new Ext.menu.TextItem(text));
24759     },
24760
24761     
24762     insert : function(index, item){
24763         this.items.insert(index, item);
24764         if(this.ul){
24765             var li = document.createElement("li");
24766             li.className = "x-menu-list-item";
24767             this.ul.dom.insertBefore(li, this.ul.dom.childNodes[index]);
24768             item.render(li, this);
24769             this.delayAutoWidth();
24770         }
24771         return item;
24772     },
24773
24774     
24775     remove : function(item){
24776         this.items.removeKey(item.id);
24777         item.destroy();
24778     },
24779
24780     
24781     removeAll : function(){
24782         var f;
24783         while(f = this.items.first()){
24784             this.remove(f);
24785         }
24786     },
24787
24788     
24789     destroy : function(){
24790         this.beforeDestroy();
24791         Ext.menu.MenuMgr.unregister(this);
24792         if (this.keyNav) {
24793                 this.keyNav.disable();  
24794         }
24795         this.removeAll();
24796         if (this.ul) {
24797                 this.ul.removeAllListeners();   
24798         }
24799         if (this.el) {
24800                 this.el.destroy();      
24801         }
24802     },
24803
24804             beforeDestroy : Ext.emptyFn
24805
24806 });
24807
24808 Ext.menu.MenuNav = function(menu){
24809     Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
24810     this.scope = this.menu = menu;
24811 };
24812
24813 Ext.extend(Ext.menu.MenuNav, Ext.KeyNav, {
24814     doRelay : function(e, h){
24815         var k = e.getKey();
24816         if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
24817             this.menu.tryActivate(0, 1);
24818             return false;
24819         }
24820         return h.call(this.scope || this, e, this.menu);
24821     },
24822
24823     up : function(e, m){
24824         if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
24825             m.tryActivate(m.items.length-1, -1);
24826         }
24827     },
24828
24829     down : function(e, m){
24830         if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
24831             m.tryActivate(0, 1);
24832         }
24833     },
24834
24835     right : function(e, m){
24836         if(m.activeItem){
24837             m.activeItem.expandMenu(true);
24838         }
24839     },
24840
24841     left : function(e, m){
24842         m.hide();
24843         if(m.parentMenu && m.parentMenu.activeItem){
24844             m.parentMenu.activeItem.activate();
24845         }
24846     },
24847
24848     enter : function(e, m){
24849         if(m.activeItem){
24850             e.stopPropagation();
24851             m.activeItem.onClick(e);
24852             m.fireEvent("click", this, m.activeItem);
24853             return true;
24854         }
24855     }
24856 });
24857
24858 Ext.menu.MenuMgr = function(){
24859    var menus, active, groups = {}, attached = false, lastShow = new Date();
24860
24861       function init(){
24862        menus = {};
24863        active = new Ext.util.MixedCollection();
24864        Ext.getDoc().addKeyListener(27, function(){
24865            if(active.length > 0){
24866                hideAll();
24867            }
24868        });
24869    }
24870
24871       function hideAll(){
24872        if(active && active.length > 0){
24873            var c = active.clone();
24874            c.each(function(m){
24875                m.hide();
24876            });
24877        }
24878    }
24879
24880       function onHide(m){
24881        active.remove(m);
24882        if(active.length < 1){
24883            Ext.getDoc().un("mousedown", onMouseDown);
24884            attached = false;
24885        }
24886    }
24887
24888       function onShow(m){
24889        var last = active.last();
24890        lastShow = new Date();
24891        active.add(m);
24892        if(!attached){
24893            Ext.getDoc().on("mousedown", onMouseDown);
24894            attached = true;
24895        }
24896        if(m.parentMenu){
24897           m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
24898           m.parentMenu.activeChild = m;
24899        }else if(last && last.isVisible()){
24900           m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
24901        }
24902    }
24903
24904       function onBeforeHide(m){
24905        if(m.activeChild){
24906            m.activeChild.hide();
24907        }
24908        if(m.autoHideTimer){
24909            clearTimeout(m.autoHideTimer);
24910            delete m.autoHideTimer;
24911        }
24912    }
24913
24914       function onBeforeShow(m){
24915        var pm = m.parentMenu;
24916        if(!pm && !m.allowOtherMenus){
24917            hideAll();
24918        }else if(pm && pm.activeChild){
24919            pm.activeChild.hide();
24920        }
24921    }
24922
24923       function onMouseDown(e){
24924        if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
24925            hideAll();
24926        }
24927    }
24928
24929       function onBeforeCheck(mi, state){
24930        if(state){
24931            var g = groups[mi.group];
24932            for(var i = 0, l = g.length; i < l; i++){
24933                if(g[i] != mi){
24934                    g[i].setChecked(false);
24935                }
24936            }
24937        }
24938    }
24939
24940    return {
24941
24942        
24943        hideAll : function(){
24944             hideAll();  
24945        },
24946
24947               register : function(menu){
24948            if(!menus){
24949                init();
24950            }
24951            menus[menu.id] = menu;
24952            menu.on("beforehide", onBeforeHide);
24953            menu.on("hide", onHide);
24954            menu.on("beforeshow", onBeforeShow);
24955            menu.on("show", onShow);
24956            var g = menu.group;
24957            if(g && menu.events["checkchange"]){
24958                if(!groups[g]){
24959                    groups[g] = [];
24960                }
24961                groups[g].push(menu);
24962                menu.on("checkchange", onCheck);
24963            }
24964        },
24965
24966         
24967        get : function(menu){
24968            if(typeof menu == "string"){                if(!menus){                     return null;
24969                }
24970                return menus[menu];
24971            }else if(menu.events){                 return menu;
24972            }else if(typeof menu.length == 'number'){                return new Ext.menu.Menu({items:menu});
24973            }else{                return new Ext.menu.Menu(menu);
24974            }
24975        },
24976
24977               unregister : function(menu){
24978            delete menus[menu.id];
24979            menu.un("beforehide", onBeforeHide);
24980            menu.un("hide", onHide);
24981            menu.un("beforeshow", onBeforeShow);
24982            menu.un("show", onShow);
24983            var g = menu.group;
24984            if(g && menu.events["checkchange"]){
24985                groups[g].remove(menu);
24986                menu.un("checkchange", onCheck);
24987            }
24988        },
24989
24990               registerCheckable : function(menuItem){
24991            var g = menuItem.group;
24992            if(g){
24993                if(!groups[g]){
24994                    groups[g] = [];
24995                }
24996                groups[g].push(menuItem);
24997                menuItem.on("beforecheckchange", onBeforeCheck);
24998            }
24999        },
25000
25001               unregisterCheckable : function(menuItem){
25002            var g = menuItem.group;
25003            if(g){
25004                groups[g].remove(menuItem);
25005                menuItem.un("beforecheckchange", onBeforeCheck);
25006            }
25007        },
25008
25009        getCheckedItem : function(groupId){
25010            var g = groups[groupId];
25011            if(g){
25012                for(var i = 0, l = g.length; i < l; i++){
25013                    if(g[i].checked){
25014                        return g[i];
25015                    }
25016                }
25017            }
25018            return null;
25019        },
25020
25021        setCheckedItem : function(groupId, itemId){
25022            var g = groups[groupId];
25023            if(g){
25024                for(var i = 0, l = g.length; i < l; i++){
25025                    if(g[i].id == itemId){
25026                        g[i].setChecked(true);
25027                    }
25028                }
25029            }
25030            return null;
25031        }
25032    };
25033 }();
25034
25035
25036 Ext.menu.BaseItem = function(config){
25037     Ext.menu.BaseItem.superclass.constructor.call(this, config);
25038
25039     this.addEvents(
25040         
25041         'click',
25042         
25043         'activate',
25044         
25045         'deactivate'
25046     );
25047
25048     if(this.handler){
25049         this.on("click", this.handler, this.scope);
25050     }
25051 };
25052
25053 Ext.extend(Ext.menu.BaseItem, Ext.Component, {
25054     
25055     
25056     
25057     canActivate : false,
25058     
25059     activeClass : "x-menu-item-active",
25060     
25061     hideOnClick : true,
25062     
25063     hideDelay : 100,
25064
25065         ctype: "Ext.menu.BaseItem",
25066
25067         actionMode : "container",
25068
25069         render : function(container, parentMenu){
25070         this.parentMenu = parentMenu;
25071         Ext.menu.BaseItem.superclass.render.call(this, container);
25072         this.container.menuItemId = this.id;
25073     },
25074
25075         onRender : function(container, position){
25076         this.el = Ext.get(this.el);
25077         container.dom.appendChild(this.el.dom);
25078     },
25079
25080     
25081     setHandler : function(handler, scope){
25082         if(this.handler){
25083             this.un("click", this.handler, this.scope);
25084         }
25085         this.on("click", this.handler = handler, this.scope = scope);
25086     },
25087
25088         onClick : function(e){
25089         if(!this.disabled && this.fireEvent("click", this, e) !== false
25090                 && this.parentMenu.fireEvent("itemclick", this, e) !== false){
25091             this.handleClick(e);
25092         }else{
25093             e.stopEvent();
25094         }
25095     },
25096
25097         activate : function(){
25098         if(this.disabled){
25099             return false;
25100         }
25101         var li = this.container;
25102         li.addClass(this.activeClass);
25103         this.region = li.getRegion().adjust(2, 2, -2, -2);
25104         this.fireEvent("activate", this);
25105         return true;
25106     },
25107
25108         deactivate : function(){
25109         this.container.removeClass(this.activeClass);
25110         this.fireEvent("deactivate", this);
25111     },
25112
25113         shouldDeactivate : function(e){
25114         return !this.region || !this.region.contains(e.getPoint());
25115     },
25116
25117         handleClick : function(e){
25118         if(this.hideOnClick){
25119             this.parentMenu.hide.defer(this.hideDelay, this.parentMenu, [true]);
25120         }
25121     },
25122
25123         expandMenu : function(autoActivate){
25124             },
25125
25126         hideMenu : function(){
25127             }
25128 });
25129
25130 Ext.menu.TextItem = function(text){
25131     this.text = text;
25132     Ext.menu.TextItem.superclass.constructor.call(this);
25133 };
25134
25135 Ext.extend(Ext.menu.TextItem, Ext.menu.BaseItem, {
25136     
25137     
25138     hideOnClick : false,
25139     
25140     itemCls : "x-menu-text",
25141
25142         onRender : function(){
25143         var s = document.createElement("span");
25144         s.className = this.itemCls;
25145         s.innerHTML = this.text;
25146         this.el = s;
25147         Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
25148     }
25149 });
25150
25151 Ext.menu.Separator = function(config){
25152     Ext.menu.Separator.superclass.constructor.call(this, config);
25153 };
25154
25155 Ext.extend(Ext.menu.Separator, Ext.menu.BaseItem, {
25156     
25157     itemCls : "x-menu-sep",
25158     
25159     hideOnClick : false,
25160
25161         onRender : function(li){
25162         var s = document.createElement("span");
25163         s.className = this.itemCls;
25164         s.innerHTML = "&#160;";
25165         this.el = s;
25166         li.addClass("x-menu-sep-li");
25167         Ext.menu.Separator.superclass.onRender.apply(this, arguments);
25168     }
25169 });
25170
25171 Ext.menu.Item = function(config){
25172     Ext.menu.Item.superclass.constructor.call(this, config);
25173     if(this.menu){
25174         this.menu = Ext.menu.MenuMgr.get(this.menu);
25175     }
25176 };
25177 Ext.extend(Ext.menu.Item, Ext.menu.BaseItem, {
25178     
25179     
25180     
25181     
25182     
25183     
25184     itemCls : "x-menu-item",
25185     
25186     canActivate : true,
25187     
25188     showDelay: 200,
25189         hideDelay: 200,
25190
25191         ctype: "Ext.menu.Item",
25192
25193         onRender : function(container, position){
25194         var el = document.createElement("a");
25195         el.hideFocus = true;
25196         el.unselectable = "on";
25197         el.href = this.href || "#";
25198         if(this.hrefTarget){
25199             el.target = this.hrefTarget;
25200         }
25201         el.className = this.itemCls + (this.menu ?  " x-menu-item-arrow" : "") + (this.cls ?  " " + this.cls : "");
25202         el.innerHTML = String.format(
25203                 '<img src="{0}" class="x-menu-item-icon {2}" />{1}',
25204                 this.icon || Ext.BLANK_IMAGE_URL, this.itemText||this.text, this.iconCls || '');
25205         this.el = el;
25206         Ext.menu.Item.superclass.onRender.call(this, container, position);
25207     },
25208
25209     
25210     setText : function(text){
25211         this.text = text;
25212         if(this.rendered){
25213             this.el.update(String.format(
25214                 '<img src="{0}" class="x-menu-item-icon {2}">{1}',
25215                 this.icon || Ext.BLANK_IMAGE_URL, this.text, this.iconCls || ''));
25216             this.parentMenu.autoWidth();
25217         }
25218     },
25219
25220     
25221     setIconClass : function(cls){
25222         var oldCls = this.iconCls;
25223         this.iconCls = cls;
25224         if(this.rendered){
25225             this.el.child('img.x-menu-item-icon').replaceClass(oldCls, this.iconCls);
25226         }
25227     },
25228
25229         handleClick : function(e){
25230         if(!this.href){             e.stopEvent();
25231         }
25232         Ext.menu.Item.superclass.handleClick.apply(this, arguments);
25233     },
25234
25235         activate : function(autoExpand){
25236         if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
25237             this.focus();
25238             if(autoExpand){
25239                 this.expandMenu();
25240             }
25241         }
25242         return true;
25243     },
25244
25245         shouldDeactivate : function(e){
25246         if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
25247             if(this.menu && this.menu.isVisible()){
25248                 return !this.menu.getEl().getRegion().contains(e.getPoint());
25249             }
25250             return true;
25251         }
25252         return false;
25253     },
25254
25255         deactivate : function(){
25256         Ext.menu.Item.superclass.deactivate.apply(this, arguments);
25257         this.hideMenu();
25258     },
25259
25260         expandMenu : function(autoActivate){
25261         if(!this.disabled && this.menu){
25262             clearTimeout(this.hideTimer);
25263             delete this.hideTimer;
25264             if(!this.menu.isVisible() && !this.showTimer){
25265                 this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
25266             }else if (this.menu.isVisible() && autoActivate){
25267                 this.menu.tryActivate(0, 1);
25268             }
25269         }
25270     },
25271
25272         deferExpand : function(autoActivate){
25273         delete this.showTimer;
25274         this.menu.show(this.container, this.parentMenu.subMenuAlign || "tl-tr?", this.parentMenu);
25275         if(autoActivate){
25276             this.menu.tryActivate(0, 1);
25277         }
25278     },
25279
25280         hideMenu : function(){
25281         clearTimeout(this.showTimer);
25282         delete this.showTimer;
25283         if(!this.hideTimer && this.menu && this.menu.isVisible()){
25284             this.hideTimer = this.deferHide.defer(this.hideDelay, this);
25285         }
25286     },
25287
25288         deferHide : function(){
25289         delete this.hideTimer;
25290         this.menu.hide();
25291     }
25292 });
25293
25294 Ext.menu.CheckItem = function(config){
25295     Ext.menu.CheckItem.superclass.constructor.call(this, config);
25296     this.addEvents(
25297         
25298         "beforecheckchange" ,
25299         
25300         "checkchange"
25301     );
25302     
25303     if(this.checkHandler){
25304         this.on('checkchange', this.checkHandler, this.scope);
25305     }
25306     Ext.menu.MenuMgr.registerCheckable(this);
25307 };
25308 Ext.extend(Ext.menu.CheckItem, Ext.menu.Item, {
25309     
25310     
25311     itemCls : "x-menu-item x-menu-check-item",
25312     
25313     groupClass : "x-menu-group-item",
25314
25315     
25316     checked: false,
25317
25318         ctype: "Ext.menu.CheckItem",
25319
25320         onRender : function(c){
25321         Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
25322         if(this.group){
25323             this.el.addClass(this.groupClass);
25324         }
25325         if(this.checked){
25326             this.checked = false;
25327             this.setChecked(true, true);
25328         }
25329     },
25330
25331         destroy : function(){
25332         Ext.menu.MenuMgr.unregisterCheckable(this);
25333         Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
25334     },
25335
25336     
25337     setChecked : function(state, suppressEvent){
25338         if(this.checked != state && this.fireEvent("beforecheckchange", this, state) !== false){
25339             if(this.container){
25340                 this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
25341             }
25342             this.checked = state;
25343             if(suppressEvent !== true){
25344                 this.fireEvent("checkchange", this, state);
25345             }
25346         }
25347     },
25348
25349         handleClick : function(e){
25350        if(!this.disabled && !(this.checked && this.group)){           this.setChecked(!this.checked);
25351        }
25352        Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
25353     }
25354 });
25355
25356 Ext.menu.Adapter = function(component, config){
25357     Ext.menu.Adapter.superclass.constructor.call(this, config);
25358     this.component = component;
25359 };
25360 Ext.extend(Ext.menu.Adapter, Ext.menu.BaseItem, {
25361         canActivate : true,
25362
25363         onRender : function(container, position){
25364         this.component.render(container);
25365         this.el = this.component.getEl();
25366     },
25367
25368         activate : function(){
25369         if(this.disabled){
25370             return false;
25371         }
25372         this.component.focus();
25373         this.fireEvent("activate", this);
25374         return true;
25375     },
25376
25377         deactivate : function(){
25378         this.fireEvent("deactivate", this);
25379     },
25380
25381         disable : function(){
25382         this.component.disable();
25383         Ext.menu.Adapter.superclass.disable.call(this);
25384     },
25385
25386         enable : function(){
25387         this.component.enable();
25388         Ext.menu.Adapter.superclass.enable.call(this);
25389     }
25390 });
25391
25392 Ext.menu.DateItem = function(config){
25393     Ext.menu.DateItem.superclass.constructor.call(this, new Ext.DatePicker(config), config);
25394     
25395     this.picker = this.component;
25396     this.addEvents('select');
25397     
25398     this.picker.on("render", function(picker){
25399         picker.getEl().swallowEvent("click");
25400         picker.container.addClass("x-menu-date-item");
25401     });
25402
25403     this.picker.on("select", this.onSelect, this);
25404 };
25405
25406 Ext.extend(Ext.menu.DateItem, Ext.menu.Adapter, {
25407         onSelect : function(picker, date){
25408         this.fireEvent("select", this, date, picker);
25409         Ext.menu.DateItem.superclass.handleClick.call(this);
25410     }
25411 });
25412
25413 Ext.menu.ColorItem = function(config){
25414     Ext.menu.ColorItem.superclass.constructor.call(this, new Ext.ColorPalette(config), config);
25415     
25416     this.palette = this.component;
25417     this.relayEvents(this.palette, ["select"]);
25418     if(this.selectHandler){
25419         this.on('select', this.selectHandler, this.scope);
25420     }
25421 };
25422 Ext.extend(Ext.menu.ColorItem, Ext.menu.Adapter);
25423
25424 Ext.menu.DateMenu = function(config){
25425     Ext.menu.DateMenu.superclass.constructor.call(this, config);
25426     this.plain = true;
25427     var di = new Ext.menu.DateItem(config);
25428     this.add(di);
25429     
25430     this.picker = di.picker;
25431     
25432     this.relayEvents(di, ["select"]);
25433
25434     this.on('beforeshow', function(){
25435         if(this.picker){
25436             this.picker.hideMonthPicker(true);
25437         }
25438     }, this);
25439 };
25440 Ext.extend(Ext.menu.DateMenu, Ext.menu.Menu, {
25441     cls:'x-date-menu',
25442
25443         beforeDestroy : function() {
25444         this.picker.destroy();
25445     }
25446 });
25447
25448 Ext.menu.ColorMenu = function(config){
25449     Ext.menu.ColorMenu.superclass.constructor.call(this, config);
25450     this.plain = true;
25451     var ci = new Ext.menu.ColorItem(config);
25452     this.add(ci);
25453     
25454     this.palette = ci.palette;
25455     
25456     this.relayEvents(ci, ["select"]);
25457 };
25458 Ext.extend(Ext.menu.ColorMenu, Ext.menu.Menu);
25459
25460 Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
25461     
25462     
25463     
25464     
25465     
25466     
25467
25468     
25469     invalidClass : "x-form-invalid",
25470     
25471     invalidText : "The value in this field is invalid",
25472     
25473     focusClass : "x-form-focus",
25474     
25475     validationEvent : "keyup",
25476     
25477     validateOnBlur : true,
25478     
25479     validationDelay : 250,
25480     
25481     defaultAutoCreate : {tag: "input", type: "text", size: "20", autocomplete: "off"},
25482     
25483     fieldClass : "x-form-field",
25484     
25485     msgTarget : 'qtip',
25486     
25487     msgFx : 'normal',
25488     
25489     
25490     readOnly : false,
25491
25492     
25493     disabled : false,
25494
25495     
25496
25497     
25498
25499         isFormField : true,
25500
25501         hasFocus : false,
25502
25503     
25504     
25505     
25506     
25507
25508                 initComponent : function(){
25509         Ext.form.Field.superclass.initComponent.call(this);
25510         this.addEvents(
25511             
25512             'focus',
25513             
25514             'blur',
25515             
25516             'specialkey',
25517             
25518             'change',
25519             
25520             'invalid',
25521             
25522             'valid'
25523         );
25524     },
25525
25526     
25527     getName: function(){
25528          return this.rendered && this.el.dom.name ? this.el.dom.name : (this.hiddenName || '');
25529     },
25530
25531         onRender : function(ct, position){
25532         Ext.form.Field.superclass.onRender.call(this, ct, position);
25533         if(!this.el){
25534             var cfg = this.getAutoCreate();
25535             if(!cfg.name){
25536                 cfg.name = this.name || this.id;
25537             }
25538             if(this.inputType){
25539                 cfg.type = this.inputType;
25540             }
25541             this.el = ct.createChild(cfg, position);
25542         }
25543         var type = this.el.dom.type;
25544         if(type){
25545             if(type == 'password'){
25546                 type = 'text';
25547             }
25548             this.el.addClass('x-form-'+type);
25549         }
25550         if(this.readOnly){
25551             this.el.dom.readOnly = true;
25552         }
25553         if(this.tabIndex !== undefined){
25554             this.el.dom.setAttribute('tabIndex', this.tabIndex);
25555         }
25556
25557         this.el.addClass([this.fieldClass, this.cls]);
25558         this.initValue();
25559     },
25560
25561         initValue : function(){
25562         if(this.value !== undefined){
25563             this.setValue(this.value);
25564         }else if(this.el.dom.value.length > 0){
25565             this.setValue(this.el.dom.value);
25566         }
25567     },
25568
25569     
25570     isDirty : function() {
25571         if(this.disabled) {
25572             return false;
25573         }
25574         return String(this.getValue()) !== String(this.originalValue);
25575     },
25576
25577         afterRender : function(){
25578         Ext.form.Field.superclass.afterRender.call(this);
25579         this.initEvents();
25580     },
25581
25582         fireKey : function(e){
25583         if(e.isSpecialKey()){
25584             this.fireEvent("specialkey", this, e);
25585         }
25586     },
25587
25588     
25589     reset : function(){
25590         this.setValue(this.originalValue);
25591         this.clearInvalid();
25592     },
25593
25594         initEvents : function(){
25595         this.el.on(Ext.isIE ? "keydown" : "keypress", this.fireKey,  this);
25596         this.el.on("focus", this.onFocus,  this);
25597         this.el.on("blur", this.onBlur,  this);
25598
25599                 this.originalValue = this.getValue();
25600     },
25601
25602         onFocus : function(){
25603         if(!Ext.isOpera && this.focusClass){             this.el.addClass(this.focusClass);
25604         }
25605         if(!this.hasFocus){
25606             this.hasFocus = true;
25607             this.startValue = this.getValue();
25608             this.fireEvent("focus", this);
25609         }
25610     },
25611
25612     beforeBlur : Ext.emptyFn,
25613
25614         onBlur : function(){
25615         this.beforeBlur();
25616         if(!Ext.isOpera && this.focusClass){             this.el.removeClass(this.focusClass);
25617         }
25618         this.hasFocus = false;
25619         if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
25620             this.validate();
25621         }
25622         var v = this.getValue();
25623         if(String(v) !== String(this.startValue)){
25624             this.fireEvent('change', this, v, this.startValue);
25625         }
25626         this.fireEvent("blur", this);
25627     },
25628
25629     
25630     isValid : function(preventMark){
25631         if(this.disabled){
25632             return true;
25633         }
25634         var restore = this.preventMark;
25635         this.preventMark = preventMark === true;
25636         var v = this.validateValue(this.processValue(this.getRawValue()));
25637         this.preventMark = restore;
25638         return v;
25639     },
25640
25641     
25642     validate : function(){
25643         if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
25644             this.clearInvalid();
25645             return true;
25646         }
25647         return false;
25648     },
25649
25650     processValue : function(value){
25651         return value;
25652     },
25653
25654             validateValue : function(value){
25655         return true;
25656     },
25657
25658     
25659     markInvalid : function(msg){
25660         if(!this.rendered || this.preventMark){             return;
25661         }
25662         this.el.addClass(this.invalidClass);
25663         msg = msg || this.invalidText;
25664         switch(this.msgTarget){
25665             case 'qtip':
25666                 this.el.dom.qtip = msg;
25667                 this.el.dom.qclass = 'x-form-invalid-tip';
25668                 if(Ext.QuickTips){                     Ext.QuickTips.enable();
25669                 }
25670                 break;
25671             case 'title':
25672                 this.el.dom.title = msg;
25673                 break;
25674             case 'under':
25675                 if(!this.errorEl){
25676                     var elp = this.el.findParent('.x-form-element', 5, true);
25677                     this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
25678                     this.errorEl.setWidth(elp.getWidth(true)-20);
25679                 }
25680                 this.errorEl.update(msg);
25681                 Ext.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
25682                 break;
25683             case 'side':
25684                 if(!this.errorIcon){
25685                     var elp = this.el.findParent('.x-form-element', 5, true);
25686                     this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
25687                 }
25688                 this.alignErrorIcon();
25689                 this.errorIcon.dom.qtip = msg;
25690                 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
25691                 this.errorIcon.show();
25692                 this.on('resize', this.alignErrorIcon, this);
25693                 break;
25694             default:
25695                 var t = Ext.getDom(this.msgTarget);
25696                 t.innerHTML = msg;
25697                 t.style.display = this.msgDisplay;
25698                 break;
25699         }
25700         this.fireEvent('invalid', this, msg);
25701     },
25702
25703         alignErrorIcon : function(){
25704         this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
25705     },
25706
25707     
25708     clearInvalid : function(){
25709         if(!this.rendered || this.preventMark){             return;
25710         }
25711         this.el.removeClass(this.invalidClass);
25712         switch(this.msgTarget){
25713             case 'qtip':
25714                 this.el.dom.qtip = '';
25715                 break;
25716             case 'title':
25717                 this.el.dom.title = '';
25718                 break;
25719             case 'under':
25720                 if(this.errorEl){
25721                     Ext.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
25722                 }
25723                 break;
25724             case 'side':
25725                 if(this.errorIcon){
25726                     this.errorIcon.dom.qtip = '';
25727                     this.errorIcon.hide();
25728                     this.un('resize', this.alignErrorIcon, this);
25729                 }
25730                 break;
25731             default:
25732                 var t = Ext.getDom(this.msgTarget);
25733                 t.innerHTML = '';
25734                 t.style.display = 'none';
25735                 break;
25736         }
25737         this.fireEvent('valid', this);
25738     },
25739
25740     
25741     getRawValue : function(){
25742         var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
25743         if(v === this.emptyText){
25744             v = '';
25745         }
25746         return v;
25747     },
25748
25749     
25750     getValue : function(){
25751         if(!this.rendered) {
25752             return this.value;
25753         }
25754         var v = this.el.getValue();
25755         if(v === this.emptyText || v === undefined){
25756             v = '';
25757         }
25758         return v;
25759     },
25760
25761     
25762     setRawValue : function(v){
25763         return this.el.dom.value = (v === null || v === undefined ? '' : v);
25764     },
25765
25766     
25767     setValue : function(v){
25768         this.value = v;
25769         if(this.rendered){
25770             this.el.dom.value = (v === null || v === undefined ? '' : v);
25771             this.validate();
25772         }
25773     },
25774
25775     adjustSize : function(w, h){
25776         var s = Ext.form.Field.superclass.adjustSize.call(this, w, h);
25777         s.width = this.adjustWidth(this.el.dom.tagName, s.width);
25778         return s;
25779     },
25780
25781     adjustWidth : function(tag, w){
25782         tag = tag.toLowerCase();
25783         if(typeof w == 'number' && !Ext.isSafari){
25784             if(Ext.isIE && (tag == 'input' || tag == 'textarea')){
25785                 if(tag == 'input' && !Ext.isStrict){
25786                     return this.inEditor ? w : w - 3;
25787                 }
25788                 if(tag == 'input' && Ext.isStrict){
25789                     return w - (Ext.isIE6 ? 4 : 1);
25790                 }
25791                 if(tag = 'textarea' && Ext.isStrict){
25792                     return w-2;
25793                 }
25794             }else if(Ext.isOpera && Ext.isStrict){
25795                 if(tag == 'input'){
25796                     return w + 2;
25797                 }
25798                 if(tag = 'textarea'){
25799                     return w-2;
25800                 }
25801             }
25802         }
25803         return w;
25804     }
25805
25806     
25807     
25808
25809     
25810 });
25811
25812
25813 Ext.form.Field.msgFx = {
25814     normal : {
25815         show: function(msgEl, f){
25816             msgEl.setDisplayed('block');
25817         },
25818
25819         hide : function(msgEl, f){
25820             msgEl.setDisplayed(false).update('');
25821         }
25822     },
25823
25824     slide : {
25825         show: function(msgEl, f){
25826             msgEl.slideIn('t', {stopFx:true});
25827         },
25828
25829         hide : function(msgEl, f){
25830             msgEl.slideOut('t', {stopFx:true,useDisplay:true});
25831         }
25832     },
25833
25834     slideRight : {
25835         show: function(msgEl, f){
25836             msgEl.fixDisplay();
25837             msgEl.alignTo(f.el, 'tl-tr');
25838             msgEl.slideIn('l', {stopFx:true});
25839         },
25840
25841         hide : function(msgEl, f){
25842             msgEl.slideOut('l', {stopFx:true,useDisplay:true});
25843         }
25844     }
25845 };
25846 Ext.reg('field', Ext.form.Field);
25847
25848
25849 Ext.form.TextField = Ext.extend(Ext.form.Field,  {
25850     
25851     
25852     grow : false,
25853     
25854     growMin : 30,
25855     
25856     growMax : 800,
25857     
25858     vtype : null,
25859     
25860     maskRe : null,
25861     
25862     disableKeyFilter : false,
25863     
25864     allowBlank : true,
25865     
25866     minLength : 0,
25867     
25868     maxLength : Number.MAX_VALUE,
25869     
25870     minLengthText : "The minimum length for this field is {0}",
25871     
25872     maxLengthText : "The maximum length for this field is {0}",
25873     
25874     selectOnFocus : false,
25875     
25876     blankText : "This field is required",
25877     
25878     validator : null,
25879     
25880     regex : null,
25881     
25882     regexText : "",
25883     
25884     emptyText : null,
25885     
25886     emptyClass : 'x-form-empty-field',
25887
25888     initComponent : function(){
25889         Ext.form.TextField.superclass.initComponent.call(this);
25890         this.addEvents(
25891             
25892             'autosize'
25893         );
25894     },
25895
25896         initEvents : function(){
25897         Ext.form.TextField.superclass.initEvents.call(this);
25898         if(this.validationEvent == 'keyup'){
25899             this.validationTask = new Ext.util.DelayedTask(this.validate, this);
25900             this.el.on('keyup', this.filterValidation, this);
25901         }
25902         else if(this.validationEvent !== false){
25903             this.el.on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
25904         }
25905         if(this.selectOnFocus || this.emptyText){
25906             this.on("focus", this.preFocus, this);
25907             if(this.emptyText){
25908                 this.on('blur', this.postBlur, this);
25909                 this.applyEmptyText();
25910             }
25911         }
25912         if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
25913             this.el.on("keypress", this.filterKeys, this);
25914         }
25915         if(this.grow){
25916             this.el.on("keyup", this.onKeyUp,  this, {buffer:50});
25917             this.el.on("click", this.autoSize,  this);
25918         }
25919     },
25920
25921     processValue : function(value){
25922         if(this.stripCharsRe){
25923             var newValue = value.replace(this.stripCharsRe, '');
25924             if(newValue !== value){
25925                 this.setRawValue(newValue);
25926                 return newValue;
25927             }
25928         }
25929         return value;
25930     },
25931
25932     filterValidation : function(e){
25933         if(!e.isNavKeyPress()){
25934             this.validationTask.delay(this.validationDelay);
25935         }
25936     },
25937
25938         onKeyUp : function(e){
25939         if(!e.isNavKeyPress()){
25940             this.autoSize();
25941         }
25942     },
25943
25944     
25945     reset : function(){
25946         Ext.form.TextField.superclass.reset.call(this);
25947         this.applyEmptyText();
25948     },
25949
25950     applyEmptyText : function(){
25951         if(this.rendered && this.emptyText && this.getRawValue().length < 1){
25952             this.setRawValue(this.emptyText);
25953             this.el.addClass(this.emptyClass);
25954         }
25955     },
25956
25957         preFocus : function(){
25958         if(this.emptyText){
25959             if(this.el.dom.value == this.emptyText){
25960                 this.setRawValue('');
25961             }
25962             this.el.removeClass(this.emptyClass);
25963         }
25964         if(this.selectOnFocus){
25965             this.el.dom.select();
25966         }
25967     },
25968
25969         postBlur : function(){
25970         this.applyEmptyText();
25971     },
25972
25973         filterKeys : function(e){
25974         var k = e.getKey();
25975         if(!Ext.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
25976             return;
25977         }
25978         var c = e.getCharCode(), cc = String.fromCharCode(c);
25979         if(Ext.isIE && (e.isSpecialKey() || !cc)){
25980             return;
25981         }
25982         if(!this.maskRe.test(cc)){
25983             e.stopEvent();
25984         }
25985     },
25986
25987     setValue : function(v){
25988         if(this.emptyText && this.el && v !== undefined && v !== null && v !== ''){
25989             this.el.removeClass(this.emptyClass);
25990         }
25991         Ext.form.TextField.superclass.setValue.apply(this, arguments);
25992         this.applyEmptyText();
25993         this.autoSize();
25994     },
25995
25996     
25997     validateValue : function(value){
25998         if(value.length < 1 || value === this.emptyText){              if(this.allowBlank){
25999                  this.clearInvalid();
26000                  return true;
26001              }else{
26002                  this.markInvalid(this.blankText);
26003                  return false;
26004              }
26005         }
26006         if(value.length < this.minLength){
26007             this.markInvalid(String.format(this.minLengthText, this.minLength));
26008             return false;
26009         }
26010         if(value.length > this.maxLength){
26011             this.markInvalid(String.format(this.maxLengthText, this.maxLength));
26012             return false;
26013         }
26014         if(this.vtype){
26015             var vt = Ext.form.VTypes;
26016             if(!vt[this.vtype](value, this)){
26017                 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
26018                 return false;
26019             }
26020         }
26021         if(typeof this.validator == "function"){
26022             var msg = this.validator(value);
26023             if(msg !== true){
26024                 this.markInvalid(msg);
26025                 return false;
26026             }
26027         }
26028         if(this.regex && !this.regex.test(value)){
26029             this.markInvalid(this.regexText);
26030             return false;
26031         }
26032         return true;
26033     },
26034
26035     
26036     selectText : function(start, end){
26037         var v = this.getRawValue();
26038         if(v.length > 0){
26039             start = start === undefined ? 0 : start;
26040             end = end === undefined ? v.length : end;
26041             var d = this.el.dom;
26042             if(d.setSelectionRange){
26043                 d.setSelectionRange(start, end);
26044             }else if(d.createTextRange){
26045                 var range = d.createTextRange();
26046                 range.moveStart("character", start);
26047                 range.moveEnd("character", end-v.length);
26048                 range.select();
26049             }
26050         }
26051     },
26052
26053     
26054     autoSize : function(){
26055         if(!this.grow || !this.rendered){
26056             return;
26057         }
26058         if(!this.metrics){
26059             this.metrics = Ext.util.TextMetrics.createInstance(this.el);
26060         }
26061         var el = this.el;
26062         var v = el.dom.value;
26063         var d = document.createElement('div');
26064         d.appendChild(document.createTextNode(v));
26065         v = d.innerHTML;
26066         d = null;
26067         v += "&#160;";
26068         var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) +  10, this.growMin));
26069         this.el.setWidth(w);
26070         this.fireEvent("autosize", this, w);
26071     }
26072 });
26073 Ext.reg('textfield', Ext.form.TextField);
26074
26075
26076 Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
26077     
26078     
26079     defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
26080     
26081     hideTrigger:false,
26082
26083     
26084     autoSize: Ext.emptyFn,
26085         monitorTab : true,
26086         deferHeight : true,
26087         mimicing : false,
26088
26089         onResize : function(w, h){
26090         Ext.form.TriggerField.superclass.onResize.call(this, w, h);
26091         if(typeof w == 'number'){
26092             this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
26093         }
26094         this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
26095     },
26096
26097         adjustSize : Ext.BoxComponent.prototype.adjustSize,
26098
26099         getResizeEl : function(){
26100         return this.wrap;
26101     },
26102
26103         getPositionEl : function(){
26104         return this.wrap;
26105     },
26106
26107         alignErrorIcon : function(){
26108         this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
26109     },
26110
26111         onRender : function(ct, position){
26112         Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
26113         this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
26114         this.trigger = this.wrap.createChild(this.triggerConfig ||
26115                 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
26116         if(this.hideTrigger){
26117             this.trigger.setDisplayed(false);
26118         }
26119         this.initTrigger();
26120         if(!this.width){
26121             this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
26122         }
26123     },
26124
26125         initTrigger : function(){
26126         this.trigger.on("click", this.onTriggerClick, this, {preventDefault:true});
26127         this.trigger.addClassOnOver('x-form-trigger-over');
26128         this.trigger.addClassOnClick('x-form-trigger-click');
26129     },
26130
26131         onDestroy : function(){
26132         if(this.trigger){
26133             this.trigger.removeAllListeners();
26134             this.trigger.remove();
26135         }
26136         if(this.wrap){
26137             this.wrap.remove();
26138         }
26139         Ext.form.TriggerField.superclass.onDestroy.call(this);
26140     },
26141
26142         onFocus : function(){
26143         Ext.form.TriggerField.superclass.onFocus.call(this);
26144         if(!this.mimicing){
26145             this.wrap.addClass('x-trigger-wrap-focus');
26146             this.mimicing = true;
26147             Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {delay: 10});
26148             if(this.monitorTab){
26149                 this.el.on("keydown", this.checkTab, this);
26150             }
26151         }
26152     },
26153
26154         checkTab : function(e){
26155         if(e.getKey() == e.TAB){
26156             this.triggerBlur();
26157         }
26158     },
26159
26160         onBlur : function(){
26161             },
26162
26163         mimicBlur : function(e){
26164         if(!this.wrap.contains(e.target) && this.validateBlur(e)){
26165             this.triggerBlur();
26166         }
26167     },
26168
26169         triggerBlur : function(){
26170         this.mimicing = false;
26171         Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur);
26172         if(this.monitorTab){
26173             this.el.un("keydown", this.checkTab, this);
26174         }
26175         this.beforeBlur();
26176         this.wrap.removeClass('x-trigger-wrap-focus');
26177         Ext.form.TriggerField.superclass.onBlur.call(this);
26178     },
26179
26180     beforeBlur : Ext.emptyFn, 
26181
26182             validateBlur : function(e){
26183         return true;
26184     },
26185
26186         onDisable : function(){
26187         Ext.form.TriggerField.superclass.onDisable.call(this);
26188         if(this.wrap){
26189             this.wrap.addClass('x-item-disabled');
26190         }
26191     },
26192
26193         onEnable : function(){
26194         Ext.form.TriggerField.superclass.onEnable.call(this);
26195         if(this.wrap){
26196             this.wrap.removeClass('x-item-disabled');
26197         }
26198     },
26199
26200
26201         onShow : function(){
26202         if(this.wrap){
26203             this.wrap.dom.style.display = '';
26204             this.wrap.dom.style.visibility = 'visible';
26205         }
26206     },
26207
26208         onHide : function(){
26209         this.wrap.dom.style.display = 'none';
26210     },
26211
26212     
26213     onTriggerClick : Ext.emptyFn
26214
26215     
26216     
26217     
26218 });
26219
26220 Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
26221     initComponent : function(){
26222         Ext.form.TwinTriggerField.superclass.initComponent.call(this);
26223
26224         this.triggerConfig = {
26225             tag:'span', cls:'x-form-twin-triggers', cn:[
26226             {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
26227             {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
26228         ]};
26229     },
26230
26231     getTrigger : function(index){
26232         return this.triggers[index];
26233     },
26234
26235     initTrigger : function(){
26236         var ts = this.trigger.select('.x-form-trigger', true);
26237         this.wrap.setStyle('overflow', 'hidden');
26238         var triggerField = this;
26239         ts.each(function(t, all, index){
26240             t.hide = function(){
26241                 var w = triggerField.wrap.getWidth();
26242                 this.dom.style.display = 'none';
26243                 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
26244             };
26245             t.show = function(){
26246                 var w = triggerField.wrap.getWidth();
26247                 this.dom.style.display = '';
26248                 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
26249             };
26250             var triggerIndex = 'Trigger'+(index+1);
26251
26252             if(this['hide'+triggerIndex]){
26253                 t.dom.style.display = 'none';
26254             }
26255             t.on("click", this['on'+triggerIndex+'Click'], this, {preventDefault:true});
26256             t.addClassOnOver('x-form-trigger-over');
26257             t.addClassOnClick('x-form-trigger-click');
26258         }, this);
26259         this.triggers = ts.elements;
26260     },
26261
26262     onTrigger1Click : Ext.emptyFn,
26263     onTrigger2Click : Ext.emptyFn
26264 });
26265 Ext.reg('trigger', Ext.form.TriggerField);
26266
26267 Ext.form.TextArea = Ext.extend(Ext.form.TextField,  {
26268     
26269     growMin : 60,
26270     
26271     growMax: 1000,
26272     growAppend : '&#160;\n&#160;',
26273     growPad : 0,
26274
26275     enterIsSpecial : false,
26276
26277     
26278     preventScrollbars: false,
26279     
26280
26281         onRender : function(ct, position){
26282         if(!this.el){
26283             this.defaultAutoCreate = {
26284                 tag: "textarea",
26285                 style:"width:100px;height:60px;",
26286                 autocomplete: "off"
26287             };
26288         }
26289         Ext.form.TextArea.superclass.onRender.call(this, ct, position);
26290         if(this.grow){
26291             this.textSizeEl = Ext.DomHelper.append(document.body, {
26292                 tag: "pre", cls: "x-form-grow-sizer"
26293             });
26294             if(this.preventScrollbars){
26295                 this.el.setStyle("overflow", "hidden");
26296             }
26297             this.el.setHeight(this.growMin);
26298         }
26299     },
26300
26301     onDestroy : function(){
26302         if(this.textSizeEl){
26303             Ext.removeNode(this.textSizeEl);
26304         }
26305         Ext.form.TextArea.superclass.onDestroy.call(this);
26306     },
26307
26308     fireKey : function(e){
26309         if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
26310             this.fireEvent("specialkey", this, e);
26311         }
26312     },
26313
26314         onKeyUp : function(e){
26315         if(!e.isNavKeyPress() || e.getKey() == e.ENTER){
26316             this.autoSize();
26317         }
26318     },
26319
26320     
26321     autoSize : function(){
26322         if(!this.grow || !this.textSizeEl){
26323             return;
26324         }
26325         var el = this.el;
26326         var v = el.dom.value;
26327         var ts = this.textSizeEl;
26328         ts.innerHTML = '';
26329         ts.appendChild(document.createTextNode(v));
26330         v = ts.innerHTML;
26331
26332         Ext.fly(ts).setWidth(this.el.getWidth());
26333         if(v.length < 1){
26334             v = "&#160;&#160;";
26335         }else{
26336             if(Ext.isIE){
26337                 v = v.replace(/\n/g, '<p>&#160;</p>');
26338             }
26339             v += this.growAppend;
26340         }
26341         ts.innerHTML = v;
26342         var h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin)+this.growPad);
26343         if(h != this.lastHeight){
26344             this.lastHeight = h;
26345             this.el.setHeight(h);
26346             this.fireEvent("autosize", this, h);
26347         }
26348     }
26349 });
26350 Ext.reg('textarea', Ext.form.TextArea);
26351
26352 Ext.form.NumberField = Ext.extend(Ext.form.TextField,  {
26353     
26354     fieldClass: "x-form-field x-form-num-field",
26355     
26356     allowDecimals : true,
26357     
26358     decimalSeparator : ".",
26359     
26360     decimalPrecision : 2,
26361     
26362     allowNegative : true,
26363     
26364     minValue : Number.NEGATIVE_INFINITY,
26365     
26366     maxValue : Number.MAX_VALUE,
26367     
26368     minText : "The minimum value for this field is {0}",
26369     
26370     maxText : "The maximum value for this field is {0}",
26371     
26372     nanText : "{0} is not a valid number",
26373     
26374     baseChars : "0123456789",
26375
26376         initEvents : function(){
26377         Ext.form.NumberField.superclass.initEvents.call(this);
26378         var allowed = this.baseChars+'';
26379         if(this.allowDecimals){
26380             allowed += this.decimalSeparator;
26381         }
26382         if(this.allowNegative){
26383             allowed += "-";
26384         }
26385         this.stripCharsRe = new RegExp('[^'+allowed+']', 'gi');
26386         var keyPress = function(e){
26387             var k = e.getKey();
26388             if(!Ext.isIE && (e.isSpecialKey() || k == e.BACKSPACE || k == e.DELETE)){
26389                 return;
26390             }
26391             var c = e.getCharCode();
26392             if(allowed.indexOf(String.fromCharCode(c)) === -1){
26393                 e.stopEvent();
26394             }
26395         };
26396         this.el.on("keypress", keyPress, this);
26397     },
26398
26399         validateValue : function(value){
26400         if(!Ext.form.NumberField.superclass.validateValue.call(this, value)){
26401             return false;
26402         }
26403         if(value.length < 1){              return true;
26404         }
26405         value = String(value).replace(this.decimalSeparator, ".");
26406         if(isNaN(value)){
26407             this.markInvalid(String.format(this.nanText, value));
26408             return false;
26409         }
26410         var num = this.parseValue(value);
26411         if(num < this.minValue){
26412             this.markInvalid(String.format(this.minText, this.minValue));
26413             return false;
26414         }
26415         if(num > this.maxValue){
26416             this.markInvalid(String.format(this.maxText, this.maxValue));
26417             return false;
26418         }
26419         return true;
26420     },
26421
26422     getValue : function(){
26423         return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
26424     },
26425
26426     setValue : function(v){
26427         v = parseFloat(v);
26428         v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
26429         Ext.form.NumberField.superclass.setValue.call(this, v);
26430     },
26431
26432         parseValue : function(value){
26433         value = parseFloat(String(value).replace(this.decimalSeparator, "."));
26434         return isNaN(value) ? '' : value;
26435     },
26436
26437         fixPrecision : function(value){
26438         var nan = isNaN(value);
26439         if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
26440            return nan ? '' : value;
26441         }
26442         return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
26443     },
26444
26445     beforeBlur : function(){
26446         var v = this.parseValue(this.getRawValue());
26447         if(v){
26448             this.setValue(this.fixPrecision(v));
26449         }
26450     }
26451 });
26452 Ext.reg('numberfield', Ext.form.NumberField);
26453
26454 Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
26455     
26456     format : "m/d/y",
26457     
26458     altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d",
26459     
26460     disabledDays : null,
26461     
26462     disabledDaysText : "Disabled",
26463     
26464     disabledDates : null,
26465     
26466     disabledDatesText : "Disabled",
26467     
26468     minValue : null,
26469     
26470     maxValue : null,
26471     
26472     minText : "The date in this field must be equal to or after {0}",
26473     
26474     maxText : "The date in this field must be equal to or before {0}",
26475     
26476     invalidText : "{0} is not a valid date - it must be in the format {1}",
26477     
26478     triggerClass : 'x-form-date-trigger',
26479     
26480
26481         defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
26482
26483     initComponent : function(){
26484         Ext.form.DateField.superclass.initComponent.call(this);
26485         if(typeof this.minValue == "string"){
26486             this.minValue = this.parseDate(this.minValue);
26487         }
26488         if(typeof this.maxValue == "string"){
26489             this.maxValue = this.parseDate(this.maxValue);
26490         }
26491         this.ddMatch = null;
26492         if(this.disabledDates){
26493             var dd = this.disabledDates;
26494             var re = "(?:";
26495             for(var i = 0; i < dd.length; i++){
26496                 re += dd[i];
26497                 if(i != dd.length-1) re += "|";
26498             }
26499             this.ddMatch = new RegExp(re + ")");
26500         }
26501     },
26502
26503         validateValue : function(value){
26504         value = this.formatDate(value);
26505         if(!Ext.form.DateField.superclass.validateValue.call(this, value)){
26506             return false;
26507         }
26508         if(value.length < 1){              return true;
26509         }
26510         var svalue = value;
26511         value = this.parseDate(value);
26512         if(!value){
26513             this.markInvalid(String.format(this.invalidText, svalue, this.format));
26514             return false;
26515         }
26516         var time = value.getTime();
26517         if(this.minValue && time < this.minValue.getTime()){
26518             this.markInvalid(String.format(this.minText, this.formatDate(this.minValue)));
26519             return false;
26520         }
26521         if(this.maxValue && time > this.maxValue.getTime()){
26522             this.markInvalid(String.format(this.maxText, this.formatDate(this.maxValue)));
26523             return false;
26524         }
26525         if(this.disabledDays){
26526             var day = value.getDay();
26527             for(var i = 0; i < this.disabledDays.length; i++) {
26528                 if(day === this.disabledDays[i]){
26529                     this.markInvalid(this.disabledDaysText);
26530                     return false;
26531                 }
26532             }
26533         }
26534         var fvalue = this.formatDate(value);
26535         if(this.ddMatch && this.ddMatch.test(fvalue)){
26536             this.markInvalid(String.format(this.disabledDatesText, fvalue));
26537             return false;
26538         }
26539         return true;
26540     },
26541
26542             validateBlur : function(){
26543         return !this.menu || !this.menu.isVisible();
26544     },
26545
26546     
26547     getValue : function(){
26548         return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
26549     },
26550
26551     
26552     setValue : function(date){
26553         Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
26554     },
26555
26556         parseDate : function(value){
26557         if(!value || Ext.isDate(value)){
26558             return value;
26559         }
26560         var v = Date.parseDate(value, this.format);
26561         if(!v && this.altFormats){
26562             if(!this.altFormatsArray){
26563                 this.altFormatsArray = this.altFormats.split("|");
26564             }
26565             for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
26566                 v = Date.parseDate(value, this.altFormatsArray[i]);
26567             }
26568         }
26569         return v;
26570     },
26571
26572         onDestroy : function(){
26573         if(this.menu) {
26574             this.menu.destroy();
26575         }
26576         if(this.wrap){
26577             this.wrap.remove();
26578         }
26579         Ext.form.DateField.superclass.onDestroy.call(this);
26580     },
26581
26582         formatDate : function(date){
26583         return Ext.isDate(date) ? date.dateFormat(this.format) : date;
26584     },
26585
26586         menuListeners : {
26587         select: function(m, d){
26588             this.setValue(d);
26589         },
26590         show : function(){             this.onFocus();
26591         },
26592         hide : function(){
26593             this.focus.defer(10, this);
26594             var ml = this.menuListeners;
26595             this.menu.un("select", ml.select,  this);
26596             this.menu.un("show", ml.show,  this);
26597             this.menu.un("hide", ml.hide,  this);
26598         }
26599     },
26600
26601             onTriggerClick : function(){
26602         if(this.disabled){
26603             return;
26604         }
26605         if(this.menu == null){
26606             this.menu = new Ext.menu.DateMenu();
26607         }
26608         Ext.apply(this.menu.picker,  {
26609             minDate : this.minValue,
26610             maxDate : this.maxValue,
26611             disabledDatesRE : this.ddMatch,
26612             disabledDatesText : this.disabledDatesText,
26613             disabledDays : this.disabledDays,
26614             disabledDaysText : this.disabledDaysText,
26615             format : this.format,
26616             minText : String.format(this.minText, this.formatDate(this.minValue)),
26617             maxText : String.format(this.maxText, this.formatDate(this.maxValue))
26618         });
26619         this.menu.on(Ext.apply({}, this.menuListeners, {
26620             scope:this
26621         }));
26622         this.menu.picker.setValue(this.getValue() || new Date());
26623         this.menu.show(this.el, "tl-bl?");
26624     },
26625
26626     beforeBlur : function(){
26627         var v = this.parseDate(this.getRawValue());
26628         if(v){
26629             this.setValue(v);
26630         }
26631     }
26632
26633     
26634     
26635     
26636     
26637 });
26638 Ext.reg('datefield', Ext.form.DateField);
26639
26640 Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
26641     
26642     
26643     
26644     
26645     
26646
26647         defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
26648     
26649     
26650     
26651     
26652     
26653     
26654     listClass: '',
26655     
26656     selectedClass: 'x-combo-selected',
26657     
26658     triggerClass : 'x-form-arrow-trigger',
26659     
26660     shadow:'sides',
26661     
26662     listAlign: 'tl-bl?',
26663     
26664     maxHeight: 300,
26665     
26666     minHeight: 90,
26667     
26668     triggerAction: 'query',
26669     
26670     minChars : 4,
26671     
26672     typeAhead: false,
26673     
26674     queryDelay: 500,
26675     
26676     pageSize: 0,
26677     
26678     selectOnFocus:false,
26679     
26680     queryParam: 'query',
26681     
26682     loadingText: 'Loading...',
26683     
26684     resizable: false,
26685     
26686     handleHeight : 8,
26687     
26688     editable: true,
26689     
26690     allQuery: '',
26691     
26692     mode: 'remote',
26693     
26694     minListWidth : 70,
26695     
26696     forceSelection:false,
26697     
26698     typeAheadDelay : 250,
26699     
26700
26701     
26702     lazyInit : true,
26703
26704     initComponent : function(){
26705         Ext.form.ComboBox.superclass.initComponent.call(this);
26706         this.addEvents(
26707             
26708             'expand',
26709             
26710             'collapse',
26711             
26712             'beforeselect',
26713             
26714             'select',
26715             
26716             'beforequery'
26717         );
26718         if(this.transform){
26719             this.allowDomMove = false;
26720             var s = Ext.getDom(this.transform);
26721             if(!this.hiddenName){
26722                 this.hiddenName = s.name;
26723             }
26724             if(!this.store){
26725                 this.mode = 'local';
26726                 var d = [], opts = s.options;
26727                 for(var i = 0, len = opts.length;i < len; i++){
26728                     var o = opts[i];
26729                     var value = (Ext.isIE ? o.getAttributeNode('value').specified : o.hasAttribute('value')) ? o.value : o.text;
26730                     if(o.selected) {
26731                         this.value = value;
26732                     }
26733                     d.push([value, o.text]);
26734                 }
26735                 this.store = new Ext.data.SimpleStore({
26736                     'id': 0,
26737                     fields: ['value', 'text'],
26738                     data : d
26739                 });
26740                 this.valueField = 'value';
26741                 this.displayField = 'text';
26742             }
26743             s.name = Ext.id();             if(!this.lazyRender){
26744                 this.target = true;
26745                 this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
26746                 Ext.removeNode(s);                 this.render(this.el.parentNode);
26747             }else{
26748                 Ext.removeNode(s);             }
26749
26750         }
26751         this.selectedIndex = -1;
26752         if(this.mode == 'local'){
26753             if(this.initialConfig.queryDelay === undefined){
26754                 this.queryDelay = 10;
26755             }
26756             if(this.initialConfig.minChars === undefined){
26757                 this.minChars = 0;
26758             }
26759         }
26760     },
26761
26762         onRender : function(ct, position){
26763         Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
26764         if(this.hiddenName){
26765             this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName, id: (this.hiddenId||this.hiddenName)},
26766                     'before', true);
26767             this.hiddenField.value =
26768                 this.hiddenValue !== undefined ? this.hiddenValue :
26769                 this.value !== undefined ? this.value : '';
26770
26771                         this.el.dom.removeAttribute('name');
26772         }
26773         if(Ext.isGecko){
26774             this.el.dom.setAttribute('autocomplete', 'off');
26775         }
26776
26777         if(!this.lazyInit){
26778             this.initList();
26779         }else{
26780             this.on('focus', this.initList, this, {single: true});
26781         }
26782
26783         if(!this.editable){
26784             this.editable = true;
26785             this.setEditable(false);
26786         }
26787     },
26788
26789     initList : function(){
26790         if(!this.list){
26791             var cls = 'x-combo-list';
26792
26793             this.list = new Ext.Layer({
26794                 shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
26795             });
26796
26797             var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
26798             this.list.setWidth(lw);
26799             this.list.swallowEvent('mousewheel');
26800             this.assetHeight = 0;
26801
26802             if(this.title){
26803                 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
26804                 this.assetHeight += this.header.getHeight();
26805             }
26806
26807             this.innerList = this.list.createChild({cls:cls+'-inner'});
26808             this.innerList.on('mouseover', this.onViewOver, this);
26809             this.innerList.on('mousemove', this.onViewMove, this);
26810             this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
26811
26812             if(this.pageSize){
26813                 this.footer = this.list.createChild({cls:cls+'-ft'});
26814                 this.pageTb = new Ext.PagingToolbar({
26815                     store:this.store,
26816                     pageSize: this.pageSize,
26817                     renderTo:this.footer
26818                 });
26819                 this.assetHeight += this.footer.getHeight();
26820             }
26821
26822             if(!this.tpl){
26823                             
26824                 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
26825             }
26826
26827                     
26828             this.view = new Ext.DataView({
26829                 applyTo: this.innerList,
26830                 tpl: this.tpl,
26831                 singleSelect: true,
26832                 selectedClass: this.selectedClass,
26833                 itemSelector: this.itemSelector || '.' + cls + '-item'
26834             });
26835
26836             this.view.on('click', this.onViewClick, this);
26837
26838             this.bindStore(this.store, true);
26839
26840             if(this.resizable){
26841                 this.resizer = new Ext.Resizable(this.list,  {
26842                    pinned:true, handles:'se'
26843                 });
26844                 this.resizer.on('resize', function(r, w, h){
26845                     this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
26846                     this.listWidth = w;
26847                     this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
26848                     this.restrictHeight();
26849                 }, this);
26850                 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
26851             }
26852         }
26853     },
26854
26855
26856         bindStore : function(store, initial){
26857         if(this.store && !initial){
26858             this.store.un('beforeload', this.onBeforeLoad, this);
26859             this.store.un('load', this.onLoad, this);
26860             this.store.un('loadexception', this.collapse, this);
26861             if(!store){
26862                 this.store = null;
26863                 if(this.view){
26864                     this.view.setStore(null);
26865                 }
26866             }
26867         }
26868         if(store){
26869             this.store = Ext.StoreMgr.lookup(store);
26870
26871             this.store.on('beforeload', this.onBeforeLoad, this);
26872             this.store.on('load', this.onLoad, this);
26873             this.store.on('loadexception', this.collapse, this);
26874
26875             if(this.view){
26876                 this.view.setStore(store);
26877             }
26878         }
26879     },
26880
26881         initEvents : function(){
26882         Ext.form.ComboBox.superclass.initEvents.call(this);
26883
26884         this.keyNav = new Ext.KeyNav(this.el, {
26885             "up" : function(e){
26886                 this.inKeyMode = true;
26887                 this.selectPrev();
26888             },
26889
26890             "down" : function(e){
26891                 if(!this.isExpanded()){
26892                     this.onTriggerClick();
26893                 }else{
26894                     this.inKeyMode = true;
26895                     this.selectNext();
26896                 }
26897             },
26898
26899             "enter" : function(e){
26900                 this.onViewClick();
26901                 this.delayedCheck = true;
26902                                 this.unsetDelayCheck.defer(10, this);
26903             },
26904
26905             "esc" : function(e){
26906                 this.collapse();
26907             },
26908
26909             "tab" : function(e){
26910                 this.onViewClick(false);
26911                 return true;
26912             },
26913
26914             scope : this,
26915
26916             doRelay : function(foo, bar, hname){
26917                 if(hname == 'down' || this.scope.isExpanded()){
26918                    return Ext.KeyNav.prototype.doRelay.apply(this, arguments);
26919                 }
26920                 return true;
26921             },
26922
26923             forceKeyDown : true
26924         });
26925         this.queryDelay = Math.max(this.queryDelay || 10,
26926                 this.mode == 'local' ? 10 : 250);
26927         this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
26928         if(this.typeAhead){
26929             this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
26930         }
26931         if(this.editable !== false){
26932             this.el.on("keyup", this.onKeyUp, this);
26933         }
26934         if(this.forceSelection){
26935             this.on('blur', this.doForce, this);
26936         }
26937     },
26938
26939     onDestroy : function(){
26940         if(this.view){
26941             this.view.el.removeAllListeners();
26942             this.view.el.remove();
26943             this.view.purgeListeners();
26944         }
26945         if(this.list){
26946             this.list.destroy();
26947         }
26948         this.bindStore(null);
26949         Ext.form.ComboBox.superclass.onDestroy.call(this);
26950     },
26951
26952         unsetDelayCheck : function(){
26953                 delete this.delayedCheck;
26954         },
26955         fireKey : function(e){
26956         if(e.isNavKeyPress() && !this.isExpanded() && !this.delayedCheck){
26957             this.fireEvent("specialkey", this, e);
26958         }
26959     },
26960
26961         onResize: function(w, h){
26962         Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
26963         if(this.list && this.listWidth === undefined){
26964             var lw = Math.max(w, this.minListWidth);
26965             this.list.setWidth(lw);
26966             this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
26967         }
26968     },
26969
26970         onEnable: function(){
26971         Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
26972         if(this.hiddenField){
26973             this.hiddenField.disabled = false;
26974         }
26975     },
26976
26977         onDisable: function(){
26978         Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
26979         if(this.hiddenField){
26980             this.hiddenField.disabled = true;
26981         }
26982     },
26983
26984     
26985     setEditable : function(value){
26986         if(value == this.editable){
26987             return;
26988         }
26989         this.editable = value;
26990         if(!value){
26991             this.el.dom.setAttribute('readOnly', true);
26992             this.el.on('mousedown', this.onTriggerClick,  this);
26993             this.el.addClass('x-combo-noedit');
26994         }else{
26995             this.el.dom.setAttribute('readOnly', false);
26996             this.el.un('mousedown', this.onTriggerClick,  this);
26997             this.el.removeClass('x-combo-noedit');
26998         }
26999     },
27000
27001         onBeforeLoad : function(){
27002         if(!this.hasFocus){
27003             return;
27004         }
27005         this.innerList.update(this.loadingText ?
27006                '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
27007         this.restrictHeight();
27008         this.selectedIndex = -1;
27009     },
27010
27011         onLoad : function(){
27012         if(!this.hasFocus){
27013             return;
27014         }
27015         if(this.store.getCount() > 0){
27016             this.expand();
27017             this.restrictHeight();
27018             if(this.lastQuery == this.allQuery){
27019                 if(this.editable){
27020                     this.el.dom.select();
27021                 }
27022                 if(!this.selectByValue(this.value, true)){
27023                     this.select(0, true);
27024                 }
27025             }else{
27026                 this.selectNext();
27027                 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
27028                     this.taTask.delay(this.typeAheadDelay);
27029                 }
27030             }
27031         }else{
27032             this.onEmptyResults();
27033         }
27034             },
27035
27036         onTypeAhead : function(){
27037         if(this.store.getCount() > 0){
27038             var r = this.store.getAt(0);
27039             var newValue = r.data[this.displayField];
27040             var len = newValue.length;
27041             var selStart = this.getRawValue().length;
27042             if(selStart != len){
27043                 this.setRawValue(newValue);
27044                 this.selectText(selStart, newValue.length);
27045             }
27046         }
27047     },
27048
27049         onSelect : function(record, index){
27050         if(this.fireEvent('beforeselect', this, record, index) !== false){
27051             this.setValue(record.data[this.valueField || this.displayField]);
27052             this.collapse();
27053             this.fireEvent('select', this, record, index);
27054         }
27055     },
27056
27057     
27058     getValue : function(){
27059         if(this.valueField){
27060             return typeof this.value != 'undefined' ? this.value : '';
27061         }else{
27062             return Ext.form.ComboBox.superclass.getValue.call(this);
27063         }
27064     },
27065
27066     
27067     clearValue : function(){
27068         if(this.hiddenField){
27069             this.hiddenField.value = '';
27070         }
27071         this.setRawValue('');
27072         this.lastSelectionText = '';
27073         this.applyEmptyText();
27074         this.value = '';
27075     },
27076
27077     
27078     setValue : function(v){
27079         var text = v;
27080         if(this.valueField){
27081             var r = this.findRecord(this.valueField, v);
27082             if(r){
27083                 text = r.data[this.displayField];
27084             }else if(this.valueNotFoundText !== undefined){
27085                 text = this.valueNotFoundText;
27086             }
27087         }
27088         this.lastSelectionText = text;
27089         if(this.hiddenField){
27090             this.hiddenField.value = v;
27091         }
27092         Ext.form.ComboBox.superclass.setValue.call(this, text);
27093         this.value = v;
27094     },
27095
27096         findRecord : function(prop, value){
27097         var record;
27098         if(this.store.getCount() > 0){
27099             this.store.each(function(r){
27100                 if(r.data[prop] == value){
27101                     record = r;
27102                     return false;
27103                 }
27104             });
27105         }
27106         return record;
27107     },
27108
27109         onViewMove : function(e, t){
27110         this.inKeyMode = false;
27111     },
27112
27113         onViewOver : function(e, t){
27114         if(this.inKeyMode){             return;
27115         }
27116         var item = this.view.findItemFromChild(t);
27117         if(item){
27118             var index = this.view.indexOf(item);
27119             this.select(index, false);
27120         }
27121     },
27122
27123         onViewClick : function(doFocus){
27124         var index = this.view.getSelectedIndexes()[0];
27125         var r = this.store.getAt(index);
27126         if(r){
27127             this.onSelect(r, index);
27128         }
27129         if(doFocus !== false){
27130             this.el.focus();
27131         }
27132     },
27133
27134         restrictHeight : function(){
27135         this.innerList.dom.style.height = '';
27136         var inner = this.innerList.dom;
27137         var pad = this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight;
27138         var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
27139         var ha = this.getPosition()[1]-Ext.getBody().getScroll().top;
27140         var hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height;
27141         var space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadow.offset-pad-2;
27142         h = Math.min(h, space, this.maxHeight);
27143         
27144         this.innerList.setHeight(h);
27145         this.list.beginUpdate();
27146         this.list.setHeight(h+pad);
27147         this.list.alignTo(this.el, this.listAlign);
27148         this.list.endUpdate();
27149     },
27150
27151         onEmptyResults : function(){
27152         this.collapse();
27153     },
27154
27155     
27156     isExpanded : function(){
27157         return this.list && this.list.isVisible();
27158     },
27159
27160     
27161     selectByValue : function(v, scrollIntoView){
27162         if(v !== undefined && v !== null){
27163             var r = this.findRecord(this.valueField || this.displayField, v);
27164             if(r){
27165                 this.select(this.store.indexOf(r), scrollIntoView);
27166                 return true;
27167             }
27168         }
27169         return false;
27170     },
27171
27172     
27173     select : function(index, scrollIntoView){
27174         this.selectedIndex = index;
27175         this.view.select(index);
27176         if(scrollIntoView !== false){
27177             var el = this.view.getNode(index);
27178             if(el){
27179                 this.innerList.scrollChildIntoView(el, false);
27180             }
27181         }
27182     },
27183
27184         selectNext : function(){
27185         var ct = this.store.getCount();
27186         if(ct > 0){
27187             if(this.selectedIndex == -1){
27188                 this.select(0);
27189             }else if(this.selectedIndex < ct-1){
27190                 this.select(this.selectedIndex+1);
27191             }
27192         }
27193     },
27194
27195         selectPrev : function(){
27196         var ct = this.store.getCount();
27197         if(ct > 0){
27198             if(this.selectedIndex == -1){
27199                 this.select(0);
27200             }else if(this.selectedIndex != 0){
27201                 this.select(this.selectedIndex-1);
27202             }
27203         }
27204     },
27205
27206         onKeyUp : function(e){
27207         if(this.editable !== false && !e.isSpecialKey()){
27208             this.lastKey = e.getKey();
27209             this.dqTask.delay(this.queryDelay);
27210         }
27211     },
27212
27213         validateBlur : function(){
27214         return !this.list || !this.list.isVisible();
27215     },
27216
27217         initQuery : function(){
27218         this.doQuery(this.getRawValue());
27219     },
27220
27221         doForce : function(){
27222         if(this.el.dom.value.length > 0){
27223             this.el.dom.value =
27224                 this.lastSelectionText === undefined ? '' : this.lastSelectionText;
27225             this.applyEmptyText();
27226         }
27227     },
27228
27229     
27230     doQuery : function(q, forceAll){
27231         if(q === undefined || q === null){
27232             q = '';
27233         }
27234         var qe = {
27235             query: q,
27236             forceAll: forceAll,
27237             combo: this,
27238             cancel:false
27239         };
27240         if(this.fireEvent('beforequery', qe)===false || qe.cancel){
27241             return false;
27242         }
27243         q = qe.query;
27244         forceAll = qe.forceAll;
27245         if(forceAll === true || (q.length >= this.minChars)){
27246             if(this.lastQuery !== q){
27247                 this.lastQuery = q;
27248                 if(this.mode == 'local'){
27249                     this.selectedIndex = -1;
27250                     if(forceAll){
27251                         this.store.clearFilter();
27252                     }else{
27253                         this.store.filter(this.displayField, q);
27254                     }
27255                     this.onLoad();
27256                 }else{
27257                     this.store.baseParams[this.queryParam] = q;
27258                     this.store.load({
27259                         params: this.getParams(q)
27260                     });
27261                     this.expand();
27262                 }
27263             }else{
27264                 this.selectedIndex = -1;
27265                 this.onLoad();
27266             }
27267         }
27268     },
27269
27270         getParams : function(q){
27271         var p = {};
27272                 if(this.pageSize){
27273             p.start = 0;
27274             p.limit = this.pageSize;
27275         }
27276         return p;
27277     },
27278
27279     
27280     collapse : function(){
27281         if(!this.isExpanded()){
27282             return;
27283         }
27284         this.list.hide();
27285         Ext.getDoc().un('mousewheel', this.collapseIf, this);
27286         Ext.getDoc().un('mousedown', this.collapseIf, this);
27287         this.fireEvent('collapse', this);
27288     },
27289
27290         collapseIf : function(e){
27291         if(!e.within(this.wrap) && !e.within(this.list)){
27292             this.collapse();
27293         }
27294     },
27295
27296     
27297     expand : function(){
27298         if(this.isExpanded() || !this.hasFocus){
27299             return;
27300         }
27301         this.list.alignTo(this.wrap, this.listAlign);
27302         this.list.show();
27303         this.innerList.setOverflow('auto');         Ext.getDoc().on('mousewheel', this.collapseIf, this);
27304         Ext.getDoc().on('mousedown', this.collapseIf, this);
27305         this.fireEvent('expand', this);
27306     },
27307
27308             onTriggerClick : function(){
27309         if(this.disabled){
27310             return;
27311         }
27312         if(this.isExpanded()){
27313             this.collapse();
27314             this.el.focus();
27315         }else {
27316             this.onFocus({});
27317             if(this.triggerAction == 'all') {
27318                 this.doQuery(this.allQuery, true);
27319             } else {
27320                 this.doQuery(this.getRawValue());
27321             }
27322             this.el.focus();
27323         }
27324     }
27325
27326     
27327     
27328     
27329     
27330
27331 });
27332 Ext.reg('combo', Ext.form.ComboBox);
27333
27334 Ext.form.Checkbox = Ext.extend(Ext.form.Field,  {
27335     
27336     focusClass : undefined,
27337     
27338     fieldClass: "x-form-field",
27339     
27340     checked: false,
27341     
27342     defaultAutoCreate : { tag: "input", type: 'checkbox', autocomplete: "off"},
27343     
27344     
27345
27346             initComponent : function(){
27347         Ext.form.Checkbox.superclass.initComponent.call(this);
27348         this.addEvents(
27349             
27350             'check'
27351         );
27352     },
27353
27354         onResize : function(){
27355         Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
27356         if(!this.boxLabel){
27357             this.el.alignTo(this.wrap, 'c-c');
27358         }
27359     },
27360     
27361         initEvents : function(){
27362         Ext.form.Checkbox.superclass.initEvents.call(this);
27363         this.el.on("click", this.onClick,  this);
27364         this.el.on("change", this.onClick,  this);
27365     },
27366
27367             getResizeEl : function(){
27368         return this.wrap;
27369     },
27370
27371         getPositionEl : function(){
27372         return this.wrap;
27373     },
27374
27375     
27376     markInvalid : Ext.emptyFn,
27377     
27378     clearInvalid : Ext.emptyFn,
27379
27380         onRender : function(ct, position){
27381         Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
27382         if(this.inputValue !== undefined){
27383             this.el.dom.value = this.inputValue;
27384         }
27385         this.wrap = this.el.wrap({cls: "x-form-check-wrap"});
27386         if(this.boxLabel){
27387             this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
27388         }
27389         if(this.checked){
27390             this.setValue(true);
27391         }else{
27392             this.checked = this.el.dom.checked;
27393         }
27394     },
27395     
27396         onDestroy : function(){
27397         if(this.wrap){
27398             this.wrap.remove();
27399         }
27400         Ext.form.Checkbox.superclass.onDestroy.call(this);
27401     },
27402
27403         initValue : Ext.emptyFn,
27404
27405     
27406     getValue : function(){
27407         if(this.rendered){
27408             return this.el.dom.checked;
27409         }
27410         return false;
27411     },
27412
27413             onClick : function(){
27414         if(this.el.dom.checked != this.checked){
27415             this.setValue(this.el.dom.checked);
27416         }
27417     },
27418
27419     
27420     setValue : function(v){
27421         this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
27422         if(this.el && this.el.dom){
27423             this.el.dom.checked = this.checked;
27424             this.el.dom.defaultChecked = this.checked;
27425         }
27426         this.fireEvent("check", this, this.checked);
27427     }
27428 });
27429 Ext.reg('checkbox', Ext.form.Checkbox);
27430
27431 Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
27432     inputType: 'radio',
27433
27434     
27435     markInvalid : Ext.emptyFn,
27436     
27437     clearInvalid : Ext.emptyFn,
27438
27439     
27440     getGroupValue : function(){
27441         var p = this.el.up('form') || Ext.getBody();
27442         var c = p.child('input[name='+this.el.dom.name+']:checked', true);
27443         return c ? c.value : null;
27444     },
27445     
27446         onClick : function(){
27447         if(this.el.dom.checked != this.checked){
27448                 var p = this.el.up('form') || Ext.getBody();
27449                         var els = p.select('input[name='+this.el.dom.name+']');
27450                         els.each(function(el){
27451                                 if(el.dom.id == this.id){
27452                                         this.setValue(true);
27453                                 }else{
27454                                         Ext.getCmp(el.dom.id).setValue(false);
27455                                 }
27456                         }, this);
27457                 }
27458     },
27459
27460     
27461     setValue : function(v){
27462         if (typeof v == 'boolean') {
27463             Ext.form.Radio.superclass.setValue.call(this, v);
27464         } else {
27465             var r = this.el.up('form').child('input[name='+this.el.dom.name+'][value='+v+']', true);
27466             if (r){
27467                 r.checked = true;
27468             };
27469         }
27470     }
27471 });
27472 Ext.reg('radio', Ext.form.Radio);
27473 \r
27474 Ext.form.Hidden = Ext.extend(Ext.form.Field, {\r
27475     
27476     inputType : 'hidden',\r
27477 \r
27478     
27479     onRender : function(){\r
27480         Ext.form.Hidden.superclass.onRender.apply(this, arguments);\r
27481     },\r
27482 \r
27483     
27484     initEvents : function(){\r
27485         this.originalValue = this.getValue();\r
27486     },\r
27487 \r
27488     
27489     setSize : Ext.emptyFn,\r
27490     setWidth : Ext.emptyFn,\r
27491     setHeight : Ext.emptyFn,\r
27492     setPosition : Ext.emptyFn,\r
27493     setPagePosition : Ext.emptyFn,\r
27494     markInvalid : Ext.emptyFn,\r
27495     clearInvalid : Ext.emptyFn\r
27496 });\r
27497 Ext.reg('hidden', Ext.form.Hidden);
27498
27499 Ext.form.BasicForm = function(el, config){
27500     Ext.apply(this, config);
27501     
27502     this.items = new Ext.util.MixedCollection(false, function(o){
27503         return o.id || (o.id = Ext.id());
27504     });
27505     this.addEvents(
27506         
27507         'beforeaction',
27508         
27509         'actionfailed',
27510         
27511         'actioncomplete'
27512     );
27513     
27514     if(el){
27515         this.initEl(el);
27516     }
27517     Ext.form.BasicForm.superclass.constructor.call(this);
27518 };
27519
27520 Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
27521     
27522     
27523     
27524     
27525     
27526     
27527     
27528     timeout: 30,
27529
27530         activeAction : null,
27531
27532     
27533     trackResetOnLoad : false,
27534
27535     
27536     
27537     
27538         initEl : function(el){
27539         this.el = Ext.get(el);
27540         this.id = this.el.id || Ext.id();
27541         if(!this.standardSubmit){
27542             this.el.on('submit', this.onSubmit, this);
27543         }
27544         this.el.addClass('x-form');
27545     },
27546
27547     
27548     getEl: function(){
27549         return this.el;
27550     },
27551
27552         onSubmit : function(e){
27553         e.stopEvent();
27554     },
27555     
27556         destroy: function() {
27557         this.items.each(function(f){
27558             Ext.destroy(f);
27559         });
27560         if(this.el){
27561                         this.el.removeAllListeners();
27562                         this.el.remove();
27563         }
27564                 this.purgeListeners();
27565         },
27566
27567     
27568     isValid : function(){
27569         var valid = true;
27570         this.items.each(function(f){
27571            if(!f.validate()){
27572                valid = false;
27573            }
27574         });
27575         return valid;
27576     },
27577
27578     
27579     isDirty : function(){
27580         var dirty = false;
27581         this.items.each(function(f){
27582            if(f.isDirty()){
27583                dirty = true;
27584                return false;
27585            }
27586         });
27587         return dirty;
27588     },
27589
27590     
27591     doAction : function(action, options){
27592         if(typeof action == 'string'){
27593             action = new Ext.form.Action.ACTION_TYPES[action](this, options);
27594         }
27595         if(this.fireEvent('beforeaction', this, action) !== false){
27596             this.beforeAction(action);
27597             action.run.defer(100, action);
27598         }
27599         return this;
27600     },
27601
27602     
27603     submit : function(options){
27604         if(this.standardSubmit){
27605             var v = this.isValid();
27606             if(v){
27607                 this.el.dom.submit();
27608             }
27609             return v;
27610         }
27611         this.doAction('submit', options);
27612         return this;
27613     },
27614
27615     
27616     load : function(options){
27617         this.doAction('load', options);
27618         return this;
27619     },
27620
27621     
27622     updateRecord : function(record){
27623         record.beginEdit();
27624         var fs = record.fields;
27625         fs.each(function(f){
27626             var field = this.findField(f.name);
27627             if(field){
27628                 record.set(f.name, field.getValue());
27629             }
27630         }, this);
27631         record.endEdit();
27632         return this;
27633     },
27634
27635     
27636     loadRecord : function(record){
27637         this.setValues(record.data);
27638         return this;
27639     },
27640
27641         beforeAction : function(action){
27642         var o = action.options;
27643         if(o.waitMsg){
27644             if(this.waitMsgTarget === true){
27645                 this.el.mask(o.waitMsg, 'x-mask-loading');
27646             }else if(this.waitMsgTarget){
27647                 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
27648                 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
27649             }else{
27650                 Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle || 'Please Wait...');
27651             }
27652         }
27653     },
27654
27655         afterAction : function(action, success){
27656         this.activeAction = null;
27657         var o = action.options;
27658         if(o.waitMsg){
27659             if(this.waitMsgTarget === true){
27660                 this.el.unmask();
27661             }else if(this.waitMsgTarget){
27662                 this.waitMsgTarget.unmask();
27663             }else{
27664                 Ext.MessageBox.updateProgress(1);
27665                 Ext.MessageBox.hide();
27666             }
27667         }
27668         if(success){
27669             if(o.reset){
27670                 this.reset();
27671             }
27672             Ext.callback(o.success, o.scope, [this, action]);
27673             this.fireEvent('actioncomplete', this, action);
27674         }else{
27675             Ext.callback(o.failure, o.scope, [this, action]);
27676             this.fireEvent('actionfailed', this, action);
27677         }
27678     },
27679
27680     
27681     findField : function(id){
27682         var field = this.items.get(id);
27683         if(!field){
27684             this.items.each(function(f){
27685                 if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
27686                     field = f;
27687                     return false;
27688                 }
27689             });
27690         }
27691         return field || null;
27692     },
27693
27694
27695     
27696     markInvalid : function(errors){
27697         if(Ext.isArray(errors)){
27698             for(var i = 0, len = errors.length; i < len; i++){
27699                 var fieldError = errors[i];
27700                 var f = this.findField(fieldError.id);
27701                 if(f){
27702                     f.markInvalid(fieldError.msg);
27703                 }
27704             }
27705         }else{
27706             var field, id;
27707             for(id in errors){
27708                 if(typeof errors[id] != 'function' && (field = this.findField(id))){
27709                     field.markInvalid(errors[id]);
27710                 }
27711             }
27712         }
27713         return this;
27714     },
27715
27716     
27717     setValues : function(values){
27718         if(Ext.isArray(values)){             for(var i = 0, len = values.length; i < len; i++){
27719                 var v = values[i];
27720                 var f = this.findField(v.id);
27721                 if(f){
27722                     f.setValue(v.value);
27723                     if(this.trackResetOnLoad){
27724                         f.originalValue = f.getValue();
27725                     }
27726                 }
27727             }
27728         }else{             var field, id;
27729             for(id in values){
27730                 if(typeof values[id] != 'function' && (field = this.findField(id))){
27731                     field.setValue(values[id]);
27732                     if(this.trackResetOnLoad){
27733                         field.originalValue = field.getValue();
27734                     }
27735                 }
27736             }
27737         }
27738         return this;
27739     },
27740
27741     
27742     getValues : function(asString){
27743         var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
27744         if(asString === true){
27745             return fs;
27746         }
27747         return Ext.urlDecode(fs);
27748     },
27749
27750     
27751     clearInvalid : function(){
27752         this.items.each(function(f){
27753            f.clearInvalid();
27754         });
27755         return this;
27756     },
27757
27758     
27759     reset : function(){
27760         this.items.each(function(f){
27761             f.reset();
27762         });
27763         return this;
27764     },
27765
27766     
27767     add : function(){
27768         this.items.addAll(Array.prototype.slice.call(arguments, 0));
27769         return this;
27770     },
27771
27772
27773     
27774     remove : function(field){
27775         this.items.remove(field);
27776         return this;
27777     },
27778
27779     
27780     render : function(){
27781         this.items.each(function(f){
27782             if(f.isFormField && !f.rendered && document.getElementById(f.id)){                 f.applyToMarkup(f.id);
27783             }
27784         });
27785         return this;
27786     },
27787
27788     
27789     applyToFields : function(o){
27790         this.items.each(function(f){
27791            Ext.apply(f, o);
27792         });
27793         return this;
27794     },
27795
27796     
27797     applyIfToFields : function(o){
27798         this.items.each(function(f){
27799            Ext.applyIf(f, o);
27800         });
27801         return this;
27802     }
27803 });
27804
27805 Ext.BasicForm = Ext.form.BasicForm;
27806
27807 Ext.FormPanel = Ext.extend(Ext.Panel, {
27808         
27809     
27810     
27811     
27812     buttonAlign:'center',
27813
27814     
27815     minButtonWidth:75,
27816
27817     
27818     labelAlign:'left',
27819
27820     
27821     monitorValid : false,
27822
27823     
27824     monitorPoll : 200,
27825
27826     
27827     layout: 'form',
27828
27829         initComponent :function(){
27830         this.form = this.createForm();
27831         
27832         Ext.FormPanel.superclass.initComponent.call(this);
27833
27834         this.addEvents(
27835             
27836             'clientvalidation'
27837         );
27838
27839         this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
27840     },
27841
27842         createForm: function(){
27843         delete this.initialConfig.listeners;
27844         return new Ext.form.BasicForm(null, this.initialConfig);
27845     },
27846
27847         initFields : function(){
27848         var f = this.form;
27849         var formPanel = this;
27850         var fn = function(c){
27851             if(c.doLayout && c != formPanel){
27852                 Ext.applyIf(c, {
27853                     labelAlign: c.ownerCt.labelAlign,
27854                     labelWidth: c.ownerCt.labelWidth,
27855                     itemCls: c.ownerCt.itemCls
27856                 });
27857                 if(c.items){
27858                     c.items.each(fn);
27859                 }
27860             }else if(c.isFormField){
27861                 f.add(c);
27862             }
27863         }
27864         this.items.each(fn);
27865     },
27866
27867         getLayoutTarget : function(){
27868         return this.form.el;
27869     },
27870
27871     
27872     getForm : function(){
27873         return this.form;
27874     },
27875
27876         onRender : function(ct, position){
27877         this.initFields();
27878
27879         Ext.FormPanel.superclass.onRender.call(this, ct, position);
27880         var o = {
27881             tag: 'form',
27882             method : this.method || 'POST',
27883             id : this.formId || Ext.id()
27884         };
27885         if(this.fileUpload) {
27886             o.enctype = 'multipart/form-data';
27887         }
27888         this.form.initEl(this.body.createChild(o));
27889     },
27890     
27891         beforeDestroy: function(){
27892         Ext.FormPanel.superclass.beforeDestroy.call(this);
27893         Ext.destroy(this.form);
27894     },
27895
27896         initEvents : function(){
27897         Ext.FormPanel.superclass.initEvents.call(this);
27898                 this.items.on('remove', this.onRemove, this);
27899                 this.items.on('add', this.onAdd, this);
27900         if(this.monitorValid){             this.startMonitoring();
27901         }
27902     },
27903     
27904         onAdd : function(ct, c) {
27905                 if (c.isFormField) {
27906                         this.form.add(c);
27907                 }
27908         },
27909         
27910                 onRemove : function(c) {
27911                 if (c.isFormField) {
27912                         Ext.destroy(c.container.up('.x-form-item'));
27913                         this.form.remove(c);
27914                 }
27915         },
27916
27917     
27918     startMonitoring : function(){
27919         if(!this.bound){
27920             this.bound = true;
27921             Ext.TaskMgr.start({
27922                 run : this.bindHandler,
27923                 interval : this.monitorPoll || 200,
27924                 scope: this
27925             });
27926         }
27927     },
27928
27929     
27930     stopMonitoring : function(){
27931         this.bound = false;
27932     },
27933
27934     
27935     load : function(){
27936         this.form.load.apply(this.form, arguments);  
27937     },
27938
27939         onDisable : function(){
27940         Ext.FormPanel.superclass.onDisable.call(this);
27941         if(this.form){
27942             this.form.items.each(function(){
27943                  this.disable();
27944             });
27945         }
27946     },
27947
27948         onEnable : function(){
27949         Ext.FormPanel.superclass.onEnable.call(this);
27950         if(this.form){
27951             this.form.items.each(function(){
27952                  this.enable();
27953             });
27954         }
27955     },
27956
27957         bindHandler : function(){
27958         if(!this.bound){
27959             return false;         }
27960         var valid = true;
27961         this.form.items.each(function(f){
27962             if(!f.isValid(true)){
27963                 valid = false;
27964                 return false;
27965             }
27966         });
27967         if(this.buttons){
27968             for(var i = 0, len = this.buttons.length; i < len; i++){
27969                 var btn = this.buttons[i];
27970                 if(btn.formBind === true && btn.disabled === valid){
27971                     btn.setDisabled(!valid);
27972                 }
27973             }
27974         }
27975         this.fireEvent('clientvalidation', this, valid);
27976     }
27977 });
27978 Ext.reg('form', Ext.FormPanel);
27979
27980 Ext.form.FormPanel = Ext.FormPanel;
27981
27982
27983 \r
27984 Ext.form.FieldSet = Ext.extend(Ext.Panel, {\r
27985     \r
27986     \r
27987     \r
27988     \r
27989     \r
27990     baseCls:'x-fieldset',\r
27991     \r
27992     layout: 'form',\r
27993 \r
27994     
27995     onRender : function(ct, position){\r
27996         if(!this.el){\r
27997             this.el = document.createElement('fieldset');\r
27998             this.el.id = this.id;\r
27999             if (this.title || this.header || this.checkboxToggle) {\r
28000                 this.el.appendChild(document.createElement('legend')).className = 'x-fieldset-header';\r
28001             }\r
28002         }\r
28003 \r
28004         Ext.form.FieldSet.superclass.onRender.call(this, ct, position);\r
28005 \r
28006         if(this.checkboxToggle){\r
28007             var o = typeof this.checkboxToggle == 'object' ?\r
28008                     this.checkboxToggle :\r
28009                     {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};\r
28010             this.checkbox = this.header.insertFirst(o);\r
28011             this.checkbox.dom.checked = !this.collapsed;\r
28012             this.checkbox.on('click', this.onCheckClick, this);\r
28013         }\r
28014     },\r
28015 \r
28016     
28017     onCollapse : function(doAnim, animArg){\r
28018         if(this.checkbox){\r
28019             this.checkbox.dom.checked = false;\r
28020         }\r
28021         this.afterCollapse();\r
28022 \r
28023     },\r
28024 \r
28025     
28026     onExpand : function(doAnim, animArg){\r
28027         if(this.checkbox){\r
28028             this.checkbox.dom.checked = true;\r
28029         }\r
28030         this.afterExpand();\r
28031     },\r
28032 \r
28033     \r
28034     onCheckClick : function(){\r
28035         this[this.checkbox.dom.checked ? 'expand' : 'collapse']();\r
28036     }\r
28037 \r
28038     \r
28039     \r
28040     \r
28041     \r
28042     \r
28043     \r
28044     \r
28045     \r
28046     \r
28047     \r
28048     \r
28049     \r
28050     \r
28051     \r
28052     \r
28053     \r
28054     \r
28055     \r
28056     \r
28057     \r
28058     \r
28059     \r
28060     \r
28061     \r
28062     \r
28063     \r
28064     \r
28065     \r
28066     \r
28067     \r
28068     \r
28069     \r
28070     \r
28071     \r
28072     \r
28073     \r
28074     \r
28075 });\r
28076 Ext.reg('fieldset', Ext.form.FieldSet);\r
28077 \r
28078
28079 \r
28080 \r
28081 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {\r
28082     \r
28083     enableFormat : true,\r
28084     \r
28085     enableFontSize : true,\r
28086     \r
28087     enableColors : true,\r
28088     \r
28089     enableAlignments : true,\r
28090     \r
28091     enableLists : true,\r
28092     \r
28093     enableSourceEdit : true,\r
28094     \r
28095     enableLinks : true,\r
28096     \r
28097     enableFont : true,\r
28098     \r
28099     createLinkText : 'Please enter the URL for the link:',\r
28100     \r
28101     defaultLinkValue : 'http:/'+'/',\r
28102     \r
28103     fontFamilies : [\r
28104         'Arial',\r
28105         'Courier New',\r
28106         'Tahoma',\r
28107         'Times New Roman',\r
28108         'Verdana'\r
28109     ],\r
28110     defaultFont: 'tahoma',\r
28111 \r
28112     
28113     validationEvent : false,\r
28114     deferHeight: true,\r
28115     initialized : false,\r
28116     activated : false,\r
28117     sourceEditMode : false,\r
28118     onFocus : Ext.emptyFn,\r
28119     iframePad:3,\r
28120     hideMode:'offsets',\r
28121     defaultAutoCreate : {\r
28122         tag: "textarea",\r
28123         style:"width:500px;height:300px;",\r
28124         autocomplete: "off"\r
28125     },\r
28126 \r
28127     
28128     initComponent : function(){\r
28129         this.addEvents(\r
28130             \r
28131             'initialize',\r
28132             \r
28133             'activate',\r
28134              \r
28135             'beforesync',\r
28136              \r
28137             'beforepush',\r
28138              \r
28139             'sync',\r
28140              \r
28141             'push',\r
28142              \r
28143             'editmodechange'\r
28144         )\r
28145     },\r
28146 \r
28147     createFontOptions : function(){\r
28148         var buf = [], fs = this.fontFamilies, ff, lc;\r
28149         for(var i = 0, len = fs.length; i< len; i++){\r
28150             ff = fs[i];\r
28151             lc = ff.toLowerCase();\r
28152             buf.push(\r
28153                 '<option value="',lc,'" style="font-family:',ff,';"',\r
28154                     (this.defaultFont == lc ? ' selected="true">' : '>'),\r
28155                     ff,\r
28156                 '</option>'\r
28157             );\r
28158         }\r
28159         return buf.join('');\r
28160     },\r
28161     \r
28162     createToolbar : function(editor){\r
28163 \r
28164         function btn(id, toggle, handler){\r
28165             return {\r
28166                 itemId : id,\r
28167                 cls : 'x-btn-icon x-edit-'+id,\r
28168                 enableToggle:toggle !== false,\r
28169                 scope: editor,\r
28170                 handler:handler||editor.relayBtnCmd,\r
28171                 clickEvent:'mousedown',\r
28172                 tooltip: editor.buttonTips[id] || undefined,\r
28173                 tabIndex:-1\r
28174             };\r
28175         }\r
28176 \r
28177         
28178         var tb = new Ext.Toolbar({\r
28179             renderTo:this.wrap.dom.firstChild\r
28180         });\r
28181 \r
28182         
28183         tb.el.on('click', function(e){\r
28184             e.preventDefault();\r
28185         });\r
28186 \r
28187         if(this.enableFont && !Ext.isSafari){\r
28188             this.fontSelect = tb.el.createChild({\r
28189                 tag:'select',\r
28190                 cls:'x-font-select',\r
28191                 html: this.createFontOptions()\r
28192             });\r
28193             this.fontSelect.on('change', function(){\r
28194                 var font = this.fontSelect.dom.value;\r
28195                 this.relayCmd('fontname', font);\r
28196                 this.deferFocus();\r
28197             }, this);\r
28198             tb.add(\r
28199                 this.fontSelect.dom,\r
28200                 '-'\r
28201             );\r
28202         };\r
28203 \r
28204         if(this.enableFormat){\r
28205             tb.add(\r
28206                 btn('bold'),\r
28207                 btn('italic'),\r
28208                 btn('underline')\r
28209             );\r
28210         };\r
28211 \r
28212         if(this.enableFontSize){\r
28213             tb.add(\r
28214                 '-',\r
28215                 btn('increasefontsize', false, this.adjustFont),\r
28216                 btn('decreasefontsize', false, this.adjustFont)\r
28217             );\r
28218         };\r
28219 \r
28220         if(this.enableColors){\r
28221             tb.add(\r
28222                 '-', {\r
28223                     itemId:'forecolor',\r
28224                     cls:'x-btn-icon x-edit-forecolor',\r
28225                     clickEvent:'mousedown',\r
28226                     tooltip: editor.buttonTips['forecolor'] || undefined,\r
28227                     tabIndex:-1,\r
28228                     menu : new Ext.menu.ColorMenu({\r
28229                         allowReselect: true,\r
28230                         focus: Ext.emptyFn,\r
28231                         value:'000000',\r
28232                         plain:true,\r
28233                         selectHandler: function(cp, color){\r
28234                             this.execCmd('forecolor', Ext.isSafari || Ext.isIE ? '#'+color : color);\r
28235                             this.deferFocus();\r
28236                         },\r
28237                         scope: this,\r
28238                         clickEvent:'mousedown'\r
28239                     })\r
28240                 }, {\r
28241                     itemId:'backcolor',\r
28242                     cls:'x-btn-icon x-edit-backcolor',\r
28243                     clickEvent:'mousedown',\r
28244                     tooltip: editor.buttonTips['backcolor'] || undefined,\r
28245                     tabIndex:-1,\r
28246                     menu : new Ext.menu.ColorMenu({\r
28247                         focus: Ext.emptyFn,\r
28248                         value:'FFFFFF',\r
28249                         plain:true,\r
28250                         allowReselect: true,\r
28251                         selectHandler: function(cp, color){\r
28252                             if(Ext.isGecko){\r
28253                                 this.execCmd('useCSS', false);\r
28254                                 this.execCmd('hilitecolor', color);\r
28255                                 this.execCmd('useCSS', true);\r
28256                                 this.deferFocus();\r
28257                             }else{\r
28258                                 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isSafari || Ext.isIE ? '#'+color : color);\r
28259                                 this.deferFocus();\r
28260                             }\r
28261                         },\r
28262                         scope:this,\r
28263                         clickEvent:'mousedown'\r
28264                     })\r
28265                 }\r
28266             );\r
28267         };\r
28268 \r
28269         if(this.enableAlignments){\r
28270             tb.add(\r
28271                 '-',\r
28272                 btn('justifyleft'),\r
28273                 btn('justifycenter'),\r
28274                 btn('justifyright')\r
28275             );\r
28276         };\r
28277 \r
28278         if(!Ext.isSafari){\r
28279             if(this.enableLinks){\r
28280                 tb.add(\r
28281                     '-',\r
28282                     btn('createlink', false, this.createLink)\r
28283                 );\r
28284             };\r
28285 \r
28286             if(this.enableLists){\r
28287                 tb.add(\r
28288                     '-',\r
28289                     btn('insertorderedlist'),\r
28290                     btn('insertunorderedlist')\r
28291                 );\r
28292             }\r
28293             if(this.enableSourceEdit){\r
28294                 tb.add(\r
28295                     '-',\r
28296                     btn('sourceedit', true, function(btn){\r
28297                         this.toggleSourceEdit(btn.pressed);\r
28298                     })\r
28299                 );\r
28300             }\r
28301         }\r
28302 \r
28303         this.tb = tb;\r
28304     },\r
28305 \r
28306     \r
28307     getDocMarkup : function(){\r
28308         return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';\r
28309     },\r
28310 \r
28311     getEditorBody : function(){\r
28312         return this.doc.body || this.doc.documentElement;\r
28313     },\r
28314 \r
28315     
28316     onRender : function(ct, position){\r
28317         Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);\r
28318         this.el.dom.style.border = '0 none';\r
28319         this.el.dom.setAttribute('tabIndex', -1);\r
28320         this.el.addClass('x-hidden');\r
28321         if(Ext.isIE){ 
28322             this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')\r
28323         }\r
28324         this.wrap = this.el.wrap({\r
28325             cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}\r
28326         });\r
28327 \r
28328         this.createToolbar(this);\r
28329 \r
28330         this.tb.items.each(function(item){\r
28331            if(item.itemId != 'sourceedit'){\r
28332                 item.disable();\r
28333             }\r
28334         });\r
28335 \r
28336         var iframe = document.createElement('iframe');\r
28337         iframe.name = Ext.id();\r
28338         iframe.frameBorder = 'no';\r
28339 \r
28340         iframe.src=(Ext.SSL_SECURE_URL || "javascript:false");\r
28341 \r
28342         this.wrap.dom.appendChild(iframe);\r
28343 \r
28344         this.iframe = iframe;\r
28345 \r
28346         if(Ext.isIE){\r
28347             iframe.contentWindow.document.designMode = 'on';\r
28348             this.doc = iframe.contentWindow.document;\r
28349             this.win = iframe.contentWindow;\r
28350         } else {\r
28351             this.doc = (iframe.contentDocument || window.frames[iframe.name].document);\r
28352             this.win = window.frames[iframe.name];\r
28353             this.doc.designMode = 'on';\r
28354         }\r
28355         this.doc.open();\r
28356         this.doc.write(this.getDocMarkup())\r
28357         this.doc.close();\r
28358 \r
28359         var task = { 
28360             run : function(){\r
28361                 if(this.doc.body || this.doc.readyState == 'complete'){\r
28362                     Ext.TaskMgr.stop(task);\r
28363                     this.doc.designMode="on";\r
28364                     this.initEditor.defer(10, this);\r
28365                 }\r
28366             },\r
28367             interval : 10,\r
28368             duration:10000,\r
28369             scope: this\r
28370         };\r
28371         Ext.TaskMgr.start(task);\r
28372 \r
28373         if(!this.width){\r
28374             this.setSize(this.el.getSize());\r
28375         }\r
28376     },\r
28377 \r
28378     
28379     onResize : function(w, h){\r
28380         Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);\r
28381         if(this.el && this.iframe){\r
28382             if(typeof w == 'number'){\r
28383                 var aw = w - this.wrap.getFrameWidth('lr');\r
28384                 this.el.setWidth(this.adjustWidth('textarea', aw));\r
28385                 this.iframe.style.width = aw + 'px';\r
28386             }\r
28387             if(typeof h == 'number'){\r
28388                 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();\r
28389                 this.el.setHeight(this.adjustWidth('textarea', ah));\r
28390                 this.iframe.style.height = ah + 'px';\r
28391                 if(this.doc){\r
28392                     this.getEditorBody().style.height = (ah - (this.iframePad*2)) + 'px';\r
28393                 }\r
28394             }\r
28395         }\r
28396     },\r
28397 \r
28398     \r
28399     toggleSourceEdit : function(sourceEditMode){\r
28400         if(sourceEditMode === undefined){\r
28401             sourceEditMode = !this.sourceEditMode;\r
28402         }\r
28403         this.sourceEditMode = sourceEditMode === true;\r
28404         var btn = this.tb.items.get('sourceedit');\r
28405         if(btn.pressed !== this.sourceEditMode){\r
28406             btn.toggle(this.sourceEditMode);\r
28407             return;\r
28408         }\r
28409         if(this.sourceEditMode){\r
28410             this.tb.items.each(function(item){\r
28411                 if(item.itemId != 'sourceedit'){\r
28412                     item.disable();\r
28413                 }\r
28414             });\r
28415             this.syncValue();\r
28416             this.iframe.className = 'x-hidden';\r
28417             this.el.removeClass('x-hidden');\r
28418             this.el.dom.removeAttribute('tabIndex');\r
28419             this.el.focus();\r
28420         }else{\r
28421             if(this.initialized){\r
28422                 this.tb.items.each(function(item){\r
28423                     item.enable();\r
28424                 });\r
28425             }\r
28426             this.pushValue();\r
28427             this.iframe.className = '';\r
28428             this.el.addClass('x-hidden');\r
28429             this.el.dom.setAttribute('tabIndex', -1);\r
28430             this.deferFocus();\r
28431         }\r
28432         var lastSize = this.lastSize;\r
28433         if(lastSize){\r
28434             delete this.lastSize;\r
28435             this.setSize(lastSize);\r
28436         }\r
28437         this.fireEvent('editmodechange', this, this.sourceEditMode);\r
28438     },\r
28439 \r
28440     
28441     createLink : function(){\r
28442         var url = prompt(this.createLinkText, this.defaultLinkValue);\r
28443         if(url && url != 'http:/'+'/'){\r
28444             this.relayCmd('createlink', url);\r
28445         }\r
28446     },\r
28447 \r
28448     
28449     adjustSize : Ext.BoxComponent.prototype.adjustSize,\r
28450 \r
28451     
28452     getResizeEl : function(){\r
28453         return this.wrap;\r
28454     },\r
28455 \r
28456     
28457     getPositionEl : function(){\r
28458         return this.wrap;\r
28459     },\r
28460 \r
28461     
28462     initEvents : function(){\r
28463         this.originalValue = this.getValue();\r
28464     },\r
28465 \r
28466     \r
28467     markInvalid : Ext.emptyFn,\r
28468     \r
28469     clearInvalid : Ext.emptyFn,\r
28470 \r
28471     setValue : function(v){\r
28472         Ext.form.HtmlEditor.superclass.setValue.call(this, v);\r
28473         this.pushValue();\r
28474     },\r
28475 \r
28476     \r
28477     cleanHtml : function(html){\r
28478         html = String(html);\r
28479         if(html.length > 5){\r
28480             if(Ext.isSafari){ 
28481                 html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');\r
28482             }\r
28483         }\r
28484         if(html == '&nbsp;'){\r
28485             html = '';\r
28486         }\r
28487         return html;\r
28488     },\r
28489 \r
28490     \r
28491     syncValue : function(){\r
28492         if(this.initialized){\r
28493             var bd = this.getEditorBody();\r
28494             var html = bd.innerHTML;\r
28495             if(Ext.isSafari){\r
28496                 var bs = bd.getAttribute('style'); 
28497                 var m = bs.match(/text-align:(.*?);/i);\r
28498                 if(m && m[1]){\r
28499                     html = '<div style="'+m[0]+'">' + html + '</div>';\r
28500                 }\r
28501             }\r
28502             html = this.cleanHtml(html);\r
28503             if(this.fireEvent('beforesync', this, html) !== false){\r
28504                 this.el.dom.value = html;\r
28505                 this.fireEvent('sync', this, html);\r
28506             }\r
28507         }\r
28508     },\r
28509 \r
28510     \r
28511     pushValue : function(){\r
28512         if(this.initialized){\r
28513             var v = this.el.dom.value;\r
28514             if(!this.activated && v.length < 1){\r
28515                 v = '&nbsp;';\r
28516             }\r
28517             if(this.fireEvent('beforepush', this, v) !== false){\r
28518                 this.getEditorBody().innerHTML = v;\r
28519                 this.fireEvent('push', this, v);\r
28520             }\r
28521         }\r
28522     },\r
28523 \r
28524     
28525     deferFocus : function(){\r
28526         this.focus.defer(10, this);\r
28527     },\r
28528 \r
28529     
28530     focus : function(){\r
28531         if(this.win && !this.sourceEditMode){\r
28532             this.win.focus();\r
28533         }else{\r
28534             this.el.focus();\r
28535         }\r
28536     },\r
28537 \r
28538     
28539     initEditor : function(){\r
28540         var dbody = this.getEditorBody();\r
28541         var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');\r
28542         ss['background-attachment'] = 'fixed'; 
28543         dbody.bgProperties = 'fixed'; 
28544         Ext.DomHelper.applyStyles(dbody, ss);\r
28545         Ext.EventManager.on(this.doc, {\r
28546             'mousedown': this.onEditorEvent,\r
28547             'dblclick': this.onEditorEvent,\r
28548             'click': this.onEditorEvent,\r
28549             'keyup': this.onEditorEvent,\r
28550             buffer:100,\r
28551             scope: this\r
28552         });\r
28553         if(Ext.isGecko){\r
28554             Ext.EventManager.on(this.doc, 'keypress', this.applyCommand, this);\r
28555         }\r
28556         if(Ext.isIE || Ext.isSafari || Ext.isOpera){\r
28557             Ext.EventManager.on(this.doc, 'keydown', this.fixKeys, this);\r
28558         }\r
28559         this.initialized = true;\r
28560 \r
28561         this.fireEvent('initialize', this);\r
28562         this.pushValue();\r
28563     },\r
28564 \r
28565     
28566     onDestroy : function(){\r
28567         if(this.rendered){\r
28568             this.tb.items.each(function(item){\r
28569                 if(item.menu){\r
28570                     item.menu.removeAll();\r
28571                     if(item.menu.el){\r
28572                         item.menu.el.destroy();\r
28573                     }\r
28574                 }\r
28575                 item.destroy();\r
28576             });\r
28577             this.wrap.dom.innerHTML = '';\r
28578             this.wrap.remove();\r
28579         }\r
28580     },\r
28581 \r
28582     
28583     onFirstFocus : function(){\r
28584         this.activated = true;\r
28585         this.tb.items.each(function(item){\r
28586            item.enable();\r
28587         });\r
28588         if(Ext.isGecko){ 
28589             this.win.focus();\r
28590             var s = this.win.getSelection();\r
28591             if(!s.focusNode || s.focusNode.nodeType != 3){\r
28592                 var r = s.getRangeAt(0);\r
28593                 r.selectNodeContents(this.getEditorBody());\r
28594                 r.collapse(true);\r
28595                 this.deferFocus();\r
28596             }\r
28597             try{\r
28598                 this.execCmd('useCSS', true);\r
28599                 this.execCmd('styleWithCSS', false);\r
28600             }catch(e){}\r
28601         }\r
28602         this.fireEvent('activate', this);\r
28603     },\r
28604 \r
28605     
28606     adjustFont: function(btn){\r
28607         var adjust = btn.itemId == 'increasefontsize' ? 1 : -1;\r
28608 \r
28609         var v = parseInt(this.doc.queryCommandValue('FontSize') || 2, 10);\r
28610         if(Ext.isSafari3 || Ext.isAir){\r
28611             
28612             
28613             if(v <= 10){\r
28614                 v = 1 + adjust;\r
28615             }else if(v <= 13){\r
28616                 v = 2 + adjust;\r
28617             }else if(v <= 16){\r
28618                 v = 3 + adjust;\r
28619             }else if(v <= 18){\r
28620                 v = 4 + adjust;\r
28621             }else if(v <= 24){\r
28622                 v = 5 + adjust;\r
28623             }else {\r
28624                 v = 6 + adjust;\r
28625             }\r
28626             v = v.constrain(1, 6);\r
28627         }else{\r
28628             if(Ext.isSafari){ 
28629                 adjust *= 2;\r
28630             }\r
28631             v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);\r
28632         }\r
28633         this.execCmd('FontSize', v);\r
28634     },\r
28635 \r
28636     onEditorEvent : function(e){\r
28637         this.updateToolbar();\r
28638     },\r
28639 \r
28640 \r
28641     \r
28642     updateToolbar: function(){\r
28643 \r
28644         if(!this.activated){\r
28645             this.onFirstFocus();\r
28646             return;\r
28647         }\r
28648 \r
28649         var btns = this.tb.items.map, doc = this.doc;\r
28650 \r
28651         if(this.enableFont && !Ext.isSafari){\r
28652             var name = (this.doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();\r
28653             if(name != this.fontSelect.dom.value){\r
28654                 this.fontSelect.dom.value = name;\r
28655             }\r
28656         }\r
28657         if(this.enableFormat){\r
28658             btns.bold.toggle(doc.queryCommandState('bold'));\r
28659             btns.italic.toggle(doc.queryCommandState('italic'));\r
28660             btns.underline.toggle(doc.queryCommandState('underline'));\r
28661         }\r
28662         if(this.enableAlignments){\r
28663             btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));\r
28664             btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));\r
28665             btns.justifyright.toggle(doc.queryCommandState('justifyright'));\r
28666         }\r
28667         if(!Ext.isSafari && this.enableLists){\r
28668             btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));\r
28669             btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));\r
28670         }\r
28671         \r
28672         Ext.menu.MenuMgr.hideAll();\r
28673 \r
28674         this.syncValue();\r
28675     },\r
28676 \r
28677     
28678     relayBtnCmd : function(btn){\r
28679         this.relayCmd(btn.itemId);\r
28680     },\r
28681 \r
28682     \r
28683     relayCmd : function(cmd, value){\r
28684         this.win.focus();\r
28685         this.execCmd(cmd, value);\r
28686         this.updateToolbar();\r
28687         this.deferFocus();\r
28688     },\r
28689 \r
28690     \r
28691     execCmd : function(cmd, value){\r
28692         this.doc.execCommand(cmd, false, value === undefined ? null : value);\r
28693         this.syncValue();\r
28694     },\r
28695 \r
28696     
28697     applyCommand : function(e){\r
28698         if(e.ctrlKey){\r
28699             var c = e.getCharCode(), cmd;\r
28700             if(c > 0){\r
28701                 c = String.fromCharCode(c);\r
28702                 switch(c){\r
28703                     case 'b':\r
28704                         cmd = 'bold';\r
28705                     break;\r
28706                     case 'i':\r
28707                         cmd = 'italic';\r
28708                     break;\r
28709                     case 'u':\r
28710                         cmd = 'underline';\r
28711                     break;\r
28712                 }\r
28713                 if(cmd){\r
28714                     this.win.focus();\r
28715                     this.execCmd(cmd);\r
28716                     this.deferFocus();\r
28717                     e.preventDefault();\r
28718                 }\r
28719             }\r
28720         }\r
28721     },\r
28722 \r
28723     \r
28724     insertAtCursor : function(text){\r
28725         if(!this.activated){\r
28726             return;\r
28727         }\r
28728         if(Ext.isIE){\r
28729             this.win.focus();\r
28730             var r = this.doc.selection.createRange();\r
28731             if(r){\r
28732                 r.collapse(true);\r
28733                 r.pasteHTML(text);\r
28734                 this.syncValue();\r
28735                 this.deferFocus();\r
28736             }\r
28737         }else if(Ext.isGecko || Ext.isOpera){\r
28738             this.win.focus();\r
28739             this.execCmd('InsertHTML', text);\r
28740             this.deferFocus();\r
28741         }else if(Ext.isSafari){\r
28742             this.execCmd('InsertText', text);\r
28743             this.deferFocus();\r
28744         }\r
28745     },\r
28746 \r
28747     
28748     fixKeys : function(){ 
28749         if(Ext.isIE){\r
28750             return function(e){\r
28751                 var k = e.getKey(), r;\r
28752                 if(k == e.TAB){\r
28753                     e.stopEvent();\r
28754                     r = this.doc.selection.createRange();\r
28755                     if(r){\r
28756                         r.collapse(true);\r
28757                         r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;');\r
28758                         this.deferFocus();\r
28759                     }\r
28760                 }else if(k == e.ENTER){\r
28761                     r = this.doc.selection.createRange();\r
28762                     if(r){\r
28763                         var target = r.parentElement();\r
28764                         if(!target || target.tagName.toLowerCase() != 'li'){\r
28765                             e.stopEvent();\r
28766                             r.pasteHTML('<br />');\r
28767                             r.collapse(false);\r
28768                             r.select();\r
28769                         }\r
28770                     }\r
28771                 }\r
28772             };\r
28773         }else if(Ext.isOpera){\r
28774             return function(e){\r
28775                 var k = e.getKey();\r
28776                 if(k == e.TAB){\r
28777                     e.stopEvent();\r
28778                     this.win.focus();\r
28779                     this.execCmd('InsertHTML','&nbsp;&nbsp;&nbsp;&nbsp;');\r
28780                     this.deferFocus();\r
28781                 }\r
28782             };\r
28783         }else if(Ext.isSafari){\r
28784             return function(e){\r
28785                 var k = e.getKey();\r
28786                 if(k == e.TAB){\r
28787                     e.stopEvent();\r
28788                     this.execCmd('InsertText','\t');\r
28789                     this.deferFocus();\r
28790                 }\r
28791              };\r
28792         }\r
28793     }(),\r
28794 \r
28795     \r
28796     getToolbar : function(){\r
28797         return this.tb;\r
28798     },\r
28799 \r
28800     \r
28801     buttonTips : {\r
28802         bold : {\r
28803             title: 'Bold (Ctrl+B)',\r
28804             text: 'Make the selected text bold.',\r
28805             cls: 'x-html-editor-tip'\r
28806         },\r
28807         italic : {\r
28808             title: 'Italic (Ctrl+I)',\r
28809             text: 'Make the selected text italic.',\r
28810             cls: 'x-html-editor-tip'\r
28811         },\r
28812         underline : {\r
28813             title: 'Underline (Ctrl+U)',\r
28814             text: 'Underline the selected text.',\r
28815             cls: 'x-html-editor-tip'\r
28816         },\r
28817         increasefontsize : {\r
28818             title: 'Grow Text',\r
28819             text: 'Increase the font size.',\r
28820             cls: 'x-html-editor-tip'\r
28821         },\r
28822         decreasefontsize : {\r
28823             title: 'Shrink Text',\r
28824             text: 'Decrease the font size.',\r
28825             cls: 'x-html-editor-tip'\r
28826         },\r
28827         backcolor : {\r
28828             title: 'Text Highlight Color',\r
28829             text: 'Change the background color of the selected text.',\r
28830             cls: 'x-html-editor-tip'\r
28831         },\r
28832         forecolor : {\r
28833             title: 'Font Color',\r
28834             text: 'Change the color of the selected text.',\r
28835             cls: 'x-html-editor-tip'\r
28836         },\r
28837         justifyleft : {\r
28838             title: 'Align Text Left',\r
28839             text: 'Align text to the left.',\r
28840             cls: 'x-html-editor-tip'\r
28841         },\r
28842         justifycenter : {\r
28843             title: 'Center Text',\r
28844             text: 'Center text in the editor.',\r
28845             cls: 'x-html-editor-tip'\r
28846         },\r
28847         justifyright : {\r
28848             title: 'Align Text Right',\r
28849             text: 'Align text to the right.',\r
28850             cls: 'x-html-editor-tip'\r
28851         },\r
28852         insertunorderedlist : {\r
28853             title: 'Bullet List',\r
28854             text: 'Start a bulleted list.',\r
28855             cls: 'x-html-editor-tip'\r
28856         },\r
28857         insertorderedlist : {\r
28858             title: 'Numbered List',\r
28859             text: 'Start a numbered list.',\r
28860             cls: 'x-html-editor-tip'\r
28861         },\r
28862         createlink : {\r
28863             title: 'Hyperlink',\r
28864             text: 'Make the selected text a hyperlink.',\r
28865             cls: 'x-html-editor-tip'\r
28866         },\r
28867         sourceedit : {\r
28868             title: 'Source Edit',\r
28869             text: 'Switch to source editing mode.',\r
28870             cls: 'x-html-editor-tip'\r
28871         }\r
28872     }\r
28873 \r
28874     
28875     \r
28876     \r
28877     \r
28878     \r
28879     \r
28880     \r
28881     \r
28882     \r
28883     \r
28884     \r
28885     \r
28886     \r
28887     \r
28888     \r
28889     \r
28890     \r
28891     \r
28892     \r
28893     \r
28894     \r
28895     \r
28896     \r
28897     \r
28898     \r
28899     \r
28900     \r
28901     \r
28902     \r
28903     \r
28904     \r
28905     \r
28906     \r
28907 });\r
28908 Ext.reg('htmleditor', Ext.form.HtmlEditor);
28909 \r
28910 Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {\r
28911     \r
28912     minValue : null,\r
28913     \r
28914     maxValue : null,\r
28915     \r
28916     minText : "The time in this field must be equal to or after {0}",\r
28917     \r
28918     maxText : "The time in this field must be equal to or before {0}",\r
28919     \r
28920     invalidText : "{0} is not a valid time",\r
28921     \r
28922     format : "g:i A",\r
28923     \r
28924     altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H",\r
28925     \r
28926     increment: 15,\r
28927 \r
28928     
28929     mode: 'local',\r
28930     
28931     triggerAction: 'all',\r
28932     
28933     typeAhead: false,\r
28934 \r
28935     
28936     initComponent : function(){\r
28937         Ext.form.TimeField.superclass.initComponent.call(this);\r
28938 \r
28939         if(typeof this.minValue == "string"){\r
28940             this.minValue = this.parseDate(this.minValue);\r
28941         }\r
28942         if(typeof this.maxValue == "string"){\r
28943             this.maxValue = this.parseDate(this.maxValue);\r
28944         }\r
28945 \r
28946         if(!this.store){\r
28947             var min = this.parseDate(this.minValue);\r
28948             if(!min){\r
28949                 min = new Date().clearTime();\r
28950             }\r
28951             var max = this.parseDate(this.maxValue);\r
28952             if(!max){\r
28953                 max = new Date().clearTime().add('mi', (24 * 60) - 1);\r
28954             }\r
28955             var times = [];\r
28956             while(min <= max){\r
28957                 times.push([min.dateFormat(this.format)]);\r
28958                 min = min.add('mi', this.increment);\r
28959             }\r
28960             this.store = new Ext.data.SimpleStore({\r
28961                 fields: ['text'],\r
28962                 data : times\r
28963             });\r
28964             this.displayField = 'text';\r
28965         }\r
28966     },\r
28967 \r
28968     
28969     getValue : function(){\r
28970         var v = Ext.form.TimeField.superclass.getValue.call(this);\r
28971         return this.formatDate(this.parseDate(v)) || '';\r
28972     },\r
28973 \r
28974     
28975     setValue : function(value){\r
28976         Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));\r
28977     },\r
28978 \r
28979     
28980     validateValue : Ext.form.DateField.prototype.validateValue,\r
28981     parseDate : Ext.form.DateField.prototype.parseDate,\r
28982     formatDate : Ext.form.DateField.prototype.formatDate,\r
28983 \r
28984     
28985     beforeBlur : function(){\r
28986         var v = this.parseDate(this.getRawValue());\r
28987         if(v){\r
28988             this.setValue(v.dateFormat(this.format));\r
28989         }\r
28990     }\r
28991 \r
28992     \r
28993     \r
28994     \r
28995     \r
28996 });\r
28997 Ext.reg('timefield', Ext.form.TimeField);
28998 Ext.form.Label = Ext.extend(Ext.BoxComponent, {\r
28999     onRender : function(ct, position){\r
29000         if(!this.el){\r
29001             this.el = document.createElement('label');\r
29002             this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');\r
29003             if(this.forId){\r
29004                 this.el.setAttribute('htmlFor', this.forId);\r
29005             }\r
29006         }\r
29007         Ext.form.Label.superclass.onRender.call(this, ct, position);\r
29008     }\r
29009 });\r
29010 \r
29011 Ext.reg('label', Ext.form.Label);
29012
29013 Ext.form.Action = function(form, options){
29014     this.form = form;
29015     this.options = options || {};
29016 };
29017
29018
29019 Ext.form.Action.CLIENT_INVALID = 'client';
29020
29021 Ext.form.Action.SERVER_INVALID = 'server';
29022
29023 Ext.form.Action.CONNECT_FAILURE = 'connect';
29024
29025 Ext.form.Action.LOAD_FAILURE = 'load';
29026
29027 Ext.form.Action.prototype = {
29028
29029
29030
29031
29032
29033
29034
29035
29036
29037
29038     type : 'default',
29039
29040
29041         run : function(options){
29042
29043     },
29044
29045         success : function(response){
29046
29047     },
29048
29049         handleResponse : function(response){
29050
29051     },
29052
29053         failure : function(response){
29054         this.response = response;
29055         this.failureType = Ext.form.Action.CONNECT_FAILURE;
29056         this.form.afterAction(this, false);
29057     },
29058
29059         processResponse : function(response){
29060         this.response = response;
29061         if(!response.responseText){
29062             return true;
29063         }
29064         this.result = this.handleResponse(response);
29065         return this.result;
29066     },
29067
29068         getUrl : function(appendParams){
29069         var url = this.options.url || this.form.url || this.form.el.dom.action;
29070         if(appendParams){
29071             var p = this.getParams();
29072             if(p){
29073                 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
29074             }
29075         }
29076         return url;
29077     },
29078
29079         getMethod : function(){
29080         return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
29081     },
29082
29083         getParams : function(){
29084         var bp = this.form.baseParams;
29085         var p = this.options.params;
29086         if(p){
29087             if(typeof p == "object"){
29088                 p = Ext.urlEncode(Ext.applyIf(p, bp));
29089             }else if(typeof p == 'string' && bp){
29090                 p += '&' + Ext.urlEncode(bp);
29091             }
29092         }else if(bp){
29093             p = Ext.urlEncode(bp);
29094         }
29095         return p;
29096     },
29097
29098         createCallback : function(opts){
29099                 var opts = opts || {};
29100         return {
29101             success: this.success,
29102             failure: this.failure,
29103             scope: this,
29104             timeout: (opts.timeout*1000) || (this.form.timeout*1000),
29105             upload: this.form.fileUpload ? this.success : undefined
29106         };
29107     }
29108 };
29109
29110
29111 Ext.form.Action.Submit = function(form, options){
29112     Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
29113 };
29114
29115 Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
29116     
29117     type : 'submit',
29118
29119         run : function(){
29120         var o = this.options;
29121         var method = this.getMethod();
29122         var isPost = method == 'POST';
29123         if(o.clientValidation === false || this.form.isValid()){
29124             Ext.Ajax.request(Ext.apply(this.createCallback(o), {
29125                 form:this.form.el.dom,
29126                 url:this.getUrl(!isPost),
29127                 method: method,
29128                 params:isPost ? this.getParams() : null,
29129                 isUpload: this.form.fileUpload
29130             }));
29131
29132         }else if (o.clientValidation !== false){             this.failureType = Ext.form.Action.CLIENT_INVALID;
29133             this.form.afterAction(this, false);
29134         }
29135     },
29136
29137         success : function(response){
29138         var result = this.processResponse(response);
29139         if(result === true || result.success){
29140             this.form.afterAction(this, true);
29141             return;
29142         }
29143         if(result.errors){
29144             this.form.markInvalid(result.errors);
29145             this.failureType = Ext.form.Action.SERVER_INVALID;
29146         }
29147         this.form.afterAction(this, false);
29148     },
29149
29150         handleResponse : function(response){
29151         if(this.form.errorReader){
29152             var rs = this.form.errorReader.read(response);
29153             var errors = [];
29154             if(rs.records){
29155                 for(var i = 0, len = rs.records.length; i < len; i++) {
29156                     var r = rs.records[i];
29157                     errors[i] = r.data;
29158                 }
29159             }
29160             if(errors.length < 1){
29161                 errors = null;
29162             }
29163             return {
29164                 success : rs.success,
29165                 errors : errors
29166             };
29167         }
29168         return Ext.decode(response.responseText);
29169     }
29170 });
29171
29172
29173
29174 Ext.form.Action.Load = function(form, options){
29175     Ext.form.Action.Load.superclass.constructor.call(this, form, options);
29176     this.reader = this.form.reader;
29177 };
29178
29179 Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
29180         type : 'load',
29181
29182         run : function(){
29183         Ext.Ajax.request(Ext.apply(
29184                 this.createCallback(this.options), {
29185                     method:this.getMethod(),
29186                     url:this.getUrl(false),
29187                     params:this.getParams()
29188         }));
29189     },
29190
29191         success : function(response){
29192         var result = this.processResponse(response);
29193         if(result === true || !result.success || !result.data){
29194             this.failureType = Ext.form.Action.LOAD_FAILURE;
29195             this.form.afterAction(this, false);
29196             return;
29197         }
29198         this.form.clearInvalid();
29199         this.form.setValues(result.data);
29200         this.form.afterAction(this, true);
29201     },
29202
29203         handleResponse : function(response){
29204         if(this.form.reader){
29205             var rs = this.form.reader.read(response);
29206             var data = rs.records && rs.records[0] ? rs.records[0].data : null;
29207             return {
29208                 success : rs.success,
29209                 data : data
29210             };
29211         }
29212         return Ext.decode(response.responseText);
29213     }
29214 });
29215
29216 Ext.form.Action.ACTION_TYPES = {
29217     'load' : Ext.form.Action.Load,
29218     'submit' : Ext.form.Action.Submit
29219 };
29220
29221
29222 Ext.form.VTypes = function(){
29223         var alpha = /^[a-zA-Z_]+$/;
29224     var alphanum = /^[a-zA-Z0-9_]+$/;
29225     var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
29226     var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
29227
29228         return {
29229         
29230         'email' : function(v){
29231             return email.test(v);
29232         },
29233         
29234         'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
29235         
29236         'emailMask' : /[a-z0-9_\.\-@]/i,
29237
29238         
29239         'url' : function(v){
29240             return url.test(v);
29241         },
29242         
29243         'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
29244         
29245         
29246         'alpha' : function(v){
29247             return alpha.test(v);
29248         },
29249         
29250         'alphaText' : 'This field should only contain letters and _',
29251         
29252         'alphaMask' : /[a-z_]/i,
29253
29254         
29255         'alphanum' : function(v){
29256             return alphanum.test(v);
29257         },
29258         
29259         'alphanumText' : 'This field should only contain letters, numbers and _',
29260         
29261         'alphanumMask' : /[a-z0-9_]/i
29262     };
29263 }();
29264 \r
29265 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {\r
29266     \r
29267     \r
29268     \r
29269     \r
29270     \r
29271     \r
29272     \r
29273     \r
29274     \r
29275     \r
29276     \r
29277 \r
29278     \r
29279     ddText : "{0} selected row{1}",\r
29280     \r
29281     minColumnWidth : 25,\r
29282     \r
29283     trackMouseOver : true,\r
29284     \r
29285     enableDragDrop : false,\r
29286     \r
29287     enableColumnMove : true,\r
29288     \r
29289     enableColumnHide : true,\r
29290     \r
29291     enableHdMenu : true,\r
29292     \r
29293     stripeRows : false,\r
29294     \r
29295     autoExpandColumn : false,\r
29296     \r
29297     autoExpandMin : 50,\r
29298     \r
29299     autoExpandMax : 1000,\r
29300     \r
29301     view : null,\r
29302     \r
29303     loadMask : false,\r
29304 \r
29305     
29306     rendered : false,\r
29307     
29308     viewReady: false,\r
29309     
29310     stateEvents: ["columnmove", "columnresize", "sortchange"],\r
29311 \r
29312     
29313     initComponent : function(){\r
29314         Ext.grid.GridPanel.superclass.initComponent.call(this);\r
29315 \r
29316         
29317         
29318         this.autoScroll = false;\r
29319         this.autoWidth = false;\r
29320 \r
29321         if(Ext.isArray(this.columns)){\r
29322             this.colModel = new Ext.grid.ColumnModel(this.columns);\r
29323             delete this.columns;\r
29324         }\r
29325 \r
29326         
29327         if(this.ds){\r
29328             this.store = this.ds;\r
29329             delete this.ds;\r
29330         }\r
29331         if(this.cm){\r
29332             this.colModel = this.cm;\r
29333             delete this.cm;\r
29334         }\r
29335         if(this.sm){\r
29336             this.selModel = this.sm;\r
29337             delete this.sm;\r
29338         }\r
29339         this.store = Ext.StoreMgr.lookup(this.store);\r
29340 \r
29341         this.addEvents(\r
29342             
29343             \r
29344             "click",\r
29345             \r
29346             "dblclick",\r
29347             \r
29348             "contextmenu",\r
29349             \r
29350             "mousedown",\r
29351             \r
29352             "mouseup",\r
29353             \r
29354             "mouseover",\r
29355             \r
29356             "mouseout",\r
29357             \r
29358             "keypress",\r
29359             \r
29360             "keydown",\r
29361 \r
29362             
29363             \r
29364             "cellmousedown",\r
29365             \r
29366             "rowmousedown",\r
29367             \r
29368             "headermousedown",\r
29369 \r
29370             \r
29371             "cellclick",\r
29372             \r
29373             "celldblclick",\r
29374             \r
29375             "rowclick",\r
29376             \r
29377             "rowdblclick",\r
29378             \r
29379             "headerclick",\r
29380             \r
29381             "headerdblclick",\r
29382             \r
29383             "rowcontextmenu",\r
29384             \r
29385             "cellcontextmenu",\r
29386             \r
29387             "headercontextmenu",\r
29388             \r
29389             "bodyscroll",\r
29390             \r
29391             "columnresize",\r
29392             \r
29393             "columnmove",\r
29394             \r
29395             "sortchange"\r
29396         );\r
29397     },\r
29398 \r
29399     
29400     onRender : function(ct, position){\r
29401         Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);\r
29402 \r
29403         var c = this.body;\r
29404 \r
29405         this.el.addClass('x-grid-panel');\r
29406 \r
29407         var view = this.getView();\r
29408         view.init(this);\r
29409 \r
29410         c.on("mousedown", this.onMouseDown, this);\r
29411         c.on("click", this.onClick, this);\r
29412         c.on("dblclick", this.onDblClick, this);\r
29413         c.on("contextmenu", this.onContextMenu, this);\r
29414         c.on("keydown", this.onKeyDown, this);\r
29415 \r
29416         this.relayEvents(c, ["mousedown","mouseup","mouseover","mouseout","keypress"]);\r
29417 \r
29418         this.getSelectionModel().init(this);\r
29419         this.view.render();\r
29420     },\r
29421 \r
29422     
29423     initEvents : function(){\r
29424         Ext.grid.GridPanel.superclass.initEvents.call(this);\r
29425 \r
29426         if(this.loadMask){\r
29427             this.loadMask = new Ext.LoadMask(this.bwrap,\r
29428                     Ext.apply({store:this.store}, this.loadMask));\r
29429         }\r
29430     },\r
29431 \r
29432     initStateEvents : function(){\r
29433         Ext.grid.GridPanel.superclass.initStateEvents.call(this);\r
29434         this.colModel.on('hiddenchange', this.saveState, this, {delay: 100});\r
29435     },\r
29436 \r
29437     applyState : function(state){\r
29438         var cm = this.colModel;\r
29439         var cs = state.columns;\r
29440         if(cs){\r
29441             for(var i = 0, len = cs.length; i < len; i++){\r
29442                 var s = cs[i];\r
29443                 var c = cm.getColumnById(s.id);\r
29444                 if(c){\r
29445                     c.hidden = s.hidden;\r
29446                     c.width = s.width;\r
29447                     var oldIndex = cm.getIndexById(s.id);\r
29448                     if(oldIndex != i){\r
29449                         cm.moveColumn(oldIndex, i);\r
29450                     }\r
29451                 }\r
29452             }\r
29453         }\r
29454         if(state.sort){\r
29455             this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);\r
29456         }\r
29457     },\r
29458 \r
29459     getState : function(){\r
29460         var o = {columns: []};\r
29461         for(var i = 0, c; c = this.colModel.config[i]; i++){\r
29462             o.columns[i] = {\r
29463                 id: c.id,\r
29464                 width: c.width\r
29465             };\r
29466             if(c.hidden){\r
29467                 o.columns[i].hidden = true;\r
29468             }\r
29469         }\r
29470         var ss = this.store.getSortState();\r
29471         if(ss){\r
29472             o.sort = ss;\r
29473         }\r
29474         return o;\r
29475     },\r
29476 \r
29477     
29478     afterRender : function(){\r
29479         Ext.grid.GridPanel.superclass.afterRender.call(this);\r
29480         this.view.layout();\r
29481         this.viewReady = true;\r
29482     },\r
29483 \r
29484     \r
29485     reconfigure : function(store, colModel){\r
29486         if(this.loadMask){\r
29487             this.loadMask.destroy();\r
29488             this.loadMask = new Ext.LoadMask(this.bwrap,\r
29489                     Ext.apply({store:store}, this.initialConfig.loadMask));\r
29490         }\r
29491         this.view.bind(store, colModel);\r
29492         this.store = store;\r
29493         this.colModel = colModel;\r
29494         if(this.rendered){\r
29495             this.view.refresh(true);\r
29496         }\r
29497     },\r
29498 \r
29499     
29500     onKeyDown : function(e){\r
29501         this.fireEvent("keydown", e);\r
29502     },\r
29503 \r
29504     
29505     onDestroy : function(){\r
29506         if(this.rendered){\r
29507             if(this.loadMask){\r
29508                 this.loadMask.destroy();\r
29509             }\r
29510             var c = this.body;\r
29511             c.removeAllListeners();\r
29512             this.view.destroy();\r
29513             c.update("");\r
29514         }\r
29515         this.colModel.purgeListeners();\r
29516         Ext.grid.GridPanel.superclass.onDestroy.call(this);\r
29517     },\r
29518 \r
29519     
29520     processEvent : function(name, e){\r
29521         this.fireEvent(name, e);\r
29522         var t = e.getTarget();\r
29523         var v = this.view;\r
29524         var header = v.findHeaderIndex(t);\r
29525         if(header !== false){\r
29526             this.fireEvent("header" + name, this, header, e);\r
29527         }else{\r
29528             var row = v.findRowIndex(t);\r
29529             var cell = v.findCellIndex(t);\r
29530             if(row !== false){\r
29531                 this.fireEvent("row" + name, this, row, e);\r
29532                 if(cell !== false){\r
29533                     this.fireEvent("cell" + name, this, row, cell, e);\r
29534                 }\r
29535             }\r
29536         }\r
29537     },\r
29538 \r
29539     
29540     onClick : function(e){\r
29541         this.processEvent("click", e);\r
29542     },\r
29543 \r
29544     
29545     onMouseDown : function(e){\r
29546         this.processEvent("mousedown", e);\r
29547     },\r
29548 \r
29549     
29550     onContextMenu : function(e, t){\r
29551         this.processEvent("contextmenu", e);\r
29552     },\r
29553 \r
29554     
29555     onDblClick : function(e){\r
29556         this.processEvent("dblclick", e);\r
29557     },\r
29558 \r
29559     
29560     walkCells : function(row, col, step, fn, scope){\r
29561         var cm = this.colModel, clen = cm.getColumnCount();\r
29562         var ds = this.store, rlen = ds.getCount(), first = true;\r
29563         if(step < 0){\r
29564             if(col < 0){\r
29565                 row--;\r
29566                 first = false;\r
29567             }\r
29568             while(row >= 0){\r
29569                 if(!first){\r
29570                     col = clen-1;\r
29571                 }\r
29572                 first = false;\r
29573                 while(col >= 0){\r
29574                     if(fn.call(scope || this, row, col, cm) === true){\r
29575                         return [row, col];\r
29576                     }\r
29577                     col--;\r
29578                 }\r
29579                 row--;\r
29580             }\r
29581         } else {\r
29582             if(col >= clen){\r
29583                 row++;\r
29584                 first = false;\r
29585             }\r
29586             while(row < rlen){\r
29587                 if(!first){\r
29588                     col = 0;\r
29589                 }\r
29590                 first = false;\r
29591                 while(col < clen){\r
29592                     if(fn.call(scope || this, row, col, cm) === true){\r
29593                         return [row, col];\r
29594                     }\r
29595                     col++;\r
29596                 }\r
29597                 row++;\r
29598             }\r
29599         }\r
29600         return null;\r
29601     },\r
29602 \r
29603     
29604     getSelections : function(){\r
29605         return this.selModel.getSelections();\r
29606     },\r
29607 \r
29608     
29609     onResize : function(){\r
29610         Ext.grid.GridPanel.superclass.onResize.apply(this, arguments);\r
29611         if(this.viewReady){\r
29612             this.view.layout();\r
29613         }\r
29614     },\r
29615 \r
29616     \r
29617     getGridEl : function(){\r
29618         return this.body;\r
29619     },\r
29620 \r
29621     
29622     stopEditing : function(){},\r
29623 \r
29624     \r
29625     getSelectionModel : function(){\r
29626         if(!this.selModel){\r
29627             this.selModel = new Ext.grid.RowSelectionModel(\r
29628                     this.disableSelection ? {selectRow: Ext.emptyFn} : null);\r
29629         }\r
29630         return this.selModel;\r
29631     },\r
29632 \r
29633     \r
29634     getStore : function(){\r
29635         return this.store;\r
29636     },\r
29637 \r
29638     \r
29639     getColumnModel : function(){\r
29640         return this.colModel;\r
29641     },\r
29642 \r
29643     \r
29644     getView : function(){\r
29645         if(!this.view){\r
29646             this.view = new Ext.grid.GridView(this.viewConfig);\r
29647         }\r
29648         return this.view;\r
29649     },\r
29650     \r
29651     getDragDropText : function(){\r
29652         var count = this.selModel.getCount();\r
29653         return String.format(this.ddText, count, count == 1 ? '' : 's');\r
29654     }\r
29655 \r
29656     \r
29657     \r
29658     \r
29659     \r
29660     \r
29661     \r
29662     \r
29663     \r
29664     \r
29665     \r
29666     \r
29667     \r
29668     \r
29669     \r
29670     \r
29671     \r
29672     \r
29673     \r
29674     \r
29675     \r
29676     \r
29677     \r
29678     \r
29679     \r
29680     \r
29681     \r
29682     \r
29683     \r
29684     \r
29685     \r
29686     \r
29687 \r
29688 \r
29689 \r
29690     \r
29691     \r
29692     \r
29693     \r
29694     \r
29695     \r
29696     \r
29697     \r
29698     \r
29699     \r
29700     \r
29701     \r
29702     \r
29703     \r
29704     \r
29705 });\r
29706 Ext.reg('grid', Ext.grid.GridPanel);
29707
29708 Ext.grid.GridView = function(config){
29709     Ext.apply(this, config);
29710         this.addEvents(
29711       
29712       "beforerowremoved",
29713       
29714       "beforerowsinserted",
29715       
29716       "beforerefresh",
29717       
29718       "rowremoved",
29719       
29720       "rowsinserted",
29721       
29722       "rowupdated",
29723       
29724       "refresh"
29725   );
29726     Ext.grid.GridView.superclass.constructor.call(this);
29727 };
29728
29729 Ext.extend(Ext.grid.GridView, Ext.util.Observable, {
29730     
29731     
29732     
29733     
29734     scrollOffset: 19,
29735     
29736     autoFill: false,
29737     
29738     forceFit: false,
29739     
29740     sortClasses : ["sort-asc", "sort-desc"],
29741     
29742     sortAscText : "Sort Ascending",
29743     
29744     sortDescText : "Sort Descending",
29745     
29746     columnsText : "Columns",
29747
29748         borderWidth: 2,
29749
29750     
29751
29752         initTemplates : function(){
29753         var ts = this.templates || {};
29754         if(!ts.master){
29755             ts.master = new Ext.Template(
29756                     '<div class="x-grid3" hidefocus="true">',
29757                         '<div class="x-grid3-viewport">',
29758                             '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset">{header}</div></div><div class="x-clear"></div></div>',
29759                             '<div class="x-grid3-scroller"><div class="x-grid3-body">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
29760                         "</div>",
29761                         '<div class="x-grid3-resize-marker">&#160;</div>',
29762                         '<div class="x-grid3-resize-proxy">&#160;</div>',
29763                     "</div>"
29764                     );
29765         }
29766
29767         if(!ts.header){
29768             ts.header = new Ext.Template(
29769                     '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
29770                     '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
29771                     "</table>"
29772                     );
29773         }
29774
29775         if(!ts.hcell){
29776             ts.hcell = new Ext.Template(
29777                     '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id}" style="{style}"><div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
29778                     '{value}<img class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
29779                     "</div></td>"
29780                     );
29781         }
29782
29783         if(!ts.body){
29784             ts.body = new Ext.Template('{rows}');
29785         }
29786
29787         if(!ts.row){
29788             ts.row = new Ext.Template(
29789                     '<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
29790                     '<tbody><tr>{cells}</tr>',
29791                     (this.enableRowBody ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>' : ''),
29792                     '</tbody></table></div>'
29793                     );
29794         }
29795
29796         if(!ts.cell){
29797             ts.cell = new Ext.Template(
29798                     '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
29799                     '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
29800                     "</td>"
29801                     );
29802         }
29803
29804         for(var k in ts){
29805             var t = ts[k];
29806             if(t && typeof t.compile == 'function' && !t.compiled){
29807                 t.disableFormats = true;
29808                 t.compile();
29809             }
29810         }
29811
29812         this.templates = ts;
29813
29814         this.tdClass = 'x-grid3-cell';
29815         this.cellSelector = 'td.x-grid3-cell';
29816         this.hdCls = 'x-grid3-hd';
29817         this.rowSelector = 'div.x-grid3-row';
29818         this.colRe = new RegExp("x-grid3-td-([^\\s]+)", "");
29819     },
29820
29821         fly : function(el){
29822         if(!this._flyweight){
29823             this._flyweight = new Ext.Element.Flyweight(document.body);
29824         }
29825         this._flyweight.dom = el;
29826         return this._flyweight;
29827     },
29828
29829         getEditorParent : function(ed){
29830         return this.scroller.dom;
29831     },
29832
29833         initElements : function(){
29834         var E = Ext.Element;
29835
29836         var el = this.grid.getGridEl().dom.firstChild;
29837         var cs = el.childNodes;
29838
29839         this.el = new E(el);
29840
29841         this.mainWrap = new E(cs[0]);
29842         this.mainHd = new E(this.mainWrap.dom.firstChild);
29843
29844         if(this.grid.hideHeaders){
29845             this.mainHd.setDisplayed(false);
29846         }
29847
29848         this.innerHd = this.mainHd.dom.firstChild;
29849         this.scroller = new E(this.mainWrap.dom.childNodes[1]);
29850         if(this.forceFit){
29851             this.scroller.setStyle('overflow-x', 'hidden');
29852         }
29853         this.mainBody = new E(this.scroller.dom.firstChild);
29854
29855         this.focusEl = new E(this.scroller.dom.childNodes[1]);
29856         this.focusEl.swallowEvent("click", true);
29857
29858         this.resizeMarker = new E(cs[1]);
29859         this.resizeProxy = new E(cs[2]);
29860     },
29861
29862         getRows : function(){
29863         return this.hasRows() ? this.mainBody.dom.childNodes : [];
29864     },
29865
29866     
29867         findCell : function(el){
29868         if(!el){
29869             return false;
29870         }
29871         return this.fly(el).findParent(this.cellSelector, 3);
29872     },
29873
29874         findCellIndex : function(el, requiredCls){
29875         var cell = this.findCell(el);
29876         if(cell && (!requiredCls || this.fly(cell).hasClass(requiredCls))){
29877             return this.getCellIndex(cell);
29878         }
29879         return false;
29880     },
29881
29882         getCellIndex : function(el){
29883         if(el){
29884             var m = el.className.match(this.colRe);
29885             if(m && m[1]){
29886                 return this.cm.getIndexById(m[1]);
29887             }
29888         }
29889         return false;
29890     },
29891
29892         findHeaderCell : function(el){
29893         var cell = this.findCell(el);
29894         return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
29895     },
29896
29897         findHeaderIndex : function(el){
29898         return this.findCellIndex(el, this.hdCls);
29899     },
29900
29901         findRow : function(el){
29902         if(!el){
29903             return false;
29904         }
29905         return this.fly(el).findParent(this.rowSelector, 10);
29906     },
29907
29908         findRowIndex : function(el){
29909         var r = this.findRow(el);
29910         return r ? r.rowIndex : false;
29911     },
29912
29913     
29914
29915     getRow : function(row){
29916         return this.getRows()[row];
29917     },
29918
29919
29920     getCell : function(row, col){
29921         return this.getRow(row).getElementsByTagName('td')[col];
29922     },
29923
29924
29925     getHeaderCell : function(index){
29926       return this.mainHd.dom.getElementsByTagName('td')[index];
29927     },
29928
29929     
29930         addRowClass : function(row, cls){
29931         var r = this.getRow(row);
29932         if(r){
29933             this.fly(r).addClass(cls);
29934         }
29935     },
29936
29937         removeRowClass : function(row, cls){
29938         var r = this.getRow(row);
29939         if(r){
29940             this.fly(r).removeClass(cls);
29941         }
29942     },
29943
29944         removeRow : function(row){
29945         Ext.removeNode(this.getRow(row));
29946     },
29947
29948         removeRows : function(firstRow, lastRow){
29949         var bd = this.mainBody.dom;
29950         for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
29951             Ext.removeNode(bd.childNodes[firstRow]);
29952         }
29953     },
29954
29955     
29956         getScrollState : function(){
29957         var sb = this.scroller.dom;
29958         return {left: sb.scrollLeft, top: sb.scrollTop};
29959     },
29960
29961         restoreScroll : function(state){
29962         var sb = this.scroller.dom;
29963         sb.scrollLeft = state.left;
29964         sb.scrollTop = state.top;
29965     },
29966
29967     
29968     scrollToTop : function(){
29969         this.scroller.dom.scrollTop = 0;
29970         this.scroller.dom.scrollLeft = 0;
29971     },
29972
29973         syncScroll : function(){
29974       this.syncHeaderScroll();
29975       var mb = this.scroller.dom;
29976         this.grid.fireEvent("bodyscroll", mb.scrollLeft, mb.scrollTop);
29977     },
29978
29979         syncHeaderScroll : function(){
29980         var mb = this.scroller.dom;
29981         this.innerHd.scrollLeft = mb.scrollLeft;
29982         this.innerHd.scrollLeft = mb.scrollLeft;     },
29983
29984         updateSortIcon : function(col, dir){
29985         var sc = this.sortClasses;
29986         var hds = this.mainHd.select('td').removeClass(sc);
29987         hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
29988     },
29989
29990         updateAllColumnWidths : function(){
29991         var tw = this.getTotalWidth();
29992         var clen = this.cm.getColumnCount();
29993         var ws = [];
29994         for(var i = 0; i < clen; i++){
29995             ws[i] = this.getColumnWidth(i);
29996         }
29997
29998         this.innerHd.firstChild.firstChild.style.width = tw;
29999
30000         for(var i = 0; i < clen; i++){
30001             var hd = this.getHeaderCell(i);
30002             hd.style.width = ws[i];
30003         }
30004
30005         var ns = this.getRows();
30006         for(var i = 0, len = ns.length; i < len; i++){
30007             ns[i].style.width = tw;
30008             ns[i].firstChild.style.width = tw;
30009             var row = ns[i].firstChild.rows[0];
30010             for(var j = 0; j < clen; j++){
30011                 row.childNodes[j].style.width = ws[j];
30012             }
30013         }
30014
30015         this.onAllColumnWidthsUpdated(ws, tw);
30016     },
30017
30018         updateColumnWidth : function(col, width){
30019         var w = this.getColumnWidth(col);
30020         var tw = this.getTotalWidth();
30021
30022         this.innerHd.firstChild.firstChild.style.width = tw;
30023         var hd = this.getHeaderCell(col);
30024         hd.style.width = w;
30025
30026         var ns = this.getRows();
30027         for(var i = 0, len = ns.length; i < len; i++){
30028             ns[i].style.width = tw;
30029             ns[i].firstChild.style.width = tw;
30030             ns[i].firstChild.rows[0].childNodes[col].style.width = w;
30031         }
30032
30033         this.onColumnWidthUpdated(col, w, tw);
30034     },
30035
30036         updateColumnHidden : function(col, hidden){
30037         var tw = this.getTotalWidth();
30038
30039         this.innerHd.firstChild.firstChild.style.width = tw;
30040
30041         var display = hidden ? 'none' : '';
30042
30043         var hd = this.getHeaderCell(col);
30044         hd.style.display = display;
30045
30046         var ns = this.getRows();
30047         for(var i = 0, len = ns.length; i < len; i++){
30048             ns[i].style.width = tw;
30049             ns[i].firstChild.style.width = tw;
30050             ns[i].firstChild.rows[0].childNodes[col].style.display = display;
30051         }
30052
30053         this.onColumnHiddenUpdated(col, hidden, tw);
30054
30055         delete this.lastViewWidth;         this.layout();
30056     },
30057
30058         doRender : function(cs, rs, ds, startRow, colCount, stripe){
30059         var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;
30060         var tstyle = 'width:'+this.getTotalWidth()+';';
30061                 var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
30062         for(var j = 0, len = rs.length; j < len; j++){
30063             r = rs[j]; cb = [];
30064             var rowIndex = (j+startRow);
30065             for(var i = 0; i < colCount; i++){
30066                 c = cs[i];
30067                 p.id = c.id;
30068                 p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
30069                 p.attr = p.cellAttr = "";
30070                 p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
30071                 p.style = c.style;
30072                 if(p.value == undefined || p.value === "") p.value = "&#160;";
30073                 if(r.dirty && typeof r.modified[c.name] !== 'undefined'){
30074                     p.css += ' x-grid3-dirty-cell';
30075                 }
30076                 cb[cb.length] = ct.apply(p);
30077             }
30078             var alt = [];
30079             if(stripe && ((rowIndex+1) % 2 == 0)){
30080                 alt[0] = "x-grid3-row-alt";
30081             }
30082             if(r.dirty){
30083                 alt[1] = " x-grid3-dirty-row";
30084             }
30085             rp.cols = colCount;
30086             if(this.getRowClass){
30087                 alt[2] = this.getRowClass(r, rowIndex, rp, ds);
30088             }
30089             rp.alt = alt.join(" ");
30090             rp.cells = cb.join("");
30091             buf[buf.length] =  rt.apply(rp);
30092         }
30093         return buf.join("");
30094     },
30095
30096         processRows : function(startRow, skipStripe){
30097         if(this.ds.getCount() < 1){
30098             return;
30099         }
30100         skipStripe = skipStripe || !this.grid.stripeRows;
30101         startRow = startRow || 0;
30102         var rows = this.getRows();
30103         var cls = ' x-grid3-row-alt ';
30104         for(var i = startRow, len = rows.length; i < len; i++){
30105             var row = rows[i];
30106             row.rowIndex = i;
30107             if(!skipStripe){
30108                 var isAlt = ((i+1) % 2 == 0);
30109                 var hasAlt = (' '+row.className + ' ').indexOf(cls) != -1;
30110                 if(isAlt == hasAlt){
30111                     continue;
30112                 }
30113                 if(isAlt){
30114                     row.className += " x-grid3-row-alt";
30115                 }else{
30116                     row.className = row.className.replace("x-grid3-row-alt", "");
30117                 }
30118             }
30119         }
30120     },
30121
30122         renderUI : function(){
30123
30124         var header = this.renderHeaders();
30125         var body = this.templates.body.apply({rows:''});
30126
30127
30128         var html = this.templates.master.apply({
30129             body: body,
30130             header: header
30131         });
30132
30133         var g = this.grid;
30134
30135         g.getGridEl().dom.innerHTML = html;
30136
30137         this.initElements();
30138
30139
30140         this.mainBody.dom.innerHTML = this.renderRows();
30141         this.processRows(0, true);
30142
30143
30144                 Ext.fly(this.innerHd).on("click", this.handleHdDown, this);
30145         this.mainHd.on("mouseover", this.handleHdOver, this);
30146         this.mainHd.on("mouseout", this.handleHdOut, this);
30147         this.mainHd.on("mousemove", this.handleHdMove, this);
30148
30149         this.scroller.on('scroll', this.syncScroll,  this);
30150         if(g.enableColumnResize !== false){
30151             this.splitone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
30152         }
30153
30154         if(g.enableColumnMove){
30155             this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
30156             this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
30157         }
30158
30159         if(g.enableHdMenu !== false){
30160             if(g.enableColumnHide !== false){
30161                 this.colMenu = new Ext.menu.Menu({id:g.id + "-hcols-menu"});
30162                 this.colMenu.on("beforeshow", this.beforeColMenuShow, this);
30163                 this.colMenu.on("itemclick", this.handleHdMenuClick, this);
30164             }
30165             this.hmenu = new Ext.menu.Menu({id: g.id + "-hctx"});
30166             this.hmenu.add(
30167                 {id:"asc", text: this.sortAscText, cls: "xg-hmenu-sort-asc"},
30168                 {id:"desc", text: this.sortDescText, cls: "xg-hmenu-sort-desc"}
30169             );
30170             if(g.enableColumnHide !== false){
30171                 this.hmenu.add('-',
30172                     {id:"columns", text: this.columnsText, menu: this.colMenu, iconCls: 'x-cols-icon'}
30173                 );
30174             }
30175             this.hmenu.on("itemclick", this.handleHdMenuClick, this);
30176
30177                     }
30178
30179         if(g.enableDragDrop || g.enableDrag){
30180             var dd = new Ext.grid.GridDragZone(g, {
30181                 ddGroup : g.ddGroup || 'GridDD'
30182             });
30183         }
30184
30185         this.updateHeaderSortState();
30186
30187     },
30188
30189         layout : function(){
30190         if(!this.mainBody){
30191             return;         }
30192         var g = this.grid;
30193         var c = g.getGridEl(), cm = this.cm,
30194                 expandCol = g.autoExpandColumn,
30195                 gv = this;
30196
30197         var csize = c.getSize(true);
30198         var vw = csize.width;
30199
30200         if(vw < 20 || csize.height < 20){             return;
30201         }
30202
30203         if(g.autoHeight){
30204             this.scroller.dom.style.overflow = 'visible';
30205         }else{
30206             this.el.setSize(csize.width, csize.height);
30207
30208             var hdHeight = this.mainHd.getHeight();
30209             var vh = csize.height - (hdHeight);
30210
30211             this.scroller.setSize(vw, vh);
30212             if(this.innerHd){
30213                 this.innerHd.style.width = (vw)+'px';
30214             }
30215         }
30216         if(this.forceFit){
30217             if(this.lastViewWidth != vw){
30218                 this.fitColumns(false, false);
30219                 this.lastViewWidth = vw;
30220             }
30221         }else {
30222             this.autoExpand();
30223             this.syncHeaderScroll();
30224         }
30225         this.onLayout(vw, vh);
30226     },
30227
30228             onLayout : function(vw, vh){
30229             },
30230
30231     onColumnWidthUpdated : function(col, w, tw){
30232             },
30233
30234     onAllColumnWidthsUpdated : function(ws, tw){
30235             },
30236
30237     onColumnHiddenUpdated : function(col, hidden, tw){
30238             },
30239
30240     updateColumnText : function(col, text){
30241             },
30242
30243     afterMove : function(colIndex){
30244             },
30245
30246     
30247         init: function(grid){
30248         this.grid = grid;
30249
30250         this.initTemplates();
30251         this.initData(grid.store, grid.colModel);
30252         this.initUI(grid);
30253     },
30254
30255         getColumnId : function(index){
30256       return this.cm.getColumnId(index);
30257     },
30258
30259         renderHeaders : function(){
30260         var cm = this.cm, ts = this.templates;
30261         var ct = ts.hcell;
30262
30263         var cb = [], sb = [], p = {};
30264
30265         for(var i = 0, len = cm.getColumnCount(); i < len; i++){
30266             p.id = cm.getColumnId(i);
30267             p.value = cm.getColumnHeader(i) || "";
30268             p.style = this.getColumnStyle(i, true);
30269             p.tooltip = this.getColumnTooltip(i);
30270             if(cm.config[i].align == 'right'){
30271                 p.istyle = 'padding-right:16px';
30272             } else {
30273                 delete p.istyle;
30274             }
30275             cb[cb.length] = ct.apply(p);
30276         }
30277         return ts.header.apply({cells: cb.join(""), tstyle:'width:'+this.getTotalWidth()+';'});
30278     },
30279
30280         getColumnTooltip : function(i){
30281         var tt = this.cm.getColumnTooltip(i);
30282         if(tt){
30283             if(Ext.QuickTips.isEnabled()){
30284                 return 'ext:qtip="'+tt+'"';
30285             }else{
30286                 return 'title="'+tt+'"';
30287             }
30288         }
30289         return "";
30290     },
30291
30292         beforeUpdate : function(){
30293         this.grid.stopEditing(true);
30294     },
30295
30296         updateHeaders : function(){
30297         this.innerHd.firstChild.innerHTML = this.renderHeaders();
30298     },
30299
30300     
30301     focusRow : function(row){
30302         this.focusCell(row, 0, false);
30303     },
30304
30305     
30306     focusCell : function(row, col, hscroll){
30307         var xy = this.ensureVisible(row, col, hscroll);
30308         this.focusEl.setXY(xy);
30309         if(Ext.isGecko){
30310             this.focusEl.focus();
30311         }else{
30312             this.focusEl.focus.defer(1, this.focusEl);
30313         }
30314     },
30315
30316         ensureVisible : function(row, col, hscroll){
30317         if(typeof row != "number"){
30318             row = row.rowIndex;
30319         }
30320         if(!this.ds){
30321             return;
30322         }
30323         if(row < 0 || row >= this.ds.getCount()){
30324             return;
30325         }
30326         col = (col !== undefined ? col : 0);
30327
30328         var rowEl = this.getRow(row), cellEl;
30329         if(!(hscroll === false && col === 0)){
30330             while(this.cm.isHidden(col)){
30331                 col++;
30332             }
30333             cellEl = this.getCell(row, col);
30334         }
30335         if(!rowEl){
30336             return;
30337         }
30338
30339         var c = this.scroller.dom;
30340
30341         var ctop = 0;
30342         var p = rowEl, stop = this.el.dom;
30343         while(p && p != stop){
30344             ctop += p.offsetTop;
30345             p = p.offsetParent;
30346         }
30347         ctop -= this.mainHd.dom.offsetHeight;
30348
30349         var cbot = ctop + rowEl.offsetHeight;
30350
30351         var ch = c.clientHeight;
30352         var stop = parseInt(c.scrollTop, 10);
30353         var sbot = stop + ch;
30354
30355         if(ctop < stop){
30356           c.scrollTop = ctop;
30357         }else if(cbot > sbot){
30358             c.scrollTop = cbot-ch;
30359         }
30360
30361         if(hscroll !== false){
30362             var cleft = parseInt(cellEl.offsetLeft, 10);
30363             var cright = cleft + cellEl.offsetWidth;
30364
30365             var sleft = parseInt(c.scrollLeft, 10);
30366             var sright = sleft + c.clientWidth;
30367             if(cleft < sleft){
30368                 c.scrollLeft = cleft;
30369             }else if(cright > sright){
30370                 c.scrollLeft = cright-c.clientWidth;
30371             }
30372         }
30373         return cellEl ? Ext.fly(cellEl).getXY() : [c.scrollLeft, Ext.fly(rowEl).getY()];
30374     },
30375
30376         insertRows : function(dm, firstRow, lastRow, isUpdate){
30377         if(!isUpdate && firstRow === 0 && lastRow == dm.getCount()-1){
30378             this.refresh();
30379         }else{
30380             if(!isUpdate){
30381                 this.fireEvent("beforerowsinserted", this, firstRow, lastRow);
30382             }
30383             var html = this.renderRows(firstRow, lastRow);
30384             var before = this.getRow(firstRow);
30385             if(before){
30386                 Ext.DomHelper.insertHtml('beforeBegin', before, html);
30387             }else{
30388                 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
30389             }
30390             if(!isUpdate){
30391                 this.fireEvent("rowsinserted", this, firstRow, lastRow);
30392                 this.processRows(firstRow);
30393             }
30394         }
30395     },
30396
30397         deleteRows : function(dm, firstRow, lastRow){
30398         if(dm.getRowCount()<1){
30399             this.refresh();
30400         }else{
30401             this.fireEvent("beforerowsdeleted", this, firstRow, lastRow);
30402
30403             this.removeRows(firstRow, lastRow);
30404
30405             this.processRows(firstRow);
30406             this.fireEvent("rowsdeleted", this, firstRow, lastRow);
30407         }
30408     },
30409
30410         getColumnStyle : function(col, isHeader){
30411         var style = !isHeader ? (this.cm.config[col].css || '') : '';
30412         style += 'width:'+this.getColumnWidth(col)+';';
30413         if(this.cm.isHidden(col)){
30414             style += 'display:none;';
30415         }
30416         var align = this.cm.config[col].align;
30417         if(align){
30418             style += 'text-align:'+align+';';
30419         }
30420         return style;
30421     },
30422
30423         getColumnWidth : function(col){
30424         var w = this.cm.getColumnWidth(col);
30425         if(typeof w == 'number'){
30426             return (Ext.isBorderBox ? w : (w-this.borderWidth > 0 ? w-this.borderWidth:0)) + 'px';
30427         }
30428         return w;
30429     },
30430
30431         getTotalWidth : function(){
30432         return this.cm.getTotalWidth()+'px';
30433     },
30434
30435         fitColumns : function(preventRefresh, onlyExpand, omitColumn){
30436         var cm = this.cm, leftOver, dist, i;
30437         var tw = cm.getTotalWidth(false);
30438         var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
30439
30440         if(aw < 20){             return;
30441         }
30442         var extra = aw - tw;
30443
30444         if(extra === 0){
30445             return false;
30446         }
30447
30448         var vc = cm.getColumnCount(true);
30449         var ac = vc-(typeof omitColumn == 'number' ? 1 : 0);
30450         if(ac === 0){
30451             ac = 1;
30452             omitColumn = undefined;
30453         }
30454         var colCount = cm.getColumnCount();
30455         var cols = [];
30456         var extraCol = 0;
30457         var width = 0;
30458         var w;
30459         for (i = 0; i < colCount; i++){
30460             if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
30461                 w = cm.getColumnWidth(i);
30462                 cols.push(i);
30463                 extraCol = i;
30464                 cols.push(w);
30465                 width += w;
30466             }
30467         }
30468         var frac = (aw - cm.getTotalWidth())/width;
30469         while (cols.length){
30470             w = cols.pop();
30471             i = cols.pop();
30472             cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
30473         }
30474
30475         if((tw = cm.getTotalWidth(false)) > aw){
30476             var adjustCol = ac != vc ? omitColumn : extraCol;
30477              cm.setColumnWidth(adjustCol, Math.max(1,
30478                      cm.getColumnWidth(adjustCol)- (tw-aw)), true);
30479         }
30480
30481         if(preventRefresh !== true){
30482             this.updateAllColumnWidths();
30483         }
30484
30485
30486         return true;
30487     },
30488
30489         autoExpand : function(preventUpdate){
30490         var g = this.grid, cm = this.cm;
30491         if(!this.userResized && g.autoExpandColumn){
30492             var tw = cm.getTotalWidth(false);
30493             var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
30494             if(tw != aw){
30495                 var ci = cm.getIndexById(g.autoExpandColumn);
30496                 var currentWidth = cm.getColumnWidth(ci);
30497                 var cw = Math.min(Math.max(((aw-tw)+currentWidth), g.autoExpandMin), g.autoExpandMax);
30498                 if(cw != currentWidth){
30499                     cm.setColumnWidth(ci, cw, true);
30500                     if(preventUpdate !== true){
30501                         this.updateColumnWidth(ci, cw);
30502                     }
30503                 }
30504             }
30505         }
30506     },
30507
30508         getColumnData : function(){
30509                 var cs = [], cm = this.cm, colCount = cm.getColumnCount();
30510         for(var i = 0; i < colCount; i++){
30511             var name = cm.getDataIndex(i);
30512             cs[i] = {
30513                 name : (typeof name == 'undefined' ? this.ds.fields.get(i).name : name),
30514                 renderer : cm.getRenderer(i),
30515                 id : cm.getColumnId(i),
30516                 style : this.getColumnStyle(i)
30517             };
30518         }
30519         return cs;
30520     },
30521
30522         renderRows : function(startRow, endRow){
30523                 var g = this.grid, cm = g.colModel, ds = g.store, stripe = g.stripeRows;
30524         var colCount = cm.getColumnCount();
30525
30526         if(ds.getCount() < 1){
30527             return "";
30528         }
30529
30530         var cs = this.getColumnData();
30531
30532         startRow = startRow || 0;
30533         endRow = typeof endRow == "undefined"? ds.getCount()-1 : endRow;
30534
30535                 var rs = ds.getRange(startRow, endRow);
30536
30537         return this.doRender(cs, rs, ds, startRow, colCount, stripe);
30538     },
30539
30540         renderBody : function(){
30541         var markup = this.renderRows();
30542         return this.templates.body.apply({rows: markup});
30543     },
30544
30545         refreshRow : function(record){
30546         var ds = this.ds, index;
30547         if(typeof record == 'number'){
30548             index = record;
30549             record = ds.getAt(index);
30550         }else{
30551             index = ds.indexOf(record);
30552         }
30553         var cls = [];
30554         this.insertRows(ds, index, index, true);
30555         this.getRow(index).rowIndex = index;
30556         this.onRemove(ds, record, index+1, true);
30557         this.fireEvent("rowupdated", this, index, record);
30558     },
30559
30560     
30561     refresh : function(headersToo){
30562         this.fireEvent("beforerefresh", this);
30563         this.grid.stopEditing(true);
30564
30565         var result = this.renderBody();
30566         this.mainBody.update(result);
30567
30568         if(headersToo === true){
30569             this.updateHeaders();
30570             this.updateHeaderSortState();
30571         }
30572         this.processRows(0, true);
30573         this.layout();
30574         this.applyEmptyText();
30575         this.fireEvent("refresh", this);
30576     },
30577
30578         applyEmptyText : function(){
30579         if(this.emptyText && !this.hasRows()){
30580             this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
30581         }
30582     },
30583
30584         updateHeaderSortState : function(){
30585         var state = this.ds.getSortState();
30586         if(!state){
30587             return;
30588         }
30589         if(!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)){
30590             this.grid.fireEvent('sortchange', this.grid, state);
30591         }
30592         this.sortState = state;
30593         var sortColumn = this.cm.findColumnIndex(state.field);
30594         if(sortColumn != -1){
30595             var sortDir = state.direction;
30596             this.updateSortIcon(sortColumn, sortDir);
30597         }
30598     },
30599
30600         destroy : function(){
30601         if(this.colMenu){
30602             this.colMenu.removeAll();
30603             Ext.menu.MenuMgr.unregister(this.colMenu);
30604             this.colMenu.getEl().remove();
30605             delete this.colMenu;
30606         }
30607         if(this.hmenu){
30608             this.hmenu.removeAll();
30609             Ext.menu.MenuMgr.unregister(this.hmenu);
30610             this.hmenu.getEl().remove();
30611             delete this.hmenu;
30612         }
30613         if(this.grid.enableColumnMove){
30614             var dds = Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
30615             if(dds){
30616                 for(var dd in dds){
30617                     if(!dds[dd].config.isTarget && dds[dd].dragElId){
30618                         var elid = dds[dd].dragElId;
30619                         dds[dd].unreg();
30620                         Ext.get(elid).remove();
30621                     } else if(dds[dd].config.isTarget){
30622                         dds[dd].proxyTop.remove();
30623                         dds[dd].proxyBottom.remove();
30624                         dds[dd].unreg();
30625                     }
30626                     if(Ext.dd.DDM.locationCache[dd]){
30627                         delete Ext.dd.DDM.locationCache[dd];
30628                     }
30629                 }
30630                 delete Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
30631             }
30632         }
30633
30634         Ext.destroy(this.resizeMarker, this.resizeProxy);
30635
30636         this.initData(null, null);
30637         Ext.EventManager.removeResizeListener(this.onWindowResize, this);
30638     },
30639
30640         onDenyColumnHide : function(){
30641
30642     },
30643
30644         render : function(){
30645
30646         var cm = this.cm;
30647         var colCount = cm.getColumnCount();
30648
30649         if(this.autoFill){
30650             this.fitColumns(true, true);
30651         }else if(this.forceFit){
30652             this.fitColumns(true, false);
30653         }else if(this.grid.autoExpandColumn){
30654             this.autoExpand(true);
30655         }
30656
30657         this.renderUI();
30658     },
30659
30660     
30661         initData : function(ds, cm){
30662         if(this.ds){
30663             this.ds.un("load", this.onLoad, this);
30664             this.ds.un("datachanged", this.onDataChange, this);
30665             this.ds.un("add", this.onAdd, this);
30666             this.ds.un("remove", this.onRemove, this);
30667             this.ds.un("update", this.onUpdate, this);
30668             this.ds.un("clear", this.onClear, this);
30669         }
30670         if(ds){
30671             ds.on("load", this.onLoad, this);
30672             ds.on("datachanged", this.onDataChange, this);
30673             ds.on("add", this.onAdd, this);
30674             ds.on("remove", this.onRemove, this);
30675             ds.on("update", this.onUpdate, this);
30676             ds.on("clear", this.onClear, this);
30677         }
30678         this.ds = ds;
30679
30680         if(this.cm){
30681             this.cm.un("configchange", this.onColConfigChange, this);
30682             this.cm.un("widthchange", this.onColWidthChange, this);
30683             this.cm.un("headerchange", this.onHeaderChange, this);
30684             this.cm.un("hiddenchange", this.onHiddenChange, this);
30685             this.cm.un("columnmoved", this.onColumnMove, this);
30686             this.cm.un("columnlockchange", this.onColumnLock, this);
30687         }
30688         if(cm){
30689             cm.on("configchange", this.onColConfigChange, this);
30690             cm.on("widthchange", this.onColWidthChange, this);
30691             cm.on("headerchange", this.onHeaderChange, this);
30692             cm.on("hiddenchange", this.onHiddenChange, this);
30693             cm.on("columnmoved", this.onColumnMove, this);
30694             cm.on("columnlockchange", this.onColumnLock, this);
30695         }
30696         this.cm = cm;
30697     },
30698
30699         onDataChange : function(){
30700         this.refresh();
30701         this.updateHeaderSortState();
30702     },
30703
30704         onClear : function(){
30705         this.refresh();
30706     },
30707
30708         onUpdate : function(ds, record){
30709         this.refreshRow(record);
30710     },
30711
30712         onAdd : function(ds, records, index){
30713         this.insertRows(ds, index, index + (records.length-1));
30714     },
30715
30716         onRemove : function(ds, record, index, isUpdate){
30717         if(isUpdate !== true){
30718             this.fireEvent("beforerowremoved", this, index, record);
30719         }
30720         this.removeRow(index);
30721         if(isUpdate !== true){
30722             this.processRows(index);
30723             this.applyEmptyText();
30724             this.fireEvent("rowremoved", this, index, record);
30725         }
30726     },
30727
30728         onLoad : function(){
30729         this.scrollToTop();
30730     },
30731
30732         onColWidthChange : function(cm, col, width){
30733         this.updateColumnWidth(col, width);
30734     },
30735
30736         onHeaderChange : function(cm, col, text){
30737         this.updateHeaders();
30738     },
30739
30740         onHiddenChange : function(cm, col, hidden){
30741         this.updateColumnHidden(col, hidden);
30742     },
30743
30744         onColumnMove : function(cm, oldIndex, newIndex){
30745         this.indexMap = null;
30746         var s = this.getScrollState();
30747         this.refresh(true);
30748         this.restoreScroll(s);
30749         this.afterMove(newIndex);
30750     },
30751
30752         onColConfigChange : function(){
30753         delete this.lastViewWidth;
30754         this.indexMap = null;
30755         this.refresh(true);
30756     },
30757
30758     
30759         initUI : function(grid){
30760         grid.on("headerclick", this.onHeaderClick, this);
30761
30762         if(grid.trackMouseOver){
30763             grid.on("mouseover", this.onRowOver, this);
30764           grid.on("mouseout", this.onRowOut, this);
30765       }
30766     },
30767
30768         initEvents : function(){
30769
30770     },
30771
30772         onHeaderClick : function(g, index){
30773         if(this.headersDisabled || !this.cm.isSortable(index)){
30774             return;
30775         }
30776         g.stopEditing(true);
30777         g.store.sort(this.cm.getDataIndex(index));
30778     },
30779
30780         onRowOver : function(e, t){
30781         var row;
30782         if((row = this.findRowIndex(t)) !== false){
30783             this.addRowClass(row, "x-grid3-row-over");
30784         }
30785     },
30786
30787         onRowOut : function(e, t){
30788         var row;
30789         if((row = this.findRowIndex(t)) !== false && row !== this.findRowIndex(e.getRelatedTarget())){
30790             this.removeRowClass(row, "x-grid3-row-over");
30791         }
30792     },
30793
30794         handleWheel : function(e){
30795         e.stopPropagation();
30796     },
30797
30798         onRowSelect : function(row){
30799         this.addRowClass(row, "x-grid3-row-selected");
30800     },
30801
30802         onRowDeselect : function(row){
30803         this.removeRowClass(row, "x-grid3-row-selected");
30804     },
30805
30806         onCellSelect : function(row, col){
30807         var cell = this.getCell(row, col);
30808         if(cell){
30809             this.fly(cell).addClass("x-grid3-cell-selected");
30810         }
30811     },
30812
30813         onCellDeselect : function(row, col){
30814         var cell = this.getCell(row, col);
30815         if(cell){
30816             this.fly(cell).removeClass("x-grid3-cell-selected");
30817         }
30818     },
30819
30820         onColumnSplitterMoved : function(i, w){
30821         this.userResized = true;
30822         var cm = this.grid.colModel;
30823         cm.setColumnWidth(i, w, true);
30824
30825         if(this.forceFit){
30826             this.fitColumns(true, false, i);
30827             this.updateAllColumnWidths();
30828         }else{
30829             this.updateColumnWidth(i, w);
30830         }
30831
30832         this.grid.fireEvent("columnresize", i, w);
30833     },
30834
30835         handleHdMenuClick : function(item){
30836         var index = this.hdCtxIndex;
30837         var cm = this.cm, ds = this.ds;
30838         switch(item.id){
30839             case "asc":
30840                 ds.sort(cm.getDataIndex(index), "ASC");
30841                 break;
30842             case "desc":
30843                 ds.sort(cm.getDataIndex(index), "DESC");
30844                 break;
30845             default:
30846                 index = cm.getIndexById(item.id.substr(4));
30847                 if(index != -1){
30848                     if(item.checked && cm.getColumnsBy(this.isHideableColumn, this).length <= 1){
30849                         this.onDenyColumnHide();
30850                         return false;
30851                     }
30852                     cm.setHidden(index, item.checked);
30853                 }
30854         }
30855         return true;
30856     },
30857
30858         isHideableColumn : function(c){
30859         return !c.hidden && !c.fixed;
30860     },
30861
30862         beforeColMenuShow : function(){
30863         var cm = this.cm,  colCount = cm.getColumnCount();
30864         this.colMenu.removeAll();
30865         for(var i = 0; i < colCount; i++){
30866             if(cm.config[i].fixed !== true && cm.config[i].hideable !== false){
30867                 this.colMenu.add(new Ext.menu.CheckItem({
30868                     id: "col-"+cm.getColumnId(i),
30869                     text: cm.getColumnHeader(i),
30870                     checked: !cm.isHidden(i),
30871                     hideOnClick:false,
30872                     disabled: cm.config[i].hideable === false
30873                 }));
30874             }
30875         }
30876     },
30877
30878         handleHdDown : function(e, t){
30879         if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
30880             e.stopEvent();
30881             var hd = this.findHeaderCell(t);
30882             Ext.fly(hd).addClass('x-grid3-hd-menu-open');
30883             var index = this.getCellIndex(hd);
30884             this.hdCtxIndex = index;
30885             var ms = this.hmenu.items, cm = this.cm;
30886             ms.get("asc").setDisabled(!cm.isSortable(index));
30887             ms.get("desc").setDisabled(!cm.isSortable(index));
30888             this.hmenu.on("hide", function(){
30889                 Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
30890             }, this, {single:true});
30891             this.hmenu.show(t, "tl-bl?");
30892         }
30893     },
30894
30895         handleHdOver : function(e, t){
30896         var hd = this.findHeaderCell(t);
30897         if(hd && !this.headersDisabled){
30898             this.activeHd = hd;
30899             this.activeHdIndex = this.getCellIndex(hd);
30900             var fly = this.fly(hd);
30901             this.activeHdRegion = fly.getRegion();
30902             if(!this.cm.isMenuDisabled(this.activeHdIndex)){
30903                 fly.addClass("x-grid3-hd-over");
30904                 this.activeHdBtn = fly.child('.x-grid3-hd-btn');
30905                 if(this.activeHdBtn){
30906                     this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight-1)+'px';
30907                 }
30908             }
30909         }
30910     },
30911
30912         handleHdMove : function(e, t){
30913         if(this.activeHd && !this.headersDisabled){
30914             var hw = this.splitHandleWidth || 5;
30915             var r = this.activeHdRegion;
30916             var x = e.getPageX();
30917             var ss = this.activeHd.style;
30918             if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
30919                 ss.cursor = Ext.isAir ? 'move' : Ext.isSafari ? 'e-resize' : 'col-resize';             }else if(r.right - x <= (!this.activeHdBtn ? hw : 2) && this.cm.isResizable(this.activeHdIndex)){
30920                 ss.cursor = Ext.isAir ? 'move' : Ext.isSafari ? 'w-resize' : 'col-resize';
30921             }else{
30922                 ss.cursor = '';
30923             }
30924         }
30925     },
30926
30927         handleHdOut : function(e, t){
30928         var hd = this.findHeaderCell(t);
30929         if(hd && (!Ext.isIE || !e.within(hd, true))){
30930             this.activeHd = null;
30931             this.fly(hd).removeClass("x-grid3-hd-over");
30932             hd.style.cursor = '';
30933         }
30934     },
30935
30936         hasRows : function(){
30937         var fc = this.mainBody.dom.firstChild;
30938         return fc && fc.className != 'x-grid-empty';
30939     },
30940
30941         bind : function(d, c){
30942         this.initData(d, c);
30943     }
30944 });
30945
30946
30947 Ext.grid.GridView.SplitDragZone = function(grid, hd){
30948     this.grid = grid;
30949     this.view = grid.getView();
30950     this.marker = this.view.resizeMarker;
30951     this.proxy = this.view.resizeProxy;
30952     Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
30953         "gridSplitters" + this.grid.getGridEl().id, {
30954         dragElId : Ext.id(this.proxy.dom), resizeFrame:false
30955     });
30956     this.scroll = false;
30957     this.hw = this.view.splitHandleWidth || 5;
30958 };
30959 Ext.extend(Ext.grid.GridView.SplitDragZone, Ext.dd.DDProxy, {
30960
30961     b4StartDrag : function(x, y){
30962         this.view.headersDisabled = true;
30963         var h = this.view.mainWrap.getHeight();
30964         this.marker.setHeight(h);
30965         this.marker.show();
30966         this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
30967         this.proxy.setHeight(h);
30968         var w = this.cm.getColumnWidth(this.cellIndex);
30969         var minw = Math.max(w-this.grid.minColumnWidth, 0);
30970         this.resetConstraints();
30971         this.setXConstraint(minw, 1000);
30972         this.setYConstraint(0, 0);
30973         this.minX = x - minw;
30974         this.maxX = x + 1000;
30975         this.startPos = x;
30976         Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
30977     },
30978
30979
30980     handleMouseDown : function(e){
30981         var t = this.view.findHeaderCell(e.getTarget());
30982         if(t){
30983             var xy = this.view.fly(t).getXY(), x = xy[0], y = xy[1];
30984             var exy = e.getXY(), ex = exy[0], ey = exy[1];
30985             var w = t.offsetWidth, adjust = false;
30986             if((ex - x) <= this.hw){
30987                 adjust = -1;
30988             }else if((x+w) - ex <= this.hw){
30989                 adjust = 0;
30990             }
30991             if(adjust !== false){
30992                 this.cm = this.grid.colModel;
30993                 var ci = this.view.getCellIndex(t);
30994                 if(adjust == -1){
30995                   if (ci + adjust < 0) {
30996                     return;
30997                   }
30998                     while(this.cm.isHidden(ci+adjust)){
30999                         --adjust;
31000                         if(ci+adjust < 0){
31001                             return;
31002                         }
31003                     }
31004                 }
31005                 this.cellIndex = ci+adjust;
31006                 this.split = t.dom;
31007                 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
31008                     Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
31009                 }
31010             }else if(this.view.columnDrag){
31011                 this.view.columnDrag.callHandleMouseDown(e);
31012             }
31013         }
31014     },
31015
31016     endDrag : function(e){
31017         this.marker.hide();
31018         var v = this.view;
31019         var endX = Math.max(this.minX, e.getPageX());
31020         var diff = endX - this.startPos;
31021         v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
31022         setTimeout(function(){
31023             v.headersDisabled = false;
31024         }, 50);
31025     },
31026
31027     autoOffset : function(){
31028         this.setDelta(0,0);
31029     }
31030 });
31031
31032 \r
31033 Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {\r
31034     \r
31035     hideGroupedColumn:false,\r
31036     \r
31037     showGroupName:true,\r
31038     \r
31039     startCollapsed:false,\r
31040     \r
31041     enableGrouping:true,\r
31042     \r
31043     enableGroupingMenu:true,\r
31044     \r
31045     enableNoGroups:true,\r
31046     \r
31047     emptyGroupText : '(None)',\r
31048     \r
31049     ignoreAdd: false,\r
31050     \r
31051     groupTextTpl : '{text}',\r
31052     \r
31053     \r
31054 \r
31055     
31056     gidSeed : 1000,\r
31057 \r
31058     
31059     initTemplates : function(){\r
31060         Ext.grid.GroupingView.superclass.initTemplates.call(this);\r
31061         this.state = {};\r
31062 \r
31063         var sm = this.grid.getSelectionModel();\r
31064         sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',\r
31065                 this.onBeforeRowSelect, this);\r
31066 \r
31067         if(!this.startGroup){\r
31068             this.startGroup = new Ext.XTemplate(\r
31069                 '<div id="{groupId}" class="x-grid-group {cls}">',\r
31070                     '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div>', this.groupTextTpl ,'</div></div>',\r
31071                     '<div id="{groupId}-bd" class="x-grid-group-body">'\r
31072             );\r
31073         }\r
31074         this.startGroup.compile();\r
31075         this.endGroup = '</div></div>';\r
31076     },\r
31077 \r
31078     
31079     findGroup : function(el){\r
31080         return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);\r
31081     },\r
31082 \r
31083     
31084     getGroups : function(){\r
31085         return this.hasRows() ? this.mainBody.dom.childNodes : [];\r
31086     },\r
31087 \r
31088     
31089     onAdd : function(){\r
31090         if(this.enableGrouping && !this.ignoreAdd){\r
31091             var ss = this.getScrollState();\r
31092             this.refresh();\r
31093             this.restoreScroll(ss);\r
31094         }else if(!this.enableGrouping){\r
31095             Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);\r
31096         }\r
31097     },\r
31098 \r
31099     
31100     onRemove : function(ds, record, index, isUpdate){\r
31101         Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);\r
31102         var g = document.getElementById(record._groupId);\r
31103         if(g && g.childNodes[1].childNodes.length < 1){\r
31104             Ext.removeNode(g);\r
31105         }\r
31106         this.applyEmptyText();\r
31107     },\r
31108 \r
31109     
31110     refreshRow : function(record){\r
31111         if(this.ds.getCount()==1){\r
31112             this.refresh();\r
31113         }else{\r
31114             this.isUpdating = true;\r
31115             Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);\r
31116             this.isUpdating = false;\r
31117         }\r
31118     },\r
31119 \r
31120     
31121     beforeMenuShow : function(){\r
31122         var field = this.getGroupField();\r
31123         var g = this.hmenu.items.get('groupBy');\r
31124         if(g){\r
31125             g.setDisabled(this.cm.config[this.hdCtxIndex].groupable === false);\r
31126         }\r
31127         var s = this.hmenu.items.get('showGroups');\r
31128         if(s){\r
31129             if (!!field){ 
31130                 s.setDisabled(this.cm.config[this.hdCtxIndex].groupable === false)\r
31131             }\r
31132             s.setChecked(!!field);\r
31133         }\r
31134     },\r
31135 \r
31136     
31137     renderUI : function(){\r
31138         Ext.grid.GroupingView.superclass.renderUI.call(this);\r
31139         this.mainBody.on('mousedown', this.interceptMouse, this);\r
31140 \r
31141         if(this.enableGroupingMenu && this.hmenu){\r
31142             this.hmenu.add('-',{\r
31143                 id:'groupBy',\r
31144                 text: this.groupByText,\r
31145                 handler: this.onGroupByClick,\r
31146                 scope: this,\r
31147                 iconCls:'x-group-by-icon'\r
31148             });\r
31149             if(this.enableNoGroups){\r
31150                 this.hmenu.add({\r
31151                     id:'showGroups',\r
31152                     text: this.showGroupsText,\r
31153                     checked: true,\r
31154                     checkHandler: this.onShowGroupsClick,\r
31155                     scope: this\r
31156                 });\r
31157             }\r
31158             this.hmenu.on('beforeshow', this.beforeMenuShow, this);\r
31159         }\r
31160     },\r
31161 \r
31162     
31163     onGroupByClick : function(){\r
31164         this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));\r
31165         this.beforeMenuShow(); 
31166     },\r
31167 \r
31168     
31169     onShowGroupsClick : function(mi, checked){\r
31170         if(checked){\r
31171             this.onGroupByClick();\r
31172         }else{\r
31173             this.grid.store.clearGrouping();\r
31174         }\r
31175     },\r
31176 \r
31177     \r
31178     toggleGroup : function(group, expanded){\r
31179         this.grid.stopEditing(true);\r
31180         group = Ext.getDom(group);\r
31181         var gel = Ext.fly(group);\r
31182         expanded = expanded !== undefined ?\r
31183                 expanded : gel.hasClass('x-grid-group-collapsed');\r
31184 \r
31185         this.state[gel.dom.id] = expanded;\r
31186         gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');\r
31187     },\r
31188 \r
31189     \r
31190     toggleAllGroups : function(expanded){\r
31191         var groups = this.getGroups();\r
31192         for(var i = 0, len = groups.length; i < len; i++){\r
31193             this.toggleGroup(groups[i], expanded);\r
31194         }\r
31195     },\r
31196 \r
31197     \r
31198     expandAllGroups : function(){\r
31199         this.toggleAllGroups(true);\r
31200     },\r
31201 \r
31202     \r
31203     collapseAllGroups : function(){\r
31204         this.toggleAllGroups(false);\r
31205     },\r
31206 \r
31207     
31208     interceptMouse : function(e){\r
31209         var hd = e.getTarget('.x-grid-group-hd', this.mainBody);\r
31210         if(hd){\r
31211             e.stopEvent();\r
31212             this.toggleGroup(hd.parentNode);\r
31213         }\r
31214     },\r
31215 \r
31216     
31217     getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){\r
31218         var g = groupRenderer ? groupRenderer(v, {}, r, rowIndex, colIndex, ds) : String(v);\r
31219         if(g === ''){\r
31220             g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;\r
31221         }\r
31222         return g;\r
31223     },\r
31224 \r
31225     
31226     getGroupField : function(){\r
31227         return this.grid.store.getGroupState();\r
31228     },\r
31229 \r
31230     
31231     renderRows : function(){\r
31232         var groupField = this.getGroupField();\r
31233         var eg = !!groupField;\r
31234         
31235         if(this.hideGroupedColumn) {\r
31236             var colIndex = this.cm.findColumnIndex(groupField);\r
31237             if(!eg && this.lastGroupField !== undefined) {\r
31238                 this.mainBody.update('');\r
31239                 this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);\r
31240                 delete this.lastGroupField;\r
31241             }else if (eg && this.lastGroupField === undefined) {\r
31242                 this.lastGroupField = groupField;\r
31243                 this.cm.setHidden(colIndex, true);\r
31244             }else if (eg && this.lastGroupField !== undefined && groupField !== this.lastGroupField) {\r
31245                 this.mainBody.update('');\r
31246                 var oldIndex = this.cm.findColumnIndex(this.lastGroupField);\r
31247                 this.cm.setHidden(oldIndex, false);\r
31248                 this.lastGroupField = groupField;\r
31249                 this.cm.setHidden(colIndex, true);\r
31250             }\r
31251         }\r
31252         return Ext.grid.GroupingView.superclass.renderRows.apply(\r
31253                     this, arguments);\r
31254     },\r
31255 \r
31256     
31257     doRender : function(cs, rs, ds, startRow, colCount, stripe){\r
31258         if(rs.length < 1){\r
31259             return '';\r
31260         }\r
31261         var groupField = this.getGroupField();\r
31262         var colIndex = this.cm.findColumnIndex(groupField);\r
31263 \r
31264         this.enableGrouping = !!groupField;\r
31265 \r
31266         if(!this.enableGrouping || this.isUpdating){\r
31267             return Ext.grid.GroupingView.superclass.doRender.apply(\r
31268                     this, arguments);\r
31269         }\r
31270         var gstyle = 'width:'+this.getTotalWidth()+';';\r
31271 \r
31272         var gidPrefix = this.grid.getGridEl().id;\r
31273         var cfg = this.cm.config[colIndex];\r
31274         var groupRenderer = cfg.groupRenderer || cfg.renderer;\r
31275         var prefix = this.showGroupName ?\r
31276                      (cfg.groupName || cfg.header)+': ' : '';\r
31277 \r
31278         var groups = [], curGroup, i, len, gid;\r
31279         for(i = 0, len = rs.length; i < len; i++){\r
31280             var rowIndex = startRow + i;\r
31281             var r = rs[i],\r
31282                 gvalue = r.data[groupField],\r
31283                 g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);\r
31284             if(!curGroup || curGroup.group != g){\r
31285                 gid = gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(g);\r
31286                 
31287                                 
31288                                 var isCollapsed  = typeof this.state[gid] !== 'undefined' ? !this.state[gid] : this.startCollapsed;\r
31289                                 var gcls = isCollapsed ? 'x-grid-group-collapsed' : ''; \r
31290                 curGroup = {\r
31291                     group: g,\r
31292                     gvalue: gvalue,\r
31293                     text: prefix + g,\r
31294                     groupId: gid,\r
31295                     startRow: rowIndex,\r
31296                     rs: [r],\r
31297                     cls: gcls,\r
31298                     style: gstyle\r
31299                 };\r
31300                 groups.push(curGroup);\r
31301             }else{\r
31302                 curGroup.rs.push(r);\r
31303             }\r
31304             r._groupId = gid;\r
31305         }\r
31306 \r
31307         var buf = [];\r
31308         for(i = 0, len = groups.length; i < len; i++){\r
31309             var g = groups[i];\r
31310             this.doGroupStart(buf, g, cs, ds, colCount);\r
31311             buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(\r
31312                     this, cs, g.rs, ds, g.startRow, colCount, stripe);\r
31313 \r
31314             this.doGroupEnd(buf, g, cs, ds, colCount);\r
31315         }\r
31316         return buf.join('');\r
31317     },\r
31318 \r
31319     \r
31320     getGroupId : function(value){\r
31321         var gidPrefix = this.grid.getGridEl().id;\r
31322         var groupField = this.getGroupField();\r
31323         var colIndex = this.cm.findColumnIndex(groupField);\r
31324         var cfg = this.cm.config[colIndex];\r
31325         var groupRenderer = cfg.groupRenderer || cfg.renderer;\r
31326         var gtext = this.getGroup(value, {data:{}}, groupRenderer, 0, colIndex, this.ds);\r
31327         return gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(value);\r
31328     },\r
31329 \r
31330     
31331     doGroupStart : function(buf, g, cs, ds, colCount){\r
31332         buf[buf.length] = this.startGroup.apply(g);\r
31333     },\r
31334 \r
31335     
31336     doGroupEnd : function(buf, g, cs, ds, colCount){\r
31337         buf[buf.length] = this.endGroup;\r
31338     },\r
31339 \r
31340     
31341     getRows : function(){\r
31342         if(!this.enableGrouping){\r
31343             return Ext.grid.GroupingView.superclass.getRows.call(this);\r
31344         }\r
31345         var r = [];\r
31346         var g, gs = this.getGroups();\r
31347         for(var i = 0, len = gs.length; i < len; i++){\r
31348             g = gs[i].childNodes[1].childNodes;\r
31349             for(var j = 0, jlen = g.length; j < jlen; j++){\r
31350                 r[r.length] = g[j];\r
31351             }\r
31352         }\r
31353         return r;\r
31354     },\r
31355 \r
31356     
31357     updateGroupWidths : function(){\r
31358         if(!this.enableGrouping || !this.hasRows()){\r
31359             return;\r
31360         }\r
31361         var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.scrollOffset) +'px';\r
31362         var gs = this.getGroups();\r
31363         for(var i = 0, len = gs.length; i < len; i++){\r
31364             gs[i].firstChild.style.width = tw;\r
31365         }\r
31366     },\r
31367 \r
31368     
31369     onColumnWidthUpdated : function(col, w, tw){\r
31370         this.updateGroupWidths();\r
31371     },\r
31372 \r
31373     
31374     onAllColumnWidthsUpdated : function(ws, tw){\r
31375         this.updateGroupWidths();\r
31376     },\r
31377 \r
31378     
31379     onColumnHiddenUpdated : function(col, hidden, tw){\r
31380         this.updateGroupWidths();\r
31381     },\r
31382 \r
31383     
31384     onLayout : function(){\r
31385         this.updateGroupWidths();\r
31386     },\r
31387 \r
31388     
31389     onBeforeRowSelect : function(sm, rowIndex){\r
31390         if(!this.enableGrouping){\r
31391             return;\r
31392         }\r
31393         var row = this.getRow(rowIndex);\r
31394         if(row && !row.offsetParent){\r
31395             var g = this.findGroup(row);\r
31396             this.toggleGroup(g, true);\r
31397         }\r
31398     },\r
31399 \r
31400     \r
31401     groupByText: 'Group By This Field',\r
31402     \r
31403     showGroupsText: 'Show in Groups'\r
31404 });\r
31405
31406 Ext.grid.GroupingView.GROUP_ID = 1000;
31407
31408
31409 Ext.grid.HeaderDragZone = function(grid, hd, hd2){\r
31410     this.grid = grid;\r
31411     this.view = grid.getView();\r
31412     this.ddGroup = "gridHeader" + this.grid.getGridEl().id;\r
31413     Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);\r
31414     if(hd2){\r
31415         this.setHandleElId(Ext.id(hd));\r
31416         this.setOuterHandleElId(Ext.id(hd2));\r
31417     }\r
31418     this.scroll = false;\r
31419 };\r
31420 Ext.extend(Ext.grid.HeaderDragZone, Ext.dd.DragZone, {\r
31421     maxDragWidth: 120,\r
31422     getDragData : function(e){\r
31423         var t = Ext.lib.Event.getTarget(e);\r
31424         var h = this.view.findHeaderCell(t);\r
31425         if(h){\r
31426             return {ddel: h.firstChild, header:h};\r
31427         }\r
31428         return false;\r
31429     },\r
31430 \r
31431     onInitDrag : function(e){\r
31432         this.view.headersDisabled = true;\r
31433         var clone = this.dragData.ddel.cloneNode(true);\r
31434         clone.id = Ext.id();\r
31435         clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";\r
31436         this.proxy.update(clone);\r
31437         return true;\r
31438     },\r
31439 \r
31440     afterValidDrop : function(){\r
31441         var v = this.view;\r
31442         setTimeout(function(){\r
31443             v.headersDisabled = false;\r
31444         }, 50);\r
31445     },\r
31446 \r
31447     afterInvalidDrop : function(){\r
31448         var v = this.view;\r
31449         setTimeout(function(){\r
31450             v.headersDisabled = false;\r
31451         }, 50);\r
31452     }\r
31453 });\r
31454 \r
31455
31456
31457 Ext.grid.HeaderDropZone = function(grid, hd, hd2){\r
31458     this.grid = grid;\r
31459     this.view = grid.getView();\r
31460     
31461     this.proxyTop = Ext.DomHelper.append(document.body, {\r
31462         cls:"col-move-top", html:"&#160;"\r
31463     }, true);\r
31464     this.proxyBottom = Ext.DomHelper.append(document.body, {\r
31465         cls:"col-move-bottom", html:"&#160;"\r
31466     }, true);\r
31467     this.proxyTop.hide = this.proxyBottom.hide = function(){\r
31468         this.setLeftTop(-100,-100);\r
31469         this.setStyle("visibility", "hidden");\r
31470     };\r
31471     this.ddGroup = "gridHeader" + this.grid.getGridEl().id;\r
31472     
31473     
31474     Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);\r
31475 };\r
31476 Ext.extend(Ext.grid.HeaderDropZone, Ext.dd.DropZone, {\r
31477     proxyOffsets : [-4, -9],\r
31478     fly: Ext.Element.fly,\r
31479 \r
31480     getTargetFromEvent : function(e){\r
31481         var t = Ext.lib.Event.getTarget(e);\r
31482         var cindex = this.view.findCellIndex(t);\r
31483         if(cindex !== false){\r
31484             return this.view.getHeaderCell(cindex);\r
31485         }\r
31486     },\r
31487 \r
31488     nextVisible : function(h){\r
31489         var v = this.view, cm = this.grid.colModel;\r
31490         h = h.nextSibling;\r
31491         while(h){\r
31492             if(!cm.isHidden(v.getCellIndex(h))){\r
31493                 return h;\r
31494             }\r
31495             h = h.nextSibling;\r
31496         }\r
31497         return null;\r
31498     },\r
31499 \r
31500     prevVisible : function(h){\r
31501         var v = this.view, cm = this.grid.colModel;\r
31502         h = h.prevSibling;\r
31503         while(h){\r
31504             if(!cm.isHidden(v.getCellIndex(h))){\r
31505                 return h;\r
31506             }\r
31507             h = h.prevSibling;\r
31508         }\r
31509         return null;\r
31510     },\r
31511 \r
31512     positionIndicator : function(h, n, e){\r
31513         var x = Ext.lib.Event.getPageX(e);\r
31514         var r = Ext.lib.Dom.getRegion(n.firstChild);\r
31515         var px, pt, py = r.top + this.proxyOffsets[1];\r
31516         if((r.right - x) <= (r.right-r.left)/2){\r
31517             px = r.right+this.view.borderWidth;\r
31518             pt = "after";\r
31519         }else{\r
31520             px = r.left;\r
31521             pt = "before";\r
31522         }\r
31523         var oldIndex = this.view.getCellIndex(h);\r
31524         var newIndex = this.view.getCellIndex(n);\r
31525 \r
31526         if(this.grid.colModel.isFixed(newIndex)){\r
31527             return false;\r
31528         }\r
31529 \r
31530         var locked = this.grid.colModel.isLocked(newIndex);\r
31531 \r
31532         if(pt == "after"){\r
31533             newIndex++;\r
31534         }\r
31535         if(oldIndex < newIndex){\r
31536             newIndex--;\r
31537         }\r
31538         if(oldIndex == newIndex && (locked == this.grid.colModel.isLocked(oldIndex))){\r
31539             return false;\r
31540         }\r
31541         px +=  this.proxyOffsets[0];\r
31542         this.proxyTop.setLeftTop(px, py);\r
31543         this.proxyTop.show();\r
31544         if(!this.bottomOffset){\r
31545             this.bottomOffset = this.view.mainHd.getHeight();\r
31546         }\r
31547         this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);\r
31548         this.proxyBottom.show();\r
31549         return pt;\r
31550     },\r
31551 \r
31552     onNodeEnter : function(n, dd, e, data){\r
31553         if(data.header != n){\r
31554             this.positionIndicator(data.header, n, e);\r
31555         }\r
31556     },\r
31557 \r
31558     onNodeOver : function(n, dd, e, data){\r
31559         var result = false;\r
31560         if(data.header != n){\r
31561             result = this.positionIndicator(data.header, n, e);\r
31562         }\r
31563         if(!result){\r
31564             this.proxyTop.hide();\r
31565             this.proxyBottom.hide();\r
31566         }\r
31567         return result ? this.dropAllowed : this.dropNotAllowed;\r
31568     },\r
31569 \r
31570     onNodeOut : function(n, dd, e, data){\r
31571         this.proxyTop.hide();\r
31572         this.proxyBottom.hide();\r
31573     },\r
31574 \r
31575     onNodeDrop : function(n, dd, e, data){\r
31576         var h = data.header;\r
31577         if(h != n){\r
31578             var cm = this.grid.colModel;\r
31579             var x = Ext.lib.Event.getPageX(e);\r
31580             var r = Ext.lib.Dom.getRegion(n.firstChild);\r
31581             var pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before";\r
31582             var oldIndex = this.view.getCellIndex(h);\r
31583             var newIndex = this.view.getCellIndex(n);\r
31584             var locked = cm.isLocked(newIndex);\r
31585             if(pt == "after"){\r
31586                 newIndex++;\r
31587             }\r
31588             if(oldIndex < newIndex){\r
31589                 newIndex--;\r
31590             }\r
31591             if(oldIndex == newIndex && (locked == cm.isLocked(oldIndex))){\r
31592                 return false;\r
31593             }\r
31594             cm.setLocked(oldIndex, locked, true);\r
31595             cm.moveColumn(oldIndex, newIndex);\r
31596             this.grid.fireEvent("columnmove", oldIndex, newIndex);\r
31597             return true;\r
31598         }\r
31599         return false;\r
31600     }\r
31601 });\r
31602 \r
31603 \r
31604 Ext.grid.GridView.ColumnDragZone = function(grid, hd){\r
31605     Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);\r
31606     this.proxy.el.addClass('x-grid3-col-dd');\r
31607 };\r
31608 \r
31609 Ext.extend(Ext.grid.GridView.ColumnDragZone, Ext.grid.HeaderDragZone, {\r
31610     handleMouseDown : function(e){\r
31611 \r
31612     },\r
31613 \r
31614     callHandleMouseDown : function(e){\r
31615         Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);\r
31616     }\r
31617 });
31618 Ext.grid.SplitDragZone = function(grid, hd, hd2){
31619     this.grid = grid;
31620     this.view = grid.getView();
31621     this.proxy = this.view.resizeProxy;
31622     Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
31623         "gridSplitters" + this.grid.getGridEl().id, {
31624         dragElId : Ext.id(this.proxy.dom), resizeFrame:false
31625     });
31626     this.setHandleElId(Ext.id(hd));
31627     this.setOuterHandleElId(Ext.id(hd2));
31628     this.scroll = false;
31629 };
31630 Ext.extend(Ext.grid.SplitDragZone, Ext.dd.DDProxy, {
31631     fly: Ext.Element.fly,
31632
31633     b4StartDrag : function(x, y){
31634         this.view.headersDisabled = true;
31635         this.proxy.setHeight(this.view.mainWrap.getHeight());
31636         var w = this.cm.getColumnWidth(this.cellIndex);
31637         var minw = Math.max(w-this.grid.minColumnWidth, 0);
31638         this.resetConstraints();
31639         this.setXConstraint(minw, 1000);
31640         this.setYConstraint(0, 0);
31641         this.minX = x - minw;
31642         this.maxX = x + 1000;
31643         this.startPos = x;
31644         Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
31645     },
31646
31647
31648     handleMouseDown : function(e){
31649         ev = Ext.EventObject.setEvent(e);
31650         var t = this.fly(ev.getTarget());
31651         if(t.hasClass("x-grid-split")){
31652             this.cellIndex = this.view.getCellIndex(t.dom);
31653             this.split = t.dom;
31654             this.cm = this.grid.colModel;
31655             if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
31656                 Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
31657             }
31658         }
31659     },
31660
31661     endDrag : function(e){
31662         this.view.headersDisabled = false;
31663         var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
31664         var diff = endX - this.startPos;
31665         this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
31666     },
31667
31668     autoOffset : function(){
31669         this.setDelta(0,0);
31670     }
31671 });
31672 Ext.grid.GridDragZone = function(grid, config){
31673     this.view = grid.getView();
31674     Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
31675     if(this.view.lockedBody){
31676         this.setHandleElId(Ext.id(this.view.mainBody.dom));
31677         this.setOuterHandleElId(Ext.id(this.view.lockedBody.dom));
31678     }
31679     this.scroll = false;
31680     this.grid = grid;
31681     this.ddel = document.createElement('div');
31682     this.ddel.className = 'x-grid-dd-wrap';
31683 };
31684
31685 Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
31686     ddGroup : "GridDD",
31687
31688     getDragData : function(e){
31689         var t = Ext.lib.Event.getTarget(e);
31690         var rowIndex = this.view.findRowIndex(t);
31691         if(rowIndex !== false){
31692             var sm = this.grid.selModel;
31693             if(!sm.isSelected(rowIndex) || e.hasModifier()){
31694                 sm.handleMouseDown(this.grid, rowIndex, e);
31695             }
31696             return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
31697         }
31698         return false;
31699     },
31700
31701     onInitDrag : function(e){
31702         var data = this.dragData;
31703         this.ddel.innerHTML = this.grid.getDragDropText();
31704         this.proxy.update(this.ddel);
31705             },
31706
31707     afterRepair : function(){
31708         this.dragging = false;
31709     },
31710
31711     getRepairXY : function(e, data){
31712         return false;
31713     },
31714
31715     onEndDrag : function(data, e){
31716             },
31717
31718     onValidDrop : function(dd, e, id){
31719                 this.hideProxy();
31720     },
31721
31722     beforeInvalidDrop : function(e, id){
31723
31724     }
31725 });
31726
31727 \r
31728 Ext.grid.ColumnModel = function(config){\r
31729         \r
31730     this.defaultWidth = 100;\r
31731 \r
31732     \r
31733     this.defaultSortable = false;\r
31734 \r
31735     \r
31736     if(config.columns){\r
31737         Ext.apply(this, config);\r
31738         this.setConfig(config.columns, true);\r
31739     }else{\r
31740         this.setConfig(config, true);\r
31741     }\r
31742     this.addEvents(\r
31743         \r
31744             "widthchange",\r
31745         \r
31746             "headerchange",\r
31747         \r
31748             "hiddenchange",\r
31749             \r
31750         "columnmoved",\r
31751         
31752         "columnlockchange",\r
31753         \r
31754         "configchange"\r
31755     );\r
31756     Ext.grid.ColumnModel.superclass.constructor.call(this);\r
31757 };\r
31758 Ext.extend(Ext.grid.ColumnModel, Ext.util.Observable, {\r
31759     \r
31760     \r
31761     \r
31762     \r
31763     \r
31764     \r
31765     \r
31766     \r
31767     \r
31768     \r
31769     \r
31770     \r
31771     \r
31772     \r
31773     \r
31774 \r
31775     \r
31776     getColumnId : function(index){\r
31777         return this.config[index].id;\r
31778     },\r
31779 \r
31780     \r
31781     setConfig : function(config, initial){\r
31782         if(!initial){ 
31783             delete this.totalWidth;\r
31784             for(var i = 0, len = this.config.length; i < len; i++){\r
31785                 var c = this.config[i];\r
31786                 if(c.editor){\r
31787                     c.editor.destroy();\r
31788                 }\r
31789             }\r
31790         }\r
31791         this.config = config;\r
31792         this.lookup = {};\r
31793         
31794         for(var i = 0, len = config.length; i < len; i++){\r
31795             var c = config[i];\r
31796             if(typeof c.renderer == "string"){\r
31797                 c.renderer = Ext.util.Format[c.renderer];\r
31798             }\r
31799             if(typeof c.id == "undefined"){\r
31800                 c.id = i;\r
31801             }\r
31802             if(c.editor && c.editor.isFormField){\r
31803                 c.editor = new Ext.grid.GridEditor(c.editor);\r
31804             }\r
31805             this.lookup[c.id] = c;\r
31806         }\r
31807         if(!initial){\r
31808             this.fireEvent('configchange', this);\r
31809         }\r
31810     },\r
31811 \r
31812     \r
31813     getColumnById : function(id){\r
31814         return this.lookup[id];\r
31815     },\r
31816 \r
31817     \r
31818     getIndexById : function(id){\r
31819         for(var i = 0, len = this.config.length; i < len; i++){\r
31820             if(this.config[i].id == id){\r
31821                 return i;\r
31822             }\r
31823         }\r
31824         return -1;\r
31825     },\r
31826 \r
31827     
31828     moveColumn : function(oldIndex, newIndex){\r
31829         var c = this.config[oldIndex];\r
31830         this.config.splice(oldIndex, 1);\r
31831         this.config.splice(newIndex, 0, c);\r
31832         this.dataMap = null;\r
31833         this.fireEvent("columnmoved", this, oldIndex, newIndex);\r
31834     },\r
31835 \r
31836     
31837     isLocked : function(colIndex){\r
31838         return this.config[colIndex].locked === true;\r
31839     },\r
31840 \r
31841     
31842     setLocked : function(colIndex, value, suppressEvent){\r
31843         if(this.isLocked(colIndex) == value){\r
31844             return;\r
31845         }\r
31846         this.config[colIndex].locked = value;\r
31847         if(!suppressEvent){\r
31848             this.fireEvent("columnlockchange", this, colIndex, value);\r
31849         }\r
31850     },\r
31851 \r
31852     
31853     getTotalLockedWidth : function(){\r
31854         var totalWidth = 0;\r
31855         for(var i = 0; i < this.config.length; i++){\r
31856             if(this.isLocked(i) && !this.isHidden(i)){\r
31857                 this.totalWidth += this.getColumnWidth(i);\r
31858             }\r
31859         }\r
31860         return totalWidth;\r
31861     },\r
31862 \r
31863     
31864     getLockedCount : function(){\r
31865         for(var i = 0, len = this.config.length; i < len; i++){\r
31866             if(!this.isLocked(i)){\r
31867                 return i;\r
31868             }\r
31869         }\r
31870     },\r
31871 \r
31872     \r
31873     getColumnCount : function(visibleOnly){\r
31874         if(visibleOnly === true){\r
31875             var c = 0;\r
31876             for(var i = 0, len = this.config.length; i < len; i++){\r
31877                 if(!this.isHidden(i)){\r
31878                     c++;\r
31879                 }\r
31880             }\r
31881             return c;\r
31882         }\r
31883         return this.config.length;\r
31884     },\r
31885 \r
31886     \r
31887     getColumnsBy : function(fn, scope){\r
31888         var r = [];\r
31889         for(var i = 0, len = this.config.length; i < len; i++){\r
31890             var c = this.config[i];\r
31891             if(fn.call(scope||this, c, i) === true){\r
31892                 r[r.length] = c;\r
31893             }\r
31894         }\r
31895         return r;\r
31896     },\r
31897 \r
31898     \r
31899     isSortable : function(col){\r
31900         if(typeof this.config[col].sortable == "undefined"){\r
31901             return this.defaultSortable;\r
31902         }\r
31903         return this.config[col].sortable;\r
31904     },\r
31905 \r
31906     \r
31907     isMenuDisabled : function(col){\r
31908         return !!this.config[col].menuDisabled;\r
31909     },\r
31910 \r
31911     \r
31912     getRenderer : function(col){\r
31913         if(!this.config[col].renderer){\r
31914             return Ext.grid.ColumnModel.defaultRenderer;\r
31915         }\r
31916         return this.config[col].renderer;\r
31917     },\r
31918 \r
31919     \r
31920     setRenderer : function(col, fn){\r
31921         this.config[col].renderer = fn;\r
31922     },\r
31923 \r
31924     \r
31925     getColumnWidth : function(col){\r
31926         return this.config[col].width || this.defaultWidth;\r
31927     },\r
31928 \r
31929     \r
31930     setColumnWidth : function(col, width, suppressEvent){\r
31931         this.config[col].width = width;\r
31932         this.totalWidth = null;\r
31933         if(!suppressEvent){\r
31934              this.fireEvent("widthchange", this, col, width);\r
31935         }\r
31936     },\r
31937 \r
31938     \r
31939     getTotalWidth : function(includeHidden){\r
31940         if(!this.totalWidth){\r
31941             this.totalWidth = 0;\r
31942             for(var i = 0, len = this.config.length; i < len; i++){\r
31943                 if(includeHidden || !this.isHidden(i)){\r
31944                     this.totalWidth += this.getColumnWidth(i);\r
31945                 }\r
31946             }\r
31947         }\r
31948         return this.totalWidth;\r
31949     },\r
31950 \r
31951     \r
31952     getColumnHeader : function(col){\r
31953         return this.config[col].header;\r
31954     },\r
31955 \r
31956     \r
31957     setColumnHeader : function(col, header){\r
31958         this.config[col].header = header;\r
31959         this.fireEvent("headerchange", this, col, header);\r
31960     },\r
31961 \r
31962     \r
31963     getColumnTooltip : function(col){\r
31964             return this.config[col].tooltip;\r
31965     },\r
31966     \r
31967     setColumnTooltip : function(col, tooltip){\r
31968             this.config[col].tooltip = tooltip;\r
31969     },\r
31970 \r
31971     \r
31972     getDataIndex : function(col){\r
31973         return this.config[col].dataIndex;\r
31974     },\r
31975 \r
31976     \r
31977     setDataIndex : function(col, dataIndex){\r
31978         this.config[col].dataIndex = dataIndex;\r
31979     },\r
31980 \r
31981     findColumnIndex : function(dataIndex){\r
31982         var c = this.config;\r
31983         for(var i = 0, len = c.length; i < len; i++){\r
31984             if(c[i].dataIndex == dataIndex){\r
31985                 return i;\r
31986             }\r
31987         }\r
31988         return -1;\r
31989     },\r
31990 \r
31991     \r
31992     isCellEditable : function(colIndex, rowIndex){\r
31993         return (this.config[colIndex].editable || (typeof this.config[colIndex].editable == "undefined" && this.config[colIndex].editor)) ? true : false;\r
31994     },\r
31995 \r
31996     \r
31997     getCellEditor : function(colIndex, rowIndex){\r
31998         return this.config[colIndex].editor;\r
31999     },\r
32000 \r
32001     \r
32002     setEditable : function(col, editable){\r
32003         this.config[col].editable = editable;\r
32004     },\r
32005 \r
32006 \r
32007     \r
32008     isHidden : function(colIndex){\r
32009         return this.config[colIndex].hidden;\r
32010     },\r
32011 \r
32012 \r
32013     \r
32014     isFixed : function(colIndex){\r
32015         return this.config[colIndex].fixed;\r
32016     },\r
32017 \r
32018     \r
32019     isResizable : function(colIndex){\r
32020         return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;\r
32021     },\r
32022     \r
32023     setHidden : function(colIndex, hidden){\r
32024         var c = this.config[colIndex];\r
32025         if(c.hidden !== hidden){\r
32026             c.hidden = hidden;\r
32027             this.totalWidth = null;\r
32028             this.fireEvent("hiddenchange", this, colIndex, hidden);\r
32029         }\r
32030     },\r
32031 \r
32032     \r
32033     setEditor : function(col, editor){\r
32034         this.config[col].editor = editor;\r
32035     }\r
32036 });\r
32037 \r
32038
32039 Ext.grid.ColumnModel.defaultRenderer = function(value){\r
32040         if(typeof value == "string" && value.length < 1){\r
32041             return "&#160;";\r
32042         }\r
32043         return value;\r
32044 };\r
32045 \r
32046
32047 Ext.grid.DefaultColumnModel = Ext.grid.ColumnModel;\r
32048
32049 \r
32050 Ext.grid.AbstractSelectionModel = function(){\r
32051     this.locked = false;\r
32052     Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);\r
32053 };\r
32054 \r
32055 Ext.extend(Ext.grid.AbstractSelectionModel, Ext.util.Observable,  {\r
32056     \r
32057     init : function(grid){\r
32058         this.grid = grid;\r
32059         this.initEvents();\r
32060     },\r
32061 \r
32062     \r
32063     lock : function(){\r
32064         this.locked = true;\r
32065     },\r
32066 \r
32067     \r
32068     unlock : function(){\r
32069         this.locked = false;\r
32070     },\r
32071 \r
32072     \r
32073     isLocked : function(){\r
32074         return this.locked;\r
32075     }\r
32076 });
32077
32078 Ext.grid.RowSelectionModel = function(config){
32079     Ext.apply(this, config);
32080     this.selections = new Ext.util.MixedCollection(false, function(o){
32081         return o.id;
32082     });
32083
32084     this.last = false;
32085     this.lastActive = false;
32086
32087     this.addEvents(
32088         
32089             "selectionchange",
32090         
32091             "beforerowselect",
32092         
32093             "rowselect",
32094         
32095             "rowdeselect"
32096     );
32097
32098     Ext.grid.RowSelectionModel.superclass.constructor.call(this);
32099 };
32100
32101 Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
32102     
32103     singleSelect : false,
32104
32105         
32106         initEvents : function(){
32107
32108         if(!this.grid.enableDragDrop && !this.grid.enableDrag){
32109             this.grid.on("rowmousedown", this.handleMouseDown, this);
32110         }else{             this.grid.on("rowclick", function(grid, rowIndex, e) {
32111                 if(e.button === 0 && !e.shiftKey && !e.ctrlKey) {
32112                     this.selectRow(rowIndex, false);
32113                     grid.view.focusRow(rowIndex);
32114                 }
32115             }, this);
32116         }
32117
32118         this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
32119             "up" : function(e){
32120                 if(!e.shiftKey){
32121                     this.selectPrevious(e.shiftKey);
32122                 }else if(this.last !== false && this.lastActive !== false){
32123                     var last = this.last;
32124                     this.selectRange(this.last,  this.lastActive-1);
32125                     this.grid.getView().focusRow(this.lastActive);
32126                     if(last !== false){
32127                         this.last = last;
32128                     }
32129                 }else{
32130                     this.selectFirstRow();
32131                 }
32132             },
32133             "down" : function(e){
32134                 if(!e.shiftKey){
32135                     this.selectNext(e.shiftKey);
32136                 }else if(this.last !== false && this.lastActive !== false){
32137                     var last = this.last;
32138                     this.selectRange(this.last,  this.lastActive+1);
32139                     this.grid.getView().focusRow(this.lastActive);
32140                     if(last !== false){
32141                         this.last = last;
32142                     }
32143                 }else{
32144                     this.selectFirstRow();
32145                 }
32146             },
32147             scope: this
32148         });
32149
32150         var view = this.grid.view;
32151         view.on("refresh", this.onRefresh, this);
32152         view.on("rowupdated", this.onRowUpdated, this);
32153         view.on("rowremoved", this.onRemove, this);
32154     },
32155
32156         onRefresh : function(){
32157         var ds = this.grid.store, index;
32158         var s = this.getSelections();
32159         this.clearSelections(true);
32160         for(var i = 0, len = s.length; i < len; i++){
32161             var r = s[i];
32162             if((index = ds.indexOfId(r.id)) != -1){
32163                 this.selectRow(index, true);
32164             }
32165         }
32166         if(s.length != this.selections.getCount()){
32167             this.fireEvent("selectionchange", this);
32168         }
32169     },
32170
32171         onRemove : function(v, index, r){
32172         if(this.selections.remove(r) !== false){
32173             this.fireEvent('selectionchange', this);
32174         }
32175     },
32176
32177         onRowUpdated : function(v, index, r){
32178         if(this.isSelected(r)){
32179             v.onRowSelect(index);
32180         }
32181     },
32182
32183     
32184     selectRecords : function(records, keepExisting){
32185         if(!keepExisting){
32186             this.clearSelections();
32187         }
32188         var ds = this.grid.store;
32189         for(var i = 0, len = records.length; i < len; i++){
32190             this.selectRow(ds.indexOf(records[i]), true);
32191         }
32192     },
32193
32194     
32195     getCount : function(){
32196         return this.selections.length;
32197     },
32198
32199     
32200     selectFirstRow : function(){
32201         this.selectRow(0);
32202     },
32203
32204     
32205     selectLastRow : function(keepExisting){
32206         this.selectRow(this.grid.store.getCount() - 1, keepExisting);
32207     },
32208
32209     
32210     selectNext : function(keepExisting){
32211         if(this.hasNext()){
32212             this.selectRow(this.last+1, keepExisting);
32213             this.grid.getView().focusRow(this.last);
32214                         return true;
32215         }
32216                 return false;
32217     },
32218
32219     
32220     selectPrevious : function(keepExisting){
32221         if(this.hasPrevious()){
32222             this.selectRow(this.last-1, keepExisting);
32223             this.grid.getView().focusRow(this.last);
32224                         return true;
32225         }
32226                 return false;
32227     },
32228
32229     
32230     hasNext : function(){
32231         return this.last !== false && (this.last+1) < this.grid.store.getCount();
32232     },
32233
32234     
32235     hasPrevious : function(){
32236         return !!this.last;
32237     },
32238
32239
32240     
32241     getSelections : function(){
32242         return [].concat(this.selections.items);
32243     },
32244
32245     
32246     getSelected : function(){
32247         return this.selections.itemAt(0);
32248     },
32249
32250     
32251     each : function(fn, scope){
32252         var s = this.getSelections();
32253         for(var i = 0, len = s.length; i < len; i++){
32254             if(fn.call(scope || this, s[i], i) === false){
32255                 return false;
32256             }
32257         }
32258         return true;
32259     },
32260
32261     
32262     clearSelections : function(fast){
32263         if(this.locked) return;
32264         if(fast !== true){
32265             var ds = this.grid.store;
32266             var s = this.selections;
32267             s.each(function(r){
32268                 this.deselectRow(ds.indexOfId(r.id));
32269             }, this);
32270             s.clear();
32271         }else{
32272             this.selections.clear();
32273         }
32274         this.last = false;
32275     },
32276
32277
32278     
32279     selectAll : function(){
32280         if(this.locked) return;
32281         this.selections.clear();
32282         for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
32283             this.selectRow(i, true);
32284         }
32285     },
32286
32287     
32288     hasSelection : function(){
32289         return this.selections.length > 0;
32290     },
32291
32292     
32293     isSelected : function(index){
32294         var r = typeof index == "number" ? this.grid.store.getAt(index) : index;
32295         return (r && this.selections.key(r.id) ? true : false);
32296     },
32297
32298     
32299     isIdSelected : function(id){
32300         return (this.selections.key(id) ? true : false);
32301     },
32302
32303         handleMouseDown : function(g, rowIndex, e){
32304         if(e.button !== 0 || this.isLocked()){
32305             return;
32306         };
32307         var view = this.grid.getView();
32308         if(e.shiftKey && this.last !== false){
32309             var last = this.last;
32310             this.selectRange(last, rowIndex, e.ctrlKey);
32311             this.last = last;             view.focusRow(rowIndex);
32312         }else{
32313             var isSelected = this.isSelected(rowIndex);
32314             if(e.ctrlKey && isSelected){
32315                 this.deselectRow(rowIndex);
32316             }else if(!isSelected || this.getCount() > 1){
32317                 this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
32318                 view.focusRow(rowIndex);
32319             }
32320         }
32321     },
32322
32323     
32324     selectRows : function(rows, keepExisting){
32325         if(!keepExisting){
32326             this.clearSelections();
32327         }
32328         for(var i = 0, len = rows.length; i < len; i++){
32329             this.selectRow(rows[i], true);
32330         }
32331     },
32332
32333     
32334     selectRange : function(startRow, endRow, keepExisting){
32335         if(this.locked) return;
32336         if(!keepExisting){
32337             this.clearSelections();
32338         }
32339         if(startRow <= endRow){
32340             for(var i = startRow; i <= endRow; i++){
32341                 this.selectRow(i, true);
32342             }
32343         }else{
32344             for(var i = startRow; i >= endRow; i--){
32345                 this.selectRow(i, true);
32346             }
32347         }
32348     },
32349
32350     
32351     deselectRange : function(startRow, endRow, preventViewNotify){
32352         if(this.locked) return;
32353         for(var i = startRow; i <= endRow; i++){
32354             this.deselectRow(i, preventViewNotify);
32355         }
32356     },
32357
32358     
32359     selectRow : function(index, keepExisting, preventViewNotify){
32360         if(this.locked || (index < 0 || index >= this.grid.store.getCount())) return;
32361         var r = this.grid.store.getAt(index);
32362         if(r && this.fireEvent("beforerowselect", this, index, keepExisting, r) !== false){
32363             if(!keepExisting || this.singleSelect){
32364                 this.clearSelections();
32365             }
32366             this.selections.add(r);
32367             this.last = this.lastActive = index;
32368             if(!preventViewNotify){
32369                 this.grid.getView().onRowSelect(index);
32370             }
32371             this.fireEvent("rowselect", this, index, r);
32372             this.fireEvent("selectionchange", this);
32373         }
32374     },
32375
32376     
32377     deselectRow : function(index, preventViewNotify){
32378         if(this.locked) return;
32379         if(this.last == index){
32380             this.last = false;
32381         }
32382         if(this.lastActive == index){
32383             this.lastActive = false;
32384         }
32385         var r = this.grid.store.getAt(index);
32386         if(r){
32387             this.selections.remove(r);
32388             if(!preventViewNotify){
32389                 this.grid.getView().onRowDeselect(index);
32390             }
32391             this.fireEvent("rowdeselect", this, index, r);
32392             this.fireEvent("selectionchange", this);
32393         }
32394     },
32395
32396         restoreLast : function(){
32397         if(this._last){
32398             this.last = this._last;
32399         }
32400     },
32401
32402         acceptsNav : function(row, col, cm){
32403         return !cm.isHidden(col) && cm.isCellEditable(col, row);
32404     },
32405
32406         onEditorKey : function(field, e){
32407         var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
32408         var shift = e.shiftKey;
32409         if(k == e.TAB){
32410             e.stopEvent();
32411             ed.completeEdit();
32412             if(shift){
32413                 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
32414             }else{
32415                 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
32416             }
32417         }else if(k == e.ENTER){
32418             e.stopEvent();
32419             ed.completeEdit();
32420                         if(this.moveEditorOnEnter !== false){
32421                                 if(shift){
32422                                         newCell = g.walkCells(ed.row - 1, ed.col, -1, this.acceptsNav, this);
32423                                 }else{
32424                                         newCell = g.walkCells(ed.row + 1, ed.col, 1, this.acceptsNav, this);
32425                                 }
32426                         }
32427         }else if(k == e.ESC){
32428             ed.cancelEdit();
32429         }
32430         if(newCell){
32431             g.startEditing(newCell[0], newCell[1]);
32432         }
32433     }
32434 });
32435
32436 Ext.grid.CellSelectionModel = function(config){
32437     Ext.apply(this, config);
32438
32439     this.selection = null;
32440
32441     this.addEvents(
32442         
32443             "beforecellselect",
32444         
32445             "cellselect",
32446         
32447             "selectionchange"
32448     );
32449
32450     Ext.grid.CellSelectionModel.superclass.constructor.call(this);
32451 };
32452
32453 Ext.extend(Ext.grid.CellSelectionModel, Ext.grid.AbstractSelectionModel,  {
32454
32455     
32456     initEvents : function(){
32457         this.grid.on("cellmousedown", this.handleMouseDown, this);
32458         this.grid.getGridEl().on(Ext.isIE ? "keydown" : "keypress", this.handleKeyDown, this);
32459         var view = this.grid.view;
32460         view.on("refresh", this.onViewChange, this);
32461         view.on("rowupdated", this.onRowUpdated, this);
32462         view.on("beforerowremoved", this.clearSelections, this);
32463         view.on("beforerowsinserted", this.clearSelections, this);
32464         if(this.grid.isEditor){
32465             this.grid.on("beforeedit", this.beforeEdit,  this);
32466         }
32467     },
32468
32469             beforeEdit : function(e){
32470         this.select(e.row, e.column, false, true, e.record);
32471     },
32472
32473             onRowUpdated : function(v, index, r){
32474         if(this.selection && this.selection.record == r){
32475             v.onCellSelect(index, this.selection.cell[1]);
32476         }
32477     },
32478
32479             onViewChange : function(){
32480         this.clearSelections(true);
32481     },
32482
32483         
32484     getSelectedCell : function(){
32485         return this.selection ? this.selection.cell : null;
32486     },
32487
32488     
32489     clearSelections : function(preventNotify){
32490         var s = this.selection;
32491         if(s){
32492             if(preventNotify !== true){
32493                 this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
32494             }
32495             this.selection = null;
32496             this.fireEvent("selectionchange", this, null);
32497         }
32498     },
32499
32500     
32501     hasSelection : function(){
32502         return this.selection ? true : false;
32503     },
32504
32505     
32506     handleMouseDown : function(g, row, cell, e){
32507         if(e.button !== 0 || this.isLocked()){
32508             return;
32509         };
32510         this.select(row, cell);
32511     },
32512
32513     
32514     select : function(rowIndex, colIndex, preventViewNotify, preventFocus,  r){
32515         if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
32516             this.clearSelections();
32517             r = r || this.grid.store.getAt(rowIndex);
32518             this.selection = {
32519                 record : r,
32520                 cell : [rowIndex, colIndex]
32521             };
32522             if(!preventViewNotify){
32523                 var v = this.grid.getView();
32524                 v.onCellSelect(rowIndex, colIndex);
32525                 if(preventFocus !== true){
32526                     v.focusCell(rowIndex, colIndex);
32527                 }
32528             }
32529             this.fireEvent("cellselect", this, rowIndex, colIndex);
32530             this.fireEvent("selectionchange", this, this.selection);
32531         }
32532     },
32533
32534             isSelectable : function(rowIndex, colIndex, cm){
32535         return !cm.isHidden(colIndex);
32536     },
32537
32538     
32539     handleKeyDown : function(e){
32540         if(!e.isNavKeyPress()){
32541             return;
32542         }
32543         var g = this.grid, s = this.selection;
32544         if(!s){
32545             e.stopEvent();
32546             var cell = g.walkCells(0, 0, 1, this.isSelectable,  this);
32547             if(cell){
32548                 this.select(cell[0], cell[1]);
32549             }
32550             return;
32551         }
32552         var sm = this;
32553         var walk = function(row, col, step){
32554             return g.walkCells(row, col, step, sm.isSelectable,  sm);
32555         };
32556         var k = e.getKey(), r = s.cell[0], c = s.cell[1];
32557         var newCell;
32558
32559         switch(k){
32560              case e.TAB:
32561                  if(e.shiftKey){
32562                      newCell = walk(r, c-1, -1);
32563                  }else{
32564                      newCell = walk(r, c+1, 1);
32565                  }
32566              break;
32567              case e.DOWN:
32568                  newCell = walk(r+1, c, 1);
32569              break;
32570              case e.UP:
32571                  newCell = walk(r-1, c, -1);
32572              break;
32573              case e.RIGHT:
32574                  newCell = walk(r, c+1, 1);
32575              break;
32576              case e.LEFT:
32577                  newCell = walk(r, c-1, -1);
32578              break;
32579              case e.ENTER:
32580                  if(g.isEditor && !g.editing){
32581                     g.startEditing(r, c);
32582                     e.stopEvent();
32583                     return;
32584                 }
32585              break;
32586         };
32587         if(newCell){
32588             this.select(newCell[0], newCell[1]);
32589             e.stopEvent();
32590         }
32591     },
32592
32593     acceptsNav : function(row, col, cm){
32594         return !cm.isHidden(col) && cm.isCellEditable(col, row);
32595     },
32596
32597     onEditorKey : function(field, e){
32598         var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
32599         if(k == e.TAB){
32600             if(e.shiftKey){
32601                 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
32602             }else{
32603                 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
32604             }
32605             e.stopEvent();
32606         }else if(k == e.ENTER){
32607             ed.completeEdit();
32608             e.stopEvent();
32609         }else if(k == e.ESC){
32610                 e.stopEvent();
32611             ed.cancelEdit();
32612         }
32613         if(newCell){
32614             g.startEditing(newCell[0], newCell[1]);
32615         }
32616     }
32617 });
32618 \r
32619 Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {\r
32620     \r
32621     clicksToEdit: 2,\r
32622 \r
32623     
32624     isEditor : true,\r
32625     
32626     detectEdit: false,\r
32627 \r
32628         \r
32629         autoEncode : false,\r
32630 \r
32631         \r
32632     
32633     trackMouseOver: false, 
32634     \r
32635     
32636     initComponent : function(){\r
32637         Ext.grid.EditorGridPanel.superclass.initComponent.call(this);\r
32638 \r
32639         if(!this.selModel){\r
32640             this.selModel = new Ext.grid.CellSelectionModel();\r
32641         }\r
32642 \r
32643         this.activeEditor = null;\r
32644 \r
32645             this.addEvents(\r
32646             \r
32647             "beforeedit",\r
32648             \r
32649             "afteredit",\r
32650             \r
32651             "validateedit"\r
32652         );\r
32653     },\r
32654 \r
32655     
32656     initEvents : function(){\r
32657         Ext.grid.EditorGridPanel.superclass.initEvents.call(this);\r
32658         \r
32659         this.on("bodyscroll", this.stopEditing, this, [true]);\r
32660 \r
32661         if(this.clicksToEdit == 1){\r
32662             this.on("cellclick", this.onCellDblClick, this);\r
32663         }else {\r
32664             if(this.clicksToEdit == 'auto' && this.view.mainBody){\r
32665                 this.view.mainBody.on("mousedown", this.onAutoEditClick, this);\r
32666             }\r
32667             this.on("celldblclick", this.onCellDblClick, this);\r
32668         }\r
32669         this.getGridEl().addClass("xedit-grid");\r
32670     },\r
32671 \r
32672     
32673     onCellDblClick : function(g, row, col){\r
32674         this.startEditing(row, col);\r
32675     },\r
32676 \r
32677     
32678     onAutoEditClick : function(e, t){\r
32679         if(e.button !== 0){\r
32680             return;\r
32681         }\r
32682         var row = this.view.findRowIndex(t);\r
32683         var col = this.view.findCellIndex(t);\r
32684         if(row !== false && col !== false){\r
32685             this.stopEditing();\r
32686             if(this.selModel.getSelectedCell){ 
32687                 var sc = this.selModel.getSelectedCell();\r
32688                 if(sc && sc.cell[0] === row && sc.cell[1] === col){\r
32689                     this.startEditing(row, col);\r
32690                 }\r
32691             }else{\r
32692                 if(this.selModel.isSelected(row)){\r
32693                     this.startEditing(row, col);\r
32694                 }\r
32695             }\r
32696         }\r
32697     },\r
32698 \r
32699     
32700     onEditComplete : function(ed, value, startValue){\r
32701         this.editing = false;\r
32702         this.activeEditor = null;\r
32703         ed.un("specialkey", this.selModel.onEditorKey, this.selModel);\r
32704                 var r = ed.record;\r
32705         var field = this.colModel.getDataIndex(ed.col);\r
32706         value = this.postEditValue(value, startValue, r, field);\r
32707         if(String(value) !== String(startValue)){\r
32708             var e = {\r
32709                 grid: this,\r
32710                 record: r,\r
32711                 field: field,\r
32712                 originalValue: startValue,\r
32713                 value: value,\r
32714                 row: ed.row,\r
32715                 column: ed.col,\r
32716                 cancel:false\r
32717             };\r
32718             if(this.fireEvent("validateedit", e) !== false && !e.cancel){\r
32719                 r.set(field, e.value);\r
32720                 delete e.cancel;\r
32721                 this.fireEvent("afteredit", e);\r
32722             }\r
32723         }\r
32724         this.view.focusCell(ed.row, ed.col);\r
32725     },\r
32726 \r
32727     \r
32728     startEditing : function(row, col){\r
32729         this.stopEditing();\r
32730         if(this.colModel.isCellEditable(col, row)){\r
32731             this.view.ensureVisible(row, col, true);\r
32732             var r = this.store.getAt(row);\r
32733             var field = this.colModel.getDataIndex(col);\r
32734             var e = {\r
32735                 grid: this,\r
32736                 record: r,\r
32737                 field: field,\r
32738                 value: r.data[field],\r
32739                 row: row,\r
32740                 column: col,\r
32741                 cancel:false\r
32742             };\r
32743             if(this.fireEvent("beforeedit", e) !== false && !e.cancel){\r
32744                 this.editing = true;\r
32745                 var ed = this.colModel.getCellEditor(col, row);\r
32746                 if(!ed.rendered){\r
32747                     ed.render(this.view.getEditorParent(ed));\r
32748                 }\r
32749                 (function(){ 
32750                     ed.row = row;\r
32751                     ed.col = col;\r
32752                     ed.record = r;\r
32753                     ed.on("complete", this.onEditComplete, this, {single: true});\r
32754                     ed.on("specialkey", this.selModel.onEditorKey, this.selModel);\r
32755                     this.activeEditor = ed;\r
32756                     var v = this.preEditValue(r, field);\r
32757                     ed.startEdit(this.view.getCell(row, col), v);\r
32758                 }).defer(50, this);\r
32759             }\r
32760         }\r
32761     },\r
32762     \r
32763         preEditValue : function(r, field){\r
32764                 return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlDecode(r.data[field]) : r.data[field];\r
32765         },\r
32766         \r
32767         postEditValue : function(value, originalValue, r, field){\r
32768                 return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value;\r
32769         },\r
32770             \r
32771     \r
32772     stopEditing : function(cancel){\r
32773         if(this.activeEditor){\r
32774             this.activeEditor[cancel === true ? 'cancelEdit' : 'completeEdit']();\r
32775         }\r
32776         this.activeEditor = null;\r
32777     }\r
32778 });\r
32779 Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
32780 Ext.grid.GridEditor = function(field, config){
32781     Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
32782     field.monitorTab = false;
32783 };
32784
32785 Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
32786     alignment: "tl-tl",
32787     autoSize: "width",
32788     hideEl : false,
32789     cls: "x-small-editor x-grid-editor",
32790     shim:false,
32791     shadow:false
32792 });
32793
32794 Ext.grid.PropertyRecord = Ext.data.Record.create([
32795     {name:'name',type:'string'}, 'value'
32796 ]);
32797
32798
32799 Ext.grid.PropertyStore = function(grid, source){
32800     this.grid = grid;
32801     this.store = new Ext.data.Store({
32802         recordType : Ext.grid.PropertyRecord
32803     });
32804     this.store.on('update', this.onUpdate,  this);
32805     if(source){
32806         this.setSource(source);
32807     }
32808     Ext.grid.PropertyStore.superclass.constructor.call(this);
32809 };
32810 Ext.extend(Ext.grid.PropertyStore, Ext.util.Observable, {
32811         setSource : function(o){
32812         this.source = o;
32813         this.store.removeAll();
32814         var data = [];
32815         for(var k in o){
32816             if(this.isEditableValue(o[k])){
32817                 data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
32818             }
32819         }
32820         this.store.loadRecords({records: data}, {}, true);
32821     },
32822
32823         onUpdate : function(ds, record, type){
32824         if(type == Ext.data.Record.EDIT){
32825             var v = record.data['value'];
32826             var oldValue = record.modified['value'];
32827             if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
32828                 this.source[record.id] = v;
32829                 record.commit();
32830                 this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
32831             }else{
32832                 record.reject();
32833             }
32834         }
32835     },
32836
32837         getProperty : function(row){
32838        return this.store.getAt(row);
32839     },
32840
32841         isEditableValue: function(val){
32842         if(Ext.isDate(val)){
32843             return true;
32844         }else if(typeof val == 'object' || typeof val == 'function'){
32845             return false;
32846         }
32847         return true;
32848     },
32849
32850         setValue : function(prop, value){
32851         this.source[prop] = value;
32852         this.store.getById(prop).set('value', value);
32853     },
32854
32855         getSource : function(){
32856         return this.source;
32857     }
32858 });
32859
32860
32861 Ext.grid.PropertyColumnModel = function(grid, store){
32862     this.grid = grid;
32863     var g = Ext.grid;
32864     g.PropertyColumnModel.superclass.constructor.call(this, [
32865         {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
32866         {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
32867     ]);
32868     this.store = store;
32869     this.bselect = Ext.DomHelper.append(document.body, {
32870         tag: 'select', cls: 'x-grid-editor x-hide-display', children: [
32871             {tag: 'option', value: 'true', html: 'true'},
32872             {tag: 'option', value: 'false', html: 'false'}
32873         ]
32874     });
32875     var f = Ext.form;
32876
32877     var bfield = new f.Field({
32878         el:this.bselect,
32879         bselect : this.bselect,
32880         autoShow: true,
32881         getValue : function(){
32882             return this.bselect.value == 'true';
32883         }
32884     });
32885     this.editors = {
32886         'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
32887         'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
32888         'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
32889         'boolean' : new g.GridEditor(bfield)
32890     };
32891     this.renderCellDelegate = this.renderCell.createDelegate(this);
32892     this.renderPropDelegate = this.renderProp.createDelegate(this);
32893 };
32894
32895 Ext.extend(Ext.grid.PropertyColumnModel, Ext.grid.ColumnModel, {
32896         nameText : 'Name',
32897     valueText : 'Value',
32898     dateFormat : 'm/j/Y',
32899
32900         renderDate : function(dateVal){
32901         return dateVal.dateFormat(this.dateFormat);
32902     },
32903
32904         renderBool : function(bVal){
32905         return bVal ? 'true' : 'false';
32906     },
32907
32908         isCellEditable : function(colIndex, rowIndex){
32909         return colIndex == 1;
32910     },
32911
32912         getRenderer : function(col){
32913         return col == 1 ?
32914             this.renderCellDelegate : this.renderPropDelegate;
32915     },
32916
32917         renderProp : function(v){
32918         return this.getPropertyName(v);
32919     },
32920
32921         renderCell : function(val){
32922         var rv = val;
32923         if(Ext.isDate(val)){
32924             rv = this.renderDate(val);
32925         }else if(typeof val == 'boolean'){
32926             rv = this.renderBool(val);
32927         }
32928         return Ext.util.Format.htmlEncode(rv);
32929     },
32930
32931         getPropertyName : function(name){
32932         var pn = this.grid.propertyNames;
32933         return pn && pn[name] ? pn[name] : name;
32934     },
32935
32936         getCellEditor : function(colIndex, rowIndex){
32937         var p = this.store.getProperty(rowIndex);
32938         var n = p.data['name'], val = p.data['value'];
32939         if(this.grid.customEditors[n]){
32940             return this.grid.customEditors[n];
32941         }
32942         if(Ext.isDate(val)){
32943             return this.editors['date'];
32944         }else if(typeof val == 'number'){
32945             return this.editors['number'];
32946         }else if(typeof val == 'boolean'){
32947             return this.editors['boolean'];
32948         }else{
32949             return this.editors['string'];
32950         }
32951     }
32952 });
32953
32954
32955 Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
32956     
32957     
32958
32959         enableColumnMove:false,
32960     stripeRows:false,
32961     trackMouseOver: false,
32962     clicksToEdit:1,
32963     enableHdMenu : false,
32964     viewConfig : {
32965         forceFit:true
32966     },
32967
32968         initComponent : function(){
32969         this.customEditors = this.customEditors || {};
32970         this.lastEditRow = null;
32971         var store = new Ext.grid.PropertyStore(this);
32972         this.propStore = store;
32973         var cm = new Ext.grid.PropertyColumnModel(this, store);
32974         store.store.sort('name', 'ASC');
32975         this.addEvents(
32976             
32977             'beforepropertychange',
32978             
32979             'propertychange'
32980         );
32981         this.cm = cm;
32982         this.ds = store.store;
32983         Ext.grid.PropertyGrid.superclass.initComponent.call(this);
32984
32985         this.selModel.on('beforecellselect', function(sm, rowIndex, colIndex){
32986             if(colIndex === 0){
32987                 this.startEditing.defer(200, this, [rowIndex, 1]);
32988                 return false;
32989             }
32990         }, this);
32991     },
32992
32993         onRender : function(){
32994         Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
32995
32996         this.getGridEl().addClass('x-props-grid');
32997     },
32998
32999         afterRender: function(){
33000         Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
33001         if(this.source){
33002             this.setSource(this.source);
33003         }
33004     },
33005
33006     
33007     setSource : function(source){
33008         this.propStore.setSource(source);
33009     },
33010
33011     
33012     getSource : function(){
33013         return this.propStore.getSource();
33014     }
33015 });
33016 \r
33017 Ext.grid.RowNumberer = function(config){\r
33018     Ext.apply(this, config);\r
33019     if(this.rowspan){\r
33020         this.renderer = this.renderer.createDelegate(this);\r
33021     }\r
33022 };\r
33023 \r
33024 Ext.grid.RowNumberer.prototype = {\r
33025     \r
33026     header: "",\r
33027     \r
33028     width: 23,\r
33029     \r
33030     sortable: false,\r
33031 \r
33032     
33033     fixed:true,\r
33034     menuDisabled:true,\r
33035     dataIndex: '',\r
33036     id: 'numberer',\r
33037     rowspan: undefined,\r
33038 \r
33039     
33040     renderer : function(v, p, record, rowIndex){\r
33041         if(this.rowspan){\r
33042             p.cellAttr = 'rowspan="'+this.rowspan+'"';\r
33043         }\r
33044         return rowIndex+1;\r
33045     }\r
33046 };
33047 \r
33048 Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {\r
33049     \r
33050     header: '<div class="x-grid3-hd-checker">&#160;</div>',\r
33051     \r
33052     width: 20,\r
33053     \r
33054     sortable: false,\r
33055 \r
33056     
33057     menuDisabled:true,\r
33058     fixed:true,\r
33059     dataIndex: '',\r
33060     id: 'checker',\r
33061 \r
33062     
33063     initEvents : function(){\r
33064         Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);\r
33065         this.grid.on('render', function(){\r
33066             var view = this.grid.getView();\r
33067             view.mainBody.on('mousedown', this.onMouseDown, this);\r
33068             Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);\r
33069 \r
33070         }, this);\r
33071     },\r
33072 \r
33073     
33074     onMouseDown : function(e, t){\r
33075         if(e.button === 0 && t.className == 'x-grid3-row-checker'){ 
33076             e.stopEvent();\r
33077             var row = e.getTarget('.x-grid3-row');\r
33078             if(row){\r
33079                 var index = row.rowIndex;\r
33080                 if(this.isSelected(index)){\r
33081                     this.deselectRow(index);\r
33082                 }else{\r
33083                     this.selectRow(index, true);\r
33084                 }\r
33085             }\r
33086         }\r
33087     },\r
33088 \r
33089     
33090     onHdMouseDown : function(e, t){\r
33091         if(t.className == 'x-grid3-hd-checker'){\r
33092             e.stopEvent();\r
33093             var hd = Ext.fly(t.parentNode);\r
33094             var isChecked = hd.hasClass('x-grid3-hd-checker-on');\r
33095             if(isChecked){\r
33096                 hd.removeClass('x-grid3-hd-checker-on');\r
33097                 this.clearSelections();\r
33098             }else{\r
33099                 hd.addClass('x-grid3-hd-checker-on');\r
33100                 this.selectAll();\r
33101             }\r
33102         }\r
33103     },\r
33104 \r
33105     
33106     renderer : function(v, p, record){\r
33107         return '<div class="x-grid3-row-checker">&#160;</div>';\r
33108     }\r
33109 });
33110
33111 Ext.LoadMask = function(el, config){
33112     this.el = Ext.get(el);
33113     Ext.apply(this, config);
33114     if(this.store){
33115         this.store.on('beforeload', this.onBeforeLoad, this);
33116         this.store.on('load', this.onLoad, this);
33117         this.store.on('loadexception', this.onLoad, this);
33118         this.removeMask = Ext.value(this.removeMask, false);
33119     }else{
33120         var um = this.el.getUpdater();
33121         um.showLoadIndicator = false;         um.on('beforeupdate', this.onBeforeLoad, this);
33122         um.on('update', this.onLoad, this);
33123         um.on('failure', this.onLoad, this);
33124         this.removeMask = Ext.value(this.removeMask, true);
33125     }
33126 };
33127
33128 Ext.LoadMask.prototype = {
33129     
33130     
33131     
33132     msg : 'Loading...',
33133     
33134     msgCls : 'x-mask-loading',
33135
33136     
33137     disabled: false,
33138
33139     
33140     disable : function(){
33141        this.disabled = true;
33142     },
33143
33144     
33145     enable : function(){
33146         this.disabled = false;
33147     },
33148
33149         onLoad : function(){
33150         this.el.unmask(this.removeMask);
33151     },
33152
33153         onBeforeLoad : function(){
33154         if(!this.disabled){
33155             this.el.mask(this.msg, this.msgCls);
33156         }
33157     },
33158
33159     
33160     show: function(){
33161         this.onBeforeLoad();
33162     },
33163
33164     
33165     hide: function(){
33166         this.onLoad();    
33167     },
33168
33169         destroy : function(){
33170         if(this.store){
33171             this.store.un('beforeload', this.onBeforeLoad, this);
33172             this.store.un('load', this.onLoad, this);
33173             this.store.un('loadexception', this.onLoad, this);
33174         }else{
33175             var um = this.el.getUpdater();
33176             um.un('beforeupdate', this.onBeforeLoad, this);
33177             um.un('update', this.onLoad, this);
33178             um.un('failure', this.onLoad, this);
33179         }
33180     }
33181 };
33182 \r
33183 Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {\r
33184    \r
33185     baseCls : 'x-progress',\r
33186 \r
33187     
33188     waitTimer : null,\r
33189 \r
33190     
33191     initComponent : function(){\r
33192         Ext.ProgressBar.superclass.initComponent.call(this);\r
33193         this.addEvents(\r
33194             \r
33195             "update"\r
33196         );\r
33197     },\r
33198 \r
33199     
33200     onRender : function(ct, position){\r
33201         Ext.ProgressBar.superclass.onRender.call(this, ct, position);\r
33202 \r
33203         var tpl = new Ext.Template(\r
33204             '<div class="{cls}-wrap">',\r
33205                 '<div class="{cls}-inner">',\r
33206                     '<div class="{cls}-bar">',\r
33207                         '<div class="{cls}-text">',\r
33208                             '<div>&#160;</div>',\r
33209                         '</div>',\r
33210                     '</div>',\r
33211                     '<div class="{cls}-text {cls}-text-back">',\r
33212                         '<div>&#160;</div>',\r
33213                     '</div>',\r
33214                 '</div>',\r
33215             '</div>'\r
33216         );\r
33217 \r
33218         if(position){\r
33219             this.el = tpl.insertBefore(position, {cls: this.baseCls}, true);\r
33220         }else{\r
33221             this.el = tpl.append(ct, {cls: this.baseCls}, true);\r
33222         }\r
33223         if(this.id){\r
33224             this.el.dom.id = this.id;\r
33225         }\r
33226         var inner = this.el.dom.firstChild;\r
33227         this.progressBar = Ext.get(inner.firstChild);\r
33228 \r
33229         if(this.textEl){\r
33230             
33231             this.textEl = Ext.get(this.textEl);\r
33232             delete this.textTopEl;\r
33233         }else{\r
33234             
33235             this.textTopEl = Ext.get(this.progressBar.dom.firstChild);\r
33236             var textBackEl = Ext.get(inner.childNodes[1]);\r
33237             this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');\r
33238             this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);\r
33239             this.textEl.setWidth(inner.offsetWidth);\r
33240         }\r
33241         if(this.value){\r
33242             this.updateProgress(this.value, this.text);\r
33243         }else{\r
33244             this.updateText(this.text);\r
33245         }\r
33246         this.setSize(this.width || 'auto', 'auto');\r
33247         this.progressBar.setHeight(inner.offsetHeight);\r
33248     },\r
33249 \r
33250     \r
33251     updateProgress : function(value, text){\r
33252         this.value = value || 0;\r
33253         if(text){\r
33254             this.updateText(text);\r
33255         }\r
33256         var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);\r
33257         this.progressBar.setWidth(w);\r
33258         if(this.textTopEl){\r
33259             
33260             this.textTopEl.removeClass('x-hidden').setWidth(w);\r
33261         }\r
33262         this.fireEvent('update', this, value, text);\r
33263         return this;\r
33264     },\r
33265 \r
33266     \r
33267     wait : function(o){\r
33268         if(!this.waitTimer){\r
33269             var scope = this;\r
33270             o = o || {};\r
33271             this.waitTimer = Ext.TaskMgr.start({\r
33272                 run: function(i){\r
33273                     var inc = o.increment || 10;\r
33274                     this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*.01);\r
33275                 },\r
33276                 interval: o.interval || 1000,\r
33277                 duration: o.duration,\r
33278                 onStop: function(){\r
33279                     if(o.fn){\r
33280                         o.fn.apply(o.scope || this);\r
33281                     }\r
33282                     this.reset();\r
33283                 },\r
33284                 scope: scope\r
33285             });\r
33286         }\r
33287         return this;\r
33288     },\r
33289 \r
33290     \r
33291     isWaiting : function(){\r
33292         return this.waitTimer != null;\r
33293     },\r
33294 \r
33295     \r
33296     updateText : function(text){\r
33297         this.text = text || '&#160;';\r
33298         this.textEl.update(this.text);\r
33299         return this;\r
33300     },\r
33301 \r
33302     \r
33303     setSize : function(w, h){\r
33304         Ext.ProgressBar.superclass.setSize.call(this, w, h);\r
33305         if(this.textTopEl){\r
33306             var inner = this.el.dom.firstChild;\r
33307             this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);\r
33308         }\r
33309         return this;\r
33310     },\r
33311 \r
33312     \r
33313     reset : function(hide){\r
33314         this.updateProgress(0);\r
33315         if(this.textTopEl){\r
33316             this.textTopEl.addClass('x-hidden');\r
33317         }\r
33318         if(this.waitTimer){\r
33319             this.waitTimer.onStop = null; 
33320             Ext.TaskMgr.stop(this.waitTimer);\r
33321             this.waitTimer = null;\r
33322         }\r
33323         if(hide === true){\r
33324             this.hide();\r
33325         }\r
33326         return this;\r
33327     }\r
33328 });\r
33329 Ext.reg('progress', Ext.ProgressBar);
33330 Ext.debug = {};
33331
33332 (function(){
33333
33334 var cp;
33335
33336 function createConsole(){
33337
33338     var scriptPanel = new Ext.debug.ScriptsPanel();
33339     var logView = new Ext.debug.LogPanel();
33340     var tree = new Ext.debug.DomTree();
33341
33342     var tabs = new Ext.TabPanel({
33343         activeTab: 0,
33344         border: false,
33345         tabPosition: 'bottom',
33346         items: [{
33347             title: 'Debug Console',
33348             layout:'border',
33349             items: [logView, scriptPanel]
33350         },{
33351             title: 'DOM Inspector',
33352             layout:'border',
33353             items: [tree]
33354         }]
33355     });
33356
33357     cp = new Ext.Panel({
33358         id: 'x-debug-browser',
33359         title: 'Console',
33360         collapsible: true,
33361         animCollapse: false,
33362         style: 'position:absolute;left:0;bottom:0;',
33363         height:200,
33364         logView: logView,
33365         layout: 'fit',
33366         
33367         tools:[{
33368             id: 'close',
33369             handler: function(){
33370                 cp.destroy();
33371                 cp = null;
33372                 Ext.EventManager.removeResizeListener(handleResize);
33373             }
33374         }],
33375
33376         items: tabs
33377     });
33378
33379     cp.render(document.body);
33380
33381     cp.resizer = new Ext.Resizable(cp.el, {
33382         minHeight:50,
33383         handles: "n",
33384         pinned: true,
33385         transparent:true,
33386         resizeElement : function(){
33387             var box = this.proxy.getBox();
33388             this.proxy.hide();
33389             cp.setHeight(box.height);
33390             return box;
33391         }
33392     });
33393
33394     function handleResize(){
33395         cp.setWidth(Ext.getBody().getViewSize().width);
33396     }
33397     Ext.EventManager.onWindowResize(handleResize);
33398
33399     handleResize();
33400 }
33401
33402
33403 Ext.apply(Ext, {
33404     log : function(){
33405         if(!cp){
33406             createConsole();
33407         }
33408         cp.logView.log.apply(cp.logView, arguments);
33409     },
33410
33411     logf : function(format, arg1, arg2, etc){
33412         Ext.log(String.format.apply(String, arguments));
33413     },
33414
33415     dump : function(o){
33416         if(typeof o == 'string' || typeof o == 'number' || typeof o == 'undefined' || Ext.isDate(o)){
33417             Ext.log(o);
33418         }else if(!o){
33419             Ext.log("null");
33420         }else if(typeof o != "object"){
33421             Ext.log('Unknown return type');
33422         }else if(Ext.isArray(o)){
33423             Ext.log('['+o.join(',')+']');
33424         }else{
33425             var b = ["{\n"];
33426             for(var key in o){
33427                 var to = typeof o[key];
33428                 if(to != "function" && to != "object"){
33429                     b.push(String.format("  {0}: {1},\n", key, o[key]));
33430                 }
33431             }
33432             var s = b.join("");
33433             if(s.length > 3){
33434                 s = s.substr(0, s.length-2);
33435             }
33436             Ext.log(s + "\n}");
33437         }
33438     },
33439
33440     _timers : {},
33441
33442     time : function(name){
33443         name = name || "def";
33444         Ext._timers[name] = new Date().getTime();
33445     },
33446
33447     timeEnd : function(name, printResults){
33448         var t = new Date().getTime();
33449         name = name || "def";
33450         var v = String.format("{0} ms", t-Ext._timers[name]);
33451         Ext._timers[name] = new Date().getTime();
33452         if(printResults !== false){
33453             Ext.log('Timer ' + (name == "def" ? v : name + ": " + v));
33454         }
33455         return v;
33456     }
33457 });
33458
33459 })();
33460
33461
33462 Ext.debug.ScriptsPanel = Ext.extend(Ext.Panel, {
33463     id:'x-debug-scripts',
33464     region: 'east',
33465     minWidth: 200,
33466     split: true,
33467     width: 350,
33468     border: false,
33469     layout:'anchor',
33470     style:'border-width:0 0 0 1px;',
33471
33472     initComponent : function(){
33473
33474         this.scriptField = new Ext.form.TextArea({
33475             anchor: '100% -26',
33476             style:'border-width:0;'
33477         });
33478
33479         this.trapBox = new Ext.form.Checkbox({
33480             id: 'console-trap',
33481             boxLabel: 'Trap Errors',
33482             checked: true
33483         });
33484
33485         this.toolbar = new Ext.Toolbar([{
33486                 text: 'Run',
33487                 scope: this,
33488                 handler: this.evalScript
33489             },{
33490                 text: 'Clear',
33491                 scope: this,
33492                 handler: this.clear
33493             },
33494             '->',
33495             this.trapBox,
33496             ' ', ' '
33497         ]);
33498
33499         this.items = [this.toolbar, this.scriptField];
33500
33501         Ext.debug.ScriptsPanel.superclass.initComponent.call(this);
33502     },
33503
33504     evalScript : function(){
33505         var s = this.scriptField.getValue();
33506         if(this.trapBox.getValue()){
33507             try{
33508                 var rt = eval(s);
33509                 Ext.dump(rt === undefined? '(no return)' : rt);
33510             }catch(e){
33511                 Ext.log(e.message || e.descript);
33512             }
33513         }else{
33514             var rt = eval(s);
33515             Ext.dump(rt === undefined? '(no return)' : rt);
33516         }
33517     },
33518
33519     clear : function(){
33520         this.scriptField.setValue('');
33521         this.scriptField.focus();
33522     }
33523
33524 });
33525
33526 Ext.debug.LogPanel = Ext.extend(Ext.Panel, {
33527     autoScroll: true,
33528     region: 'center',
33529     border: false,
33530     style:'border-width:0 1px 0 0',
33531
33532     log : function(){
33533         var markup = [  '<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
33534                     Ext.util.Format.htmlEncode(Array.prototype.join.call(arguments, ', ')).replace(/\n/g, '<br />').replace(/\s/g, '&#160;'),
33535                     '</div>'].join('');
33536
33537         this.body.insertHtml('beforeend', markup);
33538         this.body.scrollTo('top', 100000);
33539     },
33540
33541     clear : function(){
33542         this.body.update('');
33543         this.body.dom.scrollTop = 0;
33544     }
33545 });
33546
33547 Ext.debug.DomTree = Ext.extend(Ext.tree.TreePanel, {
33548     enableDD:false ,
33549     lines:false,
33550     rootVisible:false,
33551     animate:false,
33552     hlColor:'ffff9c',
33553     autoScroll: true,
33554     region:'center',
33555     border:false,
33556
33557     initComponent : function(){
33558
33559
33560         Ext.debug.DomTree.superclass.initComponent.call(this);
33561         
33562                 var styles = false, hnode;
33563         var nonSpace = /^\s*$/;
33564         var html = Ext.util.Format.htmlEncode;
33565         var ellipsis = Ext.util.Format.ellipsis;
33566         var styleRe = /\s?([a-z\-]*)\:([^;]*)(?:[;\s\n\r]*)/gi;
33567
33568         function findNode(n){
33569             if(!n || n.nodeType != 1 || n == document.body || n == document){
33570                 return false;
33571             }
33572             var pn = [n], p = n;
33573             while((p = p.parentNode) && p.nodeType == 1 && p.tagName.toUpperCase() != 'HTML'){
33574                 pn.unshift(p);
33575             }
33576             var cn = hnode;
33577             for(var i = 0, len = pn.length; i < len; i++){
33578                 cn.expand();
33579                 cn = cn.findChild('htmlNode', pn[i]);
33580                 if(!cn){                     return false;
33581                 }
33582             }
33583             cn.select();
33584             var a = cn.ui.anchor;
33585             treeEl.dom.scrollTop = Math.max(0 ,a.offsetTop-10);
33586                         cn.highlight();
33587             return true;
33588         }
33589
33590         function nodeTitle(n){
33591             var s = n.tagName;
33592             if(n.id){
33593                 s += '#'+n.id;
33594             }else if(n.className){
33595                 s += '.'+n.className;
33596             }
33597             return s;
33598         }
33599
33600         function onNodeSelect(t, n, last){
33601             return;
33602             if(last && last.unframe){
33603                 last.unframe();
33604             }
33605             var props = {};
33606             if(n && n.htmlNode){
33607                 if(frameEl.pressed){
33608                     n.frame();
33609                 }
33610                 if(inspecting){
33611                     return;
33612                 }
33613                 addStyle.enable();
33614                 reload.setDisabled(n.leaf);
33615                 var dom = n.htmlNode;
33616                 stylePanel.setTitle(nodeTitle(dom));
33617                 if(styles && !showAll.pressed){
33618                     var s = dom.style ? dom.style.cssText : '';
33619                     if(s){
33620                         var m;
33621                         while ((m = styleRe.exec(s)) != null){
33622                             props[m[1].toLowerCase()] = m[2];
33623                         }
33624                     }
33625                 }else if(styles){
33626                     var cl = Ext.debug.cssList;
33627                     var s = dom.style, fly = Ext.fly(dom);
33628                     if(s){
33629                         for(var i = 0, len = cl.length; i<len; i++){
33630                             var st = cl[i];
33631                             var v = s[st] || fly.getStyle(st);
33632                             if(v != undefined && v !== null && v !== ''){
33633                                 props[st] = v;
33634                             }
33635                         }
33636                     }
33637                 }else{
33638                     for(var a in dom){
33639                         var v = dom[a];
33640                         if((isNaN(a+10)) && v != undefined && v !== null && v !== '' && !(Ext.isGecko && a[0] == a[0].toUpperCase())){
33641                             props[a] = v;
33642                         }
33643                     }
33644                 }
33645             }else{
33646                 if(inspecting){
33647                     return;
33648                 }
33649                 addStyle.disable();
33650                 reload.disabled();
33651             }
33652             stylesGrid.setSource(props);
33653             stylesGrid.treeNode = n;
33654             stylesGrid.view.fitColumns();
33655         }
33656
33657         this.loader = new Ext.tree.TreeLoader();
33658         this.loader.load = function(n, cb){
33659             var isBody = n.htmlNode == document.body;
33660             var cn = n.htmlNode.childNodes;
33661             for(var i = 0, c; c = cn[i]; i++){
33662                 if(isBody && c.id == 'x-debug-browser'){
33663                     continue;
33664                 }
33665                 if(c.nodeType == 1){
33666                     n.appendChild(new Ext.debug.HtmlNode(c));
33667                 }else if(c.nodeType == 3 && !nonSpace.test(c.nodeValue)){
33668                     n.appendChild(new Ext.tree.TreeNode({
33669                         text:'<em>' + ellipsis(html(String(c.nodeValue)), 35) + '</em>',
33670                         cls: 'x-tree-noicon'
33671                     }));
33672                 }
33673             }
33674             cb();
33675         };
33676
33677         
33678         this.root = this.setRootNode(new Ext.tree.TreeNode('Ext'));
33679
33680         hnode = this.root.appendChild(new Ext.debug.HtmlNode(
33681                 document.getElementsByTagName('html')[0]
33682         ));
33683
33684     }
33685 });
33686
33687
33688 Ext.debug.HtmlNode = function(){
33689     var html = Ext.util.Format.htmlEncode;
33690     var ellipsis = Ext.util.Format.ellipsis;
33691     var nonSpace = /^\s*$/;
33692
33693     var attrs = [
33694         {n: 'id', v: 'id'},
33695         {n: 'className', v: 'class'},
33696         {n: 'name', v: 'name'},
33697         {n: 'type', v: 'type'},
33698         {n: 'src', v: 'src'},
33699         {n: 'href', v: 'href'}
33700     ];
33701
33702     function hasChild(n){
33703         for(var i = 0, c; c = n.childNodes[i]; i++){
33704             if(c.nodeType == 1){
33705                 return true;
33706             }
33707         }
33708         return false;
33709     }
33710
33711     function renderNode(n, leaf){
33712         var tag = n.tagName.toLowerCase();
33713         var s = '&lt;' + tag;
33714         for(var i = 0, len = attrs.length; i < len; i++){
33715             var a = attrs[i];
33716             var v = n[a.n];
33717             if(v && !nonSpace.test(v)){
33718                 s += ' ' + a.v + '=&quot;<i>' + html(v) +'</i>&quot;';
33719             }
33720         }
33721         var style = n.style ? n.style.cssText : '';
33722         if(style){
33723             s += ' style=&quot;<i>' + html(style.toLowerCase()) +'</i>&quot;';
33724         }
33725         if(leaf && n.childNodes.length > 0){
33726             s+='&gt;<em>' + ellipsis(html(String(n.innerHTML)), 35) + '</em>&lt;/'+tag+'&gt;';
33727         }else if(leaf){
33728             s += ' /&gt;';
33729         }else{
33730             s += '&gt;';
33731         }
33732         return s;
33733     }
33734
33735     var HtmlNode = function(n){
33736         var leaf = !hasChild(n);
33737         this.htmlNode = n;
33738         this.tagName = n.tagName.toLowerCase();
33739         var attr = {
33740             text : renderNode(n, leaf),
33741             leaf : leaf,
33742             cls: 'x-tree-noicon'
33743         };
33744         HtmlNode.superclass.constructor.call(this, attr);
33745         this.attributes.htmlNode = n;         if(!leaf){
33746             this.on('expand', this.onExpand,  this);
33747             this.on('collapse', this.onCollapse,  this);
33748         }
33749     };
33750
33751
33752     Ext.extend(HtmlNode, Ext.tree.AsyncTreeNode, {
33753         cls: 'x-tree-noicon',
33754         preventHScroll: true,
33755         refresh : function(highlight){
33756             var leaf = !hasChild(this.htmlNode);
33757             this.setText(renderNode(this.htmlNode, leaf));
33758             if(highlight){
33759                 Ext.fly(this.ui.textNode).highlight();
33760             }
33761         },
33762
33763         onExpand : function(){
33764             if(!this.closeNode && this.parentNode){
33765                 this.closeNode = this.parentNode.insertBefore(new Ext.tree.TreeNode({
33766                     text:'&lt;/' + this.tagName + '&gt;',
33767                     cls: 'x-tree-noicon'
33768                 }), this.nextSibling);
33769             }else if(this.closeNode){
33770                 this.closeNode.ui.show();
33771             }
33772         },
33773
33774         onCollapse : function(){
33775             if(this.closeNode){
33776                 this.closeNode.ui.hide();
33777             }
33778         },
33779
33780         render : function(bulkRender){
33781             HtmlNode.superclass.render.call(this, bulkRender);
33782         },
33783
33784         highlightNode : function(){
33785                     },
33786
33787         highlight : function(){
33788                     },
33789
33790         frame : function(){
33791             this.htmlNode.style.border = '1px solid #0000ff';
33792                     },
33793
33794         unframe : function(){
33795                         this.htmlNode.style.border = '';
33796         }
33797     });
33798
33799     return HtmlNode;
33800 }();
33801
33802
33803