examples/resizable/basic.js
[roojs1] / roojs-ui-debug.js
index 1647c58..0b2d037 100644 (file)
@@ -9170,7 +9170,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);
@@ -9182,7 +9184,8 @@ Roo.View = function(config, depreciated_tpl, depreciated_config){
     
     this.tpl.compile();
    
-
+  
+    
      
     /** @private */
     this.addEvents({
@@ -9245,8 +9248,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,
@@ -9261,7 +9268,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, {
@@ -9317,8 +9342,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.
@@ -13633,7 +13660,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;
@@ -14885,15 +14914,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){
@@ -19848,6 +19882,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);
@@ -20485,6 +20523,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")
      */
@@ -21608,9 +21652,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;
     },
 
@@ -21620,9 +21662,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;
     },
 
@@ -21659,14 +21699,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;
                 }
             }
@@ -21815,17 +21855,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);
@@ -21834,12 +21875,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);
@@ -21879,38 +21918,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();
@@ -21927,11 +21951,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();
     },
 
@@ -21942,7 +21964,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;
@@ -22026,8 +22048,12 @@ Roo.extend(Roo.form.TextField, Roo.form.Field,  {
     },
     
     // private
-    SafariOnKeyDown : function(event){
+    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;
         }
@@ -22035,12 +22061,17 @@ Roo.extend(Roo.form.TextField, Roo.form.Field,  {
             event.preventDefault();
             this.setValue('');
             return;
-         };
+        }
+        
         if(isSelectAll){ // backspace and delete key
             
             event.preventDefault();
-            this.setValue(String.fromCharCode(event.getKey())); 
-        };
+            // this is very hacky as keydown always get's upper case.
+            //
+            var cc = String.fromCharCode(event.getCharCode());
+            this.setValue( event.shiftKey ?  cc : cc.toLowerCase());
+            
+        }
         
         
     }
@@ -22839,6 +22870,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.
@@ -24030,7 +24069,7 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
         this.value = '';
         this.setRawValue('');
         this.lastSelectionText = '';
-        this.applyEmptyText();
+        
     },
 
     /**
@@ -24266,7 +24305,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();
+             
         }
     },
 
@@ -24558,6 +24597,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..
@@ -24742,7 +24785,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];
                 
@@ -25117,7 +25160,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">
 
 /*
@@ -25283,7 +25358,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);
         }
          
@@ -25592,14 +25670,13 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     pushValue : function(){
         if(this.initialized){
             var v = this.el.dom.value;
-            Roo.log(v);
+            
             if(v.length < 1){
                 v = '&#160;';
             }
             
             if(this.fireEvent('beforepush', this, v) !== false){
                 var d = (this.doc.body || this.doc.documentElement);
-                Roo.log(d);
                 d.innerHTML = v;
                 this.cleanUpPaste();
                 this.el.dom.value = d.innerHTML;
@@ -25754,7 +25831,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);
         
     },
@@ -25763,7 +25851,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     {
         
         
-        range = this.createRange();
+        var range = this.createRange();
         range.deleteContents();
                //alert(Sender.getAttribute('label'));
                
@@ -26187,19 +26275,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;
-        Roo.log('inputt........');
-        Roo.log(input);
         
         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]);
         });
-        Roo.log('output........');
-        Roo.log(output);
+        
         return output;
     },
     
@@ -26220,7 +26305,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?
@@ -26277,7 +26361,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);
             
         }
@@ -26289,9 +26373,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) {
@@ -26300,12 +26387,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;
             });
@@ -26457,8 +26555,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 
 ];
 
 
@@ -26593,7 +26698,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.
@@ -26636,24 +26742,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({
@@ -26937,6 +27046,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();
@@ -27138,6 +27250,9 @@ Roo.form.HtmlEditor.ToolbarContext = function(config)
     // dont call parent... till later.
     this.styles = this.styles || {};
 }
+
+
 Roo.form.HtmlEditor.ToolbarContext.types = {
     'IMG' : {
         width : {
@@ -27224,6 +27339,13 @@ Roo.form.HtmlEditor.ToolbarContext.types = {
             title: "Colspan",
             width: 20
             
+        },
+         'font-family'  : {
+            title : "Font",
+            style : 'fontFamily',
+            displayField: 'display',
+            optname : 'font-family',
+            width: 140
         }
     },
     'INPUT' : {
@@ -27275,16 +27397,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,  {
@@ -27310,7 +27478,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
      */
     styles : false,
     
-    
+    options: false,
     
     toolbars : false,
     
@@ -27445,6 +27613,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));
                 });
             }
@@ -27574,7 +27746,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                 }),
                 name : '-roo-edit-className',
                 attrname : 'className',
-                displayField:'val',
+                displayField: 'val',
                 typeAhead: false,
                 mode: 'local',
                 editable : false,
@@ -27592,8 +27764,9 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
     
             }));
         }
-            
         
+        var tbc = Roo.form.HtmlEditor.ToolbarContext;
+        var tbops = tbc.options;
         
         for (var i in tlist) {
             
@@ -27601,21 +27774,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',
@@ -27623,6 +27803,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'));
                         }
                     }
@@ -27667,7 +27851,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];
@@ -27675,7 +27859,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);
                         
                     }
@@ -27695,7 +27879,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 = ''; 
                 }
             }
             
@@ -27758,7 +27942,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;
         }
@@ -28297,6 +28481,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..
@@ -30488,6 +30685,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()
@@ -30510,8 +30708,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;
         
 
     },
@@ -30531,6 +30731,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;
         }
         
     },
