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 @ 4337

History | View | Annotate | Download (28 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.awt.Component;
27
import java.awt.event.ActionEvent;
28
import java.io.File;
29
import java.util.ArrayList;
30
import java.util.Collections;
31
import java.util.HashSet;
32
import java.util.List;
33
import java.util.Set;
34
import java.util.function.Predicate;
35
import javax.swing.AbstractAction;
36
import javax.swing.Action;
37
import javax.swing.JMenuItem;
38
import javax.swing.JOptionPane;
39
import javax.swing.JPopupMenu;
40
import org.apache.commons.collections4.CollectionUtils;
41
import org.apache.commons.io.FileUtils;
42
import org.apache.commons.lang.StringUtils;
43

    
44
import org.slf4j.Logger;
45
import org.slf4j.LoggerFactory;
46

    
47
import org.gvsig.andami.IconThemeHelper;
48
import org.gvsig.andami.PluginServices;
49
import org.gvsig.andami.PluginsLocator;
50
import org.gvsig.andami.actioninfo.ActionInfo;
51
import org.gvsig.andami.plugins.Extension;
52
import org.gvsig.andami.plugins.IExtension;
53
import org.gvsig.andami.plugins.status.IExtensionStatus;
54
import org.gvsig.andami.plugins.status.IUnsavedData;
55
import org.gvsig.andami.plugins.status.UnsavedData;
56
import org.gvsig.app.ApplicationLocator;
57
import org.gvsig.app.ApplicationManager;
58
import org.gvsig.app.extension.evalexpression.EvaluateExpressionExtension;
59
import org.gvsig.app.extension.evalexpression.EvaluateExpressionPanel;
60
import org.gvsig.app.extension.evalexpression.notifierfactory.AbstractUpdaterFactory;
61
import org.gvsig.app.extension.evalexpression.notifierfactory.UpdaterFactory;
62
import org.gvsig.app.project.Project;
63
import org.gvsig.app.project.documents.Document;
64
import org.gvsig.app.project.documents.view.ViewDocument;
65
import org.gvsig.app.project.documents.view.ViewManager;
66
import org.gvsig.app.project.documents.view.gui.DefaultViewPanel;
67
import org.gvsig.app.project.documents.view.gui.IView;
68
import org.gvsig.app.project.documents.view.toc.actions.EndEditingTocMenuEntry;
69
import org.gvsig.app.project.documents.view.toc.actions.StartEditingTocMenuEntry;
70
import org.gvsig.app.project.documents.view.toolListeners.StatusBarListener;
71
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingLocator;
72
import org.gvsig.expressionevaluator.swing.JExpressionBuilder;
73
import org.gvsig.fmap.dal.exception.DataException;
74
import org.gvsig.fmap.dal.feature.FeatureStore;
75
import org.gvsig.fmap.mapcontext.MapContext;
76
import org.gvsig.fmap.mapcontext.MapContextLocator;
77
import org.gvsig.fmap.mapcontext.layers.FLayer;
78
import org.gvsig.fmap.mapcontext.layers.FLayers;
79
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
80
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
81
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolException;
82
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
83
import org.gvsig.fmap.mapcontrol.MapControl;
84
import org.gvsig.fmap.mapcontrol.MapControlCreationListener;
85
import org.gvsig.fmap.mapcontrol.MapControlLocator;
86
import org.gvsig.fmap.mapcontrol.MapControlManager;
87
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
88
import org.gvsig.fmap.mapcontrol.tools.Behavior.MouseMovementBehavior;
89
import org.gvsig.tools.ToolsLocator;
90
import org.gvsig.tools.dynform.spi.DynFormSPILocator;
91
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
92
import org.gvsig.tools.extensionpoint.ExtensionPoint;
93
import org.gvsig.tools.i18n.I18nManager;
94
import org.gvsig.tools.observer.Notification;
95
import org.gvsig.tools.observer.Observable;
96
import org.gvsig.tools.observer.Observer;
97
import org.gvsig.tools.swing.api.ToolsSwingLocator;
98
import org.gvsig.tools.swing.api.windowmanager.Dialog;
99
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
100
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
101
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
102
import org.gvsig.utils.swing.threads.IMonitorableTask;
103
import org.gvsig.vectorediting.app.mainplugin.dynformfield.point.JDynFormFieldPointFactory;
104
import org.gvsig.vectorediting.lib.api.EditingService;
105
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
106
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
107
import org.gvsig.vectorediting.swing.api.EditingContext;
108
import org.gvsig.vectorediting.swing.api.EditingSwingLocator;
109
import org.gvsig.vectorediting.swing.api.EditingSwingManager;
110
import org.gvsig.vectorediting.swing.api.console.EditingConsole;
111

    
112
@SuppressWarnings("UseSpecificCatch")
113
public class EditingExtension extends Extension implements Observer {
114

    
115
    private static final Logger LOGGER = LoggerFactory.getLogger(EditingExtension.class);
116
    
117
    private VectorEditingUpdaterFactory vectorEditingUpdaterFactory;
118

    
119
    @Override
120
    public void execute(String actionCommand) {
121
        IView view = getActiveView();
122
        EditingSwingManager swingManager = EditingSwingLocator.getSwingManager();
123

    
124
        if (view != null) {
125
            EditingContext editingContext = swingManager.getEditingContext(view.getMapControl());
126

    
127
            if ("start-editing".equals(actionCommand)) {
128
                doStartEditing(view, editingContext);
129

    
130
            } else if ("end-editing".equals(actionCommand)) {
131
                doEndEditing(view, editingContext);
132

    
133
            } else if ("vector-editing-tooloptions".equalsIgnoreCase(actionCommand)) {
134
                doToolOptions(editingContext);
135
            } else if ("vector-editing-ortomode-enable".equalsIgnoreCase(actionCommand)) {
136
                editingContext.setDrawMode(EditingContext.DRAWMODE_ORTO);
137
            } else if ("vector-editing-ortomode-disable".equalsIgnoreCase(actionCommand)) {
138
                editingContext.setDrawMode(EditingContext.DRAWMODE_NORMAL);
139
            }
140
        }
141
    }
142

    
143
    private void doStartEditing(IView view, EditingContext editingContext) {
144
        ApplicationManager application = ApplicationLocator.getManager();
145
        MapControl mapControl = view.getMapControl();
146
        List<FLyrVect> reprojectedLayers = getActiveLayers(
147
                view,
148
                (FLyrVect layer) -> canBeEdited(layer)
149
                && !mapControl.getProjection().equals(layer.getProjection())
150
        );
151
        if (!reprojectedLayers.isEmpty()) {
152
            String msg = "_The_layer_is_reproyected_on_the_fly"
153
                    + "_Not_all_editing_tools_work_properly"
154
                    + "_When_you_finish_editing"
155
                    + "_will_only_export_the_changes_to_another_layer";
156
            application.messageDialog(msg, "_Warning", JOptionPane.WARNING_MESSAGE);
157
        } else {
158
            List<FLyrVect> nonWritableLayers = getActiveLayers(
159
                    view,
160
                    (FLyrVect layer) -> canBeEdited(layer) && !isWritable(layer)
161
            );
162
            if (!nonWritableLayers.isEmpty()) {
163
                String msg = "_The_layer_can_not_be_written"
164
                        + "_When_you_finish_editing"
165
                        + "_will_only_export_the_changes_to_another_layer";
166
                application.messageDialog(msg, "_Warning", JOptionPane.WARNING_MESSAGE);
167
            }
168
        }
169
        List<FLyrVect> activeLayers = getActiveLayers(
170
                view,
171
                (FLyrVect layer) -> canBeEdited(layer)
172
        );
173
        for (FLyrVect layer : activeLayers) {
174
            editingContext.beginEdition(layer);
175
            editingContext.addObserver(this);
176
        }
177
        
178
        EditingConsole console = editingContext.getConsolePanel();
179
        JPopupMenu popup = console.getComponentPopupMenu();
180
        boolean needadd = true;
181
        for (int i = 0; i < popup.getComponentCount(); i++) {
182
            Component comp = popup.getComponent(i);
183
            if( StringUtils.equals("ExpressionBuilder",comp.getName()) ) {
184
                needadd = false;
185
                break;
186
            }
187
        }
188
        if( needadd ) {
189
            JMenuItem entry = new JMenuItem(new ExpressionBuilderAction(editingContext, console));
190
            entry.setName("ExpressionBuilder");
191
            popup.add(entry);
192
        }
193
        ApplicationLocator.getManager().refreshMenusAndToolBars();
194
    }
195

    
196
    private void doEndEditing(IView view, EditingContext editingContext) {
197
        List<FLyrVect> activeLayers = getActiveLayers(
198
                view,
199
                (FLyrVect layer) -> layer.isEditing()
200
        );
201
//                for (FLyrVect layer : activeLayers) {
202
//                    editingContext.endEdition(layer);
203
//                }
204
        if (CollectionUtils.isEmpty(activeLayers)) {
205
            return;
206
        }
207
        if (activeLayers.size() == 1) {
208
            editingContext.endEdition(activeLayers.get(0));
209
            ApplicationLocator.getManager().refreshMenusAndToolBars();
210
        } else {
211
            showMultilaterFinishEditingPanel(view.getMapControl().getMapContext());
212
        }
213
    }
214

    
215
    private void doToolOptions(EditingContext editingContext) {
216
        I18nManager i18n = ToolsLocator.getI18nManager();
217
//        EditingSwingManager editingSwingManager = EditingSwingLocator.getSwingManager();
218
        if (editingContext == null) {
219
            return;
220
        }
221
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
222
        EditingToolOptionsPanel panel = new EditingToolOptionsPanel(editingContext);
223
        windowManager.showWindow(
224
                panel,
225
                i18n.getTranslation("_Vector_editing_tool_options"),
226
                WindowManager.MODE.TOOL
227
        );
228
    }
229

    
230
    @Override
231
    public void initialize() {
232
        registerIcons();
233

    
234
        // Disable default view panel console. Uses editing context console.
235
        DefaultViewPanel.setDisableConsole(true);
236

    
237
        // Adding TOC menu entry
238
        ExtensionPoint exPoint = ToolsLocator.getExtensionPointManager().add(
239
                "View_TocActions", "");
240
        exPoint.append(
241
                StartEditingTocMenuEntry.EXTENSION_POINT_NAME,
242
                "TOC popup menu to start vector layer's editing",
243
                new StartEditingTocMenuEntry());
244
        exPoint.append(
245
                EndEditingTocMenuEntry.EXTENSION_POINT_NAME,
246
                "TOC popup menu to end vector layer's editing",
247
                new EndEditingTocMenuEntry());
248
        EditingToolOptionsPanel.registerPersistence();
249
        
250
        this.vectorEditingUpdaterFactory = new VectorEditingUpdaterFactory();
251
        EvaluateExpressionPanel.registerUpdater(this.vectorEditingUpdaterFactory);
252
    }
253

    
254
    private void registerIcons() {
255
        IconThemeHelper.registerIcon("vectorediting-tools", "vector-editing", this);
256
        IconThemeHelper.registerIcon("vectorediting-tools", "vector-editing-tooloptions", this);
257
//        IconThemeHelper.registerIcon("vectorediting-tools", "vector-editing-tooloptions-confirm", this);
258
        IconThemeHelper.registerIcon("vectorediting-tools", "vector-editing-ortomode-enable", this);
259
        IconThemeHelper.registerIcon("vectorediting-tools", "vector-editing-ortomode-disable", this);
260
    }
261

    
262
    @Override
263
    @SuppressWarnings("Convert2Lambda")
264
    public void postInitialize() {
265
        super.postInitialize();
266
        registerSymbols();
267

    
268
        MapControlManager mapControlManager = MapControlLocator.getMapControlManager();
269
        mapControlManager.addMapControlCreationListener(new MapControlCreationListener() {
270
            @Override
271
            public MapControl mapControlCreated(MapControl mapControl) {
272
                EditingContext editingContext = EditingSwingLocator.getSwingManager().getEditingContext(mapControl);
273
                StatusBarListener sbl = new StatusBarListener(mapControl);
274
                editingContext.setDefaultBehaviors(new Behavior[]{new MouseMovementBehavior(sbl)});
275
                editingContext.addObserver(EditingExtension.this);
276
                ApplicationLocator.getManager().refreshMenusAndToolBars();
277
                return mapControl;
278
            }
279
        });
280

    
281
        DynFormSPIManager dynFormManager = DynFormSPILocator.getDynFormSPIManager();
282
        dynFormManager.registerDynFieldFactory(new JDynFormFieldPointFactory());
283

    
284
    }
285

    
286
    /**
287
     * Register all symbols in the plugin symbols folder in the providerManager.
288
     * The description of the symbols must be unique because the key used for
289
     * registration is the proper description of the symbol.
290
     *
291
     */
292
    private void registerSymbols() {
293

    
294
        EditingProviderManager providerManager = EditingProviderLocator.getProviderManager();
295

    
296
        SymbolManager symbolManager = MapContextLocator.getSymbolManager();
297
        File symbolsFolder = FileUtils.getFile(getPlugin().getPluginDirectory(), "symbols", "editing");
298
        ISymbol[] symbols = null;
299
        try {
300
            symbols = symbolManager.loadSymbols(symbolsFolder);
301
        } catch (SymbolException e) {
302
            LOGGER.warn("No symbols loaded from " + symbolsFolder.getAbsolutePath(), e);
303
        }
304

    
305
        if (symbols != null) {
306
            for (ISymbol symbol : symbols) {
307
                String description = symbol.getDescription();
308
                providerManager.registerSymbol(description, symbol);
309
            }
310
        }
311
    }
312

    
313
    @Override
314
    public boolean isEnabled() {
315
        return true;
316
    }
317

    
318
    @Override
319
    public boolean isVisible() {
320
        return true;
321
    }
322

    
323
    @Override
324
    public boolean isVisible(String action) {
325
        IView view = getActiveView();
326
        if (view == null) {
327
            return false;
328
        }
329
        EditingSwingManager swingManager = EditingSwingLocator.getSwingManager();
330
        EditingContext editingContext = swingManager.getEditingContext(view.getMapControl());
331
        if ("start-editing".equals(action)) {
332
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> !layer.isEditing());
333
            return !activeLayers.isEmpty();
334
        } else if ("vector-editing-ortomode-enable".equals(action)) {
335
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> layer.isEditing());
336
            return editingContext.getDrawMode()==EditingContext.DRAWMODE_NORMAL && !activeLayers.isEmpty();
337
        } else if ("vector-editing-ortomode-disable".equals(action)) {
338
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> layer.isEditing());
339
            return editingContext.getDrawMode()==EditingContext.DRAWMODE_ORTO && !activeLayers.isEmpty();
340
        } else {
341
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> layer.isEditing());
342
            return !activeLayers.isEmpty();
