Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.app / org.gvsig.vectorediting.app.mainplugin / src / main / java / org / gvsig / vectorediting / app / mainplugin / EditingExtension.java @ 770

History | View | Annotate | Download (15.2 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2014 gvSIG Association
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.vectorediting.app.mainplugin;
25

    
26
import java.io.File;
27
import java.util.ArrayList;
28
import java.util.List;
29
import javax.swing.JOptionPane;
30
import org.apache.commons.io.FileUtils;
31

    
32
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34

    
35
import org.gvsig.andami.IconThemeHelper;
36
import org.gvsig.andami.PluginServices;
37
import org.gvsig.andami.PluginsLocator;
38
import org.gvsig.andami.actioninfo.ActionInfo;
39
import org.gvsig.andami.plugins.Extension;
40
import org.gvsig.andami.plugins.IExtension;
41
import org.gvsig.andami.plugins.status.IExtensionStatus;
42
import org.gvsig.andami.plugins.status.IUnsavedData;
43
import org.gvsig.andami.plugins.status.UnsavedData;
44
import org.gvsig.app.ApplicationLocator;
45
import org.gvsig.app.ApplicationManager;
46
import org.gvsig.app.project.Project;
47
import org.gvsig.app.project.documents.Document;
48
import org.gvsig.app.project.documents.view.ViewDocument;
49
import org.gvsig.app.project.documents.view.ViewManager;
50
import org.gvsig.app.project.documents.view.gui.DefaultViewPanel;
51
import org.gvsig.app.project.documents.view.gui.IView;
52
import org.gvsig.app.project.documents.view.toc.actions.EndEditingTocMenuEntry;
53
import org.gvsig.app.project.documents.view.toc.actions.StartEditingTocMenuEntry;
54
import org.gvsig.app.project.documents.view.toolListeners.StatusBarListener;
55
import org.gvsig.fmap.dal.exception.DataException;
56
import org.gvsig.fmap.dal.feature.FeatureStore;
57
import org.gvsig.fmap.mapcontext.MapContext;
58
import org.gvsig.fmap.mapcontext.MapContextLocator;
59
import org.gvsig.fmap.mapcontext.layers.FLayer;
60
import org.gvsig.fmap.mapcontext.layers.FLayers;
61
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
62
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
63
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolException;
64
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
65
import org.gvsig.fmap.mapcontrol.MapControl;
66
import org.gvsig.fmap.mapcontrol.MapControlCreationListener;
67
import org.gvsig.fmap.mapcontrol.MapControlLocator;
68
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
69
import org.gvsig.fmap.mapcontrol.tools.Behavior.MouseMovementBehavior;
70
import org.gvsig.tools.ToolsLocator;
71
import org.gvsig.tools.extensionpoint.ExtensionPoint;
72
import org.gvsig.tools.i18n.I18nManager;
73
import org.gvsig.tools.observer.Notification;
74
import org.gvsig.tools.observer.Observable;
75
import org.gvsig.tools.observer.Observer;
76
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
77
import org.gvsig.utils.swing.threads.IMonitorableTask;
78
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
79
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
80
import org.gvsig.vectorediting.swing.api.EditingContext;
81
import org.gvsig.vectorediting.swing.api.EditingSwingLocator;
82
import org.gvsig.vectorediting.swing.api.EditingSwingManager;
83

    
84
public class EditingExtension extends Extension implements Observer {
85

    
86
    private static final Logger logger = LoggerFactory.getLogger(EditingExtension.class);
87

    
88
    @Override
89
    public void execute(String actionCommand) {
90

    
91
        ApplicationManager application = ApplicationLocator.getManager();
92
        IView view = getActiveView();
93
        EditingSwingManager swingManager = EditingSwingLocator.getSwingManager();
94

    
95
        if (view != null) {
96

    
97
            FLyrVect layer = getActiveLayer(view);
98
            MapControl mapControl = view.getMapControl();
99
            EditingContext editingContext = swingManager.getEditingContext(mapControl);
100

    
101
            if ("start-editing".equals(actionCommand)) {
102

    
103
                if (canBeEdited(layer)) {
104
                    if( !mapControl.getProjection().equals(layer.getProjection()) ) {
105
                        String msg = "_The_layer_is_reproyected_on_the_fly"
106
                                + "_Not_all_editing_tools_work_properly"
107
                                + "_When_you_finish_editing"
108
                                + "_will_only_export_the_changes_to_another_layer";
109
                        application.messageDialog(msg, "_Warning", JOptionPane.WARNING_MESSAGE);
110
                    }
111
                    editingContext.beginEdition(layer);
112
                    editingContext.addObserver(this);
113
                    ApplicationLocator.getManager().refreshMenusAndToolBars();
114
                }
115

    
116
            } else if ("end-editing".equals(actionCommand)) {
117

    
118
                if ((layer != null) && layer.isEditing()) {
119
                    editingContext.endEdition(layer);
120
                    ApplicationLocator.getManager().refreshMenusAndToolBars();
121
                }
122

    
123
            }
124
        }
125
    }
126

    
127
    @Override
128
    public void initialize() {
129
        registerIcons();
130

    
131
        // Disable default view panel console. Uses editing context console.
132
        DefaultViewPanel.setDisableConsole(true);
133

    
134
        // Adding TOC menu entry
135
        ExtensionPoint exPoint = ToolsLocator.getExtensionPointManager().add(
136
                "View_TocActions", "");
137
        exPoint.append(
138
            StartEditingTocMenuEntry.EXTENSION_POINT_NAME,
139
                "TOC popup menu to start vector layer's editing",
140
                new StartEditingTocMenuEntry());
141
        exPoint.append(
142
            EndEditingTocMenuEntry.EXTENSION_POINT_NAME,
143
                "TOC popup menu to end vector layer's editing",
144
                new EndEditingTocMenuEntry());
145
    }
146

    
147

    
148
    private void registerIcons() {
149
        IconThemeHelper.registerIcon("vectorediting", "vector-editing", this);
150
    }
151

    
152
    @Override
153
    public void postInitialize() {
154
        super.postInitialize();
155
        registerSymbols();
156

    
157
        MapControlLocator.getMapControlManager().addMapControlCreationListener(new MapControlCreationListener() {
158

    
159
            @Override
160
            public MapControl mapControlCreated(MapControl mapControl) {
161
                EditingContext editingContext = EditingSwingLocator.getSwingManager().getEditingContext(mapControl);
162
                StatusBarListener sbl = new StatusBarListener(mapControl);
163
                editingContext.setDefaultBehaviors(new Behavior[] { new MouseMovementBehavior(sbl) });
164
                editingContext.addObserver(EditingExtension.this);
165
                ApplicationLocator.getManager().refreshMenusAndToolBars();
166
                return mapControl;
167
            }
168
        });
169
    }
170

    
171
    /**
172
     * Register all symbols in the plugin symbols folder in the providerManager.
173
     * The description of the symbols must be unique because the key used for registration is the proper description of the symbol.
174
     *
175
     */
176
    private void registerSymbols() {
177

    
178
        EditingProviderManager providerManager = EditingProviderLocator.getProviderManager();
179

    
180
        SymbolManager symbolManager = MapContextLocator.getSymbolManager();
181
        File symbolsFolder = FileUtils.getFile(getPlugin().getPluginDirectory(), "symbols","editing");
182
        ISymbol[] symbols = null;
183
        try {
184
            symbols = symbolManager.loadSymbols(symbolsFolder);
185
        } catch (SymbolException e) {
186
            logger.warn("No symbols loaded from "+symbolsFolder.getAbsolutePath(), e);
187
        }
188

    
189
        if (symbols != null) {
190
            for (ISymbol symbol : symbols) {
191
                String description = symbol.getDescription();
192
                providerManager.registerSymbol(description, symbol);
193
            }
194
        }
195
    }
196

    
197
    @Override
198
    public boolean isEnabled() {
199
        return true;
200
    }
201

    
202
    @Override
203
    public boolean isVisible() {
204
        return true;
205
    }
206

    
207
    @Override
208
    public boolean isVisible(String action) {
209
        IView view = getActiveView();
210
        FLyrVect activeLayer = getActiveLayer(view);
211

    
212
        if ("start-editing".equals(action)) {
213
            return ((view != null) && (activeLayer != null) && !activeLayer
214
                .isEditing());
215

    
216
        } else {
217
            return ((view != null) && (activeLayer != null) && activeLayer
218
                .isEditing());
219

    
220
        }
221
    }
222

    
223
    @Override
224
    public boolean isEnabled(String action) {
225

    
226
        IView vista = getActiveView();
227
        FLyrVect activeLayer = getActiveLayer(vista);
228

    
229
        if ("start-editing".equals(action)) {
230
            return (canBeEdited(activeLayer));
231

    
232
        } else if ("end-editing".equals(action)) {
233
            return activeLayer.isEditing();
234

    
235
        }
236

    
237
        return false;
238

    
239
    }
240

    
241
    @Override
242
    public boolean canQueryByAction() {
243
        return true;
244
    }
245

    
246
    private IView getActiveView() {
247
        ApplicationManager application = ApplicationLocator.getManager();
248
        IView view = (IView) application.getActiveComponent(ViewDocument.class);
249
        return view;
250
    }
251

    
252
    private boolean canBeEdited(FLyrVect layer) {
253
        if (layer != null && layer.isAvailable()) {
254

    
255
            boolean isNotTransformed =
256
                layer.getFeatureStore().getTransforms().isEmpty();
257

    
258
            return isNotTransformed && !layer.isEditing();
259
        }
260

    
261
        return false;
262
    }
263

    
264
    private FLyrVect getActiveLayer(IView vista) {
265
        if (vista != null) {
266
            ViewDocument viewDocument = vista.getViewDocument();
267
            FLayer[] actives =
268
                viewDocument.getMapContext().getLayers().getActives();
269

    
270
            if ((actives.length == 1) && (actives[0] instanceof FLyrVect)) {
271
                return (FLyrVect) actives[0];
272
            }
273
        }
274
        return null;
275
    }
276

    
277
    @Override
278
    public void update(Observable observable, Object notification) {
279

    
280
        if (notification instanceof Notification){
281
            ApplicationManager appManager = ApplicationLocator.getManager();
282
            Notification n = (Notification)notification;
283
            if (n.isOfType(EditingContext.CHANGE_SELECTED_TOOL_NOTIFICATION)){
284
                String name = (String)n.getValue();
285
                logger.trace("Changed selected tool to '{}'", name);
286
                PluginServices.getMainFrame().setSelectedTool(name);
287
                appManager.refreshMenusAndToolBars();
288

    
289
            } else if (n.isOfType(EditingContext.EXPORT_LAYER_NOTIFICATION)){
290
                exportLayer((FLyrVect)(n.getValue()));
291

    
292
            } else if (n.isOfType(EditingContext.REFRESH_TOOLS_NOTIFICATION)){
293
                appManager.refreshMenusAndToolBars();
294
            }
295
        }
296
    }
297

    
298
    private void exportLayer(FLyrVect layer)  {
299
        ApplicationManager appManager = ApplicationLocator.getManager();
300
        I18nManager i18nManager = ToolsLocator.getI18nManager();
301
        ActionInfo action = PluginsLocator.getActionInfoManager().getAction("layer-exportto");
302
        action.execute(new Object[] { layer, MODE.toInteger(MODE.DIALOG) });
303
        String msg = "_Do_you_want_to_finish_editing_If_not_exported_the_data_the_changes_will_be_lost";
304
        if( appManager.confirmDialog(
305
                i18nManager.getTranslation(msg),
306
                i18nManager.getTranslation("end_editing"),
307
                JOptionPane.YES_NO_OPTION,
308
                JOptionPane.QUESTION_MESSAGE)==JOptionPane.YES_OPTION ) {
309
            try {
310
                layer.getFeatureStore().cancelEditing();
311
            } catch (Exception e) {
312
                logger.warn("Can't abort editing of layer '"+layer.getName()+"'.",e);
313
                msg = "_Cant_finish_editing_See_the_error_log_for_more_information";
314
                appManager.messageDialog(msg, "_Warning", JOptionPane.WARNING_MESSAGE);
315
            }
316
        }
317
    }
318

    
319
    private List<FLyrVect> getEditedLayers(){
320
        ApplicationManager application = ApplicationLocator.getManager();
321
        List<FLyrVect> editedLayers = new ArrayList<>();
322

    
323
        Project project = application.getCurrentProject();
324
        for( Document document : project.getDocuments(ViewManager.TYPENAME) ) {
325
            ViewDocument view = (ViewDocument) document;
326
            MapContext mapContext = view.getMapContext();
327
            if (mapContext != null) {
328
                FLayers layers = mapContext.getLayers();
329
                for (int j = 0; j < layers.getLayersCount(); j++) {
330
                    FLayer lyr = layers.getLayer(j);
331
                    if (lyr instanceof FLyrVect) {
332
                        FLyrVect layerVect = (FLyrVect) lyr;
333
                        if (layerVect.isEditing()) {
334
                            editedLayers.add(layerVect);
335
                        }
336
                    }
337
                }
338
            }
339
        }
340
        return editedLayers;
341
    }
342

    
343
    private List<IUnsavedData> getUnsavedData(List<FLyrVect> editedLayers){
344
        List<IUnsavedData> unsavedData = new ArrayList<>();
345
        for (FLyrVect editedLayer : editedLayers) {
346
            IUnsavedData unsavedDataLayer = new UnsavedLayer(this, editedLayer);
347
            unsavedData.add(unsavedDataLayer);
348
        }
349
        return unsavedData;
350

    
351
    }
352

    
353
    private static class UnsavedLayer extends UnsavedData {
354
        private final FLyrVect layer;
355

    
356
        public UnsavedLayer(IExtension extension, FLyrVect layer) {
357
            super(extension);
358
            this.layer = layer;
359
        }
360

    
361
        @Override
362
        public String getDescription() {
363
            return layer.getName();
364
        }
365

    
366
        @Override
367
        public String getResourceName() {
368
            return layer.getFeatureStore().getFullName();
369
        }
370

    
371
        @Override
372
        public boolean saveData() {
373
            FeatureStore featureStore = layer.getFeatureStore();
374
            if(featureStore.isEditing()){
375
                try {
376
                    featureStore.finishEditing();
377
                    return true;
378
                } catch (DataException e) {
379
                    throw new RuntimeException(e);
380
                }
381
            }
382
            return true;
383
        }
384
    }
385

    
386
    @Override
387
    public IExtensionStatus getStatus() {
388
        List<FLyrVect> editedLayers = getEditedLayers();
389
        final List<IUnsavedData> unsavedData = getUnsavedData(editedLayers);
390

    
391
        return new IExtensionStatus() {
392

    
393
            @Override
394
            public boolean hasUnsavedData() {
395
                if(unsavedData == null){
396
                    return false;
397
                }
398
                return !unsavedData.isEmpty();
399
            }
400

    
401
            @Override
402
            public boolean hasRunningProcesses() {
403
                return false;
404
            }
405

    
406
            @Override
407
            public IUnsavedData[] getUnsavedData() {
408
                if(unsavedData == null){
409
                    return null;
410
                }
411
                return unsavedData.toArray(new IUnsavedData[0]);
412
            }
413

    
414
            @Override
415
            public IMonitorableTask[] getRunningProcesses() {
416
                return null;
417
            }
418
        };
419
    }
420
}