diff --git a/core/src/script/CGXP/plugins/Editing.js b/core/src/script/CGXP/plugins/Editing.js
index f3851a35..f2b966c8 100644
--- a/core/src/script/CGXP/plugins/Editing.js
+++ b/core/src/script/CGXP/plugins/Editing.js
@@ -91,6 +91,12 @@ cgxp.plugins.Editing = Ext.extend(gxp.plugins.Tool, {
*/
win: null,
+ /** private: property[newFeatureBtn]
+ * ``Ext.form.SplitButton``
+ * The 'create an new feature' button.
+ */
+ newFeatureBtn: null,
+
/** api: config[helpText]
* ``String``
* The text to the top of the editing window (i18n).
@@ -110,6 +116,19 @@ cgxp.plugins.Editing = Ext.extend(gxp.plugins.Tool, {
*/
createBtnText: 'Create a new feature',
+ /** private: config[pendingRequests]
+ * ``GeoExt.data.AttributeStore``
+ * The list of pendingRequests (actually the attribute stores)
+ */
+ pendingRequests: null,
+
+ /** private: method[constructor]
+ */
+ constructor: function(config) {
+ cgxp.plugins.Editing.superclass.constructor.apply(this, arguments);
+ this.pendingRequests = [];
+ },
+
/** private: method[init]
*/
init: function() {
@@ -119,16 +138,18 @@ cgxp.plugins.Editing = Ext.extend(gxp.plugins.Tool, {
this.addEditingLayer();
this.createGetFeatureControl();
+ this.newFeatureBtn = this.createNewFeatureBtn();
var win = this.win = new Ext.Window({
width: 300,
border: false,
closable: false,
plain: true,
resizable: false,
+ disabled: true,
items: [{
xtype: 'box',
html: this.helpText + '
'
- }, this.createNewFeatureBtn()]
+ }, this.newFeatureBtn]
});
this.target.mapPanel.on({
'render': function() {
@@ -136,6 +157,59 @@ cgxp.plugins.Editing = Ext.extend(gxp.plugins.Tool, {
win.anchorTo.defer(100, win, [this.body, 'tl-tl', [55, 10]]);
}
});
+
+ var portal = this.target;
+ portal.on({
+ ready: function() {
+ var tree = portal.tools[this.layerTreeId].tree;
+ tree.on({
+ checkchange: this.manageLayers,
+ addgroup: this.manageLayers,
+ removegroup: this.manageLayers,
+ scope: this
+ });
+ },
+ scope: this
+ });
+ },
+
+ /** private: manageLayers
+ * Checks if there are editable layers, enables or disables the editing
+ * window and updates the editable layers list in the create new feature
+ * button.
+ */
+ manageLayers: function() {
+ var layers = this.getEditableLayers();
+ var size = 0;
+ var menu = this.newFeatureBtn.menu;
+ this.abortPendingRequests();
+ var alreadyAvailableItems = [];
+ menu.items.each(function(item) {
+ if (!item.layerId) {
+ return;
+ }
+ // remove items that are not in the layers list anymore
+ if (!layers[item.layerId]) {
+ menu.remove(item);
+ } else {
+ alreadyAvailableItems.push(item.layerId);
+ }
+ });
+ for (var i in layers) {
+ size++;
+ // only add an item for new editable layers
+ if (alreadyAvailableItems.indexOf(parseInt(i)) == -1) {
+ this.getAttributesStore(layers[i].attributes.layer_id, null, (function(store, geometryType, layer) {
+ menu.add(this.createMenuItem(layer, geometryType));
+ }).createDelegate(this, [layers[i]], true));
+ }
+ }
+ this.win.setDisabled(size === 0);
+ if (size === 0) {
+ this.newFeatureBtn.toggle(false);
+ this.newFeatureBtn.setText(this.createBtnText);
+ this.closeEditing();
+ }
},
/** private: method[addEditingLayer]
@@ -165,30 +239,23 @@ cgxp.plugins.Editing = Ext.extend(gxp.plugins.Tool, {
/** private: method[createNewFeatureBtn]
*/
createNewFeatureBtn: function() {
- function manageMenuItems() {
- menu.removeAll();
- menu.add('');
- var layers = this.getEditableLayers();
- for (var i in layers) {
- this.getAttributesStore(layers[i].attributes.layer_id, null, function(store, geometryType) {
- menu.add(this.createMenuItem(layers[i], geometryType));
- });
+ var menu = new Ext.menu.Menu({
+ items: [''],
+ listeners: {
+ beforeremove: function(menu, item) {
+ if (newFeatureBtn.activeItem == item) {
+ newFeatureBtn.toggle(false);
+ newFeatureBtn.activeItem = null;
+ newFeatureBtn.setText(newFeatureBtn.initialConfig.text);
+ }
+ if (this.editorGrid &&
+ this.editorGrid.store.feature.attributes.__layer_id__ == item.layerId) {
+ this.closeEditing();
+ }
+ },
+ scope: this
}
- }
-
- var portal = this.target;
- portal.on({
- ready: function() {
- var tree = portal.tools[this.layerTreeId].tree;
- tree.on({
- addgroup: manageMenuItems.createDelegate(this),
- removegroup: manageMenuItems.createDelegate(this)
- });
- },
- scope: this
});
-
- var menu = new Ext.menu.Menu({});
var newFeatureBtn = new Ext.SplitButton({
text: this.createBtnText,
enableToggle: true,
@@ -235,7 +302,7 @@ cgxp.plugins.Editing = Ext.extend(gxp.plugins.Tool, {
this.editingLayer, Handler, {
featureAdded: OpenLayers.Function.bind(function(f) {
control.deactivate();
- newFeatureBtn.toggle(false);
+ this.newFeatureBtn.toggle(false);
f.attributes.__layer_id__ =
layer.attributes.layer_id;
var store = this.getAttributesStore(
@@ -256,6 +323,7 @@ cgxp.plugins.Editing = Ext.extend(gxp.plugins.Tool, {
text: layer.attributes.text,
group: 'create_layer',
enableToggle: true,
+ layerId: layer.attributes.layer_id,
control: control,
listeners: {
checkchange: function(item, checked) {
@@ -318,6 +386,9 @@ cgxp.plugins.Editing = Ext.extend(gxp.plugins.Tool, {
for (var i in self.getEditableLayers()) {
layerIds.push(i);
}
+ if (layerIds.length === 0) {
+ return;
+ }
options.url = baseURL + layerIds.join(',');
// ensure that there's no unsaved modification before sending
// the request.
@@ -387,12 +458,27 @@ cgxp.plugins.Editing = Ext.extend(gxp.plugins.Tool, {
});
callback.call(this, store, geometryType);
},
+ beforeload: function(store) {
+ this.pendingRequests.push(store);
+ },
scope: this
});
store.load();
return store;
},
+ /** private: method[abortPendingRequests]
+ * Aborts any pending xsd request.
+ */
+ abortPendingRequests: function() {
+ Ext.each(this.pendingRequests, function(store) {
+ // destroying the store will destroy the corresponding proxy, and
+ // the corresponding active requests
+ store.destroy();
+ });
+ this.pendingRequests = [];
+ },
+
/** private: method[showAttributesEditingWindow]
*/
showAttributesEditingWindow: function(store) {
diff --git a/core/tests/spec/script/CGXP/plugins/Editing.js b/core/tests/spec/script/CGXP/plugins/Editing.js
index df7bf366..048cda83 100644
--- a/core/tests/spec/script/CGXP/plugins/Editing.js
+++ b/core/tests/spec/script/CGXP/plugins/Editing.js
@@ -107,4 +107,92 @@ describe('plugins.Editing', function() {
expect(item.control.handler.multi).toBeTruthy();
});
});
+ describe('when calling init', function() {
+ beforeEach(function() {
+ var map = new OpenLayers.Map();
+ e = new cgxp.plugins.Editing({
+ layersURL: '/layers/',
+ map: map
+ });
+ e.init({
+ tools: {},
+ on: function() {},
+ mapPanel: {
+ on: function() {},
+ map: map
+ }
+ });
+ });
+ it('sets the editing plugin window to disabled', function() {
+ expect(e.win.disabled).toBeTruthy();
+ });
+ });
+ describe('when list of editable layers changes', function() {
+ var server,
+ clock,
+ map = new OpenLayers.Map();
+ beforeEach(function() {
+ server = sinon.fakeServer.create();
+ clock = sinon.useFakeTimers();
+ e = new cgxp.plugins.Editing({
+ layersURL: '/layers/',
+ map: map
+ });
+ e.init({
+ tools: {},
+ on: function() {},
+ mapPanel: {
+ on: function() {},
+ map: map
+ }
+ });
+ e.getEditableLayers = function() {
+ return layers;
+ };
+ e.getAttributesStore = function() {};
+ });
+ afterEach(function() {
+ server.restore();
+ clock.restore();
+ });
+ var layers;
+ it('sets the editing plugin window to enabled', function() {
+ layers = {
+ 'l3': {
+ attributes: 'bar'
+ }
+ };
+ e.manageLayers();
+ expect(e.win.disabled).toBeFalsy();
+ });
+
+ it('sends requests with getFeature control', function() {
+ var oldRead = OpenLayers.Protocol.HTTP.prototype.read;
+ var foo = false;
+ OpenLayers.Protocol.HTTP.prototype.read = function() {
+ foo = true;
+ };
+
+ map.getControlsByClass('OpenLayers.Control.GetFeature')[0].request();
+ OpenLayers.Protocol.HTTP.prototype.read = oldRead;
+ expect(foo).toBeTruthy();
+ });
+
+ it('sets the editing plugin window to disabled', function() {
+ layers = {};
+ e.manageLayers();
+ expect(e.win.disabled).toBeTruthy();
+ });
+ it('prevents requests with getFeature control to be sent', function() {
+ var oldRead = OpenLayers.Protocol.HTTP.prototype.read;
+ var foo = false;
+ OpenLayers.Protocol.HTTP.prototype.read = function() {
+ foo = true;
+ };
+
+ map.getControlsByClass('OpenLayers.Control.GetFeature')[0].request();
+ OpenLayers.Protocol.HTTP.prototype.read = oldRead;
+ expect(foo).toBeFalsy();
+ });
+ });
});