343
        }
344
    }
345

    
346
    @Override
347
    @SuppressWarnings("ConvertToStringSwitch")
348
    public boolean isEnabled(String action) {
349
        IView view = getActiveView();
350
        if (view == null) {
351
            return false;
352
        }
353
        EditingSwingManager swingManager = EditingSwingLocator.getSwingManager();
354
        EditingContext editingContext = swingManager.getEditingContext(view.getMapControl());
355
        if( editingContext.isProcessing() ) {
356
            return false;
357
        }
358
        
359
        if ("start-editing".equals(action)) {
360
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> canBeEdited(layer));
361
            return !activeLayers.isEmpty();
362

    
363
        } else if ("end-editing".equals(action)) {
364
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> layer.isEditing());
365
            return !activeLayers.isEmpty();
366

    
367
        } else if ("vector-editing-tooloptions".equals(action)) {
368
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> layer.isEditing());
369
            return !activeLayers.isEmpty();
370
        } else if ("vector-editing-ortomode-enable".equals(action)) {
371
            return editingContext.getDrawMode()==EditingContext.DRAWMODE_NORMAL;
372
        } else if ("vector-editing-ortomode-disable".equals(action)) {
373
            return editingContext.getDrawMode()==EditingContext.DRAWMODE_ORTO;
374
        }
