[Commits] r1452 - in core/trunk/geoext: lib/GeoExt/data lib/GeoExt/widgets/grid tests/lib/GeoExt/widgets/grid

commits at geoext.org commits at geoext.org
Tue Nov 10 21:50:21 CET 2009


Author: elemoine
Date: 2009-11-10 21:50:21 +0100 (Tue, 10 Nov 2009)
New Revision: 1452

Modified:
   core/trunk/geoext/lib/GeoExt/data/FeatureStore.js
   core/trunk/geoext/lib/GeoExt/data/LayerStore.js
   core/trunk/geoext/lib/GeoExt/widgets/grid/FeatureSelectionModel.js
   core/trunk/geoext/tests/lib/GeoExt/widgets/grid/FeatureSelectionModel.html
Log:
fixing a bug where at most one subclass could be created using our mixins, r=ahocevar, great suggestion from ahocevar (closes #172)

Modified: core/trunk/geoext/lib/GeoExt/data/FeatureStore.js
===================================================================
--- core/trunk/geoext/lib/GeoExt/data/FeatureStore.js	2009-11-10 12:21:05 UTC (rev 1451)
+++ core/trunk/geoext/lib/GeoExt/data/FeatureStore.js	2009-11-10 20:50:21 UTC (rev 1452)
@@ -43,7 +43,7 @@
  * This class can not be instantiated directly. Instead, it is meant to extend
  * {Ext.data.Store} or a subclass of it:
  * (start code)
- * var store = new (Ext.extend(Ext.data.Store, GeoExt.data.FeatureStoreMixin))({
+ * var store = new (Ext.extend(Ext.data.Store, new GeoExt.data.FeatureStoreMixin))({
  *     layer: myLayer,
  *     features: myFeatures
  * });
@@ -59,377 +59,378 @@
  * });
  * (end)
  */
-GeoExt.data.FeatureStoreMixin = {
-    
-    /** api: config[layer]
-     *  ``OpenLayers.Layer.Vector``  Layer to synchronize the store with.
-     */
-    layer: null,
-    
-    /** api: config[features]
-     *  ``Array(OpenLayers.Feature.Vector)``  Features that will be added to the
-     *  store (and the layer if provided).
-     */
+GeoExt.data.FeatureStoreMixin = function() {
+    return {
+        /** api: config[layer]
+         *  ``OpenLayers.Layer.Vector``  Layer to synchronize the store with.
+         */
+        layer: null,
+        
+        /** api: config[features]
+         *  ``Array(OpenLayers.Feature.Vector)``  Features that will be added to the
+         *  store (and the layer if provided).
+         */
 
-    /** api: config[reader]
-     *  ``Ext.data.DataReader`` The reader used to produce records from objects
-     *  features.  Default is :class:`GeoExt.data.FeatureReader`.
-     */
-    reader: null,
+        /** api: config[reader]
+         *  ``Ext.data.DataReader`` The reader used to produce records from objects
+         *  features.  Default is :class:`GeoExt.data.FeatureReader`.
+         */
+        reader: null,
 
-    /** api: config[addFeatureFilter]
-     *  ``Function`` This function is called before a feature record is added to
-     *  the store, it receives the feature from which a feature record is to be
-     *  created, if it returns false then no record is added.
-     */
-    addFeatureFilter: null,
-    
-    /** api: config[addRecordFilter]
-     *  ``Function`` This function is called before a feature is added to the
-     *  layer, it receives the feature record associated with the feature to be
-     *  added, if it returns false then no feature is added.
-     */
-    addRecordFilter: null,
-    
-    /** api: config[initDir]
-     *  ``Number``  Bitfields specifying the direction to use for the
-     *  initial sync between the layer and the store, if set to 0 then no
-     *  initial sync is done. Default is
-     *  ``GeoExt.data.FeatureStore.LAYER_TO_STORE|GeoExt.data.FeatureStore.STORE_TO_LAYER``.
-     */
+        /** api: config[addFeatureFilter]
+         *  ``Function`` This function is called before a feature record is added to
+         *  the store, it receives the feature from which a feature record is to be
+         *  created, if it returns false then no record is added.
+         */
+        addFeatureFilter: null,
+        
+        /** api: config[addRecordFilter]
+         *  ``Function`` This function is called before a feature is added to the
+         *  layer, it receives the feature record associated with the feature to be
+         *  added, if it returns false then no feature is added.
+         */
+        addRecordFilter: null,
+        
+        /** api: config[initDir]
+         *  ``Number``  Bitfields specifying the direction to use for the
+         *  initial sync between the layer and the store, if set to 0 then no
+         *  initial sync is done. Default is
+         *  ``GeoExt.data.FeatureStore.LAYER_TO_STORE|GeoExt.data.FeatureStore.STORE_TO_LAYER``.
+         */
 
-    /** private */
-    constructor: function(config) {
-        config = config || {};
-        config.reader = config.reader ||
-                        new GeoExt.data.FeatureReader({}, config.fields);
-        var layer = config.layer;
-        delete config.layer;
-        // 'features' option - is an alias 'data' option
-        if (config.features) {
-            config.data = config.features;
-        }
-        delete config.features;
-        // "initDir" option
-        var options = {initDir: config.initDir};
-        delete config.initDir;
-        arguments.callee.superclass.constructor.call(this, config);
-        if(layer) {
-            this.bind(layer, options);
-        }
-    },
+        /** private */
+        constructor: function(config) {
+            config = config || {};
+            config.reader = config.reader ||
+                            new GeoExt.data.FeatureReader({}, config.fields);
+            var layer = config.layer;
+            delete config.layer;
+            // 'features' option - is an alias 'data' option
+            if (config.features) {
+                config.data = config.features;
+            }
+            delete config.features;
+            // "initDir" option
+            var options = {initDir: config.initDir};
+            delete config.initDir;
+            arguments.callee.superclass.constructor.call(this, config);
+            if(layer) {
+                this.bind(layer, options);
+            }
+        },
 
-    /** api: method[bind]
-     *  :param layer: ``OpenLayers.Layer`` Layer that the store should be
-     *      synchronized with.
-     *  
-     *  Bind this store to a layer instance, once bound the store
-     *  is synchronized with the layer and vice-versa.
-     */ 
-    bind: function(layer, options) {
-        if(this.layer) {
-            // already bound
-            return;
-        }
-        this.layer = layer;
-        options = options || {};
+        /** api: method[bind]
+         *  :param layer: ``OpenLayers.Layer`` Layer that the store should be
+         *      synchronized with.
+         *  
+         *  Bind this store to a layer instance, once bound the store
+         *  is synchronized with the layer and vice-versa.
+         */ 
+        bind: function(layer, options) {
+            if(this.layer) {
+                // already bound
+                return;
+            }
+            this.layer = layer;
+            options = options || {};
 
-        var initDir = options.initDir;
-        if(options.initDir == undefined) {
-            initDir = GeoExt.data.FeatureStore.LAYER_TO_STORE |
-                      GeoExt.data.FeatureStore.STORE_TO_LAYER;
-        }
+            var initDir = options.initDir;
+            if(options.initDir == undefined) {
+                initDir = GeoExt.data.FeatureStore.LAYER_TO_STORE |
+                          GeoExt.data.FeatureStore.STORE_TO_LAYER;
+            }
 
-        // create a snapshot of the layer's features
-        var features = layer.features.slice(0);
+            // create a snapshot of the layer's features
+            var features = layer.features.slice(0);
 
-        if(initDir & GeoExt.data.FeatureStore.STORE_TO_LAYER) {
-            var records = this.getRange();
-            for(var i=records.length - 1; i>=0; i--) {
-                this.layer.addFeatures([records[i].get("feature")]);
+            if(initDir & GeoExt.data.FeatureStore.STORE_TO_LAYER) {
+                var records = this.getRange();
+                for(var i=records.length - 1; i>=0; i--) {
+                    this.layer.addFeatures([records[i].get("feature")]);
+                }
             }
-        }
 
-        if(initDir & GeoExt.data.FeatureStore.LAYER_TO_STORE) {
-            this.loadData(features, true /* append */);
-        }
+            if(initDir & GeoExt.data.FeatureStore.LAYER_TO_STORE) {
+                this.loadData(features, true /* append */);
+            }
 
-        layer.events.on({
-            "featuresadded": this.onFeaturesAdded,
-            "featuresremoved": this.onFeaturesRemoved,
-            "featuremodified": this.onFeatureModified,
-            scope: this
-        });
-        this.on({
-            "load": this.onLoad,
-            "clear": this.onClear,
-            "add": this.onAdd,
-            "remove": this.onRemove,
-            "update": this.onUpdate,
-            scope: this
-        });
-    },
-
-    /** api: method[unbind]
-     *  Unbind this store from the layer it is currently bound.
-     */
-    unbind: function() {
-        if(this.layer) {
-            this.layer.events.un({
+            layer.events.on({
                 "featuresadded": this.onFeaturesAdded,
                 "featuresremoved": this.onFeaturesRemoved,
                 "featuremodified": this.onFeatureModified,
                 scope: this
             });
-            this.un("load", this.onLoad, this);
-            this.un("clear", this.onClear, this);
-            this.un("add", this.onAdd, this);
-            this.un("remove", this.onRemove, this);
-            this.un("update", this.onUpdate, this);
+            this.on({
+                "load": this.onLoad,
+                "clear": this.onClear,
+                "add": this.onAdd,
+                "remove": this.onRemove,
+                "update": this.onUpdate,
+                scope: this
+            });
+        },
 
-            this.layer = null;
-        }
-    },
-   
-    /** api: method[getRecordFromFeature]
-     *  :arg feature: ``OpenLayers.Vector.Feature``
-     *  :returns: :class:`GeoExt.data.FeatureRecord` The record corresponding
-     *      to the given feature.  Returns null if no record matches.
-     *
-     *  Get the record corresponding to a feature.
-     */
-    getRecordFromFeature: function(feature) {
-        var record = null;
-        if(feature.state !== OpenLayers.State.INSERT) {
-            record = this.getById(feature.id);
-        } else {
-            var index = this.findBy(function(r) {
-                return r.get("feature") === feature;
-            });
-            if(index > -1) {
-                record = this.getAt(index);
+        /** api: method[unbind]
+         *  Unbind this store from the layer it is currently bound.
+         */
+        unbind: function() {
+            if(this.layer) {
+                this.layer.events.un({
+                    "featuresadded": this.onFeaturesAdded,
+                    "featuresremoved": this.onFeaturesRemoved,
+                    "featuremodified": this.onFeatureModified,
+                    scope: this
+                });
+                this.un("load", this.onLoad, this);
+                this.un("clear", this.onClear, this);
+                this.un("add", this.onAdd, this);
+                this.un("remove", this.onRemove, this);
+                this.un("update", this.onUpdate, this);
+
+                this.layer = null;
             }
-        }
-        return record;
-    },
-   
-    /** private: method[onFeaturesAdded]
-     *  Handler for layer featuresadded event
-     */
-    onFeaturesAdded: function(evt) {
-        if(!this._adding) {
-            var features = evt.features, toAdd = features;
-            if(typeof this.addFeatureFilter == "function") {
-                toAdd = [];
-                var i, len, feature;
-                for(var i=0, len=features.length; i<len; i++) {
+        },
+       
+        /** api: method[getRecordFromFeature]
+         *  :arg feature: ``OpenLayers.Vector.Feature``
+         *  :returns: :class:`GeoExt.data.FeatureRecord` The record corresponding
+         *      to the given feature.  Returns null if no record matches.
+         *
+         *  Get the record corresponding to a feature.
+         */
+        getRecordFromFeature: function(feature) {
+            var record = null;
+            if(feature.state !== OpenLayers.State.INSERT) {
+                record = this.getById(feature.id);
+            } else {
+                var index = this.findBy(function(r) {
+                    return r.get("feature") === feature;
+                });
+                if(index > -1) {
+                    record = this.getAt(index);
+                }
+            }
+            return record;
+        },
+       
+        /** private: method[onFeaturesAdded]
+         *  Handler for layer featuresadded event
+         */
+        onFeaturesAdded: function(evt) {
+            if(!this._adding) {
+                var features = evt.features, toAdd = features;
+                if(typeof this.addFeatureFilter == "function") {
+                    toAdd = [];
+                    var i, len, feature;
+                    for(var i=0, len=features.length; i<len; i++) {
+                        feature = features[i];
+                        if(this.addFeatureFilter(feature) !== false) {
+                            toAdd.push(feature);
+                        }
+                    }
+                }
+                // add feature records to the store, when called with
+                // append true loadData triggers an "add" event and
+                // then a "load" event
+                this._adding = true;
+                this.loadData(toAdd, true /* append */);
+                delete this._adding;
+            }
+        },
+        
+        /** private: method[onFeaturesRemoved]
+         *  Handler for layer featuresremoved event
+         */
+        onFeaturesRemoved: function(evt){
+            if(!this._removing) {
+                var features = evt.features, feature, record, i;
+                for(i=features.length - 1; i>=0; i--) {
                     feature = features[i];
-                    if(this.addFeatureFilter(feature) !== false) {
-                        toAdd.push(feature);
+                    record = this.getRecordFromFeature(feature);
+                    if(record !== undefined) {
+                        this._removing = true;
+                        this.remove(record);
+                        delete this._removing;
                     }
                 }
             }
-            // add feature records to the store, when called with
-            // append true loadData triggers an "add" event and
-            // then a "load" event
-            this._adding = true;
-            this.loadData(toAdd, true /* append */);
-            delete this._adding;
-        }
-    },
-    
-    /** private: method[onFeaturesRemoved]
-     *  Handler for layer featuresremoved event
-     */
-    onFeaturesRemoved: function(evt){
-        if(!this._removing) {
-            var features = evt.features, feature, record, i;
-            for(i=features.length - 1; i>=0; i--) {
-                feature = features[i];
-                record = this.getRecordFromFeature(feature);
+        },
+        
+        /** private: method[onFeatureModified]
+         *  Handler for layer featuremodified event
+         */
+        onFeatureModified: function(evt) {
+            if(!this._updating) {
+                var feature = evt.feature;
+                var record = this.getRecordFromFeature(feature);
                 if(record !== undefined) {
-                    this._removing = true;
-                    this.remove(record);
-                    delete this._removing;
-                }
-            }
-        }
-    },
-    
-    /** private: method[onFeatureModified]
-     *  Handler for layer featuremodified event
-     */
-    onFeatureModified: function(evt) {
-        if(!this._updating) {
-            var feature = evt.feature;
-            var record = this.getRecordFromFeature(feature);
-            if(record !== undefined) {
-                record.beginEdit();
-                attributes = feature.attributes;
-                if(attributes) {
-                    var fields = this.recordType.prototype.fields;
-                    for(var i=0, len=fields.length; i<len; i++) {
-                        var field = fields.items[i];
-                        var key = field.mapping || field.name;
-                        if(key in attributes) {
-                            record.set(field.name, field.convert(attributes[key]));
+                    record.beginEdit();
+                    attributes = feature.attributes;
+                    if(attributes) {
+                        var fields = this.recordType.prototype.fields;
+                        for(var i=0, len=fields.length; i<len; i++) {
+                            var field = fields.items[i];
+                            var key = field.mapping || field.name;
+                            if(key in attributes) {
+                                record.set(field.name, field.convert(attributes[key]));
+                            }
                         }
                     }
+                    // the calls to set below won't trigger "update"
+                    // events because we called beginEdit to start a
+                    // "transaction", "update" will be triggered by
+                    // endEdit
+                    record.set("state", feature.state);
+                    record.set("fid", feature.fid);
+                    // Ext 3.0 does not allow circular references in objects passed
+                    // to record.set
+                    record.data["feature"] = feature;
+                    this._updating = true;
+                    record.endEdit();
+                    delete this._updating;
                 }
-                // the calls to set below won't trigger "update"
-                // events because we called beginEdit to start a
-                // "transaction", "update" will be triggered by
-                // endEdit
-                record.set("state", feature.state);
-                record.set("fid", feature.fid);
-                // Ext 3.0 does not allow circular references in objects passed
-                // to record.set
-                record.data["feature"] = feature;
-                this._updating = true;
-                record.endEdit();
-                delete this._updating;
             }
-        }
-    },
+        },
 
-    /** private: method[addFeaturesToLayer]
-     *  Given an array of records add features to the layer. This
-     *  function is used by the onLoad and onAdd handlers.
-     */
-    addFeaturesToLayer: function(records) {
-        var i, len, features, record;
-        if(typeof this.addRecordFilter == "function") {
-            features = []
-            for(i=0, len=records.length; i<len; i++) {
-                record = records[i];
-                if(this.addRecordFilter(record) !== false) {
-                    features.push(record.get("feature"));
+        /** private: method[addFeaturesToLayer]
+         *  Given an array of records add features to the layer. This
+         *  function is used by the onLoad and onAdd handlers.
+         */
+        addFeaturesToLayer: function(records) {
+            var i, len, features, record;
+            if(typeof this.addRecordFilter == "function") {
+                features = []
+                for(i=0, len=records.length; i<len; i++) {
+                    record = records[i];
+                    if(this.addRecordFilter(record) !== false) {
+                        features.push(record.get("feature"));
+                    }
                 }
+            } else {
+                features = new Array((len=records.length));
+                for(i=0; i<len; i++) {
+                    features[i] = records[i].get("feature");
+                }
             }
-        } else {
-            features = new Array((len=records.length));
-            for(i=0; i<len; i++) {
-                features[i] = records[i].get("feature");
+            if(features.length > 0) {
+                this._adding = true;
+                this.layer.addFeatures(features);
+                delete this._adding;
             }
-        }
-        if(features.length > 0) {
-            this._adding = true;
-            this.layer.addFeatures(features);
-            delete this._adding;
-        }
-    },
-   
-    /** private: method[onLoad]
-     *  :param store: ``Ext.data.Store``
-     *  :param records: ``Array(Ext.data.Record)``
-     *  :param options: ``Object``
-     * 
-     *  Handler for store load event
-     */
-    onLoad: function(store, records, options) {
-        // if options.add is true an "add" event was already
-        // triggered, and onAdd already did the work of 
-        // adding the features to the layer.
-        if(!options || options.add !== true) {
+        },
+       
+        /** private: method[onLoad]
+         *  :param store: ``Ext.data.Store``
+         *  :param records: ``Array(Ext.data.Record)``
+         *  :param options: ``Object``
+         * 
+         *  Handler for store load event
+         */
+        onLoad: function(store, records, options) {
+            // if options.add is true an "add" event was already
+            // triggered, and onAdd already did the work of 
+            // adding the features to the layer.
+            if(!options || options.add !== true) {
+                this._removing = true;
+                this.layer.removeFeatures(this.layer.features);
+                delete this._removing;
+
+                this.addFeaturesToLayer(records);
+            }
+        },
+        
+        /** private: method[onClear]
+         *  :param store: ``Ext.data.Store``
+         *      
+         *  Handler for store clear event
+         */
+        onClear: function(store) {
             this._removing = true;
             this.layer.removeFeatures(this.layer.features);
             delete this._removing;
-
-            this.addFeaturesToLayer(records);
-        }
-    },
-    
-    /** private: method[onClear]
-     *  :param store: ``Ext.data.Store``
-     *      
-     *  Handler for store clear event
-     */
-    onClear: function(store) {
-        this._removing = true;
-        this.layer.removeFeatures(this.layer.features);
-        delete this._removing;
-    },
-    
-    /** private: method[onAdd]
-     *  :param store: ``Ext.data.Store``
-     *  :param records: ``Array(Ext.data.Record)``
-     *  :param index: ``Number``
-     * 
-     *  Handler for store add event
-     */
-    onAdd: function(store, records, index) {
-        if(!this._adding) {
-            // addFeaturesToLayer takes care of setting
-            // this._adding to true and deleting it
-            this.addFeaturesToLayer(records);
-        }
-    },
-    
-    /** private: method[onRemove]
-     *  :param store: ``Ext.data.Store``
-     *  :param records: ``Array(Ext.data.Record)``
-     *  :param index: ``Number``
-     *      
-     *  Handler for store remove event
-     */
-    onRemove: function(store, record, index){
-        if(!this._removing) {
-            var feature = record.get("feature");
-            if (this.layer.getFeatureById(feature.id) != null) {
-                this._removing = true;
-                this.layer.removeFeatures([record.get("feature")]);
-                delete this._removing;
+        },
+        
+        /** private: method[onAdd]
+         *  :param store: ``Ext.data.Store``
+         *  :param records: ``Array(Ext.data.Record)``
+         *  :param index: ``Number``
+         * 
+         *  Handler for store add event
+         */
+        onAdd: function(store, records, index) {
+            if(!this._adding) {
+                // addFeaturesToLayer takes care of setting
+                // this._adding to true and deleting it
+                this.addFeaturesToLayer(records);
             }
-        }
-    },
+        },
+        
+        /** private: method[onRemove]
+         *  :param store: ``Ext.data.Store``
+         *  :param records: ``Array(Ext.data.Record)``
+         *  :param index: ``Number``
+         *      
+         *  Handler for store remove event
+         */
+        onRemove: function(store, record, index){
+            if(!this._removing) {
+                var feature = record.get("feature");
+                if (this.layer.getFeatureById(feature.id) != null) {
+                    this._removing = true;
+                    this.layer.removeFeatures([record.get("feature")]);
+                    delete this._removing;
+                }
+            }
+        },
 
-    /** private: method[onUpdate]
-     *  :param store: ``Ext.data.Store``
-     *  :param record: ``Ext.data.Record``
-     *  :param operation: ``String``
-     *
-     *  Handler for update.
-     */
-    onUpdate: function(store, record, operation) {
-        if(!this._updating) {
-            /**
-              * TODO: remove this if the FeatureReader adds attributes
-              * for all fields that map to feature.attributes.
-              * In that case, it would be sufficient to check (key in feature.attributes). 
-              */
-            var defaultFields = new GeoExt.data.FeatureRecord().fields;
-            var feature = record.get("feature");
-            if(record.fields) {
-                var cont = this.layer.events.triggerEvent(
-                    "beforefeaturemodified", {feature: feature}
-                );
-                if(cont !== false) {
-                    var attributes = feature.attributes;
-                    record.fields.each(
-                        function(field) {
-                            var key = field.mapping || field.name;
-                            if (!defaultFields.containsKey(key)) {
-                                attributes[key] = record.get(field.name);
+        /** private: method[onUpdate]
+         *  :param store: ``Ext.data.Store``
+         *  :param record: ``Ext.data.Record``
+         *  :param operation: ``String``
+         *
+         *  Handler for update.
+         */
+        onUpdate: function(store, record, operation) {
+            if(!this._updating) {
+                /**
+                  * TODO: remove this if the FeatureReader adds attributes
+                  * for all fields that map to feature.attributes.
+                  * In that case, it would be sufficient to check (key in feature.attributes). 
+                  */
+                var defaultFields = new GeoExt.data.FeatureRecord().fields;
+                var feature = record.get("feature");
+                if(record.fields) {
+                    var cont = this.layer.events.triggerEvent(
+                        "beforefeaturemodified", {feature: feature}
+                    );
+                    if(cont !== false) {
+                        var attributes = feature.attributes;
+                        record.fields.each(
+                            function(field) {
+                                var key = field.mapping || field.name;
+                                if (!defaultFields.containsKey(key)) {
+                                    attributes[key] = record.get(field.name);
+                                }
                             }
+                        );
+                        this._updating = true;
+                        this.layer.events.triggerEvent(
+                            "featuremodified", {feature: feature}
+                        );
+                        delete this._updating;
+                        if (this.layer.getFeatureById(feature.id) != null) {
+                            this.layer.drawFeature(feature);
                         }
-                    );
-                    this._updating = true;
-                    this.layer.events.triggerEvent(
-                        "featuremodified", {feature: feature}
-                    );
-                    delete this._updating;
-                    if (this.layer.getFeatureById(feature.id) != null) {
-                        this.layer.drawFeature(feature);
                     }
                 }
             }
         }
-    }
+    };
 };
 
 GeoExt.data.FeatureStore = Ext.extend(
     Ext.data.Store,
-    GeoExt.data.FeatureStoreMixin
+    new GeoExt.data.FeatureStoreMixin
 );
 
 /**

Modified: core/trunk/geoext/lib/GeoExt/data/LayerStore.js
===================================================================
--- core/trunk/geoext/lib/GeoExt/data/LayerStore.js	2009-11-10 12:21:05 UTC (rev 1451)
+++ core/trunk/geoext/lib/GeoExt/data/LayerStore.js	2009-11-10 20:50:21 UTC (rev 1452)
@@ -31,7 +31,7 @@
  *
  *  .. code-block:: javascript
  *  
- *      var store = new (Ext.extend(Ext.data.Store, GeoExt.data.LayerStoreMixin))({
+ *      var store = new (Ext.extend(Ext.data.Store, new GeoExt.data.LayerStoreMixin))({
  *          map: myMap,
  *          layers: myLayers
  *      });
@@ -40,349 +40,350 @@
  *  shortcut to the ``Ext.extend`` sequence in the above code snippet.
  */
 
-GeoExt.data.LayerStoreMixin = {
+GeoExt.data.LayerStoreMixin = function() {
+    return {
+        /** api: config[map]
+         *  ``OpenLayers.Map``
+         *  Map that this store will be in sync with.
+         */
+        
+        /** api: property[map]
+         *  ``OpenLayers.Map``
+         *  Map that the store is synchronized with.
+         */
+        map: null,
+        
+        /** api: config[layers]
+         *  ``Array(OpenLayers.Layer)``
+         *  Layers that will be added to the store (and the map, depending on the
+         *  value of the ``initDir`` option.
+         */
+        
+        /** api: config[initDir]
+         *  ``Number``
+         *  Bitfields specifying the direction to use for the initial sync between
+         *  the map and the store, if set to 0 then no initial sync is done.
+         *  Defaults to ``GeoExt.data.LayerStore.MAP_TO_STORE|GeoExt.data.LayerStore.STORE_TO_MAP``
+         */
 
-    /** api: config[map]
-     *  ``OpenLayers.Map``
-     *  Map that this store will be in sync with.
-     */
-    
-    /** api: property[map]
-     *  ``OpenLayers.Map``
-     *  Map that the store is synchronized with.
-     */
-    map: null,
-    
-    /** api: config[layers]
-     *  ``Array(OpenLayers.Layer)``
-     *  Layers that will be added to the store (and the map, depending on the
-     *  value of the ``initDir`` option.
-     */
-    
-    /** api: config[initDir]
-     *  ``Number``
-     *  Bitfields specifying the direction to use for the initial sync between
-     *  the map and the store, if set to 0 then no initial sync is done.
-     *  Defaults to ``GeoExt.data.LayerStore.MAP_TO_STORE|GeoExt.data.LayerStore.STORE_TO_MAP``
-     */
+        /** api: config[fields]
+         *  ``Array``
+         *  If provided a custom layer record type with additional fields will be
+         *  used. Default fields for every layer record are `layer`
+         *  (``OpenLayers.Layer``) `title` (``String``). The value of this option is
+         *  either a field definition objects as passed to the
+         *  :meth:`GeoExt.data.LayerRecord.create` function or a
+         *  :class:`GeoExt.data.LayerRecord` constructor created using
+         *  :meth:`GeoExt.data.LayerRecord.create`.
+         */
 
-    /** api: config[fields]
-     *  ``Array``
-     *  If provided a custom layer record type with additional fields will be
-     *  used. Default fields for every layer record are `layer`
-     *  (``OpenLayers.Layer``) `title` (``String``). The value of this option is
-     *  either a field definition objects as passed to the
-     *  :meth:`GeoExt.data.LayerRecord.create` function or a
-     *  :class:`GeoExt.data.LayerRecord` constructor created using
-     *  :meth:`GeoExt.data.LayerRecord.create`.
-     */
+        /** api: config[reader]
+         *  ``Ext.data.DataReader`` The reader used to produce
+         *  :class:`GeoExt.data.LayerRecord` objects from ``OpenLayers.Layer``
+         *  objects.  If not provided, a :class:`GeoExt.data.LayerReader` will be
+         *  used.
+         */
+        reader: null,
 
-    /** api: config[reader]
-     *  ``Ext.data.DataReader`` The reader used to produce
-     *  :class:`GeoExt.data.LayerRecord` objects from ``OpenLayers.Layer``
-     *  objects.  If not provided, a :class:`GeoExt.data.LayerReader` will be
-     *  used.
-     */
-    reader: null,
+        /** private: method[constructor]
+         */
+        constructor: function(config) {
+            config = config || {};
+            config.reader = config.reader ||
+                            new GeoExt.data.LayerReader({}, config.fields);
+            delete config.fields;
+            // "map" option
+            var map = config.map instanceof GeoExt.MapPanel ?
+                      config.map.map : config.map;
+            delete config.map;
+            // "layers" option - is an alias to "data" option
+            if(config.layers) {
+                config.data = config.layers;
+            }
+            delete config.layers;
+            // "initDir" option
+            var options = {initDir: config.initDir};
+            delete config.initDir;
+            arguments.callee.superclass.constructor.call(this, config);
+            if(map) {
+                this.bind(map, options);
+            }
+        },
 
-    /** private: method[constructor]
-     */
-    constructor: function(config) {
-        config = config || {};
-        config.reader = config.reader ||
-                        new GeoExt.data.LayerReader({}, config.fields);
-        delete config.fields;
-        // "map" option
-        var map = config.map instanceof GeoExt.MapPanel ?
-                  config.map.map : config.map;
-        delete config.map;
-        // "layers" option - is an alias to "data" option
-        if(config.layers) {
-            config.data = config.layers;
-        }
-        delete config.layers;
-        // "initDir" option
-        var options = {initDir: config.initDir};
-        delete config.initDir;
-        arguments.callee.superclass.constructor.call(this, config);
-        if(map) {
-            this.bind(map, options);
-        }
-    },
+        /** private: method[bind]
+         *  :param map: ``OpenLayers.Map`` The map instance.
+         *  :param options: ``Object``
+         *  
+         *  Bind this store to a map instance, once bound the store
+         *  is synchronized with the map and vice-versa.
+         */
+        bind: function(map, options) {
+            if(this.map) {
+                // already bound
+                return;
+            }
+            this.map = map;
+            options = options || {};
 
-    /** private: method[bind]
-     *  :param map: ``OpenLayers.Map`` The map instance.
-     *  :param options: ``Object``
-     *  
-     *  Bind this store to a map instance, once bound the store
-     *  is synchronized with the map and vice-versa.
-     */
-    bind: function(map, options) {
-        if(this.map) {
-            // already bound
-            return;
-        }
-        this.map = map;
-        options = options || {};
+            var initDir = options.initDir;
+            if(options.initDir == undefined) {
+                initDir = GeoExt.data.LayerStore.MAP_TO_STORE |
+                          GeoExt.data.LayerStore.STORE_TO_MAP;
+            }
 
-        var initDir = options.initDir;
-        if(options.initDir == undefined) {
-            initDir = GeoExt.data.LayerStore.MAP_TO_STORE |
-                      GeoExt.data.LayerStore.STORE_TO_MAP;
-        }
+            // create a snapshot of the map's layers
+            var layers = map.layers.slice(0);
 
-        // create a snapshot of the map's layers
-        var layers = map.layers.slice(0);
+            if(initDir & GeoExt.data.LayerStore.STORE_TO_MAP) {
+                this.each(function(record) {
+                    this.map.addLayer(record.get("layer"));
+                }, this);
+            }
+            if(initDir & GeoExt.data.LayerStore.MAP_TO_STORE) {
+                this.loadData(layers, true);
+            }
 
-        if(initDir & GeoExt.data.LayerStore.STORE_TO_MAP) {
-            this.each(function(record) {
-                this.map.addLayer(record.get("layer"));
-            }, this);
-        }
-        if(initDir & GeoExt.data.LayerStore.MAP_TO_STORE) {
-            this.loadData(layers, true);
-        }
-
-        map.events.on({
-            "changelayer": this.onChangeLayer,
-            "addlayer": this.onAddLayer,
-            "removelayer": this.onRemoveLayer,
-            scope: this
-        });
-        this.on({
-            "load": this.onLoad,
-            "clear": this.onClear,
-            "add": this.onAdd,
-            "remove": this.onRemove,
-            "update": this.onUpdate,
-            scope: this
-        });
-        this.data.on({
-            "replace" : this.onReplace,
-            scope: this
-        });
-    },
-
-    /** private: method[unbind]
-     *  Unbind this store from the map it is currently bound.
-     */
-    unbind: function() {
-        if(this.map) {
-            this.map.events.un({
+            map.events.on({
                 "changelayer": this.onChangeLayer,
                 "addlayer": this.onAddLayer,
                 "removelayer": this.onRemoveLayer,
                 scope: this
             });
-            this.un("load", this.onLoad, this);
-            this.un("clear", this.onClear, this);
-            this.un("add", this.onAdd, this);
-            this.un("remove", this.onRemove, this);
+            this.on({
+                "load": this.onLoad,
+                "clear": this.onClear,
+                "add": this.onAdd,
+                "remove": this.onRemove,
+                "update": this.onUpdate,
+                scope: this
+            });
+            this.data.on({
+                "replace" : this.onReplace,
+                scope: this
+            });
+        },
 
-            this.data.un("replace", this.onReplace, this);
+        /** private: method[unbind]
+         *  Unbind this store from the map it is currently bound.
+         */
+        unbind: function() {
+            if(this.map) {
+                this.map.events.un({
+                    "changelayer": this.onChangeLayer,
+                    "addlayer": this.onAddLayer,
+                    "removelayer": this.onRemoveLayer,
+                    scope: this
+                });
+                this.un("load", this.onLoad, this);
+                this.un("clear", this.onClear, this);
+                this.un("add", this.onAdd, this);
+                this.un("remove", this.onRemove, this);
 
-            this.map = null;
-        }
-    },
-    
-    /** private: method[onChangeLayer]
-     *  :param evt: ``Object``
-     * 
-     *  Handler for layer changes.  When layer order changes, this moves the
-     *  appropriate record within the store.
-     */
-    onChangeLayer: function(evt) {
-        var layer = evt.layer;
-        var recordIndex = this.findBy(function(rec, id) {
-            return rec.get("layer") === layer;
-        });
-        if(recordIndex > -1) {
-            var record = this.getAt(recordIndex);
-            if(evt.property === "order") {
-                if(!this._adding && !this._removing) {
-                    var layerIndex = this.map.getLayerIndex(layer);
-                    if(layerIndex !== recordIndex) {
-                        this._removing = true;
-                        this.remove(record);
-                        delete this._removing;
-                        this._adding = true;
-                        this.insert(layerIndex, [record]);
-                        delete this._adding;
+                this.data.un("replace", this.onReplace, this);
+
+                this.map = null;
+            }
+        },
+        
+        /** private: method[onChangeLayer]
+         *  :param evt: ``Object``
+         * 
+         *  Handler for layer changes.  When layer order changes, this moves the
+         *  appropriate record within the store.
+         */
+        onChangeLayer: function(evt) {
+            var layer = evt.layer;
+            var recordIndex = this.findBy(function(rec, id) {
+                return rec.get("layer") === layer;
+            });
+            if(recordIndex > -1) {
+                var record = this.getAt(recordIndex);
+                if(evt.property === "order") {
+                    if(!this._adding && !this._removing) {
+                        var layerIndex = this.map.getLayerIndex(layer);
+                        if(layerIndex !== recordIndex) {
+                            this._removing = true;
+                            this.remove(record);
+                            delete this._removing;
+                            this._adding = true;
+                            this.insert(layerIndex, [record]);
+                            delete this._adding;
+                        }
                     }
+                } else if(evt.property === "name") {
+                    record.set("title", layer.name);
+                } else {
+                    this.fireEvent("update", this, record, Ext.data.Record.EDIT);
                 }
-            } else if(evt.property === "name") {
-                record.set("title", layer.name);
+            }
+        },
+       
+        /** private: method[onAddLayer]
+         *  :param evt: ``Object``
+         *  
+         *  Handler for a map's addlayer event
+         */
+        onAddLayer: function(evt) {
+            if(!this._adding) {
+                var layer = evt.layer;
+                this._adding = true;
+                this.loadData([layer], true);
+                delete this._adding;
+            }
+        },
+        
+        /** private: method[onRemoveLayer]
+         *  :param evt: ``Object``
+         * 
+         *  Handler for a map's removelayer event
+         */
+        onRemoveLayer: function(evt){
+            //TODO replace the check for undloadDestroy with a listener for the
+            // map's beforedestroy event, doing unbind(). This can be done as soon
+            // as http://trac.openlayers.org/ticket/2136 is fixed.
+            if(this.map.unloadDestroy) {
+                if(!this._removing) {
+                    var layer = evt.layer;
+                    this._removing = true;
+                    this.remove(this.getById(layer.id));
+                    delete this._removing;
+                }
             } else {
-                this.fireEvent("update", this, record, Ext.data.Record.EDIT);
+                this.unbind();
             }
-        }
-    },
-   
-    /** private: method[onAddLayer]
-     *  :param evt: ``Object``
-     *  
-     *  Handler for a map's addlayer event
-     */
-    onAddLayer: function(evt) {
-        if(!this._adding) {
-            var layer = evt.layer;
-            this._adding = true;
-            this.loadData([layer], true);
-            delete this._adding;
-        }
-    },
-    
-    /** private: method[onRemoveLayer]
-     *  :param evt: ``Object``
-     * 
-     *  Handler for a map's removelayer event
-     */
-    onRemoveLayer: function(evt){
-        //TODO replace the check for undloadDestroy with a listener for the
-        // map's beforedestroy event, doing unbind(). This can be done as soon
-        // as http://trac.openlayers.org/ticket/2136 is fixed.
-        if(this.map.unloadDestroy) {
-            if(!this._removing) {
-                var layer = evt.layer;
+        },
+        
+        /** private: method[onLoad]
+         *  :param store: ``Ext.data.Store``
+         *  :param records: ``Array(Ext.data.Record)``
+         *  :param options: ``Object``
+         * 
+         *  Handler for a store's load event
+         */
+        onLoad: function(store, records, options) {
+            if (!Ext.isArray(records)) {
+                records = [records];
+            }
+            if (options && !options.add) {
                 this._removing = true;
-                this.remove(this.getById(layer.id));
+                for (var i = this.map.layers.length - 1; i >= 0; i--) {
+                    this.map.removeLayer(this.map.layers[i]);
+                }
                 delete this._removing;
+
+                // layers has already been added to map on "add" event
+                var len = records.length;
+                if (len > 0) {
+                    var layers = new Array(len);
+                    for (var j = 0; j < len; j++) {
+                        layers[j] = records[j].get("layer");
+                    }
+                    this._adding = true;
+                    this.map.addLayers(layers);
+                    delete this._adding;
+                }
             }
-        } else {
-            this.unbind();
-        }
-    },
-    
-    /** private: method[onLoad]
-     *  :param store: ``Ext.data.Store``
-     *  :param records: ``Array(Ext.data.Record)``
-     *  :param options: ``Object``
-     * 
-     *  Handler for a store's load event
-     */
-    onLoad: function(store, records, options) {
-        if (!Ext.isArray(records)) {
-            records = [records];
-        }
-        if (options && !options.add) {
+        },
+        
+        /** private: method[onClear]
+         *  :param store: ``Ext.data.Store``
+         * 
+         *  Handler for a store's clear event
+         */
+        onClear: function(store) {
             this._removing = true;
             for (var i = this.map.layers.length - 1; i >= 0; i--) {
                 this.map.removeLayer(this.map.layers[i]);
             }
             delete this._removing;
-
-            // layers has already been added to map on "add" event
-            var len = records.length;
-            if (len > 0) {
-                var layers = new Array(len);
-                for (var j = 0; j < len; j++) {
-                    layers[j] = records[j].get("layer");
+        },
+        
+        /** private: method[onAdd]
+         *  :param store: ``Ext.data.Store``
+         *  :param records: ``Array(Ext.data.Record)``
+         *  :param index: ``Number``
+         * 
+         *  Handler for a store's add event
+         */
+        onAdd: function(store, records, index) {
+            if(!this._adding) {
+                this._adding = true;
+                var layer;
+                for(var i=records.length-1; i>=0; --i) {
+                    layer = records[i].get("layer");
+                    this.map.addLayer(layer);
+                    if(index !== this.map.layers.length-1) {
+                        this.map.setLayerIndex(layer, index);
+                    }
                 }
-                this._adding = true;
-                this.map.addLayers(layers);
                 delete this._adding;
             }
-        }
-    },
-    
-    /** private: method[onClear]
-     *  :param store: ``Ext.data.Store``
-     * 
-     *  Handler for a store's clear event
-     */
-    onClear: function(store) {
-        this._removing = true;
-        for (var i = this.map.layers.length - 1; i >= 0; i--) {
-            this.map.removeLayer(this.map.layers[i]);
-        }
-        delete this._removing;
-    },
-    
-    /** private: method[onAdd]
-     *  :param store: ``Ext.data.Store``
-     *  :param records: ``Array(Ext.data.Record)``
-     *  :param index: ``Number``
-     * 
-     *  Handler for a store's add event
-     */
-    onAdd: function(store, records, index) {
-        if(!this._adding) {
-            this._adding = true;
-            var layer;
-            for(var i=records.length-1; i>=0; --i) {
-                layer = records[i].get("layer");
-                this.map.addLayer(layer);
-                if(index !== this.map.layers.length-1) {
-                    this.map.setLayerIndex(layer, index);
+        },
+        
+        /** private: method[onRemove]
+         *  :param store: ``Ext.data.Store``
+         *  :param record: ``Ext.data.Record``
+         *  :param index: ``Number``
+         * 
+         *  Handler for a store's remove event
+         */
+        onRemove: function(store, record, index){
+            if(!this._removing) {
+                var layer = record.get("layer");
+                if (this.map.getLayer(layer.id) != null) {
+                    this._removing = true;
+                    this.removeMapLayer(record);
+                    delete this._removing;
                 }
             }
-            delete this._adding;
-        }
-    },
-    
-    /** private: method[onRemove]
-     *  :param store: ``Ext.data.Store``
-     *  :param record: ``Ext.data.Record``
-     *  :param index: ``Number``
-     * 
-     *  Handler for a store's remove event
-     */
-    onRemove: function(store, record, index){
-        if(!this._removing) {
-            var layer = record.get("layer");
-            if (this.map.getLayer(layer.id) != null) {
-                this._removing = true;
-                this.removeMapLayer(record);
-                delete this._removing;
+        },
+        
+        /** private: method[onUpdate]
+         *  :param store: ``Ext.data.Store``
+         *  :param record: ``Ext.data.Record``
+         *  :param operation: ``Number``
+         * 
+         *  Handler for a store's update event
+         */
+        onUpdate: function(store, record, operation) {
+            if(operation === Ext.data.Record.EDIT) {
+                var layer = record.get("layer");
+                var title = record.get("title");
+                if(title !== layer.name) {
+                    layer.setName(title);
+                }
             }
-        }
-    },
-    
-    /** private: method[onUpdate]
-     *  :param store: ``Ext.data.Store``
-     *  :param record: ``Ext.data.Record``
-     *  :param operation: ``Number``
-     * 
-     *  Handler for a store's update event
-     */
-    onUpdate: function(store, record, operation) {
-        if(operation === Ext.data.Record.EDIT) {
-            var layer = record.get("layer");
-            var title = record.get("title");
-            if(title !== layer.name) {
-                layer.setName(title);
-            }
-        }
-    },
+        },
 
-    /** private: method[removeMapLayer]
-     *  :param record: ``Ext.data.Record``
-     *  
-     *  Removes a record's layer from the bound map.
-     */
-    removeMapLayer: function(record){
-        this.map.removeLayer(record.get("layer"));
-    },
+        /** private: method[removeMapLayer]
+         *  :param record: ``Ext.data.Record``
+         *  
+         *  Removes a record's layer from the bound map.
+         */
+        removeMapLayer: function(record){
+            this.map.removeLayer(record.get("layer"));
+        },
 
-    /** private: method[onReplace]
-     *  :param key: ``String``
-     *  :param oldRecord: ``Object`` In this case, a record that has been
-     *      replaced.
-     *  :param newRecord: ``Object`` In this case, a record that is replacing
-     *      oldRecord.
+        /** private: method[onReplace]
+         *  :param key: ``String``
+         *  :param oldRecord: ``Object`` In this case, a record that has been
+         *      replaced.
+         *  :param newRecord: ``Object`` In this case, a record that is replacing
+         *      oldRecord.
 
-     *  Handler for a store's data collections' replace event
-     */
-    onReplace: function(key, oldRecord, newRecord){
-        this.removeMapLayer(oldRecord);
-    },
-    
-    /** private: method[destroy]
-     */
-    destroy: function() {
-        this.unbind();
-        GeoExt.data.LayerStore.superclass.destroy.call(this);
-    }
+         *  Handler for a store's data collections' replace event
+         */
+        onReplace: function(key, oldRecord, newRecord){
+            this.removeMapLayer(oldRecord);
+        },
+        
+        /** private: method[destroy]
+         */
+        destroy: function() {
+            this.unbind();
+            GeoExt.data.LayerStore.superclass.destroy.call(this);
+        }
+    };
 };
 
 /** api: example
@@ -405,7 +406,7 @@
  */
 GeoExt.data.LayerStore = Ext.extend(
     Ext.data.Store,
-    GeoExt.data.LayerStoreMixin
+    new GeoExt.data.LayerStoreMixin
 );
 
 /**

Modified: core/trunk/geoext/lib/GeoExt/widgets/grid/FeatureSelectionModel.js
===================================================================
--- core/trunk/geoext/lib/GeoExt/widgets/grid/FeatureSelectionModel.js	2009-11-10 12:21:05 UTC (rev 1451)
+++ core/trunk/geoext/lib/GeoExt/widgets/grid/FeatureSelectionModel.js	2009-11-10 20:50:21 UTC (rev 1452)
@@ -44,273 +44,274 @@
  *      });
  */
 
-GeoExt.grid.FeatureSelectionModelMixin = {
+GeoExt.grid.FeatureSelectionModelMixin = function() {
+    return {
+        /** api: config[autoActivateControl]
+         *  ``Boolean`` If true the select feature control is activated and
+         *  deactivated when binding and unbinding. Defaults to true.
+         */
+        autoActivateControl: true,
 
-    /** api: config[autoActivateControl]
-     *  ``Boolean`` If true the select feature control is activated and
-     *  deactivated when binding and unbinding. Defaults to true.
-     */
-    autoActivateControl: true,
+        /** api: config[layerFromStore]
+         *  ``Boolean`` If true, and if the constructor is passed neither a
+         *  layer nor a select feature control, a select feature control is
+         *  created using the layer found in the grid's store. Set it to
+         *  false if you want to manually bind the selection model to a
+         *  layer. Defaults to true.
+         */
+        layerFromStore: true,
 
-    /** api: config[layerFromStore]
-     *  ``Boolean`` If true, and if the constructor is passed neither a
-     *  layer nor a select feature control, a select feature control is
-     *  created using the layer found in the grid's store. Set it to
-     *  false if you want to manually bind the selection model to a
-     *  layer. Defaults to true.
-     */
-    layerFromStore: true,
+        /** api: config[selectControl]
+         *
+         *  ``OpenLayers.Control.SelectFeature`` A select feature control. If not
+         *  provided one will be created.  If provided any "layer" config option
+         *  will be ignored, and its "multiple" option will be used to configure
+         *  the selectionModel.  If an ``Object`` is provided here, it will be
+         *  passed as config to the SelectFeature constructor, and the "layer"
+         *  config option will be used for the layer.
+         */
 
-    /** api: config[selectControl]
-     *
-     *  ``OpenLayers.Control.SelectFeature`` A select feature control. If not
-     *  provided one will be created.  If provided any "layer" config option
-     *  will be ignored, and its "multiple" option will be used to configure
-     *  the selectionModel.  If an ``Object`` is provided here, it will be
-     *  passed as config to the SelectFeature constructor, and the "layer"
-     *  config option will be used for the layer.
-     */
+        /** private: property[selectControl] 
+         *  ``OpenLayers.Control.SelectFeature`` The select feature control 
+         *  instance. 
+         */ 
+        selectControl: null, 
+        
+        /** api: config[layer]
+         *  ``OpenLayers.Layer.Vector`` The vector layer used for the creation of
+         *  the select feature control, it must already be added to the map. If not
+         *  provided, the layer bound to the grid's store, if any, will be used.
+         */
 
-    /** private: property[selectControl] 
-     *  ``OpenLayers.Control.SelectFeature`` The select feature control 
-     *  instance. 
-     */ 
-    selectControl: null, 
-    
-    /** api: config[layer]
-     *  ``OpenLayers.Layer.Vector`` The vector layer used for the creation of
-     *  the select feature control, it must already be added to the map. If not
-     *  provided, the layer bound to the grid's store, if any, will be used.
-     */
+        /** private: property[bound]
+         *  ``Boolean`` Flag indicating if the selection model is bound.
+         */
+        bound: false,
+        
+        /** private: property[superclass]
+         *  ``Ext.grid.AbstractSelectionModel`` Our superclass.
+         */
+        superclass: null,
 
-    /** private: property[bound]
-     *  ``Boolean`` Flag indicating if the selection model is bound.
-     */
-    bound: false,
-    
-    /** private: property[superclass]
-     *  ``Ext.grid.AbstractSelectionModel`` Our superclass.
-     */
-    superclass: null,
-
-    /** private */
-    constructor: function(config) {
-        config = config || {};
-        if(config.selectControl instanceof OpenLayers.Control.SelectFeature) { 
-            if(!config.singleSelect) {
-                var ctrl = config.selectControl;
-                config.singleSelect = !(ctrl.multiple || !!ctrl.multipleKey);
-            }
-        } else if(config.layer instanceof OpenLayers.Layer.Vector) {
-            this.selectControl = this.createSelectControl(
-                config.layer, config.selectControl
-            );
-            delete config.layer;
-            delete config.selectControl;
-        }
-        this.superclass = arguments.callee.superclass;
-        this.superclass.constructor.call(this, config);
-    },
-    
-    /** private: method[initEvents]
-     *
-     *  Called after this.grid is defined
-     */
-    initEvents: function() {
-        this.superclass.initEvents.call(this);
-        if(this.layerFromStore) {
-            var layer = this.grid.getStore() && this.grid.getStore().layer;
-            if(layer &&
-               !(this.selectControl instanceof OpenLayers.Control.SelectFeature)) {
+        /** private */
+        constructor: function(config) {
+            config = config || {};
+            if(config.selectControl instanceof OpenLayers.Control.SelectFeature) { 
+                if(!config.singleSelect) {
+                    var ctrl = config.selectControl;
+                    config.singleSelect = !(ctrl.multiple || !!ctrl.multipleKey);
+                }
+            } else if(config.layer instanceof OpenLayers.Layer.Vector) {
                 this.selectControl = this.createSelectControl(
-                    layer, this.selectControl
+                    config.layer, config.selectControl
                 );
+                delete config.layer;
+                delete config.selectControl;
             }
-        }
-        if(this.selectControl) {
-            this.bind(this.selectControl);
-        }
-    },
+            this.superclass = arguments.callee.superclass;
+            this.superclass.constructor.call(this, config);
+        },
+        
+        /** private: method[initEvents]
+         *
+         *  Called after this.grid is defined
+         */
+        initEvents: function() {
+            this.superclass.initEvents.call(this);
+            if(this.layerFromStore) {
+                var layer = this.grid.getStore() && this.grid.getStore().layer;
+                if(layer &&
+                   !(this.selectControl instanceof OpenLayers.Control.SelectFeature)) {
+                    this.selectControl = this.createSelectControl(
+                        layer, this.selectControl
+                    );
+                }
+            }
+            if(this.selectControl) {
+                this.bind(this.selectControl);
+            }
+        },
 
-    /** private: createSelectControl
-     *  :param layer: ``OpenLayers.Layer.Vector`` The vector layer.
-     *  :param config: ``Object`` The select feature control config.
-     *
-     *  Create the select feature control.
-     */
-    createSelectControl: function(layer, config) {
-        config = config || {};
-        var singleSelect = config.singleSelect !== undefined ?
-                           config.singleSelect : this.singleSelect;
-        config = OpenLayers.Util.extend({
-            toggle: true,
-            multipleKey: singleSelect ? null :
-                (Ext.isMac ? "metaKey" : "ctrlKey")
-        }, config);
-        var selectControl = new OpenLayers.Control.SelectFeature(
-            layer, config
-        );
-        layer.map.addControl(selectControl);
-        return selectControl;
-    },
-    
-    /** api: method[bind]
-     *
-     *  :param obj: ``OpenLayers.Layer.Vector`` or
-     *      ``OpenLayers.Control.SelectFeature`` The object this selection model
-     *      should be bound to, either a vector layer or a select feature
-     *      control.
-     *  :param options: ``Object`` An object with a "controlConfig"
-     *      property referencing the configuration object to pass to the
-     *      ``OpenLayers.Control.SelectFeature`` constructor.
-     *  :return: ``OpenLayers.Control.SelectFeature`` The select feature
-     *      control this selection model uses.
-     *
-     *  Bind the selection model to a layer or a SelectFeature control.
-     */
-    bind: function(obj, options) {
-        if(!this.bound) {
-            options = options || {};
-            this.selectControl = obj;
-            if(obj instanceof OpenLayers.Layer.Vector) {
-                this.selectControl = this.createSelectControl(
-                    obj, options.controlConfig
-                );
+        /** private: createSelectControl
+         *  :param layer: ``OpenLayers.Layer.Vector`` The vector layer.
+         *  :param config: ``Object`` The select feature control config.
+         *
+         *  Create the select feature control.
+         */
+        createSelectControl: function(layer, config) {
+            config = config || {};
+            var singleSelect = config.singleSelect !== undefined ?
+                               config.singleSelect : this.singleSelect;
+            config = OpenLayers.Util.extend({
+                toggle: true,
+                multipleKey: singleSelect ? null :
+                    (Ext.isMac ? "metaKey" : "ctrlKey")
+            }, config);
+            var selectControl = new OpenLayers.Control.SelectFeature(
+                layer, config
+            );
+            layer.map.addControl(selectControl);
+            return selectControl;
+        },
+        
+        /** api: method[bind]
+         *
+         *  :param obj: ``OpenLayers.Layer.Vector`` or
+         *      ``OpenLayers.Control.SelectFeature`` The object this selection model
+         *      should be bound to, either a vector layer or a select feature
+         *      control.
+         *  :param options: ``Object`` An object with a "controlConfig"
+         *      property referencing the configuration object to pass to the
+         *      ``OpenLayers.Control.SelectFeature`` constructor.
+         *  :return: ``OpenLayers.Control.SelectFeature`` The select feature
+         *      control this selection model uses.
+         *
+         *  Bind the selection model to a layer or a SelectFeature control.
+         */
+        bind: function(obj, options) {
+            if(!this.bound) {
+                options = options || {};
+                this.selectControl = obj;
+                if(obj instanceof OpenLayers.Layer.Vector) {
+                    this.selectControl = this.createSelectControl(
+                        obj, options.controlConfig
+                    );
+                }
+                if(this.autoActivateControl) {
+                    this.selectControl.activate();
+                }
+                var layers = this.getLayers();
+                for(var i = 0, len = layers.length; i < len; i++) {
+                    layers[i].events.on({
+                        featureselected: this.featureSelected,
+                        featureunselected: this.featureUnselected,
+                        scope: this
+                    });
+                }
+                this.on("rowselect", this.rowSelected, this);
+                this.on("rowdeselect", this.rowDeselected, this);
+                this.bound = true;
             }
-            if(this.autoActivateControl) {
-                this.selectControl.activate();
+            return this.selectControl;
+        },
+        
+        /** api: method[unbind]
+         *  :return: ``OpenLayers.Control.SelectFeature`` The select feature
+         *      control this selection model used.
+         *
+         *  Unbind the selection model from the layer or SelectFeature control.
+         */
+        unbind: function() {
+            var selectControl = this.selectControl;
+            if(this.bound) {
+                var layers = this.getLayers();
+                for(var i = 0, len = layers.length; i < len; i++) {
+                    layers[i].events.un({
+                        featureselected: this.featureSelected,
+                        featureunselected: this.featureUnselected,
+                        scope: this
+                    });
+                }
+                this.un("rowselect", this.rowSelected, this);
+                this.un("rowdeselect", this.rowDeselected, this);
+                if(this.autoActivateControl) {
+                    selectControl.deactivate();
+                }
+                this.selectControl = null;
+                this.bound = false;
             }
-            var layers = this.getLayers();
-            for(var i = 0, len = layers.length; i < len; i++) {
-                layers[i].events.on({
-                    featureselected: this.featureSelected,
-                    featureunselected: this.featureUnselected,
-                    scope: this
+            return selectControl;
+        },
+        
+        /** private: method[featureSelected]
+         *  :param evt: ``Object`` An object with a feature property referencing
+         *                         the selected feature.
+         */
+        featureSelected: function(evt) {
+            if(!this._selecting) {
+                var store = this.grid.store;
+                var row = store.findBy(function(record, id) {
+                    return record.data.feature == evt.feature;
                 });
-            }
-            this.on("rowselect", this.rowSelected, this);
-            this.on("rowdeselect", this.rowDeselected, this);
-            this.bound = true;
-        }
-        return this.selectControl;
-    },
-    
-    /** api: method[unbind]
-     *  :return: ``OpenLayers.Control.SelectFeature`` The select feature
-     *      control this selection model used.
-     *
-     *  Unbind the selection model from the layer or SelectFeature control.
-     */
-    unbind: function() {
-        var selectControl = this.selectControl;
-        if(this.bound) {
-            var layers = this.getLayers();
-            for(var i = 0, len = layers.length; i < len; i++) {
-                layers[i].events.un({
-                    featureselected: this.featureSelected,
-                    featureunselected: this.featureUnselected,
-                    scope: this
-                });
-            }
-            this.un("rowselect", this.rowSelected, this);
-            this.un("rowdeselect", this.rowDeselected, this);
-            if(this.autoActivateControl) {
-                selectControl.deactivate();
-            }
-            this.selectControl = null;
-            this.bound = false;
-        }
-        return selectControl;
-    },
-    
-    /** private: method[featureSelected]
-     *  :param evt: ``Object`` An object with a feature property referencing
-     *                         the selected feature.
-     */
-    featureSelected: function(evt) {
-        if(!this._selecting) {
-            var store = this.grid.store;
-            var row = store.findBy(function(record, id) {
-                return record.data.feature == evt.feature;
-            });
-            if(row != -1 && !this.isSelected(row)) {
-                this._selecting = true;
-                this.selectRow(row, !this.singleSelect);
-                this._selecting = false;
-                // focus the row in the grid to ensure it is visible
-                this.grid.getView().focusRow(row);
-            }
-        }
-    },
-    
-    /** private: method[featureUnselected]
-     *  :param evt: ``Object`` An object with a feature property referencing
-     *                         the unselected feature.
-     */
-    featureUnselected: function(evt) {
-        if(!this._selecting) {
-            var store = this.grid.store;
-            var row = store.findBy(function(record, id) {
-                return record.data.feature == evt.feature;
-            });
-            if(row != -1 && this.isSelected(row)) {
-                this._selecting = true;
-                this.deselectRow(row); 
-                this._selecting = false;
-                this.grid.getView().focusRow(row);
-            }
-        }
-    },
-    
-    /** private: method[rowSelected]
-     *  :param model: ``Ext.grid.RowSelectModel`` The row select model.
-     *  :param row: ``Integer`` The row index.
-     *  :param record: ``Ext.data.Record`` The record.
-     */
-    rowSelected: function(model, row, record) {
-        var feature = record.data.feature;
-        if(!this._selecting && feature) {
-            var layers = this.getLayers();
-            for(var i = 0, len = layers.length; i < len; i++) {
-                if(layers[i].selectedFeatures.indexOf(feature) == -1) {
+                if(row != -1 && !this.isSelected(row)) {
                     this._selecting = true;
-                    this.selectControl.select(feature);
+                    this.selectRow(row, !this.singleSelect);
                     this._selecting = false;
-                    break;
+                    // focus the row in the grid to ensure it is visible
+                    this.grid.getView().focusRow(row);
                 }
             }
-         }
-    },
-    
-    /** private: method[rowDeselected]
-     *  :param model: ``Ext.grid.RowSelectModel`` The row select model.
-     *  :param row: ``Integer`` The row index.
-     *  :param record: ``Ext.data.Record`` The record.
-     */
-    rowDeselected: function(model, row, record) {
-        var feature = record.data.feature;
-        if(!this._selecting && feature) {
-            var layers = this.getLayers();
-            for(var i = 0, len = layers.length; i < len; i++) {
-                if(layers[i].selectedFeatures.indexOf(feature) != -1) {
+        },
+        
+        /** private: method[featureUnselected]
+         *  :param evt: ``Object`` An object with a feature property referencing
+         *                         the unselected feature.
+         */
+        featureUnselected: function(evt) {
+            if(!this._selecting) {
+                var store = this.grid.store;
+                var row = store.findBy(function(record, id) {
+                    return record.data.feature == evt.feature;
+                });
+                if(row != -1 && this.isSelected(row)) {
                     this._selecting = true;
-                    this.selectControl.unselect(feature);
+                    this.deselectRow(row); 
                     this._selecting = false;
-                    break;
+                    this.grid.getView().focusRow(row);
                 }
             }
+        },
+        
+        /** private: method[rowSelected]
+         *  :param model: ``Ext.grid.RowSelectModel`` The row select model.
+         *  :param row: ``Integer`` The row index.
+         *  :param record: ``Ext.data.Record`` The record.
+         */
+        rowSelected: function(model, row, record) {
+            var feature = record.data.feature;
+            if(!this._selecting && feature) {
+                var layers = this.getLayers();
+                for(var i = 0, len = layers.length; i < len; i++) {
+                    if(layers[i].selectedFeatures.indexOf(feature) == -1) {
+                        this._selecting = true;
+                        this.selectControl.select(feature);
+                        this._selecting = false;
+                        break;
+                    }
+                }
+             }
+        },
+        
+        /** private: method[rowDeselected]
+         *  :param model: ``Ext.grid.RowSelectModel`` The row select model.
+         *  :param row: ``Integer`` The row index.
+         *  :param record: ``Ext.data.Record`` The record.
+         */
+        rowDeselected: function(model, row, record) {
+            var feature = record.data.feature;
+            if(!this._selecting && feature) {
+                var layers = this.getLayers();
+                for(var i = 0, len = layers.length; i < len; i++) {
+                    if(layers[i].selectedFeatures.indexOf(feature) != -1) {
+                        this._selecting = true;
+                        this.selectControl.unselect(feature);
+                        this._selecting = false;
+                        break;
+                    }
+                }
+            }
+        },
+
+        /** private: method[getLayers]
+         *  Return the layers attached to the select feature control.
+         */
+        getLayers: function() {
+            return this.selectControl.layers || [this.selectControl.layer];
         }
-    },
-
-    /** private: method[getLayers]
-     *  Return the layers attached to the select feature control.
-     */
-    getLayers: function() {
-        return this.selectControl.layers || [this.selectControl.layer];
-    }
+    };
 };
 
 GeoExt.grid.FeatureSelectionModel = Ext.extend(
     Ext.grid.RowSelectionModel,
-    GeoExt.grid.FeatureSelectionModelMixin
+    new GeoExt.grid.FeatureSelectionModelMixin
 );

Modified: core/trunk/geoext/tests/lib/GeoExt/widgets/grid/FeatureSelectionModel.html
===================================================================
--- core/trunk/geoext/tests/lib/GeoExt/widgets/grid/FeatureSelectionModel.html	2009-11-10 12:21:05 UTC (rev 1451)
+++ core/trunk/geoext/tests/lib/GeoExt/widgets/grid/FeatureSelectionModel.html	2009-11-10 20:50:21 UTC (rev 1452)
@@ -99,7 +99,7 @@
             // 1 test
             var CheckboxSelectionModel = Ext.extend(
                 Ext.grid.CheckboxSelectionModel,
-                GeoExt.grid.FeatureSelectionModelMixin
+                new GeoExt.grid.FeatureSelectionModelMixin
             );
             sm = new CheckboxSelectionModel();
             t.ok(sm instanceof Ext.grid.CheckboxSelectionModel,



More information about the Commits mailing list