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 / project / documents / view / dynformfield / linkforeingkeywgs / JDynFormFieldForeingKeyWGS.java @ 47213

History | View | Annotate | Download (30.2 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 modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.app.project.documents.view.dynformfield.linkforeingkeywgs;
24

    
25
import java.awt.Dimension;
26
import java.awt.GridBagConstraints;
27
import java.awt.GridBagLayout;
28
import java.awt.Image;
29
import java.awt.event.ActionEvent;
30
import java.awt.event.ComponentAdapter;
31
import java.awt.event.ComponentEvent;
32
import java.awt.event.FocusEvent;
33
import java.awt.event.FocusListener;
34
import java.awt.event.InputEvent;
35
import java.awt.event.MouseEvent;
36
import java.util.Objects;
37
import javax.swing.JButton;
38
import javax.swing.JComponent;
39
import javax.swing.JOptionPane;
40
import javax.swing.JPanel;
41
import javax.swing.JTextField;
42
import javax.swing.JToggleButton;
43
import javax.swing.SwingUtilities;
44
import javax.swing.event.AncestorEvent;
45
import javax.swing.event.AncestorListener;
46
import javax.swing.text.JTextComponent;
47
import org.apache.commons.lang.StringUtils;
48
import org.apache.commons.lang3.tuple.ImmutablePair;
49
import org.apache.commons.lang3.tuple.Pair;
50
import org.cresques.cts.IProjection;
51
import org.gvsig.app.ApplicationLocator;
52
import org.gvsig.app.ApplicationManager;
53
import org.gvsig.app.project.documents.view.ViewDocument;
54
import org.gvsig.app.project.documents.view.gui.IView;
55
import org.gvsig.expressionevaluator.GeometryExpressionBuilder;
56
import org.gvsig.expressionevaluator.GeometryExpressionUtils;
57
import org.gvsig.featureform.swing.JFeaturesForm;
58
import org.gvsig.featureform.swing.FeaturesFormContext;
59
import org.gvsig.fmap.dal.DataStoreParameters;
60
import org.gvsig.fmap.dal.exception.DataException;
61
import org.gvsig.fmap.dal.feature.Feature;
62
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
63
import org.gvsig.fmap.dal.feature.FeatureQuery;
64
import org.gvsig.fmap.dal.feature.FeatureStore;
65
import org.gvsig.fmap.dal.feature.FeatureType;
66
import org.gvsig.fmap.dal.feature.ForeingKey;
67
import org.gvsig.fmap.dal.feature.ForeingKey.ContextForeingKey;
68
import org.gvsig.fmap.dal.swing.DALSwingLocator;
69
import org.gvsig.fmap.dal.swing.DataSwingManager;
70
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
71
import org.gvsig.fmap.geom.Geometry;
72
import org.gvsig.fmap.geom.GeometryLocator;
73
import org.gvsig.fmap.geom.GeometryManager;
74
import org.gvsig.fmap.geom.exception.CreateGeometryException;
75
import org.gvsig.fmap.geom.primitive.Circle;
76
import org.gvsig.fmap.geom.primitive.Point;
77
import org.gvsig.fmap.mapcontext.MapContext;
78
import org.gvsig.fmap.mapcontext.ViewPort;
79
import org.gvsig.fmap.mapcontext.layers.FLayer;
80
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
81
import org.gvsig.fmap.mapcontext.layers.vectorial.SpatialEvaluatorsFactory;
82
import org.gvsig.fmap.mapcontrol.MapControl;
83
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
84
import org.gvsig.fmap.mapcontrol.tools.Behavior.PointBehavior;
85
import org.gvsig.fmap.mapcontrol.tools.Behavior.RectangleBehavior;
86
import org.gvsig.fmap.mapcontrol.tools.BehaviorException;
87
import org.gvsig.fmap.mapcontrol.tools.CompoundBehavior;
88
import org.gvsig.fmap.mapcontrol.tools.Events.EnvelopeEvent;
89
import org.gvsig.fmap.mapcontrol.tools.Events.PointEvent;
90
import org.gvsig.fmap.mapcontrol.tools.Listeners.AbstractPointListener;
91
import org.gvsig.fmap.mapcontrol.tools.Listeners.RectangleListener;
92
import org.gvsig.tools.dispose.DisposeUtils;
93
import org.gvsig.tools.dynform.DynFormFieldDefinition;
94
import org.gvsig.tools.dynform.JDynForm;
95

    
96
import org.gvsig.tools.dynform.JDynFormField;
97
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
98
import org.gvsig.tools.dynform.spi.DynFormSPIManager.ComponentsFactory;
99
import org.gvsig.tools.dynform.spi.dynformfield.AbstractJDynFormField;
100
import org.gvsig.tools.dynform.spi.dynformfield.JDynFormFieldFactory;
101
import org.gvsig.tools.dynobject.DynObject;
102
import org.gvsig.tools.evaluator.Evaluator;
103
import org.gvsig.tools.swing.api.ToolsSwingLocator;
104
import org.gvsig.tools.swing.api.ToolsSwingUtils;
105
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
106
import org.gvsig.tools.swing.api.windowmanager.Dialog;
107
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
108
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
109

    
110
@SuppressWarnings("UseSpecificCatch")
111
public class JDynFormFieldForeingKeyWGS extends AbstractJDynFormField implements JDynFormField {
112

    
113
    private Object assignedValue = null;
114
    private Object value = null;
115
    private Feature relatedFeature = null;
116
    private JTextComponent txtDescription = null;
117
    private JToggleButton btnLinkGraphically = null;
118
    private JButton btnLink = null;
119
    private JButton btnUnlink = null;
120
    private JButton btnEdit = null;
121
    private MapControl mapControl;
122
    private String previosTool;
123

    
124
    private static class ForeignkeyCaptureListener extends AbstractPointListener implements RectangleListener {
125

    
126
        private FLyrVect layer;
127
        protected MapControl mapControl;
128
        private JDynFormFieldForeingKeyWGS field;
129

    
130
        private ForeignkeyCaptureListener(MapControl mapControl) {
131
            this.mapControl = mapControl;
132
        }
133

    
134
        public void putValueInFormField(Feature f) throws BehaviorException {
135
            if (f == null) {
136
                return;
137
            }
138
            final ForeingKey foreingKey = field.getForeingKey();
139
            if (foreingKey == null) {
140
                return;
141
            }
142
            final ContextForeingKey context = foreingKey.createContext();
143
            try {
144
                field.setEditedValue(foreingKey.getCode(context, f));
145
                field.relatedFeature = f;
146
            } finally {
147
                DisposeUtils.disposeQuietly(context);
148
            }
149
            field.fireFieldChangedEvent();
150
        }
151

    
152
        public void setLayer(FLyrVect layer) {
153
            this.layer = layer;
154
        }
155

    
156
        public FLyrVect getLayer() {
157
            return this.layer;
158
        }
159
        
160
        public void setField(JDynFormFieldForeingKeyWGS field) {
161
            this.field = field;
162
        }
163

    
164
        @Override
165
        public void point(PointEvent e) throws BehaviorException {
166
            MouseEvent mouseEvent = e.getEvent();
167
            if (((mouseEvent.getModifiersEx() & (InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK
168
                    | InputEvent.ALT_DOWN_MASK | InputEvent.ALT_GRAPH_DOWN_MASK | InputEvent.META_DOWN_MASK)) != 0)
169
                    || !SwingUtilities.isLeftMouseButton(mouseEvent)) {
170
                return;
171
            }
172
            String layerName = "";
173
            try {
174
                @SuppressWarnings("LocalVariableHidesMemberVariable")
175
                FLyrVect layer = getLayer();
176
                layerName = layer.getName();
177
                ViewPort vp = this.mapControl.getViewPort();
178
                Point point = vp.convertToMapPoint(e.getPoint());
179
                double tolerance = vp.toMapDistance(layer.getDefaultTolerance());
180
                FeatureQuery query = queryByPoint(point, tolerance);
181
                search(layer, query);
182
            } catch (Exception ex) {
183
                LOGGER.warn("Can't get information from point on the layer " + layerName, ex);
184
            }
185
        }
186

    
187
        private FeatureQuery queryByPoint(Point point, double tol) throws CreateGeometryException, DataException {
188
            GeometryManager manager = GeometryLocator.getGeometryManager();
189
            Circle circle = (Circle) manager.create(Geometry.TYPES.CIRCLE, Geometry.SUBTYPES.GEOM2D);
190
            circle.setPoints(point, tol);
191

    
192
            FLyrVect currentLayer = getLayer();
193
            if (currentLayer == null) {
194
                return null;
195
            }
196
            FeatureStore featureStore = currentLayer.getFeatureStore();
197
            FeatureQuery featureQuery = featureStore.createFeatureQuery();
198
            FeatureType featureType = featureStore.getDefaultFeatureType();
199
            featureQuery.setFeatureType(featureType);
200

    
201
            Geometry query_geo = currentLayer.transformToSourceCRS(circle, true);
202

    
203
            IProjection query_proj = currentLayer.getMapContext().getProjection();
204
            if (currentLayer.getCoordTrans() != null) {
205
                query_proj = currentLayer.getCoordTrans().getPOrig();
206
            }
207

    
208
            Evaluator iee = SpatialEvaluatorsFactory.getInstance().intersects(
209
                    query_geo.getEnvelope(),
210
                    query_proj,
211
                    featureStore
212
            );
213
            featureQuery.setFilter(iee);
214
            featureQuery.retrievesAllAttributes();
215
            return featureQuery;
216
        }
217

    
218
        @Override
219
        public void rectangle(EnvelopeEvent e) throws BehaviorException {
220
            MouseEvent mouseEvent = e.getEvent();
221
            if (((mouseEvent.getModifiersEx() & (InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK
222
                    | InputEvent.ALT_DOWN_MASK | InputEvent.ALT_GRAPH_DOWN_MASK | InputEvent.META_DOWN_MASK)) != 0)
223
                    || !SwingUtilities.isLeftMouseButton(mouseEvent)) {
224
                return;
225
            }
226
            String layerName = "";
227
            try {
228
                @SuppressWarnings("LocalVariableHidesMemberVariable")
229
                FLyrVect layer = getLayer();
230
                layerName = layer.getName();
231
                FeatureQuery query;
232
                Geometry geom = e.getWorldCoordRect().getGeometry();
233
                if (geom instanceof Point) {
234
                    ViewPort vp = this.mapControl.getViewPort();
235
                    double tolerance = vp.toMapDistance(layer.getDefaultTolerance());
236
                    query = queryByPoint((Point) geom, tolerance);
237
                } else {
238
                    FeatureStore store = layer.getFeatureStore();
239
                    FeatureType featureType = store.getDefaultFeatureTypeQuietly();
240
                    GeometryExpressionBuilder builder = GeometryExpressionUtils.createExpressionBuilder();
241
                    String filter = builder.ST_Intersects(
242
                            builder.column(featureType.getDefaultGeometryAttributeName()),
243
                            builder.geometry(e.getWorldCoordRect().getGeometry())
244
                    ).toString();
245
                    query = store.createFeatureQuery(filter);
246
                }
247
                search(layer, query);
248
            } catch (Exception ex) {
249
                LOGGER.warn("Can't get information from point on the layer " + layerName, ex);
250
            }
251
        }
252

    
253
        private void search(FLyrVect layer, FeatureQuery query) {
254
            if (layer == null || query == null) {
255
                return;
256
            }
257
            String layerName = "";
258
            try {
259
                layerName = layer.getName();
260
                FeatureStore featureStore = layer.getFeatureStore();
261
                this.putValueInFormField(featureStore.findFirst(query));
262
            } catch (Exception ex) {
263
                LOGGER.warn("Can't get information from point on the layer " + layerName, ex);
264
            }
265
        }
266
    }
267

    
268
    private static class ForeignkeyCaptureBehavior extends CompoundBehavior {
269

    
270
        ForeignkeyCaptureListener foreignkeyCaptureListener;
271

    
272
        @SuppressWarnings("OverridableMethodCallInConstructor")
273
        public ForeignkeyCaptureBehavior(MapControl mapControl) {
274
            super(new Behavior[0]);
275
            this.foreignkeyCaptureListener = new ForeignkeyCaptureListener(mapControl);
276

    
277
            this.addMapBehavior(new PointBehavior(foreignkeyCaptureListener), true);
278
            this.addMapBehavior(new RectangleBehavior(foreignkeyCaptureListener), true);
279
        }
280

    
281
        @Override
282
        public Image getImageCursor() {
283
            return this.foreignkeyCaptureListener.getImageCursor();
284
        }
285

    
286
        @Override
287
        public ForeignkeyCaptureListener getListener() {
288
            return this.foreignkeyCaptureListener;
289
        }
290

    
291
        public void setLayer(FLyrVect layer) {
292
            this.foreignkeyCaptureListener.setLayer(layer);
293
        }
294

    
295
        public void setField(JDynFormFieldForeingKeyWGS field) {
296
            this.foreignkeyCaptureListener.setField(field);
297
        }
298

    
299
    }
300

    
301
    public JDynFormFieldForeingKeyWGS(
302
            DynFormSPIManager serviceManager,
303
            DynFormSPIManager.ComponentsFactory componentsFactory,
304
            JDynFormFieldFactory factory,
305
            DynFormFieldDefinition definition,
306
            Object value
307
    ) {
308
        super(serviceManager, componentsFactory, factory, definition, value);
309
        if (value != null) {
310
            this.assignedValue = (DynObject) value;
311
        }
312
    }
313

    
314
    @Override
315
    public Object getAssignedValue() {
316
        return this.assignedValue;
317
    }
318

    
319
    public void initComponentIfNeed() {
320
        if (this.contents == null) {
321
            this.initComponent();
322
        }
323
    }
324

    
325
    @Override
326
    public void initComponent() {
327
        ComponentsFactory components = this.getComponentsFactory();
328
        FocusListener focusListener = new FocusListener() {
329
            @Override
330
            public void focusGained(FocusEvent e) {
331
                fireFieldEnterEvent();
332
            }
333

    
334
            @Override
335
            public void focusLost(FocusEvent e) {
336
                fireFieldExitEvent();
337
            }
338
        };
339
        this.txtDescription = components.getJTextField(this.getDefinition(), null);
340
        if (this.txtDescription == null) {
341
            this.txtDescription = new JTextField();
342
        }
343
        this.btnLinkGraphically = components.getJToggleButton(this.getDefinition(), "LinkGraphical");
344
        if (this.btnLinkGraphically == null) {
345
            this.btnLinkGraphically = new JToggleButton();
346
        }
347
        this.btnLink = components.getJButton(this.getDefinition(), "Link");
348
        if (this.btnLink == null) {
349
            this.btnLink = new JButton();
350
        }
351
        this.btnUnlink = components.getJButton(this.getDefinition(), "Unlink");
352
        if (this.btnUnlink == null) {
353
            this.btnUnlink = new JButton();
354
        }
355
        this.btnEdit = components.getJButton(this.getDefinition(), "Edit");
356
        if (this.btnEdit == null) {
357
            this.btnEdit = new JButton();
358
        }
359
        ToolsSwingUtils.configurePickersButton(
360
                btnLinkGraphically, 
361
                "_Select_related_item_graphically", 
362
                "selection-simple-select", 
363
                (ActionEvent ae) -> {doLinkGraphically(this.btnLinkGraphically.isSelected());},
364
                focusListener
365
        );
366
        ToolsSwingUtils.configurePickersButton(
367
                btnLink, 
368
                "_Select_related_item", 
369
                "picker-foreingkey-link", 
370
                (ActionEvent ae) -> {doLink();},
371
                focusListener
372
        );
373
        ToolsSwingUtils.configurePickersButton(
374
                btnUnlink, 
375
                "_Remove_relation", 
376
                "picker-foreingkey-unlink", 
377
                (ActionEvent ae) -> {doUnlink();},
378
                focusListener
379
        );
380
        ToolsSwingUtils.configurePickersButton(
381
                btnEdit, 
382
                "_See_related_item", 
383
                "picker-foreingkey-showform", 
384
                (ActionEvent ae) -> {doEdit();},
385
                focusListener
386
        );        
387
        
388
//        this.initButton(this.btnLinkGraphically, "Select item to link graphically", "selection-simple-select");
389
//        this.initButton(this.btnLink, "Select item to link", "formfield-foreignkey-link");
390
//        this.initButton(this.btnUnlink, "Remove link", "formfield-foreignkey-unlink");
391
//        this.initButton(this.btnEdit, "View linked item", "formfield-foreignkey-edit");
392
//
393
//        this.btnLinkGraphically.addActionListener((ActionEvent ae) -> {
394
//            fireFieldEnterEvent();
395
//            doLinkGraphically(this.btnLinkGraphically.isSelected());
396
//        });
397
        this.btnLinkGraphically.addComponentListener(new ComponentAdapter() {
398
            @Override
399
            public void componentHidden(ComponentEvent e) {
400
                doLinkGraphically(false);
401
            }
402
        });
403
        this.btnLinkGraphically.addAncestorListener(new AncestorListener() {
404
            @Override
405
            public void ancestorAdded(AncestorEvent event) {
406
            }
407

    
408
            @Override
409
            public void ancestorRemoved(AncestorEvent event) {
410
                doLinkGraphically(false);
411
            }
412

    
413
            @Override
414
            public void ancestorMoved(AncestorEvent event) {
415
            }
416
        });
417
//        this.btnLink.addActionListener((ActionEvent ae) -> {
418
//            fireFieldEnterEvent();
419
//            doLink();
420
//        });
421
//        this.btnUnlink.addActionListener((ActionEvent ae) -> {
422
//            fireFieldEnterEvent();
423
//            doUnlink();
424
//        });
425
//        this.btnEdit.addActionListener((ActionEvent ae) -> {
426
//            fireFieldEnterEvent();
427
//            doEdit();
428
//        });
429

    
430
        this.txtDescription.setText("                        ");
431
        this.txtDescription.addFocusListener(new FocusListener() {
432
            @Override
433
            public void focusGained(FocusEvent e) {
434
                fireFieldEnterEvent();
435
            }
436

    
437
            @Override
438
            public void focusLost(FocusEvent e) {
439
                fireFieldExitEvent();
440
            }
441
        });
442
        this.txtDescription.setEditable(false);
443

    
444
        boolean enabled = !this.isReadOnly();
445
        this.btnEdit.setEnabled(enabled);
446
        this.btnLink.setEnabled(enabled);
447
        this.btnUnlink.setEnabled(enabled);
448

    
449
        // Habilitar solo si no hay ninguna modal visible.
450
        this.btnLinkGraphically.setEnabled(enabled);
451

    
452
        JPanel panel = new JPanel();
453
        if (!components.containsJTextField(this.getDefinition(), null)) {
454
            panel.setLayout(new GridBagLayout());
455
            GridBagConstraints c = new GridBagConstraints();
456
            c.fill = GridBagConstraints.HORIZONTAL;
457
            c.ipadx = 4;
458
            c.ipady = 1;
459
            c.gridx = 1;
460
            c.gridy = 0;
461
            c.weightx = 1;
462
            panel.add(this.txtDescription, c);
463
            c.fill = GridBagConstraints.NONE;
464
            c.ipadx = 4;
465
            c.ipady = 1;
466
            c.gridx = 2;
467
            c.gridy = 0;
468
            c.weightx = 0;
469
            panel.add(this.btnLinkGraphically, c);
470
            c.fill = GridBagConstraints.NONE;
471
            c.ipadx = 4;
472
            c.ipady = 1;
473
            c.gridx = 3;
474
            c.gridy = 0;
475
            c.weightx = 0;
476
            panel.add(this.btnLink, c);
477
            c.fill = GridBagConstraints.NONE;
478
            c.ipadx = 4;
479
            c.ipady = 1;
480
            c.gridx = 4;
481
            c.gridy = 0;
482
            c.weightx = 0;
483
            panel.add(this.btnUnlink, c);
484
            c.fill = GridBagConstraints.NONE;
485
            c.ipadx = 4;
486
            c.ipady = 1;
487
            c.gridx = 5;
488
            c.gridy = 0;
489
            c.weightx = 0;
490
            panel.add(this.btnEdit, c);
491
        }
492
        this.contents = panel;
493
        this.setValue(this.assignedValue);
494

    
495
    }
496
   
497
//    private AbstractButton initButton(AbstractButton button, final String tip, final String image) {
498
//        if (button.getIcon() == null) {
499
//            IconThemeManager iconThemeManager = ToolsSwingLocator.getIconThemeManager();
500
//            Icon icon = iconThemeManager.getCurrent().get(image);
501
//            if (icon == null) {
502
//                URL url = this.getClass().getClassLoader().getResource("org/gvsig/featureform/swing/impl/" + image + ".png");
503
//                if (url != null) {
504
//                    icon = new ImageIcon(url);
505
//                }
506
//            }
507
//            if (icon != null) {
508
//                button.setIcon(icon);
509
//            }
510
//        }
511
//        if (button.getText().trim().equals("...") && button.getIcon() != null) {
512
//            button.setText("");
513
//        }
514
//        button.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
515
//        button.setBorderPainted(false);
516
////        button.setFocusPainted(false);
517
////        button.setContentAreaFilled(false);
518
//        button.setToolTipText(tip);
519
//        button.setCursor(new Cursor(Cursor.HAND_CURSOR));
520
//        return button;
521
//    }
522

    
523
    private ForeingKey getForeingKey() {
524
        JDynForm.DynFormContext context = this.getForm().getContext();
525
        if (!(context instanceof FeaturesFormContext)) {
526
            return null;
527
        }
528
        FeatureType featureType = ((FeaturesFormContext) context).getFeatureType();
529
        if (featureType == null) {
530
            return null;
531
        }
532
        FeatureAttributeDescriptor attribute = featureType.getAttributeDescriptor(this.getName());
533
        if (attribute == null) {
534
            return null;
535
        }
536
        ForeingKey foreingKey = attribute.getForeingKey();
537
        return foreingKey;
538
    }
539

    
540
    private void doLink() {
541
        final ForeingKey foreingKey = this.getForeingKey();
542
        if (foreingKey == null) {
543
            return;
544
        }
545
        final ContextForeingKey context = foreingKey.createContext();
546
        try {
547
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
548
            final FeatureStoreSearchPanel searchPanel = dataSwingManager.createFeatureStoreSearchPanel(
549
                    foreingKey.getFeatureStore(context)
550
            );
551
            searchPanel.setFilterOnlyMode(true);
552
            WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
553
            
554
            ToolsSwingUtils.ensureHeightWitdh(
555
                    searchPanel, 
556
                    ToolsSwingUtils.RELATIVE_TO_SCREEN,
557
                    0.75f, 0.75f, 0.85f, 0.85f
558
            );               
559
            
560
            final Dialog dialog = winManager.createDialog(
561
                    searchPanel.asJComponent(),
562
                    "Select",
563
                    "Select the '" + this.getLabel() + "'.",
564
                    WindowManager_v2.BUTTONS_OK_CANCEL
565
            );
566
            dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, this.btnUnlink.isEnabled());
567
            dialog.addActionListener((ActionEvent e) -> {
568
                if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
569
                    Feature feature = searchPanel.getLastSelectedFeature();
570
                    if (feature != null) {
571
                        setEditedValue(foreingKey.getCode(context, feature));
572
                        this.relatedFeature = feature;
573
                        fireFieldChangedEvent();
574
                    }
575
                }
576
            });
577
            dialog.show(WindowManager.MODE.DIALOG);
578

    
579
        } catch (Exception ex) {
580
            LOGGER.warn("Can't show selector", ex);
581
        } finally {
582
            DisposeUtils.disposeQuietly(context);
583
        }
584
    }