375

    
376
        return false;
377

    
378
    }
379

    
380
    @Override
381
    public boolean canQueryByAction() {
382
        return true;
383
    }
384

    
385
    private IView getActiveView() {
386
        ApplicationManager application = ApplicationLocator.getManager();
387
        IView view = (IView) application.getActiveComponent(ViewDocument.class);
388
        return view;
389
    }
390

    
391
    private boolean isWritable(FLyrVect layer) {
392
        if (layer != null && layer.isAvailable() && layer.isVisible()) {
393
            return layer.getFeatureStore().allowWrite();
394
        }
395
        return false;
396
    }
397

    
398
    private boolean canBeEdited(FLyrVect layer) {
399
        if (layer != null && layer.isAvailable() && layer.isVisible()) {
400
            FeatureStore store = layer.getFeatureStore();
401
            boolean storeCanBeEdited=  false;
402
            if(store != null){
403
                storeCanBeEdited = store.canBeEdited();
404
            }
405
            return storeCanBeEdited && !layer.isEditing();
406
        }
407

    
408
        return false;
409
    }
410

    
411
//  private FLyrVect getActiveLayer(IView vista) {
412
//    if (vista != null) {
413
//      ViewDocument viewDocument = vista.getViewDocument();
414
//      FLayer[] actives
415
//              = viewDocument.getMapContext().getLayers().getActives();
416
//
417
//      if ((actives.length == 1) && (actives[0] instanceof FLyrVect)) {
418
//        return (FLyrVect) actives[0];
419
//      }
420
//    }
421
//    return null;
422
//  }
423
    private List<FLyrVect> getActiveLayers(IView view, Predicate<FLyrVect> valid) {
424
        if (view == null) {
425
            return Collections.EMPTY_LIST;
426
        }
427
        List<FLyrVect> layers = new ArrayList<>();
428
        ViewDocument viewDocument = view.getViewDocument();
429
        FLayer[] actives = viewDocument.getMapContext().getLayers().getActives();
430
        for (FLayer layer : actives) {
431
            if (layer instanceof FLyrVect && valid.test((FLyrVect) layer)) {
432
                layers.add((FLyrVect) layer);
433
            }
434
        }
435
        return layers;
436
    }
