examples/resizable/basic.js
[roojs1] / roojs-debug.js
index 6736d9e..67df8bb 100644 (file)
@@ -9554,7 +9554,28 @@ if(opt.anim.isAnimated()){
         } : function(ns, name){
             var d = this.dom;
             return d.getAttributeNS(ns, name) || d.getAttribute(ns+":"+name) || d.getAttribute(name) || d[name];
+        },
+        
+        
+        /**
+         * Sets or Returns the value the dom attribute value
+         * @param {String} name The attribute name
+         * @param {String} value (optional) The value to set the attribute to
+         * @return {String} The attribute value
+         */
+        attr : function(name){
+            if (arguments.length > 1) {
+                this.dom.setAttribute(name, arguments[1]);
+                return arguments[1];
+            }
+            if (!this.dom.hasAttribute(name)) {
+                return undefined;
+            }
+            return this.dom.getAttribute(name);
         }
+        
+        
+        
     };
 
     var ep = El.prototype;
@@ -12172,18 +12193,19 @@ Roo.extend(Roo.DomTemplate, Roo.Template, {
         
         // covert the html into DOM...
         var doc = false;
+        var div =false;
         try {
             doc = document.implementation.createHTMLDocument("");
             doc.documentElement.innerHTML =   this.html  ;
+            div = doc.documentElement;
         } catch (e) {
-            // old IE...
-            doc = new ActiveXObject('htmlfile');
-            doc.open();
-            doc.write(this.html);
-            doc.close();
+            // old IE... - nasty -- it causes all sorts of issues.. with
+            // images getting pulled from server..
+            div = document.createElement('div');
+            div.innerHTML = this.html;
         }
         //doc.documentElement.innerHTML = htmlBody
-        var div = doc.documentElement;
+         
         
         
         this.tpls = [];
@@ -12404,7 +12426,7 @@ Roo.extend(Roo.DomTemplate, Roo.Template, {
                 return "'"+ sep +   udef_st   +    format + name + args + "))"+sep+"'";
             }
              
-            if (args.length) {
+            if (args && args.length) {
                 // called with xxyx.yuu:(test,test)
                 // change to ()
                 return "'"+ sep + udef_st  + name + '(' +  args + "))"+sep+"'";
@@ -24095,7 +24117,9 @@ Roo.View = function(config, depreciated_tpl, depreciated_config){
         this.tpl = depreciated_tpl;
         Roo.apply(this, depreciated_config);
     }
-     
+    this.wrapEl  = this.el.wrap().wrap();
+    ///this.el = this.wrapEla.appendChild(document.createElement("div"));
+    
     
     if(typeof(this.tpl) == "string"){
         this.tpl = new Roo.Template(this.tpl);
@@ -24107,7 +24131,8 @@ Roo.View = function(config, depreciated_tpl, depreciated_config){
     
     this.tpl.compile();
    
-
+  
+    
      
     /** @private */
     this.addEvents({
@@ -24170,8 +24195,12 @@ Roo.View = function(config, depreciated_tpl, depreciated_config){
          * @param {Object} data to be rendered (change this)
          */
           "preparedata" : true
+          
+          
         });
 
+
+
     this.el.on({
         "click": this.onClick,
         "dblclick": this.onDblClick,
@@ -24186,7 +24215,25 @@ Roo.View = function(config, depreciated_tpl, depreciated_config){
         this.store = Roo.factory(this.store, Roo.data);
         this.setStore(this.store, true);
     }
+    
+    if ( this.footer && this.footer.xtype) {
+           
+         var fctr = this.wrapEl.appendChild(document.createElement("div"));
+        
+        this.footer.dataSource = this.store
+        this.footer.container = fctr;
+        this.footer = Roo.factory(this.footer, Roo);
+        fctr.insertFirst(this.el);
+        
+        // this is a bit insane - as the paging toolbar seems to detach the el..
+//        dom.parentNode.parentNode.parentNode
+         // they get detached?
+    }
+    
+    
     Roo.View.superclass.constructor.call(this);
+    
+    
 };
 
 Roo.extend(Roo.View, Roo.util.Observable, {
@@ -24242,8 +24289,10 @@ Roo.extend(Roo.View, Roo.util.Observable, {
      * @return {Roo.Element}
      */
     getEl : function(){
-        return this.el;
+        return this.wrapEl;
     },
+    
+    
 
     /**
      * Refreshes the view. - called by datachanged on the store. - do not call directly.
@@ -28558,7 +28607,9 @@ Roo.extend(Roo.Resizable, Roo.util.Observable, {
 
     // private
     updateChildSize : function(){
+        
         if(this.resizeChild){
+            Roo.log('in?');
             var el = this.el;
             var child = this.resizeChild;
             var adj = this.adjustments;
@@ -29810,15 +29861,20 @@ Roo.extend(Roo.BasicDialog, Roo.util.Observable, {
     },
 
     // private
-    syncBodyHeight : function(){
-        var bd = this.body, cb = this.centerBg, bw = this.bwrap;
+    syncBodyHeight : function()
+    {
+        var bd = this.body, // the text
+            cb = this.centerBg, // wrapper around bottom.. but does not seem to be used..
+            bw = this.bwrap;
         var height = this.size.height - this.getHeaderFooterHeight(false);
         bd.setHeight(height-bd.getMargins("tb"));
         var hh = this.header.getHeight();
         var h = this.size.height-hh;
         cb.setHeight(h);
+        
         bw.setLeftTop(cb.getPadding("l"), hh+cb.getPadding("t"));
         bw.setHeight(h-cb.getPadding("tb"));
+        
         bw.setWidth(this.el.getWidth(true)-cb.getPadding("lr"));
         bd.setWidth(bw.getWidth(true));
         if(this.tabs){
@@ -34773,6 +34829,10 @@ Roo.extend(Roo.menu.Menu, Roo.util.Observable, {
         ul.on("mouseover", this.onMouseOver, this);
         ul.on("mouseout", this.onMouseOut, this);
         this.items.each(function(item){
+            if (item.hidden) {
+                return;
+            }
+            
             var li = document.createElement("li");
             li.className = "x-menu-list-item";
             ul.dom.appendChild(li);
@@ -35410,6 +35470,12 @@ Roo.extend(Roo.menu.BaseItem, Roo.Component, {
      * @cfg {Boolean} canActivate True if this item can be visually activated (defaults to false)
      */
     canActivate : false,
+    
+     /**
+     * @cfg {Boolean} hidden True to prevent creation of this menu item (defaults to false)
+     */
+    hidden: false,
+    
     /**
      * @cfg {String} activeClass The CSS class to use when the item becomes activated (defaults to "x-menu-item-active")
      */
@@ -36533,9 +36599,7 @@ side          Add an error icon to the right of the field with a popup on hover
      */
     getRawValue : function(){
         var v = this.el.getValue();
-        if(v === this.emptyText){
-            v = '';
-        }
+        
         return v;
     },
 
@@ -36545,9 +36609,7 @@ side          Add an error icon to the right of the field with a popup on hover
      */
     getValue : function(){
         var v = this.el.getValue();
-        if(v === this.emptyText || v === undefined){
-            v = '';
-        }
+         
         return v;
     },
 
@@ -36584,14 +36646,14 @@ side          Add an error icon to the right of the field with a popup on hover
                 if(tag == 'input'){
                     return w + 2;
                 }
-                if(tag = 'textarea'){
+                if(tag == 'textarea'){
                     return w-2;
                 }
             }else if(Roo.isOpera){
                 if(tag == 'input'){
                     return w + 2;
                 }
-                if(tag = 'textarea'){
+                if(tag == 'textarea'){
                     return w-2;
                 }
             }
@@ -36740,17 +36802,18 @@ Roo.extend(Roo.form.TextField, Roo.form.Field,  {
      */
     regexText : "",
     /**
-     * @cfg {String} emptyText The default text to display in an empty field (defaults to null).
+     * @cfg {String} emptyText The default text to display in an empty field - placeholder... (defaults to null).
      */
     emptyText : null,
-    /**
-     * @cfg {String} emptyClass The CSS class to apply to an empty field to style the {@link #emptyText} (defaults to
-     * 'x-form-empty-field').  This class is automatically added and removed as needed depending on the current field value.
-     */
-    emptyClass : 'x-form-empty-field',
+   
 
     // private
-    initEvents : function(){
+    initEvents : function()
+    {
+        if (this.emptyText) {
+            this.el.attr('placeholder', this.emptyText);
+        }
+        
         Roo.form.TextField.superclass.initEvents.call(this);
         if(this.validationEvent == 'keyup'){
             this.validationTask = new Roo.util.DelayedTask(this.validate, this);
@@ -36759,12 +36822,10 @@ Roo.extend(Roo.form.TextField, Roo.form.Field,  {
         else if(this.validationEvent !== false){
             this.el.on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
         }
-        if(this.selectOnFocus || this.emptyText){
+        
+        if(this.selectOnFocus){
             this.on("focus", this.preFocus, this);
-            if(this.emptyText){
-                this.on('blur', this.postBlur, this);
-                this.applyEmptyText();
-            }
+            
         }
         if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
             this.el.on("keypress", this.filterKeys, this);
@@ -36773,6 +36834,9 @@ Roo.extend(Roo.form.TextField, Roo.form.Field,  {
             this.el.on("keyup", this.onKeyUp,  this, {buffer:50});
             this.el.on("click", this.autoSize,  this);
         }
+        if(this.el.is('input[type=password]') && Roo.isSafari){
+            this.el.on('keydown', this.SafariOnKeyDown, this);
+        }
     },
 
     processValue : function(value){
@@ -36801,38 +36865,23 @@ Roo.extend(Roo.form.TextField, Roo.form.Field,  {
 
     /**
      * Resets the current field value to the originally-loaded value and clears any validation messages.
-     * Also adds emptyText and emptyClass if the original value was blank.
+     *  
      */
     reset : function(){
         Roo.form.TextField.superclass.reset.call(this);
-        this.applyEmptyText();
-    },
-
-    applyEmptyText : function(){
-        if(this.rendered && this.emptyText && this.getRawValue().length < 1){
-            this.setRawValue(this.emptyText);
-            this.el.addClass(this.emptyClass);
-        }
+       
     },
 
+    
     // private
     preFocus : function(){
-        if(this.emptyText){
-            if(this.el.dom.value == this.emptyText){
-                this.setRawValue('');
-            }
-            this.el.removeClass(this.emptyClass);
-        }
+        
         if(this.selectOnFocus){
             this.el.dom.select();
         }
     },
 
-    // private
-    postBlur : function(){
-        this.applyEmptyText();
-    },
-
+    
     // private
     filterKeys : function(e){
         var k = e.getKey();
@@ -36849,11 +36898,9 @@ Roo.extend(Roo.form.TextField, Roo.form.Field,  {
     },
 
     setValue : function(v){
-        if(this.emptyText && this.el && v !== undefined && v !== null && v !== ''){
-            this.el.removeClass(this.emptyClass);
-        }
+        
         Roo.form.TextField.superclass.setValue.apply(this, arguments);
-        this.applyEmptyText();
+        
         this.autoSize();
     },
 
@@ -36864,7 +36911,7 @@ Roo.extend(Roo.form.TextField, Roo.form.Field,  {
      * @return {Boolean} True if the value is valid, else false
      */
     validateValue : function(value){
-        if(value.length < 1 || value === this.emptyText){ // if it's blank
+        if(value.length < 1)  { // if it's blank
              if(this.allowBlank){
                 this.clearInvalid();
                 return true;
@@ -36945,6 +36992,35 @@ Roo.extend(Roo.form.TextField, Roo.form.Field,  {
         var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + /* add extra padding */ 10, this.growMin));
         this.el.setWidth(w);
         this.fireEvent("autosize", this, w);
+    },
+    
+    // private
+    SafariOnKeyDown : function(event)
+    {
+        // this is a workaround for a password hang bug on chrome/ webkit.
+        
+        var isSelectAll = false;
+        
+        if(this.el.dom.selectionEnd > 0){
+            isSelectAll = (this.el.dom.selectionEnd - this.el.dom.selectionStart - this.getValue().length == 0) ? true : false;
+        }
+        if(((event.getKey() == 8 || event.getKey() == 46) && this.getValue().length ==1)){ // backspace and delete key
+            event.preventDefault();
+            this.setValue('');
+            return;
+        }
+        
+        if(isSelectAll){ // backspace and delete key
+            
+            event.preventDefault();
+            // this is very hacky as keydown always get's upper case.
+            //
+            var cc = String.fromCharCode(event.getCharCode());
+            this.setValue( event.shiftKey ?  cc : cc.toLowerCase());
+            
+        }
+        
+        
     }
 });/*
  * Based on:
@@ -37679,7 +37755,9 @@ Roo.extend(Roo.form.DateField, Roo.form.TriggerField,  {
     {
         Roo.form.DateField.superclass.onRender.call(this, ct, position);
         if (this.useIso) {
-            this.el.dom.removeAttribute('name'); 
+            //this.el.dom.removeAttribute('name'); 
+            Roo.log("Changing name?");
+            this.el.dom.setAttribute('name', this.name + '____hidden___' ); 
             this.hiddenField = this.el.insertSibling({ tag:'input', type:'hidden', name: this.name },
                     'before', true);
             this.hiddenField.value = this.value ? this.formatDate(this.value, 'Y-m-d') : '';
@@ -37739,6 +37817,14 @@ Roo.extend(Roo.form.DateField, Roo.form.TriggerField,  {
     validateBlur : function(){
         return !this.menu || !this.menu.isVisible();
     },
+    
+    getName: function()
+    {
+        // returns hidden if it's set..
+        if (!this.rendered) {return ''};
+        return !this.hiddenName && this.el.dom.name  ? this.el.dom.name : (this.hiddenName || '');
+        
+    },
 
     /**
      * Returns the current date value of the date field.
@@ -38930,7 +39016,7 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
         this.value = '';
         this.setRawValue('');
         this.lastSelectionText = '';
-        this.applyEmptyText();
+        
     },
 
     /**
@@ -39166,7 +39252,7 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
         if(this.el.dom.value.length > 0){
             this.el.dom.value =
                 this.lastSelectionText === undefined ? '' : this.lastSelectionText;
-            this.applyEmptyText();
+             
         }
     },
 
@@ -39458,6 +39544,10 @@ Roo.extend(Roo.form.ComboBoxArray, Roo.form.TextField,
         
         this.combo = Roo.factory(this.combo, Roo.form);
         this.combo.onRender(ct, position);
+        if (typeof(this.combo.width) != 'undefined') {
+            this.combo.onResize(this.combo.width,0);
+        }
+        
         this.combo.initEvents();
         
         // assigned so form know we need to do this..
@@ -39642,7 +39732,7 @@ Roo.extend(Roo.form.ComboBoxArray, Roo.form.TextField,
                 if (!li.length) {
                     return;
                 }
-                add = {};
+                var add = {};
                 add[this.valueField] = k;
                 add[this.displayField] = li.item(0).data[this.displayField];
                 
@@ -40017,7 +40107,39 @@ Roo.extend(Roo.form.Radio, Roo.form.Checkbox, {
      */
     getGroupValue : function(){
         return this.el.up('form').child('input[name='+this.el.dom.name+']:checked', true).value;
-    }
+    },
+    
+    
+    onRender : function(ct, position){
+        Roo.form.Checkbox.superclass.onRender.call(this, ct, position);
+        
+        if(this.inputValue !== undefined){
+            this.el.dom.value = this.inputValue;
+        }
+         
+        this.wrap = this.el.wrap({cls: "x-form-check-wrap"});
+        //this.wrap = this.el.wrap({cls: 'x-menu-check-item '});
+        //var viewEl = this.wrap.createChild({ 
+        //    tag: 'img', cls: 'x-menu-item-icon', style: 'margin: 0px;' ,src : Roo.BLANK_IMAGE_URL });
+        //this.viewEl = viewEl;   
+        //this.wrap.on('click', this.onClick,  this); 
+        
+        //this.el.on('DOMAttrModified', this.setFromHidden,  this); //ff
+        //this.el.on('propertychange', this.setFromHidden,  this);  //ie
+        
+        
+        
+        if(this.boxLabel){
+            this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
+        //    viewEl.on('click', this.onClick,  this); 
+        }
+         if(this.checked){
+            this.el.dom.checked =   'checked' ;
+        }
+         
+    } 
+    
+    
 });//<script type="text/javascript">
 
 /*
@@ -40183,7 +40305,10 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         }
         
         for (var i =0 ; i < editor.toolbars.length;i++) {
-            editor.toolbars[i] = Roo.factory(editor.toolbars[i], Roo.form.HtmlEditor);
+            editor.toolbars[i] = Roo.factory(
+                    typeof(editor.toolbars[i]) == 'string' ?
+                        { xtype: editor.toolbars[i]} : editor.toolbars[i],
+                Roo.form.HtmlEditor);
             editor.toolbars[i].init(editor);
         }
          
@@ -40367,14 +40492,16 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         this.sourceEditMode = sourceEditMode === true;
         
         if(this.sourceEditMode){
-          
+//            Roo.log('in');
+//            Roo.log(this.syncValue());
             this.syncValue();
             this.iframe.className = 'x-hidden';
             this.el.removeClass('x-hidden');
             this.el.dom.removeAttribute('tabIndex');
             this.el.focus();
         }else{
-             
+//            Roo.log('out')
+//            Roo.log(this.pushValue()); 
             this.pushValue();
             this.iframe.className = '';
             this.el.addClass('x-hidden');
@@ -40463,9 +40590,18 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 }
             }
             html = this.cleanHtml(html);
-            // fix up the special chars..
+            // fix up the special chars.. normaly like back quotes in word...
+            // however we do not want to do this with chinese..
             html = html.replace(/([\x80-\uffff])/g, function (a, b) {
-                return "&#"+b.charCodeAt()+";" 
+                var cc = b.charCodeAt();
+                if (
+                    (cc >= 0x4E00 && cc < 0xA000 ) ||
+                    (cc >= 0x3400 && cc < 0x4E00 ) ||
+                    (cc >= 0xf900 && cc < 0xfb00 )
+                ) {
+                        return b;
+                }
+                return "&#"+cc+";" 
             });
             if(this.fireEvent('beforesync', this, html) !== false){
                 this.el.dom.value = html;
@@ -40481,6 +40617,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     pushValue : function(){
         if(this.initialized){
             var v = this.el.dom.value;
+            
             if(v.length < 1){
                 v = '&#160;';
             }
@@ -40641,7 +40778,18 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     insertTag : function(tg)
     {
         // could be a bit smarter... -> wrap the current selected tRoo..
-        
+        if (tg.toLowerCase() == 'span' || tg.toLowerCase() == 'code') {
+            
+            range = this.createRange(this.getSelection());
+            var wrappingNode = this.doc.createElement(tg.toLowerCase());
+            wrappingNode.appendChild(range.extractContents());
+            range.insertNode(wrappingNode);
+
+            return;
+            
+            
+            
+        }
         this.execCmd("formatblock",   tg);
         
     },
@@ -40650,7 +40798,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     {
         
         
-        range = this.createRange();
+        var range = this.createRange();
         range.deleteContents();
                //alert(Sender.getAttribute('label'));
                
@@ -41074,15 +41222,16 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         
     },
     
-    cleanWordChars : function(input) {
+    cleanWordChars : function(input) {// change the chars to hex code
         var he = Roo.form.HtmlEditor;
-    
+        
         var output = input;
         Roo.each(he.swapCodes, function(sw) { 
-        
             var swapper = new RegExp("\\u" + sw[0].toString(16), "g"); // hex codes
+            
             output = output.replace(swapper, sw[1]);
         });
+        
         return output;
     },
     
@@ -41103,7 +41252,6 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     cleanUpChild : function (node)
     {
         var ed = this;
-        
         //console.log(node);
         if (node.nodeName == "#text") {
             // clean up silly Windows -- stuff?
@@ -41160,7 +41308,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
             if (v.match(/^#/)) {
                 return;
             }
-            Roo.log("(REMOVE TAG)"+ node.tagName +'.' + n + '=' + v);
+//            Roo.log("(REMOVE TAG)"+ node.tagName +'.' + n + '=' + v);
             node.removeAttribute(n);
             
         }
@@ -41172,9 +41320,12 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 return;
             }
             var cwhite = typeof(ed.cwhite) == 'undefined' ? Roo.form.HtmlEditor.cwhite : ed.cwhite;
+            var cblack = typeof(ed.cblack) == 'undefined' ? Roo.form.HtmlEditor.cblack : ed.cblack;
+            
             
             var parts = v.split(/;/);
             var clean = [];
+            
             Roo.each(parts, function(p) {
                 p = p.replace(/^\s+/g,'').replace(/\s+$/g,'');
                 if (!p.length) {
@@ -41183,12 +41334,23 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 var l = p.split(':').shift().replace(/\s+/g,'');
                 l = l.replace(/^\s+/g,'').replace(/\s+$/g,'');
                 
+                
+                if ( cblack.indexOf(l) > -1) {
+//                    Roo.log('(REMOVE CSS)' + node.tagName +'.' + n + ':'+l + '=' + v);
+                    //node.removeAttribute(n);
+                    return true;
+                }
+                //Roo.log()
                 // only allow 'c whitelisted system attributes'
-                if ( cwhite.indexOf(l) < 0) {
-                    Roo.log('(REMOVE CSS)' + node.tagName +'.' + n + ':'+l + '=' + v);
+                if ( cwhite.length &&  cwhite.indexOf(l) < 0) {
+//                    Roo.log('(REMOVE CSS)' + node.tagName +'.' + n + ':'+l + '=' + v);
                     //node.removeAttribute(n);
                     return true;
                 }
+                
+                
+                 
+                
                 clean.push(p);
                 return true;
             });
@@ -41340,8 +41502,15 @@ Roo.form.HtmlEditor.pwhite= [
 
 // white listed style attributes.
 Roo.form.HtmlEditor.cwhite= [
-        'text-align',
-        'font-size'
+      //  'text-align', /// default is to allow most things..
+      
+         
+//        'font-size'//??
+];
+
+// black listed style attributes.
+Roo.form.HtmlEditor.cblack= [
+      //  'font-size' -- this can be set by the project 
 ];
 
 
@@ -41476,7 +41645,8 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
         ["p"] ,  
         ["h1"],["h2"],["h3"],["h4"],["h5"],["h6"], 
         ["pre"],[ "code"], 
-        ["abbr"],[ "acronym"],[ "address"],[ "cite"],[ "samp"],[ "var"]
+        ["abbr"],[ "acronym"],[ "address"],[ "cite"],[ "samp"],[ "var"],
+        ['div'],['span']
     ],
      /**
      * @cfg {String} defaultFont default font to use.
@@ -41519,24 +41689,27 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
             e.preventDefault(); // what does this do?
         });
 
-        if(!this.disable.font && !Roo.isSafari){
-            /* why no safari for fonts
+        if(!this.disable.font) { // && !Roo.isSafari){
+            /* why no safari for fonts 
             editor.fontSelect = tb.el.createChild({
                 tag:'select',
                 tabIndex: -1,
                 cls:'x-font-select',
-                html: editor.createFontOptions()
+                html: this.createFontOptions()
             });
+            
             editor.fontSelect.on('change', function(){
                 var font = editor.fontSelect.dom.value;
                 editor.relayCmd('fontname', font);
                 editor.deferFocus();
             }, editor);
+            
             tb.add(
                 editor.fontSelect.dom,
                 '-'
             );
             */
+            
         };
         if(!this.disable.formats){
             this.formatCombo = new Roo.form.ComboBox({
@@ -41820,6 +41993,9 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
     
     createFontOptions : function(){
         var buf = [], fs = this.fontFamilies, ff, lc;
+        
+        
+        
         for(var i = 0, len = fs.length; i< len; i++){
             ff = fs[i];
             lc = ff.toLowerCase();
@@ -42021,6 +42197,9 @@ Roo.form.HtmlEditor.ToolbarContext = function(config)
     // dont call parent... till later.
     this.styles = this.styles || {};
 }
+
+
 Roo.form.HtmlEditor.ToolbarContext.types = {
     'IMG' : {
         width : {
@@ -42107,6 +42286,13 @@ Roo.form.HtmlEditor.ToolbarContext.types = {
             title: "Colspan",
             width: 20
             
+        },
+         'font-family'  : {
+            title : "Font",
+            style : 'fontFamily',
+            displayField: 'display',
+            optname : 'font-family',
+            width: 140
         }
     },
     'INPUT' : {
@@ -42158,16 +42344,62 @@ Roo.form.HtmlEditor.ToolbarContext.types = {
     // should this just be 
     'BODY' : {
         title : {
-            title: "title",
+            title: "Title",
             width: 200,
             disabled : true
         }
     },
+    'SPAN' : {
+        'font-family'  : {
+            title : "Font",
+            style : 'fontFamily',
+            displayField: 'display',
+            optname : 'font-family',
+            width: 140
+        }
+    },
+    'DIV' : {
+        'font-family'  : {
+            title : "Font",
+            style : 'fontFamily',
+            displayField: 'display',
+            optname : 'font-family',
+            width: 140
+        }
+    },
+     'P' : {
+        'font-family'  : {
+            title : "Font",
+            style : 'fontFamily',
+            displayField: 'display',
+            optname : 'font-family',
+            width: 140
+        }
+    },
+    
     '*' : {
         // empty..
     }
+
+};
+
+// this should be configurable.. - you can either set it up using stores, or modify options somehwere..
+Roo.form.HtmlEditor.ToolbarContext.stores = false;
+
+Roo.form.HtmlEditor.ToolbarContext.options = {
+        'font-family'  : [ 
+                [ 'Helvetica,Arial,sans-serif', 'Helvetica'],
+                [ 'Courier New', 'Courier New'],
+                [ 'Tahoma', 'Tahoma'],
+                [ 'Times New Roman,serif', 'Times'],
+                [ 'Verdana','Verdana' ]
+        ]
 };
 
+// fixme - these need to be configurable..
+
+Roo.form.HtmlEditor.ToolbarContext.types
 
 
 Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
@@ -42193,7 +42425,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
      */
     styles : false,
     
-    
+    options: false,
     
     toolbars : false,
     
@@ -42328,6 +42560,10 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
             // update attributes
             if (this.tb.fields) {
                 this.tb.fields.each(function(e) {
+                    if (e.stylename) {
+                        e.setValue(sel.style[e.stylename]);
+                        return;
+                    } 
                    e.setValue(sel.getAttribute(e.attrname));
                 });
             }
@@ -42457,7 +42693,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                 }),
                 name : '-roo-edit-className',
                 attrname : 'className',
-                displayField:'val',
+                displayField: 'val',
                 typeAhead: false,
                 mode: 'local',
                 editable : false,
@@ -42475,8 +42711,9 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
     
             }));
         }
-            
         
+        var tbc = Roo.form.HtmlEditor.ToolbarContext;
+        var tbops = tbc.options;
         
         for (var i in tlist) {
             
@@ -42484,21 +42721,28 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
             tb.add(item.title + ":&nbsp;");
             
             
+            //optname == used so you can configure the options available..
+            var opts = item.opts ? item.opts : false;
+            if (item.optname) {
+                opts = tbops[item.optname];
+           
+            }
             
-            
-            if (item.opts) {
+            if (opts) {
                 // opts == pulldown..
                 tb.addField( new Roo.form.ComboBox({
-                    store: new Roo.data.SimpleStore({
+                    store:   typeof(tbc.stores[i]) != 'undefined' ?  Roo.factory(tbc.stores[i],Roo.data) : new Roo.data.SimpleStore({
                         id : 'val',
-                        fields: ['val'],
-                        data : item.opts  
+                        fields: ['val', 'display'],
+                        data : opts  
                     }),
                     name : '-roo-edit-' + i,
                     attrname : i,
-                    displayField:'val',
+                    stylename : item.style ? item.style : false,
+                    displayField: item.displayField ? item.displayField : 'val',
+                    valueField :  'val',
                     typeAhead: false,
-                    mode: 'local',
+                    mode: typeof(tbc.stores[i]) != 'undefined'  ? 'remote' : 'local',
                     editable : false,
                     triggerAction: 'all',
                     emptyText:'Select',
@@ -42506,6 +42750,10 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                     width: item.width ? item.width  : 130,
                     listeners : {
                         'select': function(c, r, i) {
+                            if (c.stylename) {
+                                tb.selectedNode.style[c.stylename] =  r.get('val');
+                                return;
+                            }
                             tb.selectedNode.setAttribute(c.attrname, r.get('val'));
                         }
                     }
@@ -42550,7 +42798,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                     // undo does not work.
                      
                     var sn = tb.selectedNode;
-                    Roo.log(sn);
+                    
                     var pn = sn.parentNode;
                     
                     var stn =  sn.childNodes[0];
@@ -42558,7 +42806,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                     while (sn.childNodes.length) {
                         var node = sn.childNodes[0];
                         sn.removeChild(node);
-                        Roo.log(node);
+                        //Roo.log(node);
                         pn.insertBefore(node, sn);
                         
                     }
@@ -42578,7 +42826,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                     
                     //_this.updateToolbar(null, null, pn);
                     _this.updateToolbar(null, null, null);
-                    this.footDisp.dom.innerHTML = ''; 
+                    _this.footDisp.dom.innerHTML = ''; 
                 }
             }
             
@@ -42641,7 +42889,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
     {
         ev.preventDefault();
         var  cn = dom.className;
-        Roo.log(cn);
+        //Roo.log(cn);
         if (!cn.match(/x-ed-loc-/)) {
             return;
         }
@@ -43180,6 +43428,19 @@ clientValidation  Boolean          Applies to submit only.  Pass true to call fo
                 return;
             }
             var v = f.getValue();
+            if (f.inputType =='radio') {
+                if (typeof(ret[f.getName()]) == 'undefined') {
+                    ret[f.getName()] = ''; // empty..
+                }
+                
+                if (!f.el.dom.checked) {
+                    return;
+                    
+                }
+                v = f.el.dom.value;
+                
+            }
+            
             // not sure if this supported any more..
             if ((typeof(v) == 'object') && f.getRawValue) {
                 v = f.getRawValue() ; // dates..
@@ -45371,6 +45632,7 @@ Roo.extend(Roo.form.ComboCheck, Roo.form.ComboBox, {
         this.setValue('[]');
         if (this.value != this.valueBefore) {
             this.fireEvent('change', this, this.value, this.valueBefore);
+            this.valueBefore = this.value;
         }
     },
     getValueArray : function()
@@ -45393,8 +45655,10 @@ Roo.extend(Roo.form.ComboCheck, Roo.form.ComboBox, {
     },
     expand : function ()
     {
+        
         Roo.form.ComboCheck.superclass.expand.call(this);
-        this.valueBefore = this.value;
+        this.valueBefore = typeof(this.value) == 'undefined' ? '' : this.value;
+        //this.valueBefore = typeof(this.valueBefore) == 'undefined' ? '' : this.valueBefore;
         
 
     },
@@ -45414,6 +45678,7 @@ Roo.extend(Roo.form.ComboCheck, Roo.form.ComboBox, {
         if (this.value != this.valueBefore) {
 
             this.fireEvent('change', this, this.value, this.valueBefore);
+            this.valueBefore = this.value;
         }
         
     },
@@ -45439,6 +45704,359 @@ Roo.extend(Roo.form.ComboCheck, Roo.form.ComboBox, {
         this.value = v;
     }
     
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+/**
+ * @class Roo.form.Signature
+ * @extends Roo.form.Field
+ * Signature field.  
+ * @constructor
+ * 
+ * @param {Object} config Configuration options
+ */
+
+Roo.form.Signature = function(config){
+    Roo.form.Signature.superclass.constructor.call(this, config);
+    
+    this.addEvents({// not in used??
+         /**
+         * @event confirm
+         * Fires when the 'confirm' icon is pressed (add a listener to enable add button)
+            * @param {Roo.form.Signature} combo This combo box
+            */
+        'confirm' : true,
+        /**
+         * @event reset
+         * Fires when the 'edit' icon is pressed (add a listener to enable add button)
+            * @param {Roo.form.ComboBox} combo This combo box
+            * @param {Roo.data.Record|false} record The data record returned from the underlying store (or false on nothing selected)
+            */
+        'reset' : true
+    });
+};
+
+Roo.extend(Roo.form.Signature, Roo.form.Field,  {
+    /**
+     * @cfg {Object} labels Label to use when rendering a form.
+     * defaults to 
+     * labels : { 
+     *      clear : "Clear",
+     *      confirm : "Confirm"
+     *  }
+     */
+    labels : { 
+        clear : "Clear",
+        confirm : "Confirm"
+    },
+    /**
+     * @cfg {Number} width The signature panel width (defaults to 300)
+     */
+    width: 300,
+    /**
+     * @cfg {Number} height The signature panel height (defaults to 100)
+     */
+    height : 100,
+    /**
+     * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to false)
+     */
+    allowBlank : false,
+    
+    //private
+    // {Object} signPanel The signature SVG panel element (defaults to {})
+    signPanel : {},
+    // {Boolean} isMouseDown False to validate that the mouse down event (defaults to false)
+    isMouseDown : false,
+    // {Boolean} isConfirmed validate the signature is confirmed or not for submitting form (defaults to false)
+    isConfirmed : false,
+    // {String} signatureTmp SVG mapping string (defaults to empty string)
+    signatureTmp : '',
+    
+    
+    defaultAutoCreate : { // modified by initCompnoent..
+        tag: "input",
+        type:"hidden"
+    },
+
+    // private
+    onRender : function(ct, position){
+        
+        Roo.form.Signature.superclass.onRender.call(this, ct, position);
+        
+        this.wrap = this.el.wrap({
+            cls:'x-form-signature-wrap', style : 'width: ' + this.width + 'px', cn:{cls:'x-form-signature'}
+        });
+        
+        this.createToolbar(this);
+        this.signPanel = this.wrap.createChild({
+                tag: 'div',
+                style: 'width: ' + this.width + 'px; height: ' + this.height + 'px; border: 0;'
+            }, this.el
+        );
+            
+        this.svgID = Roo.id();
+        this.svgEl = this.signPanel.createChild({
+              xmlns : 'http://www.w3.org/2000/svg',
+              tag : 'svg',
+              id : this.svgID + "-svg",
+              width: this.width,
+              height: this.height,
+              viewBox: '0 0 '+this.width+' '+this.height,
+              cn : [
+                {
+                    tag: "rect",
+                    id: this.svgID + "-svg-r",
+                    width: this.width,
+                    height: this.height,
+                    fill: "#ffa"
+                },
+                {
+                    tag: "line",
+                    id: this.svgID + "-svg-l",
+                    x1: "0", // start
+                    y1: (this.height*0.8), // start set the line in 80% of height
+                    x2: this.width, // end
+                    y2: (this.height*0.8), // end set the line in 80% of height
+                    'stroke': "#666",
+                    'stroke-width': "1",
+                    'stroke-dasharray': "3",
+                    'shape-rendering': "crispEdges",
+                    'pointer-events': "none"
+                },
+                {
+                    tag: "path",
+                    id: this.svgID + "-svg-p",
+                    'stroke': "navy",
+                    'stroke-width': "3",
+                    'fill': "none",
+                    'pointer-events': 'none'
+                }
+              ]
+        });
+        this.createSVG();
+        this.svgBox = this.svgEl.dom.getScreenCTM();
+    },
+    createSVG : function(){ 
+        var svg = this.signPanel;
+        var r = svg.select('#'+ this.svgID + '-svg-r', true).first().dom;
+        var t = this;
+
+        r.addEventListener('mousedown', function(e) { return t.down(e); }, false);
+        r.addEventListener('mousemove', function(e) { return t.move(e); }, false);
+        r.addEventListener('mouseup', function(e) { return t.up(e); }, false);
+        r.addEventListener('mouseout', function(e) { return t.up(e); }, false);
+        r.addEventListener('touchstart', function(e) { return t.down(e); }, false);
+        r.addEventListener('touchmove', function(e) { return t.move(e); }, false);
+        r.addEventListener('touchend', function(e) { return t.up(e); }, false);
+        
+    },
+    isTouchEvent : function(e){
+        return e.type.match(/^touch/);
+    },
+    getCoords : function (e) {
+        var pt    = this.svgEl.dom.createSVGPoint();
+        pt.x = e.clientX; 
+        pt.y = e.clientY;
+        if (this.isTouchEvent(e)) {
+            pt.x =  e.targetTouches[0].clientX 
+            pt.y = e.targetTouches[0].clientY;
+        }
+        var a = this.svgEl.dom.getScreenCTM();
+        var b = a.inverse();
+        var mx = pt.matrixTransform(b);
+        return mx.x + ',' + mx.y;
+    },
+    //mouse event headler 
+    down : function (e) {
+        this.signatureTmp += 'M' + this.getCoords(e) + ' ';
+        this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr('d', this.signatureTmp);
+        
+        this.isMouseDown = true;
+        
+        e.preventDefault();
+    },
+    move : function (e) {
+        if (this.isMouseDown) {
+            this.signatureTmp += 'L' + this.getCoords(e) + ' ';
+            this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', this.signatureTmp);
+        }
+        
+        e.preventDefault();
+    },
+    up : function (e) {
+        this.isMouseDown = false;
+        var sp = this.signatureTmp.split(' ');
+        
+        if(sp.length > 1){
+            if(!sp[sp.length-2].match(/^L/)){
+                sp.pop();
+                sp.pop();
+                sp.push("");
+                this.signatureTmp = sp.join(" ");
+            }
+        }
+        if(this.getValue() != this.signatureTmp){
+            this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
+            this.isConfirmed = false;
+        }
+        e.preventDefault();
+    },
+    
+    /**
+     * Protected method that will not generally be called directly. It
+     * is called when the editor creates its toolbar. Override this method if you need to
+     * add custom toolbar buttons.
+     * @param {HtmlEditor} editor
+     */
+    createToolbar : function(editor){
+         function btn(id, toggle, handler){
+            var xid = fid + '-'+ id ;
+            return {
+                id : xid,
+                cmd : id,
+                cls : 'x-btn-icon x-edit-'+id,
+                enableToggle:toggle !== false,
+                scope: editor, // was editor...
+                handler:handler||editor.relayBtnCmd,
+                clickEvent:'mousedown',
+                tooltip: etb.buttonTips[id] || undefined, ///tips ???
+                tabIndex:-1
+            };
+        }
+        
+        
+        var tb = new Roo.Toolbar(editor.wrap.dom.firstChild);
+        this.tb = tb;
+        this.tb.add(
+           {
+                cls : ' x-signature-btn x-signature-'+id,
+                scope: editor, // was editor...
+                handler: this.reset,
+                clickEvent:'mousedown',
+                text: this.labels.clear
+            },
+            {
+                 xtype : 'Fill',
+                 xns: Roo.Toolbar
+            }, 
+            {
+                cls : '  x-signature-btn x-signature-'+id,
+                scope: editor, // was editor...
+                handler: this.confirmHandler,
+                clickEvent:'mousedown',
+                text: this.labels.confirm
+            }
+        );
+    
+    },
+    //public
+    /**
+     * when user is clicked confirm then show this image.....
+     * 
+     * @return {String} Image Data URI
+     */
+    getImageDataURI : function(){
+        var svg = this.svgEl.dom.parentNode.innerHTML;
+        var src = 'data:image/svg+xml;base64,'+window.btoa(svg);
+        return src; 
+    },
+    /**
+     * 
+     * @return {Boolean} this.isConfirmed
+     */
+    getConfirmed : function(){
+        return this.isConfirmed;
+    },
+    /**
+     * 
+     * @return {Number} this.width
+     */
+    getWidth : function(){
+        return this.width;
+    },
+    /**
+     * 
+     * @return {Number} this.height
+     */
+    getHeight : function(){
+        return this.height;
+    },
+    // private
+    getSignature : function(){
+        return this.signatureTmp;
+    },
+    // private
+    reset : function(){
+        this.signatureTmp = '';
+        this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
+        this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', '');
+        this.isConfirmed = false;
+        Roo.form.Signature.superclass.reset.call(this);
+    },
+    setSignature : function(s){
+        this.signatureTmp = s;
+        this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
+        this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', s);
+        this.setValue(s);
+        this.isConfirmed = false;
+        Roo.form.Signature.superclass.reset.call(this);
+    }, 
+    test : function(){
+//        Roo.log(this.signPanel.dom.contentWindow.up())
+    },
+    //private
+    setConfirmed : function(){
+        
+        
+        
+//        Roo.log(Roo.get(this.signPanel.dom.contentWindow.r).attr('fill', '#cfc'));
+    },
+    // private
+    confirmHandler : function(){
+        if(!this.getSignature()){
+            return;
+        }
+        this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#cfc');
+        this.setValue(this.getSignature());
+        this.isConfirmed = true;
+        
+        Roo.log('in confirm clicked');
+//        
+//        var valid = true;
+//        this.items.each(function(f){
+//            if(!f.isValid(true)){
+//                valid = false;
+//                return false;
+//            }
+//        });
+//        for(var i = 0, len = this.buttons.length; i < len; i++){
+//            var btn = this.buttons[i];
+//            if(btn.formBind === true && btn.disabled === valid){
+//                btn.setDisabled(!valid);
+//            }
+//        }
+        this.fireEvent('confirm', this);
+    },
+    // private
+    // Subclasses should provide the validation implementation by overriding this
+    validateValue : function(value){
+        if(this.allowBlank){
+            return true;
+        }
+        
+        if(this.isConfirmed){
+            return true;
+        }
+        return false;
+    }
 });//<script type="text/javasscript">
  
 
@@ -46402,6 +47020,7 @@ layout.addxtype({
         {
             case 'ContentPanel':  // ContentPanel (el, cfg)
             case 'ScrollPanel':  // ContentPanel (el, cfg)
+            case 'ViewPanel': 
                 if(cfg.autoCreate) {
                     ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
                 } else {
@@ -46467,7 +47086,9 @@ layout.addxtype({
                 }
                 break;
            
-               
+           
+           
+                
                 
                 
             default: 
@@ -48250,12 +48871,7 @@ Roo.ContentPanel = function(el, config, content){
     }
     // handle view.xtype
     
-    if (this.view && typeof(this.view.xtype) != 'undefined') {
-        this.view.el = this.el.appendChild(document.createElement("div"));
-        this.view = Roo.factory(this.view);
-        this.view.render && this.view.render(false, ''); // render blank..
-    }
-    
     
     
     this.addEvents({
@@ -48291,6 +48907,10 @@ Roo.ContentPanel = function(el, config, content){
         
         
     });
+    
+
+    
+    
     if(this.autoScroll){
         this.resizeEl.setStyle("overflow", "auto");
     } else {
@@ -48312,6 +48932,13 @@ Roo.ContentPanel = function(el, config, content){
     
     Roo.ContentPanel.superclass.constructor.call(this);
     
+    if (this.view && typeof(this.view.xtype) != 'undefined') {
+        this.view.el = this.el.appendChild(document.createElement("div"));
+        this.view = Roo.factory(this.view); 
+        this.view.render  &&  this.view.render(false, '');  
+    }
+    
+    
     this.fireEvent('render', this);
 };
 
@@ -48583,13 +49210,15 @@ layout.addxtype({
             return this.form;
         }
         // should only have one of theses..
-        if (['View', 'JsonView', 'DatePicker'].indexOf(cfg.xtype) > -1) {
-            // views..
+        if ([ 'View', 'JsonView', 'DatePicker'].indexOf(cfg.xtype) > -1) {
+            // views.. should not be just added - used named prop 'view''
+            
             cfg.el = this.el.appendChild(document.createElement("div"));
             // factory?
             
             var ret = new Roo.factory(cfg);
-            ret.render && ret.render(false, ''); // render blank..
+             
+             ret.render && ret.render(false, ''); // render blank..
             this.view = ret;
             return ret;
         }
@@ -53837,9 +54466,23 @@ Roo.LoadMask.prototype = {
     
     onLoadException : function()
     {
-        if (this.store && typeof(this.store.reader.jsonData.errorMsg) != 'undefined') {
-            Roo.MessageBox.alert("Error loading",this.store.reader.jsonData.errorMsg);
+        Roo.log(arguments);
+        
+        if (typeof(arguments[3]) != 'undefined') {
+            Roo.MessageBox.alert("Error loading",arguments[3]);
+        } 
+        /*
+        try {
+            if (this.store && typeof(this.store.reader.jsonData.errorMsg) != 'undefined') {
+                Roo.MessageBox.alert("Error loading",this.store.reader.jsonData.errorMsg);
+            }   
+        } catch(e) {
+            
         }
+        */
+    
+        
+        
         this.el.unmask(this.removeMask);
     },
     // private
@@ -54562,26 +55205,36 @@ Roo.apply(Roo.XComponent, {
         // make a flat list in order of modules to build.
         var mods = this.topModule ? [ this.topModule ] : [];
                
+        
        // elmodules (is a list of DOM based modules )
         Roo.each(this.elmodules, function(e) {
-            mods.push(e)
+            mods.push(e);
+            if (!this.topModule &&
+                typeof(e.parent) == 'string' &&
+                e.parent.substring(0,1) == '#' &&
+                Roo.get(e.parent.substr(1))
+               ) {
+                
+                _this.topModule = e;
+            }
+            
         });
 
         
         // add modules to their parents..
         var addMod = function(m) {
-           Roo.debug && Roo.log("build Order: add: " + m.name);
-            
-        mods.push(m);
-        if (m.modules && !m.disabled) {
-            Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules");
-            m.modules.keySort('ASC',  cmp );
-            Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules (after sort)");
-
-            m.modules.each(addMod);
-        } else {
-            Roo.debug && Roo.log("build Order: no child modules");
-           }
+            Roo.debug && Roo.log("build Order: add: " + m.name);
+                
+            mods.push(m);
+            if (m.modules && !m.disabled) {
+                Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules");
+                m.modules.keySort('ASC',  cmp );
+                Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules (after sort)");
+    
+                m.modules.each(addMod);
+            } else {
+                Roo.debug && Roo.log("build Order: no child modules");
+            }
             // not sure if this is used any more..
             if (m.finalize) {
                 m.finalize.name = m.name + " (clean up) ";
@@ -54589,10 +55242,10 @@ Roo.apply(Roo.XComponent, {
             }
             
         }
-        if (this.topModule) { 
+        if (this.topModule && this.topModule.modules) { 
             this.topModule.modules.keySort('ASC',  cmp );
             this.topModule.modules.each(addMod);
-        }
+        } 
         return mods;
     },
     
@@ -54739,614 +55392,4 @@ Roo.XComponent.event = new Roo.util.Observable({
 });
 
 Roo.XComponent.on = Roo.XComponent.event.on.createDelegate(Roo.XComponent.event); 
- //<script type="text/javascript">
-
-
-/**
- * @class Roo.Login
- * @extends Roo.LayoutDialog
- * A generic Login Dialog..... - only one needed in theory!?!?
- *
- * Fires XComponent builder on success...
- * 
- * Sends 
- *    username,password, lang = for login actions.
- *    check = 1 for periodic checking that sesion is valid.
- *    passwordRequest = email request password
- *    logout = 1 = to logout
- * 
- * Affects: (this id="????" elements)
- *   loading  (removed) (used to indicate application is loading)
- *   loading-mask (hides) (used to hide application when it's building loading)
- *   
- * 
- * Usage: 
- *    
- * 
- * Myapp.login = Roo.Login({
-     url: xxxx,
-   
-     realm : 'Myapp', 
-     
-     
-     method : 'POST',
-     
-     
-     * 
- })
- * 
- * 
- * 
- **/
-Roo.Login = function(cfg)
-{
-    this.addEvents({
-        'refreshed' : true
-    });
-    
-    Roo.apply(this,cfg);
-    
-    Roo.onReady(function() {
-        this.onLoad();
-    }, this);
-    // call parent..
-    
-   
-    Roo.Login.superclass.constructor.call(this, this);
-    //this.addxtype(this.items[0]);
-    
-    
-}
-
-
-Roo.extend(Roo.Login, Roo.LayoutDialog, {
-    
-    /**
-     * @cfg {String} method
-     * Method used to query for login details.
-     */
-    
-    method : 'POST',
-    /**
-     * @cfg {String} url
-     * URL to query login data. - eg. baseURL + '/Login.php'
-     */
-    url : '',
-    
-    /**
-     * @property user
-     * The user data - if user.id < 0 then login will be bypassed. (used for inital setup situation.
-     * @type {Object} 
-     */
-    user : false,
-    /**
-     * @property checkFails
-     * Number of times we have attempted to get authentication check, and failed.
-     * @type {Number} 
-     */
-    checkFails : 0,
-      /**
-     * @property intervalID
-     * The window interval that does the constant login checking.
-     * @type {Number} 
-     */
-    intervalID : 0,
-    
-    
-    onLoad : function() // called on page load...
-    {
-        // load 
-         
-        if (Roo.get('loading')) { // clear any loading indicator..
-            Roo.get('loading').remove();
-        }
-        
-        //this.switchLang('en'); // set the language to english..
-       
-        this.check({
-            success:  function(response, opts)  {  // check successfull...
-            
-                var res = this.processResponse(response);
-                this.checkFails =0;
-                if (!res.success) { // error!
-                    this.checkFails = 5;
-                    //console.log('call failure');
-                    return this.failure(response,opts);
-                }
-                
-                if (!res.data.id) { // id=0 == login failure.
-                    return this.show();
-                }
-                
-                              
-                        //console.log(success);
-                this.fillAuth(res.data);   
-                this.checkFails =0;
-                Roo.XComponent.build();
-            },
-            failure : this.show
-        });
-        
-    }, 
-    
-    
-    check: function(cfg) // called every so often to refresh cookie etc..
-    {
-        if (cfg.again) { // could be undefined..
-            this.checkFails++;
-        } else {
-            this.checkFails = 0;
-        }
-        var _this = this;
-        if (this.sending) {
-            if ( this.checkFails > 4) {
-                Roo.MessageBox.alert("Error",  
-                    "Error getting authentication status. - try reloading, or wait a while", function() {
-                        _this.sending = false;
-                    }); 
-                return;
-            }
-            cfg.again = true;
-            _this.check.defer(10000, _this, [ cfg ]); // check in 10 secs.
-            return;
-        }
-        this.sending = true;
-        
-        Roo.Ajax.request({  
-            url: this.url,
-            params: {
-                getAuthUser: true
-            },  
-            method: this.method,
-            success:  cfg.success || this.success,
-            failure : cfg.failure || this.failure,
-            scope : this,
-            callCfg : cfg
-              
-        });  
-    }, 
-    
-    
-    logout: function()
-    {
-        window.onbeforeunload = function() { }; // false does not work for IE..
-        this.user = false;
-        var _this = this;
-        
-        Roo.Ajax.request({  
-            url: this.url,
-            params: {
-                logout: 1
-            },  
-            method: 'GET',
-            failure : function() {
-                Roo.MessageBox.alert("Error", "Error logging out. - continuing anyway.", function() {
-                    document.location = document.location.toString() + '?ts=' + Math.random();
-                });
-                
-            },
-            success : function() {
-                _this.user = false;
-                this.checkFails =0;
-                // fixme..
-                document.location = document.location.toString() + '?ts=' + Math.random();
-            }
-              
-              
-        }); 
-    },
-    
-    processResponse : function (response)
-    {
-        var res = '';
-        try {
-            res = Roo.decode(response.responseText);
-            // oops...
-            if (typeof(res) != 'object') {
-                res = { success : false, errorMsg : res, errors : true };
-            }
-            if (typeof(res.success) == 'undefined') {
-                res.success = false;
-            }
-            
-        } catch(e) {
-            res = { success : false,  errorMsg : response.responseText, errors : true };
-        }
-        return res;
-    },
-    
-    success : function(response, opts)  // check successfull...
-    {  
-        this.sending = false;
-        var res = this.processResponse(response);
-        if (!res.success) {
-            return this.failure(response, opts);
-        }
-        if (!res.data || !res.data.id) {
-            return this.failure(response,opts);
-        }
-        //console.log(res);
-        this.fillAuth(res.data);
-        
-        this.checkFails =0;
-        
-    },
-    
-    
-    failure : function (response, opts) // called if login 'check' fails.. (causes re-check)
-    {
-        this.authUser = -1;
-        this.sending = false;
-        var res = this.processResponse(response);
-        //console.log(res);
-        if ( this.checkFails > 2) {
-        
-            Roo.MessageBox.alert("Error", res.errorMsg ? res.errorMsg : 
-                "Error getting authentication status. - try reloading"); 
-            return;
-        }
-        opts.callCfg.again = true;
-        this.check.defer(1000, this, [ opts.callCfg ]);
-        return;  
-    },
-    
-    
-    
-    fillAuth: function(au) {
-        this.startAuthCheck();
-        this.authUserId = au.id;
-        this.authUser = au;
-        this.lastChecked = new Date();
-        this.fireEvent('refreshed', au);
-        //Pman.Tab.FaxQueue.newMaxId(au.faxMax);
-        //Pman.Tab.FaxTab.setTitle(au.faxNumPending);
-        au.lang = au.lang || 'en';
-        //this.switchLang(Roo.state.Manager.get('Pman.Login.lang', 'en'));
-        Roo.state.Manager.set( this.realm + 'lang' , au.lang);
-        this.switchLang(au.lang );
-        
-     
-        // open system... - -on setyp..
-        if (this.authUserId  < 0) {
-            Roo.MessageBox.alert("Warning", 
-                "This is an open system - please set up a admin user with a password.");  
-        }
-         
-        //Pman.onload(); // which should do nothing if it's a re-auth result...
-        
-             
-    },
-    
-    startAuthCheck : function() // starter for timeout checking..
-    {
-        if (this.intervalID) { // timer already in place...
-            return false;
-        }
-        var _this = this;
-        this.intervalID =  window.setInterval(function() {
-              _this.check(false);
-            }, 120000); // every 120 secs = 2mins..
-        
-        
-    },
-         
-    
-    switchLang : function (lang) 
-    {
-        _T = typeof(_T) == 'undefined' ? false : _T;
-          if (!_T || !lang.length) {
-            return;
-        }
-        
-        if (!_T && lang != 'en') {
-            Roo.MessageBox.alert("Sorry", "Language not available yet (" + lang +')');
-            return;
-        }
-        
-        if (typeof(_T.en) == 'undefined') {
-            _T.en = {};
-            Roo.apply(_T.en, _T);
-        }
-        
-        if (typeof(_T[lang]) == 'undefined') {
-            Roo.MessageBox.alert("Sorry", "Language not available yet (" + lang +')');
-            return;
-        }
-        
-        
-        Roo.apply(_T, _T[lang]);
-        // just need to set the text values for everything...
-        var _this = this;
-        /* this will not work ...
-        if (this.form) { 
-            
-               
-            function formLabel(name, val) {
-                _this.form.findField(name).fieldEl.child('label').dom.innerHTML  = val;
-            }
-            
-            formLabel('password', "Password"+':');
-            formLabel('username', "Email Address"+':');
-            formLabel('lang', "Language"+':');
-            this.dialog.setTitle("Login");
-            this.dialog.buttons[0].setText("Forgot Password");
-            this.dialog.buttons[1].setText("Login");
-        }
-        */
-        
-        
-    },
-    
-    
-    title: "Login",
-    modal: true,
-    width:  350,
-    //height: 230,
-    height: 180,
-    shadow: true,
-    minWidth:200,
-    minHeight:180,
-    //proxyDrag: true,
-    closable: false,
-    draggable: false,
-    collapsible: false,
-    resizable: false,
-    center: {  // needed??
-        autoScroll:false,
-        titlebar: false,
-       // tabPosition: 'top',
-        hideTabs: true,
-        closeOnTab: true,
-        alwaysShowTabs: false
-    } ,
-    listeners : {
-        
-        show  : function(dlg)
-        {
-            //console.log(this);
-            this.form = this.layout.getRegion('center').activePanel.form;
-            this.form.dialog = dlg;
-            this.buttons[0].form = this.form;
-            this.buttons[0].dialog = dlg;
-            this.buttons[1].form = this.form;
-            this.buttons[1].dialog = dlg;
-           
-           //this.resizeToLogo.defer(1000,this);
-            // this is all related to resizing for logos..
-            //var sz = Roo.get(Pman.Login.form.el.query('img')[0]).getSize();
-           //// if (!sz) {
-             //   this.resizeToLogo.defer(1000,this);
-             //   return;
-           // }
-            //var w = Ext.lib.Dom.getViewWidth() - 100;
-            //var h = Ext.lib.Dom.getViewHeight() - 100;
-            //this.resizeTo(Math.max(350, Math.min(sz.width + 30, w)),Math.min(sz.height+200, h));
-            //this.center();
-            if (this.disabled) {
-                this.hide();
-                return;
-            }
-            
-            if (this.user.id < 0) { // used for inital setup situations.
-                return;
-            }
-            
-            if (this.intervalID) {
-                // remove the timer
-                window.clearInterval(this.intervalID);
-                this.intervalID = false;
-            }
-            
-            
-            if (Roo.get('loading')) {
-                Roo.get('loading').remove();
-            }
-            if (Roo.get('loading-mask')) {
-                Roo.get('loading-mask').hide();
-            }
-            
-            //incomming._node = tnode;
-            this.form.reset();
-            //this.dialog.modal = !modal;
-            //this.dialog.show();
-            this.el.unmask(); 
-            
-            
-            this.form.setValues({
-                'username' : Roo.state.Manager.get(this.realm + '.username', ''),
-                'lang' : Roo.state.Manager.get(this.realm + '.lang', 'en')
-            });
-            
-            this.switchLang(Roo.state.Manager.get(this.realm + '.lang', 'en'));
-            if (this.form.findField('username').getValue().length > 0 ){
-                this.form.findField('password').focus();
-            } else {
-               this.form.findField('username').focus();
-            }
-    
-        }
-    },
-    items : [
-         {
-       
-            xtype : 'ContentPanel',
-            xns : Roo,
-            region: 'center',
-            fitToFrame : true,
-            
-            items : [
-    
-                {
-               
-                    xtype : 'Form',
-                    xns : Roo.form,
-                    labelWidth: 100,
-                    style : 'margin: 10px;',
-                    
-                    listeners : {
-                        actionfailed : function(f, act) {
-                            // form can return { errors: .... }
-                                
-                            //act.result.errors // invalid form element list...
-                            //act.result.errorMsg// invalid form element list...
-                            
-                            this.dialog.el.unmask();
-                            Roo.MessageBox.alert("Error", act.result.errorMsg ? act.result.errorMsg : 
-                                        "Login failed - communication error - try again.");
-                                      
-                        },
-                        actioncomplete: function(re, act) {
-                             
-                            Roo.state.Manager.set(
-                                this.dialog.realm + '.username',  
-                                    this.findField('username').getValue()
-                            );
-                            Roo.state.Manager.set(
-                                this.dialog.realm + '.lang',  
-                                this.findField('lang').getValue() 
-                            );
-                            
-                            this.dialog.fillAuth(act.result.data);
-                              
-                            this.dialog.hide();
-                            
-                            if (Roo.get('loading-mask')) {
-                                Roo.get('loading-mask').show();
-                            }
-                            Roo.XComponent.build();
-                            
-                             
-                            
-                        }
-                    },
-                    items : [
-                        {
-                            xtype : 'TextField',
-                            xns : Roo.form,
-                            fieldLabel: "Email Address",
-                            name: 'username',
-                            width:200,
-                            autoCreate : {tag: "input", type: "text", size: "20"}
-                        },
-                        {
-                            xtype : 'TextField',
-                            xns : Roo.form,
-                            fieldLabel: "Password",
-                            inputType: 'password',
-                            name: 'password',
-                            width:200,
-                            autoCreate : {tag: "input", type: "text", size: "20"},
-                            listeners : {
-                                specialkey : function(e,ev) {
-                                    if (ev.keyCode == 13) {
-                                        this.form.dialog.el.mask("Logging in");
-                                        this.form.doAction('submit', {
-                                            url: this.form.dialog.url,
-                                            method: this.form.dialog.method
-                                        });
-                                    }
-                                }
-                            }  
-                        },
-                        {
-                            xtype : 'ComboBox',
-                            xns : Roo.form,
-                            fieldLabel: "Language",
-                            name : 'langdisp',
-                            store: {
-                                xtype : 'SimpleStore',
-                                fields: ['lang', 'ldisp'],
-                                data : [
-                                    [ 'en', 'English' ],
-                                    [ 'zh_HK' , '\u7E41\u4E2D' ],
-                                    [ 'zh_CN', '\u7C21\u4E2D' ]
-                                ]
-                            },
-                            
-                            valueField : 'lang',
-                            hiddenName:  'lang',
-                            width: 200,
-                            displayField:'ldisp',
-                            typeAhead: false,
-                            editable: false,
-                            mode: 'local',
-                            triggerAction: 'all',
-                            emptyText:'Select a Language...',
-                            selectOnFocus:true,
-                            listeners : {
-                                select :  function(cb, rec, ix) {
-                                    this.form.switchLang(rec.data.lang);
-                                }
-                            }
-                        
-                        }
-                    ]
-                }
-                  
-                
-            ]
-        }
-    ],
-    buttons : [
-        {
-            xtype : 'Button',
-            xns : 'Roo',
-            text : "Forgot Password",
-            listeners : {
-                click : function() {
-                    //console.log(this);
-                    var n = this.form.findField('username').getValue();
-                    if (!n.length) {
-                        Roo.MessageBox.alert("Error", "Fill in your email address");
-                        return;
-                    }
-                    Roo.Ajax.request({
-                        url: this.dialog.url,
-                        params: {
-                            passwordRequest: n
-                        },
-                        method: this.dialog.method,
-                        success:  function(response, opts)  {  // check successfull...
-                        
-                            var res = this.dialog.processResponse(response);
-                            if (!res.success) { // error!
-                               Roo.MessageBox.alert("Error" ,
-                                    res.errorMsg ? res.errorMsg  : "Problem Requesting Password Reset");
-                               return;
-                            }
-                            Roo.MessageBox.alert("Notice" ,
-                                "Please check you email for the Password Reset message");
-                        },
-                        failure : function() {
-                            Roo.MessageBox.alert("Error" , "Problem Requesting Password Reset");
-                        }
-                        
-                    });
-                }
-            }
-        },
-        {
-            xtype : 'Button',
-            xns : 'Roo',
-            text : "Login",
-            listeners : {
-                
-                click : function () {
-                        
-                    this.dialog.el.mask("Logging in");
-                    this.form.doAction('submit', {
-                            url: this.dialog.url,
-                            method: this.dialog.method
-                    });
-                }
-            }
-        }
-    ]
-  
-  
-})
-
-
-   
\ No newline at end of file
\ No newline at end of file