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

History | View | Annotate | Download (25.6 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.List;
32
import java.util.function.Predicate;
33
import javax.swing.AbstractAction;
34
import javax.swing.Action;
35
import javax.swing.JMenuItem;
36
import javax.swing.JOptionPane;
37
import javax.swing.JPopupMenu;
38
import org.apache.commons.collections4.CollectionUtils;
39
import org.apache.commons.io.FileUtils;
40
import org.codehaus.plexus.util.StringUtils;
41

    
42
import org.slf4j.Logger;
43
import org.slf4j.LoggerFactory;
44

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

    
105
@SuppressWarnings("UseSpecificCatch")
106
public class EditingExtension extends Extension implements Observer {
107

    
108
    private static final Logger LOGGER = LoggerFactory.getLogger(EditingExtension.class);
109

    
110
    @Override
111
    public void execute(String actionCommand) {
112
        IView view = getActiveView();
113
        EditingSwingManager swingManager = EditingSwingLocator.getSwingManager();
114

    
115
        if (view != null) {
116
            EditingContext editingContext = swingManager.getEditingContext(view.getMapControl());
117

    
118
            if ("start-editing".equals(actionCommand)) {
119
                doStartEditing(view, editingContext);
120

    
121
            } else if ("end-editing".equals(actionCommand)) {
122
                doEndEditing(view, editingContext);
123

    
124
            } else if ("vector-editing-tooloptions".equalsIgnoreCase(actionCommand)) {
125
                doToolOptions(editingContext);
126
            } else if ("vector-editing-ortomode-enable".equalsIgnoreCase(actionCommand)) {
127
                editingContext.setDrawMode(EditingContext.DRAWMODE_ORTO);
128
            } else if ("vector-editing-ortomode-disable".equalsIgnoreCase(actionCommand)) {
129
                editingContext.setDrawMode(EditingContext.DRAWMODE_NORMAL);
130
            }
131
        }
132
    }
133

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

    
187
    private void doEndEditing(IView view, EditingContext editingContext) {
188
        List<FLyrVect> activeLayers = getActiveLayers(
189
                view,
190
                (FLyrVect layer) -> layer.isEditing()
191
        );
192
//                for (FLyrVect layer : activeLayers) {
193
//                    editingContext.endEdition(layer);
194
//                }
195
        if (CollectionUtils.isEmpty(activeLayers)) {
196
            return;
197
        }
198
        if (activeLayers.size() == 1) {
199
            editingContext.endEdition(activeLayers.get(0));
200
            ApplicationLocator.getManager().refreshMenusAndToolBars();
201
        } else {
202
            showMultilaterFinishEditingPanel(view.getMapControl().getMapContext());
203
        }
204
    }
205

    
206
    private void doToolOptions(EditingContext editingContext) {
207
        I18nManager i18n = ToolsLocator.getI18nManager();
208
//        EditingSwingManager editingSwingManager = EditingSwingLocator.getSwingManager();
209
        if (editingContext == null) {
210
            return;
211
        }
212
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
213
        EditingToolOptionsPanel panel = new EditingToolOptionsPanel(editingContext);
214
        windowManager.showWindow(
215
                panel,
216
                i18n.getTranslation("_Vector_editing_tool_options"),
217
                WindowManager.MODE.TOOL
218
        );
219
    }
220

    
221
    @Override
222
    public void initialize() {
223
        registerIcons();
224

    
225
        // Disable default view panel console. Uses editing context console.
226
        DefaultViewPanel.setDisableConsole(true);
227

    
228
        // Adding TOC menu entry
229
        ExtensionPoint exPoint = ToolsLocator.getExtensionPointManager().add(
230
                "View_TocActions", "");
231
        exPoint.append(
232
                StartEditingTocMenuEntry.EXTENSION_POINT_NAME,
233
                "TOC popup menu to start vector layer's editing",
234
                new StartEditingTocMenuEntry());
235
        exPoint.append(
236
                EndEditingTocMenuEntry.EXTENSION_POINT_NAME,
237
                "TOC popup menu to end vector layer's editing",
238
                new EndEditingTocMenuEntry());
239
        EditingToolOptionsPanel.registerPersistence();
240
    }
241

    
242
    private void registerIcons() {
243
        IconThemeHelper.registerIcon("vectorediting", "vector-editing", this);
244
        IconThemeHelper.registerIcon("vectorediting", "vector-editing-tooloptions", this);
245
        IconThemeHelper.registerIcon("vectorediting", "vector-editing-tooloptions-confirm", this);
246
        IconThemeHelper.registerIcon("vectorediting", "vector-editing-ortomode-enable", this);
247
        IconThemeHelper.registerIcon("vectorediting", "vector-editing-ortomode-disable", this);
248
    }
249

    
250
    @Override
251
    @SuppressWarnings("Convert2Lambda")
252
    public void postInitialize() {
253
        super.postInitialize();
254
        registerSymbols();
255

    
256
        MapControlManager mapControlManager = MapControlLocator.getMapControlManager();
257
        mapControlManager.addMapControlCreationListener(new MapControlCreationListener() {
258
            @Override
259
            public MapControl mapControlCreated(MapControl mapControl) {
260
                EditingContext editingContext = EditingSwingLocator.getSwingManager().getEditingContext(mapControl);
261
                StatusBarListener sbl = new StatusBarListener(mapControl);
262
                editingContext.setDefaultBehaviors(new Behavior[]{new MouseMovementBehavior(sbl)});
263
                editingContext.addObserver(EditingExtension.this);
264
                ApplicationLocator.getManager().refreshMenusAndToolBars();
265
                return mapControl;
266
            }
267
        });
268

    
269
        DynFormSPIManager dynFormManager = DynFormSPILocator.getDynFormSPIManager();
270
        dynFormManager.registerDynFieldFactory(new JDynFormFieldPointFactory());
271

    
272
    }
273

    
274
    /**
275
     * Register all symbols in the plugin symbols folder in the providerManager.
276
     * The description of the symbols must be unique because the key used for
277
     * registration is the proper description of the symbol.
278
     *
279
     */
280
    private void registerSymbols() {
281

    
282
        EditingProviderManager providerManager = EditingProviderLocator.getProviderManager();
283

    
284
        SymbolManager symbolManager = MapContextLocator.getSymbolManager();
285
        File symbolsFolder = FileUtils.getFile(getPlugin().getPluginDirectory(), "symbols", "editing");
286
        ISymbol[] symbols = null;
287
        try {
288
            symbols = symbolManager.loadSymbols(symbolsFolder);
289
        } catch (SymbolException e) {
290
            LOGGER.warn("No symbols loaded from " + symbolsFolder.getAbsolutePath(), e);
291
        }
292

    
293
        if (symbols != null) {
294
            for (ISymbol symbol : symbols) {
295
                String description = symbol.getDescription();
296
                providerManager.registerSymbol(description, symbol);
297
            }
298
        }
299
    }
300

    
301
    @Override
302
    public boolean isEnabled() {
303
        return true;
304
    }
305

    
306
    @Override
307
    public boolean isVisible() {
308
        return true;
309
    }
310

    
311
    @Override
312
    public boolean isVisible(String action) {
313
        IView view = getActiveView();
314
        if (view == null) {
315
            return false;
316
        }
317
        EditingSwingManager swingManager = EditingSwingLocator.getSwingManager();
318
        EditingContext editingContext = swingManager.getEditingContext(view.getMapControl());
319
        if ("start-editing".equals(action)) {
320
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> !layer.isEditing());
321
            return !activeLayers.isEmpty();
322
        } else if ("vector-editing-ortomode-enable".equals(action)) {
323
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> layer.isEditing());
324
            return editingContext.getDrawMode()==EditingContext.DRAWMODE_NORMAL && !activeLayers.isEmpty();
325
        } else if ("vector-editing-ortomode-disable".equals(action)) {
326
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> layer.isEditing());
327
            return editingContext.getDrawMode()==EditingContext.DRAWMODE_ORTO && !activeLayers.isEmpty();
328
        } else {
329
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> layer.isEditing());
330
            return !activeLayers.isEmpty();