437

    
438
    @Override
439
    public void update(Observable observable, Object notification) {
440

    
441
        if (notification instanceof Notification) {
442
            ApplicationManager appManager = ApplicationLocator.getManager();
443
            Notification n = (Notification) notification;
444
            if (n.isOfType(EditingContext.CHANGE_SELECTED_TOOL_NOTIFICATION)) {
445
                String name = (String) n.getValue();
446
                if( name!=null ) {
447
                    LOGGER.trace("Changed selected tool to '{}'", name);
448
                    appManager.getMainFrame().setSelectedTool(name);
449
                    appManager.refreshMenusAndToolBars();
450
                }
451

    
452
            } else if (n.isOfType(EditingContext.EXPORT_LAYER_NOTIFICATION)) {
453
                exportLayer((FLyrVect) (n.getValue()));
454

    
455
            } else if (n.isOfType(EditingContext.REFRESH_TOOLS_NOTIFICATION)) {
456
                EditingService activeService = ((EditingContext)observable).getActiveService();
457
                if(activeService != null){
458
                    appManager.getMainFrame().setSelectedTool(activeService.getName());
459
                }
460
                appManager.refreshMenusAndToolBars();
461
            }
462
            this.vectorEditingUpdaterFactory.updateAll(n);
463
        }
464
    }
