[qo-modules-dev] [55] I'm finally happier with the handlers for the buttons, start menu, etc .

[ Thread Index | Date Index | More lists.tuxfamily.org/qo-modules-dev Archives ]


Revision: 55
Author:   mjlecomte
Date:     2008-12-09 05:02:36 +0100 (Tue, 09 Dec 2008)

Log Message:
-----------
I'm finally happier with the handlers for the buttons, start menu, etc.  I've created a class that I think is better than Ext.Action because it doesn't have to update any subscribed components like Ext.Action does.  Instead, a class is created that any buttons, menu handlers, etc. link to and are updated simply by updating the class's handler.

There appears to be a bug with destroying sub menus of menus.  If there is a sub menu for a menu, it will not be destroyed automatically.  I posted a thread about this (not in bug forum), awaiting response before trying to correct myself.  I noticed this monitoring ComponentMgr creep when closing module windows because I made the associated taskbar button have a context menu with a submenu to arrange the module windows.

Modified Paths:
--------------
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/desktop.html
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/App.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/Module.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/ActiveApps.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/Appbar.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/TaskBar.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/preload.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/resources/css/desktop.css

Added Paths:
-----------
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/XAction.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.Button.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.GridPanel.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.PagingToolbar.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.WindowGroup.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.GroupingStore.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.JsonReader.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.Store.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.Action.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.ErrorReader.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.Field.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.VTypes.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.grid.ColumnModel.js
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.grid.filter.DateFilter.js

Removed Paths:
-------------
    mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/Launch.js


Modified: mickael/trunk/ext/v3.0.0-a1/learn/desktop/desktop.html
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/desktop.html	2008-12-07 07:39:01 UTC (rev 54)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/desktop.html	2008-12-09 04:02:36 UTC (rev 55)
@@ -22,11 +22,12 @@
 -->
  	<!-- OVERRIDES -->       <!-- Destroy context menus -->
     <script type="text/javascript" src="js/overrides/override.js"></script>
+    <script type="text/javascript" src="js/overrides/Ext.Button.js"></script>
 
     <!-- APPLICATION -->     <!-- These must be loaded immediately (logic to get modules, etc.) -->
     <script type="text/javascript" src="js/Module.js"></script>
     <script type="text/javascript" src="js/data/RemoteLoader.js"></script>
-    <script type="text/javascript" src="js/Launch.js"></script>
+    <script type="text/javascript" src="js/XAction.js"></script>
     <script type="text/javascript" src="js/App.js"></script>
 
     <!-- MODEL (Sample Modules) -->  <!-- Flat file for module configuration, could serve this content via php/mySQL -->

Modified: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/App.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/App.js	2008-12-07 07:39:01 UTC (rev 54)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/App.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -14,11 +14,6 @@
     
         Ext.apply(this, config);
         
-        // abstract method that shall be implemented by the instance of this app.
-        // This method will typically load the platform (modules, settings, etc.).  
-        // The getPlatform() method shall set this.platformLoaded = true to
-        // signify that the system can be initialized (this is required in order
-        // to handle a possible race condition with Ext.isReady.
         this.getPlatform();
         
         //add events
@@ -76,12 +71,16 @@
         
         this.onAppReady(this.initAutoRun, this);
         this.on({
-            beforecreate: this.onBeforeCreate,
             changecount: this.onChangeCount
         });
     },
 
-    /* @private */
+    /**
+     * Create a module.  Will fire a beforecreate event to provide a hook to prevent
+     * creating another instance of the module.
+     * @param {Object} m The module
+     * @private 
+     */
     createModule: function (m) {
         if (typeof m === 'string') {
             Ext.ComponentMgr.get(m);
@@ -98,13 +97,18 @@
         return m;
     },
 
-    /* @private */
+    /**
+     * Determines the id for this instance of the module so that there are
+     * no duplicate id's used. 
+     * @param {Object} m The module
+     * @private 
+     */
     getModId: function (m) {
         var i, id, k, n = m.instances;
         //need to loop through instances array to make sure not reusing an id
         //this step is needed because a module instance may have been destroyed
         for (i = 0; i < m.limit; i++) {
-            id = m.id + '_' + i;
+            id = m.moduleId + '_' + i;
             // does the id exist in the array?
             if (n.indexOf(id) > -1) {
                 //there is a match
@@ -112,43 +116,57 @@
             }
             break;
         }
+        // update the module.instances property to include this id
         n.push(id);
         return id;
     },
 
-    /* @private */
-    onBeforeCreate: function (scope, m) {
-        // check if the number of instances are within the number permitted
-        if (m.instances.length < m.limit) {
-            return true;
-        }
-        return false;
-    },
+    /**
+     * Callback after the module has been loaded 
+     * @param {Object} m The module
+     * @private 
+     */
+    onLoad: function (m) {
 
-    onLoad: function (m) {
-        // Point launcher's handler at createModule once loaded
-        var item = Ext.ux.Launch.get(m.id);
-        item.handler = this.createModule.createDelegate(this, [m]);
+        // get a reference to the handler class instance from the manager
+        var h = Ext.ux.XActionMgr.all.get(m.moduleId);
+
+        // update the handler to point at createModule once loaded
+        h.handler = this.createModule.createDelegate(this, [m]);
     },
 
-    /* @private */
+    /**
+     * A module has instances that are tracked.  When a module is created
+     * or destroyed this method is called to update the XAction handlers
+     * associated with this module. 
+     * @param {Object} m The module
+     * @private 
+     */
     onChangeCount: function (scope, m, change) {
-//      Ext.each(launchers, function (item, index, allItems){
-        var n, item = Ext.ux.Launch.get(m.id);
-        n = m.instances;
+
+        // number of current instances for the module
+        var n = m.instances;
+        
+        // get a reference to the handler class instance from the manager
+        var h = Ext.ux.XActionMgr.all.get(m.moduleId);
+        
         if (n.length >= m.limit) {
             var k, last, launchers;
             // if limit has been met, change the handler to show the last instance created
             k = n[m.limit - 1];
             last = Ext.getCmp(k);
-            launchers = Ext.ux.Launch.filter('id', m.id, true);
-            item.handler = last.show.createDelegate(last);
+            h.handler = last.show.createDelegate(last);
         } else {
-            item.handler = this.createModule.createDelegate(this, [m]);
+            h.handler = this.createModule.createDelegate(this, [m]);
         }
-//      });
     },
 
+    /**
+     * Returns the appropriate handler for the module based on if the module has been loaded.
+     * If the module has not been loaded, the handler will load the module.
+     * If the module has been loaded, the handler will create a new module instance.
+     * @param {Object} m The module
+     */
     getHandler: function (m) {
         var handler;
         if (m.loaded === true) {
@@ -161,16 +179,33 @@
         }
         return handler;
     },
-
+/*
     getLaunchers: function (val) {
         return Ext.ux.Launch.filter('type', val);
     },
-
+*/
+    /**
+     * Convenience method to access the ModuleMgr's Mixed Collection to get a reference to
+     * a module.
+     * @param {Object} m The object shall have an id property which will be used to lookup the module.
+     */
     getModule: function (m) {
         return Ext.ux.ModuleMgr.get(m.id);
     },
 
-    //abstract method to be overridden if needed
+    /**
+     * Abstract method to be implemented by the instance of this app.
+     * This method will typically load the platform (modules, settings, etc.).
+     * The getPlatform() method shall set this.platformLoaded = true to signify 
+     * that the system can be initialized (this is required in order to handle
+     * a possible race condition with Ext.isReady.
+     */
+    getPlatform: Ext.emptyFn,
+
+
+    /**
+     * Abstract method to be overridden if needed.
+     */
     getViewConfig: Ext.emptyFn,
 
     /* @private */
@@ -185,16 +220,18 @@
     },
 
     /**
+     * Runs when this app is ready
      * @private
-     * Runs when this app is ready
      */
     initAutoRun: function () {
-        var m, items = this.getLaunchers('autorun');
+        var m, items = Ext.ux.ModuleMgr.filterType('autorun');
+
         if (items) {
             for (var i = 0, len = items.length; i < len; i++) {
                 m = this.getModule(items[i]);
+
                 // call the module's handler
-                this.getHandler(m).call();
+                m.handler.call();
             }
         }
     },
@@ -202,6 +239,7 @@
     /**
      * Initialize the module's launchers
      * @param {Object} m the module
+     * @private
      */
     initLaunchers: function (m) {
         if (!m.launchers) {
@@ -214,7 +252,7 @@
         for (var i = 0, len = l.length; i < len; i++) {
             k = {};
             
-            // set the launcher type
+            // set the launcher type (launch config can be just a string or a config object)
             if (typeof l[i] === "string") {
                 k.type = l[i];
             } else {
@@ -224,21 +262,8 @@
             l[i] = Ext.applyIf(k, m.launchDefaults);
             
             // assign id
-            l[i].launchId = k.type + '_' + m.id;
-            l[i].id = m.id;
-
-            // set up the handler
-            l[i].handler = new Ext.ux.Launch({
-                handler: this.getHandler(m),
-                id: m.id
-            });
-
-            l[i].scope = l[i].scope || m;
+            l[i].id = m.moduleId;
         }
-
-// add to the launch manager
-// TODO: this should be removed and added to the constructor for the handler
-        Ext.ux.Launch.manager.addAll(l);
     },
 
     /* @private */
@@ -260,8 +285,15 @@
             // initialize array to track module instances (used to limit
             // instances to the configured 'limit')
             m.instances = [];
+
             // Initialize launchers for the module
             this.initLaunchers(m);
+
+            // set up the ONE handler for the module
+            m.handler = new Ext.ux.XAction({
+                handler: this.getHandler(m),
+                itemId: m.moduleId
+            });
         }
         return true;
     },
@@ -320,6 +352,10 @@
         }
     },
 