331
        }
332
    }
333

    
334
    @Override
335
    @SuppressWarnings("ConvertToStringSwitch")
336
    public boolean isEnabled(String action) {
337
        IView view = getActiveView();
338
        if (view == null) {
339
            return false;
340
        }
341
        EditingSwingManager swingManager = EditingSwingLocator.getSwingManager();
342
        EditingContext editingContext = swingManager.getEditingContext(view.getMapControl());
343
        if( editingContext.isProcessing() ) {
344
            return false;
345
        }
346
        
347
        if ("start-editing".equals(action)) {
348
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> canBeEdited(layer));
349
            return !activeLayers.isEmpty();
350

    
351
        } else if ("end-editing".equals(action)) {
352
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> layer.isEditing());
353
            return !activeLayers.isEmpty();
354

    
355
        } else if ("vector-editing-tooloptions".equals(action)) {
356
            List<FLyrVect> activeLayers = getActiveLayers(view, (FLyrVect layer) -> layer.isEditing());
357
            return !activeLayers.isEmpty();
358
        } else if ("vector-editing-ortomode-enable".equals(action)) {
359
            return editingContext.getDrawMode()==EditingContext.DRAWMODE_NORMAL;
360
        } else if ("vector-editing-ortomode-disable".equals(action)) {
361
            return editingContext.getDrawMode()==EditingContext.DRAWMODE_ORTO;
362
        }