465

    
466
    private void exportLayer(FLyrVect layer) {
467
        ApplicationManager appManager = ApplicationLocator.getManager();
468
        I18nManager i18nManager = ToolsLocator.getI18nManager();
469
        ActionInfo action = PluginsLocator.getActionInfoManager().getAction("layer-exportto");
470
        action.execute(new Object[]{layer, MODE.toInteger(MODE.DIALOG)});
471
        String msg = "_Do_you_want_to_finish_editing_If_not_exported_the_data_the_changes_will_be_lost";
472
        if (appManager.confirmDialog(
473
                i18nManager.getTranslation(msg),
474
                i18nManager.getTranslation("end_editing"),
475
                JOptionPane.YES_NO_OPTION,
476
                JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
477
            try {
478
                layer.getFeatureStore().cancelEditing();
479
            } catch (Exception e) {
480
                LOGGER.warn("Can't abort editing of layer '" + layer.getName() + "'.", e);
481
                msg = "_Cant_finish_editing_See_the_error_log_for_more_information";
482
                appManager.messageDialog(msg, "_Warning", JOptionPane.WARNING_MESSAGE);
483
            }
484
        }
485
    }
486

    
487
    private List<FLyrVect> getEditedLayers() {
488
        ApplicationManager application = ApplicationLocator.getManager();
489
        List<FLyrVect> editedLayers = new ArrayList<>();
490

    
491
        Project project = application.getCurrentProject();
492
        for (Document document : project.getDocuments(ViewManager.TYPENAME)) {
493
            ViewDocument view = (ViewDocument) document;
494
            MapContext mapContext = view.getMapContext();
495
            if (mapContext != null) {
496
                FLayers layers = mapContext.getLayers();
497
                for (int j = 0; j < layers.getLayersCount(); j++) {
498
                    FLayer lyr = layers.getLayer(j);
499
                    if (lyr instanceof FLyrVect) {
500
                        FLyrVect layerVect = (FLyrVect) lyr;
501
                        if (layerVect.isEditing()) {
502
                            editedLayers.add(layerVect);
503
                        }
504
                    }
505
                }
506
            }
507
        }
508
        return editedLayers;
509
    }
510

    
511
    private List<IUnsavedData> getUnsavedData(List<FLyrVect> editedLayers) {
512
        List<IUnsavedData> unsavedData = new ArrayList<>();
513
        for (FLyrVect editedLayer : editedLayers) {
514
            IUnsavedData unsavedDataLayer = new UnsavedLayer(this, editedLayer);
515
            unsavedData.add(unsavedDataLayer);
516
        }
517
        return unsavedData;
518

    
519
    }
520

    
521
    private static class UnsavedLayer extends UnsavedData {
522

    
523
        private final FLyrVect layer;
524

    
525
        public UnsavedLayer(IExtension extension, FLyrVect layer) {
526
            super(extension);
527
            this.layer = layer;
528
        }
529

    
530
        @Override
531
        public String getDescription() {
532
            return layer.getName();
533
        }
534

    
535
        @Override
536
        public String getResourceName() {
537
            return layer.getFeatureStore().getFullName();
538
        }
539

    
540
        @Override
541
        public boolean saveData() {
542
            FeatureStore featureStore = layer.getFeatureStore();
543
            if (featureStore.isEditing()) {
544
                try {
545
                    featureStore.finishEditing();
546
                    return true;
547
                } catch (DataException e) {
548
                    throw new RuntimeException(e);
549
                }
550
            }
551
            return true;
552
        }
553
    }
554

    
555
    @Override
556
    public IExtensionStatus getStatus() {
557
        List<FLyrVect> editedLayers = getEditedLayers();
558
        final List<IUnsavedData> unsavedData = getUnsavedData(editedLayers);
559

    
560
        return new IExtensionStatus() {
561

    
562
            @Override
563
            public boolean hasUnsavedData() {
564
                if (unsavedData == null) {
565
                    return false;
566
                }
567
                return !unsavedData.isEmpty();
568
            }
569

    
570
            @Override
571
            public boolean hasRunningProcesses() {
572
                return false;
573
            }
574

    
575
            @Override
576
            public IUnsavedData[] getUnsavedData() {
577
                if (unsavedData == null) {
578
                    return null;
579
                }
580
                return unsavedData.toArray(new IUnsavedData[0]);
581
            }
582

    
583
            @Override
584
            public IMonitorableTask[] getRunningProcesses() {
585
                return null;
586
            }
587
        };
588
    }
589

    
590
    private void showMultilaterFinishEditingPanel(MapContext mapContext) {
591
        I18nManager i18n = ToolsLocator.getI18nManager();
592
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
593
        MultilayerFinishEditingPanel finishEditingPanel = new MultilayerFinishEditingPanel(mapContext);
594
        Dialog dialog = windowManager.createDialog(
595
                finishEditingPanel.asJComponent(),
596
                i18n.getTranslation("end_editing"),
597
                i18n.getTranslation("_List_of_layers_to_finish_editing"),
598
                WindowManager_v2.BUTTONS_OK_CANCEL
599
        );
600
        finishEditingPanel.setDialog(dialog);
601
        dialog.addActionListener((ActionEvent e) -> {
602
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
603
                finishEditingPanel.apply();
604
            }
605
        });
606
        dialog.show(WindowManager.MODE.WINDOW);
607
    }