+    /**
+     * Method called when the browser attempts to unload.
+     * @param {Object} e
+     */
     onBeforeUnload: function (e) {
         if (this.fireEvent('beforeunload', this) === false) {
             e.stopEvent();
@@ -344,6 +380,8 @@
 
     /**
      * Dynamically remove external JavaScript files from appearing in the head section.
+     * Calling this function will remove all linked javascript files from the head element
+     * of the page.  This method does not remove from the browser's memory.
      */
     removeAlljs: function () {
         var f = document.getElementsByTagName('script');

Deleted: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/Launch.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/Launch.js	2008-12-07 07:39:01 UTC (rev 54)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/Launch.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -1,92 +0,0 @@
-/**
- * <p>This class is used to manage handlers for buttons, menus, shortcuts, etc.</p>
- * <p>Since this class will emulate a function, it needs to behave as a function, so
- * we will implement call and apply methods as per  
- * https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Function#Methods
- * @class Ext.ux.Launch
- * @singleton
- */
-Ext.ux.Launch = (function(){
-
-    // Private area
-    // Only the members passed back with the *return* can access these properties
-
-    var LaunchMgr = new Ext.util.MixedCollection(
-        false, //false = do not add function references when using addAll 
-        // the getKey function:
-        function (h) {
-            return h.launchId || h.id;
-        }
-    );
-    
-    /* @private */
-    var launch = Ext.extend(Object, {
-
-        constructor: function (config) {
-            Ext.apply(this, config);
-            if (this.launchId || this.id) {
-                LaunchMgr.add(this);
-            }
-        },
-        /**
-         * @private
-         */
-        call: function () {
-            //slice is not available to Object so we have to call on Array to help us out
-            this.handler.apply(this.scope || arguments[0], Array.prototype.slice.call(arguments, 1));
-        },
-        /**
-         * @param {Object} scope
-         * @param {Object} a
-         * @private
-         */
-        apply: function (scope, a) {
-            this.handler.apply(this.scope || a[0], Array.prototype.slice.call(a, 1));
-        }
-    });
-
-    // additional methods attached to constructor object for ease of access later
-
-    /**
-    * Returns the item associated with the passed key or index.
-    * <pre><code>
-var alert1 = function(){alert(1);};
-var alert2 = function(){alert(2);};
-
-var myHandler = new Ext.ux.Launch({
-	handler: alert1,
-    id: 'testHandler'
-});
-
-Ext.onReady(function(){
-    Ext.get("elementId").on("click", myHandler);
-});
-
-var test = Ext.ux.Launch.get('testHandler');
-test.handler = alert2;
-</code></pre>
-    * @param {String/Number } id The key or index of the item.
-    */
-    launch.get = function (key) {
-        return LaunchMgr.get(key);
-    };
-
-    /**
-     * Filters the MixedCollection by the specified property and value.
-     * @param {Object} by property to filter by
-     * @param {Object} val value for the filter property
-     * @param {Boolean} anyMatch (optional) True to match any part of the string, not just the beginning
-     */
-    launch.filter = function (prop, val, anyMatch) {
-        return LaunchMgr.filter(prop, val, anyMatch).items;
-    };
-
-    /**
-     * A reference to the MixedCollection of handlers 
-     * @type {Ext.util.MixedCollection }
-     * @property
-     */
-    launch.manager = LaunchMgr;
-    
-    return launch;
-})();
\ No newline at end of file

Modified: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/Module.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/Module.js	2008-12-07 07:39:01 UTC (rev 54)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/Module.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -1,25 +1,36 @@
 /**
- * Mixed Collection implementation for module management.
+ * <p>Provides a registry of all Modules (instances of {@link Ext.ux.Module}
+ * so that they can be easily accessed by moduleId or id (see {@link #getKey}.</p>
  * TODO: implement an onAvailable method similar to Component Manager 
  * @class Ext.ux.ModuleMgr
  */
 Ext.ux.ModuleMgr = Ext.apply(new Ext.util.MixedCollection(), {
     /**
-     * adds to the MixedCollection
+     * Filters the Mixed Collection to return an array of module launcher
+     * configurations that match the type passed.
+     * @param {String} type The launcher type ('start','quick','tray', etc.)
      */
-    register : function () {
-        for (var i = 0, s; s = arguments[i]; i++) {
-            this.add(s);
-        }
+    filterType: function(type) {
+        var r = [];
+        this.each(function (i){
+            Ext.each(i.launchers, function (j){
+                if (j.type === type) {
+                       j.handler = Ext.ux.XActionMgr.get(j.id);
+                    r.push(j);
+                }
+            });
+        });
+        return r;
     },
+
     /**
-     * removes from the MixedCollection
+     * getKey implementation for MixedCollection
+     * @param {Object} o Object containing either a moduleId or id property.
      */
-    unregister : function () {
-        for (var i = 0, s; s = arguments[i]; i++) {
-            this.remove(this.lookup(s));
-        }
+    getKey : function (o) {
+        return  o.moduleId || o.id;
     },
+
     /**
      * Return the item associated with the passed key or index. 
      * @param {Object} id
@@ -27,11 +38,29 @@
     lookup : function (id) {
         return typeof id === "object" ? id : this.get(id);
     },
+
     /**
-     * getKey implementation for MixedCollection
+     * Registers one or more Modules with the ModuleMgr. 
+     * @param {Ext.ux.Module} module1 A Module instance
+     * @param {Ext.ux.Module} module2 (optional)
+     * @param {Ext.ux.Module} etc... (optional)
      */
-    getKey : function (o) {
-        return o.id;
+    register : function () {
+        for (var i = 0, s; s = arguments[i]; i++) {
+            this.add(s);
+        }
+    },
+
+    /**
+     * Unregisters one or more Modules with the ModuleMgr. 
+     * @param {Ext.ux.Module} module1 A Module instance
+     * @param {Ext.ux.Module} module2 (optional)
+     * @param {Ext.ux.Module} etc... (optional)
+     */
+    unregister : function () {
+        for (var i = 0, s; s = arguments[i]; i++) {
+            this.remove(this.lookup(s));
+        }
     }
 });
 

Copied: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/XAction.js (from rev 54, mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/Launch.js)
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/XAction.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/XAction.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,111 @@
+/**
+ * <p>Provides a registry of all XActions (instances of {@link Ext.ux.XAction}
+ * so that they can be easily accessed by itemId (see {@link #get}.</p>
+ * @class Ext.ux.XActionMgr
+ * @singleton
+ */
+Ext.ux.XActionMgr = function(){
+    var all = new Ext.util.MixedCollection(false, 
+        // the getKey function:
+        function (h) {
+            return h.itemId;
+        }
+    );
+
+    return {
+        /**
+         * The MixedCollection used internally for the XAction cache. An example
+         * usage may be subscribing to events on the MixedCollection to monitor
+         * addition or removal.  Read-only.
+         * @type {MixedCollection}
+         */
+        all : all,
+
+        /**
+         * Returns a component by id
+         * @param {String} id The XAction id
+         * @return Ext.Component
+         */
+        get : function(id){
+            return all.get(id);
+        },
+
+        /**
+         * Registers a XAction.
+         * @param {Ext.Component} c The XAction
+         */
+        register : function(c){
+            all.add(c);
+        },
+
+        /**
+         * Unregisters a XAction.
+         * @param {Ext.Component} c The XAction
+         */
+        unregister : function(c){
+            all.remove(c);
+        }
+    };
+}();
+
+/**
+ * <p>This class provides a central interface to control handlers.  Handlers assigned to buttons, menus, links, etc.
+ * can be updated at this class so that all linkages to this handler are automatically updated.</p>
+ * <p>Since this class will emulate a function, it needs to behave as a function, so we will implement call and apply
+ * methods as per http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Function#Methods
+ * Example usage:<br>
+ * <pre><code>
+var alert1 = function(){alert(1);};
+var alert2 = function(){alert(2);};
+
+// create XAction
+var myHandler = new Ext.ux.XAction({
+	handler: alert1,
+    itemId: 'testHandler'
+});
+
+Ext.onReady(function(){
+    // assign the XAction as a handler to some widget
+    Ext.get("elementId").on("click", myHandler);
+});
+
+// get a reference to the XAction instance through it's id
+var test = Ext.ux.XActionMgr.get('testHandler');
+
+// update the handler, so all widgets implementing this XAction automatically map to this XAction
+test.handler = alert2;
+</code></pre>
+ * @class Ext.ux.XAction
+ */
+Ext.ux.XAction = Ext.extend(Object, {
+    /**
+     * @cfg {String} itemId The unique id for the XAction.  Use this id to get a reference to the XAction
+     * from the Ext.ux.XActionMgr Mixed Collection.
+     */
+
+    /**
+     * @private
+     */
+    constructor: function (config) {
+        Ext.apply(this, config);
+        this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
+        Ext.ux.XActionMgr.register(this);
+    },
+
+    /**
+     * @private
+     */
+    call: function () {
+        //slice is not available to Object so we have to call on Array to help us out
+        this.handler.apply(this.scope || arguments[0], Array.prototype.slice.call(arguments, 1));
+    },
+
+    /**
+     * @param {Object} scope
+     * @param {Object} a
+     * @private
+     */
+    apply: function (scope, a) {
+        this.handler.apply(this.scope || a[0], Array.prototype.slice.call(a, 1));
+    }
+});
\ No newline at end of file


Property changes on: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/XAction.js
___________________________________________________________________
Name: svn:mergeinfo
   + 

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.Button.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.Button.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.Button.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,15 @@
+/** 
+ * Ext Button Override
+ * 
+ * @class Ext.Button
+ * @extends Ext.Component
+ * 
+ * ensure that context menus for buttons are destroyed
+ */
+Ext.override(Ext.Button, {
+    beforeDestroy: Ext.Button.prototype.beforeDestroy.createSequence(function(){
+        if(this.cmenu){
+            Ext.destroy(this.cmenu);
+        }
+    })
+});
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.GridPanel.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.GridPanel.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.GridPanel.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,56 @@
+/** 
+ * Ext grid GridPanel Override
+ * 
+ * @author Michael LeComte, michael.lecomte@xxxxxxxxxxxx 
+ * @copyright (c) 2008 
+ * @date October 18, 2008 
+ * 
+ * @class Ext.grid.GridPanel
+ * 
+ * correction for loadMask being applied too late
+ */
+
+Ext.override(Ext.grid.GridPanel, {
+    onRender : function(ct, position){
+        Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
+
+//moved from initEvents
+        //instantiate the loadMask any time after bwrap is available
+        //loadMask shows up on all loads this way, but first load
+        //needs correction to message placement (vertically)
+        if(this.loadMask){
+            this.loadMask = new Ext.LoadMask(this.bwrap,
+                    Ext.apply({store:this.store}, this.loadMask));
+        }
+//moved from initEvents
+
+        var c = this.body;
+
+        this.el.addClass('x-grid-panel');
+
+        var view = this.getView();
+        view.init(this);
+
+        c.on("mousedown", this.onMouseDown, this);
+        c.on("click", this.onClick, this);
+        c.on("dblclick", this.onDblClick, this);
+        c.on("contextmenu", this.onContextMenu, this);
+        c.on("keydown", this.onKeyDown, this);
+
+        this.relayEvents(c, ["mousedown","mouseup","mouseover","mouseout","keypress"]);
+
+        this.getSelectionModel().init(this);
+        this.view.render();
+    },
+
+    // private
+    initEvents : function(){
+        Ext.grid.GridPanel.superclass.initEvents.call(this);
+/*
+        if(this.loadMask){
+            this.loadMask = new Ext.LoadMask(this.bwrap,
+                    Ext.apply({store:this.store}, this.loadMask));
+        }
+*/
+    }
+});
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.PagingToolbar.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.PagingToolbar.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.PagingToolbar.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,146 @@
+/** 
+ * Ext PagingToolbar Override
+ * 
+ * @author Michael LeComte, michael.lecomte@xxxxxxxxxxxx 
+ * @copyright (c) 2008 
+ * @date August 28, 2008 
+ * 
+ * @class Ext.PagingToolbar
+ * 
+ * Override to configure whether or not refresh button is included in paging toolbar.
+ */
+Ext.override(Ext.PagingToolbar, {
+
+    /**
+     * @cfg {Boolean} hideRefresh
+     * True to hide the refresh button (defaults to false)
+     */
+
+    // private
+    onRender : function(ct, position){
+        Ext.PagingToolbar.superclass.onRender.call(this, ct, position);
+        this.first = this.addButton({
+            tooltip: this.firstText,
+            iconCls: "x-tbar-page-first",
+            disabled: true,
+            handler: this.onClick.createDelegate(this, ["first"])
+        });
+        this.prev = this.addButton({
+            tooltip: this.prevText,
+            iconCls: "x-tbar-page-prev",
+            disabled: true,
+            handler: this.onClick.createDelegate(this, ["prev"])
+        });
+        this.addSeparator();
+        this.add(this.beforePageText);
+        this.field = Ext.get(this.addDom({
+           tag: "input",
+           type: "text",
+           size: "3",
+           value: "1",
+           cls: "x-tbar-page-number"
+        }).el);
+        this.field.on("keydown", this.onPagingKeydown, this);
+        this.field.on("focus", function(){this.dom.select();});
+        this.afterTextEl = this.addText(String.format(this.afterPageText, 1));
+        this.field.setHeight(18);
+        this.addSeparator();
+        this.next = this.addButton({
+            tooltip: this.nextText,
+            iconCls: "x-tbar-page-next",
+            disabled: true,
+            handler: this.onClick.createDelegate(this, ["next"])
+        });
+        this.last = this.addButton({
+            tooltip: this.lastText,
+            iconCls: "x-tbar-page-last",
+            disabled: true,
+            handler: this.onClick.createDelegate(this, ["last"])
+        });
+        this.addSeparator();
+//modification begin
+        if(!this.hideRefresh){
+            this.loading = this.addButton({
+                tooltip: this.refreshText,
+                iconCls: "x-tbar-loading",
+                handler: this.onClick.createDelegate(this, ["refresh"])
+            });
+        }        
+//modification end
+        if(this.displayInfo){
+            this.displayEl = Ext.fly(this.el.dom).createChild({cls:'x-paging-info'});
+        }
+        if(this.dsLoaded){
+            this.onLoad.apply(this, this.dsLoaded);
+        }
+    }
+});
+
+
+
+/** 
+ * Ext PagingToolbar Override
+ * 
+ * @author Michael LeComte, michael.lecomte@xxxxxxxxxxxx 
+ * @copyright (c) 2008 
+ * @date Sept 5, 2008 
+ * 
+ * @class Ext.PagingToolbar
+ * 
+ * Override to configure whether or not refresh button is included in paging toolbar.
+ */
+
+
+Ext.override(Ext.PagingToolbar, {
+
+    /**
+     * @cfg {Boolean} pageFit
+     * True to adjust the pageSize according to the grid panel's display area so 
+     * that each page contains the number of records that fit the height of the panel
+     * without displaying vertical scroll bars (defaults to false)
+     */
+
+    //add to existing function
+    beforeLoad: Ext.PagingToolbar.prototype.beforeLoad.createSequence(function () {
+        if (this.pageFit) {
+            this.setPageSize();
+        }
+    }),
+
+    /**
+     * {Function} setBotValue Sets the random equation and corresponding solution.
+     */
+    setPageSize: function() {
+        //console.dir(this);
+  //look at liveGrid for how to do this properly       
+/*        
+        var body = this.ownerCt.body;//includes header row
+        var bodyHeight =   body.getHeight();
+        var headerId =     body.dom.firstChild.id;
+        var headerHeight = Ext.get(headerId).getComputedHeight();
+        var headerHeight2 = Ext.get(headerId).getHeight();
+        var headerHeight3 = Ext.get(headerId).getHeight(false);
+
+        /**
+         *  Height of a row in the grid. it's usually around 20px, but can depend on images
+         *  or other elements making it larger.
+         */
+/*
+        var rowId =     body.dom.lastChild.id;
+        var rowHeight = Ext.get(rowId).getComputedHeight();
+        var rowHeight2 = Ext.get(rowId).getHeight();
+        var rowHeight3 = Ext.get(rowId).getHeight(false);
+        
+        // Number of rows = bodyHeight minus header row height divided by RowHeight
+      //  var rowSize = parseInt( (bodyHeight - headerHeight)/ rowHeight);
+        var rowSize = Math.ceil( (bodyHeight - headerHeight)/ rowHeight);
+        
+        if (rowSize) {
+            this.pageSize = rowSize;
+        }
+        
+        
+        var test = 'something';
+*/        
+    }
+});
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.WindowGroup.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.WindowGroup.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.WindowGroup.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,13 @@
+/** 
+ * Ext.WindowGroup Override
+ * With this implementation, an Ext.Window would accept an additional config option,
+ * alwaysOnTop, to have a window thats always on top, but not necessarily modal.
+ * This takes into account both the alwaysOnTop config option and
+ * lastAccess in the case of multiple alwaysOnTop windows
+ * @class Ext.WindowGroup
+ */
+Ext.WindowGroup.prototype.sortWindows = function(d1, d2){
+    if( !d1.alwaysOnTop && d2.alwaysOnTop ){ return -1; }
+    if( d1.alwaysOnTop && !d2.alwaysOnTop ){ return  1; }
+    return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
+};
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.GroupingStore.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.GroupingStore.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.GroupingStore.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,28 @@
+/** 
+ * Ext GroupingStore Override
+ * 
+ * @author Michael LeComte, michael.lecomte@xxxxxxxxxxxx 
+ * @copyright (c) 2008 
+ * @date August 18, 2008 
+ * 
+ * @class Ext.data.GroupingStore
+ * @extends Ext.data.Store
+ * Override for GroupingStore applySort method.
+ * if sortInfo is not specifies causes error in applySort()
+ */ 
+ 
+Ext.override(Ext.data.GroupingStore, {
+    applySort : function(){
+        Ext.data.GroupingStore.superclass.applySort.call(this);
+        if(!this.groupOnSort && !this.remoteGroup){
+            var gs = this.getGroupState();
+//new
+            var si = this.sortInfo || {};
+//change
+            if(gs && gs != si.field){
+//            if(gs && gs != this.sortInfo.field){
+                this.sortData(this.groupField);
+            }
+        }
+    }
+});
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.JsonReader.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.JsonReader.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.JsonReader.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,110 @@
+/** 
+ * Ext JSON Reader Override
+ * 
+ * @author Michael LeComte, michael.lecomte@xxxxxxxxxxxx 
+ * @copyright (c) 2008 
+ * @date August 5, 2008 
+ * 
+ * @class Ext.data.JsonReader
+ * @extends Ext.data.DataReader
+ * Override for JsonReader readRecords method.
+ * readRecords assumes the root is an array.  This is an override to ensure
+ * that the root property in the incoming datapacket is an array.
+ */ 
+ 
+Ext.override(Ext.data.JsonReader, {
+    /**
+     * Create a data block containing Ext.data.Records from a JSON object.
+     * @param {Object} o An object which contains an Array of row objects in the property specified
+     * in the config as 'root, and optionally a property, specified in the config as 'totalProperty'
+     * which contains the total size of the dataset.
+     * @return {Object} data A data block which is used by an Ext.data.Store object as
+     * a cache of Ext.data.Records.
+     */
+    readRecords : function(o){
+        /**
+         * After any data loads, the raw JSON data is available for further custom processing.  If no data is
+         * loaded or there is a load exception this property will be undefined.
+         * @type Object
+         */
+        this.jsonData = o;
+        if(o.metaData){
+            delete this.ef;
+            this.meta = o.metaData;
+            this.recordType = Ext.data.Record.create(o.metaData.fields);
+            this.onMetaChange(this.meta, this.recordType, o);
+        }
+        var s = this.meta, Record = this.recordType,
+            f = Record.prototype.fields, fi = f.items, fl = f.length;
+
+//      Generate extraction functions for the totalProperty, the root, the id, and for each field
+        if (!this.ef) {
+            if(s.totalProperty) {
+	            this.getTotal = this.getJsonAccessor(s.totalProperty);
+	        }
+	        if(s.successProperty) {
+	            this.getSuccess = this.getJsonAccessor(s.successProperty);
+	        }
+            //original
+	        this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
+            //doug
+            //this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){ return [].concat(p); } ;
+            //animal
+            //this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return Ext.isArray(p) ? p : [ p ];};
+	        if (s.id) {
+	        	var g = this.getJsonAccessor(s.id);
+	        	this.getId = function(rec) {
+	        		var r = g(rec);
+		        	return (r === undefined || r === "") ? null : r;
+	        	};
+	        } else {
+	        	this.getId = function(){return null;};
+	        }
+            this.ef = [];
+            for(var i = 0; i < fl; i++){
+                f = fi[i];
+                var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
+                this.ef[i] = this.getJsonAccessor(map);
+            }
+        }
+//    	var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
+/*modification*/
+/**/
+    	var root = this.getRoot(o) || [];
+        root = Ext.isArray(root) ?  root : [root];//ensure the root is an array
+        var c = root.length, totalRecords = c, success = true;
+/**/
+/*modification*/        
+    	if(s.totalProperty){
+            var v = parseInt(this.getTotal(o), 10);
+            if(!isNaN(v)){
+                totalRecords = v;
+            }
+        }
+        if(s.successProperty){
+            var v = this.getSuccess(o);
+            if(v === false || v === 'false'){
+                success = false;
+            }
+        }
+        var records = [];
+	    for(var i = 0; i < c; i++){
+		    var n = root[i];
+	        var values = {};
+	        var id = this.getId(n);
+	        for(var j = 0; j < fl; j++){
+	            f = fi[j];
+                var v = this.ef[j](n);
+                values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, n);
+	        }
+	        var record = new Record(values, id);
+	        record.json = n;
+	        records[i] = record;
+	    }
+	    return {
+	        success : success,
+	        records : records,
+	        totalRecords : totalRecords
+	    };
+    }
+});
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.Store.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.Store.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.data.Store.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,28 @@
+/** 
+ * Ext data Store Override
+ * 
+ * @author Michael LeComte, michael.lecomte@xxxxxxxxxxxx 
+ * @copyright (c) 2008 
+ * @date August 24, 2008 
+ * 
+ * @class Ext.data.Store
+ * 
+ * If you insert records then try to filter the store (including the new inserted
+ * records the new records are not included in the mixed collection yet).
+ */
+
+Ext.override(Ext.data.Store, {
+    insert : function(index, records){
+        records = [].concat(records);
+        for(var i = 0, len = records.length; i < len; i++){
+            this.data.insert(index, records[i]);
+            records[i].join(this);
+        }
+//alteration begin
+        if(this.snapshot){
+            this.snapshot.addAll(records);
+        }
+//alteration end
+        this.fireEvent("add", this, records, index);
+    }
+});
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.Action.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.Action.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.Action.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,37 @@
+/** 
+ * Ext form ErrorReader Override
+ * 
+ * @author Michael LeComte, michael.lecomte@xxxxxxxxxxxx 
+ * @copyright (c) 2008 
+ * @date August 5, 2008 
+ * 
+ * @class Ext.form.Action
+ * @extends Ext.BoxComponent
+ * 
+ * Allow configuration of successProperty and errorsProperty.
+ */
+
+// A reusable error reader class for XML forms
+Ext.form.XmlErrorReader = function(){
+    Ext.form.XmlErrorReader.superclass.constructor.call(this, {
+            record : 'field',
+            success: '@success'
+        }, [
+            'id', 'msg'
+        ]
+    );
+};
+Ext.extend(Ext.form.XmlErrorReader, Ext.data.XmlReader);
+
+// A reusable form error reader class for custom JSON data packets
+Ext.form.JsonErrorReader = function(){
+    Ext.form.JsonErrorReader.superclass.constructor.call(this, {
+            successProperty: 'message.success',
+            root : 'message.errors'
+        }, [
+            'id', 
+            {name: 'msg', mapping: 'message'}
+        ]
+    );
+};
+Ext.extend(Ext.form.JsonErrorReader, Ext.data.JsonReader);
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.ErrorReader.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.ErrorReader.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.ErrorReader.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,37 @@
+/** 
+ * Ext form ErrorReader Override
+ * 
+ * @author Michael LeComte, michael.lecomte@xxxxxxxxxxxx 
+ * @copyright (c) 2008 
+ * @date August 5, 2008 
+ * 
+ * @class Ext.form.Action
+ * @extends Ext.BoxComponent
+ * 
+ * Allow configuration of successProperty and errorsProperty.
+ */
+
+// A reusable error reader class for XML forms
+Ext.form.XmlErrorReader = function(){
+    Ext.form.XmlErrorReader.superclass.constructor.call(this, {
+            record : 'field',
+            success: '@success'
+        }, [
+            'id', 'msg'
+        ]
+    );
+};
+Ext.extend(Ext.form.XmlErrorReader, Ext.data.XmlReader);
+
+// A reusable form error reader class for custom JSON data packets
+Ext.form.JsonErrorReader = function(){
+    Ext.form.JsonErrorReader.superclass.constructor.call(this, {
+            successProperty: 'message.success',
+            root : 'message.errors'
+        }, [
+            'id', 
+            {name: 'msg', mapping: 'message'}
+        ]
+    );
+};
+Ext.extend(Ext.form.JsonErrorReader, Ext.data.JsonReader);
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.Field.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.Field.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.Field.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,46 @@
+/** 
+ * Ext form Field Override
+ * 
+ * @author Michael LeComte 
+ * @copyright (c) 2008 
+ * @date August 5, 2008 
+ * 
+ * @class Ext.form.Field
+ * @extends Ext.BoxComponent
+ * Tooltips on form fields
+ * By default you cannot have tooltips on form fields 
+ * This is because by default tooltips are used to display validation messages.
+ * To override this and use tooltips to display user help you first need to 
+ * override the default onRender action for form fields as follows
+ * http://www.rowlands-bcs.com/?q=node/11
+ */
+Ext.override(Ext.form.Field, {
+    afterRender: Ext.form.Field.prototype.afterRender.createSequence(function(){ // My code
+        var qt = this.qtip; // or this.qtipText,
+        if (qt) { // or this.qtipText,
+/*
+            Ext.apply(Ext.QuickTips.getQuickTip(), {
+                //dismissDelay: 5000, //default = 5000 (use 0 to hide immediately) 
+                //hideDelay: 200, //default = 200
+                maxWidth: 200,
+                minWidth: 100,
+                showDelay: 50, //default = 500
+                trackMouse: true
+            });
+*/
+            Ext.QuickTips.register({
+                //autoHide
+                //cls
+                //dismissDelay (overrides the singleton value)
+                //maxWidth
+                target: this.getEl(), //required // or this.getEl(),
+                title: qt.title,
+                text: qt.text,//qt, //required 
+                enabled: true,
+                showDelay: 0,
+                //trackMouse
+                width: qt.width || 100
+            });
+        }
+    })
+});
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.VTypes.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.VTypes.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.form.VTypes.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,23 @@
+/** 
+ * Ext form VType Overrides
+ * 
+ * @author Michael LeComte 
+ * @copyright (c) 2008 
+ * @date August 5, 2008 
+ * 
+ * @class Ext.form.VTypes
+ * 
+ * Custom validation types.
+ */
+
+// Add password vtype
+Ext.apply(Ext.form.VTypes, {
+    password: function(val, field) {
+        if (field.initialPassField) {
+            var pwd = Ext.getCmp(field.initialPassField);
+            return (val == pwd.getValue());
+        }
+        return true;
+    }, 
+    passwordText: 'Passwords do not match'
+});
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.grid.ColumnModel.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.grid.ColumnModel.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.grid.ColumnModel.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,227 @@
+/** 
+ * Ext grid ColumnModel Override
+ * 
+ * @author Michael LeComte, michael.lecomte@xxxxxxxxxxxx 
+ * @copyright (c) 2008 
+ * @date August 7, 2008 
+ * 
+ * @class Ext.grid.ColumnModel
+ * @extends Ext.util.Observable
+ * 
+ * Provide callback function to control if cell is editable.
+ */
+
+Ext.override(Ext.grid.ColumnModel, {
+
+    /**
+     * Add method to retrieve columns by visibility 
+     * Returns an array of column config objects for the visibility given.
+     * @param {Boolean} hidden True returns visible columns; False returns hidden columns (defaults to True).
+     * @param {String} cfg Specify the config property to return (defaults to the config).
+     * @return {Array} result
+     */
+    getColumnsVisible : function(visibility, cfg){
+        var visible = (visibility === false) ? false : true;
+        var r = [];
+        for(var i = 0, len = this.config.length; i < len; i++){
+            var c = this.config[i];
+            var hidden = c.hidden ? true : false;
+            if(hidden !== visible){
+                r[r.length] = c[cfg] || c;
+            }
+        }
+        return r;
+    },  
+
+    /**
+     * Returns true if the cell is editable. A custom function may be specified to enable or disable editing.
+     * @param {Number} colIndex The column index
+     * @param {Number} rowIndex The row index
+     * @param {Object} grid The grid
+     * @return {Boolean}
+     */
+    isCellEditable : function(colIndex, rowIndex, grid){
+//    isCellEditable : function(colIndex, rowIndex){
+/*change begin*/        
+        if (typeof this.config[colIndex].enableEditor == "function") {
+
+            var field = this.getDataIndex(colIndex);
+
+            var selModel = grid.getSelectionModel();
+            var record = selModel.selection.record;
+            var dataIndex = this.getDataIndex(colIndex);
+            var cellValue = record.data[this.getDataIndex(colIndex)];
+
+            var result = this.config[colIndex].enableEditor(cellValue, colIndex, rowIndex, selModel, record, grid);
+            if (true !== result) {
+                //this.fireEvent('editDenied', this);
+                return false;
+            }
+            return true;
+        }
+/*change end*/        
+
+        return (this.config[colIndex].editable || (typeof this.config[colIndex].editable == "undefined" && this.config[colIndex].editor)) ? true : false;
+    },
+/*change begin*/        
+
+    /*
+     * @cfg {Function} enableEditor A custom function that will be called before the editor is activated (defaults to null).
+     * If available, this function will be called and expected to return boolean true if the editor should be activated or false if the editor should be disabled.
+     * <p>The funtion will be called with the following parameters:
+     * <div class="mdetail-params"><ul>
+     * <li><b>cellValue</b> : String<p class="sub-desc">current field value</p></li>
+     * <li><b>colIndex</b> : Number<p class="sub-desc">The column index</p></li>
+     * <li><b>rowIndex</b> : Number<p class="sub-desc">The row index</p></li>
+     * <li><b>selModel</b> : Object<p class="sub-desc">The grid's selection model</p></li>
+     * <li><b>record</b> : Object<p class="sub-desc">Ext.data.Record[]</p></li>
+     * <li><b>grid</b> : Object<p class="sub-desc">The grid</p></li>
+     * </ul></div></p>
+     */
+    enableEditor : null
+/*change end*/        
+     
+});
+
+Ext.override(Ext.grid.EditorGridPanel, {
+    startEditing : function(row, col){
+
+        this.stopEditing();
+/*change begin*/        
+//        if(this.colModel.isCellEditable(col, row)){
+        if(this.colModel.isCellEditable(col, row, this)){
+/*change end*/        
+            this.view.ensureVisible(row, col, true);
+            var r = this.store.getAt(row);
+            var field = this.colModel.getDataIndex(col);
+            var e = {
+                grid: this,
+                record: r,
+                field: field,
+                value: r.data[field],
+                row: row,
+                column: col,
+                cancel:false
+            };
+            if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
+                this.editing = true;
+                var ed = this.colModel.getCellEditor(col, row);
+                if(!ed.rendered){
+                    ed.render(this.view.getEditorParent(ed));
+                }
+                (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);
+                    this.activeEditor = ed;
+                    var v = this.preEditValue(r, field);
+                    ed.startEdit(this.view.getCell(row, col).firstChild, v);
+                }).defer(50, this);
+            }
+        }
+    }
+});
+
+Ext.override(Ext.grid.CellSelectionModel, {
+/*change begin*/
+    //normalize selection models getSelected() method        
+    getSelected: Ext.grid.CellSelectionModel.prototype.getSelectedCell,
+/*change end*/        
+    
+    acceptsNav: function(row, col, cm){
+/*change begin*/        
+        //return !cm.isHidden(col) && cm.isCellEditable(col, row);
+        return !cm.isHidden(col) && cm.isCellEditable(col, row, this.grid);
+/*change end*/        
+    }
+});
+
+
+/*
+// does the same as:
+
+Ext.grid.ColumnModel.superclass.getColumnsVisible = function(visibility, cfg){
+        var visible = (visibility === false) ? false : true;
+        var r = [];
+        for(var i = 0, len = this.config.length; i < len; i++){
+            var c = this.config[i];
+            var hidden = c.hidden ? true : false;
+            if(hidden !== visible){
+                r[r.length] = c[cfg] || c;
+            }
+        }
+        return r;
+};
+*/
+
+/** 
+ * Ext grid ColumnModel Override
+ * 
+ * @author Michael LeComte, michael.lecomte@xxxxxxxxxxxx 
+ * @copyright (c) 2008 
+ * @date August 23, 2008 
+ * 
+ * @class Ext.grid.ColumnModel
+ * Override for grid ColumnModel to control individual column movement.
+ */ 
+ 
+Ext.override(Ext.grid.ColumnModel, {
+    /**
+     * @cfg {Boolean} movable (optional) Specify as <tt>false</tt> to prevent the user from moving this column
+     * (defaults to true).  To disallow column moving globally for all columns in the grid, use
+     * {@link Ext.grid.GridPanel#enableColumnMove} instead.
+     */
+
+     moveColumn : function(oldIndex, newIndex){
+        if (this.isMovable(oldIndex)){
+           var c = this.config[oldIndex];
+           this.config.splice(oldIndex, 1);
+           this.config.splice(newIndex, 0, c);
+           this.dataMap = null;
+           this.fireEvent("columnmoved", this, oldIndex, newIndex);
+       }
+    },
+    isMovable: function(col){
+        if(typeof this.config[col].movable == "undefined"){
+            return this.enableColumnMove || true;
+        }
+        return this.config[col].movable;
+    }
+
+});
+
+/*
+
+// example of usage
+ 
+    // create the Grid
+    var grid = new Ext.grid.GridPanel({
+        columns: [
+            {id:'company',header: "Company", width: 160, sortable: true, dataIndex: 'company'},
+            {header: "Price", width: 75, sortable: true, movable: false, renderer: 'usMoney', dataIndex: 'price'}
+        ],
+    });
+
+    grid.on({
+        render:{
+            fn: function(){
+                store.loadData(myData);
+            }
+        }
+    });
+
+    var gridView = grid.getView();
+
+    grid.on({
+        viewready:{
+            fn: function(){
+                console.info('viewReady fired');
+                grid.getSelectionModel().selectFirstRow();
+            }
+        }
+    });
+    
+});
+*/
\ No newline at end of file

Added: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.grid.filter.DateFilter.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.grid.filter.DateFilter.js	                        (rev 0)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/overrides/Ext.grid.filter.DateFilter.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -0,0 +1,34 @@
+/**
+ * @author Michael
+ */
+//filter works fine when all rows of the date column in a grid has a valid date value but errors out when it contains empty string
+//http://extjs.com/forum/showthread.php?p=219499#post219499
+Ext.override(Ext.grid.filter.DateFilter, {
+	validateRecord: function(record) {
+		var val = record.get(this.dataIndex);
+		val = Ext.isDate(val) ? val.clearTime(true).getTime() : null;
+		if(this.dates.on.checked && val != this.getFieldValue('on').clearTime(true).getTime()) {
+			return false;
+		}
+		if(this.dates.before.checked && val >= this.getFieldValue('before').clearTime(true).getTime()) {
+			return false;
+		}
+		if(this.dates.after.checked && val <= this.getFieldValue('after').clearTime(true).getTime()) {
+			return false;
+		}
+		return true;
+	}
+});
+
+//clear check box selection in the filter 
+//http://extjs.com/forum/showthread.php?p=219580#post219580
+Ext.override(Ext.grid.filter.DateFilter, {
+	setActive: function(active, suppressEvent) {
+		if (this.active && !active) {
+			this.dates.on.setChecked(false, true);
+			this.dates.before.setChecked(false, true);
+			this.dates.after.setChecked(false, true);
+		}
+		Ext.grid.filter.DateFilter.superclass.setActive.call(this, active, suppressEvent);
+	}
+});
\ No newline at end of file

Modified: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/ActiveApps.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/ActiveApps.js	2008-12-07 07:39:01 UTC (rev 54)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/ActiveApps.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -68,8 +68,10 @@
         this.addButton(btn);
         this.doLayout();
         m.animateTarget = btn.el;
-        //when the module is destroyed we'll go ahead and remove this button
-        m.on('destroy', this.removeButton.createDelegate(this, [btn]));
+
+        // add listener to module destruction so we can remove this button as well
+        // use the containers remove method
+        m.on('destroy', this.remove.createDelegate(this, [btn]));
         m.show();
     },
 

Modified: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/Appbar.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/Appbar.js	2008-12-07 07:39:01 UTC (rev 54)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/Appbar.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -26,7 +26,10 @@
      * @param {String} l launch menu type
      */
     initButtons: function (l) {
-        var qItems = this.app.getLaunchers(l);        
+
+        //get the modules that are registered for this menu type
+        var qItems = Ext.ux.ModuleMgr.filterType(l);
+       
         if(qItems){
             var btns = [];
             var b = {};  
@@ -39,14 +42,6 @@
             })
         }
         return btns;