363

    
364
        return false;
365

    
366
    }
367

    
368
    @Override
369
    public boolean canQueryByAction() {
370
        return true;
371
    }
372

    
373
    private IView getActiveView() {
374
        ApplicationManager application = ApplicationLocator.getManager();
375
        IView view = (IView) application.getActiveComponent(ViewDocument.class);
376
        return view;
377
    }
378

    
379
    private boolean isWritable(FLyrVect layer) {
380
        if (layer != null && layer.isAvailable()) {
381
            return layer.getFeatureStore().allowWrite();
382
        }
383
        return false;
384
    }
385

    
386
    private boolean canBeEdited(FLyrVect layer) {
387
        if (layer != null && layer.isAvailable()) {
388

    
389
            boolean isNotTransformed
390
                    = layer.getFeatureStore().getTransforms().isEmpty();
391

    
392
            return isNotTransformed && !layer.isEditing();
393
        }
394

    
395
        return false;
396
    }
397

    
398
//  private FLyrVect getActiveLayer(IView vista) {
399
//    if (vista != null) {
400
//      ViewDocument viewDocument = vista.getViewDocument();
401
//      FLayer[] actives
402
//              = viewDocument.getMapContext().getLayers().getActives();
403
//
404
//      if ((actives.length == 1) && (actives[0] instanceof FLyrVect)) {
405
//        return (FLyrVect) actives[0];
406
//      }
407
//    }
408
//    return null;
409
//  }
410
    private List<FLyrVect> getActiveLayers(IView view, Predicate<FLyrVect> valid) {
411
        if (view == null) {
412
            return Collections.EMPTY_LIST;
413
        }
414
        List<FLyrVect> layers = new ArrayList<>();
415
        ViewDocument viewDocument = view.getViewDocument();
416
        FLayer[] actives = viewDocument.getMapContext().getLayers().getActives();
417
        for (FLayer layer : actives) {
418
            if (layer instanceof FLyrVect && valid.test((FLyrVect) layer)) {
419
                layers.add((FLyrVect) layer);
420
            }
421
        }
422
        return layers;
423
    }
424

    
425
    @Override