585

    
586
    public Feature getRelatedFeature() {
587
        try {
588
            if (this.relatedFeature != null) {
589
                return this.relatedFeature;
590
            }
591
            final ForeingKey foreingKey = this.getForeingKey();
592
            if (foreingKey == null) {
593
                return null;
594
            }
595
            this.relatedFeature = foreingKey.getFeature(null, value);
596
            return this.relatedFeature;
597
        } catch (Exception ex) {
598
            LOGGER.warn("Can't retrieve related feature from '" + value + "'.", ex);
599
            return null;
600
        }
601
    }
602

    
603
    private void doUnlink() {
604
        this.setEditedValue(null);
605
        fireFieldChangedEvent();
606
    }
607

    
608
    private void doEdit() {
609
        if (this.value == null) {
610
            return;
611
        }
612
        final ForeingKey foreingKey = this.getForeingKey();
613
        if (foreingKey == null) {
614
            return;
615
        }
616
        final ContextForeingKey context = foreingKey.createContext();
617
        try {
618
            this.btnEdit.setEnabled(false);
619
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
620
            FeatureQuery query = foreingKey.getQuery(context, value);
621
            JFeaturesForm form = dataSwingManager.createJFeaturesForm(
622
                    foreingKey.getFeatureStore(context)
623
            );
624
            form.setQuery(query);
625
            form.showForm(WindowManager.MODE.WINDOW);
626

    
627
        } catch (Exception ex) {
628
            LOGGER.warn("Can't show linked form", ex);
629
        } finally {
630
            this.btnEdit.setEnabled(true);
631
            DisposeUtils.disposeQuietly(context);
632
        }
633
    }