-    },
-    
-    /**
-     * Destroys the button
-     * @param {Object} btn The button to remove
-     */
-    removeButton: function (btn) {
-        btn.destroy();
-    }
+    }    
 });
 Ext.reg('appbar', Ext.ux.Appbar);
\ No newline at end of file

Modified: mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/TaskBar.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/TaskBar.js	2008-12-07 07:39:01 UTC (rev 54)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/js/toolbar/TaskBar.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -12,13 +12,9 @@
     collapsible: true,
     
     /**
-     * @cfg {Integer} Start button width, defaults to 93.
+     * @cfg {Integer} Initial Start Bbutton width, defaults to 93 (width later adjusted to fit the button).
      */
     sbWidth: 93,
-    //TODO: adjust the width depending on the content inside?
-    //could do this for each area actually (start button, quick start, system tray)
-    //to maximize area for active applications area of task bar.
-    //var width = Ext.get('ux-startbutton').getWidth()+10;
     
     /**
      * @cfg {Integer} System tray starting width, defaults to 60.
@@ -97,8 +93,9 @@
         // ------------------
         
         // Start Button Panel
-        var startItems = this.app.getLaunchers('start');
-        
+        // get startItems for startMenu
+        var startItems = Ext.ux.ModuleMgr.filterType('start');
+
         /**
          * Reference to the start menu
          * @type Object
@@ -120,9 +117,15 @@
             id: 'ux-startbutton',
             iconCls: 'start',
             menu: this.startMenu,
-            menuAlign: 'bl-tl',
+            menuAlign: 'bl-tl', // this should change depending on the region for the taskbar (north/south)
             listeners: {
                 render: {
+                    /**
+                     * Adjust the width depending on the content inside
+                     * TODO:
+                     * could do this for each area actually (start button, quick start, system tray)
+                     * to maximize area for active applications area of task bar.
+                     */
                     fn: function () {
                         //adjust the width of the container for this button
                         var width = this.startBtn.getWidth()+5;
@@ -132,8 +135,7 @@
                     scope: this
                 }
             },