426
    public void update(Observable observable, Object notification) {
427

    
428
        if (notification instanceof Notification) {
429
            ApplicationManager appManager = ApplicationLocator.getManager();
430
            Notification n = (Notification) notification;
431
            if (n.isOfType(EditingContext.CHANGE_SELECTED_TOOL_NOTIFICATION)) {
432
                String name = (String) n.getValue();
433
                if( name!=null ) {
434
                    LOGGER.trace("Changed selected tool to '{}'", name);
435
                    PluginServices.getMainFrame().setSelectedTool(name);
436
                    appManager.refreshMenusAndToolBars();
437
                }
438

    
439
            } else if (n.isOfType(EditingContext.EXPORT_LAYER_NOTIFICATION)) {
440
                exportLayer((FLyrVect) (n.getValue()));
441

    
442
            } else if (n.isOfType(EditingContext.REFRESH_TOOLS_NOTIFICATION)) {
443
                appManager.refreshMenusAndToolBars();
444
            }
445
        }
446
    }
447

    
448
    private void exportLayer(FLyrVect layer) {
449
        ApplicationManager appManager = ApplicationLocator.getManager();
450
        I18nManager i18nManager = ToolsLocator.getI18nManager();
451
        ActionInfo action = PluginsLocator.getActionInfoManager().getAction("layer-exportto");
452
        action.execute(new Object[]{layer, MODE.toInteger(MODE.DIALOG)});
453
        String msg = "_Do_you_want_to_finish_editing_If_not_exported_the_data_the_changes_will_be_lost";
454
        if (appManager.confirmDialog(
455
                i18nManager.getTranslation(msg),
456
                i18nManager.getTranslation("end_editing"),
457
                JOptionPane.YES_NO_OPTION,
458
                JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
459
            try {
460
                layer.getFeatureStore().cancelEditing();
461
            } catch (Exception e) {
462
                LOGGER.warn("Can't abort editing of layer '" + layer.getName() + "'.", e);
463
                msg = "_Cant_finish_editing_See_the_error_log_for_more_information";
464
                appManager.messageDialog(msg, "_Warning", JOptionPane.WARNING_MESSAGE);
465
            }
466
        }
467
    }
468

    
469
    private List<FLyrVect> getEditedLayers() {
470
        ApplicationManager application = ApplicationLocator.getManager();
471
        List<FLyrVect> editedLayers = new ArrayList<>();
472

    
473
        Project project = application.getCurrentProject();
474
        for (Document document : project.getDocuments(ViewManager.TYPENAME)) {
475
            ViewDocument view = (ViewDocument) document;
476
            MapContext mapContext = view.getMapContext();
477
            if (mapContext != null) {
478
                FLayers layers = mapContext.getLayers();
479
                for (int j = 0; j < layers.getLayersCount(); j++) {
480
                    FLayer lyr = layers.getLayer(j);
481
                    if (lyr instanceof FLyrVect) {
482
                        FLyrVect layerVect = (FLyrVect) lyr;
483
                        if (layerVect.isEditing()) {
484
                            editedLayers.add(layerVect);
485
                        }
486
                    }
487
                }
488
            }
489
        }
490
        return editedLayers;
491
    }
492

    
493
    private List<IUnsavedData> getUnsavedData(List<FLyrVect> editedLayers) {
494
        List<IUnsavedData> unsavedData = new ArrayList<>();
495
        for (FLyrVect editedLayer : editedLayers) {
496
            IUnsavedData unsavedDataLayer = new UnsavedLayer(this, editedLayer);
497
            unsavedData.add(unsavedDataLayer);
498
        }
499
        return unsavedData;
500

    
501
    }
502

    
503
    private static class UnsavedLayer extends UnsavedData {
504

    
505
        private final FLyrVect layer;
506

    
507
        public UnsavedLayer(IExtension extension, FLyrVect layer) {
508
            super(extension);
509
            this.layer = layer;
510
        }
511

    
512
        @Override
513
        public String getDescription() {
514
            return layer.getName();
515
        }
516

    
517
        @Override
518
        public String getResourceName() {
519
            return layer.getFeatureStore().getFullName();
520
        }
521

    
522
        @Override
523
        public boolean saveData() {
524
            FeatureStore featureStore = layer.getFeatureStore();
525
            if (featureStore.isEditing()) {
526
                try {
527
                    featureStore.finishEditing();
528
                    return true;
529
                } catch (DataException e) {
530
                    throw new RuntimeException(e);
531
                }
532
            }
533
            return true;
534
        }
535
    }
536

    
537
    @Override
538
    public IExtensionStatus getStatus() {
539
        List<FLyrVect> editedLayers = getEditedLayers();
540
        final List<IUnsavedData> unsavedData = getUnsavedData(editedLayers);
541

    
542
        return new IExtensionStatus() {
543

    
544
            @Override
545
            public boolean hasUnsavedData() {
546
                if (unsavedData == null) {
547
                    return false;
548
                }
549
                return !unsavedData.isEmpty();
550
            }
551

    
552
            @Override
553
            public boolean hasRunningProcesses() {
554
                return false;
555
            }
556

    
557
            @Override
558
            public IUnsavedData[] getUnsavedData() {
559
                if (unsavedData == null) {
560
                    return null;
561
                }
562
                return unsavedData.toArray(new IUnsavedData[0]);
563
            }
564

    
565
            @Override
566
            public IMonitorableTask[] getRunningProcesses() {
567
                return null;
568
            }
569
        };
570
    }
571

    
572
    private void showMultilaterFinishEditingPanel(MapContext mapContext) {
573
        I18nManager i18n = ToolsLocator.getI18nManager();
574
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
575
        MultilayerFinishEditingPanel finishEditingPanel = new MultilayerFinishEditingPanel(mapContext);
576
        Dialog dialog = windowManager.createDialog(
577
                finishEditingPanel.asJComponent(),
578
                i18n.getTranslation("end_editing"),
579
                i18n.getTranslation("_List_of_layers_to_finish_editing"),
580
                WindowManager_v2.BUTTONS_OK_CANCEL
581
        );
582
        finishEditingPanel.setDialog(dialog);
583
        dialog.addActionListener((ActionEvent e) -> {
584
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
585
                finishEditingPanel.apply();
586
            }
587
        });
588
        dialog.show(WindowManager.MODE.WINDOW);
589
    }