608

    
609
    private static class ExpressionBuilderAction extends AbstractAction {
610

    
611
        private final EditingConsole console;
612
        private final EditingContext editingContext;
613
        
614
        
615
        @SuppressWarnings("OverridableMethodCallInConstructor")
616
        public ExpressionBuilderAction(EditingContext editingContext, EditingConsole console) {
617
            this.editingContext = editingContext;
618
            this.console = console;
619
            I18nManager i18n = ToolsLocator.getI18nManager();
620
            this.putValue(
621
                    Action.ACTION_COMMAND_KEY, 
622
                    "CreateJExpressionBuilderAction"
623
            );
624
            this.putValue(
625
                    Action.NAME, 
626
                    i18n.getTranslation("_Show_expression_builder")
627
            );
628
            this.putValue(
629
                    Action.SMALL_ICON, 
630
                    ToolsSwingLocator.getIconThemeManager().getCurrent().get("picker-expression")
631
            );
632
        }
633
        
634
        @Override
635
        public void actionPerformed(ActionEvent e) {
636
            I18nManager i18n = ToolsLocator.getI18nManager();
637
            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
638
            final JExpressionBuilder panel = ExpressionEvaluatorSwingLocator.getManager().createJExpressionBuilder();
639
            panel.getConfig().addSymbolTable(this.editingContext.getContextSymbolTable());
640
            panel.getConfig().setPreviewSymbolTable(this.editingContext.getContextSymbolTable());
641
            final Dialog dialog = winmgr.createDialog(
642
                    panel.asJComponent(),
643
                    i18n.getTranslation("_Expression_builder"),
644
                    null, 
645
                    WindowManager_v2.BUTTONS_OK_CANCEL
646
            );
647
            dialog.addActionListener((ActionEvent e2) -> {
648
                if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
649
                    console.addResponseText(panel.getExpression().getPhrase());
650
                }
651
            });
652
            dialog.show(WindowManager.MODE.DIALOG);
653
        }