-            clickEvent: 'mousedown'//,
-            //template: new Ext.Template('<table border="0" cellpadding="0" cellspacing="0" class="x-btn-wrap"><tbody><tr>', '<td class="x-btn-left"><i>&#160;</i></td>', '<td class="x-btn-center">', '<em unselectable="on"><button class="x-btn-text" type="{1}" style="height:30px;">{0}</button></em></td>', '<td class="x-btn-right"><i>&#160;</i></td>', "</tr></tbody></table>")
+            clickEvent: 'mousedown'
         });
         
         var tbStart = {

Modified: mickael/trunk/ext/v3.0.0-a1/learn/desktop/preload.js
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/preload.js	2008-12-07 07:39:01 UTC (rev 54)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/preload.js	2008-12-09 04:02:36 UTC (rev 55)
@@ -69,7 +69,7 @@
 		    //A typical module config object will have a form something like this:
 
 		    // id (required), must be unique for entire app
-		    id: 'layoutwin',
+		    moduleId: 'layoutwin',
             
             // description will be displayed with the taskbutton tooltip
             // notice how each launcher has a configurable tooltip display (see tooltipTpl also) 
@@ -114,7 +114,7 @@
                 // across modules instead of the current random filename used.
 	            iconCls: 'layoutwin-icon',
 	            text: 'Layout Window',
-	            tooltip: '<b>Layout Window</b><br />A window with a layout'
+	            tooltip: '<b>Layout Window</b><br />A window with a layout (default tooltip)'
 	        },
 
 	        // launchers: an array of launcher config objects or just the name of the menu type
