Statistics
| Revision:

gvsig-attributeeditor / org.gvsig.attributeeditor / trunk / org.gvsig.attributeeditor / org.gvsig.attributeeditor.mapcontrol / src / main / java / org / gvsig / fmap / mapcontrol / tools / Listeners / AttributeEditorPointListener.java @ 1198

History | View | Annotate | Download (15.6 KB)

1 8 fdiaz
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2014 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
24
package org.gvsig.fmap.mapcontrol.tools.Listeners;
25
26 685 jjdelcerro
import java.awt.event.ActionEvent;
27 741 jjdelcerro
import java.awt.event.ComponentAdapter;
28 25 fdiaz
import java.awt.event.ComponentEvent;
29 8 fdiaz
import java.awt.event.InputEvent;
30
import java.awt.event.MouseEvent;
31 685 jjdelcerro
import java.util.function.Predicate;
32 1198 jjdelcerro
import javax.swing.Action;
33 8 fdiaz
34
import javax.swing.JOptionPane;
35 26 fdiaz
import javax.swing.SwingUtilities;
36 970 jjdelcerro
import org.apache.commons.lang3.StringUtils;
37 8 fdiaz
38
import org.cresques.cts.IProjection;
39 747 jjdelcerro
import org.gvsig.expressionevaluator.GeometryExpressionBuilder;
40
import org.gvsig.expressionevaluator.GeometryExpressionUtils;
41 8 fdiaz
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
43
44 95 fdiaz
import org.gvsig.featureform.swing.CreateJFeatureFormException;
45 186 jjdelcerro
import org.gvsig.featureform.swing.JFeaturesForm;
46 1198 jjdelcerro
import org.gvsig.fmap.dal.DataStoreProviderFactory;
47 8 fdiaz
import org.gvsig.fmap.dal.exception.DataException;
48
import org.gvsig.fmap.dal.feature.FeatureQuery;
49 95 fdiaz
import org.gvsig.fmap.dal.feature.FeatureSelection;
50
import org.gvsig.fmap.dal.feature.FeatureSet;
51 8 fdiaz
import org.gvsig.fmap.dal.feature.FeatureStore;
52 1198 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
53
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
54 8 fdiaz
import org.gvsig.fmap.dal.feature.FeatureType;
55 43 jjdelcerro
import org.gvsig.fmap.dal.swing.DALSwingLocator;
56
import org.gvsig.fmap.dal.swing.DataSwingManager;
57 8 fdiaz
import org.gvsig.fmap.geom.Geometry;
58
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
59
import org.gvsig.fmap.geom.Geometry.TYPES;
60
import org.gvsig.fmap.geom.GeometryLocator;
61
import org.gvsig.fmap.geom.GeometryManager;
62
import org.gvsig.fmap.geom.exception.CreateGeometryException;
63
import org.gvsig.fmap.geom.primitive.Circle;
64
import org.gvsig.fmap.geom.primitive.Point;
65
import org.gvsig.fmap.mapcontext.ViewPort;
66
import org.gvsig.fmap.mapcontext.layers.FLayer;
67
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
68 400 jjdelcerro
import org.gvsig.fmap.mapcontext.layers.vectorial.SpatialEvaluatorsFactory;
69 8 fdiaz
import org.gvsig.fmap.mapcontrol.MapControl;
70
import org.gvsig.fmap.mapcontrol.tools.BehaviorException;
71 747 jjdelcerro
import org.gvsig.fmap.mapcontrol.tools.Events.EnvelopeEvent;
72 8 fdiaz
import org.gvsig.fmap.mapcontrol.tools.Events.PointEvent;
73
import org.gvsig.tools.ToolsLocator;
74 987 jjdelcerro
import org.gvsig.tools.dispose.DisposeUtils;
75 400 jjdelcerro
import org.gvsig.tools.evaluator.Evaluator;
76 8 fdiaz
import org.gvsig.tools.i18n.I18nManager;
77 1198 jjdelcerro
import org.gvsig.tools.observer.Observable;
78
import org.gvsig.tools.observer.Observer;
79 25 fdiaz
import org.gvsig.tools.service.ServiceException;
80 8 fdiaz
import org.gvsig.tools.swing.api.ToolsSwingLocator;
81
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
82
83
/**
84 685 jjdelcerro
 * @author gvSIG Team
85 8 fdiaz
 *
86
 */
