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

History | View | Annotate | Download (41 KB)

1 159 llmarques
/**
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 89 llmarques
 */
24 159 llmarques
25 89 llmarques
package org.gvsig.vectorediting.swing.impl;
26
27
import java.awt.BorderLayout;
28
import java.awt.Component;
29 150 llmarques
import java.lang.ref.WeakReference;
30 876 jjdelcerro
import java.lang.reflect.InvocationTargetException;
31 366 llmarques
import java.util.ArrayList;
32 226 llmarques
import java.util.Set;
33
import java.util.Stack;
34 876 jjdelcerro
import java.util.logging.Level;
35 366 llmarques
import java.util.prefs.PreferenceChangeEvent;
36
import java.util.prefs.PreferenceChangeListener;
37
import java.util.prefs.Preferences;
38 89 llmarques
39 376 llmarques
import javax.swing.JComponent;
40 876 jjdelcerro
import javax.swing.SwingUtilities;
41 376 llmarques
42 226 llmarques
import org.gvsig.fmap.dal.exception.DataException;
43 1143 fdiaz
import org.gvsig.fmap.dal.feature.FeatureSelection;
44 89 llmarques
import org.gvsig.fmap.dal.feature.FeatureStore;
45 226 llmarques
import org.gvsig.fmap.geom.Geometry;
46
import org.gvsig.fmap.geom.GeometryLocator;
47
import org.gvsig.fmap.geom.GeometryManager;
48
import org.gvsig.fmap.geom.primitive.Point;
49
import org.gvsig.fmap.geom.type.GeometryType;
50 89 llmarques
import org.gvsig.fmap.mapcontext.MapContext;
51
import org.gvsig.fmap.mapcontext.layers.CancelationException;
52
import org.gvsig.fmap.mapcontext.layers.FLayer;
53
import org.gvsig.fmap.mapcontext.layers.FLayers;
54
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
55
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
56
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
57
import org.gvsig.fmap.mapcontext.layers.LayerListener;
58
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
59
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
60
import org.gvsig.fmap.mapcontrol.MapControl;
61
import org.gvsig.fmap.mapcontrol.tools.CompoundBehavior;
62
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
63 226 llmarques
import org.gvsig.tools.ToolsLocator;
64
import org.gvsig.tools.i18n.I18nManager;
65 303 fdiaz
import org.gvsig.tools.observer.BaseNotification;
66
import org.gvsig.tools.observer.Notification;
67 157 llmarques
import org.gvsig.tools.observer.ObservableHelper;
68
import org.gvsig.tools.observer.Observer;
69 89 llmarques
import org.gvsig.utils.console.JDockPanel;
70
import org.gvsig.utils.console.ResponseListener;
71 226 llmarques
import org.gvsig.vectorediting.lib.api.EditingLocator;
72 89 llmarques
import org.gvsig.vectorediting.lib.api.EditingManager;
73 226 llmarques
import org.gvsig.vectorediting.lib.api.EditingService;
74
import org.gvsig.vectorediting.lib.api.EditingServiceInfo;
75
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
76
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
77 89 llmarques
import org.gvsig.vectorediting.lib.api.exceptions.CreateEditingBehaviorException;
78
import org.gvsig.vectorediting.lib.api.exceptions.EndEditingException;
79 226 llmarques
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
80
import org.gvsig.vectorediting.lib.api.exceptions.ParsePointException;
81
import org.gvsig.vectorediting.lib.api.exceptions.ParseValueException;
82 157 llmarques
import org.gvsig.vectorediting.lib.api.exceptions.ServiceInformationException;
83 89 llmarques
import org.gvsig.vectorediting.lib.api.exceptions.StartEditingException;
84 226 llmarques
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
85
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
86 89 llmarques
import org.gvsig.vectorediting.lib.api.exceptions.VectorEditingException;
87
import org.gvsig.vectorediting.swing.api.EditingContext;
88
import org.gvsig.vectorediting.swing.api.EditingSwingLocator;
89
import org.gvsig.vectorediting.swing.api.EditingSwingManager;
90 376 llmarques
import org.gvsig.vectorediting.swing.api.console.EditingConsole;
91
import org.gvsig.vectorediting.swing.impl.console.DefaultEditingConsole;
92 842 fdiaz
93
import org.apache.commons.lang3.StringUtils;
94 1143 fdiaz
95 844 jjdelcerro
import org.gvsig.fmap.dal.EditingNotification;
96
import org.gvsig.fmap.dal.EditingNotificationManager;
97
import org.gvsig.fmap.dal.swing.DALSwingLocator;
98 1143 fdiaz
99 547 llmarques
import org.slf4j.Logger;
100
import org.slf4j.LoggerFactory;
101 89 llmarques
102
public class DefaultEditingContext implements EditingContext {
103
104 109 llmarques
    private static final Logger logger = LoggerFactory
105
        .getLogger(EditingManager.class);
106 89 llmarques
107 150 llmarques
    private WeakReference<MapControl> mapControlReference;
108 89 llmarques
109 383 llmarques
    private WeakReference<MapContext> mapContextReference;
110 150 llmarques
111 109 llmarques
    private EditingCompoundBehavior editingCompoundBehavior;
112 89 llmarques
113 155 llmarques
    private Behavior[] lastAdditionalBehaviors;
114 150 llmarques
115 157 llmarques
    private ObservableHelper observableHelper;
116
117 376 llmarques
    private EditingConsole console;
118 89 llmarques
119 109 llmarques
    private JDockPanel dockConsole = null;
120 89 llmarques
121 109 llmarques
    private boolean isShowConsole = false;
122 89 llmarques
123 226 llmarques
    private Stack<EditingService> serviceStack;
124
125
    private FLyrVect currentLayer;
126
127
    private EditingServiceParameter currentParam;
128
129 438 fdiaz
    private Behavior[] defaultBehaviors;
130
131 109 llmarques
    private LayerListener layerListener = new LayerListener() {
132 89 llmarques
133 876 jjdelcerro
        @Override
134
        public void activationChanged(final LayerEvent e) {
135
            if( !SwingUtilities.isEventDispatchThread() ) {
136
                SwingUtilities.invokeLater(new Runnable() {
137
138
                    @Override
139
                    public void run() {
140
                        activationChanged(e);
141
                    }
142
                });
143
                return;
144
            }
145 1095 fdiaz
146 109 llmarques
            FLayer layer = e.getSource();
147 89 llmarques
148 127 llmarques
            FLayer[] activeLayers =
149
                layer.getMapContext().getLayers().getActives();
150 130 llmarques
151 227 llmarques
            if ((activeLayers.length == 1) && (layer instanceof FLyrVect)) {
152 127 llmarques
                if (layer.isActive() && layer.isEditing()) {
153 438 fdiaz
                    getMapControl().setTool("VectorEditing");
154
                    setCurrentLayer((FLyrVect) layer);
155 127 llmarques
                    showConsole();
156
                    return;
157
                }
158
            }
159 109 llmarques
160 127 llmarques
            hideConsole();
161 227 llmarques
            if ((getMapControl().getCurrentTool() != null)
162 205 llmarques
                && getMapControl().getCurrentTool().equals("VectorEditing")) {
163 197 llmarques
                getMapControl().setPrevTool();
164
            }
165 89 llmarques
        }
166 109 llmarques
167
        public void drawValueChanged(LayerEvent e) {
168 89 llmarques
        }
169
170 876 jjdelcerro
        @Override
171
        public void editionChanged(final LayerEvent e) {
172
            if( !SwingUtilities.isEventDispatchThread() ) {
173
                SwingUtilities.invokeLater(new Runnable() {
174
175
                    @Override
176
                    public void run() {
177
                        editionChanged(e);
178
                    }
179
                });
180
                return;
181
            }
182 438 fdiaz
            FLayer layer = e.getSource();
183
184
            if (layer instanceof FLyrVect) {
185
                if (layer.isEditing()) {
186
                    synchronized (DefaultEditingContext.this) {
187 546 llmarques
                        beginEdition((FLyrVect) layer);
188 438 fdiaz
                        showConsole();
189
                    }
190
                } else {
191
                    hideConsole();
192
                }
193
            }
194
195 109 llmarques
        }
196 89 llmarques
197 109 llmarques
        public void nameChanged(LayerEvent e) {
198
        }
199 89 llmarques
200 109 llmarques
        public void visibilityChanged(LayerEvent e) {
201
        }
202
    };
203 89 llmarques
204 366 llmarques
    private PreferenceChangeListener preferenceChangeListener =
205
        new PreferenceChangeListener() {
206
207
            public void preferenceChange(PreferenceChangeEvent evt) {
208
                String key = evt.getKey();
209
                if (key.equalsIgnoreCase("apply-snappers")) {
210
                    boolean newValue = Boolean.parseBoolean(evt.getNewValue());
211
                    getMapControl().setRefentEnabled(newValue);
212
                }
213
            }
214
        };
215
216 109 llmarques
    public DefaultEditingContext(MapControl mapControl) {
217 226 llmarques
218 150 llmarques
        this.mapControlReference = new WeakReference<MapControl>(mapControl);
219 383 llmarques
        this.mapContextReference =
220
            new WeakReference<MapContext>(mapControl.getMapContext());
221 385 llmarques
        this.observableHelper = new ObservableHelper();
222 205 llmarques
223 226 llmarques
        this.serviceStack = new Stack<EditingService>();
224
225 163 llmarques
        addLayerListeners();
226 366 llmarques
        addPreferenceListener();
227 109 llmarques
    }
228 89 llmarques
229 366 llmarques
    private void addPreferenceListener() {
230
        Preferences prefs = Preferences.userRoot().node("snappers");
231
        prefs.addPreferenceChangeListener(preferenceChangeListener);
232
    }
233
234 109 llmarques
    public void activateService(String name) {
235 226 llmarques
236 227 llmarques
        if ((getMapControl() != null)
237
            && getMapControl().hasTool("VectorEditing")) {
238 226 llmarques
239 109 llmarques
            CompoundBehavior editingCompoundBehavior =
240
                getEditingCompoundBehavior();
241 142 llmarques
            getMapControl().setTool("VectorEditing");
242 109 llmarques
            editingCompoundBehavior.setDrawnBehavior(
243
                EditingCompoundBehavior.EDITING_INDEX, true);
244 226 llmarques
245
            EditingManager manager = EditingLocator.getManager();
246
247
            if (currentLayer != null) {
248
249
                EditingService service =
250 227 llmarques
                    manager.getEditingService(name,
251 383 llmarques
                        currentLayer.getFeatureStore(),
252
                        mapContextReference.get());
253 226 llmarques
254
                if (service != null) {
255
256
                    this.enableSelection(false);
257
258
                    try {
259
                        service.start();
260
                    } catch (StartServiceException e) {
261 252 llmarques
262 226 llmarques
                        logger.info(String.format(
263
                            "Can't start the service %1$s", service.getName()),
264
                            e);
265
                        cleanEditingContext();
266
                        return;
267 252 llmarques
268
                    } catch (InvalidEntryException e) {
269
270
                        I18nManager i18nManager = ToolsLocator.getI18nManager();
271 376 llmarques
                        showConsoleMessage("\n"
272
                            + i18nManager.getTranslation("invalid_option"));
273 226 llmarques
                    }
274
275
                    if (!serviceStack.isEmpty()
276
                        && !getActiveService().next().getTypes()
277 245 llmarques
                            .contains(TYPE.GEOMETRY)) {
278 226 llmarques
                        serviceStack.pop();
279
                    }
280
281
                    setActiveService(service);
282 252 llmarques
283 226 llmarques
                    getNextParameter();
284
                }
285
            }
286 109 llmarques
        }
287
    }
288 89 llmarques
289 227 llmarques
    private void addBehaviors(Behavior[] additionalBehavior)
290
        throws CreateEditingBehaviorException {
291
292
        DefaultEditingBehavior editingBehavior;
293
        EditingCompoundBehavior editingCompoundBehavior;
294
295
        if (!getMapControl().hasTool("VectorEditing")) {
296
297
            editingBehavior = new DefaultEditingBehavior(this);
298
            editingCompoundBehavior =
299
                new EditingCompoundBehavior(editingBehavior);
300
            setCompoundBehavior(editingCompoundBehavior);
301
302
            if (additionalBehavior != null) {
303
304
                Behavior[] behaviors =
305
                    new Behavior[additionalBehavior.length + 1];
306
                behaviors[0] = editingCompoundBehavior;
307
308
                for (int i = 0; i < additionalBehavior.length; i++) {
309
                    behaviors[i + 1] = additionalBehavior[i];
310
                }
311
312
                getMapControl().addBehavior("VectorEditing", behaviors);
313
314
                lastAdditionalBehaviors = additionalBehavior;
315
316
            } else {
317
                getMapControl().addBehavior("VectorEditing",
318
                    editingCompoundBehavior);
319
            }
320
321
        } else {
322
            editingCompoundBehavior = getEditingCompoundBehavior();
323
            editingBehavior =
324
                (DefaultEditingBehavior) editingCompoundBehavior
325 245 llmarques
                    .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
326 227 llmarques
            setCompoundBehavior(editingCompoundBehavior);
327
            cleanEditingContext();
328
        }
329
330
    }
331
332
    private void addLayerListeners() {
333
334 383 llmarques
        FLayers layers = mapContextReference.get().getLayers();
335 227 llmarques
336
        layers.addLayerListener(layerListener);
337
338
        layers.addLayerCollectionListener(new LayerCollectionListener() {
339
340 546 llmarques
            public void addLayer(FLayer layer) {
341
                if (layer instanceof FLayers) {
342
                    FLayers layers = (FLayers) layer;
343
                    for (int i = 0; i < layers.getLayersCount(); i++) {
344
                        addLayer(layers.getLayer(i));
345 227 llmarques
                    }
346 546 llmarques
                } else if (layer instanceof FLyrVect) {
347
                    ((FLyrVect) layer).addLayerListener(layerListener);
348 227 llmarques
                }
349
            }
350 842 fdiaz
351 546 llmarques
            public void layerAdded(LayerCollectionEvent e) {
352
                addLayer(e.getLayers());
353
            }
354 227 llmarques
355
            public void layerAdding(LayerCollectionEvent e)
356
                throws CancelationException {
357
            }
358
359
            public void layerMoved(LayerPositionEvent e) {
360
            }
361
362
            public void layerMoving(LayerPositionEvent e)
363
                throws CancelationException {
364
            }
365 842 fdiaz
366 547 llmarques
            public void removeLayer(FLayer layer) {
367
                if (layer instanceof FLayers) {
368
                    FLayers layers = (FLayers) layer;
369
                    for (int i = 0; i < layers.getLayersCount(); i++) {
370
                        addLayer(layers.getLayer(i));
371 227 llmarques
                    }
372 547 llmarques
                } else if (layer instanceof FLyrVect) {
373
                    ((FLyrVect) layer).removeLayerListener(layerListener);
374 227 llmarques
                }
375
            }
376
377 547 llmarques
            public void layerRemoved(LayerCollectionEvent e) {
378
                removeLayer(e.getLayers());
379
            }
380
381 227 llmarques
            public void layerRemoving(LayerCollectionEvent e)
382
                throws CancelationException {
383
            }
384
385
            public void visibilityChanged(LayerCollectionEvent e)
386
                throws CancelationException {
387
            }
388
        });
389
    }
390
391
    public void addObserver(Observer o) {
392
        this.observableHelper.addObserver(o);
393
    }
394
395
    private void askQuestion(EditingServiceParameter param) {
396 245 llmarques
        I18nManager i18nManager = ToolsLocator.getI18nManager();
397
        String translation = i18nManager.getTranslation(param.getDescription());
398
        String activeServiceName =
399
            i18nManager.getTranslation(getActiveService().getName());
400 365 llmarques
401 377 fdiaz
        Object defaultValue = param.getDefaultValue();
402
        String strDefaultValue;
403
404
        if (defaultValue != null) {
405 383 llmarques
            if (defaultValue instanceof String) {
406
                strDefaultValue = (String) defaultValue;
407
                strDefaultValue =
408
                    i18nManager.getTranslation((String) defaultValue);
409 377 fdiaz
            } else {
410 842 fdiaz
                if(defaultValue instanceof Point){
411
                    Point point = (Point)defaultValue;
412
                    StringBuilder builder = new StringBuilder();
413
                    for(int i=0; i<point.getDimension(); i++){
414
                        builder.append(point.getCoordinateAt(i));
415
                        if(i < point.getDimension()-1){
416
                            builder.append(" , ");
417
                        }
418
                    }
419
                    strDefaultValue = builder.toString();
420
                } else {
421
                    strDefaultValue = defaultValue.toString();
422
                }
423 377 fdiaz
            }
424 383 llmarques
            showConsoleMessage("\n" + activeServiceName + "# " + translation
425
                + "<" + strDefaultValue + "> : ");
426 365 llmarques
        } else {
427
            showConsoleMessage("\n" + activeServiceName + "# " + translation
428
                + " : ");
429
        }
430 227 llmarques
    }
431 842 fdiaz
432 438 fdiaz
    public synchronized void beginEdition(FLyrVect layer,
433
        Behavior[] additionalBehaviors) {
434 842 fdiaz
435 546 llmarques
        try{
436
            throw new Exception("Deprecated method");
437
        } catch (Exception e){
438
            logger.info("Deprecated method", e);
439
        }
440 842 fdiaz
441 546 llmarques
        beginEdition(layer);
442
        try {
443
            addBehaviors(additionalBehaviors);
444
        } catch (CreateEditingBehaviorException e1) {
445
            logger.info("Problems adding behaviors to editing context", e1);
446
            getMapControl().setTool("pan");
447
            return;
448
        }
449
    }
450 842 fdiaz
451
    public synchronized void beginEdition(FLyrVect layer) {
452
453 109 llmarques
        EditingNotificationManager editingNotificationManager =
454 844 jjdelcerro
            DALSwingLocator.getEditingNotificationManager();
455 89 llmarques
456 109 llmarques
        EditingNotification notification =
457
            editingNotificationManager.notifyObservers(this,
458 986 jjdelcerro
                EditingNotification.BEFORE_ENTER_EDITING_STORE, null, layer,layer.getFeatureStore());
459 89 llmarques
460 109 llmarques
        if (notification.isCanceled()) {
461 130 llmarques
            String msg =
462
                String.format("Edit layer %1$s canceled by somme observer.",
463
                    layer.getName());
464
            logger.info(msg, new StartEditingException(msg, null));
465
            return;
466 109 llmarques
        }
467 842 fdiaz
468 226 llmarques
        setCurrentLayer(layer);
469 127 llmarques
470 438 fdiaz
        FeatureStore featureStore = layer.getFeatureStore();
471
        if (!featureStore.isEditing()) {
472
            try {
473
                featureStore.edit();
474
            } catch (Exception e) {
475
                String msg =
476
                    String.format("Can't set %1$s in edit mode",
477
                        featureStore.getName());
478
                logger.info(msg, new VectorEditingException(e));
479
                cleanEditingContext();
480
                return;
481
            }
482 109 llmarques
        }
483 89 llmarques
484 438 fdiaz
        featureStore.addObserver(getMapControl());
485 89 llmarques
486 109 llmarques
        editingNotificationManager.notifyObservers(this,
487 986 jjdelcerro
            EditingNotification.AFTER_ENTER_EDITING_STORE, null, layer, layer.getFeatureStore());
488 150 llmarques
489 366 llmarques
        enableSnapping();
490 89 llmarques
    }
491
492 366 llmarques
    @SuppressWarnings({ "rawtypes", "unchecked" })
493
    private void enableSnapping() {
494
        Preferences prefs = Preferences.userRoot().node("snappers");
495 1095 fdiaz
         getMapControl().setRefentEnabled(prefs.getBoolean("apply-snappers", false));
496
         if (currentLayer != null) {
497 366 llmarques
            ArrayList layersToSnap =
498
                getMapControl().getMapContext().getLayersToSnap();
499
            if (!layersToSnap.contains(currentLayer)) {
500
                layersToSnap.add(currentLayer);
501
            }
502
        }
503
    }
504
505
    @SuppressWarnings("rawtypes")
506
    private void disableSnapping() {
507
        ArrayList layersToSnap =
508
            getMapControl().getMapContext().getLayersToSnap();
509
        if (layersToSnap.contains(currentLayer)) {
510
            layersToSnap.remove(currentLayer);
511
        }
512
    }
513
514 245 llmarques
    private void changeSelectedTool(String name) {
515 316 llmarques
        if (name.equalsIgnoreCase(DEFAULT_TOOL)) {
516 303 fdiaz
            name = "selection-simple-select-view";
517
            this.getMapControl().setTool("pointSelection");
518
        }
519 365 llmarques
        Notification notification =
520
            new BaseNotification(
521
                EditingContext.CHANGE_SELECTED_TOOL_NOTIFICATION,
522
                new Object[] { name });
523 303 fdiaz
        this.observableHelper.notifyObservers(this, notification);
524 245 llmarques
    }
525
526 227 llmarques
    private void cleanEditingContext() {
527
        serviceStack.clear();
528
        currentParam = null;
529
        this.enableSelection(false);
530
        refreshMenusAndToolBars();
531 89 llmarques
532 227 llmarques
        I18nManager i18nManager = ToolsLocator.getI18nManager();
533
        showConsoleMessage("\n" + i18nManager.getTranslation("select_new_tool")
534
            + "\n");
535
    }
536 127 llmarques
537 227 llmarques
    public void deleteObserver(Observer o) {
538
        this.observableHelper.deleteObserver(o);
539 109 llmarques
    }
540 89 llmarques
541 227 llmarques
    public void deleteObservers() {
542
        this.observableHelper.deleteObservers();
543 142 llmarques
    }
544
545 109 llmarques
    private void discardChanges(FLyrVect layer) throws EndEditingException {
546
        FeatureStore featureStore = layer.getFeatureStore();
547
        try {
548
            featureStore.cancelEditing();
549
        } catch (Exception e) {
550
            throw new EndEditingException(e);
551 89 llmarques
        }
552
    }
553
554 109 llmarques
    private void doAction(FLyrVect layer, int option) {
555
        switch (option) {
556
        case SAVE_CHANGES:
557
            try {
558
                saveChanges(layer);
559
            } catch (VectorEditingException e) {
560 130 llmarques
                String msg =
561
                    String.format("Changes can not be saved in %1$s",
562
                        layer.getName());
563
                logger.info(msg, e);
564 161 llmarques
                return;
565 109 llmarques
            }
566
            break;
567 130 llmarques
568 109 llmarques
        case DISCARD_CHANGES:
569
            try {
570
                discardChanges(layer);
571
            } catch (VectorEditingException e) {
572 130 llmarques
                String msg =
573
                    String.format("Changes can not be discared in %1$s",
574
                        layer.getName());
575
                logger.info(msg, e);
576 161 llmarques
                return;
577 109 llmarques
            }
578
            break;
579 130 llmarques
580 109 llmarques
        case EXPORT_LAYER:
581
            try {
582
                exportLayer(layer);
583
            } catch (VectorEditingException e) {
584 130 llmarques
                String msg =
585
                    String.format("Changes of %1$s can not be exported",
586
                        layer.getName());
587
                logger.info(msg, e);
588 161 llmarques
                return;
589 109 llmarques
            }
590
            break;
591 130 llmarques
592 109 llmarques
        case CANCEL:
593 126 llmarques
            return;
594 109 llmarques
        }
595 127 llmarques
596 226 llmarques
        cleanEditingContext();
597 126 llmarques
        hideConsole();
598 366 llmarques
        disableSnapping();
599 302 fdiaz
        changeSelectedTool(DEFAULT_TOOL);
600 127 llmarques
601 126 llmarques
        FeatureStore featureStore = layer.getFeatureStore();
602 142 llmarques
        featureStore.deleteObserver(getMapControl());
603 89 llmarques
604 109 llmarques
    }
605 89 llmarques
606 226 llmarques
    private void enableSelection(boolean enableSelection) {
607 109 llmarques
        this.editingCompoundBehavior.setDrawnBehavior(
608
            EditingCompoundBehavior.SELECTION_INDEX, enableSelection);
609 89 llmarques
    }
610
611 109 llmarques
    public void endEdition(FLyrVect layer) {
612
        if (layer.isEditing()) {
613
            EditingNotificationManager editingNotificationManager =
614 844 jjdelcerro
                DALSwingLocator.getEditingNotificationManager();
615 89 llmarques
616 109 llmarques
            EditingNotification notification =
617
                editingNotificationManager.notifyObservers(this,
618 986 jjdelcerro
                    EditingNotification.BEFORE_EXIT_EDITING_STORE, null, layer, layer.getFeatureStore());
619 89 llmarques
620 109 llmarques
            if (notification.isCanceled()) {
621 130 llmarques
                String msg =
622
                    String.format(
623
                        "Stop edit layer %1$s canceled by somme observer.",
624
                        layer.getName());
625
                logger.info(msg, new EndEditingException(msg, null));
626 89 llmarques
627 109 llmarques
            }
628 130 llmarques
629 142 llmarques
            getMapControl().getCanceldraw().setCanceled(true);
630 109 llmarques
            int option;
631
            EditingSwingManager swingManager =
632
                EditingSwingLocator.getSwingManager();
633 130 llmarques
634 842 fdiaz
635 672 jjdelcerro
            if (layer.isWritable() && getMapControl().getProjection().equals(layer.getProjection()) ) {
636 109 llmarques
                option =
637 142 llmarques
                    swingManager.showPanelSaveOrDiscard(getMapControl(),
638 109 llmarques
                        layer.getName());
639
            } else {
640
                option =
641 142 llmarques
                    swingManager.showPanelExportOrDiscard(getMapControl(),
642 109 llmarques
                        layer.getName());
643
            }
644 89 llmarques
645 109 llmarques
            doAction(layer, option);
646 89 llmarques
647 109 llmarques
            editingNotificationManager.notifyObservers(this,
648 986 jjdelcerro
                EditingNotification.AFTER_EXIT_EDITING_STORE, null, layer, layer.getFeatureStore());
649 89 llmarques
650 109 llmarques
        }
651 89 llmarques
652
    }
653
654 109 llmarques
    private void exportLayer(FLyrVect layer) throws EndEditingException {
655 673 jjdelcerro
        Notification notification = new BaseNotification(EditingContext.EXPORT_LAYER_NOTIFICATION,1);
656
        notification.setValue(layer);
657
        this.observableHelper.notifyObservers(this, notification);
658 109 llmarques
    }
659 89 llmarques
660 227 llmarques
    protected void finishService() {
661
        EditingService lastService = serviceStack.pop();
662
        try {
663
664
            if (!serviceStack.isEmpty()
665
                && getActiveService().next().getTypes().contains(TYPE.GEOMETRY)) {
666
                Geometry geometry = lastService.finish();
667
                if (geometry != null) {
668
                    getActiveService().setValue(geometry);
669
                }
670
            } else {
671
                lastService.finishAndStore();
672
                getMapControl().rePaintDirtyLayers();
673 252 llmarques
674
                I18nManager i18nManager = ToolsLocator.getI18nManager();
675
                showConsoleMessage("\n"
676 316 llmarques
                    + i18nManager.getTranslation(lastService.getName()) + "# "
677 252 llmarques
                    + i18nManager.getTranslation("finished") + "\n");
678 484 fdiaz
                lastService.stop();
679 227 llmarques
                setActiveService(lastService);
680 484 fdiaz
                lastService.start();
681 316 llmarques
                changeSelectedTool(getActiveService().getName());
682 227 llmarques
            }
683
684
        } catch (InvalidEntryException ex) {
685
            I18nManager i18nManager = ToolsLocator.getI18nManager();
686 376 llmarques
            showConsoleMessage("\n"
687
                + i18nManager.getTranslation("invalid_option"));
688 316 llmarques
            changeSelectedTool(getActiveService().getName());
689 227 llmarques
        } catch (VectorEditingException ex) {
690
            logger.info("Can't finish " + lastService.getName(), ex);
691
            cleanEditingContext();
692
            return;
693
        }
694
695
        getNextParameter();
696
    }
697
698
    protected EditingService getActiveService() {
699
        if (!serviceStack.isEmpty()) {
700
            return serviceStack.peek();
701
        }
702
        return null;
703
    }
704
705 376 llmarques
    private EditingConsole getConsolePanel() {
706 109 llmarques
        if (console == null) {
707 376 llmarques
            console = new DefaultEditingConsole(new ResponseListener() {
708
709
                public void acceptResponse(String response) {
710
                    textEntered(response);
711
                }
712
            });
713 109 llmarques
        }
714
        return console;
715
    }
716 89 llmarques
717 227 llmarques
    protected FLyrVect getCurrentLayer() {
718
        return this.currentLayer;
719
    }
720
721
    protected EditingServiceParameter getCurrentParam() {
722
        return this.currentParam;
723
    }
724
725 109 llmarques
    private Component getDockConsole() {
726
        if (dockConsole == null) {
727 376 llmarques
            dockConsole = new JDockPanel((JComponent) getConsolePanel());
728 109 llmarques
        }
729
        return dockConsole;
730 89 llmarques
    }
731
732 224 llmarques
    private DefaultEditingBehavior getEditingBehavior() {
733 160 llmarques
        if (editingCompoundBehavior != null) {
734 224 llmarques
            return (DefaultEditingBehavior) editingCompoundBehavior
735 160 llmarques
                .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
736
        }
737
        return null;
738 89 llmarques
    }
739
740 109 llmarques
    private EditingCompoundBehavior getEditingCompoundBehavior() {
741
        if (editingCompoundBehavior != null) {
742
            return editingCompoundBehavior;
743
        } else {
744
            EditingCompoundBehavior editingCompoundBehavior;
745 89 llmarques
746 109 llmarques
            CompoundBehavior compoundBehavior =
747 142 llmarques
                (CompoundBehavior) getMapControl().getMapTool("VectorEditing");
748 127 llmarques
749 109 llmarques
            if (compoundBehavior instanceof EditingCompoundBehavior) {
750
                editingCompoundBehavior =
751
                    (EditingCompoundBehavior) compoundBehavior;
752
            } else {
753
                editingCompoundBehavior =
754
                    (EditingCompoundBehavior) compoundBehavior.getBehavior(0);
755
            }
756 127 llmarques
757 109 llmarques
            setCompoundBehavior(editingCompoundBehavior);
758
            return editingCompoundBehavior;
759
        }
760 89 llmarques
    }
761
762 227 llmarques
    public MapControl getMapControl() {
763 323 llmarques
        return mapControlReference.get();
764 227 llmarques
    }
765
766 226 llmarques
    protected void getNextParameter() {
767 1143 fdiaz
        if ((getMapControl().getCurrentTool() != null)
768
            && !getMapControl().getCurrentTool().equals("VectorEditing")) {
769
            getMapControl().setTool("VectorEditing");
770
        }
771 226 llmarques
        currentParam = getActiveService().next();
772
773
        if (currentParam == null) {
774
            finishService();
775
        } else {
776
            askQuestion(currentParam);
777
            if (currentParam.getTypes().contains(TYPE.SELECTION)) {
778
                enableSelection(true);
779
            } else if (currentParam.getTypes().contains(TYPE.GEOMETRY)) {
780
                refreshMenusAndToolBars();
781
            }
782
        }
783
    }
784
785 227 llmarques
    protected Stack<EditingService> getServiceStack() {
786
        return this.serviceStack;
787
    }
788
789 109 llmarques
    private void hideConsole() {
790
        isShowConsole = false;
791 876 jjdelcerro
        if( !SwingUtilities.isEventDispatchThread() ) {
792
            try {
793
                SwingUtilities.invokeAndWait(new Runnable() {
794 1095 fdiaz
795 876 jjdelcerro
                    @Override
796
                    public void run() {
797
                        hideConsole();
798
                    }
799
                });
800
                return;
801
            } catch (InterruptedException | InvocationTargetException ex) {
802
                logger.warn("Can't hide editing console.",ex);
803
            }
804
            return;
805 1095 fdiaz
        }
806 109 llmarques
        getDockConsole().setVisible(false);
807
    }
808 89 llmarques
809 157 llmarques
    public boolean isServiceCompatible(String name) {
810 224 llmarques
        DefaultEditingBehavior editingBehavior = getEditingBehavior();
811 157 llmarques
812
        if (editingBehavior != null) {
813
814
            try {
815 226 llmarques
                EditingManager manager = EditingLocator.getManager();
816
                EditingServiceInfo serviceInfo = manager.getServiceInfo(name);
817
                GeometryType geoType = null;
818
819
                for (EditingService editingService : getServiceStack()) {
820 316 llmarques
                    EditingServiceParameter parameter = editingService.next();
821
                    if (parameter != null
822
                        && parameter.getTypes().contains(TYPE.GEOMETRY)) {
823 226 llmarques
824 316 llmarques
                        int geometryType = parameter.getGeometryType();
825 226 llmarques
                        int subType = -1;
826 316 llmarques
827 226 llmarques
                        try {
828
                            subType =
829
                                getCurrentLayer().getFeatureStore()
830 245 llmarques
                                    .getDefaultFeatureType()
831
                                    .getDefaultGeometryAttribute()
832
                                    .getGeomType().getSubType();
833 226 llmarques
834
                            geoType =
835
                                GeometryLocator.getGeometryManager()
836 245 llmarques
                                    .getGeometryType(geometryType, subType);
837 226 llmarques
                        } catch (Exception e) {
838
839
                            String msg =
840 316 llmarques
                                String.format(
841
                                    "Problems getting default feature"
842
                                        + " type of %1$s or getting geometry"
843
                                        + " type of %2$s %3$s",
844
                                    getCurrentLayer().getName(), geometryType,
845
                                    subType);
846 226 llmarques
847
                            throw new ServiceInformationException(msg, e);
848
                        }
849
850
                        return serviceInfo.isCompatibleWith(geoType)
851
                            && serviceInfo.createsNewGeometries();
852
                    }
853
                }
854
855
                if (getCurrentLayer() != null) {
856
                    try {
857
                        geoType =
858
                            getCurrentLayer().getFeatureStore()
859 245 llmarques
                                .getDefaultFeatureType()
860
                                .getDefaultGeometryAttribute().getGeomType();
861 226 llmarques
                    } catch (DataException e) {
862
                        String msg =
863
                            String.format("Problems getting default "
864
                                + "feature type of %1$s", getCurrentLayer()
865
                                .getName());
866
                        throw new ServiceInformationException(msg, e);
867
                    }
868
869
                    return serviceInfo.isCompatibleWith(geoType);
870
                }
871
872
                return false;
873 157 llmarques
            } catch (ServiceInformationException e) {
874 365 llmarques
                logger.warn(
875
                    "Problems getting if editing context is compatible with "
876
                        + name, e);
877 157 llmarques
            }
878
        }
879
        return false;
880
    }
881
882 227 llmarques
    private Point parsePoint(String response) throws ParsePointException {
883
        String[] numbers = new String[1];
884
        numbers[0] = response;
885
        numbers = response.split(",");
886 842 fdiaz
        int dimension = numbers.length;
887
        if (dimension >= 2 && dimension <= 4) {
888 157 llmarques
889 842 fdiaz
            if (numbers[0].startsWith("(") && numbers[dimension-1].endsWith(")\n")) { // CCS
890 227 llmarques
                numbers[0] = numbers[0].replace("(", "");
891 842 fdiaz
                numbers[dimension-1] = numbers[dimension-1].replace(")\n", "");
892 227 llmarques
            }
893 157 llmarques
894 227 llmarques
            Point point;
895
            try {
896
                GeometryManager geomManager =
897
                    GeometryLocator.getGeometryManager();
898 842 fdiaz
                int subType;
899
                switch (dimension) {
900
                case 3:
901
                    subType = Geometry.SUBTYPES.GEOM3D;
902
                    break;
903
                case 4:
904
                    subType = Geometry.SUBTYPES.GEOM3DM;
905
                    break;
906
                default:
907
                    subType = Geometry.SUBTYPES.GEOM2D;
908
                    break;
909
                }
910
                point = (Point) geomManager.create(geomManager.getGeometryType(Geometry.TYPES.POINT, subType));
911
                for (int i = 0; i < dimension; i++) {
912
                    point.setCoordinateAt(i, Double.parseDouble(numbers[i]));
913
                }
914 226 llmarques
915 227 llmarques
            } catch (Exception e) {
916
                throw new ParsePointException(e);
917
            }
918
            return point;
919
        } else {
920
            throw new ParsePointException(null);
921 226 llmarques
        }
922
    }
923
924 227 llmarques
    private Double parseValue(String response) throws ParseValueException {
925
        try {
926
            return Double.valueOf(response);
927
        } catch (Exception e) {
928
            throw new ParseValueException(e);
929
        }
930 226 llmarques
931
    }
932
933 227 llmarques
    protected void refreshMenusAndToolBars() {
934 876 jjdelcerro
        if (!SwingUtilities.isEventDispatchThread()) {
935
            SwingUtilities.invokeLater(new Runnable() {
936
937
                @Override
938
                public void run() {
939
                    refreshMenusAndToolBars();
940
                }
941
            });
942
            return;
943
        }
944
        Notification notification = new BaseNotification(
945
                EditingContext.REFRESH_TOOLS_NOTIFICATION,
946
                null
947
        );
948 303 fdiaz
        this.observableHelper.notifyObservers(this, notification);
949 226 llmarques
    }
950
951 227 llmarques
    private void saveChanges(FLyrVect layer) throws EndEditingException {
952
        FeatureStore featureStore = layer.getFeatureStore();
953 226 llmarques
        try {
954 227 llmarques
            featureStore.finishEditing();
955
        } catch (Exception e) {
956
            throw new EndEditingException(e);
957 226 llmarques
        }
958 227 llmarques
    }
959 226 llmarques
960 227 llmarques
    private void setActiveService(EditingService service) {
961
        serviceStack.add(service);
962 226 llmarques
    }
963
964 227 llmarques
    private void setCompoundBehavior(EditingCompoundBehavior compoundBehavior) {
965
        this.editingCompoundBehavior = compoundBehavior;
966
    }
967
968 226 llmarques
    private void setCurrentLayer(FLyrVect layer) {
969
970
        if (this.currentLayer != layer) {
971 438 fdiaz
            this.currentLayer = layer;
972 226 llmarques
            cleanEditingContext();
973
        }
974
975
    }
976
977 227 llmarques
    public void setMapControl(MapControl mapControl) {
978 226 llmarques
979 227 llmarques
        this.mapControlReference = new WeakReference<MapControl>(mapControl);
980 383 llmarques
        this.mapContextReference =
981
            new WeakReference<MapContext>(mapControl.getMapContext());
982 227 llmarques
983
        // When mapControl is updated we have to add older additional behaviors
984
        // to new mapControl
985
        if (lastAdditionalBehaviors != null) {
986
            try {
987
                addBehaviors(lastAdditionalBehaviors);
988
            } catch (CreateEditingBehaviorException e1) {
989
                logger.info("Problems adding behaviors to editing context", e1);
990
                getMapControl().setTool("pan");
991
                return;
992
            }
993
        }
994 226 llmarques
    }
995
996 227 llmarques
    private void showConsole() {
997
        if (isShowConsole) {
998
            return;
999
        }
1000 876 jjdelcerro
        if( !SwingUtilities.isEventDispatchThread() ) {
1001
            try {
1002
                SwingUtilities.invokeAndWait(new Runnable() {
1003 1095 fdiaz
1004 876 jjdelcerro
                    @Override
1005
                    public void run() {
1006
                        showConsole();
1007
                    }
1008
                });
1009
                return;
1010
            } catch (InterruptedException | InvocationTargetException ex) {
1011
                logger.warn("Can't show editing console.",ex);
1012
            }
1013
            return;
1014 1095 fdiaz
        }
1015 227 llmarques
        isShowConsole = true;
1016
        getMapControl().remove(getDockConsole());
1017
        getMapControl().setLayout(new BorderLayout());
1018
        getMapControl().add(getDockConsole(), BorderLayout.SOUTH);
1019
        getDockConsole().setVisible(true);
1020 226 llmarques
    }
1021
1022 876 jjdelcerro
    protected void showConsoleMessage(final String text) {
1023
        if (!SwingUtilities.isEventDispatchThread()) {
1024
            SwingUtilities.invokeLater(new Runnable() {
1025
1026
                @Override
1027
                public void run() {
1028
                    showConsoleMessage(text);
1029
                }
1030
            });
1031
            return;
1032
        }
1033 376 llmarques
        getConsolePanel().addText(text);
1034 227 llmarques
    }
1035
1036 226 llmarques
    protected void textEntered(String response) {
1037 472 fdiaz
        FeatureStore featureStore = getCurrentLayer().getFeatureStore();
1038 842 fdiaz
        EditingService activeService = getActiveService();
1039 226 llmarques
        if (response == null) {
1040 842 fdiaz
            if (activeService != null) {
1041 226 llmarques
                try {
1042 842 fdiaz
                    activeService.stop();
1043 302 fdiaz
                    serviceStack.pop();
1044 316 llmarques
                    if (serviceStack.isEmpty()) {
1045 472 fdiaz
                        featureStore
1046 302 fdiaz
                            .getFeatureSelection().deselectAll();
1047
                        changeSelectedTool(DEFAULT_TOOL);
1048
                    } else {
1049 842 fdiaz
                        changeSelectedTool(activeService.getName());
1050 302 fdiaz
                    }
1051 226 llmarques
1052 245 llmarques
                    refreshMenusAndToolBars();
1053 842 fdiaz
                    activeService = getActiveService();
1054
                    if (activeService != null) {
1055 302 fdiaz
                        getNextParameter();
1056
                    } else {
1057
                        cleanEditingContext();
1058
                    }
1059 245 llmarques
1060 226 llmarques
                } catch (StopServiceException e) {
1061
                    logger
1062 842 fdiaz
                        .info("Can't stop " + activeService.getName(), e);
1063 226 llmarques
                    return;
1064 245 llmarques
                } catch (DataException e) {
1065
                    logger.info("Can't get selection of "
1066 472 fdiaz
                        + featureStore.getFullName(), e);
1067 245 llmarques
                    return;
1068 226 llmarques
                }
1069
            }
1070
        } else {
1071
1072
            if (getCurrentParam() != null) {
1073
                Set<TYPE> types = getCurrentParam().getTypes();
1074
                Point point = null;
1075
                Double value = null;
1076 842 fdiaz
                Point defaultPoint = null;
1077
                Object defaultValue = getCurrentParam().getDefaultValue();
1078
//                int dimension = 2;
1079
//                if(defaultValue != null && defaultValue instanceof Point){
1080
                    defaultPoint = (Point)defaultValue;
1081
//                    dimension = defaultPoint.getDimension();
1082
//                }
1083 226 llmarques
1084
                boolean insertedValue = false;
1085 227 llmarques
                if ((!insertedValue && types.contains(TYPE.POSITION))
1086 226 llmarques
                    || types.contains(TYPE.LIST_POSITIONS)) {
1087
1088
                    try {
1089 842 fdiaz
                        if(StringUtils.isEmpty(response.replace("\n", ""))){
1090
                            point = defaultPoint;
1091
                        } else {
1092
                            point = parsePoint(response);
1093
                        }
1094 226 llmarques
1095
                        if (point != null) {
1096 842 fdiaz
                            activeService.setValue(point);
1097 226 llmarques
                            insertedValue = true;
1098
                        }
1099
1100
                    } catch (VectorEditingException e) {
1101
                        // Do nothing to try other types
1102
                    }
1103
                }
1104
                if (!insertedValue && types.contains(TYPE.VALUE)) {
1105
1106
                    try {
1107
1108
                        value = parseValue(response);
1109
                        if (value != null) {
1110 842 fdiaz
                            activeService.setValue(value);
1111 226 llmarques
                            insertedValue = true;
1112
                        }
1113
1114
                    } catch (VectorEditingException e) {
1115
                        // Do nothing to try other types
1116
                    }
1117
1118
                }
1119
                if (!insertedValue && types.contains(TYPE.OPTION)) {
1120
1121
                    try {
1122
1123
                        response = response.replace("\n", "");
1124
                        if (response != null) {
1125 842 fdiaz
                            activeService.setValue(response);
1126 226 llmarques
                            insertedValue = true;
1127
                        }
1128
1129
                    } catch (VectorEditingException e) {
1130
                        // Do nothing to try other types
1131
                    }
1132
                }
1133
                if (!insertedValue && types.contains(TYPE.SELECTION)) {
1134
                    if (response.equalsIgnoreCase("\n")) {
1135
                        enableSelection(false);
1136
                        insertedValue = true;
1137
1138
                        try {
1139
1140 1143 fdiaz
                            FeatureSelection clonedSelection = (FeatureSelection)featureStore
1141
                                .getFeatureSelection().clone();
1142
                            if(clonedSelection.isEmpty()){
1143
                               throw new InvalidEntryException(null);
1144
                            }
1145 842 fdiaz
                            activeService.setValue(
1146 1143 fdiaz
                                clonedSelection);
1147 226 llmarques
1148
                        } catch (InvalidEntryException e) {
1149
                            I18nManager i18nManager =
1150
                                ToolsLocator.getI18nManager();
1151 376 llmarques
                            showConsoleMessage("\n"
1152
                                + i18nManager.getTranslation("invalid_option"));
1153 226 llmarques
                        } catch (Exception e) {
1154 472 fdiaz
                            logger.info("Can't access to selection.", e);
1155 226 llmarques
                            cleanEditingContext();
1156
                            return;
1157
                        }
1158
                    }
1159
                }
1160
                if (!insertedValue) {
1161
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
1162 376 llmarques
                    showConsoleMessage("\n"
1163
                        + i18nManager.getTranslation("invalid_option"));
1164 226 llmarques
                }
1165
                getNextParameter();
1166
            }
1167
        }
1168
    }
1169 438 fdiaz
1170
    public void setDefaultBehaviors(Behavior[] defaultBehaviors) {
1171
        this.defaultBehaviors = defaultBehaviors;
1172 546 llmarques
        try {
1173
            addBehaviors(defaultBehaviors);
1174
        } catch (CreateEditingBehaviorException e1) {
1175
            logger.info("Problems adding behaviors to editing context", e1);
1176
            getMapControl().setTool("pan");
1177
            return;
1178
        }
1179 438 fdiaz
    }
1180
1181
    public Behavior[] getDefaultBehaviors() {
1182
        return this.defaultBehaviors;
1183
    }
1184 89 llmarques
}