Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / extension / clipboard / PasteFeaturesFromClipboardExtension.java @ 43510

History | View | Annotate | Download (10.8 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 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 3
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.app.extension.clipboard;
25

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

    
30
import javax.swing.JOptionPane;
31

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

    
35
import org.gvsig.andami.IconThemeHelper;
36
import org.gvsig.andami.PluginServices;
37
import org.gvsig.andami.plugins.Extension;
38
import org.gvsig.andami.ui.mdiManager.IWindow;
39
import org.gvsig.app.ApplicationLocator;
40
import org.gvsig.app.extension.clipboard.util.FeatureTextUtils;
41
import org.gvsig.app.project.documents.view.ViewDocument;
42
import org.gvsig.app.project.documents.view.gui.DefaultViewPanel;
43
import org.gvsig.app.project.documents.view.gui.IView;
44
import org.gvsig.fmap.dal.exception.DataException;
45
import org.gvsig.fmap.dal.feature.EditableFeature;
46
import org.gvsig.fmap.dal.feature.Feature;
47
import org.gvsig.fmap.dal.feature.FeatureStore;
48
import org.gvsig.fmap.geom.Geometry;
49
import org.gvsig.fmap.geom.GeometryException;
50
import org.gvsig.fmap.geom.primitive.Envelope;
51
import org.gvsig.fmap.geom.type.GeometryType;
52
import org.gvsig.fmap.mapcontext.MapContext;
53
import org.gvsig.fmap.mapcontext.layers.FLayer;
54
import org.gvsig.fmap.mapcontext.layers.FLayers;
55
import org.gvsig.fmap.mapcontext.layers.LayersIterator;
56
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
57
import org.gvsig.i18n.Messages;
58

    
59

    
60
public class PasteFeaturesFromClipboardExtension extends Extension {
61

    
62
    private static Logger logger = LoggerFactory.getLogger(
63
                    PasteFeaturesFromClipboardExtension.class);
64

    
65
        public void initialize() {
66

    
67
                IconThemeHelper.registerIcon("action", "layer-modify-clipboard-paste", this);
68
        }
69

    
70
        public void execute(String actionCommand) {
71

    
72
                if (actionCommand.compareToIgnoreCase("layer-modify-clipboard-paste") != 0) {
73
                        return;
74
                }
75

    
76
                IWindow actw = actWin();
77

    
78
                if (actw instanceof IView) {
79

    
80
                        IView vw = (IView) actw;
81
                        FLayer[] act_lyr = vw.getMapControl().getMapContext().getLayers().getActives();
82
                        if (act_lyr == null || act_lyr.length != 1
83
                                        || !(act_lyr[0] instanceof FLyrVect)) {
84

    
85
                        } else {
86
                                FLyrVect vect = (FLyrVect) act_lyr[0];
87
                                if (vect.isEditing()) {
88

    
89
                                        // Discard if no text data or empty:
90
                                        if (!FeatureTextUtils.textInClipboard()) {
91
                                                JOptionPane.showMessageDialog(
92
                                                                ApplicationLocator.getManager().getRootComponent(),
93
                                                                Messages.getText("_Clipboard_has_no_valid_info_or_is_empty"),
94
                                                                Messages.getText("_Pasting_features_from_clipboard"),
95
                                                                JOptionPane.INFORMATION_MESSAGE);
96
                                                return;
97
                                        }
98
                                        String clipb = PluginServices.getFromClipboard();
99
                                        if (clipb == null || clipb.length() == 0) {
100
                                                JOptionPane.showMessageDialog(
101
                                                                ApplicationLocator.getManager().getRootComponent(),
102
                                                                Messages.getText("_Clipboard_has_no_valid_info_or_is_empty"),
103
                                                                Messages.getText("_Pasting_features_from_clipboard"),
104
                                                                JOptionPane.INFORMATION_MESSAGE);
105
                                                return;
106
                                        }
107

    
108
                                        // ============================================
109
                                        // ============================================
110

    
111
                                        FeatureStore fsto = vect.getFeatureStore();
112
                                        List<EditableFeature> try_feats = FeatureTextUtils.fromString(clipb, fsto);
113
                                        /*
114
                                         * This method will check geometry type
115
                                         */
116
                                        List<EditableFeature> added_feats = addFeatures(fsto, try_feats);
117

    
118
                                        int n_orig = try_feats.size();
119
                                        int n_added = added_feats.size();
120
                                        int n_disc = n_orig - n_added;
121

    
122
                                        String msg = "";
123

    
124
                                        if (n_orig == 0) {
125
                                                msg = Messages.getText("_No_features_found_in_clipboard");
126
                                        } else {
127
                                                msg = Messages.getText("_Number_of_features_pasted_from_clipboard");
128
                                                msg = msg + ":   " + n_added + "    \n";
129
                                                msg = msg + Messages.getText("_Number_of_features_from_clipboard_discarded_due_to_bad_format");
130
                                                msg = msg + ":   " + n_disc + "    ";
131
                                        }
132

    
133

    
134
                                        if (n_added > 0) {
135

    
136
                                                msg = msg + "\n\n" +
137
                                                                Messages.getText("_Zoom_to_added_features_question");
138
                                                int user_opt = JOptionPane.showConfirmDialog(
139
                                                                ApplicationLocator.getManager().getRootComponent(),
140
                                                                msg,
141
                                                                Messages.getText("_Pasting_features_from_clipboard"),
142
                                                                JOptionPane.YES_NO_OPTION);
143
                                                if (user_opt == JOptionPane.YES_OPTION) {
144
                                                        try {
145
                                                                zoomToExtent(added_feats,
146
                                                                                vw.getMapControl().getMapContext());
147
                                                        } catch (Exception ex) {
148
                                                                JOptionPane.showMessageDialog(
149
                                                                                ApplicationLocator.getManager().getRootComponent(),
150
                                                                                Messages.getText("_Unable_to_zoom_to_features")
151
                                                                                + ": " + ex.getMessage(),
152
                                                                                Messages.getText("_Pasting_features_from_clipboard"),
153
                                                                                JOptionPane.ERROR_MESSAGE);
154
                                                        }
155

    
156
                                                } else {
157
                                                        // Repaint view
158
                                                        vw.getMapControl().getMapContext().invalidate();
159
                                                }
160

    
161
                                        } else {
162
                                                JOptionPane.showMessageDialog(
163
                                                                ApplicationLocator.getManager().getRootComponent(),
164
                                                                msg,
165
                                                                Messages.getText("_Pasting_features_from_clipboard"),
166
                                                                JOptionPane.INFORMATION_MESSAGE);
167
                                        }
168
                                }
169
                        }
170

    
171
                }
172

    
173

    
174
        }
175

    
176
        private void zoomToExtent(
177
                        List<EditableFeature> added_feats,
178
                        MapContext mco) throws Exception {
179

    
180
                Envelope env = null;
181
                Envelope itemenv = null;
182
                Iterator<EditableFeature> iter = added_feats.iterator();
183
                Feature feat = null;
184
                while (iter.hasNext()) {
185
                        feat = (Feature) iter.next();
186
                        itemenv = feat.getDefaultGeometry().getEnvelope();
187
                        if (itemenv != null) {
188
                                if (env == null) {
189
                                        itemenv = (Envelope) itemenv.clone();
190
                                        env = itemenv;
191
                                } else {
192
                                        env.add(itemenv);
193
                                }
194
                        }
195
                }
196
                if (env == null) {
197
                        throw new GeometryException(new Exception("All envelopes are null."));
198
                }
199
                mco.getViewPort().setEnvelope(env);
200
        }
201

    
202
        /**
203
         * Add features if geometry is of right type.
204
         * Returns number of features added.
205
         * If returned number is negative, it means there were errors.
206
         * Example: -5 means 5 were added and there were errors with other geometries.
207
         *
208
         * @param fsto
209
         * @param add_feats
210
         * @throws DataException
211
         */
212
        private List<EditableFeature> addFeatures(
213
                        FeatureStore fsto,
214
                        List<EditableFeature> add_feats) {
215

    
216
                List<EditableFeature> really_added = new ArrayList<EditableFeature>();
217

    
218
                Iterator<EditableFeature> iter = add_feats.iterator();
219
                EditableFeature item = null;
220
                Geometry geom = null;
221
                GeometryType good_gt = null;
222
                int good_dimensions = 0;
223

    
224
                try {
225
                        good_gt = fsto.getDefaultFeatureType().getDefaultGeometryAttribute().getGeomType();
226
                        good_dimensions = FeatureTextUtils.geoman().create(good_gt).getDimension();
227
                } catch (Exception e) {
228
                        logger.error("While getting geom type.", e);
229
                        return really_added;
230
                }
231

    
232
                while (iter.hasNext()) {
233
                        item = iter.next();
234
                        geom = item.getDefaultGeometry();
235
                        /*
236
                         * Same number of dimensions and compatible types
237
                         */
238
                        if ((geom.getDimension() == good_dimensions)
239
                                        &&
240
                                        (geom.getGeometryType().isTypeOf(good_gt)
241
                                        || simpleTypeOf(geom.getGeometryType(), good_gt))
242
                                        ) {
243
                                try {
244
                                        fsto.insert(item);
245
                                        really_added.add(item);
246
                                } catch (DataException e) {
247
                                        /*
248
                                         * This error will cause that "really_added"
249
                                         * will be shorter than "add_feats" and the user
250
                                         * must be notified of that when the process ends.
251
                                         */
252
                                        logger.info("Error while inserting feature from clipboard: " + e.getMessage());
253
                                }
254
                        }
255
                }
256

    
257
                return really_added;
258
        }
259

    
260
        private boolean simpleTypeOf(GeometryType simplet, GeometryType multit) {
261

    
262
        return (multit.isTypeOf(Geometry.TYPES.MULTISURFACE) && 
263
                simplet.isTypeOf(Geometry.TYPES.SURFACE))
264
               ||
265
               (multit.isTypeOf(Geometry.TYPES.MULTICURVE) && 
266
                simplet.isTypeOf(Geometry.TYPES.CURVE))
267
               ||
268
               (multit.isTypeOf(Geometry.TYPES.MULTIPOINT) && 
269
                simplet.isTypeOf(Geometry.TYPES.POINT));
270
        }
271

    
272
    @Override
273
        public boolean isEnabled() {
274

    
275
                /*
276
                 * I think it's better to make it enabled always when the active layer
277
                 * is in editing mode, so it's not necessary to refresh the state of the button
278
                 * (with a zoom or changing window, etc). The content of the clipboard can change
279
                 * and gvSIG does not know. Of course, if the user clicks the button,
280
                 * a dialog will tell if the clipboard is empty or has invalid data.
281
                 */
282
                return isVisible();
283

    
284
                /*
285
                 * Discarded by now:
286
                 *
287
                 * It's enabled if the active layer is a vector layer
288
                 * in editing mode and the clipboard seems to have valid features
289
                 *
290
                IWindow actw = actWin();
291
                if (actw instanceof IView) {
292

293
                        IView vw = (IView) actw;
294
                        FLayer[] act_lyr = vw.getMapControl().getMapContext().getLayers().getActives();
295
                        if (act_lyr == null || act_lyr.length != 1
296
                                        || !(act_lyr[0] instanceof FLyrVect)) {
297
                                return false;
298

299
                        } else {
300
                                FLyrVect vect = (FLyrVect) act_lyr[0];
301
                                if (vect.isEditing()) {
302
                                        return FeatureTextUtils.clipboardSeemsToHaveValidFeatures();
303
                                } else {
304
                                        return false;
305
                                }
306
                        }
307

308
                } else {
309
                        return false;
310
                }
311
                */
312
        }
313

    
314

    
315
        public boolean isVisible() {
316

    
317
        org.gvsig.andami.ui.mdiManager.IWindow f = PluginServices.getMDIManager()
318
        .getActiveWindow();
319
        if (f == null)
320
            return false;
321

    
322
        if (f instanceof DefaultViewPanel) {
323
            DefaultViewPanel vista = (DefaultViewPanel) f;
324
            ViewDocument model = vista.getViewDocument();
325
            MapContext mapa = model.getMapContext();
326

    
327
            FLayers capas = mapa.getLayers();
328

    
329
            int numActiveVectorial = 0;
330
            int numActiveVectorialEditable = 0;
331

    
332
            LayersIterator iter = new LayersIterator(capas);
333

    
334
            FLayer capa;
335
            while (iter.hasNext()) {
336
                capa = iter.nextLayer();
337
                if (capa instanceof FLyrVect &&
338
                        capa.isActive() && capa.isAvailable()) {
339
                    numActiveVectorial++;
340
                    if (capa.isEditing())
341
                        numActiveVectorialEditable++;
342
                }
343

    
344
            }
345

    
346
            if (numActiveVectorialEditable == 1 && numActiveVectorial == 1)
347
                        return true;
348
                }
349
                return false;
350
        }
351

    
352
        /**
353
         * Gets active window
354
         * @return
355
         */
356
        private IWindow actWin() {
357
                return ApplicationLocator.getManager().getActiveWindow();
358
        }
359

    
360
}