@@ -138,7 +138,7 @@
 	                type: 'shortcut',
 	                iconCls: 'layoutwin-shortcut',//notice different iconCls for shortcut
 	                text: 'Layout Window',
-    	            tooltip: '<b>Layout Window</b><br />A window with a layout'
+    	            tooltip: '<b>Layout Window</b><br />A window with a layout (shortcut tooltip)'
 	            },
 
 		        // To add this module to the Start Menu, specify one of the following:

Modified: mickael/trunk/ext/v3.0.0-a1/learn/desktop/resources/css/desktop.css
===================================================================
--- mickael/trunk/ext/v3.0.0-a1/learn/desktop/resources/css/desktop.css	2008-12-07 07:39:01 UTC (rev 54)
+++ mickael/trunk/ext/v3.0.0-a1/learn/desktop/resources/css/desktop.css	2008-12-09 04:02:36 UTC (rev 55)
@@ -30,32 +30,6 @@
 /*	padding:2px;*/
 }
 
-/* We must hidde new container top & bottom for all taskbar button to avoide one pixel show on top and bottom */
-#ux-taskbuttons-panel .x-btn-tl,
-#ux-taskbuttons-panel .x-btn-tc,
-#ux-taskbuttons-panel .x-btn-tr,
-#ux-taskbuttons-panel .x-btn-bl,
-#ux-taskbuttons-panel .x-btn-bc,
-#ux-taskbuttons-panel .x-btn-br,
-
-#ux-quickstart-panel .x-btn-tl,
-#ux-quickstart-panel .x-btn-tc,
-#ux-quickstart-panel .x-btn-tr,
-#ux-quickstart-panel .x-btn-bl,
-#ux-quickstart-panel .x-btn-bc,
-#ux-quickstart-panel .x-btn-br,
-
-#ux-systemtray-panel .x-btn-tl,
-#ux-systemtray-panel .x-btn-tc,
-#ux-systemtray-panel .x-btn-tr,
-#ux-systemtray-panel .x-btn-bl,
-#ux-systemtray-panel .x-btn-bc,
-#ux-systemtray-panel .x-btn-br {
-  visibility: hidden;
-}
-
-
-
 /*
  * This one is used to help cover up the vertical line in a menu that
  * would otherwise run through any text in the context menu.
@@ -235,7 +209,6 @@
 #ux-taskbuttons-panel .x-btn-mc{
 	background-position:0 -56px;
 }
-
 #ux-taskbuttons-panel .x-btn-over .x-btn-ml{
 	background-position:0 -252px;
 }
@@ -245,7 +218,6 @@
 #ux-taskbuttons-panel .x-btn-over .x-btn-mc{
 	background-position:0 -308px;
 }
-
 #ux-taskbuttons-panel .x-btn-click .x-btn-ml{
 	background-position:0 -168px;
 }
@@ -255,18 +227,18 @@
 #ux-taskbuttons-panel .x-btn-click .x-btn-mc{
 	background-position:0 -224px;
 }
-
-#ux-taskbuttons-panel .x-btn-pressed .x-btn-ml{
+#ux-taskbuttons-panel .active-win .x-btn-ml{
 	background-position:0 -84px;
 }
-#ux-taskbuttons-panel .x-btn-pressed  .x-btn-mr{
+#ux-taskbuttons-panel .active-win  .x-btn-mr{
 	background-position:0 -112px;
 }
-#ux-taskbuttons-panel .x-btn-pressed .x-btn-mc{
+#ux-taskbuttons-panel .active-win .x-btn-mc{
 	background-position:0 -140px;
 }
-#ux-taskbuttons-panel .x-btn-pressed .x-btn-mc button {
-    color:#fff;
+/*#ux-taskbuttons-panel .active-win .x-btn-mc button {*/
+#ux-taskbuttons-panel .active-win .x-btn-mc button {
+    color:red;/*#fff;*/
 }
 /* end: taskbutton */
 