87 685 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
88 747 jjdelcerro
public class AttributeEditorPointListener
89
        extends AbstractPointListener
90
        implements RectangleListener
91
    {
92 8 fdiaz
93 987 jjdelcerro
    private static Logger LOGGER = LoggerFactory.getLogger(AttributeEditorPointListener.class);
94 8 fdiaz
95
    public static final String ATTRIBUTE_EDITOR_TOOL_NAME = "attributeEditorTool";
96
    private static final String ATTRIBUTE_EDITOR_FORM_NAME = "attributeEditorForm";
97 400 jjdelcerro
98
    private final MapControl mapControl;
99 186 jjdelcerro
    private JFeaturesForm form;
100 685 jjdelcerro
    private Predicate<FeatureStore> refreshCallback;
101 1198 jjdelcerro
    private Observer refreshFormObserver;
102 8 fdiaz
103 186 jjdelcerro
    public AttributeEditorPointListener(MapControl mapControl, JFeaturesForm form) {
104 8 fdiaz
        super();
105
        this.mapControl = mapControl;
106
        this.form = form;
107 1198 jjdelcerro
        this.refreshFormObserver = (Observable o, Object o1) -> {
108
            doRefreshFormObserver(o, o1);
109
        };
110 8 fdiaz
    }
111
112
    public AttributeEditorPointListener(MapControl mapControl) {
113
        super();
114
        this.mapControl = mapControl;
115 1198 jjdelcerro
        this.refreshFormObserver = (Observable o, Object o1) -> {
116
            doRefreshFormObserver(o, o1);
117
        };
118
119 8 fdiaz
    }
120
121 95 fdiaz
    private FLyrVect getLayer() {
122 8 fdiaz
        FLayer[] layers = mapControl.getMapContext().getLayers().getActives();
123 95 fdiaz
        if (layers == null || layers.length != 1) {
124 8 fdiaz
            return null;
125
        }
126
        return (FLyrVect) layers[0];
127
128
    }
129
130 685 jjdelcerro
    @Override
131 8 fdiaz
    public void point(PointEvent e) throws BehaviorException {
132
        MouseEvent mouseEvent = e.getEvent();
133 95 fdiaz
        if (((mouseEvent.getModifiersEx() & (InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK
134
            | InputEvent.ALT_DOWN_MASK | InputEvent.ALT_GRAPH_DOWN_MASK | InputEvent.META_DOWN_MASK)) != 0)
135
            || !SwingUtilities.isLeftMouseButton(mouseEvent)) {
136 8 fdiaz
            return;
137
        }
138 747 jjdelcerro
        String layerName = "";
139 8 fdiaz
        I18nManager i18nManager = ToolsLocator.getI18nManager();
140
        try {
141
            FLyrVect layer = getLayer();
142
            if (layer == null) {
143
                String msg = i18nManager.getTranslation("There_is_no_one_and_only_one_active_layer");
144 95 fdiaz
                ToolsSwingLocator.getThreadSafeDialogsManager().messageDialog(msg,
145
                    i18nManager.getTranslation("attribute_editor"), JOptionPane.INFORMATION_MESSAGE);
146 8 fdiaz
                return;
147
            }
148 747 jjdelcerro
            layerName = layer.getName();
149
            ViewPort vp = this.mapControl.getViewPort();
150
            Point point = vp.convertToMapPoint(e.getPoint());
151
            double tolerance = vp.toMapDistance(layer.getDefaultTolerance());
152
            FeatureQuery query = queryByPoint(point, tolerance);
153
            showOrUpdateForm(layer, query);
154
        } catch (Exception ex) {
155 987 jjdelcerro
            LOGGER.warn("Can't show attribute information from point on the layer " + layerName, ex);
156 747 jjdelcerro
            String msg =
157
                i18nManager.getTranslation("Cant_show_attribute_information_for_layer_%1_on_point",
158
                    new String[] { layerName });
159
            ToolsSwingLocator.getThreadSafeDialogsManager().messageDialog(msg,
160
                i18nManager.getTranslation("attribute_editor"), JOptionPane.WARNING_MESSAGE);
161
        }
162
    }
163
164
    private void showOrUpdateForm(FLyrVect layer, FeatureQuery query) {
165 987 jjdelcerro
        if( layer == null || query==null ) {
166
            return;
167
        }
168 1146 jjdelcerro
        String layerName = layer.getName();
169
        if( layerName == null ) {
170
            layerName = "";
171
        }
172
        showOrUpdateForm(layerName, layer.getFeatureStore(), query);
173
    }
174
175
    public void showOrUpdateForm(String storeName, FeatureStore featureStore, FeatureQuery query) {
176
        if( featureStore == null || query==null ) {
177
            return;
178
        }
179 1048 jjdelcerro
        I18nManager i18n = ToolsLocator.getI18nManager();
180 747 jjdelcerro
        try {
181 1146 jjdelcerro
            if( StringUtils.isBlank(storeName) ) {
182
                storeName = featureStore.getLabel();
183
            }
184 987 jjdelcerro
            try {
185
                synchronized (featureStore) {
186
                    FeatureSet featSet = featureStore.getFeatureSet(query);
187
                    if( featSet.isEmpty() ) {
188
                        return;
189 8 fdiaz
                    }
190 987 jjdelcerro
                    FeatureSelection selection = (FeatureSelection) featureStore.getSelection();
191
                    selection.deselectAll();
192
                    selection.select(featSet);
193 8 fdiaz
                }
194 987 jjdelcerro
            } catch (DataException ex) {
195 1146 jjdelcerro
                LOGGER.warn("Can't query layer " + storeName+", query: "+query, ex);
196 987 jjdelcerro
                return;
197 8 fdiaz
            }
198 987 jjdelcerro
            if (this.form == null) {
199 1146 jjdelcerro
                this.form = getForm(featureStore, query);
200
                this.form.showForm(makeTitle("attribute_editor", storeName, featureStore.getName()), MODE.TOOL);
201 987 jjdelcerro
            } else if( this.form.getFeatureStore()!=featureStore ) {
202 1059 jjdelcerro
//                Dimension size = this.form.asJComponent().getPreferredSize();
203 987 jjdelcerro
                disposeForm();
204 1146 jjdelcerro
                this.form = getForm(featureStore, query);
205 1059 jjdelcerro
//                this.form.asJComponent().setPreferredSize(size);
206 1146 jjdelcerro
                this.form.showForm(makeTitle("attribute_editor", storeName, featureStore.getName()), MODE.TOOL);
207 8 fdiaz
            }
208 987 jjdelcerro
            this.form.setQuery(query);
209 8 fdiaz
        } catch (Exception ex) {
210 1146 jjdelcerro
            LOGGER.warn("Can't show attribute information from point on the layer " + storeName, ex);
211 95 fdiaz
            String msg =
212 1048 jjdelcerro
                i18n.getTranslation("Cant_show_attribute_information_for_layer_%1_on_point",
213 1146 jjdelcerro
                    new String[] { storeName });
214 95 fdiaz
            ToolsSwingLocator.getThreadSafeDialogsManager().messageDialog(msg,
215 1048 jjdelcerro
                i18n.getTranslation("attribute_editor"), JOptionPane.WARNING_MESSAGE);
216 987 jjdelcerro
            disposeForm();
217 8 fdiaz
        }
218
    }
219 685 jjdelcerro
220 987 jjdelcerro
    private void disposeForm() {
221 1198 jjdelcerro
        if( this.form != null ) {
222
            FeatureStore store = this.form.getFeatureStore();
223
            if( store!=null ) {
224
                store.deleteObserver(this.refreshFormObserver);
225
            }
226
        }
227 987 jjdelcerro
        DisposeUtils.disposeQuietly(this.form);
228
        this.form = null;
229
    }
230
231 685 jjdelcerro
    public void setRefreshCallback(Predicate<FeatureStore> refreshCallback) {
232
        this.refreshCallback = refreshCallback;
233
    }
234 8 fdiaz
235 1146 jjdelcerro
    private JFeaturesForm getForm(FeatureStore store, FeatureQuery query) throws CreateJFeatureFormException, ServiceException, DataException {
236 8 fdiaz
        if (this.form == null) {
237 95 fdiaz
            DataSwingManager swingManager = DALSwingLocator.getSwingManager();
238 987 jjdelcerro
            JFeaturesForm theForm = swingManager.createJFeaturesForm(store, query);
239
            this.form = theForm;
240 1091 fdiaz
            this.form.setTerminateEditingOnClose(false);
241 95 fdiaz
            this.form.asJComponent().setName(ATTRIBUTE_EDITOR_FORM_NAME);
242 741 jjdelcerro
            this.form.asJComponent().addComponentListener(new ComponentAdapter() {
243
                @Override
244
                public void componentHidden(ComponentEvent e) {
245 987 jjdelcerro
                    DisposeUtils.disposeQuietly(theForm);
246 741 jjdelcerro
                }
247
            });
248 685 jjdelcerro
            this.form.addActionListener((ActionEvent e) -> {
249 741 jjdelcerro
                switch (e.getActionCommand()) {
250 685 jjdelcerro
                    case "formAfterSave":
251
                    case "formAfterDelete":
252
                        if( this.refreshCallback!=null ) {
253
                            this.refreshCallback.test(store);
254
                        }
255
                        break;
256
                }
257
            });
258 1198 jjdelcerro
            store.addObserver(this.refreshFormObserver);
259 8 fdiaz
        }
260
        return this.form;
261
    }
262 1198 jjdelcerro
263
    private void doRefreshFormObserver(Observable o, Object o1) {
264
        if( this.form == null ||
265
                !(o instanceof FeatureStore && o1 instanceof FeatureStoreNotification ) ) {
266
            return;
267
        }
268
        try {
269
            FeatureStoreNotification n = (FeatureStoreNotification) o1;
270
            if( n.getType().equalsIgnoreCase(FeatureStoreNotification.AFTER_REFRESH) ) {
271
                Action refreshAction = this.form.getFormset().getAction(JFeaturesForm.REFRESHFORM_ACTION);
272
                if( refreshAction!=null ) {
273
                    refreshAction.actionPerformed(null);
274
                }
275
            }
276
        } catch(Exception ex) {
277
            LOGGER.warn("Can't refresh attribute editor",ex);
278
        }
279
    }
280 8 fdiaz
281 95 fdiaz
    private FeatureQuery queryByPoint(Point point, double tol) throws CreateGeometryException, DataException {
282 8 fdiaz
        GeometryManager manager = GeometryLocator.getGeometryManager();
283
        Circle circle = (Circle) manager.create(TYPES.CIRCLE, SUBTYPES.GEOM2D);
284
        circle.setPoints(point, tol);
285 987 jjdelcerro
286
        FLyrVect currentLayer = this.getLayer();
287
        if( currentLayer==null ) {
288
            return null;
289
        }
290
        FeatureStore featureStore = currentLayer.getFeatureStore();
291 8 fdiaz
        FeatureQuery featureQuery = featureStore.createFeatureQuery();
292
        FeatureType featureType = featureStore.getDefaultFeatureType();
293
        featureQuery.setFeatureType(featureType);
294
295 987 jjdelcerro
        Geometry query_geo = currentLayer.transformToSourceCRS(circle, true);
296 8 fdiaz
297 987 jjdelcerro
        IProjection query_proj = currentLayer.getMapContext().getProjection();
298
        if (currentLayer.getCoordTrans() != null) {
299
            query_proj = currentLayer.getCoordTrans().getPOrig();
300 8 fdiaz
        }
301
302 400 jjdelcerro
        Evaluator iee = SpatialEvaluatorsFactory.getInstance().intersects(
303
                query_geo,
304
                query_proj,
305
                featureStore
306
        );
307 8 fdiaz
        featureQuery.setFilter(iee);
308 400 jjdelcerro
        featureQuery.retrievesAllAttributes();
309 8 fdiaz
        return featureQuery;
310
    }
311 747 jjdelcerro
312
    @Override
313
    public void rectangle(EnvelopeEvent e) throws BehaviorException {
314
        MouseEvent mouseEvent = e.getEvent();
315
        if (((mouseEvent.getModifiersEx() & (InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK
316
            | InputEvent.ALT_DOWN_MASK | InputEvent.ALT_GRAPH_DOWN_MASK | InputEvent.META_DOWN_MASK)) != 0)
317
            || !SwingUtilities.isLeftMouseButton(mouseEvent)) {
318
            return;
319
        }
320
        String layerName = "";
321
        I18nManager i18nManager = ToolsLocator.getI18nManager();
322
        try {
323
            FLyrVect layer = getLayer();
324
            if (layer == null) {
325
                String msg = i18nManager.getTranslation("There_is_no_one_and_only_one_active_layer");
326
                ToolsSwingLocator.getThreadSafeDialogsManager().messageDialog(msg,
327
                    i18nManager.getTranslation("attribute_editor"), JOptionPane.INFORMATION_MESSAGE);
328
                return;
329
            }
330
            layerName = layer.getName();
331
            FeatureQuery query;
332
            Geometry geom = e.getWorldCoordRect().getGeometry();
333
            if( geom instanceof Point ) {
334
                ViewPort vp = this.mapControl.getViewPort();
335
                double tolerance = vp.toMapDistance(layer.getDefaultTolerance());
336
                query = queryByPoint((Point) geom, tolerance);
337
            } else {
338
                FeatureStore store = layer.getFeatureStore();
339
                FeatureType featureType = store.getDefaultFeatureTypeQuietly();
340
                GeometryExpressionBuilder builder = GeometryExpressionUtils.createExpressionBuilder();
341
                String filter = builder.ST_Intersects(
342
                        builder.column(featureType.getDefaultGeometryAttributeName()),
343
                        builder.geometry(e.getWorldCoordRect().getGeometry())
344
                ).toString();
345
                query = store.createFeatureQuery(filter);
346
            }
347
            showOrUpdateForm(layer, query);
348
        } catch (Exception ex) {
349 987 jjdelcerro
            LOGGER.warn("Can't show attribute information from point on the layer " + layerName, ex);
350 747 jjdelcerro
            String msg =
351
                i18nManager.getTranslation("Cant_show_attribute_information_for_layer_%1_on_point",
352
                    new String[] { layerName });
353
            ToolsSwingLocator.getThreadSafeDialogsManager().messageDialog(msg,
354
                i18nManager.getTranslation("attribute_editor"), JOptionPane.WARNING_MESSAGE);
355
        }
356
    }
357 1065 jjdelcerro
358
    public String makeTitle(String base, String docname, String docname2) {
359
        I18nManager i18n = ToolsLocator.getI18nManager();
360
//        if( StringUtils.startsWith(base, "_") ) {
361
            base = i18n.getTranslation(base);
362
//        }
363
        String title = base + ": " + docname;
364
        if( StringUtils.isNotBlank(docname2) && !StringUtils.equals(docname, docname2)) {
365
            title = title + " ("+docname2+")";
366
        }
367
        return title;
368
    }
369 8 fdiaz
}