634

    
635
    private String getDescription() {
636
        if (this.value == null) {
637
            return null;
638
        }
639
        try {
640
            final ForeingKey foreingKey = this.getForeingKey();
641
            if (foreingKey == null) {
642
                return null;
643
            }
644
            String description = foreingKey.getLabel(null, value);
645
            return description;
646
        } catch (Exception ex) {
647
        }
648
        return null;
649

    
650
    }
651

    
652
    @Override
653
    public void setReadOnly(boolean readonly) {
654
        initComponentIfNeed();
655
        this.readOnly = readonly;
656
        boolean editable = !readonly;
657
        JComponent theJLabel = this.getJLabel();
658
        if( this.jlabel != null ) {
659
            this.jlabel.setEnabled(editable);
660
        } else if( theJLabel !=null ) {
661
            theJLabel.setEnabled(editable);
662
        }
663
        this.txtDescription.setEditable(false);
664
        this.btnEdit.setEnabled(true);
665
        this.btnLink.setEnabled(true);
666
        this.btnUnlink.setEnabled(editable);
667

    
668
        // Habilitar solo si no hay ninguna modal visible.
669
        this.btnLinkGraphically.setEnabled(editable);
670
        this.setReadOnlyButtonsOfEvents(readonly);
671
    }
672

    
673
    @Override