@@ -666,16 +638,16 @@
 #ux-taskbar-start .x-btn-click .x-btn-mc{
 	background-position:0 -240px;
 }
-#ux-taskbar-start .x-btn-pressed .x-btn-ml{
+#ux-taskbar-start .active-win .x-btn-ml{
 	background-position:0 -90px;
 }
-#ux-taskbar-start .x-btn-pressed  .x-btn-mr{
+#ux-taskbar-start .active-win  .x-btn-mr{
 	background:url(../images/default/taskbar/startbutton.gif) no-repeat 0 -120px;
 }
-#ux-taskbar-start .x-btn-pressed .x-btn-mc{
+#ux-taskbar-start .active-win .x-btn-mc{
 	background:url(../images/default/taskbar/startbutton.gif) repeat-x 0 -150px;
 }
-#ux-taskbar-start .x-btn-pressed .x-btn-mc button {
+#ux-taskbar-start .active-win .x-btn-mc button {
     color:#fff;
 }
 #ux-taskbar-start .x-btn-text-icon .x-btn-with-menu .x-btn-mc em {
@@ -685,8 +657,8 @@
 }
 /* End: startbutton */
 
-/* Begin QuickStart /SYstemTray button */
-#ux-quickstart-panel .x-btn-icon .x-btn-mc .x-btn-text, #ux-systemtray-panel .x-btn-icon .x-btn-mc .x-btn-text {
+/* Begin QuickStart button */
+#ux-quickstart-panel .x-btn-icon .x-btn-mc .x-btn-text{
 	background-position: center;
 	background-repeat: no-repeat;
 	height: 16px;