654
        
655
    }
656

    
657

    
658
    private static class VectorEditingUpdaterFactory extends AbstractUpdaterFactory {
659

    
660
        private final Set<VectorEditingUpdater> vectorEditingUpdaters = new HashSet<>();
661

    
662
        private class VectorEditingUpdater extends AbstractUpdaterFactory.AbstractUpdater {
663

    
664
            @SuppressWarnings("Convert2Lambda")
665
            public VectorEditingUpdater(UpdaterFactory factory, Observer observer) {
666
                super(factory, observer);
667
            }
668

    
669
            @Override
670
            public void add() {
671
                vectorEditingUpdaters.add(this);
672
            }
673

    
674
            @Override
675
            public void remove() {
676
                vectorEditingUpdaters.remove(this);
677
            }
678

    
679
        }
680

    
681
        public VectorEditingUpdaterFactory() {
682
            super("VectorEditing", "Actualizar cuando cambie la edicion vectorial");
683
        }
684

    
685
        @Override
686
        public UpdaterFactory.Updater create(Observer observer) {
687
            UpdaterFactory.Updater updater = new VectorEditingUpdater(this, observer);
688
            return updater;
689
        }
690

    
691
        public void updateAll(Notification n) {
692
            for (VectorEditingUpdater vectorEditingUpdater : vectorEditingUpdaters) {
693
                vectorEditingUpdater.update(n);
694
            }        
695
        }
696
    }
697

    
698

    
699
    
700
}