674
    public void setValue(Object value) {
675
        setEditedValue(value);
676
        this.assignedValue = value;
677
        this.relatedFeature = null;
678
    }
679

    
680
    public void setEditedValue(Object value) {
681
        initComponentIfNeed();
682
        if (value == null) {
683
            this.value = null;
684
            this.txtDescription.setText("");
685
            return;
686
        }
687
        this.value = value;
688
        this.txtDescription.setText(Objects.toString(this.getDescription(), ""));
689

    
690
    }
691

    
692
    @Override
693
    public Object getValue() {
694
        return this.value;
695
    }
696

    
697
    @Override
698
    public boolean hasValidValue() {
699
        return true;
700
    }
701

    
702
    @Override
703
    public void clear() {
704
        this.setValue(null);
705
    }
706

    
707
    @Override
708
    public boolean isModified() {
709
        return !Objects.equals(this.value, this.getAssignedValue());
710
    }
711

    
712
    private void doLinkGraphically(boolean isSelected) {
713
        final ForeingKey foreingKey = this.getForeingKey();
714
        if (foreingKey == null) {
715
            return;
716
        }
717
        final ContextForeingKey context = foreingKey.createContext();
718
        try {
719
            if (isSelected) {
720
                FeatureStore store = foreingKey.getFeatureStore(context);
721
                Pair<MapControl, FLyrVect> mapControlAndLayer = findMapControl(store);
722
                if (mapControlAndLayer != null) {
723
                    this.mapControl = mapControlAndLayer.getLeft();
724
                    if (!this.mapControl.hasTool("foreingkey-capture")) {
725
                        Behavior captureTool = new ForeignkeyCaptureBehavior(mapControl);
726
                        this.mapControl.addBehavior("foreingkey-capture", captureTool);
727
                    }
728
                    String s = this.mapControl.getCurrentTool();
729
                    if (!StringUtils.equalsIgnoreCase(s, "foreingkey-capture")) {
730
                        this.previosTool = s;
731
                    }
732
                    this.mapControl.setTool("foreingkey-capture");
733
                    Behavior captureTool = this.mapControl.getCurrentMapTool();
734
                    if (captureTool instanceof ForeignkeyCaptureBehavior) {
735
                        ((ForeignkeyCaptureBehavior)captureTool).setField(this);
736
                        ((ForeignkeyCaptureBehavior)captureTool).setLayer(mapControlAndLayer.getRight());
737
                    }
738
                    this.getForm().message("Activada la seleccion grafica de '"+this.getDefinition().getLabel()+"'.");
739
                } else {
740
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
741
                    dialogs.messageDialog(
742
                            "No se ha encontrado la tabla '"+store.getName()+"' en la Vista activa.", 
743
                            "Selector grafico", 
744
                            JOptionPane.INFORMATION_MESSAGE
745
                    );
746
                    this.mapControl = null;
747
                    this.btnLinkGraphically.setSelected(false);
748
                }
749
            } else {
750
                if( this.mapControl!=null ) {
751
                    if (StringUtils.isBlank(this.previosTool)) {
752
                        this.mapControl.setTool("pointSelection");
753
                    } else {
754
                        this.mapControl.setTool(this.previosTool);
755
                    }
756
                }
757
                this.getForm().message("Desactivada la seleccion grafica.");
758
            }
759
        } catch (Exception ex) {
760
            LOGGER.warn("Can't active/deactive foreingkey grafical selection", ex);
761
        } finally {
762
            DisposeUtils.disposeQuietly(context);
763
        }
764
    }
765

    
766
    private Pair<MapControl, FLyrVect> findMapControl(FeatureStore store) {
767
        ApplicationManager application = ApplicationLocator.getApplicationManager();
768
        IView view = (IView) application.getActiveComponent(ViewDocument.class);
769
        if (view == null) {
770
            return null;
771
        }
772
        DataStoreParameters storeParams = store.getParameters();
773
        MapControl theMapControl = view.getMapControl();
774
        MapContext mapContext = theMapControl.getMapContext();
775
        for (FLayer layer : mapContext.getLayers().deepiterable()) {
776
            if (layer instanceof FLyrVect) {
777
                FeatureStore layerStore = ((FLyrVect) layer).getFeatureStore();
778
                if (layerStore.getParameters().isTheSameStore(storeParams)) {
779
                    return new ImmutablePair<>(theMapControl, ((FLyrVect) layer));
780
                }
781
            }
782
        }
783
        return null;
784
    }
785
}