Statistics
| Revision:

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

History | View | Annotate | Download (14.8 KB)

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

    
26
import java.io.File;
27
import java.util.ArrayList;
28
import java.util.Iterator;
29
import java.util.List;
30

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

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

    
83
public class EditingExtension extends Extension implements Observer {
84

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

    
87
    public void execute(String actionCommand) {
88

    
89
        IView view = getActiveView();
90
        EditingSwingManager swingManager =
91
            EditingSwingLocator.getSwingManager();
92

    
93
        if (view != null) {
94

    
95
            FLyrVect layer = getActiveLayer(view);
96
            EditingContext editingContext =
97
                swingManager.getEditingContext(view.getMapControl());
98

    
99
            if ("start-editing".equals(actionCommand)) {
100

    
101
                if (canBeEdited(layer)) {
102
                    MapControl mapControl = view.getMapControl();
103
                    StatusBarListener sbl = new StatusBarListener(mapControl);
104
                    editingContext.beginEdition(layer,
105
                        new Behavior[] { new MouseMovementBehavior(sbl) });
106
                    editingContext.addObserver(this);
107
                    ApplicationLocator.getManager().refreshMenusAndToolBars();
108
                }
109

    
110
            } else if ("end-editing".equals(actionCommand)) {
111

    
112
                if ((layer != null) && layer.isEditing()) {
113
                    editingContext.endEdition(layer);
114
                    ApplicationLocator.getManager().refreshMenusAndToolBars();
115
                }
116

    
117
            }
118
        }
119
    }
120

    
121
    public void initialize() {
122
        registerIcons();
123

    
124
        // Disable default view panel console. Uses editing context console.
125
        DefaultViewPanel.setDisableConsole(true);
126

    
127
        // Adding TOC menu entry
128
        ExtensionPoint exPoint = ToolsLocator.getExtensionPointManager().add(
129
                "View_TocActions", "");
130
        exPoint.append(
131
            StartEditingTocMenuEntry.EXTENSION_POINT_NAME,
132
                "TOC popup menu to start vector layer's editing",
133
                new StartEditingTocMenuEntry());
134
        exPoint.append(
135
            EndEditingTocMenuEntry.EXTENSION_POINT_NAME,
136
                "TOC popup menu to end vector layer's editing",
137
                new EndEditingTocMenuEntry());
138
    }
139

    
140

    
141
    private void registerIcons() {
142
        IconThemeHelper.registerIcon("vectorediting", "vector-editing", this);
143
    }
144

    
145
    @Override
146
    public void postInitialize() {
147
        super.postInitialize();
148
        registerSymbols();
149

    
150
        MapControlLocator.getMapControlManager().addMapControlCreationListener(new MapControlCreationListener() {
151

    
152
            public MapControl mapControlCreated(MapControl mapControl) {
153
                EditingContext editingContext = EditingSwingLocator.getSwingManager().getEditingContext(mapControl);
154
                StatusBarListener sbl = new StatusBarListener(mapControl);
155
                editingContext.setDefaultBehaviors(new Behavior[] { new MouseMovementBehavior(sbl) });
156
                editingContext.addObserver(EditingExtension.this);
157
                ApplicationLocator.getManager().refreshMenusAndToolBars();
158
                return mapControl;
159
            }
160
        });
161
    }
162

    
163
    /**
164
     * Register all symbols in the plugin symbols folder in the providerManager.
165
     * The description of the symbols must be unique because the key used for registration is the proper description of the symbol.
166
     *
167
     */
168
    private void registerSymbols() {
169

    
170
        EditingProviderManager providerManager =
171
            EditingProviderLocator.getProviderManager();
172

    
173
        SymbolManager symbolManager = MapContextLocator.getSymbolManager();
174
        File pluginFolder = getPlugin().getPluginDirectory();
175
        String pathSeparator = System.getProperty("file.separator");
176
        String symbolsPath = pluginFolder.getAbsolutePath()+pathSeparator+"symbols"+pathSeparator+"editing";
177
        File symbolsFolder = new File(symbolsPath);
178
        ISymbol[] symbols = null;
179
        try {
180
            symbols = symbolManager.loadSymbols(symbolsFolder);
181
        } catch (SymbolException e) {
182
            logger.warn("No symbols loaded from "+symbolsPath, e);
183
        }
184

    
185
        if (symbols != null) {
186
            for (int i = 0; i < symbols.length; i++) {
187
                ISymbol symbol = symbols[i];
188
                String description = symbol.getDescription();
189
                providerManager.registerSymbol(description, symbol);
190
            }
191
        }
192
    }
193

    
194
    public boolean isEnabled() {
195
        return true;
196
    }
197

    
198
    public boolean isVisible() {
199
        return true;
200
    }
201

    
202
    @Override
203
    public boolean isVisible(String action) {
204
        IView view = getActiveView();
205
        FLyrVect activeLayer = getActiveLayer(view);
206

    
207
        if ("start-editing".equals(action)) {
208
            return ((view != null) && (activeLayer != null) && !activeLayer
209
                .isEditing());
210

    
211
        } else {
212
            return ((view != null) && (activeLayer != null) && activeLayer
213
                .isEditing());
214

    
215
        }
216
    }
217

    
218
    @Override
219
    public boolean isEnabled(String action) {
220

    
221
        IView vista = getActiveView();
222
        FLyrVect activeLayer = getActiveLayer(vista);
223

    
224
        if ("start-editing".equals(action)) {
225
            return (canBeEdited(activeLayer));
226

    
227
        } else if ("end-editing".equals(action)) {
228
            return activeLayer.isEditing();
229

    
230
        }
231

    
232
        return false;
233

    
234
    }
235

    
236
    @Override
237
    public boolean canQueryByAction() {
238
        return true;
239
    }
240

    
241
    private IView getActiveView() {
242
        ApplicationManager application = ApplicationLocator.getManager();
243
        IView view = (IView) application.getActiveComponent(ViewDocument.class);
244
        return view;
245
    }
246

    
247
    private boolean canBeEdited(FLyrVect layer) {
248
        if (layer != null && layer.isAvailable()) {
249

    
250
            boolean isWritable = layer.isWritable();
251
            boolean isNotTransformed =
252
                layer.getFeatureStore().getTransforms().isEmpty();
253

    
254
            return isWritable && isNotTransformed && !layer.isEditing();
255
        }
256

    
257
        return false;
258
    }
259

    
260
    private FLyrVect getActiveLayer(IView vista) {
261
        if (vista != null) {
262
            ViewDocument viewDocument = vista.getViewDocument();
263
            FLayer[] actives =
264
                viewDocument.getMapContext().getLayers().getActives();
265

    
266
            if ((actives.length == 1) && (actives[0] instanceof FLyrVect)) {
267
                return (FLyrVect) actives[0];
268
            }
269
        }
270
        return null;
271
    }
272

    
273
    public void update(Observable observable, Object notification) {
274

    
275
        if (notification instanceof Notification){
276
            ApplicationManager appManager =
277
                ApplicationLocator.getManager();
278
            Notification n = (Notification)notification;
279
            if (n.getType().equalsIgnoreCase(EditingContext.CHANGE_SELECTED_TOOL_NOTIFICATION)){
280
                String name = (String)n.getValue();
281
                logger.info("Changed selected tool to '{}'", name);
282
                PluginServices.getMainFrame().setSelectedTool(name);
283
                appManager.refreshMenusAndToolBars();
284

    
285
            } else if (n.getType().equalsIgnoreCase(EditingContext.REFRESH_TOOLS_NOTIFICATION)){
286
                appManager.refreshMenusAndToolBars();
287
            }
288
        }
289
    }
290

    
291
    private List<FLyrVect> getEditedLayers(){
292
        List<FLyrVect> editedLayers = new ArrayList<FLyrVect>();
293

    
294
        ApplicationManager application = ApplicationLocator.getManager();
295
        IWindow[] windows = application.getUIManager().getOrderedWindows();
296
        for (int i = 0; i < windows.length; i++) {
297
            IWindow window = windows[i];
298
            if (window instanceof SingletonWindow && window instanceof IDocumentWindow) {
299
                // Recorremos las ventanas.
300
                // Cogemos el model de aquellas que sea de tipo Document.
301
                // Si el model es de tipo View,
302
                // comprobamos que adem?s sean de tipo View.
303
                // Le pedimos al mapContext de la View las layers
304
                // y a?adimos a editedLayers aquellas layers vectoriales que est?n en edici?n.
305
                Document document;
306
                try {
307
                    document = (Document) ((SingletonWindow) window).getWindowModel();
308
                } catch (ClassCastException e) {
309
                    // Do nothing, skip this window
310
                    continue;
311
                }
312
                if (ViewDocument.class.isAssignableFrom(document.getClass())) {
313
                    ViewDocument view = (ViewDocument) document;
314
                    MapContext mapContext = view.getMapContext();
315
                    if (mapContext != null) {
316
                        FLayers layers = mapContext.getLayers();
317
                        for (int j = 0; j < layers.getLayersCount(); j++) {
318
                            FLayer lyr = layers.getLayer(j);
319
                            if (lyr instanceof FLyrVect) {
320
                                FLyrVect layerVect = (FLyrVect) lyr;
321
                                if (layerVect.isEditing()) {
322
                                    editedLayers.add(layerVect);
323
                                }
324
                            }
325
                        }
326
                    }
327
                }
328
            }
329
        }
330
        return editedLayers;
331
    }
332

    
333
    private List<IUnsavedData> getUnsavedData(List<FLyrVect> editedLayers){
334
        List<IUnsavedData> unsavedData = new ArrayList<IUnsavedData>();
335
        for (Iterator iterator = editedLayers.iterator(); iterator.hasNext();) {
336
            FLyrVect editedLayer = (FLyrVect) iterator.next();
337
            IUnsavedData unsavedDataLayer = new UnsavedLayer(this, editedLayer);
338
            unsavedData.add(unsavedDataLayer);
339
        }
340
        return unsavedData;
341

    
342
    }
343

    
344
    private static class UnsavedLayer extends UnsavedData {
345
        private FLyrVect layer;
346

    
347
        public UnsavedLayer(IExtension extension, FLyrVect layer) {
348
            super(extension);
349
            this.layer = layer;
350
        }
351

    
352
        @Override
353
        public String getDescription() {
354
            return layer.getName();
355
        }
356

    
357
        @Override
358
        public String getResourceName() {
359
            return layer.getFeatureStore().getFullName();
360
        }
361

    
362
        @Override
363
        public boolean saveData() {
364
            FeatureStore featureStore = layer.getFeatureStore();
365
            if(featureStore.isEditing()){
366
                try {
367
                    featureStore.finishEditing();
368
                    return true;
369
                } catch (DataException e) {
370
                    throw new RuntimeException(e);
371
                }
372
            }
373
            return true;
374
        }
375
    }
376

    
377
    @Override
378
    public IExtensionStatus getStatus() {
379
        List<FLyrVect> editedLayers = getEditedLayers();
380
        final List<IUnsavedData> unsavedData = getUnsavedData(editedLayers);
381

    
382
        return new IExtensionStatus() {
383

    
384
            public boolean hasUnsavedData() {
385
                if(unsavedData == null){
386
                    return false;
387
                }
388
                return !unsavedData.isEmpty();
389
            }
390

    
391
            public boolean hasRunningProcesses() {
392
                return false;
393
            }
394

    
395
            public IUnsavedData[] getUnsavedData() {
396
                if(unsavedData == null){
397
                    return null;
398
                }
399
                return unsavedData.toArray(new IUnsavedData[0]);
400
            }
401

    
402
            public IMonitorableTask[] getRunningProcesses() {
403
                return null;
404
            }
405
        };
406
    }
407
}