@@ -30556,68 +30757,421 @@ Roo.extend(Roo.form.ComboCheck, Roo.form.ComboBox, {
         this.value = v;
     }
     
-});//<script type="text/javasscript">
+});/*
+ * 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.DDView
- * A DnD enabled version of Roo.View.
- * @param {Element/String} container The Element in which to create the View.
- * @param {String} tpl The template string used to create the markup for each element of the View
- * @param {Object} config The configuration properties. These include all the config options of
- * {@link Roo.View} plus some specific to this class.<br>
- * <p>
- * Drag/drop is implemented by adding {@link Roo.data.Record}s to the target DDView. If copying is
- * not being performed, the original {@link Roo.data.Record} is removed from the source DDView.<br>
- * <p>
- * The following extra CSS rules are needed to provide insertion point highlighting:<pre><code>
-.x-view-drag-insert-above {
-       border-top:1px dotted #3366cc;
-}
-.x-view-drag-insert-below {
-       border-bottom:1px dotted #3366cc;
-}
-</code></pre>
+ * @class Roo.form.Signature
+ * @extends Roo.form.Field
+ * Signature field.  
+ * @constructor
  * 
+ * @param {Object} config Configuration options
  */
-Roo.DDView = function(container, tpl, config) {
-    Roo.DDView.superclass.constructor.apply(this, arguments);
-    this.getEl().setStyle("outline", "0px none");
-    this.getEl().unselectable();
-    if (this.dragGroup) {
-               this.setDraggable(this.dragGroup.split(","));
-    }
-    if (this.dropGroup) {
-               this.setDroppable(this.dropGroup.split(","));
-    }
-    if (this.deletable) {
-       this.setDeletable();
-    }
-    this.isDirtyFlag = false;
-       this.addEvents({
-               "drop" : true
-       });
-};
-
-Roo.extend(Roo.DDView, Roo.View, {
-/**    @cfg {String/Array} dragGroup The ddgroup name(s) for the View's DragZone. */
-/**    @cfg {String/Array} dropGroup The ddgroup name(s) for the View's DropZone. */
-/**    @cfg {Boolean} copy Causes drag operations to copy nodes rather than move. */
-/**    @cfg {Boolean} allowCopy Causes ctrl/drag operations to copy nodes rather than move. */
-
-       isFormField: true,
 
-       reset: Roo.emptyFn,
-       
-       clearInvalid: Roo.form.Field.prototype.clearInvalid,
+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
+    });
+};
 
-       validate: function() {
-               return true;
-       },
-       
-       destroy: function() {
-               this.purgeListeners();
+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">
+
+/**
+ * @class Roo.DDView
+ * A DnD enabled version of Roo.View.
+ * @param {Element/String} container The Element in which to create the View.
+ * @param {String} tpl The template string used to create the markup for each element of the View
+ * @param {Object} config The configuration properties. These include all the config options of
+ * {@link Roo.View} plus some specific to this class.<br>
+ * <p>
+ * Drag/drop is implemented by adding {@link Roo.data.Record}s to the target DDView. If copying is
+ * not being performed, the original {@link Roo.data.Record} is removed from the source DDView.<br>
+ * <p>
+ * The following extra CSS rules are needed to provide insertion point highlighting:<pre><code>
+.x-view-drag-insert-above {
+       border-top:1px dotted #3366cc;
+}
+.x-view-drag-insert-below {
+       border-bottom:1px dotted #3366cc;
+}
+</code></pre>
+ * 
+ */
+Roo.DDView = function(container, tpl, config) {
+    Roo.DDView.superclass.constructor.apply(this, arguments);
+    this.getEl().setStyle("outline", "0px none");
+    this.getEl().unselectable();
+    if (this.dragGroup) {
+               this.setDraggable(this.dragGroup.split(","));
+    }
+    if (this.dropGroup) {
+               this.setDroppable(this.dropGroup.split(","));
+    }
+    if (this.deletable) {
+       this.setDeletable();
+    }
+    this.isDirtyFlag = false;
+       this.addEvents({
+               "drop" : true
+       });
+};
+
+Roo.extend(Roo.DDView, Roo.View, {
+/**    @cfg {String/Array} dragGroup The ddgroup name(s) for the View's DragZone. */
+/**    @cfg {String/Array} dropGroup The ddgroup name(s) for the View's DropZone. */
+/**    @cfg {Boolean} copy Causes drag operations to copy nodes rather than move. */
+/**    @cfg {Boolean} allowCopy Causes ctrl/drag operations to copy nodes rather than move. */
+
+       isFormField: true,
+
+       reset: Roo.emptyFn,
+       
+       clearInvalid: Roo.form.Field.prototype.clearInvalid,
+
+       validate: function() {
+               return true;
+       },
+       
+       destroy: function() {
+               this.purgeListeners();
                this.getEl.removeAllListeners();
                this.getEl().remove();
                if (this.dragZone) {
@@ -31519,6 +32073,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 {
@@ -31584,7 +32139,9 @@ layout.addxtype({
                 }
                 break;
            
-               
+           
+           
+                
                 
                 
             default: 
@@ -33367,12 +33924,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({
@@ -33408,6 +33960,10 @@ Roo.ContentPanel = function(el, config, content){
         
         
     });
+    
+
+    
+    
     if(this.autoScroll){
         this.resizeEl.setStyle("overflow", "auto");
     } else {
@@ -33429,6 +33985,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);
 };
 
@@ -33700,13 +34263,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;
         }
@@ -38954,9 +39519,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
@@ -39679,26 +40258,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) ";
@@ -39706,10 +40295,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;
     },
     
@@ -39856,614 +40445,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