Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.swing / org.gvsig.vectorediting.swing.impl / src / main / java / org / gvsig / vectorediting / swing / impl / DefaultEditingContext.java @ 3225

History | View | Annotate | Download (52.1 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

    
25
package org.gvsig.vectorediting.swing.impl;
26

    
27
import java.awt.BorderLayout;
28
import java.awt.Component;
29
import java.awt.Cursor;
30
import java.lang.ref.WeakReference;
31
import java.lang.reflect.InvocationTargetException;
32
import java.util.ArrayList;
33
import java.util.HashSet;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Set;
37
import java.util.Stack;
38
import java.util.logging.Level;
39
import java.util.prefs.PreferenceChangeEvent;
40
import java.util.prefs.PreferenceChangeListener;
41
import java.util.prefs.Preferences;
42
import javax.swing.JComponent;
43
import javax.swing.JOptionPane;
44
import javax.swing.SwingUtilities;
45
import org.apache.commons.lang3.StringUtils;
46
import org.apache.commons.text.StringEscapeUtils;
47
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
48
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
49
import org.gvsig.expressionevaluator.ExpressionUtils;
50
import org.gvsig.expressionevaluator.Function;
51
import org.gvsig.expressionevaluator.SymbolTable;
52
import org.gvsig.fmap.dal.DataTypes;
53
import org.gvsig.fmap.dal.EditingNotification;
54
import org.gvsig.fmap.dal.EditingNotificationManager;
55
import org.gvsig.fmap.dal.exception.DataException;
56
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
57
import org.gvsig.fmap.dal.feature.FeatureSelection;
58
import org.gvsig.fmap.dal.feature.FeatureStore;
59
import org.gvsig.fmap.dal.feature.FeatureType;
60
import org.gvsig.fmap.dal.swing.DALSwingLocator;
61
import org.gvsig.fmap.geom.Geometry;
62
import org.gvsig.fmap.geom.GeometryLocator;
63
import org.gvsig.fmap.geom.GeometryUtils;
64
import org.gvsig.fmap.geom.primitive.Point;
65
import org.gvsig.fmap.geom.type.GeometryType;
66
import org.gvsig.fmap.mapcontext.MapContext;
67
import org.gvsig.fmap.mapcontext.layers.CancelationException;
68
import org.gvsig.fmap.mapcontext.layers.FLayer;
69
import org.gvsig.fmap.mapcontext.layers.FLayers;
70
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
71
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
72
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
73
import org.gvsig.fmap.mapcontext.layers.LayerListener;
74
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
75
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
76
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
77
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
78
import org.gvsig.fmap.mapcontrol.MapControl;
79
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
80
import org.gvsig.fmap.mapcontrol.tools.CompoundBehavior;
81
import org.gvsig.tools.ToolsLocator;
82
import org.gvsig.tools.bookmarksandhistory.Bookmark;
83
import org.gvsig.tools.dataTypes.Coercion;
84
import org.gvsig.tools.i18n.I18nManager;
85
import org.gvsig.tools.locator.LocatorException;
86
import org.gvsig.tools.observer.BaseNotification;
87
import org.gvsig.tools.observer.Notification;
88
import org.gvsig.tools.observer.ObservableHelper;
89
import org.gvsig.tools.observer.Observer;
90
import org.gvsig.tools.swing.api.ToolsSwingLocator;
91
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
92
import org.gvsig.utils.console.JDockPanel;
93
import org.gvsig.utils.console.ResponseListener;
94
import org.gvsig.vectorediting.lib.api.EditingLocator;
95
import org.gvsig.vectorediting.lib.api.EditingManager;
96
import org.gvsig.vectorediting.lib.api.EditingService;
97
import org.gvsig.vectorediting.lib.api.EditingServiceInfo;
98
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
99
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
100
import org.gvsig.vectorediting.lib.api.exceptions.CreateEditingBehaviorException;
101
import org.gvsig.vectorediting.lib.api.exceptions.EndEditingException;
102
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
103
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
104
import org.gvsig.vectorediting.lib.api.exceptions.ParsePointException;
105
import org.gvsig.vectorediting.lib.api.exceptions.ParseValueException;
106
import org.gvsig.vectorediting.lib.api.exceptions.ServiceInformationException;
107
import org.gvsig.vectorediting.lib.api.exceptions.StartEditingException;
108
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
109
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
110
import org.gvsig.vectorediting.lib.api.exceptions.VectorEditingException;
111
import org.gvsig.vectorediting.swing.api.EditingContext;
112
import org.gvsig.vectorediting.swing.api.EditingSwingLocator;
113
import org.gvsig.vectorediting.swing.api.EditingSwingManager;
114
import org.gvsig.vectorediting.swing.api.console.EditingConsole;
115
import org.gvsig.vectorediting.swing.impl.console.DefaultEditingConsole;
116
import org.slf4j.Logger;
117
import org.slf4j.LoggerFactory;
118

    
119
public class DefaultEditingContext implements EditingContext {
120

    
121
    private static final Logger LOGGER = LoggerFactory
122
        .getLogger(EditingManager.class);
123

    
124
    private WeakReference<MapControl> mapControlReference;
125

    
126
    private WeakReference<MapContext> mapContextReference;
127

    
128
    private EditingCompoundBehavior editingCompoundBehavior;
129

    
130
    private Behavior[] lastAdditionalBehaviors;
131

    
132
    private final ObservableHelper observableHelper;
133

    
134
    private EditingConsole console;
135

    
136
    private JDockPanel dockConsole = null;
137

    
138
    private boolean isShowConsole = false;
139

    
140
    private final Stack<EditingService> serviceStack;
141

    
142
    private FLyrVect currentLayer;
143

    
144
    private EditingServiceParameter currentParam;
145

    
146
    private Behavior[] defaultBehaviors;
147
    
148
    private Set<FLyrVect> layersSpatialCacheEnabled = new HashSet<>();
149
    
150
    private boolean processing;
151

    
152
    private final LayerListener layerListener = new LayerListener() {
153

    
154
        @Override
155
        public void activationChanged(final LayerEvent e) {
156
            if( !SwingUtilities.isEventDispatchThread() ) {
157
                SwingUtilities.invokeLater(new Runnable() {
158

    
159
                    @Override
160
                    public void run() {
161
                        activationChanged(e);
162
                    }
163
                });
164
                return;
165
            }
166

    
167
            FLayer layer = e.getSource();
168
            final MapContext mapContext = layer.getMapContext();
169

    
170
            if (countActiveAndEditingLayers(mapContext) > 1) {
171
                hideConsole();
172
                return;
173
            }
174

    
175
            if (layer instanceof FLyrVect) {
176
                if (layer.isActive()) {
177
                    if(layer.isEditing()) {
178
                        getMapControl().setTool("VectorEditing");
179
                        setCurrentLayer((FLyrVect) layer);
180
                        showConsole();
181
                        return;
182
                    } else {
183
                        final SpatialCache spatialCache = ((FLyrVect) layer).getSpatialCache();
184
                        if(!spatialCache.isEnabled("active")){
185
                            spatialCache.setEnabled("active",true);
186
                            //We keep the list of layers whose spatial cache is enabled here.
187
                            layersSpatialCacheEnabled.add((FLyrVect) layer);
188

    
189
                        }
190
                    }
191
                } else {
192
                    if(!layer.isEditing()) {
193
                        //We disabled the spatial cache of the layers that we had enabled here.
194
                        final SpatialCache spatialCache = ((FLyrVect) layer).getSpatialCache();
195
                        if(spatialCache.isEnabled("active") && layersSpatialCacheEnabled.contains((FLyrVect) layer)){
196
                            spatialCache.setEnabled("active",false);
197
                            layersSpatialCacheEnabled.remove((FLyrVect) layer);
198
                        }
199
                    }
200
                }
201
            }
202

    
203
            FLayer[] activeLayers =
204
                layer.getMapContext().getLayers().getActives();
205
            
206
            for (FLayer activeLayer : activeLayers) {
207
                if (activeLayer instanceof FLyrVect) {
208
                    if (activeLayer.isEditing()) {
209
                        getMapControl().setTool("VectorEditing");
210
                        setCurrentLayer((FLyrVect) activeLayer);
211
                        showConsole();
212
                        return;
213
                    }
214
                }
215
            }
216

    
217
            hideConsole();
218
            if ((getMapControl().getCurrentTool() != null)
219
                && getMapControl().getCurrentTool().equals("VectorEditing")) {
220
                getMapControl().setPrevTool();
221
            }
222
        }
223

    
224
        @Override
225
        public void drawValueChanged(LayerEvent e) {
226
        }
227

    
228
        @Override
229
        public void editionChanged(final LayerEvent e) {
230
            if( !SwingUtilities.isEventDispatchThread() ) {
231
                SwingUtilities.invokeLater(new Runnable() {
232

    
233
                    @Override
234
                    public void run() {
235
                        editionChanged(e);
236
                    }
237
                });
238
                return;
239
            }
240
            FLayer layer = e.getSource();
241

    
242
            if (layer instanceof FLyrVect) {
243
                if (layer.isEditing()) {
244
                    synchronized (DefaultEditingContext.this) {
245
                        beginEdition((FLyrVect) layer);
246
                        showConsole();
247
                    }
248
                } else {
249
                    hideConsole();
250
                }
251
            }
252

    
253
        }
254

    
255
        @Override
256
        public void nameChanged(LayerEvent e) {
257
        }
258

    
259
        @Override
260
        public void visibilityChanged(LayerEvent e) {
261
        }
262
    };
263
    
264
    private int countActiveAndEditingLayers(MapContext mapcontext){
265
        int count = 0;
266
        
267
        FLayer[] activeLayers =
268
                mapcontext.getLayers().getActives();
269
            
270
        for (FLayer activeLayer : activeLayers) {
271
            if (activeLayer instanceof FLyrVect) {
272
                if (activeLayer.isEditing()) {
273
                    count++;
274
                }
275
            }
276
        }
277
        
278
        return count;
279
    }
280

    
281
    private final PreferenceChangeListener preferenceChangeListener =
282
        new PreferenceChangeListener() {
283

    
284
            @Override
285
            public void preferenceChange(PreferenceChangeEvent evt) {
286
                String key = evt.getKey();
287
                if (key.equalsIgnoreCase("apply-snappers")) {
288
                    boolean newValue = Boolean.parseBoolean(evt.getNewValue());
289
                    getMapControl().setRefentEnabled(newValue);
290
                }
291
            }
292
        };
293

    
294
    public DefaultEditingContext(MapControl mapControl) {
295
        this.processing = false;
296
        this.mapControlReference = new WeakReference<>(mapControl);
297
        this.mapContextReference =
298
            new WeakReference<>(mapControl.getMapContext());
299
        this.observableHelper = new ObservableHelper();
300

    
301
        this.serviceStack = new Stack<>();
302

    
303
        addLayerListeners();
304
        addPreferenceListener();
305
    }
306

    
307
    private void addPreferenceListener() {
308
        Preferences prefs = Preferences.userRoot().node("snappers");
309
        prefs.addPreferenceChangeListener(preferenceChangeListener);
310
    }
311

    
312
    @Override
313
    public void activateService(String name) {
314
        if( this.isProcessing() ) {
315
            return;
316
        }
317

    
318
        if ((getMapControl() != null)
319
            && getMapControl().hasTool("VectorEditing")) {
320

    
321
            CompoundBehavior editingCompoundBehavior =
322
                getEditingCompoundBehavior();
323
            getMapControl().setTool("VectorEditing");
324
            editingCompoundBehavior.setDrawnBehavior(
325
                EditingCompoundBehavior.EDITING_INDEX, true);
326

    
327
            EditingManager manager = EditingLocator.getManager();
328

    
329
            if (currentLayer != null) {
330
                IVectorLegend legend = null;
331
                try {
332
                    legend = (IVectorLegend) currentLayer.getLegend();
333
                } catch (Exception e) {
334
                    LOGGER.trace("Can't retrieve legend from layer.");
335
                    //DO NOTHING
336
                }
337

    
338
//                EditingService activeService = getActiveService();
339
//                if(activeService != null && !activeService.next().getTypes().contains(TYPE.GEOMETRY)) {
340
//                    activeService.setShowPreviewSymbol(true);
341
//                }
342
                EditingService service =
343
                    manager.getEditingService(name,
344
                        currentLayer.getFeatureStore(),
345
                        mapContextReference.get(), 
346
                        legend);
347

    
348
                if (service != null) {
349
//                     if(!serviceStack.isEmpty()) { service.setShowPreviewSymbol(false); }
350
                    this.enableSelection(false);
351

    
352
                    try {
353
                        service.activate();
354
                        service.start();                       
355
                    } catch (StartServiceException e) {
356

    
357
                        LOGGER.info(String.format(
358
                            "Can't start the service %1$s", service.getName()),
359
                            e);
360
                        cleanEditingContext();
361
                        return;
362

    
363
                    } catch (InvalidEntryException e) {
364

    
365
                        I18nManager i18nManager = ToolsLocator.getI18nManager();
366
                        showConsoleMessage("\n"
367
                            + i18nManager.getTranslation("invalid_option"));
368
                    }
369

    
370
                    if (!serviceStack.isEmpty()){
371
                        if(getActiveService().next().getTypes().contains(TYPE.GEOMETRY)) {
372
                            service.setShowPreviewSymbol(false);
373
                        } else {
374
//                            service.setShowPreviewSymbol(true);
375
//                            getActiveService().setShowPreviewSymbol(true);
376
                            serviceStack.pop();
377
                        }
378
                    }
379

    
380
                    setActiveService(service);
381

    
382
                    nextParameter();
383
                }
384
            }
385
        }
386
    }
387

    
388
    private void addBehaviors(Behavior[] additionalBehavior)
389
        throws CreateEditingBehaviorException {
390

    
391
        DefaultEditingBehavior editingBehavior;
392
        EditingCompoundBehavior editingCompoundBehavior;
393

    
394
        if (!getMapControl().hasTool("VectorEditing")) {
395

    
396
            editingBehavior = new DefaultEditingBehavior(this);
397
            editingCompoundBehavior =
398
                new EditingCompoundBehavior(editingBehavior);
399
            setCompoundBehavior(editingCompoundBehavior);
400

    
401
            if (additionalBehavior != null) {
402

    
403
                Behavior[] behaviors =
404
                    new Behavior[additionalBehavior.length + 1];
405
                behaviors[0] = editingCompoundBehavior;
406

    
407
                System.arraycopy(additionalBehavior, 0, behaviors, 1, additionalBehavior.length);
408

    
409
                getMapControl().addBehavior("VectorEditing", behaviors);
410

    
411
                lastAdditionalBehaviors = additionalBehavior;
412

    
413
            } else {
414
                getMapControl().addBehavior("VectorEditing",
415
                    editingCompoundBehavior);
416
            }
417

    
418
        } else {
419
            editingCompoundBehavior = getEditingCompoundBehavior();
420
            editingBehavior =
421
                (DefaultEditingBehavior) editingCompoundBehavior
422
                    .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
423
            setCompoundBehavior(editingCompoundBehavior);
424
            cleanEditingContext();
425
        }
426

    
427
    }
428

    
429
    private void addLayerListeners() {
430

    
431
        FLayers layers = mapContextReference.get().getLayers();
432

    
433
        layers.addLayerListener(layerListener);
434

    
435
        layers.addLayerCollectionListener(new LayerCollectionListener() {
436

    
437
            public void addLayer(FLayer layer) {
438
                if (layer instanceof FLayers) {
439
                    FLayers layers = (FLayers) layer;
440
                    for (int i = 0; i < layers.getLayersCount(); i++) {
441
                        addLayer(layers.getLayer(i));
442
                    }
443
                } else if (layer instanceof FLyrVect) {
444
                    ((FLyrVect) layer).addLayerListener(layerListener);
445
                }
446
            }
447

    
448
            @Override
449
            public void layerAdded(LayerCollectionEvent e) {
450
                addLayer(e.getLayers());
451
            }
452

    
453
            @Override
454
            public void layerAdding(LayerCollectionEvent e)
455
                throws CancelationException {
456
            }
457

    
458
            @Override
459
            public void layerMoved(LayerPositionEvent e) {
460
            }
461

    
462
            @Override
463
            public void layerMoving(LayerPositionEvent e)
464
                throws CancelationException {
465
            }
466

    
467
            public void removeLayer(FLayer layer) {
468
                if (layer instanceof FLayers) {
469
                    FLayers layers = (FLayers) layer;
470
                    for (int i = 0; i < layers.getLayersCount(); i++) {
471
                        addLayer(layers.getLayer(i));
472
                    }
473
                } else if (layer instanceof FLyrVect) {
474
                    ((FLyrVect) layer).removeLayerListener(layerListener);
475
                }
476
            }
477

    
478
            @Override
479
            public void layerRemoved(LayerCollectionEvent e) {
480
                removeLayer(e.getLayers());
481
            }
482

    
483
            @Override
484
            public void layerRemoving(LayerCollectionEvent e)
485
                throws CancelationException {
486
            }
487

    
488
            @Override
489
            public void visibilityChanged(LayerCollectionEvent e)
490
                throws CancelationException {
491
            }
492
        });
493
    }
494

    
495
    @Override
496
    public void addObserver(Observer o) {
497
        this.observableHelper.addObserver(o);
498
    }
499

    
500
    private void askQuestion(EditingServiceParameter param) {
501
        I18nManager i18nManager = ToolsLocator.getI18nManager();
502
        String translation = i18nManager.getTranslation(param.getDescription());
503
        String activeServiceName =
504
            i18nManager.getTranslation(getActiveService().getName());
505

    
506
        String strDefaultValue = param.getConsoleDefaultValue();
507
        
508
        if(StringUtils.isBlank(strDefaultValue)) {
509
            showConsoleMessage("\n" + activeServiceName + "# " + translation + " : ");
510
        } else {
511
            showConsoleMessage("\n" + activeServiceName + "# " + translation + "<" + strDefaultValue + "> : ");
512
        }
513
    }
514

    
515
    @Override
516
    public synchronized void beginEdition(FLyrVect layer,
517
        Behavior[] additionalBehaviors) {
518

    
519
        try{
520
            throw new Exception("Deprecated method");
521
        } catch (Exception e){
522
            LOGGER.info("Deprecated method", e);
523
        }
524

    
525
        beginEdition(layer);
526
        try {
527
            addBehaviors(additionalBehaviors);
528
        } catch (CreateEditingBehaviorException e1) {
529
            LOGGER.info("Problems adding behaviors to editing context", e1);
530
            getMapControl().setTool("pan");
531
        }
532
    }
533

    
534
    @Override
535
    public synchronized void beginEdition(FLyrVect layer) {
536

    
537
        EditingNotificationManager editingNotificationManager =
538
            DALSwingLocator.getEditingNotificationManager();
539

    
540
        EditingNotification notification =
541
            editingNotificationManager.notifyObservers(this,
542
                EditingNotification.BEFORE_ENTER_EDITING_STORE, null, layer,layer.getFeatureStore());
543

    
544
        if (notification.isCanceled()) {
545
            String msg =
546
                String.format("Edit layer %1$s canceled by somme observer.",
547
                    layer.getName());
548
            LOGGER.info(msg, new StartEditingException(msg, null));
549
            return;
550
        }
551

    
552
        setCurrentLayer(layer);
553

    
554
        FeatureStore featureStore = layer.getFeatureStore();
555
        if (!featureStore.isEditing()) {
556
            try {
557
                featureStore.edit();
558
            } catch (Exception e) {
559
                String msg =
560
                    String.format("Can't set %1$s in edit mode",
561
                        featureStore.getName());
562
                LOGGER.info(msg, new VectorEditingException(e));
563
                cleanEditingContext();
564
                return;
565
            }
566
        }
567

    
568
        featureStore.addObserver(getMapControl());
569

    
570
        editingNotificationManager.notifyObservers(this,
571
            EditingNotification.AFTER_ENTER_EDITING_STORE, null, layer, layer.getFeatureStore());
572

    
573
        enableSnapping();
574
    }
575

    
576
    @SuppressWarnings({ "rawtypes", "unchecked" })
577
    private void enableSnapping() {
578
        Preferences prefs = Preferences.userRoot().node("snappers");
579
         getMapControl().setRefentEnabled(prefs.getBoolean("apply-snappers", false));
580
         if (currentLayer != null) {
581
            ArrayList layersToSnap =
582
                getMapControl().getMapContext().getLayersToSnap();
583
            if (!layersToSnap.contains(currentLayer)) {
584
                layersToSnap.add(currentLayer);
585
            }
586
        }
587
    }
588

    
589
    @SuppressWarnings("rawtypes")
590
    private void disableSnapping() {
591
        ArrayList layersToSnap =
592
            getMapControl().getMapContext().getLayersToSnap();
593
        if (layersToSnap.contains(currentLayer)) {
594
            layersToSnap.remove(currentLayer);
595
        }
596
    }
597

    
598
    private void changeSelectedTool(String name) {
599
        if (name.equalsIgnoreCase(DEFAULT_TOOL)) {
600
            name = "selection-simple-select-view";
601
            this.getMapControl().setTool("pointSelection");
602
//            notifyChangeSelectedTool();
603
        }
604
    }
605
    
606
    private void notifyChangeSelectedTool() {
607
        Notification notification = new BaseNotification(
608
            EditingContext.CHANGE_SELECTED_TOOL_NOTIFICATION,
609
            null
610
        );
611
        this.observableHelper.notifyObservers(this, notification);
612
    }
613

    
614
    private void cleanEditingContext() {
615
        serviceStack.clear();
616
        currentParam = null;
617
        this.enableSelection(false);
618
        refreshMenusAndToolBars();
619

    
620
        I18nManager i18nManager = ToolsLocator.getI18nManager();
621
        showConsoleMessage("\n" + i18nManager.getTranslation("select_new_tool")
622
            + "\n");
623
        notifyChangeSelectedTool();
624
    }
625

    
626
    @Override
627
    public void deleteObserver(Observer o) {
628
        this.observableHelper.deleteObserver(o);
629
    }
630

    
631
    @Override
632
    public void deleteObservers() {
633
        this.observableHelper.deleteObservers();
634
    }
635

    
636
    private void discardChanges(FLyrVect layer) throws EndEditingException {
637
        FeatureStore featureStore = layer.getFeatureStore();
638
        try {
639
            featureStore.cancelEditing();
640
        } catch (Exception e) {
641
            throw new EndEditingException(e);
642
        }
643
    }
644

    
645
    private void doAction(FLyrVect layer, int option) {
646
        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
647
        I18nManager i18n = ToolsLocator.getI18nManager();
648
        
649
        switch (option) {
650
        case SAVE_CHANGES:
651
            try {
652
                saveChanges(layer);
653
            } catch (VectorEditingException e) {
654
                String msg =
655
                    String.format("Changes can not be saved in %1$s",
656
                        layer.getName());
657
                LOGGER.info(msg, e);
658
                dialogs.messageDialog(                   
659
                    i18n.getTranslation("_There_are_problems_saving_changes")+"\n\n"+
660
                    i18n.getTranslation("_See_error_log_for_more_information"), 
661
                    null, 
662
                    i18n.getTranslation("_Warning"), 
663
                    JOptionPane.WARNING_MESSAGE, 
664
                    "Vectorediting_cant_save_changes"
665
                );
666
                return;
667
            }
668
            break;
669

    
670
        case DISCARD_CHANGES:
671
            try {
672
                discardChanges(layer);
673
            } catch (VectorEditingException e) {
674
                String msg =
675
                    String.format("Changes can not be discared in %1$s",
676
                        layer.getName());
677
                LOGGER.info(msg, e);
678
                dialogs.messageDialog(                   
679
                    i18n.getTranslation("_There_are_problems_discarding_changes")+"\n"+
680
                    "\n" + i18n.getTranslation("_See_error_log_for_more_information"), 
681
                    null, 
682
                    i18n.getTranslation("_Warning"), 
683
                    JOptionPane.WARNING_MESSAGE, 
684
                    "Vectorediting_cant_discard_changes"
685
                );
686
                return;
687
            }
688
            break;
689

    
690
        case EXPORT_LAYER:
691
            try {
692
                exportLayer(layer);
693
            } catch (VectorEditingException e) {
694
                String msg =
695
                    String.format("Changes of %1$s can not be exported",
696
                        layer.getName());
697
                LOGGER.info(msg, e);
698
                dialogs.messageDialog(                   
699
                    i18n.getTranslation("_There_are_problems_exporting_changes")+"\n\n"+
700
                    i18n.getTranslation("_See_error_log_for_more_information"), 
701
                    null, 
702
                    i18n.getTranslation("_Warning"), 
703
                    JOptionPane.WARNING_MESSAGE, 
704
                    "Vectorediting_cant_export_changes"
705
                );
706
                return;
707
            }
708
            break;
709

    
710
        case CANCEL:
711
            return;
712
        }
713

    
714
        cleanEditingContext();
715
        hideConsole();
716
        disableSnapping();
717
        changeSelectedTool(DEFAULT_TOOL);
718

    
719
        FeatureStore featureStore = layer.getFeatureStore();
720
        featureStore.deleteObserver(getMapControl());
721

    
722
    }
723

    
724
    private void enableSelection(boolean enableSelection) {
725
        this.getEditingCompoundBehavior().setDrawnBehavior(
726
                EditingCompoundBehavior.SELECTION_INDEX, enableSelection);
727
    }
728

    
729
    @Override
730
    public void endEdition(FLyrVect layer) {
731
        if( this.isProcessing() ) {
732
            return;
733
        }
734
        if (layer.isEditing()) {
735
            EditingNotificationManager editingNotificationManager =
736
                DALSwingLocator.getEditingNotificationManager();
737

    
738
            EditingNotification notification =
739
                editingNotificationManager.notifyObservers(this,
740
                    EditingNotification.BEFORE_EXIT_EDITING_STORE, null, layer, layer.getFeatureStore());
741

    
742
            if (notification.isCanceled()) {
743
                String msg =
744
                    String.format(
745
                        "Stop edit layer %1$s canceled by somme observer.",
746
                        layer.getName());
747
                LOGGER.info(msg, new EndEditingException(msg, null));
748

    
749
            }
750

    
751
            getMapControl().getCanceldraw().setCanceled(true);
752
            int option;
753
            EditingSwingManager swingManager =
754
                EditingSwingLocator.getSwingManager();
755

    
756

    
757
            if (layer.isWritable() && getMapControl().getProjection().equals(layer.getProjection()) ) {
758
                option =
759
                    swingManager.showPanelSaveOrDiscard(getMapControl(),
760
                        layer.getName());
761
            } else {
762
                option =
763
                    swingManager.showPanelExportOrDiscard(getMapControl(),
764
                        layer.getName());
765
            }
766

    
767
            doAction(layer, option);
768

    
769
            editingNotificationManager.notifyObservers(this,
770
                EditingNotification.AFTER_EXIT_EDITING_STORE, null, layer, layer.getFeatureStore());
771

    
772
        }
773

    
774
    }
775

    
776
    private void exportLayer(FLyrVect layer) throws EndEditingException {
777
        Notification notification = new BaseNotification(EditingContext.EXPORT_LAYER_NOTIFICATION,1);
778
        notification.setValue(layer);
779
        this.observableHelper.notifyObservers(this, notification);
780
    }
781

    
782
    protected void finishService() {
783
        if (this.isProcessing()) {
784
            return;
785
        }
786
        Thread task = new Thread(() -> {
787
            doFinishService();
788
        }, "EditingContextFinishService");
789
        this.processing = true;
790
        this.setMouseBusy(true);
791
        task.start();
792
        refreshMenusAndToolBars();
793
    }
794

    
795
    private void doFinishService() {
796
        try {
797
            this.setMouseBusy(true);
798
            this.processing = true;
799
            EditingService lastService = serviceStack.pop();
800
            try {
801
                if (!serviceStack.isEmpty()
802
                        && getActiveService().next().getTypes().contains(TYPE.GEOMETRY)) {
803
                    Geometry geometry = lastService.finish();
804
                    lastService.setShowPreviewSymbol(true);
805
                    if (geometry != null) {
806
                        getActiveService().setValue(geometry);
807
                    }
808
                } else {
809
                    lastService.finishAndStore();
810
                    getMapControl().rePaintDirtyLayers();
811
                    refreshMenusAndToolBars();
812

    
813
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
814
                    showConsoleMessage("\n"
815
                            + i18nManager.getTranslation(lastService.getName()) + "# "
816
                            + i18nManager.getTranslation("finished") + "\n");
817
//                lastService.stop();
818
                    setActiveService(lastService);
819
//                lastService.start();
820
                    lastService.restart();
821
                    changeSelectedTool(getActiveService().getName());
822
                }
823

    
824
            } catch (FinishServiceException ex) {
825
                showConsoleMessage("\n"+ex.getLocalizedMessage());
826
                cleanEditingContext();
827
                return;
828
            } catch (InvalidEntryException ex) {
829
                I18nManager i18nManager = ToolsLocator.getI18nManager();
830
                showConsoleMessage("\n"
831
                        + i18nManager.getTranslation("invalid_option"));
832
                changeSelectedTool(getActiveService().getName());
833
            } catch (VectorEditingException ex) {
834
                LOGGER.info("Can't finish " + lastService.getName(), ex);
835
                cleanEditingContext();
836
                return;
837
            }
838

    
839
            doNextParameter();
840
        } finally {
841
            this.processing = false;
842
            this.setMouseBusy(false);
843
            refreshMenusAndToolBars();
844
        }
845
    }
846

    
847
    public EditingService getActiveService() {
848
        if (!serviceStack.isEmpty()) {
849
            return serviceStack.peek();
850
        }
851
        return null;
852
    }
853

    
854
    public EditingConsole getConsolePanel() {
855
        if (console == null) {
856
            console = new DefaultEditingConsole(new ResponseListener() {
857

    
858
                @Override
859
                public void acceptResponse(String response) {
860
                    textEntered(response);
861
                }
862
            });
863
        }
864
        return console;
865
    }
866

    
867
    protected FLyrVect getCurrentLayer() {
868
        return this.currentLayer;
869
    }
870

    
871
    protected EditingServiceParameter getCurrentParam() {
872
        return this.currentParam;
873
    }
874

    
875
    private Component getDockConsole() {
876
        if (dockConsole == null) {
877
            dockConsole = new JDockPanel((JComponent) getConsolePanel());
878
        }
879
        return dockConsole;
880
    }
881

    
882
    private DefaultEditingBehavior getEditingBehavior() {
883
        if (editingCompoundBehavior != null) {
884
            return (DefaultEditingBehavior) editingCompoundBehavior
885
                .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
886
        }
887
        return null;
888
    }
889

    
890
    private EditingCompoundBehavior getEditingCompoundBehavior() {
891
        if (editingCompoundBehavior != null) {
892
            return editingCompoundBehavior;
893
        } else {
894
            EditingCompoundBehavior editingCompoundBehavior;
895

    
896
            CompoundBehavior compoundBehavior =
897
                (CompoundBehavior) getMapControl().getMapTool("VectorEditing");
898

    
899
            if (compoundBehavior instanceof EditingCompoundBehavior) {
900
                editingCompoundBehavior =
901
                    (EditingCompoundBehavior) compoundBehavior;
902
            } else {
903
                editingCompoundBehavior =
904
                    (EditingCompoundBehavior) compoundBehavior.getBehavior(0);
905
            }
906

    
907
            setCompoundBehavior(editingCompoundBehavior);
908
            return editingCompoundBehavior;
909
        }
910
    }
911

    
912
    @Override
913
    public MapControl getMapControl() {
914
        return mapControlReference.get();
915
    }
916

    
917
    
918
    public void nextParameter() {
919
        if( this.isProcessing() ) {
920
            return;
921
        }
922
        doNextParameter();
923
    }
924
    
925
    private void doNextParameter() {
926
        if ((getMapControl().getCurrentTool() != null)
927
            && !getMapControl().getCurrentTool().equals("VectorEditing")) {
928
            getMapControl().setTool("VectorEditing");
929
        }
930
        EditingService activeService = getActiveService();
931
        currentParam = activeService.next();
932

    
933
        if (currentParam == null) {
934
            doFinishService();
935
        } else {
936
            askQuestion(currentParam);
937
            if (currentParam.getTypes().contains(TYPE.SELECTION)) {
938
                enableSelection(true);
939
            } else if (currentParam.getTypes().contains(TYPE.GEOMETRY)) {
940
                refreshMenusAndToolBars();
941
            }
942
        }
943
    }
944

    
945
    protected Stack<EditingService> getServiceStack() {
946
        return this.serviceStack;
947
    }
948

    
949
    private void hideConsole() {
950
        isShowConsole = false;
951
        if( !SwingUtilities.isEventDispatchThread() ) {
952
            try {
953
                SwingUtilities.invokeAndWait(new Runnable() {
954

    
955
                    @Override
956
                    public void run() {
957
                        hideConsole();
958
                    }
959
                });
960
                return;
961
            } catch (InterruptedException | InvocationTargetException ex) {
962
                LOGGER.warn("Can't hide editing console.",ex);
963
            }
964
            return;
965
        }
966
        getDockConsole().setVisible(false);
967
    }
968

    
969
    @Override
970
    public boolean isServiceCompatible(String name) {
971
        DefaultEditingBehavior editingBehavior = getEditingBehavior();
972

    
973
        if (editingBehavior != null) {
974

    
975
            try {
976
                EditingManager manager = EditingLocator.getManager();
977
                EditingServiceInfo serviceInfo = manager.getServiceInfo(name);
978
                GeometryType geoType = null;
979

    
980
                for (EditingService editingService : getServiceStack()) {
981
                    EditingServiceParameter parameter = editingService.next();
982
                    if (parameter != null) {
983
                        if (parameter.getTypes().contains(TYPE.GEOMETRY)) {
984

    
985
                            int geometryType = parameter.getGeometryType();
986
                            int subType = -1;
987

    
988
                            try {
989
                                subType
990
                                        = getCurrentLayer().getFeatureStore()
991
                                                .getDefaultFeatureType()
992
                                                .getDefaultGeometryAttribute()
993
                                                .getGeomType().getSubType();
994

    
995
                                geoType
996
                                        = GeometryLocator.getGeometryManager()
997
                                                .getGeometryType(geometryType, subType);
998
                            } catch (Exception e) {
999

    
1000
                                String msg
1001
                                        = String.format(
1002
                                                "Problems getting default feature"
1003
                                                + " type of %1$s or getting geometry"
1004
                                                + " type of %2$s %3$s",
1005
                                                getCurrentLayer().getName(), geometryType,
1006
                                                subType);
1007

    
1008
                                throw new ServiceInformationException(msg, e);
1009
                            }
1010

    
1011
                            return serviceInfo.isCompatibleWith(geoType)
1012
                                    && serviceInfo.createsNewGeometries();
1013
                        }
1014
                    }
1015
                }
1016

    
1017
                if (getCurrentLayer() != null) {
1018
                    try {
1019
                        geoType
1020
                                = getCurrentLayer().getFeatureStore()
1021
                                        .getDefaultFeatureType()
1022
                                        .getDefaultGeometryAttribute().getGeomType();
1023

    
1024
                        if (serviceInfo.isCompatibleWith(geoType)) {
1025
                            return true;
1026
                        }
1027
                    } catch (DataException e) {
1028
                        String msg
1029
                                = String.format("Problems getting default "
1030
                                        + "feature type of %1$s", getCurrentLayer()
1031
                                                .getName());
1032
                        throw new ServiceInformationException(msg, e);
1033
                    }
1034
                }
1035

    
1036
                return false;
1037
            } catch (ServiceInformationException e) {
1038
                LOGGER.warn(
1039
                    "Problems getting if editing context is compatible with "
1040
                        + name, e);
1041
            }
1042
        }
1043
        return false;
1044
    }
1045
     
1046
    private static final EditingContextSymbolTable contextSymbolTable = new EditingContextSymbolTable();
1047
    
1048
    @Override
1049
    public SymbolTable getContextSymbolTable() {
1050
        return contextSymbolTable;
1051
    }
1052
    
1053
    @Override
1054
    public Point parsePoint(String response) throws ParsePointException {
1055
        response = fixResponseUsingBookmarks(response);
1056
        
1057
        try {
1058
            Object x = ExpressionUtils.evaluate(contextSymbolTable, response);
1059
            if( x instanceof Point ) {
1060
                contextSymbolTable.addPoint((Point) x);
1061
                return (Point) x;
1062
            }
1063
        } catch(Exception ex) {
1064
            LOGGER.debug("Can't evaluate: "+StringEscapeUtils.escapeJava(response),ex);
1065
        }
1066
        String s = "ST_MakePoint("+response+")";
1067
        try {
1068
            Object x = ExpressionUtils.evaluate(contextSymbolTable, s);
1069
            if( x instanceof Point ) {
1070
                contextSymbolTable.addPoint((Point) x);
1071
                return (Point) x;
1072
            }
1073
        } catch(Exception ex) {
1074
            throw new ParsePointException(ex);
1075
        }
1076
        throw new ParsePointException(null);
1077
    }
1078
    
1079
    private Double parseValue(String response) throws ParseValueException {
1080
        response = fixResponseUsingBookmarks(response);
1081

    
1082
        try {
1083
            Object x = ExpressionUtils.evaluate(contextSymbolTable, response);
1084
            if( x instanceof Double ) {
1085
                return (Double) x;
1086
            }  
1087
            if( x==null ) {
1088
                throw new ParseValueException(new NullPointerException());
1089
            }
1090
            Coercion toDouble = ToolsLocator.getDataTypesManager().get(DataTypes.DOUBLE).getCoercion();
1091
            return (Double) toDouble.coerce(x);
1092
        } catch(Exception ex) {
1093
            throw new ParseValueException(ex);
1094
        }
1095

    
1096
    }
1097

    
1098
    protected String fixResponseUsingBookmarks(String response) throws LocatorException {
1099
        if( response != null ) {
1100
            response = response.trim();
1101
            int n = StringUtils.indexOf(response, " ");
1102
            if(n>0){
1103
                String name = StringUtils.left(response, n);
1104
                Function fn = contextSymbolTable.function(name);
1105
                if(fn != null){
1106
                    response = name+"("+response.substring(n)+")";
1107
                }
1108
            }
1109
        }
1110
        return response;
1111
    }
1112

    
1113
    protected void refreshMenusAndToolBars() {
1114
        if (!SwingUtilities.isEventDispatchThread()) {
1115
            SwingUtilities.invokeLater(() -> { refreshMenusAndToolBars(); });
1116
            return;
1117
        }
1118
        Notification notification = new BaseNotification(
1119
                EditingContext.REFRESH_TOOLS_NOTIFICATION,
1120
                null
1121
        );
1122
        this.observableHelper.notifyObservers(this, notification);
1123
    }
1124

    
1125
    private void saveChanges(FLyrVect layer) throws EndEditingException {
1126
        FeatureStore featureStore = layer.getFeatureStore();
1127
        try {
1128
            featureStore.finishEditing();
1129
        } catch (Exception e) {
1130
            throw new EndEditingException(e);
1131
        }
1132
    }
1133

    
1134
    private void setActiveService(EditingService service) {
1135
        //Si se hace este metodo publico hay que comprobar el isProcessing
1136
        serviceStack.add(service);
1137
        notifyChangeSelectedTool();
1138
    }
1139

    
1140
    private void setCompoundBehavior(EditingCompoundBehavior compoundBehavior) {
1141
        if( this.isProcessing() ) {
1142
            return;
1143
        }
1144
        this.editingCompoundBehavior = compoundBehavior;
1145
    }
1146

    
1147
    private void setCurrentLayer(FLyrVect layer) {
1148
        if( this.isProcessing() ) {
1149
            return;
1150
        }
1151
        if (this.currentLayer != layer) {
1152
            this.currentLayer = layer;
1153
            cleanEditingContext();
1154
        }
1155

    
1156
    }
1157

    
1158
    @Override
1159
    public void setMapControl(MapControl mapControl) {
1160
        if( this.isProcessing() ) {
1161
            return;
1162
        }
1163

    
1164
        this.mapControlReference = new WeakReference<>(mapControl);
1165
        this.mapContextReference =
1166
            new WeakReference<>(mapControl.getMapContext());
1167

    
1168
        // When mapControl is updated we have to add older additional behaviors
1169
        // to new mapControl
1170
        if (lastAdditionalBehaviors != null) {
1171
            try {
1172
                addBehaviors(lastAdditionalBehaviors);
1173
            } catch (CreateEditingBehaviorException e1) {
1174
                LOGGER.info("Problems adding behaviors to editing context", e1);
1175
                getMapControl().setTool("pan");
1176
            }
1177
        }
1178
    }
1179

    
1180
    private void showConsole() {
1181
        if (isShowConsole) {
1182
            return;
1183
        }
1184
        if( !SwingUtilities.isEventDispatchThread() ) {
1185
            try {
1186
                SwingUtilities.invokeAndWait(new Runnable() {
1187

    
1188
                    @Override
1189
                    public void run() {
1190
                        showConsole();
1191
                    }
1192
                });
1193
                return;
1194
            } catch (InterruptedException | InvocationTargetException ex) {
1195
                LOGGER.warn("Can't show editing console.",ex);
1196
            }
1197
            return;
1198
        }
1199
        isShowConsole = true;
1200
        getMapControl().remove(getDockConsole());
1201
        getMapControl().setLayout(new BorderLayout());
1202
        getMapControl().add(getDockConsole(), BorderLayout.SOUTH);
1203
        getDockConsole().setVisible(true);
1204
    }
1205

    
1206
    protected void showConsoleMessage(final String text) {
1207
        if (!SwingUtilities.isEventDispatchThread()) {
1208
            SwingUtilities.invokeLater(new Runnable() {
1209

    
1210
                @Override
1211
                public void run() {
1212
                    showConsoleMessage(text);
1213
                }
1214
            });
1215
            return;
1216
        }
1217
        getConsolePanel().addText(text);
1218
    }
1219

    
1220
    @Override
1221
    public void cancelActiveService() {
1222
        this.textEntered(null);
1223
    }
1224
    
1225
//    protected void selectedValue(Object value) {
1226
//        EditingService activeService = getActiveService();
1227
//        I18nManager i18nManager = ToolsLocator.getI18nManager();
1228
//        
1229
//        try {
1230
//            activeService.setValue(value);
1231
//        } catch (InvalidEntryException ex) {
1232
//            showConsoleMessage("\n"
1233
//                    + i18nManager.getTranslation("invalid_option"));
1234
//        }
1235
//
1236
//        activeService = getActiveService();
1237
//        if (activeService != null) {
1238
//            nextParameter();
1239
//        } else {
1240
//            cleanEditingContext();
1241
//        }
1242
//
1243
//    }
1244
    
1245
    protected void textEntered(String response) {
1246
        if( this.isProcessing() ) {
1247
            return;
1248
        }
1249
        FeatureStore featureStore = getCurrentLayer().getFeatureStore();        
1250
        if (response == null) {
1251
            EditingService activeService = getActiveService();
1252
            if (activeService != null) {
1253
                try {
1254
                    activeService.stop();
1255
                    serviceStack.pop();
1256
                    if (serviceStack.isEmpty()) {
1257
                        featureStore
1258
                            .getFeatureSelection().deselectAll();
1259
                        changeSelectedTool(DEFAULT_TOOL);
1260
                    } else {
1261
                        changeSelectedTool(activeService.getName());
1262
                    }
1263

    
1264
                    refreshMenusAndToolBars();
1265
                    activeService = getActiveService();
1266
                    if (activeService != null) {
1267
                        nextParameter();
1268
                    } else {
1269
                        cleanEditingContext();
1270
                    }
1271

    
1272
                } catch (StopServiceException e) {
1273
                    LOGGER
1274
                        .info("Can't stop " + activeService.getName(), e);
1275
                } catch (DataException e) {
1276
                    LOGGER.info("Can't get selection of "
1277
                        + featureStore.getFullName(), e);
1278
                }
1279
            }
1280
        } else {
1281
            Thread task = new Thread(() -> {
1282
                try {
1283
                    this.setMouseBusy(true);
1284
                    this.processing = true;
1285
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
1286
                    EditingService activeService = getActiveService();
1287
                    if (getCurrentParam() != null) {
1288
                        try {
1289
                            Object coercedValue = coerceInputParameter(getCurrentParam(), response);
1290
                            activeService.setValue(coercedValue);
1291
                        } catch (InvalidEntryException ex) {
1292
                            showConsoleMessage("\n"
1293
                                    + i18nManager.getTranslation("invalid_option"));
1294
                        }
1295
                    }
1296

    
1297
                    activeService = getActiveService();
1298
                    if (activeService != null) {
1299
                        doNextParameter();
1300
                    } else {
1301
                        cleanEditingContext();
1302
                    }
1303
                } finally {
1304
                    this.processing = false;
1305
                    this.setMouseBusy(false);
1306
                    refreshMenusAndToolBars();
1307
                }
1308
            }, "EditingContextTextEntered");
1309
            this.processing = true;
1310
            this.setMouseBusy(true);
1311
            task.start();
1312
            refreshMenusAndToolBars();
1313
        }
1314
    }
1315
    
1316
    private Object coerceInputParameter(EditingServiceParameter parameter, String input) throws InvalidEntryException {
1317
        if (parameter != null) {
1318
            FeatureStore featureStore = getCurrentLayer().getFeatureStore();
1319
            Set<TYPE> types = parameter.getTypes();
1320
            Point point = null;
1321
            Double value = null;
1322
            Point defaultPoint = null;
1323
            Object defaultValue = parameter.getDefaultValue();
1324

    
1325
            boolean insertedValue = false;
1326
            if ((!insertedValue && types.contains(TYPE.POSITION))
1327
                    || types.contains(TYPE.LIST_POSITIONS)) {
1328

    
1329
                if(defaultValue instanceof Point){
1330
                    defaultPoint = (Point) defaultValue;
1331
                }
1332
                try {
1333
                    if (StringUtils.isEmpty(input.replace("\n", ""))) {
1334
                        point = defaultPoint;
1335
                    } else {
1336
                        point = parsePoint(input);
1337
                    }
1338

    
1339
                    if (point != null) {
1340
                        return point;
1341
                    }
1342

    
1343
                } catch (ParsePointException e) {
1344
                    // Do nothing to try other types
1345
                }
1346
            }
1347
            if (types.contains(TYPE.VALUE)) {
1348

    
1349
                try {
1350
                    value = parseValue(input);
1351
                    if (value != null) {
1352
                        return value;
1353
                    }
1354

    
1355
                } catch (ParseValueException e) {
1356
                    // Do nothing to try other types
1357
                }
1358

    
1359
            }
1360
            if (types.contains(TYPE.OPTION)) {
1361
                input = input.replace("\n", "");
1362
                return input;
1363
            }
1364

    
1365
            if (!insertedValue && types.contains(TYPE.SELECTION)) {
1366
                if (input.equalsIgnoreCase("\n")) {
1367
                    enableSelection(false);
1368
                    insertedValue = true;
1369

    
1370
                    FeatureSelection clonedSelection;
1371
                    try {
1372
                        clonedSelection = (FeatureSelection) featureStore
1373
                                .getFeatureSelection().clone();
1374
                        if (clonedSelection.isEmpty()) {
1375
                            throw new InvalidEntryException(null);
1376
                        }
1377
                    } catch (InvalidEntryException e) {
1378
                        throw e;
1379
                    } catch (Exception e) {
1380
                        LOGGER.warn("Can't access to selection.", e);
1381
                        throw new InvalidEntryException(e);
1382
//                        cleanEditingContext();
1383
//                        return null;
1384
                    }
1385
                    
1386
                    return clonedSelection;
1387
                }
1388
            }
1389
        }
1390
        return null;
1391
    }
1392

    
1393
    @Override
1394
    public void setDefaultBehaviors(Behavior[] defaultBehaviors) {
1395
        if( this.isProcessing() ) {
1396
            return;
1397
        }
1398
        this.defaultBehaviors = defaultBehaviors;
1399
        try {
1400
            addBehaviors(defaultBehaviors);
1401
        } catch (CreateEditingBehaviorException e1) {
1402
            LOGGER.info("Problems adding behaviors to editing context", e1);
1403
            getMapControl().setTool("pan");
1404
        }
1405
    }
1406

    
1407
    @Override
1408
    public Behavior[] getDefaultBehaviors() {
1409
        return this.defaultBehaviors;
1410
    }
1411

    
1412
    @Override
1413
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
1414
        if( this.isProcessing() ) {
1415
            return;
1416
        }
1417
        if( value instanceof CharSequence){
1418
            value = coerceInputParameter(parameter, value.toString());
1419
        } else if( value instanceof Point) {
1420
            contextSymbolTable.addPoint((Point) value);
1421
        }
1422
        Object v = value;
1423
        Thread task = new Thread(() -> {
1424
            try {
1425
                this.setMouseBusy(true);
1426
                this.processing = true;
1427
                getActiveService().setValue(parameter, v);
1428
//        doNextParameter();
1429
            } catch (InvalidEntryException ex) {
1430
                I18nManager i18nManager = ToolsLocator.getI18nManager();
1431
                showConsoleMessage("\n"+ i18nManager.getTranslation("invalid_option"));
1432
            } finally {
1433
                this.processing = false;
1434
                this.setMouseBusy(false);
1435
                refreshMenusAndToolBars();
1436
            }
1437
        }, "EditingContextSetValue");
1438
        this.processing = true;
1439
        this.setMouseBusy(true);
1440
        task.start();
1441
        refreshMenusAndToolBars();
1442
        
1443
        
1444
    }
1445

    
1446
    public GeometryType getGeometryType() {
1447
        if( this.currentLayer==null ) {
1448
            return null;
1449
        }
1450
        FeatureStore store = this.currentLayer.getFeatureStore();
1451
        if( store == null ) {
1452
            return null;
1453
        }
1454
        FeatureType ftype = store.getDefaultFeatureTypeQuietly();
1455
        if( ftype == null ) {
1456
            return null;
1457
        }
1458
        FeatureAttributeDescriptor geomattr = ftype.getDefaultGeometryAttribute();
1459
        if( geomattr == null ) {
1460
            return null;
1461
        }
1462
        return geomattr.getGeomType();
1463
    }    
1464
    
1465
    public boolean isProcessing() {
1466
        return this.processing;
1467
    }
1468
    
1469
    private Cursor lastNoBusyCursor = null;
1470
    
1471
    public void setMouseBusy(boolean busy) {
1472
        JComponent component = this.getMapControl();
1473
        if( busy ) {
1474
            if( lastNoBusyCursor==null ) {
1475
                this.lastNoBusyCursor = component.getCursor();
1476
            }
1477
            component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1478
        } else {
1479
            component.setCursor(lastNoBusyCursor);
1480
            lastNoBusyCursor = null;
1481
        }
1482
    }
1483
}