Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-routing-foss4g/web/ext/pkgs/window-debug.js @ 77

Revision 76, 74.3 KB checked in by djay, 13 years ago (diff)

Ajout du répertoire web

  • Property svn:executable set to *
RevLine 
[76]1/*!
2 * Ext JS Library 3.4.0
3 * Copyright(c) 2006-2011 Sencha Inc.
4 * licensing@sencha.com
5 * http://www.sencha.com/license
6 */
7/**
8 * @class Ext.Window
9 * @extends Ext.Panel
10 * <p>A specialized panel intended for use as an application window.  Windows are floated, {@link #resizable}, and
11 * {@link #draggable} by default.  Windows can be {@link #maximizable maximized} to fill the viewport,
12 * restored to their prior size, and can be {@link #minimize}d.</p>
13 * <p>Windows can also be linked to a {@link Ext.WindowGroup} or managed by the {@link Ext.WindowMgr} to provide
14 * grouping, activation, to front, to back and other application-specific behavior.</p>
15 * <p>By default, Windows will be rendered to document.body. To {@link #constrain} a Window to another element
16 * specify {@link Ext.Component#renderTo renderTo}.</p>
17 * <p><b>Note:</b> By default, the <code>{@link #closable close}</code> header tool <i>destroys</i> the Window resulting in
18 * destruction of any child Components. This makes the Window object, and all its descendants <b>unusable</b>. To enable
19 * re-use of a Window, use <b><code>{@link #closeAction closeAction: 'hide'}</code></b>.</p>
20 * @constructor
21 * @param {Object} config The config object
22 * @xtype window
23 */
24Ext.Window = Ext.extend(Ext.Panel, {
25    /**
26     * @cfg {Number} x
27     * The X position of the left edge of the window on initial showing. Defaults to centering the Window within
28     * the width of the Window's container {@link Ext.Element Element) (The Element that the Window is rendered to).
29     */
30    /**
31     * @cfg {Number} y
32     * The Y position of the top edge of the window on initial showing. Defaults to centering the Window within
33     * the height of the Window's container {@link Ext.Element Element) (The Element that the Window is rendered to).
34     */
35    /**
36     * @cfg {Boolean} modal
37     * True to make the window modal and mask everything behind it when displayed, false to display it without
38     * restricting access to other UI elements (defaults to false).
39     */
40    /**
41     * @cfg {String/Element} animateTarget
42     * Id or element from which the window should animate while opening (defaults to null with no animation).
43     */
44    /**
45     * @cfg {String} resizeHandles
46     * A valid {@link Ext.Resizable} handles config string (defaults to 'all').  Only applies when resizable = true.
47     */
48    /**
49     * @cfg {Ext.WindowGroup} manager
50     * A reference to the WindowGroup that should manage this window (defaults to {@link Ext.WindowMgr}).
51     */
52    /**
53    * @cfg {String/Number/Component} defaultButton
54    * <p>Specifies a Component to receive focus when this Window is focussed.</p>
55    * <p>This may be one of:</p><div class="mdetail-params"><ul>
56    * <li>The index of a footer Button.</li>
57    * <li>The id of a Component.</li>
58    * <li>A Component.</li>
59    * </ul></div>
60    */
61    /**
62    * @cfg {Function} onEsc
63    * Allows override of the built-in processing for the escape key. Default action
64    * is to close the Window (performing whatever action is specified in {@link #closeAction}.
65    * To prevent the Window closing when the escape key is pressed, specify this as
66    * Ext.emptyFn (See {@link Ext#emptyFn}).
67    */
68    /**
69     * @cfg {Boolean} collapsed
70     * True to render the window collapsed, false to render it expanded (defaults to false). Note that if
71     * {@link #expandOnShow} is true (the default) it will override the <tt>collapsed</tt> config and the window
72     * will always be expanded when shown.
73     */
74    /**
75     * @cfg {Boolean} maximized
76     * True to initially display the window in a maximized state. (Defaults to false).
77     */
78
79    /**
80    * @cfg {String} baseCls
81    * The base CSS class to apply to this panel's element (defaults to 'x-window').
82    */
83    baseCls : 'x-window',
84    /**
85     * @cfg {Boolean} resizable
86     * True to allow user resizing at each edge and corner of the window, false to disable resizing (defaults to true).
87     */
88    resizable : true,
89    /**
90     * @cfg {Boolean} draggable
91     * True to allow the window to be dragged by the header bar, false to disable dragging (defaults to true).  Note
92     * that by default the window will be centered in the viewport, so if dragging is disabled the window may need
93     * to be positioned programmatically after render (e.g., myWindow.setPosition(100, 100);).
94     */
95    draggable : true,
96    /**
97     * @cfg {Boolean} closable
98     * <p>True to display the 'close' tool button and allow the user to close the window, false to
99     * hide the button and disallow closing the window (defaults to true).</p>
100     * <p>By default, when close is requested by either clicking the close button in the header
101     * or pressing ESC when the Window has focus, the {@link #close} method will be called. This
102     * will <i>{@link Ext.Component#destroy destroy}</i> the Window and its content meaning that
103     * it may not be reused.</p>
104     * <p>To make closing a Window <i>hide</i> the Window so that it may be reused, set
105     * {@link #closeAction} to 'hide'.
106     */
107    closable : true,
108    /**
109     * @cfg {String} closeAction
110     * <p>The action to take when the close header tool is clicked:
111     * <div class="mdetail-params"><ul>
112     * <li><b><code>'{@link #close}'</code></b> : <b>Default</b><div class="sub-desc">
113     * {@link #close remove} the window from the DOM and {@link Ext.Component#destroy destroy}
114     * it and all descendant Components. The window will <b>not</b> be available to be
115     * redisplayed via the {@link #show} method.
116     * </div></li>
117     * <li><b><code>'{@link #hide}'</code></b> : <div class="sub-desc">
118     * {@link #hide} the window by setting visibility to hidden and applying negative offsets.
119     * The window will be available to be redisplayed via the {@link #show} method.
120     * </div></li>
121     * </ul></div>
122     * <p><b>Note:</b> This setting does not affect the {@link #close} method
123     * which will always {@link Ext.Component#destroy destroy} the window. To
124     * programatically <i>hide</i> a window, call {@link #hide}.</p>
125     */
126    closeAction : 'close',
127    /**
128     * @cfg {Boolean} constrain
129     * True to constrain the window within its containing element, false to allow it to fall outside of its
130     * containing element. By default the window will be rendered to document.body.  To render and constrain the
131     * window within another element specify {@link #renderTo}.
132     * (defaults to false).  Optionally the header only can be constrained using {@link #constrainHeader}.
133     */
134    constrain : false,
135    /**
136     * @cfg {Boolean} constrainHeader
137     * True to constrain the window header within its containing element (allowing the window body to fall outside
138     * of its containing element) or false to allow the header to fall outside its containing element (defaults to
139     * false). Optionally the entire window can be constrained using {@link #constrain}.
140     */
141    constrainHeader : false,
142    /**
143     * @cfg {Boolean} plain
144     * True to render the window body with a transparent background so that it will blend into the framing
145     * elements, false to add a lighter background color to visually highlight the body element and separate it
146     * more distinctly from the surrounding frame (defaults to false).
147     */
148    plain : false,
149    /**
150     * @cfg {Boolean} minimizable
151     * True to display the 'minimize' tool button and allow the user to minimize the window, false to hide the button
152     * and disallow minimizing the window (defaults to false).  Note that this button provides no implementation --
153     * the behavior of minimizing a window is implementation-specific, so the minimize event must be handled and a
154     * custom minimize behavior implemented for this option to be useful.
155     */
156    minimizable : false,
157    /**
158     * @cfg {Boolean} maximizable
159     * True to display the 'maximize' tool button and allow the user to maximize the window, false to hide the button
160     * and disallow maximizing the window (defaults to false).  Note that when a window is maximized, the tool button
161     * will automatically change to a 'restore' button with the appropriate behavior already built-in that will
162     * restore the window to its previous size.
163     */
164    maximizable : false,
165    /**
166     * @cfg {Number} minHeight
167     * The minimum height in pixels allowed for this window (defaults to 100).  Only applies when resizable = true.
168     */
169    minHeight : 100,
170    /**
171     * @cfg {Number} minWidth
172     * The minimum width in pixels allowed for this window (defaults to 200).  Only applies when resizable = true.
173     */
174    minWidth : 200,
175    /**
176     * @cfg {Boolean} expandOnShow
177     * True to always expand the window when it is displayed, false to keep it in its current state (which may be
178     * {@link #collapsed}) when displayed (defaults to true).
179     */
180    expandOnShow : true,
181   
182    /**
183     * @cfg {Number} showAnimDuration The number of seconds that the window show animation takes if enabled.
184     * Defaults to 0.25
185     */
186    showAnimDuration: 0.25,
187   
188    /**
189     * @cfg {Number} hideAnimDuration The number of seconds that the window hide animation takes if enabled.
190     * Defaults to 0.25
191     */
192    hideAnimDuration: 0.25,
193
194    // inherited docs, same default
195    collapsible : false,
196
197    /**
198     * @cfg {Boolean} initHidden
199     * True to hide the window until show() is explicitly called (defaults to true).
200     * @deprecated
201     */
202    initHidden : undefined,
203
204    /**
205     * @cfg {Boolean} hidden
206     * Render this component hidden (default is <tt>true</tt>). If <tt>true</tt>, the
207     * {@link #hide} method will be called internally.
208     */
209    hidden : true,
210
211    // The following configs are set to provide the basic functionality of a window.
212    // Changing them would require additional code to handle correctly and should
213    // usually only be done in subclasses that can provide custom behavior.  Changing them
214    // may have unexpected or undesirable results.
215    /** @cfg {String} elements @hide */
216    elements : 'header,body',
217    /** @cfg {Boolean} frame @hide */
218    frame : true,
219    /** @cfg {Boolean} floating @hide */
220    floating : true,
221
222    // private
223    initComponent : function(){
224        this.initTools();
225        Ext.Window.superclass.initComponent.call(this);
226        this.addEvents(
227            /**
228             * @event activate
229             * Fires after the window has been visually activated via {@link #setActive}.
230             * @param {Ext.Window} this
231             */
232            /**
233             * @event deactivate
234             * Fires after the window has been visually deactivated via {@link #setActive}.
235             * @param {Ext.Window} this
236             */
237            /**
238             * @event resize
239             * Fires after the window has been resized.
240             * @param {Ext.Window} this
241             * @param {Number} width The window's new width
242             * @param {Number} height The window's new height
243             */
244            'resize',
245            /**
246             * @event maximize
247             * Fires after the window has been maximized.
248             * @param {Ext.Window} this
249             */
250            'maximize',
251            /**
252             * @event minimize
253             * Fires after the window has been minimized.
254             * @param {Ext.Window} this
255             */
256            'minimize',
257            /**
258             * @event restore
259             * Fires after the window has been restored to its original size after being maximized.
260             * @param {Ext.Window} this
261             */
262            'restore'
263        );
264        // for backwards compat, this should be removed at some point
265        if(Ext.isDefined(this.initHidden)){
266            this.hidden = this.initHidden;
267        }
268        if(this.hidden === false){
269            this.hidden = true;
270            this.show();
271        }
272    },
273
274    // private
275    getState : function(){
276        return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true));
277    },
278
279    // private
280    onRender : function(ct, position){
281        Ext.Window.superclass.onRender.call(this, ct, position);
282
283        if(this.plain){
284            this.el.addClass('x-window-plain');
285        }
286
287        // this element allows the Window to be focused for keyboard events
288        this.focusEl = this.el.createChild({
289                    tag: 'a', href:'#', cls:'x-dlg-focus',
290                    tabIndex:'-1', html: '&#160;'});
291        this.focusEl.swallowEvent('click', true);
292
293        this.proxy = this.el.createProxy('x-window-proxy');
294        this.proxy.enableDisplayMode('block');
295
296        if(this.modal){
297            this.mask = this.container.createChild({cls:'ext-el-mask'}, this.el.dom);
298            this.mask.enableDisplayMode('block');
299            this.mask.hide();
300            this.mon(this.mask, 'click', this.focus, this);
301        }
302        if(this.maximizable){
303            this.mon(this.header, 'dblclick', this.toggleMaximize, this);
304        }
305    },
306
307    // private
308    initEvents : function(){
309        Ext.Window.superclass.initEvents.call(this);
310        if(this.animateTarget){
311            this.setAnimateTarget(this.animateTarget);
312        }
313
314        if(this.resizable){
315            this.resizer = new Ext.Resizable(this.el, {
316                minWidth: this.minWidth,
317                minHeight:this.minHeight,
318                handles: this.resizeHandles || 'all',
319                pinned: true,
320                resizeElement : this.resizerAction,
321                handleCls: 'x-window-handle'
322            });
323            this.resizer.window = this;
324            this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
325        }
326
327        if(this.draggable){
328            this.header.addClass('x-window-draggable');
329        }
330        this.mon(this.el, 'mousedown', this.toFront, this);
331        this.manager = this.manager || Ext.WindowMgr;
332        this.manager.register(this);
333        if(this.maximized){
334            this.maximized = false;
335            this.maximize();
336        }
337        if(this.closable){
338            var km = this.getKeyMap();
339            km.on(27, this.onEsc, this);
340            km.disable();
341        }
342    },
343
344    initDraggable : function(){
345        /**
346         * <p>If this Window is configured {@link #draggable}, this property will contain
347         * an instance of {@link Ext.dd.DD} which handles dragging the Window's DOM Element.</p>
348         * <p>This has implementations of <code>startDrag</code>, <code>onDrag</code> and <code>endDrag</code>
349         * which perform the dragging action. If extra logic is needed at these points, use
350         * {@link Function#createInterceptor createInterceptor} or {@link Function#createSequence createSequence} to
351         * augment the existing implementations.</p>
352         * @type Ext.dd.DD
353         * @property dd
354         */
355        this.dd = new Ext.Window.DD(this);
356    },
357
358   // private
359    onEsc : function(k, e){
360        if (this.activeGhost) {
361            this.unghost();
362        }
363        e.stopEvent();
364        this[this.closeAction]();
365    },
366
367    // private
368    beforeDestroy : function(){
369        if(this.rendered){
370            this.hide();
371            this.clearAnchor();
372            Ext.destroy(
373                this.focusEl,
374                this.resizer,
375                this.dd,
376                this.proxy,
377                this.mask
378            );
379        }
380        Ext.Window.superclass.beforeDestroy.call(this);
381    },
382
383    // private
384    onDestroy : function(){
385        if(this.manager){
386            this.manager.unregister(this);
387        }
388        Ext.Window.superclass.onDestroy.call(this);
389    },
390
391    // private
392    initTools : function(){
393        if(this.minimizable){
394            this.addTool({
395                id: 'minimize',
396                handler: this.minimize.createDelegate(this, [])
397            });
398        }
399        if(this.maximizable){
400            this.addTool({
401                id: 'maximize',
402                handler: this.maximize.createDelegate(this, [])
403            });
404            this.addTool({
405                id: 'restore',
406                handler: this.restore.createDelegate(this, []),
407                hidden:true
408            });
409        }
410        if(this.closable){
411            this.addTool({
412                id: 'close',
413                handler: this[this.closeAction].createDelegate(this, [])
414            });
415        }
416    },
417
418    // private
419    resizerAction : function(){
420        var box = this.proxy.getBox();
421        this.proxy.hide();
422        this.window.handleResize(box);
423        return box;
424    },
425
426    // private
427    beforeResize : function(){
428        this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40); // 40 is a magic minimum content size?
429        this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
430        this.resizeBox = this.el.getBox();
431    },
432
433    // private
434    updateHandles : function(){
435        if(Ext.isIE && this.resizer){
436            this.resizer.syncHandleHeight();
437            this.el.repaint();
438        }
439    },
440
441    // private
442    handleResize : function(box){
443        var rz = this.resizeBox;
444        if(rz.x != box.x || rz.y != box.y){
445            this.updateBox(box);
446        }else{
447            this.setSize(box);
448            if (Ext.isIE6 && Ext.isStrict) {
449                this.doLayout();
450            }
451        }
452        this.focus();
453        this.updateHandles();
454        this.saveState();
455    },
456
457    /**
458     * Focuses the window.  If a defaultButton is set, it will receive focus, otherwise the
459     * window itself will receive focus.
460     */
461    focus : function(){
462        var f = this.focusEl,
463            db = this.defaultButton,
464            t = typeof db,
465            el,
466            ct;
467        if(Ext.isDefined(db)){
468            if(Ext.isNumber(db) && this.fbar){
469                f = this.fbar.items.get(db);
470            }else if(Ext.isString(db)){
471                f = Ext.getCmp(db);
472            }else{
473                f = db;
474            }
475            el = f.getEl();
476            ct = Ext.getDom(this.container);
477            if (el && ct) {
478                if (ct != document.body && !Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){
479                    return;
480                }
481            }
482        }
483        f = f || this.focusEl;
484        f.focus.defer(10, f);
485    },
486
487    /**
488     * Sets the target element from which the window should animate while opening.
489     * @param {String/Element} el The target element or id
490     */
491    setAnimateTarget : function(el){
492        el = Ext.get(el);
493        this.animateTarget = el;
494    },
495
496    // private
497    beforeShow : function(){
498        delete this.el.lastXY;
499        delete this.el.lastLT;
500        if(this.x === undefined || this.y === undefined){
501            var xy = this.el.getAlignToXY(this.container, 'c-c');
502            var pos = this.el.translatePoints(xy[0], xy[1]);
503            this.x = this.x === undefined? pos.left : this.x;
504            this.y = this.y === undefined? pos.top : this.y;
505        }
506        this.el.setLeftTop(this.x, this.y);
507
508        if(this.expandOnShow){
509            this.expand(false);
510        }
511
512        if(this.modal){
513            Ext.getBody().addClass('x-body-masked');
514            this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
515            this.mask.show();
516        }
517    },
518
519    /**
520     * Shows the window, rendering it first if necessary, or activates it and brings it to front if hidden.
521     * @param {String/Element} animateTarget (optional) The target element or id from which the window should
522     * animate while opening (defaults to null with no animation)
523     * @param {Function} callback (optional) A callback function to call after the window is displayed
524     * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to this Window.
525     * @return {Ext.Window} this
526     */
527    show : function(animateTarget, cb, scope){
528        if(!this.rendered){
529            this.render(Ext.getBody());
530        }
531        if(this.hidden === false){
532            this.toFront();
533            return this;
534        }
535        if(this.fireEvent('beforeshow', this) === false){
536            return this;
537        }
538        if(cb){
539            this.on('show', cb, scope, {single:true});
540        }
541        this.hidden = false;
542        if(Ext.isDefined(animateTarget)){
543            this.setAnimateTarget(animateTarget);
544        }
545        this.beforeShow();
546        if(this.animateTarget){
547            this.animShow();
548        }else{
549            this.afterShow();
550        }
551        return this;
552    },
553
554    // private
555    afterShow : function(isAnim){
556        if (this.isDestroyed){
557            return false;
558        }
559        this.proxy.hide();
560        this.el.setStyle('display', 'block');
561        this.el.show();
562        if(this.maximized){
563            this.fitContainer();
564        }
565        if(Ext.isMac && Ext.isGecko2){ // work around stupid FF 2.0/Mac scroll bar bug
566            this.cascade(this.setAutoScroll);
567        }
568
569        if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
570            Ext.EventManager.onWindowResize(this.onWindowResize, this);
571        }
572        this.doConstrain();
573        this.doLayout();
574        if(this.keyMap){
575            this.keyMap.enable();
576        }
577        this.toFront();
578        this.updateHandles();
579        if(isAnim && (Ext.isIE || Ext.isWebKit)){
580            var sz = this.getSize();
581            this.onResize(sz.width, sz.height);
582        }
583        this.onShow();
584        this.fireEvent('show', this);
585    },
586
587    // private
588    animShow : function(){
589        this.proxy.show();
590        this.proxy.setBox(this.animateTarget.getBox());
591        this.proxy.setOpacity(0);
592        var b = this.getBox();
593        this.el.setStyle('display', 'none');
594        this.proxy.shift(Ext.apply(b, {
595            callback: this.afterShow.createDelegate(this, [true], false),
596            scope: this,
597            easing: 'easeNone',
598            duration: this.showAnimDuration,
599            opacity: 0.5
600        }));
601    },
602
603    /**
604     * Hides the window, setting it to invisible and applying negative offsets.
605     * @param {String/Element} animateTarget (optional) The target element or id to which the window should
606     * animate while hiding (defaults to null with no animation)
607     * @param {Function} callback (optional) A callback function to call after the window is hidden
608     * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to this Window.
609     * @return {Ext.Window} this
610     */
611    hide : function(animateTarget, cb, scope){
612        if(this.hidden || this.fireEvent('beforehide', this) === false){
613            return this;
614        }
615        if(cb){
616            this.on('hide', cb, scope, {single:true});
617        }
618        this.hidden = true;
619        if(animateTarget !== undefined){
620            this.setAnimateTarget(animateTarget);
621        }
622        if(this.modal){
623            this.mask.hide();
624            Ext.getBody().removeClass('x-body-masked');
625        }
626        if(this.animateTarget){
627            this.animHide();
628        }else{
629            this.el.hide();
630            this.afterHide();
631        }
632        return this;
633    },
634
635    // private
636    afterHide : function(){
637        this.proxy.hide();
638        if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
639            Ext.EventManager.removeResizeListener(this.onWindowResize, this);
640        }
641        if(this.keyMap){
642            this.keyMap.disable();
643        }
644        this.onHide();
645        this.fireEvent('hide', this);
646    },
647
648    // private
649    animHide : function(){
650        this.proxy.setOpacity(0.5);
651        this.proxy.show();
652        var tb = this.getBox(false);
653        this.proxy.setBox(tb);
654        this.el.hide();
655        this.proxy.shift(Ext.apply(this.animateTarget.getBox(), {
656            callback: this.afterHide,
657            scope: this,
658            duration: this.hideAnimDuration,
659            easing: 'easeNone',
660            opacity: 0
661        }));
662    },
663
664    /**
665     * Method that is called immediately before the <code>show</code> event is fired.
666     * Defaults to <code>Ext.emptyFn</code>.
667     */
668    onShow : Ext.emptyFn,
669
670    /**
671     * Method that is called immediately before the <code>hide</code> event is fired.
672     * Defaults to <code>Ext.emptyFn</code>.
673     */
674    onHide : Ext.emptyFn,
675
676    // private
677    onWindowResize : function(){
678        if(this.maximized){
679            this.fitContainer();
680        }
681        if(this.modal){
682            this.mask.setSize('100%', '100%');
683            var force = this.mask.dom.offsetHeight;
684            this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
685        }
686        this.doConstrain();
687    },
688
689    // private
690    doConstrain : function(){
691        if(this.constrain || this.constrainHeader){
692            var offsets;
693            if(this.constrain){
694                offsets = {
695                    right:this.el.shadowOffset,
696                    left:this.el.shadowOffset,
697                    bottom:this.el.shadowOffset
698                };
699            }else {
700                var s = this.getSize();
701                offsets = {
702                    right:-(s.width - 100),
703                    bottom:-(s.height - 25 + this.el.getConstrainOffset())
704                };
705            }
706
707            var xy = this.el.getConstrainToXY(this.container, true, offsets);
708            if(xy){
709                this.setPosition(xy[0], xy[1]);
710            }
711        }
712    },
713
714    // private - used for dragging
715    ghost : function(cls){
716        var ghost = this.createGhost(cls);
717        var box = this.getBox(true);
718        ghost.setLeftTop(box.x, box.y);
719        ghost.setWidth(box.width);
720        this.el.hide();
721        this.activeGhost = ghost;
722        return ghost;
723    },
724
725    // private
726    unghost : function(show, matchPosition){
727        if(!this.activeGhost) {
728            return;
729        }
730        if(show !== false){
731            this.el.show();
732            this.focus.defer(10, this);
733            if(Ext.isMac && Ext.isGecko2){ // work around stupid FF 2.0/Mac scroll bar bug
734                this.cascade(this.setAutoScroll);
735            }
736        }
737        if(matchPosition !== false){
738            this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
739        }
740        this.activeGhost.hide();
741        this.activeGhost.remove();
742        delete this.activeGhost;
743    },
744
745    /**
746     * Placeholder method for minimizing the window.  By default, this method simply fires the {@link #minimize} event
747     * since the behavior of minimizing a window is application-specific.  To implement custom minimize behavior,
748     * either the minimize event can be handled or this method can be overridden.
749     * @return {Ext.Window} this
750     */
751    minimize : function(){
752        this.fireEvent('minimize', this);
753        return this;
754    },
755
756    /**
757     * <p>Closes the Window, removes it from the DOM, {@link Ext.Component#destroy destroy}s
758     * the Window object and all its descendant Components. The {@link Ext.Panel#beforeclose beforeclose}
759     * event is fired before the close happens and will cancel the close action if it returns false.<p>
760     * <p><b>Note:</b> This method is not affected by the {@link #closeAction} setting which
761     * only affects the action triggered when clicking the {@link #closable 'close' tool in the header}.
762     * To hide the Window without destroying it, call {@link #hide}.</p>
763     */
764    close : function(){
765        if(this.fireEvent('beforeclose', this) !== false){
766            if(this.hidden){
767                this.doClose();
768            }else{
769                this.hide(null, this.doClose, this);
770            }
771        }
772    },
773
774    // private
775    doClose : function(){
776        this.fireEvent('close', this);
777        this.destroy();
778    },
779
780    /**
781     * Fits the window within its current container and automatically replaces
782     * the {@link #maximizable 'maximize' tool button} with the 'restore' tool button.
783     * Also see {@link #toggleMaximize}.
784     * @return {Ext.Window} this
785     */
786    maximize : function(){
787        if(!this.maximized){
788            this.expand(false);
789            this.restoreSize = this.getSize();
790            this.restorePos = this.getPosition(true);
791            if (this.maximizable){
792                this.tools.maximize.hide();
793                this.tools.restore.show();
794            }
795            this.maximized = true;
796            this.el.disableShadow();
797
798            if(this.dd){
799                this.dd.lock();
800            }
801            if(this.collapsible){
802                this.tools.toggle.hide();
803            }
804            this.el.addClass('x-window-maximized');
805            this.container.addClass('x-window-maximized-ct');
806
807            this.setPosition(0, 0);
808            this.fitContainer();
809            this.fireEvent('maximize', this);
810        }
811        return this;
812    },
813
814    /**
815     * Restores a {@link #maximizable maximized}  window back to its original
816     * size and position prior to being maximized and also replaces
817     * the 'restore' tool button with the 'maximize' tool button.
818     * Also see {@link #toggleMaximize}.
819     * @return {Ext.Window} this
820     */
821    restore : function(){
822        if(this.maximized){
823            var t = this.tools;
824            this.el.removeClass('x-window-maximized');
825            if(t.restore){
826                t.restore.hide();
827            }
828            if(t.maximize){
829                t.maximize.show();
830            }
831            this.setPosition(this.restorePos[0], this.restorePos[1]);
832            this.setSize(this.restoreSize.width, this.restoreSize.height);
833            delete this.restorePos;
834            delete this.restoreSize;
835            this.maximized = false;
836            this.el.enableShadow(true);
837
838            if(this.dd){
839                this.dd.unlock();
840            }
841            if(this.collapsible && t.toggle){
842                t.toggle.show();
843            }
844            this.container.removeClass('x-window-maximized-ct');
845
846            this.doConstrain();
847            this.fireEvent('restore', this);
848        }
849        return this;
850    },
851
852    /**
853     * A shortcut method for toggling between {@link #maximize} and {@link #restore} based on the current maximized
854     * state of the window.
855     * @return {Ext.Window} this
856     */
857    toggleMaximize : function(){
858        return this[this.maximized ? 'restore' : 'maximize']();
859    },
860
861    // private
862    fitContainer : function(){
863        var vs = this.container.getViewSize(false);
864        this.setSize(vs.width, vs.height);
865    },
866
867    // private
868    // z-index is managed by the WindowManager and may be overwritten at any time
869    setZIndex : function(index){
870        if(this.modal){
871            this.mask.setStyle('z-index', index);
872        }
873        this.el.setZIndex(++index);
874        index += 5;
875
876        if(this.resizer){
877            this.resizer.proxy.setStyle('z-index', ++index);
878        }
879
880        this.lastZIndex = index;
881    },
882
883    /**
884     * Aligns the window to the specified element
885     * @param {Mixed} element The element to align to.
886     * @param {String} position (optional, defaults to "tl-bl?") The position to align to (see {@link Ext.Element#alignTo} for more details).
887     * @param {Array} offsets (optional) Offset the positioning by [x, y]
888     * @return {Ext.Window} this
889     */
890    alignTo : function(element, position, offsets){
891        var xy = this.el.getAlignToXY(element, position, offsets);
892        this.setPagePosition(xy[0], xy[1]);
893        return this;
894    },
895
896    /**
897     * Anchors this window to another element and realigns it when the window is resized or scrolled.
898     * @param {Mixed} element The element to align to.
899     * @param {String} position The position to align to (see {@link Ext.Element#alignTo} for more details)
900     * @param {Array} offsets (optional) Offset the positioning by [x, y]
901     * @param {Boolean/Number} monitorScroll (optional) true to monitor body scroll and reposition. If this parameter
902     * is a number, it is used as the buffer delay (defaults to 50ms).
903     * @return {Ext.Window} this
904     */
905    anchorTo : function(el, alignment, offsets, monitorScroll){
906        this.clearAnchor();
907        this.anchorTarget = {
908            el: el,
909            alignment: alignment,
910            offsets: offsets
911        };
912
913        Ext.EventManager.onWindowResize(this.doAnchor, this);
914        var tm = typeof monitorScroll;
915        if(tm != 'undefined'){
916            Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
917                {buffer: tm == 'number' ? monitorScroll : 50});
918        }
919        return this.doAnchor();
920    },
921
922    /**
923     * Performs the anchor, using the saved anchorTarget property.
924     * @return {Ext.Window} this
925     * @private
926     */
927    doAnchor : function(){
928        var o = this.anchorTarget;
929        this.alignTo(o.el, o.alignment, o.offsets);
930        return this;
931    },
932
933    /**
934     * Removes any existing anchor from this window. See {@link #anchorTo}.
935     * @return {Ext.Window} this
936     */
937    clearAnchor : function(){
938        if(this.anchorTarget){
939            Ext.EventManager.removeResizeListener(this.doAnchor, this);
940            Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
941            delete this.anchorTarget;
942        }
943        return this;
944    },
945
946    /**
947     * Brings this window to the front of any other visible windows
948     * @param {Boolean} e (optional) Specify <tt>false</tt> to prevent the window from being focused.
949     * @return {Ext.Window} this
950     */
951    toFront : function(e){
952        if(this.manager.bringToFront(this)){
953            if(!e || !e.getTarget().focus){
954                this.focus();
955            }
956        }
957        return this;
958    },
959
960    /**
961     * Makes this the active window by showing its shadow, or deactivates it by hiding its shadow.  This method also
962     * fires the {@link #activate} or {@link #deactivate} event depending on which action occurred. This method is
963     * called internally by {@link Ext.WindowMgr}.
964     * @param {Boolean} active True to activate the window, false to deactivate it (defaults to false)
965     */
966    setActive : function(active){
967        if(active){
968            if(!this.maximized){
969                this.el.enableShadow(true);
970            }
971            this.fireEvent('activate', this);
972        }else{
973            this.el.disableShadow();
974            this.fireEvent('deactivate', this);
975        }
976    },
977
978    /**
979     * Sends this window to the back of (lower z-index than) any other visible windows
980     * @return {Ext.Window} this
981     */
982    toBack : function(){
983        this.manager.sendToBack(this);
984        return this;
985    },
986
987    /**
988     * Centers this window in the viewport
989     * @return {Ext.Window} this
990     */
991    center : function(){
992        var xy = this.el.getAlignToXY(this.container, 'c-c');
993        this.setPagePosition(xy[0], xy[1]);
994        return this;
995    }
996
997    /**
998     * @cfg {Boolean} autoWidth @hide
999     **/
1000});
1001Ext.reg('window', Ext.Window);
1002
1003// private - custom Window DD implementation
1004Ext.Window.DD = Ext.extend(Ext.dd.DD, {
1005   
1006    constructor : function(win){
1007        this.win = win;
1008        Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
1009        this.setHandleElId(win.header.id);
1010        this.scroll = false;       
1011    },
1012   
1013    moveOnly:true,
1014    headerOffsets:[100, 25],
1015    startDrag : function(){
1016        var w = this.win;
1017        this.proxy = w.ghost(w.initialConfig.cls);
1018        if(w.constrain !== false){
1019            var so = w.el.shadowOffset;
1020            this.constrainTo(w.container, {right: so, left: so, bottom: so});
1021        }else if(w.constrainHeader !== false){
1022            var s = this.proxy.getSize();
1023            this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
1024        }
1025    },
1026    b4Drag : Ext.emptyFn,
1027
1028    onDrag : function(e){
1029        this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
1030    },
1031
1032    endDrag : function(e){
1033        this.win.unghost();
1034        this.win.saveState();
1035    }
1036});
1037/**
1038 * @class Ext.WindowGroup
1039 * An object that manages a group of {@link Ext.Window} instances and provides z-order management
1040 * and window activation behavior.
1041 * @constructor
1042 */
1043Ext.WindowGroup = function(){
1044    var list = {};
1045    var accessList = [];
1046    var front = null;
1047
1048    // private
1049    var sortWindows = function(d1, d2){
1050        return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
1051    };
1052
1053    // private
1054    var orderWindows = function(){
1055        var a = accessList, len = a.length;
1056        if(len > 0){
1057            a.sort(sortWindows);
1058            var seed = a[0].manager.zseed;
1059            for(var i = 0; i < len; i++){
1060                var win = a[i];
1061                if(win && !win.hidden){
1062                    win.setZIndex(seed + (i*10));
1063                }
1064            }
1065        }
1066        activateLast();
1067    };
1068
1069    // private
1070    var setActiveWin = function(win){
1071        if(win != front){
1072            if(front){
1073                front.setActive(false);
1074            }
1075            front = win;
1076            if(win){
1077                win.setActive(true);
1078            }
1079        }
1080    };
1081
1082    // private
1083    var activateLast = function(){
1084        for(var i = accessList.length-1; i >=0; --i) {
1085            if(!accessList[i].hidden){
1086                setActiveWin(accessList[i]);
1087                return;
1088            }
1089        }
1090        // none to activate
1091        setActiveWin(null);
1092    };
1093
1094    return {
1095        /**
1096         * The starting z-index for windows in this WindowGroup (defaults to 9000)
1097         * @type Number The z-index value
1098         */
1099        zseed : 9000,
1100
1101        /**
1102         * <p>Registers a {@link Ext.Window Window} with this WindowManager. This should not
1103         * need to be called under normal circumstances. Windows are automatically registered
1104         * with a {@link Ext.Window#manager manager} at construction time.</p>
1105         * <p>Where this may be useful is moving Windows between two WindowManagers. For example,
1106         * to bring the Ext.MessageBox dialog under the same manager as the Desktop's
1107         * WindowManager in the desktop sample app:</p><code><pre>
1108var msgWin = Ext.MessageBox.getDialog();
1109MyDesktop.getDesktop().getManager().register(msgWin);
1110</pre></code>
1111         * @param {Window} win The Window to register.
1112         */
1113        register : function(win){
1114            if(win.manager){
1115                win.manager.unregister(win);
1116            }
1117            win.manager = this;
1118
1119            list[win.id] = win;
1120            accessList.push(win);
1121            win.on('hide', activateLast);
1122        },
1123
1124        /**
1125         * <p>Unregisters a {@link Ext.Window Window} from this WindowManager. This should not
1126         * need to be called. Windows are automatically unregistered upon destruction.
1127         * See {@link #register}.</p>
1128         * @param {Window} win The Window to unregister.
1129         */
1130        unregister : function(win){
1131            delete win.manager;
1132            delete list[win.id];
1133            win.un('hide', activateLast);
1134            accessList.remove(win);
1135        },
1136
1137        /**
1138         * Gets a registered window by id.
1139         * @param {String/Object} id The id of the window or a {@link Ext.Window} instance
1140         * @return {Ext.Window}
1141         */
1142        get : function(id){
1143            return typeof id == "object" ? id : list[id];
1144        },
1145
1146        /**
1147         * Brings the specified window to the front of any other active windows in this WindowGroup.
1148         * @param {String/Object} win The id of the window or a {@link Ext.Window} instance
1149         * @return {Boolean} True if the dialog was brought to the front, else false
1150         * if it was already in front
1151         */
1152        bringToFront : function(win){
1153            win = this.get(win);
1154            if(win != front){
1155                win._lastAccess = new Date().getTime();
1156                orderWindows();
1157                return true;
1158            }
1159            return false;
1160        },
1161
1162        /**
1163         * Sends the specified window to the back of other active windows in this WindowGroup.
1164         * @param {String/Object} win The id of the window or a {@link Ext.Window} instance
1165         * @return {Ext.Window} The window
1166         */
1167        sendToBack : function(win){
1168            win = this.get(win);
1169            win._lastAccess = -(new Date().getTime());
1170            orderWindows();
1171            return win;
1172        },
1173
1174        /**
1175         * Hides all windows in this WindowGroup.
1176         */
1177        hideAll : function(){
1178            for(var id in list){
1179                if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
1180                    list[id].hide();
1181                }
1182            }
1183        },
1184
1185        /**
1186         * Gets the currently-active window in this WindowGroup.
1187         * @return {Ext.Window} The active window
1188         */
1189        getActive : function(){
1190            return front;
1191        },
1192
1193        /**
1194         * Returns zero or more windows in this WindowGroup using the custom search function passed to this method.
1195         * The function should accept a single {@link Ext.Window} reference as its only argument and should
1196         * return true if the window matches the search criteria, otherwise it should return false.
1197         * @param {Function} fn The search function
1198         * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to the Window being tested.
1199         * that gets passed to the function if not specified)
1200         * @return {Array} An array of zero or more matching windows
1201         */
1202        getBy : function(fn, scope){
1203            var r = [];
1204            for(var i = accessList.length-1; i >=0; --i) {
1205                var win = accessList[i];
1206                if(fn.call(scope||win, win) !== false){
1207                    r.push(win);
1208                }
1209            }
1210            return r;
1211        },
1212
1213        /**
1214         * Executes the specified function once for every window in this WindowGroup, passing each
1215         * window as the only parameter. Returning false from the function will stop the iteration.
1216         * @param {Function} fn The function to execute for each item
1217         * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to the current Window in the iteration.
1218         */
1219        each : function(fn, scope){
1220            for(var id in list){
1221                if(list[id] && typeof list[id] != "function"){
1222                    if(fn.call(scope || list[id], list[id]) === false){
1223                        return;
1224                    }
1225                }
1226            }
1227        }
1228    };
1229};
1230
1231
1232/**
1233 * @class Ext.WindowMgr
1234 * @extends Ext.WindowGroup
1235 * The default global window group that is available automatically.  To have more than one group of windows
1236 * with separate z-order stacks, create additional instances of {@link Ext.WindowGroup} as needed.
1237 * @singleton
1238 */
1239Ext.WindowMgr = new Ext.WindowGroup();/**
1240 * @class Ext.MessageBox
1241 * <p>Utility class for generating different styles of message boxes.  The alias Ext.Msg can also be used.<p/>
1242 * <p>Note that the MessageBox is asynchronous.  Unlike a regular JavaScript <code>alert</code> (which will halt
1243 * browser execution), showing a MessageBox will not cause the code to stop.  For this reason, if you have code
1244 * that should only run <em>after</em> some user feedback from the MessageBox, you must use a callback function
1245 * (see the <code>function</code> parameter for {@link #show} for more details).</p>
1246 * <p>Example usage:</p>
1247 *<pre><code>
1248// Basic alert:
1249Ext.Msg.alert('Status', 'Changes saved successfully.');
1250
1251// Prompt for user data and process the result using a callback:
1252Ext.Msg.prompt('Name', 'Please enter your name:', function(btn, text){
1253    if (btn == 'ok'){
1254        // process text value and close...
1255    }
1256});
1257
1258// Show a dialog using config options:
1259Ext.Msg.show({
1260   title:'Save Changes?',
1261   msg: 'You are closing a tab that has unsaved changes. Would you like to save your changes?',
1262   buttons: Ext.Msg.YESNOCANCEL,
1263   fn: processResult,
1264   animEl: 'elId',
1265   icon: Ext.MessageBox.QUESTION
1266});
1267</code></pre>
1268 * @singleton
1269 */
1270Ext.MessageBox = function(){
1271    var dlg, opt, mask, waitTimer,
1272        bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl,
1273        buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '',
1274        buttonNames = ['ok', 'yes', 'no', 'cancel'];
1275
1276    // private
1277    var handleButton = function(button){
1278        buttons[button].blur();
1279        if(dlg.isVisible()){
1280            dlg.hide();
1281            handleHide();
1282            Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);
1283        }
1284    };
1285
1286    // private
1287    var handleHide = function(){
1288        if(opt && opt.cls){
1289            dlg.el.removeClass(opt.cls);
1290        }
1291        progressBar.reset();       
1292    };
1293
1294    // private
1295    var handleEsc = function(d, k, e){
1296        if(opt && opt.closable !== false){
1297            dlg.hide();
1298            handleHide();
1299        }
1300        if(e){
1301            e.stopEvent();
1302        }
1303    };
1304
1305    // private
1306    var updateButtons = function(b){
1307        var width = 0,
1308            cfg;
1309        if(!b){
1310            Ext.each(buttonNames, function(name){
1311                buttons[name].hide();
1312            });
1313            return width;
1314        }
1315        dlg.footer.dom.style.display = '';
1316        Ext.iterate(buttons, function(name, btn){
1317            cfg = b[name];
1318            if(cfg){
1319                btn.show();
1320                btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]);
1321                width += btn.getEl().getWidth() + 15;
1322            }else{
1323                btn.hide();
1324            }
1325        });
1326        return width;
1327    };
1328
1329    return {
1330        /**
1331         * Returns a reference to the underlying {@link Ext.Window} element
1332         * @return {Ext.Window} The window
1333         */
1334        getDialog : function(titleText){
1335           if(!dlg){
1336                var btns = [];
1337               
1338                buttons = {};
1339                Ext.each(buttonNames, function(name){
1340                    btns.push(buttons[name] = new Ext.Button({
1341                        text: this.buttonText[name],
1342                        handler: handleButton.createCallback(name),
1343                        hideMode: 'offsets'
1344                    }));
1345                }, this);
1346                dlg = new Ext.Window({
1347                    autoCreate : true,
1348                    title:titleText,
1349                    resizable:false,
1350                    constrain:true,
1351                    constrainHeader:true,
1352                    minimizable : false,
1353                    maximizable : false,
1354                    stateful: false,
1355                    modal: true,
1356                    shim:true,
1357                    buttonAlign:"center",
1358                    width:400,
1359                    height:100,
1360                    minHeight: 80,
1361                    plain:true,
1362                    footer:true,
1363                    closable:true,
1364                    close : function(){
1365                        if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
1366                            handleButton("no");
1367                        }else{
1368                            handleButton("cancel");
1369                        }
1370                    },
1371                    fbar: new Ext.Toolbar({
1372                        items: btns,
1373                        enableOverflow: false
1374                    })
1375                });
1376                dlg.render(document.body);
1377                dlg.getEl().addClass('x-window-dlg');
1378                mask = dlg.mask;
1379                bodyEl = dlg.body.createChild({
1380                    html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'
1381                });
1382                iconEl = Ext.get(bodyEl.dom.firstChild);
1383                var contentEl = bodyEl.dom.childNodes[1];
1384                msgEl = Ext.get(contentEl.firstChild);
1385                textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
1386                textboxEl.enableDisplayMode();
1387                textboxEl.addKeyListener([10,13], function(){
1388                    if(dlg.isVisible() && opt && opt.buttons){
1389                        if(opt.buttons.ok){
1390                            handleButton("ok");
1391                        }else if(opt.buttons.yes){
1392                            handleButton("yes");
1393                        }
1394                    }
1395                });
1396                textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
1397                textareaEl.enableDisplayMode();
1398                progressBar = new Ext.ProgressBar({
1399                    renderTo:bodyEl
1400                });
1401               bodyEl.createChild({cls:'x-clear'});
1402            }
1403            return dlg;
1404        },
1405
1406        /**
1407         * Updates the message box body text
1408         * @param {String} text (optional) Replaces the message box element's innerHTML with the specified string (defaults to
1409         * the XHTML-compliant non-breaking space character '&amp;#160;')
1410         * @return {Ext.MessageBox} this
1411         */
1412        updateText : function(text){
1413            if(!dlg.isVisible() && !opt.width){
1414                dlg.setSize(this.maxWidth, 100); // resize first so content is never clipped from previous shows
1415            }
1416            // Append a space here for sizing. In IE, for some reason, it wraps text incorrectly without one in some cases
1417            msgEl.update(text ? text + ' ' : '&#160;');
1418
1419            var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0,
1420                mw = msgEl.getWidth() + msgEl.getMargins('lr'),
1421                fw = dlg.getFrameWidth('lr'),
1422                bw = dlg.body.getFrameWidth('lr'),
1423                w;
1424               
1425            w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth),
1426                    Math.max(opt.minWidth || this.minWidth, bwidth || 0));
1427
1428            if(opt.prompt === true){
1429                activeTextEl.setWidth(w-iw-fw-bw);
1430            }
1431            if(opt.progress === true || opt.wait === true){
1432                progressBar.setSize(w-iw-fw-bw);
1433            }
1434            if(Ext.isIE && w == bwidth){
1435                w += 4; //Add offset when the content width is smaller than the buttons.   
1436            }
1437            msgEl.update(text || '&#160;');
1438            dlg.setSize(w, 'auto').center();
1439            return this;
1440        },
1441
1442        /**
1443         * Updates a progress-style message box's text and progress bar. Only relevant on message boxes
1444         * initiated via {@link Ext.MessageBox#progress} or {@link Ext.MessageBox#wait},
1445         * or by calling {@link Ext.MessageBox#show} with progress: true.
1446         * @param {Number} value Any number between 0 and 1 (e.g., .5, defaults to 0)
1447         * @param {String} progressText The progress text to display inside the progress bar (defaults to '')
1448         * @param {String} msg The message box's body text is replaced with the specified string (defaults to undefined
1449         * so that any existing body text will not get overwritten by default unless a new value is passed in)
1450         * @return {Ext.MessageBox} this
1451         */
1452        updateProgress : function(value, progressText, msg){
1453            progressBar.updateProgress(value, progressText);
1454            if(msg){
1455                this.updateText(msg);
1456            }
1457            return this;
1458        },
1459
1460        /**
1461         * Returns true if the message box is currently displayed
1462         * @return {Boolean} True if the message box is visible, else false
1463         */
1464        isVisible : function(){
1465            return dlg && dlg.isVisible();
1466        },
1467
1468        /**
1469         * Hides the message box if it is displayed
1470         * @return {Ext.MessageBox} this
1471         */
1472        hide : function(){
1473            var proxy = dlg ? dlg.activeGhost : null;
1474            if(this.isVisible() || proxy){
1475                dlg.hide();
1476                handleHide();
1477                if (proxy){
1478                    // unghost is a private function, but i saw no better solution
1479                    // to fix the locking problem when dragging while it closes
1480                    dlg.unghost(false, false);
1481                } 
1482            }
1483            return this;
1484        },
1485
1486        /**
1487         * Displays a new message box, or reinitializes an existing message box, based on the config options
1488         * passed in. All display functions (e.g. prompt, alert, etc.) on MessageBox call this function internally,
1489         * although those calls are basic shortcuts and do not support all of the config options allowed here.
1490         * @param {Object} config The following config options are supported: <ul>
1491         * <li><b>animEl</b> : String/Element<div class="sub-desc">An id or Element from which the message box should animate as it
1492         * opens and closes (defaults to undefined)</div></li>
1493         * <li><b>buttons</b> : Object/Boolean<div class="sub-desc">A button config object (e.g., Ext.MessageBox.OKCANCEL or {ok:'Foo',
1494         * cancel:'Bar'}), or false to not show any buttons (defaults to false)</div></li>
1495         * <li><b>closable</b> : Boolean<div class="sub-desc">False to hide the top-right close button (defaults to true). Note that
1496         * progress and wait dialogs will ignore this property and always hide the close button as they can only
1497         * be closed programmatically.</div></li>
1498         * <li><b>cls</b> : String<div class="sub-desc">A custom CSS class to apply to the message box's container element</div></li>
1499         * <li><b>defaultTextHeight</b> : Number<div class="sub-desc">The default height in pixels of the message box's multiline textarea
1500         * if displayed (defaults to 75)</div></li>
1501         * <li><b>fn</b> : Function<div class="sub-desc">A callback function which is called when the dialog is dismissed either
1502         * by clicking on the configured buttons, or on the dialog close button, or by pressing
1503         * the return button to enter input.
1504         * <p>Progress and wait dialogs will ignore this option since they do not respond to user
1505         * actions and can only be closed programmatically, so any required function should be called
1506         * by the same code after it closes the dialog. Parameters passed:<ul>
1507         * <li><b>buttonId</b> : String<div class="sub-desc">The ID of the button pressed, one of:<div class="sub-desc"><ul>
1508         * <li><tt>ok</tt></li>
1509         * <li><tt>yes</tt></li>
1510         * <li><tt>no</tt></li>
1511         * <li><tt>cancel</tt></li>
1512         * </ul></div></div></li>
1513         * <li><b>text</b> : String<div class="sub-desc">Value of the input field if either <tt><a href="#show-option-prompt" ext:member="show-option-prompt" ext:cls="Ext.MessageBox">prompt</a></tt>
1514         * or <tt><a href="#show-option-multiline" ext:member="show-option-multiline" ext:cls="Ext.MessageBox">multiline</a></tt> is true</div></li>
1515         * <li><b>opt</b> : Object<div class="sub-desc">The config object passed to show.</div></li>
1516         * </ul></p></div></li>
1517         * <li><b>scope</b> : Object<div class="sub-desc">The scope of the callback function</div></li>
1518         * <li><b>icon</b> : String<div class="sub-desc">A CSS class that provides a background image to be used as the body icon for the
1519         * dialog (e.g. Ext.MessageBox.WARNING or 'custom-class') (defaults to '')</div></li>
1520         * <li><b>iconCls</b> : String<div class="sub-desc">The standard {@link Ext.Window#iconCls} to
1521         * add an optional header icon (defaults to '')</div></li>
1522         * <li><b>maxWidth</b> : Number<div class="sub-desc">The maximum width in pixels of the message box (defaults to 600)</div></li>
1523         * <li><b>minWidth</b> : Number<div class="sub-desc">The minimum width in pixels of the message box (defaults to 100)</div></li>
1524         * <li><b>modal</b> : Boolean<div class="sub-desc">False to allow user interaction with the page while the message box is
1525         * displayed (defaults to true)</div></li>
1526         * <li><b>msg</b> : String<div class="sub-desc">A string that will replace the existing message box body text (defaults to the
1527         * XHTML-compliant non-breaking space character '&amp;#160;')</div></li>
1528         * <li><a id="show-option-multiline"></a><b>multiline</b> : Boolean<div class="sub-desc">
1529         * True to prompt the user to enter multi-line text (defaults to false)</div></li>
1530         * <li><b>progress</b> : Boolean<div class="sub-desc">True to display a progress bar (defaults to false)</div></li>
1531         * <li><b>progressText</b> : String<div class="sub-desc">The text to display inside the progress bar if progress = true (defaults to '')</div></li>
1532         * <li><a id="show-option-prompt"></a><b>prompt</b> : Boolean<div class="sub-desc">True to prompt the user to enter single-line text (defaults to false)</div></li>
1533         * <li><b>proxyDrag</b> : Boolean<div class="sub-desc">True to display a lightweight proxy while dragging (defaults to false)</div></li>
1534         * <li><b>title</b> : String<div class="sub-desc">The title text</div></li>
1535         * <li><b>value</b> : String<div class="sub-desc">The string value to set into the active textbox element if displayed</div></li>
1536         * <li><b>wait</b> : Boolean<div class="sub-desc">True to display a progress bar (defaults to false)</div></li>
1537         * <li><b>waitConfig</b> : Object<div class="sub-desc">A {@link Ext.ProgressBar#waitConfig} object (applies only if wait = true)</div></li>
1538         * <li><b>width</b> : Number<div class="sub-desc">The width of the dialog in pixels</div></li>
1539         * </ul>
1540         * Example usage:
1541         * <pre><code>
1542Ext.Msg.show({
1543   title: 'Address',
1544   msg: 'Please enter your address:',
1545   width: 300,
1546   buttons: Ext.MessageBox.OKCANCEL,
1547   multiline: true,
1548   fn: saveAddress,
1549   animEl: 'addAddressBtn',
1550   icon: Ext.MessageBox.INFO
1551});
1552</code></pre>
1553         * @return {Ext.MessageBox} this
1554         */
1555        show : function(options){
1556            if(this.isVisible()){
1557                this.hide();
1558            }
1559            opt = options;
1560            var d = this.getDialog(opt.title || "&#160;");
1561
1562            d.setTitle(opt.title || "&#160;");
1563            var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
1564            d.tools.close.setDisplayed(allowClose);
1565            activeTextEl = textboxEl;
1566            opt.prompt = opt.prompt || (opt.multiline ? true : false);
1567            if(opt.prompt){
1568                if(opt.multiline){
1569                    textboxEl.hide();
1570                    textareaEl.show();
1571                    textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight);
1572                    activeTextEl = textareaEl;
1573                }else{
1574                    textboxEl.show();
1575                    textareaEl.hide();
1576                }
1577            }else{
1578                textboxEl.hide();
1579                textareaEl.hide();
1580            }
1581            activeTextEl.dom.value = opt.value || "";
1582            if(opt.prompt){
1583                d.focusEl = activeTextEl;
1584            }else{
1585                var bs = opt.buttons;
1586                var db = null;
1587                if(bs && bs.ok){
1588                    db = buttons["ok"];
1589                }else if(bs && bs.yes){
1590                    db = buttons["yes"];
1591                }
1592                if (db){
1593                    d.focusEl = db;
1594                }
1595            }
1596            if(Ext.isDefined(opt.iconCls)){
1597              d.setIconClass(opt.iconCls);
1598            }
1599            this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon);
1600            bwidth = updateButtons(opt.buttons);
1601            progressBar.setVisible(opt.progress === true || opt.wait === true);
1602            this.updateProgress(0, opt.progressText);
1603            this.updateText(opt.msg);
1604            if(opt.cls){
1605                d.el.addClass(opt.cls);
1606            }
1607            d.proxyDrag = opt.proxyDrag === true;
1608            d.modal = opt.modal !== false;
1609            d.mask = opt.modal !== false ? mask : false;
1610            if(!d.isVisible()){
1611                // force it to the end of the z-index stack so it gets a cursor in FF
1612                document.body.appendChild(dlg.el.dom);
1613                d.setAnimateTarget(opt.animEl);
1614                //workaround for window internally enabling keymap in afterShow
1615                d.on('show', function(){
1616                    if(allowClose === true){
1617                        d.keyMap.enable();
1618                    }else{
1619                        d.keyMap.disable();
1620                    }
1621                }, this, {single:true});
1622                d.show(opt.animEl);
1623            }
1624            if(opt.wait === true){
1625                progressBar.wait(opt.waitConfig);
1626            }
1627            return this;
1628        },
1629
1630        /**
1631         * Adds the specified icon to the dialog.  By default, the class 'ext-mb-icon' is applied for default
1632         * styling, and the class passed in is expected to supply the background image url. Pass in empty string ('')
1633         * to clear any existing icon. This method must be called before the MessageBox is shown.
1634         * The following built-in icon classes are supported, but you can also pass in a custom class name:
1635         * <pre>
1636Ext.MessageBox.INFO
1637Ext.MessageBox.WARNING
1638Ext.MessageBox.QUESTION
1639Ext.MessageBox.ERROR
1640         *</pre>
1641         * @param {String} icon A CSS classname specifying the icon's background image url, or empty string to clear the icon
1642         * @return {Ext.MessageBox} this
1643         */
1644        setIcon : function(icon){
1645            if(!dlg){
1646                bufferIcon = icon;
1647                return;
1648            }
1649            bufferIcon = undefined;
1650            if(icon && icon != ''){
1651                iconEl.removeClass('x-hidden');
1652                iconEl.replaceClass(iconCls, icon);
1653                bodyEl.addClass('x-dlg-icon');
1654                iconCls = icon;
1655            }else{
1656                iconEl.replaceClass(iconCls, 'x-hidden');
1657                bodyEl.removeClass('x-dlg-icon');
1658                iconCls = '';
1659            }
1660            return this;
1661        },
1662
1663        /**
1664         * Displays a message box with a progress bar.  This message box has no buttons and is not closeable by
1665         * the user.  You are responsible for updating the progress bar as needed via {@link Ext.MessageBox#updateProgress}
1666         * and closing the message box when the process is complete.
1667         * @param {String} title The title bar text
1668         * @param {String} msg The message box body text
1669         * @param {String} progressText (optional) The text to display inside the progress bar (defaults to '')
1670         * @return {Ext.MessageBox} this
1671         */
1672        progress : function(title, msg, progressText){
1673            this.show({
1674                title : title,
1675                msg : msg,
1676                buttons: false,
1677                progress:true,
1678                closable:false,
1679                minWidth: this.minProgressWidth,
1680                progressText: progressText
1681            });
1682            return this;
1683        },
1684
1685        /**
1686         * Displays a message box with an infinitely auto-updating progress bar.  This can be used to block user
1687         * interaction while waiting for a long-running process to complete that does not have defined intervals.
1688         * You are responsible for closing the message box when the process is complete.
1689         * @param {String} msg The message box body text
1690         * @param {String} title (optional) The title bar text
1691         * @param {Object} config (optional) A {@link Ext.ProgressBar#waitConfig} object
1692         * @return {Ext.MessageBox} this
1693         */
1694        wait : function(msg, title, config){
1695            this.show({
1696                title : title,
1697                msg : msg,
1698                buttons: false,
1699                closable:false,
1700                wait:true,
1701                modal:true,
1702                minWidth: this.minProgressWidth,
1703                waitConfig: config
1704            });
1705            return this;
1706        },
1707
1708        /**
1709         * Displays a standard read-only message box with an OK button (comparable to the basic JavaScript alert prompt).
1710         * If a callback function is passed it will be called after the user clicks the button, and the
1711         * id of the button that was clicked will be passed as the only parameter to the callback
1712         * (could also be the top-right close button).
1713         * @param {String} title The title bar text
1714         * @param {String} msg The message box body text
1715         * @param {Function} fn (optional) The callback function invoked after the message box is closed
1716         * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to the browser wnidow.
1717         * @return {Ext.MessageBox} this
1718         */
1719        alert : function(title, msg, fn, scope){
1720            this.show({
1721                title : title,
1722                msg : msg,
1723                buttons: this.OK,
1724                fn: fn,
1725                scope : scope,
1726                minWidth: this.minWidth
1727            });
1728            return this;
1729        },
1730
1731        /**
1732         * Displays a confirmation message box with Yes and No buttons (comparable to JavaScript's confirm).
1733         * If a callback function is passed it will be called after the user clicks either button,
1734         * and the id of the button that was clicked will be passed as the only parameter to the callback
1735         * (could also be the top-right close button).
1736         * @param {String} title The title bar text
1737         * @param {String} msg The message box body text
1738         * @param {Function} fn (optional) The callback function invoked after the message box is closed
1739         * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to the browser wnidow.
1740         * @return {Ext.MessageBox} this
1741         */
1742        confirm : function(title, msg, fn, scope){
1743            this.show({
1744                title : title,
1745                msg : msg,
1746                buttons: this.YESNO,
1747                fn: fn,
1748                scope : scope,
1749                icon: this.QUESTION,
1750                minWidth: this.minWidth
1751            });
1752            return this;
1753        },
1754
1755        /**
1756         * Displays a message box with OK and Cancel buttons prompting the user to enter some text (comparable to JavaScript's prompt).
1757         * The prompt can be a single-line or multi-line textbox.  If a callback function is passed it will be called after the user
1758         * clicks either button, and the id of the button that was clicked (could also be the top-right
1759         * close button) and the text that was entered will be passed as the two parameters to the callback.
1760         * @param {String} title The title bar text
1761         * @param {String} msg The message box body text
1762         * @param {Function} fn (optional) The callback function invoked after the message box is closed
1763         * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to the browser wnidow.
1764         * @param {Boolean/Number} multiline (optional) True to create a multiline textbox using the defaultTextHeight
1765         * property, or the height in pixels to create the textbox (defaults to false / single-line)
1766         * @param {String} value (optional) Default value of the text input element (defaults to '')
1767         * @return {Ext.MessageBox} this
1768         */
1769        prompt : function(title, msg, fn, scope, multiline, value){
1770            this.show({
1771                title : title,
1772                msg : msg,
1773                buttons: this.OKCANCEL,
1774                fn: fn,
1775                minWidth: this.minPromptWidth,
1776                scope : scope,
1777                prompt:true,
1778                multiline: multiline,
1779                value: value
1780            });
1781            return this;
1782        },
1783
1784        /**
1785         * Button config that displays a single OK button
1786         * @type Object
1787         */
1788        OK : {ok:true},
1789        /**
1790         * Button config that displays a single Cancel button
1791         * @type Object
1792         */
1793        CANCEL : {cancel:true},
1794        /**
1795         * Button config that displays OK and Cancel buttons
1796         * @type Object
1797         */
1798        OKCANCEL : {ok:true, cancel:true},
1799        /**
1800         * Button config that displays Yes and No buttons
1801         * @type Object
1802         */
1803        YESNO : {yes:true, no:true},
1804        /**
1805         * Button config that displays Yes, No and Cancel buttons
1806         * @type Object
1807         */
1808        YESNOCANCEL : {yes:true, no:true, cancel:true},
1809        /**
1810         * The CSS class that provides the INFO icon image
1811         * @type String
1812         */
1813        INFO : 'ext-mb-info',
1814        /**
1815         * The CSS class that provides the WARNING icon image
1816         * @type String
1817         */
1818        WARNING : 'ext-mb-warning',
1819        /**
1820         * The CSS class that provides the QUESTION icon image
1821         * @type String
1822         */
1823        QUESTION : 'ext-mb-question',
1824        /**
1825         * The CSS class that provides the ERROR icon image
1826         * @type String
1827         */
1828        ERROR : 'ext-mb-error',
1829
1830        /**
1831         * The default height in pixels of the message box's multiline textarea if displayed (defaults to 75)
1832         * @type Number
1833         */
1834        defaultTextHeight : 75,
1835        /**
1836         * The maximum width in pixels of the message box (defaults to 600)
1837         * @type Number
1838         */
1839        maxWidth : 600,
1840        /**
1841         * The minimum width in pixels of the message box (defaults to 100)
1842         * @type Number
1843         */
1844        minWidth : 100,
1845        /**
1846         * The minimum width in pixels of the message box if it is a progress-style dialog.  This is useful
1847         * for setting a different minimum width than text-only dialogs may need (defaults to 250).
1848         * @type Number
1849         */
1850        minProgressWidth : 250,
1851        /**
1852         * The minimum width in pixels of the message box if it is a prompt dialog.  This is useful
1853         * for setting a different minimum width than text-only dialogs may need (defaults to 250).
1854         * @type Number
1855         */
1856        minPromptWidth: 250,
1857        /**
1858         * An object containing the default button text strings that can be overriden for localized language support.
1859         * Supported properties are: ok, cancel, yes and no.  Generally you should include a locale-specific
1860         * resource file for handling language support across the framework.
1861         * Customize the default text like so: Ext.MessageBox.buttonText.yes = "oui"; //french
1862         * @type Object
1863         */
1864        buttonText : {
1865            ok : "OK",
1866            cancel : "Cancel",
1867            yes : "Yes",
1868            no : "No"
1869        }
1870    };
1871}();
1872
1873/**
1874 * Shorthand for {@link Ext.MessageBox}
1875 */
1876Ext.Msg = Ext.MessageBox;/**
1877 * @class Ext.dd.PanelProxy
1878 * A custom drag proxy implementation specific to {@link Ext.Panel}s. This class is primarily used internally
1879 * for the Panel's drag drop implementation, and should never need to be created directly.
1880 * @constructor
1881 * @param panel The {@link Ext.Panel} to proxy for
1882 * @param config Configuration options
1883 */
1884Ext.dd.PanelProxy  = Ext.extend(Object, {
1885   
1886    constructor : function(panel, config){
1887        this.panel = panel;
1888        this.id = this.panel.id +'-ddproxy';
1889        Ext.apply(this, config);       
1890    },
1891   
1892    /**
1893     * @cfg {Boolean} insertProxy True to insert a placeholder proxy element while dragging the panel,
1894     * false to drag with no proxy (defaults to true).
1895     */
1896    insertProxy : true,
1897
1898    // private overrides
1899    setStatus : Ext.emptyFn,
1900    reset : Ext.emptyFn,
1901    update : Ext.emptyFn,
1902    stop : Ext.emptyFn,
1903    sync: Ext.emptyFn,
1904
1905    /**
1906     * Gets the proxy's element
1907     * @return {Element} The proxy's element
1908     */
1909    getEl : function(){
1910        return this.ghost;
1911    },
1912
1913    /**
1914     * Gets the proxy's ghost element
1915     * @return {Element} The proxy's ghost element
1916     */
1917    getGhost : function(){
1918        return this.ghost;
1919    },
1920
1921    /**
1922     * Gets the proxy's element
1923     * @return {Element} The proxy's element
1924     */
1925    getProxy : function(){
1926        return this.proxy;
1927    },
1928
1929    /**
1930     * Hides the proxy
1931     */
1932    hide : function(){
1933        if(this.ghost){
1934            if(this.proxy){
1935                this.proxy.remove();
1936                delete this.proxy;
1937            }
1938            this.panel.el.dom.style.display = '';
1939            this.ghost.remove();
1940            delete this.ghost;
1941        }
1942    },
1943
1944    /**
1945     * Shows the proxy
1946     */
1947    show : function(){
1948        if(!this.ghost){
1949            this.ghost = this.panel.createGhost(this.panel.initialConfig.cls, undefined, Ext.getBody());
1950            this.ghost.setXY(this.panel.el.getXY());
1951            if(this.insertProxy){
1952                this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
1953                this.proxy.setSize(this.panel.getSize());
1954            }
1955            this.panel.el.dom.style.display = 'none';
1956        }
1957    },
1958
1959    // private
1960    repair : function(xy, callback, scope){
1961        this.hide();
1962        if(typeof callback == "function"){
1963            callback.call(scope || this);
1964        }
1965    },
1966
1967    /**
1968     * Moves the proxy to a different position in the DOM.  This is typically called while dragging the Panel
1969     * to keep the proxy sync'd to the Panel's location.
1970     * @param {HTMLElement} parentNode The proxy's parent DOM node
1971     * @param {HTMLElement} before (optional) The sibling node before which the proxy should be inserted (defaults
1972     * to the parent's last child if not specified)
1973     */
1974    moveProxy : function(parentNode, before){
1975        if(this.proxy){
1976            parentNode.insertBefore(this.proxy.dom, before);
1977        }
1978    }
1979});
1980
1981// private - DD implementation for Panels
1982Ext.Panel.DD = Ext.extend(Ext.dd.DragSource, {
1983   
1984    constructor : function(panel, cfg){
1985        this.panel = panel;
1986        this.dragData = {panel: panel};
1987        this.proxy = new Ext.dd.PanelProxy(panel, cfg);
1988        Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
1989        var h = panel.header,
1990            el = panel.body;
1991        if(h){
1992            this.setHandleElId(h.id);
1993            el = panel.header;
1994        }
1995        el.setStyle('cursor', 'move');
1996        this.scroll = false;       
1997    },
1998   
1999    showFrame: Ext.emptyFn,
2000    startDrag: Ext.emptyFn,
2001    b4StartDrag: function(x, y) {
2002        this.proxy.show();
2003    },
2004    b4MouseDown: function(e) {
2005        var x = e.getPageX(),
2006            y = e.getPageY();
2007        this.autoOffset(x, y);
2008    },
2009    onInitDrag : function(x, y){
2010        this.onStartDrag(x, y);
2011        return true;
2012    },
2013    createFrame : Ext.emptyFn,
2014    getDragEl : function(e){
2015        return this.proxy.ghost.dom;
2016    },
2017    endDrag : function(e){
2018        this.proxy.hide();
2019        this.panel.saveState();
2020    },
2021
2022    autoOffset : function(x, y) {
2023        x -= this.startPageX;
2024        y -= this.startPageY;
2025        this.setDelta(x, y);
2026    }
2027});
Note: See TracBrowser for help on using the repository browser.