@@ -695,28 +667,28 @@
 	white-space: nowrap;
     padding:0;
 }
-#ux-quickstart-panel .x-btn-ml, #ux-systemtray-panel .x-btn-ml {
+#ux-quickstart-panel .x-btn-ml, #ux-quickstart-panel .x-btn-mr{
 	font-size:1px;
     line-height:1px;
 }
-#ux-quickstart-panel .x-btn-ml, #ux-systemtray-panel .x-btn-ml {
+#ux-quickstart-panel .x-btn-ml{
 	width:4px;
 	height:28px;
 	background:url(../images/default/taskbar/quickstart-button.gif) no-repeat 0 0;
 }
-#ux-quickstart-panel .x-btn-mr, #ux-systemtray-panel .x-btn-mr {
+#ux-quickstart-panel .x-btn-mr{
 	width:4px;
 	height:28px;
 	background:url(../images/default/taskbar/quickstart-button.gif) no-repeat 0 -28px;
 }
-#ux-quickstart-panel .x-btn-ml i, #ux-systemtray-panel .x-btn-ml i{
+#ux-quickstart-panel .x-btn-ml i, #ux-quickstart-panel .x-btn-mr i{
 	display:block;
     width:4px;
     overflow:hidden;
     font-size:1px;
     line-height:1px;
 }