590

    
591
    private static class ExpressionBuilderAction extends AbstractAction {
592

    
593
        private final EditingConsole console;
594
        private final EditingContext editingContext;
595
        
596
        
597
        @SuppressWarnings("OverridableMethodCallInConstructor")
598
        public ExpressionBuilderAction(EditingContext editingContext, EditingConsole console) {
599
            this.editingContext = editingContext;
600
            this.console = console;
601
            I18nManager i18n = ToolsLocator.getI18nManager();
602
            this.putValue(
603
                    Action.ACTION_COMMAND_KEY, 
604
                    "CreateJExpressionBuilderAction"
605
            );
606
            this.putValue(
607
                    Action.NAME, 
608
                    i18n.getTranslation("_Show_expression_builder")
609
            );
610
            this.putValue(
611
                    Action.SMALL_ICON, 
612
                    ToolsSwingLocator.getIconThemeManager().getCurrent().get("picker-expression")
613
            );
614
        }
615
        
616
        @Override
617
        public void actionPerformed(ActionEvent e) {
618
            I18nManager i18n = ToolsLocator.getI18nManager();
619
            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
620
            final JExpressionBuilder panel = ExpressionEvaluatorSwingLocator.getManager().createJExpressionBuilder();
621
            panel.addSymbolTable(this.editingContext.getContextSymbolTable());
622
            panel.setPreviewSymbolTable(this.editingContext.getContextSymbolTable());
623
            final Dialog dialog = winmgr.createDialog(
624
                    panel.asJComponent(),
625
                    i18n.getTranslation("_Expression_builder"),
626
                    null, 
627
                    WindowManager_v2.BUTTONS_OK_CANCEL
628
            );
629
            dialog.addActionListener((ActionEvent e2) -> {
630
                if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
631
                    console.addResponseText(panel.getExpression().getPhrase());
632
                }
633
            });
634
            dialog.show(WindowManager.MODE.DIALOG);
635
        }
636
        
637
    }
638
    
639
}