fix html editor
[roojs1] / roojs-debug.js
index 1a993fb..7560334 100644 (file)
@@ -68,7 +68,7 @@ Roo.apply = function(o, c, defaults){
             document.execCommand("BackgroundImageCache", false, true);
         }catch(e){}
     }
-
+    
     Roo.apply(Roo, {
         /**
          * True if the browser is in strict mode
@@ -2471,8 +2471,14 @@ Roo.lib.Event = function() {
  */
 
 (function() {
-    
+    /**
+     * @class Roo.lib.Ajax
+     *
+     */
     Roo.lib.Ajax = {
+        /**
+         * @static 
+         */
         request : function(method, uri, cb, data, options) {
             if(options){
                 var hs = options.headers;
@@ -8854,7 +8860,8 @@ if(opt.anim.isAnimated()){
          * @param {String} msgCls (optional) A css class to apply to the msg element
          * @return {Element} The mask  element
          */
-        mask : function(msg, msgCls){
+        mask : function(msg, msgCls)
+        {
             if(this.getStyle("position") == "static"){
                 this.setStyle("position", "relative");
             }
@@ -8863,6 +8870,18 @@ if(opt.anim.isAnimated()){
             }
             this.addClass("x-masked");
             this._mask.setDisplayed(true);
+            
+            // we wander
+            var z = 0;
+            var dom = this.dom
+            while (dom && dom.style) {
+                if (!isNaN(parseInt(dom.style.zIndex))) {
+                    z = Math.max(z, parseInt(dom.style.zIndex));
+                }
+                dom = dom.parentNode;
+            }
+            
+           
             if(typeof msg == 'string'){
                 if(!this._maskMsg){
                     this._maskMsg = Roo.DomHelper.append(this.dom, {cls:"roo-el-mask-msg", cn:{tag:'div'}}, true);
@@ -8872,10 +8891,13 @@ if(opt.anim.isAnimated()){
                 mm.dom.firstChild.innerHTML = msg;
                 mm.setDisplayed(true);
                 mm.center(this);
+                mm.setStyle('z-index', z + 102);
             }
             if(Roo.isIE && !(Roo.isIE7 && Roo.isStrict) && this.getStyle('height') == 'auto'){ // ie will not expand full height automatically
                 this._mask.setHeight(this.getHeight());
             }
+            this._mask.setStyle('z-index', z + 100);
+            
             return this._mask;
         },
 
@@ -11548,84 +11570,31 @@ Roo.Ajax = new Roo.data.Connection({
  */
  
 /**
+ * Global Ajax request class.
+ * 
  * @class Roo.Ajax
  * @extends Roo.data.Connection
- * Global Ajax request class.
- *
- * @instanceOf  Roo.data.Connection
+ * @static
+ * 
+ * @cfg {String} url  The default URL to be used for requests to the server. (defaults to undefined)
+ * @cfg {Object} extraParams  An object containing properties which are used as extra parameters to each request made by this object. (defaults to undefined)
+ * @cfg {Object} defaultHeaders  An object containing request headers which are added to each request made by this object. (defaults to undefined)
+ * @cfg {String} method (Optional)  The default HTTP method to be used for requests. (defaults to undefined; if not set but parms are present will use POST, otherwise GET)
+ * @cfg {Number} timeout (Optional) The timeout in milliseconds to be used for requests. (defaults to 30000)
+ * @cfg {Boolean} autoAbort (Optional) Whether a new request should abort any pending requests. (defaults to false)
+ * @cfg {Boolean} disableCaching (Optional)   True to add a unique cache-buster param to GET requests. (defaults to true)
  */
 Roo.Ajax = new Roo.data.Connection({
     // fix up the docs
-    
     /**
-     * fix up scoping
      * @scope Roo.Ajax
-     */
-    
-   /**
-     * @cfg {String} url @hide
-     */
-    /**
-     * @cfg {Object} extraParams @hide
-     */
-    /**
-     * @cfg {Object} defaultHeaders @hide
-     */
-    /**
-     * @cfg {String} method (Optional) @hide
-     */
-    /**
-     * @cfg {Number} timeout (Optional) @hide
-     */
-    /**
-     * @cfg {Boolean} autoAbort (Optional) @hide
-     */
-
-    /**
-     * @cfg {Boolean} disableCaching (Optional) @hide
-     */
-
-    /**
-     * @property  disableCaching
-     * True to add a unique cache-buster param to GET requests. (defaults to true)
-     * @type Boolean
-     */
-    /**
-     * @property  url
-     * The default URL to be used for requests to the server. (defaults to undefined)
-     * @type String
-     */
-    /**
-     * @property  extraParams
-     * An object containing properties which are used as
-     * extra parameters to each request made by this object. (defaults to undefined)
-     * @type Object
-     */
-    /**
-     * @property  defaultHeaders
-     * An object containing request headers which are added to each request made by this object. (defaults to undefined)
-     * @type Object
-     */
-    /**
-     * @property  method
-     * The default HTTP method to be used for requests. (defaults to undefined; if not set but parms are present will use POST, otherwise GET)
-     * @type String
-     */
-    /**
-     * @property  timeout
-     * The timeout in milliseconds to be used for requests. (defaults to 30000)
-     * @type Number
-     */
-
-    /**
-     * @property  autoAbort
-     * Whether a new request should abort any pending requests. (defaults to false)
-     * @type Boolean
+     * @type {Boolear} 
      */
     autoAbort : false,
 
     /**
      * Serialize the passed form into a url encoded string
+     * @scope Roo.Ajax
      * @param {String/HTMLElement} form
      * @return {String}
      */
@@ -19547,6 +19516,11 @@ Roo.extend(Roo.data.Store, Roo.util.Observable, {
         }
         // if data returned failure - throw an exception.
         if (o.success === false) {
+            // show a message if no listener is registered.
+            if (!this.hasListener('loadexception') && typeof(this.reader.jsonData.errorMsg) != 'undefined') {
+                    Roo.MessageBox.alert("Error loading",this.reader.jsonData.errorMsg);
+            }
+            // loadmask wil be hooked into this..
             this.fireEvent("loadexception", this, o, options, this.reader.jsonData);
             return;
         }
@@ -19577,6 +19551,7 @@ Roo.extend(Roo.data.Store, Roo.util.Observable, {
         }
     },
 
+
     /**
      * Loads data from a passed data block. A Reader which understands the format of the data
      * must have been configured in the constructor.
@@ -19819,7 +19794,7 @@ Roo.extend(Roo.data.Store, Roo.util.Observable, {
         }
         this.fireEvent("update", this, record, Roo.data.Record.EDIT);
     },
-
+    
     // private
     afterReject : function(record){
         this.modified.remove(record);
@@ -21876,20 +21851,23 @@ Roo.Component = function(config){
     }
 };
 
-// private
+/** @private */
 Roo.Component.AUTO_ID = 1000;
 
 Roo.extend(Roo.Component, Roo.util.Observable, {
     /**
-     * @property {Boolean} hidden
+     * @scope Roo.Component.prototype
+     * @type {Boolean}
      * true if this component is hidden. Read-only.
      */
     hidden : false,
     /**
+     * @type {Boolean}
      * true if this component is disabled. Read-only.
      */
     disabled : false,
     /**
+     * @type {Boolean}
      * true if this component has been rendered. Read-only.
      */
     rendered : false,
@@ -21909,16 +21887,17 @@ Roo.extend(Roo.Component, Roo.util.Observable, {
      */
     hideMode: 'display',
 
-    // private
+    /** @private */
     ctype : "Roo.Component",
 
-    /** @cfg {String} actionMode 
+    /**
+     * @cfg {String} actionMode 
      * which property holds the element that used for  hide() / show() / disable() / enable()
      * default is 'el' 
      */
     actionMode : "el",
 
-    // private
+    /** @private */
     getActionEl : function(){
         return this[this.actionMode];
     },
@@ -21965,7 +21944,7 @@ Roo.extend(Roo.Component, Roo.util.Observable, {
         return this;
     },
 
-    // private
+    /** @private */
     // default function is not really useful
     onRender : function(ct, position){
         if(this.el){
@@ -21976,7 +21955,7 @@ Roo.extend(Roo.Component, Roo.util.Observable, {
         }
     },
 
-    // private
+    /** @private */
     getAutoCreate : function(){
         var cfg = typeof this.autoCreate == "object" ?
                       this.autoCreate : Roo.apply({}, this.defaultAutoCreate);
@@ -21986,7 +21965,7 @@ Roo.extend(Roo.Component, Roo.util.Observable, {
         return cfg;
     },
 
-    // private
+    /** @private */
     afterRender : Roo.emptyFn,
 
     /**
@@ -22010,12 +21989,12 @@ Roo.extend(Roo.Component, Roo.util.Observable, {
         }
     },
 
-       // private
+       /** @private */
     beforeDestroy : function(){
 
     },
 
-       // private
+       /** @private */
        onDestroy : function(){
 
     },
@@ -22051,7 +22030,7 @@ Roo.extend(Roo.Component, Roo.util.Observable, {
         return this;
     },
 
-    // private
+    /** @private */
     blur : function(){
         if(this.rendered){
             this.el.blur();
@@ -23747,13 +23726,17 @@ Roo.extend(Roo.View, Roo.util.Observable, {
     /**
      * @cfg {Boolean} multiSelect Allow multiple selection
      */
-    
     multiSelect : false,
     /**
      * @cfg {Boolean} singleSelect Allow single selection
      */
     singleSelect:  false,
     
+    /**
+     * @cfg {Boolean} toggleSelect - selecting 
+     */
+    toggleSelect : false,
+    
     /**
      * Returns the element this view is bound to.
      * @return {Roo.Element}
@@ -23920,10 +23903,18 @@ Roo.extend(Roo.View, Roo.util.Observable, {
         }
     },
 
-    onItemClick : function(item, index, e){
+    onItemClick : function(item, index, e)
+    {
         if(this.fireEvent("beforeclick", this, index, item, e) === false){
             return false;
         }
+        if (this.toggleSelect) {
+            var m = this.isSelected(item) ? 'unselect' : 'select';
+            Roo.log(m);
+            var _t = this;
+            _t[m](item, true, false);
+            return true;
+        }
         if(this.multiSelect || this.singleSelect){
             if(this.multiSelect && e.shiftKey && this.lastSelection){
                 this.select(this.getNodes(this.indexOf(this.lastSelection), index), false);
@@ -24007,21 +23998,57 @@ Roo.extend(Roo.View, Roo.util.Observable, {
             for(var i = 0, len = nodeInfo.length; i < len; i++){
                 this.select(nodeInfo[i], true, true);
             }
-        } else{
-            var node = this.getNode(nodeInfo);
-            if(node && !this.isSelected(node)){
-                if(!keepExisting){
-                    this.clearSelections(true);
-                }
-                if(this.fireEvent("beforeselect", this, node, this.selections) !== false){
-                    Roo.fly(node).addClass(this.selectedClass);
-                    this.selections.push(node);
-                    if(!suppressEvent){
-                        this.fireEvent("selectionchange", this, this.selections);
-                    }
-                }
+            return;
+        } 
+        var node = this.getNode(nodeInfo);
+        if(!node || this.isSelected(node)){
+            return; // already selected.
+        }
+        if(!keepExisting){
+            this.clearSelections(true);
+        }
+        if(this.fireEvent("beforeselect", this, node, this.selections) !== false){
+            Roo.fly(node).addClass(this.selectedClass);
+            this.selections.push(node);
+            if(!suppressEvent){
+                this.fireEvent("selectionchange", this, this.selections);
             }
         }
+        
+        
+    },
+      /**
+     * Unselects nodes.
+     * @param {Array/HTMLElement/String/Number} nodeInfo An HTMLElement template node, index of a template node, id of a template node or an array of any of those to select
+     * @param {Boolean} keepExisting (optional) true IGNORED (for campatibility with select)
+     * @param {Boolean} suppressEvent (optional) true to skip firing of the selectionchange vent
+     */
+    unselect : function(nodeInfo, keepExisting, suppressEvent)
+    {
+        if(nodeInfo instanceof Array){
+            Roo.each(this.selections, function(s) {
+                this.unselect(s, nodeInfo);
+            }, this);
+            return;
+        }
+        var node = this.getNode(nodeInfo);
+        if(!node || !this.isSelected(node)){
+            Roo.log("not selected");
+            return; // not selected.
+        }
+        // fireevent???
+        var ns = [];
+        Roo.each(this.selections, function(s) {
+            if (s == node ) {
+                Roo.fly(node).removeClass(this.selectedClass);
+
+                return;
+            }
+            ns.push(s);
+        },this);
+        
+        this.selections= ns;
+        this.fireEvent("selectionchange", this, this.selections);
     },
 
     /**
@@ -24571,7 +24598,14 @@ Roo.DatePicker = function(config){
             * @param {DatePicker} this
             * @param {Date} date The selected date
             */
-        select: true
+        'select': true,
+        /**
+            * @event monthchange
+            * Fires when the displayed month changes 
+            * @param {DatePicker} this
+            * @param {Date} date The selected month
+            */
+        'monthchange': true
     });
 
     if(this.handler){
@@ -25052,7 +25086,8 @@ Roo.extend(Roo.DatePicker, Roo.Component, {
     },
 
     // private
-    update : function(date){
+    update : function(date)
+    {
         var vd = this.activeDate;
         this.activeDate = date;
         if(vd && this.el){
@@ -25071,6 +25106,7 @@ Roo.extend(Roo.DatePicker, Roo.Component, {
                 return;
             }
         }
+        
         var days = date.getDaysInMonth();
         var firstOfMonth = date.getFirstDateOfMonth();
         var startingPos = firstOfMonth.getDay()-this.startDay;
@@ -25162,7 +25198,8 @@ Roo.extend(Roo.DatePicker, Roo.Component, {
         }
 
         this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());
-
+        this.fireEvent('monthchange', this, date);
+        
         if(!this.internalRender){
             var main = this.el.dom.firstChild;
             var w = main.offsetWidth;
@@ -25178,6 +25215,8 @@ Roo.extend(Roo.DatePicker, Roo.Component, {
                 this.update.defer(10, this, [date]);
             }
         }
+        
+        
     }
 });        /*
  * Based on:
@@ -26727,7 +26766,7 @@ Roo.MenuButton = Roo.SplitButton;/*
  * Basic Toolbar class.
  * @constructor
  * Creates a new Toolbar
- * @param {Object} config The config object
+ * @param {Object} container The config object
  */ 
 Roo.Toolbar = function(container, buttons, config)
 {
@@ -26740,7 +26779,7 @@ Roo.Toolbar = function(container, buttons, config)
     if (typeof(container) == 'object' && container.xtype) {
         config = container;
         container = config.container;
-        buttons = config.buttons; // not really - use items!!
+        buttons = config.buttons || []; // not really - use items!!
     }
     var xitems = [];
     if (config && config.items) {
@@ -26753,6 +26792,7 @@ Roo.Toolbar = function(container, buttons, config)
     if(container){
         this.render(container);
     }
+    this.xitems = xitems;
     Roo.each(xitems, function(b) {
         this.add(b);
     }, this);
@@ -26761,8 +26801,8 @@ Roo.Toolbar = function(container, buttons, config)
 
 Roo.Toolbar.prototype = {
     /**
-     * @cfg {Roo.data.Store} items
-     * array of button configs or elements to add
+     * @cfg {Array} items
+     * array of button configs or elements to add (will be converted to a MixedCollection)
      */
     
     /**
@@ -26996,8 +27036,9 @@ Roo.Toolbar.prototype = {
     fields : false,
     
     /**
-     * Adds a dynamically rendered Roo.form field (TextField, ComboBox, etc). Note: the field should not have
-     * been rendered yet. For a field that has already been rendered, use {@link #addElement}.
+     * Adds a dynamically rendered Roo.form field (TextField, ComboBox, etc).
+     * Note: the field should not have been rendered yet. For a field that has already been
+     * rendered, use {@link #addElement}.
      * @param {Roo.form.Field} field
      * @return {Roo.ToolbarItem}
      */
@@ -30068,6 +30109,15 @@ Roo.MessageBox = function(){
             if(dlg.isVisible()){
                 dlg.fixedcenter = false;
             }
+            // to big, make it scoll.
+            if ( bodyEl.getHeight() > (Roo.lib.Dom.getViewHeight() - 100)) {
+                bodyEl.setHeight ( Roo.lib.Dom.getViewHeight() - 100 );
+                bodyEl.dom.style.overflowY = 'auto';
+            } else {
+                bodyEl.dom.style.height = '';
+                bodyEl.dom.style.overflowY = '';
+            }
+            
             dlg.setContentSize(w, bodyEl.getHeight());
             if(dlg.isVisible()){
                 dlg.fixedcenter = true;
@@ -30166,9 +30216,19 @@ Roo.Msg.show({
          * @param {Object} config Configuration options
          * @return {Roo.MessageBox} This message box
          */
-        show : function(options){
+        show : function(options)
+        {
+            
+            // this causes nightmares if you show one dialog after another
+            // especially on callbacks..
+             
             if(this.isVisible()){
+                
                 this.hide();
+                Roo.log("Old Dialog Message:" +  msgEl.innerHTML )
+                //this.alert("ERROR", "Multiple dialogs where displayed at the same time");
+                //throw "Roo.MessageBox ERROR : Multiple dialogs where displayed at the same time";
+                
             }
             var d = this.getDialog();
             opt = options;
@@ -30838,9 +30898,10 @@ Roo.QuickTips.tips = Roo.QuickTips.register;/*
  * @cfg {Boolean} singleExpand true if only 1 node per branch may be expanded
  * @cfg {Boolean} selModel A tree selection model to use with this TreePanel (defaults to a {@link Roo.tree.DefaultSelectionModel})
  * @cfg {Boolean} loader A TreeLoader for use with this TreePanel
+ * @cfg {Object|Roo.tree.TreeEditor} editor The TreeEditor or xtype data to display when clicked.
  * @cfg {String} pathSeparator The token used to separate sub-paths in path strings (defaults to '/')
- * @cfg {Function} renderer Sets the rendering (formatting) function for the nodes. to return HTML markup for the tree view. The render function is called with  the following parameters:<ul><li>The {Object} The data for the node.</li></ul>
- * @cfg {Function} rendererTip Sets the rendering (formatting) function for the nodes hovertip to return HTML markup for the tree view. The render function is called with  the following parameters:<ul><li>The {Object} The data for the node.</li></ul>
+ * @cfg {Function} renderer DEPRECATED - use TreeLoader:create event / Sets the rendering (formatting) function for the nodes. to return HTML markup for the tree view. The render function is called with  the following parameters:<ul><li>The {Object} The data for the node.</li></ul>
+ * @cfg {Function} rendererTip DEPRECATED - use TreeLoader:create event / Sets the rendering (formatting) function for the nodes hovertip to return HTML markup for the tree view. The render function is called with  the following parameters:<ul><li>The {Object} The data for the node.</li></ul>
  * 
  * @constructor
  * @param {String/HTMLElement/Element} el The container element
@@ -30872,8 +30933,8 @@ Roo.tree.TreePanel = function(el, config){
    /**
     * Read-only. The id of the container element becomes this TreePanel's id.
     */
-   this.id = this.el.id;
-   this.addEvents({
+    this.id = this.el.id;
+    this.addEvents({
         /**
         * @event beforeload
         * Fires before a node is loaded, return false to cancel
@@ -30970,87 +31031,96 @@ Roo.tree.TreePanel = function(el, config){
         * @param {Node} node The node
         */
         "beforechildrenrendered":true,
+        /**
+        * @event startdrag
+        * Fires when a node starts being dragged
+        * @param {Roo.tree.TreePanel} this
+        * @param {Roo.tree.TreeNode} node
+        * @param {event} e The raw browser event
+        */ 
+       "startdrag" : true,
        /**
-            * @event startdrag
-            * Fires when a node starts being dragged
-            * @param {Roo.tree.TreePanel} this
-            * @param {Roo.tree.TreeNode} node
-            * @param {event} e The raw browser event
-            */ 
-           "startdrag" : true,
-           /**
-            * @event enddrag
-            * Fires when a drag operation is complete
-            * @param {Roo.tree.TreePanel} this
-            * @param {Roo.tree.TreeNode} node
-            * @param {event} e The raw browser event
-            */
-           "enddrag" : true,
-           /**
-            * @event dragdrop
-            * Fires when a dragged node is dropped on a valid DD target
-            * @param {Roo.tree.TreePanel} this
-            * @param {Roo.tree.TreeNode} node
-            * @param {DD} dd The dd it was dropped on
-            * @param {event} e The raw browser event
-            */
-           "dragdrop" : true,
-           /**
-            * @event beforenodedrop
-            * Fires when a DD object is dropped on a node in this tree for preprocessing. Return false to cancel the drop. The dropEvent
-            * passed to handlers has the following properties:<br />
-            * <ul style="padding:5px;padding-left:16px;">
-            * <li>tree - The TreePanel</li>
-            * <li>target - The node being targeted for the drop</li>
-            * <li>data - The drag data from the drag source</li>
-            * <li>point - The point of the drop - append, above or below</li>
-            * <li>source - The drag source</li>
-            * <li>rawEvent - Raw mouse event</li>
-            * <li>dropNode - Drop node(s) provided by the source <b>OR</b> you can supply node(s)
-            * to be inserted by setting them on this object.</li>
-            * <li>cancel - Set this to true to cancel the drop.</li>
-            * </ul>
-            * @param {Object} dropEvent
-            */
-           "beforenodedrop" : true,
-           /**
-            * @event nodedrop
-            * Fires after a DD object is dropped on a node in this tree. The dropEvent
-            * passed to handlers has the following properties:<br />
-            * <ul style="padding:5px;padding-left:16px;">
-            * <li>tree - The TreePanel</li>
-            * <li>target - The node being targeted for the drop</li>
-            * <li>data - The drag data from the drag source</li>
-            * <li>point - The point of the drop - append, above or below</li>
-            * <li>source - The drag source</li>
-            * <li>rawEvent - Raw mouse event</li>
-            * <li>dropNode - Dropped node(s).</li>
-            * </ul>
-            * @param {Object} dropEvent
-            */
-           "nodedrop" : true,
-            /**
-            * @event nodedragover
-            * Fires when a tree node is being targeted for a drag drop, return false to signal drop not allowed. The dragOverEvent
-            * passed to handlers has the following properties:<br />
-            * <ul style="padding:5px;padding-left:16px;">
-            * <li>tree - The TreePanel</li>
-            * <li>target - The node being targeted for the drop</li>
-            * <li>data - The drag data from the drag source</li>
-            * <li>point - The point of the drop - append, above or below</li>
-            * <li>source - The drag source</li>
-            * <li>rawEvent - Raw mouse event</li>
-            * <li>dropNode - Drop node(s) provided by the source.</li>
-            * <li>cancel - Set this to true to signal drop not allowed.</li>
-            * </ul>
-            * @param {Object} dragOverEvent
-            */
-           "nodedragover" : true
+        * @event enddrag
+        * Fires when a drag operation is complete
+        * @param {Roo.tree.TreePanel} this
+        * @param {Roo.tree.TreeNode} node
+        * @param {event} e The raw browser event
+        */
+       "enddrag" : true,
+       /**
+        * @event dragdrop
+        * Fires when a dragged node is dropped on a valid DD target
+        * @param {Roo.tree.TreePanel} this
+        * @param {Roo.tree.TreeNode} node
+        * @param {DD} dd The dd it was dropped on
+        * @param {event} e The raw browser event
+        */
+       "dragdrop" : true,
+       /**
+        * @event beforenodedrop
+        * Fires when a DD object is dropped on a node in this tree for preprocessing. Return false to cancel the drop. The dropEvent
+        * passed to handlers has the following properties:<br />
+        * <ul style="padding:5px;padding-left:16px;">
+        * <li>tree - The TreePanel</li>
+        * <li>target - The node being targeted for the drop</li>
+        * <li>data - The drag data from the drag source</li>
+        * <li>point - The point of the drop - append, above or below</li>
+        * <li>source - The drag source</li>
+        * <li>rawEvent - Raw mouse event</li>
+        * <li>dropNode - Drop node(s) provided by the source <b>OR</b> you can supply node(s)
+        * to be inserted by setting them on this object.</li>
+        * <li>cancel - Set this to true to cancel the drop.</li>
+        * </ul>
+        * @param {Object} dropEvent
+        */
+       "beforenodedrop" : true,
+       /**
+        * @event nodedrop
+        * Fires after a DD object is dropped on a node in this tree. The dropEvent
+        * passed to handlers has the following properties:<br />
+        * <ul style="padding:5px;padding-left:16px;">
+        * <li>tree - The TreePanel</li>
+        * <li>target - The node being targeted for the drop</li>
+        * <li>data - The drag data from the drag source</li>
+        * <li>point - The point of the drop - append, above or below</li>
+        * <li>source - The drag source</li>
+        * <li>rawEvent - Raw mouse event</li>
+        * <li>dropNode - Dropped node(s).</li>
+        * </ul>
+        * @param {Object} dropEvent
+        */
+       "nodedrop" : true,
+        /**
+        * @event nodedragover
+        * Fires when a tree node is being targeted for a drag drop, return false to signal drop not allowed. The dragOverEvent
+        * passed to handlers has the following properties:<br />
+        * <ul style="padding:5px;padding-left:16px;">
+        * <li>tree - The TreePanel</li>
+        * <li>target - The node being targeted for the drop</li>
+        * <li>data - The drag data from the drag source</li>
+        * <li>point - The point of the drop - append, above or below</li>
+        * <li>source - The drag source</li>
+        * <li>rawEvent - Raw mouse event</li>
+        * <li>dropNode - Drop node(s) provided by the source.</li>
+        * <li>cancel - Set this to true to signal drop not allowed.</li>
+        * </ul>
+        * @param {Object} dragOverEvent
+        */
+       "nodedragover" : true
         
-   });
-   if(this.singleExpand){
+    });
+    if(this.singleExpand){
        this.on("beforeexpand", this.restrictExpand, this);
-   }
+    }
+    if (this.editor) {
+        this.editor.tree = this;
+        this.editor = Roo.factory(this.editor, Roo.tree);
+    }
+    
+    if (this.selModel) {
+        this.selModel = Roo.factory(this.selModel, Roo.tree);
+    }
+   
 };
 Roo.extend(Roo.tree.TreePanel, Roo.data.Tree, {
     rootVisible : true,
@@ -31279,10 +31349,13 @@ Roo.extend(Roo.tree.TreePanel, Roo.data.Tree, {
  * @class Roo.tree.DefaultSelectionModel
  * @extends Roo.util.Observable
  * The default single selection for a TreePanel.
+ * @param {Object} cfg Configuration
  */
-Roo.tree.DefaultSelectionModel = function(){
+Roo.tree.DefaultSelectionModel = function(cfg){
    this.selNode = null;
    
+   
+   
    this.addEvents({
        /**
         * @event selectionchange
@@ -31301,6 +31374,8 @@ Roo.tree.DefaultSelectionModel = function(){
         */
        "beforeselect" : true
    });
+   
+    Roo.tree.DefaultSelectionModel.superclass.constructor.call(this,cfg);
 };
 
 Roo.extend(Roo.tree.DefaultSelectionModel, Roo.util.Observable, {
@@ -31471,6 +31546,7 @@ Roo.extend(Roo.tree.DefaultSelectionModel, Roo.util.Observable, {
  * @class Roo.tree.MultiSelectionModel
  * @extends Roo.util.Observable
  * Multi selection for a TreePanel.
+ * @param {Object} cfg Configuration
  */
 Roo.tree.MultiSelectionModel = function(){
    this.selNodes = [];
@@ -31484,6 +31560,8 @@ Roo.tree.MultiSelectionModel = function(){
         */
        "selectionchange" : true
    });
+   Roo.tree.MultiSelectionModel.superclass.constructor.call(this,cfg);
+   
 };
 
 Roo.extend(Roo.tree.MultiSelectionModel, Roo.util.Observable, {
@@ -32563,11 +32641,15 @@ Roo.tree.TreeNodeUI.prototype = {
         }
     },
 
-    renderElements : function(n, a, targetNode, bulkRender){
+    renderElements : function(n, a, targetNode, bulkRender)
+    {
         // add some indent caching, this helps performance when rendering a large tree
         this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
         var t = n.getOwnerTree();
         var txt = t.renderer ? t.renderer(n.attributes) : Roo.util.Format.htmlEncode(n.text);
+        if (typeof(n.attributes.html) != 'undefined') {
+            txt = n.attributes.html;
+        }
         var tip = t.rendererTip ? t.rendererTip(n.attributes) : txt;
         var cb = typeof a.checked == 'boolean';
         var href = a.href ? a.href : Roo.isGecko ? "" : "#";
@@ -32644,7 +32726,10 @@ Roo.tree.TreeNodeUI.prototype = {
                     this.c1 = c1; this.c2 = c2;
                 }
             }else{
-                if(!this.wasLeaf){
+                // this changes non-leafs into leafs if they have no children.
+                // it's not very rational behaviour..
+                
+                if(!this.wasLeaf && this.node.leaf){
                     Roo.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");
                     delete this.c1;
                     delete this.c2;
@@ -32809,7 +32894,7 @@ Roo.extend(Roo.tree.TreeLoader, Roo.util.Observable, {
     /**
     * @cfg {Object} uiProviders (optional) An object containing properties which
     * 
-    * DEPRECIATED - use 'create' event handler to modify attributes - which affect creation.
+    * DEPRECATED - use 'create' event handler to modify attributes - which affect creation.
     * specify custom {@link Roo.tree.TreeNodeUI} implementations. If the optional
     * <i>uiProvider</i> attribute of a returned child node is a string rather
     * than a reference to a TreeNodeUI implementation, this that string value
@@ -32909,7 +32994,8 @@ Roo.extend(Roo.tree.TreeLoader, Roo.util.Observable, {
     },
 
     // private
-    createNode : function(attr){
+    createNode : function(attr)
+    {
         // apply baseAttrs, nice idea Corey!
         if(this.baseAttrs){
             Roo.applyIf(attr, this.baseAttrs);
@@ -32935,11 +33021,21 @@ Roo.extend(Roo.tree.TreeLoader, Roo.util.Observable, {
                         new Roo.tree.AsyncTreeNode(attr));
     },
 
-    processResponse : function(response, node, callback){
+    processResponse : function(response, node, callback)
+    {
         var json = response.responseText;
         try {
             
-            var o = /**  eval:var:zzzzzzzzzz */ eval("("+json+")");
+            var o = Roo.decode(json);
+            
+            if (!o.success) {
+                // it's a failure condition.
+                var a = response.argument;
+                this.fireEvent("loadexception", this, a.node, response);
+                Roo.log("Load failed - should have a handler really");
+                return;
+            }
+            
             if (this.root !== false) {
                 o = o[this.root];
             }
@@ -32965,7 +33061,9 @@ Roo.extend(Roo.tree.TreeLoader, Roo.util.Observable, {
         this.fireEvent("load", this, a.node, response);
     },
 
-    handleFailure : function(response){
+    handleFailure : function(response)
+    {
+        // should handle failure better..
         this.transId = false;
         var a = response.argument;
         this.fireEvent("loadexception", this, a.node, response);
@@ -33484,13 +33582,42 @@ Roo.extend(Roo.tree.TreeDragZone, Roo.dd.DragZone, {
  * Provides editor functionality for inline tree node editing.  Any valid {@link Roo.form.Field} can be used
  * as the editor field.
  * @constructor
- * @param {TreePanel} tree
- * @param {Object} config Either a prebuilt {@link Roo.form.Field} instance or a Field config object
+ * @param {Object} config (used to be the tree panel.)
+ * @param {Object} oldconfig DEPRECIATED Either a prebuilt {@link Roo.form.Field} instance or a Field config object
+ * 
+ * @cfg {Roo.tree.TreePanel} tree The tree to bind to.
+ * @cfg {Roo.form.TextField|Object} field The field configuration
+ *
+ * 
  */
-Roo.tree.TreeEditor = function(tree, config){
+Roo.tree.TreeEditor = function(config, oldconfig) { // was -- (tree, config){
+    var tree = config;
+    var field;
+    if (oldconfig) { // old style..
+        field = oldconfig.events ? oldconfig : new Roo.form.TextField(oldconfig);
+    } else {
+        // new style..
+        tree = config.tree;
+        config.field = config.field  || {};
+        config.field.xtype = 'TextField';
+        field = Roo.factory(config.field, Roo.form);
+    }
     config = config || {};
-    var field = config.events ? config : new Roo.form.TextField(config);
-    Roo.tree.TreeEditor.superclass.constructor.call(this, field);
+    
+    
+    this.addEvents({
+        /**
+         * @event beforenodeedit
+         * Fires when editing is initiated, but before the value changes.  Editing can be canceled by returning
+         * false from the handler of this event.
+         * @param {Editor} this
+         * @param {Roo.tree.Node} node 
+         */
+        "beforenodeedit" : true
+    });
+    
+    //Roo.log(config);
+    Roo.tree.TreeEditor.superclass.constructor.call(this, field, config);
 
     this.tree = tree;
 
@@ -33547,6 +33674,9 @@ Roo.extend(Roo.tree.TreeEditor, Roo.Editor, {
                 this.maxWidth,
                 (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - /*cushion*/5);
         this.setSize(w, '');
+        
+        return this.fireEvent('beforenodeedit', this, this.editNode);
+        
     },
 
     // private
@@ -33570,6 +33700,7 @@ Roo.extend(Roo.tree.TreeEditor, Roo.Editor, {
             this.triggerEdit(node);
             return false;
         }
+        return true;
     },
 
     // private
@@ -35802,7 +35933,7 @@ side          Add an error icon to the right of the field with a popup on hover
         this.value = v;
         if(this.rendered){
             this.el.dom.value = (v === null || v === undefined ? '' : v);
-            this.validate();
+             this.validate();
         }
     },
 
@@ -37263,6 +37394,8 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
      * in order for a value to be mapped.
      */
     valueField: undefined,
+    
+    
     /**
      * @cfg {String} hiddenName If specified, a hidden form field with this name is dynamically generated to store the
      * field's data value (defaults to the underlying DOM element's name)
@@ -37393,7 +37526,8 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
     addicon : false,
     editicon: false,
     
-    
+    // element that contains real text value.. (when hidden is used..)
+     
     // private
     onRender : function(ct, position){
         Roo.form.ComboBox.superclass.onRender.call(this, ct, position);
@@ -37406,6 +37540,8 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
 
             // prevent input submission
             this.el.dom.removeAttribute('name');
+             
+             
         }
         if(Roo.isGecko){
             this.el.dom.setAttribute('autocomplete', 'off');
@@ -37474,7 +37610,7 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
 
         this.store.on('beforeload', this.onBeforeLoad, this);
         this.store.on('load', this.onLoad, this);
-        this.store.on('loadexception', this.collapse, this);
+        this.store.on('loadexception', this.onLoadException, this);
 
         if(this.resizable){
             this.resizer = new Roo.Resizable(this.list,  {
@@ -37552,6 +37688,7 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
 
             "tab" : function(e){
                 this.onViewClick(false);
+                this.fireEvent("specialkey", this, e);
                 return true;
             },
 
@@ -37593,7 +37730,7 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
         if(this.store){
             this.store.un('beforeload', this.onBeforeLoad, this);
             this.store.un('load', this.onLoad, this);
-            this.store.un('loadexception', this.collapse, this);
+            this.store.un('loadexception', this.onLoadException, this);
         }
         Roo.form.ComboBox.superclass.onDestroy.call(this);
     },
@@ -37690,7 +37827,17 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
         }
         //this.el.focus();
     },
-
+    // private
+    onLoadException : function()
+    {
+        this.collapse();
+        Roo.log(this.store.reader.jsonData);
+        if (this.store && typeof(this.store.reader.jsonData.errorMsg) != 'undefined') {
+            Roo.MessageBox.alert("Error loading",this.store.reader.jsonData.errorMsg);
+        }
+        
+        
+    },
     // private
     onTypeAhead : function(){
         if(this.store.getCount() > 0){
@@ -37818,11 +37965,19 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
                     record = r;
                     return false;
                 }
+                return true;
             });
         }
         return record;
     },
-
+    
+    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 || '');
+        
+    },
     // private
     onViewMove : function(e, t){
         this.inKeyMode = false;
@@ -37841,7 +37996,8 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
     },
 
     // private
-    onViewClick : function(doFocus){
+    onViewClick : function(doFocus)
+    {
         var index = this.view.getSelectedIndexes()[0];
         var r = this.store.getAt(index);
         if(r){
@@ -38454,6 +38610,13 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
      * @cfg {Number} width (in pixels)
      */   
     width: 500,
+    
+    /**
+     * @cfg {Array} stylesheets url of stylesheets. set to [] to disable stylesheets.
+     * 
+     */
+    stylesheets: false,
+    
     // id of frame..
     frameId: false,
     
@@ -38565,7 +38728,35 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
      * want to change the initialization markup of the iframe (e.g. to add stylesheets).
      */
     getDocMarkup : function(){
-        return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
+        // body styles..
+        var st = '';
+        if (this.stylesheets === false) {
+            
+            Roo.get(document.head).select('style').each(function(node) {
+                st += node.dom.outerHTML || new XMLSerializer().serializeToString(node.dom);
+            });
+            
+            Roo.get(document.head).select('link').each(function(node) { 
+                st += node.dom.outerHTML || new XMLSerializer().serializeToString(node.dom);
+            });
+            
+        } else if (!this.stylesheets.length) {
+                // simple..
+                st = '<style type="text/css">' +
+                    'body{border:0;margin:0;padding:3px;height:98%;cursor:text;}' +
+                   '</style>';
+        } else {
+            Roo.each(this.stylesheets, function(s) {
+                st += '<link rel="stylesheet" type="text/css" href="' + s +'" />'
+            });
+            
+        }
+        
+        return '<html><head>' + st  +
+            //<style type="text/css">' +
+            //'body{border:0;margin:0;padding:3px;height:98%;cursor:text;}' +
+            //'</style>' +
+            ' </head><body></body></html>';
     },
 
     // private
@@ -38602,10 +38793,8 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         }
 
         this.frameId = Roo.id();
-        this.createToolbar(this);
-        
-        
         
+        this.createToolbar(this);
         
       
         
@@ -38615,7 +38804,8 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
             name: this.frameId,
             frameBorder : 'no',
             'src' : Roo.SSL_SECURE_URL ? Roo.SSL_SECURE_URL  :  "javascript:false"
-        });
+        }, this.el
+        );
         
        // console.log(iframe);
         //this.wrap.dom.appendChild(iframe);
@@ -38676,13 +38866,16 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 for (var i =0; i < this.toolbars.length;i++) {
                     // fixme - ask toolbars for heights?
                     tbh += this.toolbars[i].tb.el.getHeight();
+                    if (this.toolbars[i].footer) {
+                        tbh += this.toolbars[i].footer.el.getHeight();
+                    }
                 }
                 
                 
                 
                 
                 var ah = h - this.wrap.getFrameWidth('tb') - tbh;// this.tb.el.getHeight();
-                ah -= 10; // knock a few pixes off for look..
+                ah -= 5; // knock a few pixes off for look..
                 this.el.setHeight(this.adjustWidth('textarea', ah));
                 this.iframe.style.height = ah + 'px';
                 if(this.doc){
@@ -38787,7 +38980,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     syncValue : function(){
         if(this.initialized){
             var bd = (this.doc.body || this.doc.documentElement);
-            this.cleanUpPaste();
+            //this.cleanUpPaste();
             var html = bd.innerHTML;
             if(Roo.isSafari){
                 var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!
@@ -38876,7 +39069,8 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         dbody.bgProperties = 'fixed'; // ie
         Roo.DomHelper.applyStyles(dbody, ss);
         Roo.EventManager.on(this.doc, {
-            'mousedown': this.onEditorEvent,
+            //'mousedown': this.onEditorEvent,
+            'mouseup': this.onEditorEvent,
             'dblclick': this.onEditorEvent,
             'click': this.onEditorEvent,
             'keyup': this.onEditorEvent,
@@ -38964,7 +39158,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     onEditorEvent : function(e){
         this.fireEvent('editorevent', this, e);
       //  this.updateToolbar();
-        this.syncValue();
+        this.syncValue(); //we can not sync so often.. sync cleans, so this breaks stuff
     },
 
     insertTag : function(tg)
@@ -39058,6 +39252,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                     break;
                     case 'u':
                         cmd = 'underline';
+                        break;
                     case 'v':
                         this.cleanUpPaste.defer(100, this);
                         return;
@@ -39179,7 +39374,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         
         
          
-        var range = this.createRange(this.getSelection());
+        var range = this.createRange(this.getSelection()).cloneRange();
         
         if (Roo.isIE) {
             var parent = range.parentElement();
@@ -39197,12 +39392,14 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
             return parent;
         }
         
-        
-        var ar = range.endContainer.childNodes;
-        if (!ar.length) {
-            ar = range.commonAncestorContainer.childNodes;
-            //alert(ar.length);
+        // is ancestor a text element.
+        var ac =  range.commonAncestorContainer;
+        if (ac.nodeType == 3) {
+            ac = ac.parentNode;
         }
+        
+        var ar = ac.childNodes;
+         
         var nodes = [];
         var other_nodes = [];
         var has_other_nodes = false;
@@ -39222,6 +39419,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 other_nodes.push(ar[i]);
                 continue;
             }
+            // outer..
             if (!this.rangeIntersectsNode(range,ar[i])|| (this.rangeCompareNode(range,ar[i]) == 0))  {
                 continue;
             }
@@ -39272,40 +39470,84 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         }
     
     },
+    /***
+     *
+     * Range intersection.. the hard stuff...
+     *  '-1' = before
+     *  '0' = hits..
+     *  '1' = after.
+     *         [ -- selected range --- ]
+     *   [fail]                        [fail]
+     *
+     *    basically..
+     *      if end is before start or  hits it. fail.
+     *      if start is after end or hits it fail.
+     *
+     *   if either hits (but other is outside. - then it's not 
+     *   
+     *    
+     **/
     
     
-    
-    // BC Hacks - cause I cant work out what i was trying to do..
+    // @see http://www.thismuchiknow.co.uk/?p=64.
     rangeIntersectsNode : function(range, node)
     {
         var nodeRange = node.ownerDocument.createRange();
         try {
             nodeRange.selectNode(node);
-        }
-        catch (e) {
+        } catch (e) {
             nodeRange.selectNodeContents(node);
         }
-
-        return range.compareBoundaryPoints(Range.END_TO_START, nodeRange) == -1 &&
-                 range.compareBoundaryPoints(Range.START_TO_END, nodeRange) == 1;
+    
+        var rangeStartRange = range.cloneRange();
+        rangeStartRange.collapse(true);
+    
+        var rangeEndRange = range.cloneRange();
+        rangeEndRange.collapse(false);
+    
+        var nodeStartRange = nodeRange.cloneRange();
+        nodeStartRange.collapse(true);
+    
+        var nodeEndRange = nodeRange.cloneRange();
+        nodeEndRange.collapse(false);
+    
+        return rangeStartRange.compareBoundaryPoints(
+                 Range.START_TO_START, nodeEndRange) == -1 &&
+               rangeEndRange.compareBoundaryPoints(
+                 Range.START_TO_START, nodeStartRange) == 1;
+        
+         
     },
-    rangeCompareNode : function(range, node) {
+    rangeCompareNode : function(range, node)
+    {
         var nodeRange = node.ownerDocument.createRange();
         try {
             nodeRange.selectNode(node);
         } catch (e) {
             nodeRange.selectNodeContents(node);
         }
-        var nodeIsBefore = range.compareBoundaryPoints(Range.START_TO_START, nodeRange) == 1;
-        var nodeIsAfter = range.compareBoundaryPoints(Range.END_TO_END, nodeRange) == -1;
-
-        if (nodeIsBefore && !nodeIsAfter)
-            return 0;
-        if (!nodeIsBefore && nodeIsAfter)
-            return 1;
+        
+        
+        range.collapse(true);
+    
+        nodeRange.collapse(true);
+     
+        var ss = range.compareBoundaryPoints( Range.START_TO_START, nodeRange);
+        var ee = range.compareBoundaryPoints(  Range.END_TO_END, nodeRange);
+         
+        //Roo.log(node.tagName + ': ss='+ss +', ee='+ee)
+        
+        var nodeIsBefore   =  ss == 1;
+        var nodeIsAfter    = ee == -1;
+        
         if (nodeIsBefore && nodeIsAfter)
-            return 2;
-
+            return 0; // outer
+        if (!nodeIsBefore && nodeIsAfter)
+            return 1; //right trailed.
+        
+        if (nodeIsBefore && !nodeIsAfter)
+            return 2;  // left trailed.
+        // fully contined.
         return 3;
     },
 
@@ -39313,11 +39555,28 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     cleanUpPaste :  function()
     {
         // cleans up the whole document..
-      //  console.log('cleanuppaste');
+         Roo.log('cleanuppaste');
         this.cleanUpChildren(this.doc.body);
+        var clean = this.cleanWordChars(this.doc.body.innerHTML);
+        if (clean != this.doc.body.innerHTML) {
+            this.doc.body.innerHTML = clean;
+        }
         
+    },
+    
+    cleanWordChars : function(input) {
+        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;
     },
+    
+    
     cleanUpChildren : function (n)
     {
         if (!n.childNodes.length) {
@@ -39350,7 +39609,16 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
             return;
             
         }
-        if (Roo.form.HtmlEditor.remove.indexOf(node.tagName.toLowerCase()) > -1) {
+        
+        var remove_keep_children= Roo.form.HtmlEditor.remove.indexOf(node.tagName.toLowerCase()) > -1;
+        
+        // remove <a name=....> as rendering on yahoo mailer is bored with this.
+        
+        if (node.tagName.toLowerCase() == 'a' && !node.hasAttribute('href')) {
+            remove_keep_children = true;
+        }
+        
+        if (remove_keep_children) {
             this.cleanUpChildren(node);
             // inserts everything just before this node...
             while (node.childNodes.length) {
@@ -39397,6 +39665,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 }
                 var l = p.split(':').shift().replace(/\s+/g,'');
                 
+                // only allow 'c whitelisted system attributes'
                 if (Roo.form.HtmlEditor.cwhite.indexOf(l) < 0) {
                     Roo.log('(REMOVE)' + node.tagName +'.' + n + ':'+l + '=' + v);
                     node.removeAttribute(n);
@@ -39424,10 +39693,17 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 cleanStyle(a.name,a.value);
             }
             /// clean up MS crap..
+            // tecnically this should be a list of valid class'es..
+            
+            
             if (a.name == 'class') {
                 if (a.value.match(/^Mso/)) {
                     node.className = '';
                 }
+                
+                if (a.value.match(/body/)) {
+                    node.className = '';
+                }
             }
             
             // style cleanup!?
@@ -39532,12 +39808,25 @@ Roo.form.HtmlEditor.pwhite= [
         'http',  'https',  'mailto'
 ];
 
+// white listed style attributes.
 Roo.form.HtmlEditor.cwhite= [
         'text-align',
         'font-size'
 ];
 
-// <script type="text/javascript">
+
+Roo.form.HtmlEditor.swapCodes   =[ 
+    [    8211, "--" ], 
+    [    8212, "--" ], 
+    [    8216,  "'" ],  
+    [    8217, "'" ],  
+    [    8220, '"' ],  
+    [    8221, '"' ],  
+    [    8226, "*" ],  
+    [    8230, "..." ]
+]; 
+
+    // <script type="text/javascript">
 /*
  * Based on
  * Ext JS Library 1.1.1
@@ -39574,6 +39863,16 @@ Roo.form.HtmlEditor.ToolbarStandard = function(config)
 {
     
     Roo.apply(this, config);
+    
+    // default disabled, based on 'good practice'..
+    this.disable = this.disable || {};
+    Roo.applyIf(this.disable, {
+        fontSize : true,
+        colors : true,
+        specialElements : true
+    });
+    
+    
     //Roo.form.HtmlEditorToolbar1.superclass.constructor.call(this, editor.wrap.dom.firstChild, [], config);
     // dont call parent... till later.
 }
@@ -39619,6 +39918,27 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
          // "&#233;"     , // e ecute
          // "&#250;"     , // u ecute?
     ],
+    
+    specialElements : [
+        {
+            text: "Insert Table",
+            xtype: 'MenuItem',
+            xns : Roo.Menu,
+            ihtml :  '<table><tr><td>Cell</td></tr></table>' 
+                
+        },
+        {    
+            text: "Insert Image",
+            xtype: 'MenuItem',
+            xns : Roo.Menu,
+            ihtml : '<img src="about:blank"/>'
+            
+        }
+        
+         
+    ],
+    
+    
     inputElements : [ 
             "form", "input:text", "input:hidden", "input:checkbox", "input:radio", "input:password", 
             "input:submit", "input:button", "select", "textarea", "label" ],
@@ -39735,7 +40055,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
         };
         
         
-        if(this.disable.colors){
+        if(!this.disable.colors){
             tb.add(
                 '-', {
                     id:editor.frameId +'-forecolor',
@@ -39827,9 +40147,10 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
             smenu = {
                 text: "&#169;",
                 cls: 'x-edit-none',
+                
                 menu : {
                     items : []
-                   }
+                }
             };
             for (var i =0; i < this.specialChars.length; i++) {
                 smenu.menu.items.push({
@@ -39848,6 +40169,32 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
             
             
         }
+         
+        if (!this.disable.specialElements) {
+            var semenu = {
+                text: "Other;",
+                cls: 'x-edit-none',
+                menu : {
+                    items : []
+                }
+            };
+            for (var i =0; i < this.specialElements.length; i++) {
+                semenu.menu.items.push(
+                    Roo.apply({ 
+                        handler: function(a,b) {
+                            editor.insertAtCursor(this.ihtml);
+                        }
+                    }, this.specialElements[i])
+                );
+                    
+            }
+            
+            tb.add(semenu);
+            
+            
+        }
+         
+        
         if (this.btns) {
             for(var i =0; i< this.btns.length;i++) {
                 var b = this.btns[i];
@@ -40122,14 +40469,15 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
  new Roo.form.HtmlEditor({
     ....
     toolbars : [
-        new Roo.form.HtmlEditor.ToolbarStandard(),
-        new Roo.form.HtmlEditor.ToolbarContext()
-        })
-    }
+        { xtype: 'ToolbarStandard', styles : {} }
+        { xtype: 'ToolbarContext', disable : {} }
+    ]
+})
+
      
  * 
  * @config : {Object} disable List of elements to disable.. (not done yet.)
- * 
+ * @config : {Object} styles  Map of styles available.
  * 
  */
 
@@ -40139,6 +40487,7 @@ Roo.form.HtmlEditor.ToolbarContext = function(config)
     Roo.apply(this, config);
     //Roo.form.HtmlEditorToolbar1.superclass.constructor.call(this, editor.wrap.dom.firstChild, [], config);
     // dont call parent... till later.
+    this.styles = this.styles || {};
 }
 Roo.form.HtmlEditor.ToolbarContext.types = {
     'IMG' : {
@@ -40215,12 +40564,12 @@ Roo.form.HtmlEditor.ToolbarContext.types = {
         align: {
             title: "Align",
             opts : [[""],[ "left"],[ "center"],[ "right"],[ "justify"],[ "char"]],
-            width: 40
+            width: 80
         },
         valign: {
             title: "Valign",
             opts : [[""],[ "top"],[ "middle"],[ "bottom"],[ "baseline"]],
-            width: 40
+            width: 80
         },
         colspan: {
             title: "Colspan",
@@ -40272,12 +40621,18 @@ Roo.form.HtmlEditor.ToolbarContext.types = {
             width: 200
         }
     },
+    
+    // should we really allow this??
+    // should this just be 
     'BODY' : {
         title : {
             title: "title",
-            width: 120,
+            width: 200,
             disabled : true
         }
+    },
+    '*' : {
+        // empty..
     }
 };
 
@@ -40295,6 +40650,16 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
          
      */
     disable : false,
+    /**
+     * @cfg {Object} styles List of styles 
+     *    eg. { '*' : [ 'headline' ] , 'TD' : [ 'underline', 'double-underline' ] } 
+     *
+     * These must be defined in the page, so they get rendered correctly..
+     * .headline { }
+     * TD.underline { }
+     * 
+     */
+    styles : false,
     
     
     
@@ -40341,7 +40706,8 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
         }
         this.tb = this.toolbars.BODY;
         this.tb.el.show();
-        
+        this.buildFooter();
+        this.footer.show();
          
         this.rendered = true;
         
@@ -40357,39 +40723,110 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
      * Protected method that will not generally be called directly. It triggers
      * a toolbar update by reading the markup state of the current selection in the editor.
      */
-    updateToolbar: function(){
+    updateToolbar: function(ignore_a,ignore_b,sel){
 
+        
         if(!this.editor.activated){
-            this.editor.onFirstFocus();
+             this.editor.onFirstFocus();
             return;
         }
-
+        var updateFooter = sel ? false : true;
+        
         
         var ans = this.editor.getAllAncestors();
         
         // pick
         var ty= Roo.form.HtmlEditor.ToolbarContext.types;
-        var sel = ans.length ? (ans[0] ?  ans[0]  : ans[1]) : this.editor.doc.body;
-        sel = sel ? sel : this.editor.doc.body;
-        sel = sel.tagName.length ? sel : this.editor.doc.body;
+        
+        if (!sel) { 
+            sel = ans.length ? (ans[0] ?  ans[0]  : ans[1]) : this.editor.doc.body;
+            sel = sel ? sel : this.editor.doc.body;
+            sel = sel.tagName.length ? sel : this.editor.doc.body;
+            
+        }
+        // pick a menu that exists..
         var tn = sel.tagName.toUpperCase();
-        sel = typeof(ty[tn]) != 'undefined' ? sel : this.editor.doc.body;
+        //sel = typeof(ty[tn]) != 'undefined' ? sel : this.editor.doc.body;
+        
         tn = sel.tagName.toUpperCase();
-        if (this.tb.name  == tn) {
-            return; // no change
+        
+        var lastSel = this.tb.selectedNode
+        
+        this.tb.selectedNode = sel;
+        
+        // if current menu does not match..
+        if ((this.tb.name != tn) || (lastSel != this.tb.selectedNode)) {
+                
+            this.tb.el.hide();
+            ///console.log("show: " + tn);
+            this.tb =  typeof(ty[tn]) != 'undefined' ? this.toolbars[tn] : this.toolbars['*'];
+            this.tb.el.show();
+            // update name
+            this.tb.items.first().el.innerHTML = tn + ':&nbsp;';
+            
+            
+            // update attributes
+            if (this.tb.fields) {
+                this.tb.fields.each(function(e) {
+                   e.setValue(sel.getAttribute(e.name));
+                });
+            }
+            
+            // update styles
+            var st = this.tb.fields.item(0);
+            st.store.removeAll();
+            var cn = sel.className.split(/\s+/);
+            
+            var avs = [];
+            if (this.styles['*']) {
+                
+                Roo.each(this.styles['*'], function(v) {
+                    avs.push( [ v , cn.indexOf(v) > -1 ? 1 : 0 ] );         
+                });
+            }
+            if (this.styles[tn]) { 
+                Roo.each(this.styles[tn], function(v) {
+                    avs.push( [ v , cn.indexOf(v) > -1 ? 1 : 0 ] );         
+                });
+            }
+            
+            st.store.loadData(avs);
+            st.collapse();
+            st.setValue(cn);
+            
+            // flag our selected Node.
+            this.tb.selectedNode = sel;
+           
+           
+            Roo.menu.MenuMgr.hideAll();
+
         }
-        this.tb.el.hide();
-        ///console.log("show: " + tn);
-        this.tb =  this.toolbars[tn];
-        this.tb.el.show();
-        this.tb.fields.each(function(e) {
-            e.setValue(sel.getAttribute(e.name));
+        
+        if (!updateFooter) {
+            return;
+        }
+        // update the footer
+        //
+        var html = '';
+        
+        this.footerEls = ans.reverse();
+        Roo.each(this.footerEls, function(a,i) {
+            if (!a) { return; }
+            html += html.length ? ' &gt; '  :  '';
+            
+            html += '<span class="x-ed-loc-' + i + '">' + a.tagName + '</span>';
+            
         });
-        this.tb.selectedNode = sel;
+       
+        // 
+        var sz = this.footDisp.up('td').getSize();
+        this.footDisp.dom.style.width = (sz.width -10) + 'px';
+        this.footDisp.dom.style.marginLeft = '5px';
         
+        this.footDisp.dom.style.overflow = 'hidden';
         
-        Roo.menu.MenuMgr.hideAll();
-
+        this.footDisp.dom.innerHTML = html;
+            
         //this.editorsyncValue();
     },
    
@@ -40426,19 +40863,56 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
         
        
         var tb = new Roo.Toolbar(wdiv);
+        // add the name..
+        
         tb.add(nm+ ":&nbsp;");
+        
+        // styles...
+        if (this.styles) {
+            
+            // this needs a multi-select checkbox...
+            tb.addField( new Roo.form.ComboBox({
+                store: new Roo.data.SimpleStore({
+                    id : 'val',
+                    fields: ['val', 'selected'],
+                    data : [] 
+                }),
+                name : 'className',
+                displayField:'val',
+                typeAhead: false,
+                mode: 'local',
+                editable : false,
+                triggerAction: 'all',
+                emptyText:'Select Style',
+                selectOnFocus:true,
+                width: 130,
+                listeners : {
+                    'select': function(c, r, i) {
+                        // initial support only for on class per el..
+                        tb.selectedNode.className =  r ? r.get('val') : '';
+                    }
+                }
+    
+            }));
+        }
+            
+        
+        
         for (var i in tlist) {
+            
             var item = tlist[i];
             tb.add(item.title + ":&nbsp;");
+            
+            
+            
+            
             if (item.opts) {
-                // fixme
-                
-              
+                // opts == pulldown..
                 tb.addField( new Roo.form.ComboBox({
                     store: new Roo.data.SimpleStore({
                         id : 'val',
                         fields: ['val'],
-                        data : item.opts // from states.js
+                        data : item.opts  
                     }),
                     name : i,
                     displayField:'val',
@@ -40458,9 +40932,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                 }));
                 continue;
                     
-                
-                
-                
+                 
                 
                 tb.addField( new Roo.form.TextField({
                     name: i,
@@ -40493,11 +40965,79 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
         return tb;
          
         
+    },
+    buildFooter : function()
+    {
+        
+        var fel = this.editor.wrap.createChild();
+        this.footer = new Roo.Toolbar(fel);
+        // toolbar has scrolly on left / right?
+        var footDisp= new Roo.Toolbar.Fill();
+        var _t = this;
+        this.footer.add(
+            {
+                text : '&lt;',
+                xtype: 'Button',
+                handler : function() {
+                    _t.footDisp.scrollTo('left',0,true)
+                }
+            }
+        );
+        this.footer.add( footDisp );
+        this.footer.add( 
+            {
+                text : '&gt;',
+                xtype: 'Button',
+                handler : function() {
+                    // no animation..
+                    _t.footDisp.select('span').last().scrollIntoView(_t.footDisp,true);
+                }
+            }
+        );
+        var fel = Roo.get(footDisp.el);
+        fel.addClass('x-editor-context');
+        this.footDispWrap = fel; 
+        this.footDispWrap.overflow  = 'hidden';
+        
+        this.footDisp = fel.createChild();
+        this.footDispWrap.on('click', this.onContextClick, this)
+        
+        
+    },
+    onContextClick : function (ev,dom)
+    {
+        ev.preventDefault();
+        var  cn = dom.className;
+        Roo.log(cn);
+        if (!cn.match(/x-ed-loc-/)) {
+            return;
+        }
+        var n = cn.split('-').pop();
+        var ans = this.footerEls;
+        var sel = ans[n];
+        
+         // pick
+        var range = this.editor.createRange();
+        
+        range.selectNodeContents(sel);
+        //range.selectNode(sel);
+        
+        
+        var selection = this.editor.getSelection();
+        selection.removeAllRanges();
+        selection.addRange(range);
+        
+        
+        
+        this.updateToolbar(null, null, sel);
+        
+        
     }
     
     
     
     
+    
 });
 
 
@@ -40788,7 +41328,11 @@ clientValidation  Boolean          Applies to submit only.  Pass true to call fo
             Roo.callback(o.failure, o.scope, [this, action]);
             // show an error message if no failed handler is set..
             if (!this.hasListener('actionfailed')) {
-                Roo.MessageBox.alert("Error", "Saving Failed, please check your entries");
+                Roo.MessageBox.alert("Error",
+                    (typeof(action.result) != 'undefined' && typeof(action.result.errorMsg) != 'undefined') ?
+                        action.result.errorMsg :
+                        "Saving Failed, please check your entries"
+                );
             }
             
             this.fireEvent('actionfailed', this, action);
@@ -40958,10 +41502,12 @@ clientValidation  Boolean          Applies to submit only.  Pass true to call fo
      * This differs from getValues as it calls getValue on each child item, rather than using dom data.
      * @return {Object}
      */
-    getFieldValues : function()
+    getFieldValues : function(with_hidden)
     {
         if (this.childForms) {
             // copy values from the child forms
+            // should this call getFieldValues - probably not as we do not currently copy
+            // hidden fields when we generate..
             Roo.each(this.childForms, function (f) {
                 this.setValues(f.getValues());
             }, this);
@@ -40973,9 +41519,14 @@ clientValidation  Boolean          Applies to submit only.  Pass true to call fo
                 return;
             }
             var v = f.getValue();
+            // not sure if this supported any more..
             if ((typeof(v) == 'object') && f.getRawValue) {
                 v = f.getRawValue() ; // dates..
             }
+            // combo boxes where name != hiddenName...
+            if (f.name != f.getName()) {
+                ret[f.name] = f.getRawValue();
+            }
             ret[f.getName()] = v;
         });
         
@@ -41780,7 +42331,6 @@ Roo.extend(Roo.form.Action.Submit, Roo.form.Action, {
             Roo.MessageBox.hide();
         }
         
-        
         this.response = response;
         this.failureType = Roo.form.Action.CONNECT_FAILURE;
         this.form.afterAction(this, false);
@@ -42721,6 +43271,11 @@ Roo.extend(Roo.form.GridField, Roo.form.Field,  {
             data[ds.reader.meta.root ] =  typeof(v) == 'string' ? Roo.decode(v) : v;
             ds.loadData( data);
         }
+        // clear selection so it does not get stale.
+        if (this.grid.sm) { 
+            this.grid.sm.clearSelections();
+        }
+        
         Roo.form.GridField.superclass.setValue.call(this, v);
         this.refreshValue();
         // should load data in the grid really....
@@ -43035,6 +43590,193 @@ Roo.extend(Roo.form.DayPicker, Roo.form.Field,  {
         Roo.form.DayPicker.superclass.onDestroy.call(this);
     }
 
+});/*
+ * RooJS Library 1.1.1
+ * Copyright(c) 2008-2011  Alan Knowles
+ *
+ * License - LGPL
+ */
+
+/**
+ * @class Roo.form.ComboCheck
+ * @extends Roo.form.ComboBox
+ * A combobox for multiple select items.
+ *
+ * FIXME - could do with a reset button..
+ * 
+ * @constructor
+ * Create a new ComboCheck
+ * @param {Object} config Configuration options
+ */
+Roo.form.ComboCheck = function(config){
+    Roo.form.ComboCheck.superclass.constructor.call(this, config);
+    // should verify some data...
+    // like
+    // hiddenName = required..
+    // displayField = required
+    // valudField == required
+    var req= [ 'hiddenName', 'displayField', 'valueField' ];
+    var _t = this;
+    Roo.each(req, function(e) {
+        if ((typeof(_t[e]) == 'undefined' ) || !_t[e].length) {
+            throw "Roo.form.ComboCheck : missing value for: " + e;
+        }
+    });
+    
+    
+};
+
+Roo.extend(Roo.form.ComboCheck, Roo.form.ComboBox, {
+     
+     
+    editable : false,
+     
+    selectedClass: 'x-menu-item-checked', 
+    
+    // private
+    onRender : function(ct, position){
+        var _t = this;
+        
+        
+        
+        if(!this.tpl){
+            var cls = 'x-combo-list';
+
+            
+            this.tpl =  new Roo.Template({
+                html :  '<div class="'+cls+'-item x-menu-check-item">' +
+                   '<img class="x-menu-item-icon" style="margin: 0px;" src="' + Roo.BLANK_IMAGE_URL + '">' + 
+                   '<span>{' + this.displayField + '}</span>' +
+                    '</div>' 
+                
+            });
+        }
+        
+        Roo.form.ComboCheck.superclass.onRender.call(this, ct, position);
+        this.view.singleSelect = false;
+        this.view.multiSelect = true;
+        this.view.toggleSelect = true;
+        this.pageTb.add(new Roo.Toolbar.Fill(), {
+            
+            text: 'Done',
+            handler: function()
+            {
+                _t.collapse();
+            }
+        });
+    },
+    
+    onViewOver : function(e, t){
+        // do nothing...
+        return;
+        
+    },
+    
+    onViewClick : function(doFocus,index){
+        return;
+        
+    },
+    select: function () {
+        //Roo.log("SELECT CALLED");
+    },
+     
+    selectByValue : function(xv, scrollIntoView){
+        var ar = this.getValueArray();
+        var sels = [];
+        
+        Roo.each(ar, function(v) {
+            if(v === undefined || v === null){
+                return;
+            }
+            var r = this.findRecord(this.valueField, v);
+            if(r){
+                sels.push(this.store.indexOf(r))
+                
+            }
+        },this);
+        this.view.select(sels);
+        return false;
+    },
+    
+    
+    
+    onSelect : function(record, index){
+       // Roo.log("onselect Called");
+       // this is only called by the clear button now..
+        this.view.clearSelections();
+        this.setValue('[]');
+        if (this.value != this.valueBefore) {
+            this.fireEvent('change', this, this.value, this.valueBefore);
+        }
+    },
+    getValueArray : function()
+    {
+        var ar = [] ;
+        
+        try {
+            //Roo.log(this.value);
+            if (typeof(this.value) == 'undefined') {
+                return [];
+            }
+            var ar = Roo.decode(this.value);
+            return  ar instanceof Array ? ar : []; //?? valid?
+            
+        } catch(e) {
+            Roo.log(e + "\nRoo.form.ComboCheck:getValueArray  invalid data:" + this.getValue());
+            return [];
+        }
+         
+    },
+    expand : function ()
+    {
+        Roo.form.ComboCheck.superclass.expand.call(this);
+        this.valueBefore = this.value;
+        
+
+    },
+    
+    collapse : function(){
+        Roo.form.ComboCheck.superclass.collapse.call(this);
+        var sl = this.view.getSelectedIndexes();
+        var st = this.store;
+        var nv = [];
+        var tv = [];
+        var r;
+        Roo.each(sl, function(i) {
+            r = st.getAt(i);
+            nv.push(r.get(this.valueField));
+        },this);
+        this.setValue(Roo.encode(nv));
+        if (this.value != this.valueBefore) {
+
+            this.fireEvent('change', this, this.value, this.valueBefore);
+        }
+        
+    },
+    
+    setValue : function(v){
+        // Roo.log(v);
+        this.value = v;
+        
+        var vals = this.getValueArray();
+        var tv = [];
+        Roo.each(vals, function(k) {
+            var r = this.findRecord(this.valueField, k);
+            if(r){
+                tv.push(r.data[this.displayField]);
+            }else if(this.valueNotFoundText !== undefined){
+                tv.push( this.valueNotFoundText );
+            }
+        },this);
+       // Roo.log(tv);
+        
+        Roo.form.ComboBox.superclass.setValue.call(this, tv.join(', '));
+        this.hiddenField.value = v;
+        this.value = v;
+    }
+    
 });//<script type="text/javasscript">
  
 
@@ -43971,12 +44713,18 @@ layout.addxtype({
     {
         // basically accepts a pannel...
         // can accept a layout region..!?!?
-       // console.log('BorderLayout add ' + cfg.xtype)
+        //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
         
         if (!cfg.xtype.match(/Panel$/)) {
             return false;
         }
         var ret = false;
+        
+        if (typeof(cfg.region) == 'undefined') {
+            Roo.log("Failed to add Panel, region was not set");
+            Roo.log(cfg);
+            return false;
+        }
         var region = cfg.region;
         delete cfg.region;
         
@@ -43986,7 +44734,7 @@ layout.addxtype({
             xitems = cfg.items;
             delete cfg.items;
         }
-        
+        var nb = false;
         
         switch(cfg.xtype) 
         {
@@ -44027,7 +44775,7 @@ layout.addxtype({
                 ret = new Roo[cfg.xtype](layout, cfg); // new panel!!!!!
                 //console.log('adding nested layout panel '  + cfg.toSource());
                 this.add(region, ret);
-                
+                nb = {}; /// find first...
                 break;
                 
             case 'GridPanel': 
@@ -44068,10 +44816,37 @@ layout.addxtype({
         }
         this.beginUpdate();
         // add children..
+        var region = '';
+        var abn = {};
         Roo.each(xitems, function(i)  {
-            ret.addxtype(i);
+            region = nb && i.region ? i.region : false;
+            
+            var add = ret.addxtype(i);
+           
+            if (region) {
+                nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
+                if (!i.background) {
+                    abn[region] = nb[region] ;
+                }
+            }
+            
         });
         this.endUpdate();
+
+        // make the last non-background panel active..
+        //if (nb) { Roo.log(abn); }
+        if (nb) {
+            
+            for(var r in abn) {
+                region = this.getRegion(r);
+                if (region) {
+                    // tried using nb[r], but it does not work..
+                     
+                    region.showPanel(abn[r]);
+                   
+                }
+            }
+        }
         return ret;
         
     }
@@ -45741,7 +46516,7 @@ Roo.LayoutStateManager.prototype = {
  * @cfg {String} region         (center|north|south|east|west) which region to put this panel on (when used with xtype constructors)
  * @cfg {String/Object} params  When used with {@link #url}, calls {@link #setUrl} with this value
  * @cfg {Boolean} loadOnce      When used with {@link #url}, calls {@link #setUrl} with this value
- * @cfg {String} content        Raw content to fill content panel with (uses setContent on construction.)
+ * @cfg {String}    content        Raw content to fill content panel with (uses setContent on construction.)
 
  * @constructor
  * Create a new ContentPanel.
@@ -45789,9 +46564,9 @@ Roo.ContentPanel = function(el, config, content){
     }
     
     if (this.toolbar && !this.toolbar.el && this.toolbar.xtype) {
-        this.wrapEl = this.el.wrap();    
-        this.toolbar = new Roo.Toolbar(this.el.insertSibling(false, 'before'), [] , this.toolbar);
-        
+        this.wrapEl = this.el.wrap();
+        this.toolbar.container = this.el.insertSibling(false, 'before');
+        this.toolbar = new Roo.Toolbar(this.toolbar);
     }
     
     
@@ -47952,7 +48727,14 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         this.rowEl.elements = els;
         return this.rowEl;
     },
-
+    /**
+     * Gets the 'td' of the cell
+     * 
+     * @param {Integer} rowIndex row to select
+     * @param {Integer} colIndex column to select
+     * 
+     * @return {Object} 
+     */
     getCell : function(rowIndex, colIndex){
         var locked = this.cm.getLockedCount();
         var source;
@@ -50411,6 +51193,7 @@ Roo.extend(Roo.grid.RowSelectionModel, Roo.grid.AbstractSelectionModel,  {
  * This class provides the basic implementation for cell selection in a grid.
  * @constructor
  * @param {Object} config The object containing the configuration of this model.
+ * @cfg {Boolean} enter_is_tab Enter behaves the same as tab. (eg. goes to next cell) default: false
  */
 Roo.grid.CellSelectionModel = function(config){
     Roo.apply(this, config);
@@ -50444,12 +51227,21 @@ Roo.grid.CellSelectionModel = function(config){
                <li>o.cell: An array of [rowIndex, columnIndex]</li>
                </ul>
             */
-           "selectionchange" : true
+           "selectionchange" : true,
+        /**
+            * @event tabend
+            * Fires when the tab (or enter) was pressed on the last editable cell
+            * You can use this to trigger add new row.
+            * @param {SelectionModel} this
+            */
+           "tabend" : true
     });
     Roo.grid.CellSelectionModel.superclass.constructor.call(this);
 };
 
 Roo.extend(Roo.grid.CellSelectionModel, Roo.grid.AbstractSelectionModel,  {
+    
+    enter_is_tab: false,
 
     /** @ignore */
     initEvents : function(){
@@ -50558,7 +51350,7 @@ Roo.extend(Roo.grid.CellSelectionModel, Roo.grid.AbstractSelectionModel,  {
 
     /** @ignore */
     handleKeyDown : function(e){
-        Roo.log('Cell Sel Model handleKeyDown');
+        //Roo.log('Cell Sel Model handleKeyDown');
         if(!e.isNavKeyPress()){
             return;
         }
@@ -50578,61 +51370,93 @@ Roo.extend(Roo.grid.CellSelectionModel, Roo.grid.AbstractSelectionModel,  {
         var k = e.getKey(), r = s.cell[0], c = s.cell[1];
         var newCell;
 
+      
+
         switch(k){
             case e.TAB:
                 // handled by onEditorKey
                 if (g.isEditor && g.editing) {
                     return;
                 }
-                if(e.shiftKey){
-                     newCell = walk(r, c-1, -1);
-                }else{
-                     newCell = walk(r, c+1, 1);
+                if(e.shiftKey) {
+                    newCell = walk(r, c-1, -1);
+                } else {
+                    newCell = walk(r, c+1, 1);
                 }
-             break;
-             case e.DOWN:
-                 newCell = walk(r+1, c, 1);
-             break;
-             case e.UP:
-                 newCell = walk(r-1, c, -1);
-             break;
-             case e.RIGHT:
-                 newCell = walk(r, c+1, 1);
-             break;
-             case e.LEFT:
-                 newCell = walk(r, c-1, -1);
-             break;
-             case e.ENTER:
-                 if(g.isEditor && !g.editing){
-                    g.startEditing(r, c);
-                    e.stopEvent();
-                    return;
+                break;
+            
+            case e.DOWN:
+               newCell = walk(r+1, c, 1);
+                break;
+            
+            case e.UP:
+                newCell = walk(r-1, c, -1);
+                break;
+            
+            case e.RIGHT:
+                newCell = walk(r, c+1, 1);
+                break;
+            
+            case e.LEFT:
+                newCell = walk(r, c-1, -1);
+                break;
+            
+            case e.ENTER:
+                
+                if(g.isEditor && !g.editing){
+                   g.startEditing(r, c);
+                   e.stopEvent();
+                   return;
                 }
+                
+                
              break;
         };
         if(newCell){
             this.select(newCell[0], newCell[1]);
             e.stopEvent();
+            
         }
     },
 
     acceptsNav : function(row, col, cm){
         return !cm.isHidden(col) && cm.isCellEditable(col, row);
     },
-
+    /**
+     * Selects a cell.
+     * @param {Number} field (not used) - as it's normally used as a listener
+     * @param {Number} e - event - fake it by using
+     *
+     * var e = Roo.EventObjectImpl.prototype;
+     * e.keyCode = e.TAB
+     *
+     * 
+     */
     onEditorKey : function(field, e){
         
-        var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
+        var k = e.getKey(),
+            newCell,
+            g = this.grid,
+            ed = g.activeEditor,
+            forward = false;
         ///Roo.log('onEditorKey' + k);
         
+        
+        if (this.enter_is_tab && k == e.ENTER) {
+            k = e.TAB;
+        }
+        
         if(k == e.TAB){
             if(e.shiftKey){
                 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
             }else{
                 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
+                forward = true;
             }
+            
             e.stopEvent();
-        }else if(k == e.ENTER && !e.ctrlKey){
+            
+        }else if(k == e.ENTER &&  !e.ctrlKey){
             ed.completeEdit();
             e.stopEvent();
             newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
@@ -50644,6 +51468,9 @@ Roo.extend(Roo.grid.CellSelectionModel, Roo.grid.AbstractSelectionModel,  {
         if(newCell){
             //Roo.log('next cell after edit');
             g.startEditing.defer(100, g, [newCell[0], newCell[1]]);
+        } else if (forward) {
+            // tabbed past last
+            this.fireEvent.defer(100, this, ['tabend',this]);
         }
     }
 });/*
@@ -50765,6 +51592,9 @@ Roo.extend(Roo.grid.EditorGrid, Roo.grid.Grid, {
             cancel:false,
             editor: ed
         };
+        var cell = Roo.get(this.view.getCell(ed.row,ed.col))
+        cell.show();
+          
         if(String(value) !== String(startValue)){
             
             if(this.fireEvent("validateedit", e) !== false && !e.cancel){
@@ -50793,8 +51623,10 @@ Roo.extend(Roo.grid.EditorGrid, Roo.grid.Grid, {
         this.stopEditing();
         if(this.colModel.isCellEditable(col, row)){
             this.view.ensureVisible(row, col, true);
+          
             var r = this.dataSource.getAt(row);
             var field = this.colModel.getDataIndex(col);
+            var cell = Roo.get(this.view.getCell(row,col));
             var e = {
                 grid: this,
                 record: r,
@@ -50802,7 +51634,7 @@ Roo.extend(Roo.grid.EditorGrid, Roo.grid.Grid, {
                 value: r.data[field],
                 row: row,
                 column: col,
-                cancel:false
+                cancel:false 
             };
             if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
                 this.editing = true;
@@ -50815,12 +51647,15 @@ Roo.extend(Roo.grid.EditorGrid, Roo.grid.Grid, {
                     ed.render(ed.parentEl || document.body);
                 }
                 ed.field.reset();
+               
+                cell.hide();
+                
                 (function(){ // complex but required for focus issues in safari, ie and opera
                     ed.row = row;
                     ed.col = col;
                     ed.record = r;
-                    ed.on("complete", this.onEditComplete, this, {single: true});
-                    ed.on("specialkey", this.selModel.onEditorKey, this.selModel);
+                    ed.on("complete",   this.onEditComplete,        this,       {single: true});
+                    ed.on("specialkey", this.selModel.onEditorKey,  this.selModel);
                     this.activeEditor = ed;
                     var v = r.data[field];
                     ed.startEdit(this.view.getCell(row, col), v);
@@ -51192,7 +52027,7 @@ Roo.LoadMask = function(el, config){
     if(this.store){
         this.store.on('beforeload', this.onBeforeLoad, this);
         this.store.on('load', this.onLoad, this);
-        this.store.on('loadexception', this.onLoad, this);
+        this.store.on('loadexception', this.onLoadException, this);
         this.removeMask = false;
     }else{
         var um = this.el.getUpdateManager();
@@ -51240,9 +52075,17 @@ Roo.LoadMask.prototype = {
     enable : function(){
         this.disabled = false;
     },
-
+    
+    onLoadException : function()
+    {
+        if (this.store && typeof(this.store.reader.jsonData.errorMsg) != 'undefined') {
+            Roo.MessageBox.alert("Error loading",this.store.reader.jsonData.errorMsg);
+        }
+        this.el.unmask(this.removeMask);
+    },
     // private
-    onLoad : function(){
+    onLoad : function()
+    {
         this.el.unmask(this.removeMask);
     },
 
@@ -51258,7 +52101,7 @@ Roo.LoadMask.prototype = {
         if(this.store){
             this.store.un('beforeload', this.onBeforeLoad, this);
             this.store.un('load', this.onLoad, this);
-            this.store.un('loadexception', this.onLoad, this);
+            this.store.un('loadexception', this.onLoadException, this);
         }else{
             var um = this.el.getUpdateManager();
             um.un('beforeupdate', this.onBeforeLoad, this);