-#ux-quickstart-panel .x-btn-mc, #ux-systemtray-panel .x-btn-mc {
+#ux-quickstart-panel .x-btn-mc{
 	background:url(../images/default/taskbar/quickstart-button.gif) repeat-x 0 -56px;
 	vertical-align: middle;
 	text-align:center;
@@ -724,55 +696,43 @@
 	cursor:pointer;
 	white-space:nowrap;
 }
-#ux-quickstart-panel .x-btn-ml, #ux-systemtray-panel .x-btn-ml {
+#ux-quickstart-panel .x-btn-ml{ 
 	background-position:0 0;
 }
-#ux-quickstart-panel .x-btn-mr, #ux-systemtray-panel .x-btn-mr {
+#ux-quickstart-panel .x-btn-mr{
 	background-position:0 0;
 }
-#ux-quickstart-panel .x-btn-mc, #ux-systemtray-panel .x-btn-mc {
+#ux-quickstart-panel .x-btn-mc{
 	background-position:0 0;
 }
 #ux-quickstart-panel .x-btn-over .x-btn-ml,
-#ux-quickstart-panel .x-btn-menu-active .x-btn-ml,
-#ux-systemtray-panel .x-btn-over .x-btn-ml,
-#ux-systemtray-panel .x-btn-menu-active .x-btn-ml {
+#ux-quickstart-panel .x-btn-menu-active .x-btn-ml{
 	background-position:0 -250px;
 }
 #ux-quickstart-panel .x-btn-over  .x-btn-mr,
-#ux-quickstart-panel .x-btn-menu-active .x-btn-mr,
-#ux-systemtray-panel .x-btn-over  .x-btn-mr,
-#ux-systemtray-panel .x-btn-menu-active .x-btn-mr{
+#ux-quickstart-panel .x-btn-menu-active .x-btn-mr{
 	background-position:0 -279px;
 }
 #ux-quickstart-panel .x-btn-over .x-btn-mc,
-#ux-quickstart-panel .x-btn-menu-active .x-btn-mc,
-#ux-systemtray-panel .x-btn-over .x-btn-mc,
-#ux-systemtray-panel .x-btn-menu-active .x-btn-mc{
+#ux-quickstart-panel .x-btn-menu-active .x-btn-mc{
 	background-position:0 -308px;
 }
-#ux-quickstart-panel .x-btn-click .x-btn-ml,
-#ux-systemtray-panel .x-btn-click .x-btn-ml{
+#ux-quickstart-panel .x-btn-click .x-btn-ml{
 	background-position:0 -163px;
 }
-#ux-quickstart-panel .x-btn-click  .x-btn-mr,
-#ux-systemtray-panel .x-btn-click  .x-btn-mr{
+#ux-quickstart-panel .x-btn-click  .x-btn-mr{
 	background-position:0 -192px;
 }
-#ux-quickstart-panel .x-btn-click .x-btn-mc,
-#ux-systemtray-panel .x-btn-click .x-btn-mc{
+#ux-quickstart-panel .x-btn-click .x-btn-mc{
 	background-position:0 -221px;
 }
-#ux-quickstart-panel .x-btn-pressed .x-btn-ml,
-#ux-systemtray-panel .x-btn-pressed .x-btn-ml{
+#ux-quickstart-panel .active-win .x-btn-ml{
 	background-position:0 -84px;
 }
-#ux-quickstart-panel .x-btn-pressed  .x-btn-mr,
-#ux-systemtray-panel .x-btn-pressed  .x-btn-mr{
+#ux-quickstart-panel .active-win  .x-btn-mr{
 	background-position:0 -112px;
 }
-#ux-quickstart-panel .x-btn-pressed .x-btn-mc,
-#ux-systemtray-panel .x-btn-pressed .x-btn-mc{
+#ux-quickstart-panel .active-win .x-btn-mc{
 	background-position:0 -140px;
 }
 /* End: QuickStart button */


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/