Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.swing / org.gvsig.fmap.dal.swing.impl / src / main / java / org / gvsig / fmap / dal / swing / impl / featuretype / DefaultFeatureAttributePanel.java @ 45920

History | View | Annotate | Download (64.9 KB)

1
package org.gvsig.fmap.dal.swing.impl.featuretype;
2

    
3
import java.awt.Component;
4
import java.awt.event.ActionEvent;
5
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypeAttributePanel;
6
import java.awt.event.ItemEvent;
7
import java.net.URL;
8
import java.util.ArrayList;
9
import java.util.Collections;
10
import java.util.List;
11
import java.util.Objects;
12
import javax.swing.DefaultComboBoxModel;
13
import javax.swing.DefaultListCellRenderer;
14
import javax.swing.DefaultListModel;
15
import javax.swing.ImageIcon;
16
import javax.swing.JButton;
17
import javax.swing.JCheckBox;
18
import javax.swing.JComboBox;
19
import javax.swing.JComponent;
20
import javax.swing.JLabel;
21
import javax.swing.JList;
22
import javax.swing.JOptionPane;
23
import javax.swing.JScrollPane;
24
import javax.swing.JTextField;
25
import javax.swing.ListModel;
26
import javax.swing.SwingUtilities;
27
import javax.swing.event.ChangeEvent;
28
import javax.swing.event.ListSelectionEvent;
29
import javax.swing.text.JTextComponent;
30
import org.apache.commons.io.FilenameUtils;
31
import org.apache.commons.lang3.StringUtils;
32
import org.cresques.cts.IProjection;
33
import org.gvsig.expressionevaluator.Expression;
34
import org.gvsig.expressionevaluator.ExpressionUtils;
35
import org.gvsig.expressionevaluator.swing.CalculatorController;
36
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingLocator;
37
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
38
import org.gvsig.expressionevaluator.swing.ExpressionPickerController;
39
import org.gvsig.fmap.dal.DALLocator;
40
import org.gvsig.fmap.dal.DataManager;
41
import org.gvsig.fmap.dal.DataStore;
42
import org.gvsig.fmap.dal.DataTypes;
43
import org.gvsig.fmap.dal.StoresRepository;
44
import org.gvsig.fmap.dal.complements.Search;
45
import org.gvsig.fmap.dal.exception.DataException;
46
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
47
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
48
import org.gvsig.fmap.dal.feature.DataProfile;
49
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
50
import org.gvsig.fmap.dal.feature.EditableFeatureType;
51
import org.gvsig.fmap.dal.feature.EditableForeingKey;
52
import org.gvsig.fmap.dal.feature.Feature;
53
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
54
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
55
import org.gvsig.fmap.dal.feature.FeatureStore;
56
import org.gvsig.fmap.dal.feature.FeatureType;
57
import org.gvsig.fmap.dal.feature.ForeingKey;
58
import org.gvsig.fmap.dal.swing.DALSwingLocator;
59
import org.gvsig.fmap.dal.swing.DataSwingManager;
60
import org.gvsig.fmap.dal.swing.expressionevaluator.FeatureStoreElement;
61
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel;
62
import static org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel.MODE_EDIT_ALL;
63
import static org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel.MODE_EDIT_ONLY_METADATA;
64
import static org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel.MODE_SHOW_ONLY;
65
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.Tag;
66
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.TagController;
67
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.TagsModel;
68
import org.gvsig.fmap.geom.Geometry;
69
import org.gvsig.fmap.geom.GeometryLocator;
70
import org.gvsig.fmap.geom.GeometryManager;
71
import org.gvsig.fmap.geom.type.GeometryType;
72
import org.gvsig.timesupport.RelativeInterval;
73
import org.gvsig.tools.ToolsLocator;
74
import org.gvsig.tools.dataTypes.DataType;
75
import org.gvsig.tools.dataTypes.DataType.NumberPrecisionAndScale;
76
import org.gvsig.tools.dataTypes.DataTypesManager;
77
import org.gvsig.tools.dynobject.DynField;
78
import org.gvsig.tools.dynobject.DynObjectValueItem;
79
import org.gvsig.tools.i18n.I18nManager;
80
import org.gvsig.tools.swing.api.ListElement;
81
import org.gvsig.tools.swing.api.ToolsSwingLocator;
82
import org.gvsig.tools.swing.api.ToolsSwingManager;
83
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
84
import org.gvsig.tools.swing.api.pickercontroller.PickerController;
85
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
86
import org.gvsig.tools.swing.api.windowmanager.Dialog;
87
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
88
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
89
import org.gvsig.tools.swing.icontheme.IconTheme;
90
import org.slf4j.Logger;
91
import org.slf4j.LoggerFactory;
92

    
93
/**
94
 *
95
 * @author jjdelcerro
96
 */
97
@SuppressWarnings({"UseSpecificCatch"})
98
public class DefaultFeatureAttributePanel
99
        extends DefaultFeatureAttributePanelView
100
        implements FeatureTypeAttributePanel {
101

    
102
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureAttributePanel.class);
103
    
104
    // ----
105
    // Los he eliminado del GUI pero los mantengo aqui por si decido rescatarlos
106
    private final JTextComponent txtMaxValue = new JTextField();
107
    private final JTextComponent txtMinValue = new JTextField();
108
    private final JComponent lblMinValue = new JLabel();
109
    private final JComponent lblMaxValue = new JLabel();
110
    // ----
111

    
112
    private static class ForeingKeyController {
113

    
114
        private final JCheckBox chkIsForeingKey;
115
        private final JCheckBox chkIsClosedList;
116
        private final JComboBox cboTable;
117
        private final JComboBox cboCode;
118
        private final JTextField txtFormula;
119
        private final JButton btnFormula;
120
        private final JButton btnFormulaHistory;
121
        private final JButton btnFormulaBokkmarks;
122
        private ExpressionPickerController pickerFormula;
123
        private boolean editable;
124
        private FeatureStoreElement featureStoreElement;
125
        private ForeingKey foreingKey;
126
        
127
        public ForeingKeyController(
128
                JCheckBox chkIsForeingKey,
129
                JCheckBox chkIsClosedList,
130
                JComboBox cboTable,
131
                JComboBox cboCode,
132
                JTextField txtFormula,
133
                JButton btnFormula,
134
                JButton btnFormulaBokkmarks,
135
                JButton btnFormulaHistory
136
        ) {
137
            this.chkIsForeingKey = chkIsForeingKey;
138
            this.chkIsClosedList = chkIsClosedList;
139
            this.cboTable = cboTable;
140
            this.cboCode = cboCode;
141
            this.txtFormula = txtFormula;
142
            this.btnFormula = btnFormula;
143
            this.btnFormulaHistory = btnFormulaHistory;
144
            this.btnFormulaBokkmarks = btnFormulaBokkmarks;
145
            this.initComponents();
146
        }
147

    
148
        private void initComponents() {
149
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
150
    
151
            this.editable = true;
152
            
153
            DefaultComboBoxModel<String> model = new DefaultComboBoxModel();
154
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
155
            List<String> tableNames = new ArrayList<>();
156
            for (String tableName : repository.keySet()) {
157
                tableNames.add(tableName);
158
            }
159
            Collections.sort(tableNames);
160
            for (String tableName : tableNames) {
161
                model.addElement(tableName);
162
            }
163
            this.cboTable.setModel(model);
164
            this.cboTable.addItemListener((ItemEvent e) -> {
165
              if (e.getStateChange() != ItemEvent.SELECTED) {
166
                return;
167
              }
168
              Thread th = new Thread(() -> {
169
                doPopulateComboCode();
170
              }, "FeatureTypePanelForeingKeyPopulateComboCode");
171
              th.start();
172
            });
173
            this.btnFormula.setText("");
174
            this.btnFormulaBokkmarks.setText("");
175
            this.btnFormulaHistory.setText("");
176
            this.featureStoreElement = dataSwingManager.createFeatureStoreElement();
177
            this.pickerFormula = ExpressionEvaluatorSwingLocator.getManager()
178
                    .createExpressionPickerController(txtFormula, btnFormula, btnFormulaBokkmarks, btnFormulaHistory);
179
            this.pickerFormula.addElement(this.featureStoreElement);
180
            
181
//            this.chkIsForeingKey.addChangeListener(new ChangeListener() {
182
//                @Override
183
//                public void stateChanged(ChangeEvent e) {
184
//                    if (chkIsForeingKey.isSelected()) {
185
//                        setEnabled(editable);
186
//                    } else {
187
//                        setEnabled(false);
188
//                    }
189
//                }
190
//            });
191
        }
192

    
193
        private void doPopulateComboCode() {
194
            String tableName = (String) this.cboTable.getSelectedItem();
195
            if( StringUtils.isBlank(tableName) ) {
196
                return;
197
            }
198
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
199
            DataStore store = repository.getStore(tableName);
200
            if( !(store instanceof FeatureStore) ) {
201
                return;
202
            }
203
            this.featureStoreElement.setFeatureStore((FeatureStore) store);
204
            FeatureType featureType;
205
            try {
206
                featureType = ((FeatureStore)store).getDefaultFeatureType();
207
            } catch (DataException ex) {
208
                return;
209
            }
210
            Search search = (Search) ToolsLocator.getComplementsManager().get(
211
                    Search.COMPLEMENT_MANE, featureType
212
            );
213
            List<Search.OrderedAttribute> attributes = search.getOrderedAttributes(
214
                    Search.BASIC_TYPES_FILTER,
215
                    Search.LABEL_ORDER, 
216
                    -1
217
            );
218
            final DefaultComboBoxModel model = new DefaultComboBoxModel();
219
            for (Search.OrderedAttribute attribute : attributes) {
220
                model.addElement(attribute.getDescriptor().getName());
221
            }
222
            SwingUtilities.invokeLater(() -> {
223
              cboCode.setModel(model);
224
              cboCode.setSelectedItem(foreingKey.getCodeName());
225
            });
226
        }
227

    
228
        public void setEditable(boolean editable) {
229
            this.chkIsForeingKey.setEnabled(editable);
230
            this.chkIsClosedList.setEnabled(editable);
231
            this.cboTable.setEnabled(editable);
232
            this.cboCode.setEnabled(editable);
233
            this.pickerFormula.setEditable(editable);
234
            this.editable = editable;
235
        }
236
        
237
        public void setEnabled(boolean enabled) {
238
            if( !editable ) {
239
                enabled =  false;
240
            }
241
            this.chkIsForeingKey.setEnabled(enabled);
242
            this.chkIsClosedList.setEnabled(enabled);
243
            this.cboTable.setEnabled(enabled);
244
            this.cboCode.setEnabled(enabled);
245
            this.pickerFormula.setEditable(editable);
246
        }
247
        
248
        public void clean() {
249
            this.chkIsForeingKey.setSelected(false);
250
            this.chkIsClosedList.setSelected(false);
251
            this.cboTable.setSelectedItem("");
252
            this.cboCode.setSelectedItem("");
253
            this.pickerFormula.set(null);
254
        }
255
        
256
        public void put(ForeingKey foreingKey) {
257
            if( foreingKey==null ) {
258
                this.clean();
259
                return;
260
            }
261
            this.foreingKey = foreingKey;
262
            this.chkIsForeingKey.setSelected(foreingKey.isForeingKey());
263
            this.chkIsClosedList.setSelected(foreingKey.isClosedList());
264
            this.cboTable.setSelectedItem(foreingKey.getTableName());
265
            this.cboCode.setSelectedItem(foreingKey.getCodeName());
266
            this.pickerFormula.set(foreingKey.getLabelExpression(null));
267
        }
268
        
269
        public void fetch(EditableForeingKey foreingKey) {
270
            if( foreingKey==null ) {
271
                return;
272
            }
273
            foreingKey.setForeingKey(this.chkIsForeingKey.isSelected());
274
            foreingKey.setClosedList(this.chkIsClosedList.isSelected());
275
            foreingKey.setTableName((String) this.cboTable.getSelectedItem());
276
            foreingKey.setCodeName((String) this.cboCode.getSelectedItem());
277
            Expression exp = this.pickerFormula.get();
278
            if( ExpressionUtils.isPhraseEmpty(exp) ) {
279
                foreingKey.setLabelFormula("");
280
            } else {
281
                foreingKey.setLabelFormula(exp.getPhrase());
282
            }
283
        }
284
    }
285
    
286

    
287
    private static class AvailableValuesController {
288

    
289
        private final JList lstValues;
290
        private final JTextComponent txtLabel;
291
        private final JTextComponent txtValue;
292
        private final JButton btnAdd;
293
        private final JButton btnUpdate;
294
        private final JButton btnRemove;
295
        private final JButton btnRemoveAll;
296

    
297
        public AvailableValuesController(
298
                JList lstValues,
299
                JTextComponent txtLabel,
300
                JTextComponent txtValue,
301
                JButton btnAdd,
302
                JButton btnUpdate,
303
                JButton btnRemove,
304
                JButton btnRemoveAll
305
        ) {
306
            this.lstValues = lstValues;
307
            this.txtLabel = txtLabel;
308
            this.txtValue = txtValue;
309
            this.btnAdd = btnAdd;
310
            this.btnUpdate = btnUpdate;
311
            this.btnRemove = btnRemove;
312
            this.btnRemoveAll = btnRemoveAll;
313

    
314
            this.lstValues.addListSelectionListener((ListSelectionEvent e) -> {
315
              doValuesChanged();
316
            });
317
            this.btnAdd.addActionListener((ActionEvent e) -> {
318
              doAdd();
319
            });
320
            this.btnUpdate.addActionListener((ActionEvent e) -> {
321
              doUpdate();
322
            });
323
            this.btnRemove.addActionListener((ActionEvent e) -> {
324
              doRemove();
325
            });
326
            this.btnRemoveAll.addActionListener((ActionEvent e) -> {
327
              doRemoveAll();
328
            });
329
        }
330

    
331
        public void clean() {
332
            this.lstValues.setModel(new DefaultListModel());
333
            this.txtLabel.setText("");
334
            this.txtValue.setText("");
335
            this.lstValues.setSelectedIndex(-1);
336
        }
337

    
338
        public DynObjectValueItem[] get() {
339
            ListModel<DynObjectValueItem> model = this.lstValues.getModel();
340
            if( model.getSize()==0 ) {
341
              return null;
342
            }
343
            DynObjectValueItem[] values = new DynObjectValueItem[model.getSize()];
344
            for (int i = 0; i < model.getSize(); i++) {
345
                values[i] = model.getElementAt(i);
346
            }
347
            return values;
348
        }
349

    
350
        public void set(DynObjectValueItem[] availableValues) {
351
            DefaultListModel model = new DefaultListModel();
352
            if (availableValues != null) {
353
                for (DynObjectValueItem availableValue : availableValues) {
354
                    model.addElement(availableValue);
355
                }
356
            }
357
            this.lstValues.setModel(model);
358
            if (model.getSize() > 0) {
359
                this.lstValues.setSelectedIndex(0);
360
            } else {
361
                this.lstValues.setSelectedIndex(-1);
362
            }
363
        }
364

    
365
        public void setEditable(boolean editable) {
366
            this.lstValues.setEnabled(editable);
367
            this.txtLabel.setEditable(editable);
368
            this.txtValue.setEditable(editable);
369
            this.btnAdd.setEnabled(editable);
370
            this.btnUpdate.setEnabled(editable);
371
            this.btnRemove.setEnabled(editable);
372
            this.btnRemoveAll.setEnabled(editable);
373
        }
374

    
375
        private void doValuesChanged() {
376
            DynObjectValueItem value = (DynObjectValueItem) this.lstValues.getSelectedValue();
377
            if (value == null) {
378
                this.txtLabel.setText("");
379
                this.txtValue.setText("");
380
                this.btnAdd.setEnabled(true);
381
                this.btnUpdate.setEnabled(false);
382
                this.btnRemove.setEnabled(false);
383
                return;
384
            }
385
            this.txtLabel.setText(value.getLabel());
386
            this.txtValue.setText(Objects.toString(value.getValue(), ""));
387
            this.btnAdd.setEnabled(true);
388
            this.btnUpdate.setEnabled(true);
389
            this.btnRemove.setEnabled(true);
390
        }
391

    
392
        private void doAdd() {
393
            DynObjectValueItem value = new DynObjectValueItem("Value", "Label");
394
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
395
            model.addElement(value);
396
            this.lstValues.setSelectedIndex(model.getSize() - 1);
397
        }
398

    
399
        private void doUpdate() {
400
            DynObjectValueItem value = (DynObjectValueItem) this.lstValues.getSelectedValue();
401
            if (value == null) {
402
                return; // EEhh?? esto no deberia pasar
403
            }
404
            value.setLabel(this.txtLabel.getText());
405
            value.setValue(this.txtValue.getText());
406
        }
407

    
408
        private void doRemove() {
409
            int n = this.lstValues.getSelectedIndex();
410
            if (n < 0) {
411
                return; // EEhh?? esto no deberia pasar
412
            }
413
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
414
            model.removeElementAt(n);
415
            if (--n < 0) {
416
                n = 0;
417
            }
418
            this.lstValues.setSelectedIndex(n);
419
        }
420

    
421
        private void doRemoveAll() {
422
            DefaultListModel model = new DefaultListModel();
423
            this.lstValues.setModel(model);
424
            this.lstValues.setSelectedIndex(-1);
425
        }
426

    
427
    }
428

    
429
    private final List<ListElement<Integer>> fieldTypes;
430
    private final List<ListElement<Integer>> geometryTypes;
431
    private final List<ListElement<Integer>> geometrySubtypes;
432

    
433
    private DatePickerController pickerIntervalEnd;
434
    private DatePickerController pickerIntervalStart;
435
    private CalculatorController<Integer> pickerSize;
436
    private CalculatorController<Integer> pickerDisplaySize;
437
    private CalculatorController<Integer> pickerPrecision;
438
    private CalculatorController<Integer> pickerScale;
439
    private PickerController<IProjection> pickerCRS;
440
    private ExpressionPickerController pickerVirtualField;
441
    private CalculatorController<Integer> pickerOrder;
442
    private AvailableValuesController availableValuesController;
443
    private AggregateController<Tag> tagsController;
444
    private ForeingKeyController foreingKeyController;
445
    private ExpressionPickerController pickerValuesFilter;
446

    
447
    private int mode;
448
    private FeatureStoreElement featureStoreElement;
449

    
450
    public DefaultFeatureAttributePanel() {
451
        this.mode = FeatureTypePanel.MODE_SHOW_ONLY;
452
        DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
453
        // se deber?a de utilizar el datatypepicker
454
        this.fieldTypes = new ArrayList<>();
455
        fieldTypes.add( new ListElement<>("Decimal", DataTypes.DECIMAL) );
456
        fieldTypes.add( new ListElement<>("Integer", DataTypes.INTEGER) );
457
        fieldTypes.add( new ListElement<>("String", DataTypes.STRING) );
458
        fieldTypes.add( new ListElement<>("Boolean", DataTypes.BOOLEAN) );
459
        fieldTypes.add( new ListElement<>("Date", DataTypes.DATE) );
460
        fieldTypes.add( new ListElement<>("Date/Time (Timestamp)", DataTypes.TIMESTAMP) );
461
//        for (DataType dataType : dataManager) {
462
//            fieldTypes.add( new ListElement<>(dataType.getName(), dataType.getType()) );
463
//        }
464
        fieldTypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
465
                o1.toString().compareTo(o2.toString())
466
        );
467

    
468
        this.geometryTypes = new ArrayList<>();
469
        this.geometryTypes.add(new ListElement("Point", Geometry.TYPES.POINT));
470
        this.geometryTypes.add(new ListElement("Line", Geometry.TYPES.LINE));
471
        this.geometryTypes.add(new ListElement("Polygon", Geometry.TYPES.POLYGON));
472
        this.geometryTypes.add(new ListElement("MultiPoint", Geometry.TYPES.MULTIPOINT));
473
        this.geometryTypes.add(new ListElement("MultiLine", Geometry.TYPES.MULTILINE));
474
        this.geometryTypes.add(new ListElement("MultiPolygon", Geometry.TYPES.MULTIPOLYGON));
475
        this.geometryTypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
476
                  o1.toString().compareTo(o2.toString())
477
        );
478

    
479
        this.geometrySubtypes = new ArrayList<>();
480
        this.geometrySubtypes.add(new ListElement("2D", Geometry.SUBTYPES.GEOM2D));
481
        this.geometrySubtypes.add(new ListElement("2DM", Geometry.SUBTYPES.GEOM3D));
482
        this.geometrySubtypes.add(new ListElement("3D", Geometry.SUBTYPES.GEOM2DM));
483
        this.geometrySubtypes.add(new ListElement("3DM", Geometry.SUBTYPES.GEOM3DM));
484
        this.geometrySubtypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
485
                o1.toString().compareTo(o2.toString())
486
        );
487

    
488
        this.initComponents();
489
    }
490

    
491
    private void initComponents() {
492
        final ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
493
        final ExpressionEvaluatorSwingManager evaluatorSwingManager = ExpressionEvaluatorSwingLocator.getManager();
494
        final DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
495
        final I18nManager i18n = ToolsLocator.getI18nManager();
496
        final DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
497

    
498
        DefaultComboBoxModel<ListElement<Integer>> modelTypes = new DefaultComboBoxModel<>();
499
        for (ListElement<Integer> element : fieldTypes) {
500
            modelTypes.addElement(element);
501
        }
502
        this.cboFieldType.setModel(modelTypes);
503
        this.cboFieldType.setRenderer(new DefaultListCellRenderer() {
504
          @Override
505
          public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
506
              JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
507
              label.setIcon(null);
508
              try {
509
                DataType dataType = dataTypeManager.get((int) value);
510
                IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
511
                if (theme.exists(dataType.getIconName())) {
512
                    label.setIcon(theme.get(dataType.getIconName()));
513
                }
514
              } catch(Exception ex) {
515
                // Do nothing, ignore
516
              }
517
              return label;
518
          }
519
        });
520

    
521
        DefaultComboBoxModel<ListElement<Integer>> modelGeomTypes = new DefaultComboBoxModel<>();
522
        for (ListElement<Integer> element : this.geometryTypes) {
523
            modelGeomTypes.addElement(element);
524
        }
525
        this.cboGeometryType.setModel(modelGeomTypes);
526

    
527
        DefaultComboBoxModel<ListElement<Integer>> modelGeomSubtypes = new DefaultComboBoxModel<>();
528
        for (ListElement<Integer> element : this.geometrySubtypes) {
529
            modelGeomSubtypes.addElement(element);
530
        }
531

    
532
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
533

    
534
        swingManager.translate(this.lblAllowNulls);
535
        swingManager.translate(this.lblCRS);
536
        swingManager.translate(this.lblDataProfile);
537
        swingManager.translate(this.lblDateFormat);
538
        swingManager.translate(this.lblDefaultValue);
539
        swingManager.translate(this.lblFieldName);
540
        swingManager.translate(this.lblFieldType);
541
        swingManager.translate(this.lblGeometrySubtype);
542
        swingManager.translate(this.lblGeometryType);
543
        swingManager.translate(this.lblInterval);
544
        swingManager.translate(this.lblIntervalEnd);
545
        swingManager.translate(this.lblIntervalStart);
546
        swingManager.translate(this.lblIsAutomatic);
547
        swingManager.translate(this.lblIsIndexed);
548
        swingManager.translate(this.lblIsReadOnly);
549
        swingManager.translate(this.lblIsPrimaryKey);
550
        swingManager.translate(this.lblPrecision);
551
        swingManager.translate(this.lblScale);
552
        swingManager.translate(this.lblSize);
553
        swingManager.translate(this.lblDisplaySize);
554
        swingManager.translate(this.chkVirtualField);
555
        swingManager.translate(this.tabAditionalFields);
556
        swingManager.translate(this.tabLayout);
557
        swingManager.translate(this.lblGroup);
558
        swingManager.translate(this.lblOrder);
559
        swingManager.translate(this.lblHidden);
560
        swingManager.translate(this.lblLabel);
561
        swingManager.translate(this.lblDescription);
562
        swingManager.translate(this.lblMinValue);
563
        swingManager.translate(this.lblMaxValue);
564
        swingManager.translate(this.lblAvailableValues);
565
        swingManager.translate(this.lblAvailableValuesLabel);
566
        swingManager.translate(this.lblAvailableValuesValue);
567
        swingManager.translate(this.lblRelationType);
568
        swingManager.translate(this.btnAvailableValuesAdd);
569
        swingManager.translate(this.btnAvailableValuesUpdate);
570
        swingManager.translate(this.btnAvailableValuesRemove);
571
        swingManager.translate(this.btnAvailableValuesRemoveAll);
572
        swingManager.translate(this.lblAttrTagsItemName);
573
        swingManager.translate(this.lblAttrTagsItemValue);
574
        swingManager.translate(this.lblAttrTagsItemNotes);
575
        swingManager.translate(this.lblValuesFilter);
576

    
577
        swingManager.translate(this.lblForeingKeyCodeName);
578
        swingManager.translate(this.lblForeingKeyLabelFormula);
579
        swingManager.translate(this.lblForeingKeyTableName);
580
        swingManager.translate(this.lblIsClosedList);
581
        swingManager.translate(this.chkIsForeingKey);
582

    
583
        swingManager.translate(this.txtDisplaySize);
584
        swingManager.translate(this.txtPrecision);
585
        swingManager.translate(this.txtScale);
586
        swingManager.translate(this.txtScale);
587

    
588
        swingManager.addClearButton(this.txtDefaultValue);
589
        swingManager.addClearButton(this.txtFieldName);
590
        swingManager.addClearButton(this.txtIntervalEnd);
591
        swingManager.addClearButton(this.txtIntervalStart);
592
        swingManager.addClearButton(this.txtScale);
593
        swingManager.addClearButton(this.txtSize);
594
        swingManager.addClearButton(this.txtDisplaySize);
595
        swingManager.addClearButton(this.txtLabel);
596
        swingManager.addClearButton(this.txtDescription);
597
        swingManager.addClearButton(this.cboGroup);
598
        swingManager.addClearButton(this.txtMaxValue);
599
        swingManager.addClearButton(this.txtMinValue);
600
        swingManager.addClearButton(this.txtAvailableValuesLabel);
601
        swingManager.addClearButton(this.txtAvailableValuesValue);
602

    
603
        swingManager.setDefaultPopupMenu(this.txtDefaultValue);
604
        swingManager.setDefaultPopupMenu(this.txtFieldName);
605
        swingManager.setDefaultPopupMenu(this.txtIntervalEnd);
606
        swingManager.setDefaultPopupMenu(this.txtIntervalStart);
607
        swingManager.setDefaultPopupMenu(this.txtScale);
608
        swingManager.setDefaultPopupMenu(this.txtSize);
609
        swingManager.setDefaultPopupMenu(this.txtDisplaySize);
610
        swingManager.setDefaultPopupMenu(this.cboDateFormat);
611
        swingManager.setDefaultPopupMenu(this.cboFieldType);
612
        swingManager.setDefaultPopupMenu(this.cboGeometrySubtype);
613
        swingManager.setDefaultPopupMenu(this.cboGeometryType);
614
        swingManager.setDefaultPopupMenu(this.cboDataProfile);
615

    
616
        swingManager.setDefaultPopupMenu(this.cboForeingKeyCodeName);
617
        swingManager.setDefaultPopupMenu(this.cboForeingKeyTableName);
618

    
619
        swingManager.setDefaultPopupMenu(this.cboGroup);
620
        swingManager.setDefaultPopupMenu(this.txtOrder);
621
        swingManager.setDefaultPopupMenu(this.txtLabel);
622
        swingManager.setDefaultPopupMenu(this.txtDescription);
623
        swingManager.setDefaultPopupMenu(this.txtMinValue);
624
        swingManager.setDefaultPopupMenu(this.txtMaxValue);
625
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesLabel);
626
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesValue);
627

    
628
        this.foreingKeyController = new ForeingKeyController(
629
                chkIsForeingKey, 
630
                chkIsClosedList, 
631
                cboForeingKeyTableName, 
632
                cboForeingKeyCodeName, 
633
                txtForeingKeyFormula, 
634
                btnForeingKeyFormula,
635
                btnForeingKeyFormulaBookmarks,
636
                btnForeingKeyFormulaHistory
637
        );
638
        this.pickerIntervalEnd = swingManager.createDatePickerController(
639
                this.txtIntervalEnd,
640
                this.btnIntervalEnd
641
        );
642
        this.pickerIntervalStart = swingManager.createDatePickerController(
643
                this.txtIntervalStart,
644
                this.btnIntervalStart
645
        );
646
        this.pickerSize = evaluatorSwingManager.createCalculatorController(
647
                this.txtSize, DataTypes.INT
648
        );
649
        this.pickerDisplaySize = evaluatorSwingManager.createCalculatorController(this.txtDisplaySize, DataTypes.INT
650
        );
651
        this.pickerPrecision = evaluatorSwingManager.createCalculatorController(
652
                this.txtPrecision, DataTypes.INT
653
        );
654
        this.pickerScale = evaluatorSwingManager.createCalculatorController(
655
                this.txtScale, DataTypes.INT
656
        );
657
        this.txtDefaultValue.getComponentPopupMenu().add(evaluatorSwingManager.createJExpressionBuilderAction(txtDefaultValue));
658
        this.pickerOrder = evaluatorSwingManager.createCalculatorController(
659
                this.txtOrder, DataTypes.INT
660
        );
661

    
662
        this.availableValuesController = new AvailableValuesController(
663
                lstAvailableValues,
664
                txtAvailableValuesLabel,
665
                txtAvailableValuesValue,
666
                btnAvailableValuesAdd,
667
                btnAvailableValuesUpdate,
668
                btnAvailableValuesRemove,
669
                btnAvailableValuesRemoveAll
670
        );
671
        
672
        this.tagsController = new DefaultAggregateController<>(
673
                this.tblAttrTagsItems,
674
                this.btnAttrTagsModify,
675
                this.btnAttrTagsDiscard,
676
                this.btnAttrTagsAccept,
677
                this.btnAttrTagsNew,
678
                this.btnAttrTagsDelete,
679
                new TagController(
680
                        this.cboAttrTagsItemName,
681
                        this.cboAttrTagsItemValue,
682
                        this.lblAttrTagsItemNotesValue
683
                )
684
        );        
685
        this.txtMinValue.setEnabled(false);
686
        this.txtMaxValue.setEnabled(false);
687

    
688
        this.btnVirtualField.setText("");
689
        this.featureStoreElement = dataSwingManager.createFeatureStoreElement();
690
        this.pickerVirtualField = evaluatorSwingManager.createExpressionPickerController(
691
                txtVirtualField, btnVirtualField, btnVirtualFieldBookmarks, btnVirtualFieldHistory
692
        );
693
        this.pickerVirtualField.addElement(this.featureStoreElement);
694
        this.chkVirtualField.addChangeListener((ChangeEvent e) -> {
695
          if (chkVirtualField.isSelected()) {
696
            pickerVirtualField.setEditable(mode==MODE_EDIT_ALL || mode==MODE_EDIT_ONLY_METADATA);
697
          } else {
698
            pickerVirtualField.setEditable(false);
699
          }
700
        });
701

    
702
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
703
                this.txtCRS, this.btnCRS
704
        );
705

    
706
        this.cboFieldType.addItemListener((ItemEvent e) -> {
707
          SwingUtilities.invokeLater(() -> {
708
            doFieldTypeChanged();
709
          });
710
        });
711

    
712
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
713
          doCheckPrecisionAndScale();
714
        });
715
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
716
          doCheckPrecisionAndScale();
717
        });
718

    
719
        DefaultComboBoxModel dataProfilesModel = new DefaultComboBoxModel<>();
720
        dataProfilesModel.addElement(new ListElement<>("", null));
721
        for (DataProfile profile : DALLocator.getDataManager().getDataProfiles()) {
722
            dataProfilesModel.addElement(new ListElement<>(profile.getName(), profile.getID()));
723
        }
724
        this.cboDataProfile.setModel(dataProfilesModel);
725
        
726
        this.btnFieldType.addActionListener((ActionEvent e) -> {
727
          doDataTypeSelection();
728
        });
729
        
730
        DefaultComboBoxModel<ListElement<Integer>> relationTypeModel = new DefaultComboBoxModel<>();
731
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_None"),DynField.RELATION_TYPE_NONE));
732
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Identity_1_1"),DynField.RELATION_TYPE_IDENTITY));
733
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Collaboration_1_1"),DynField.RELATION_TYPE_COLLABORATION));
734
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Composition_1_N"),DynField.RELATION_TYPE_COMPOSITION));
735
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Aggregate_1_N"),DynField.RELATION_TYPE_AGGREGATE));
736
        this.cboRelationType.setModel(relationTypeModel);
737

    
738

    
739
        this.pickerValuesFilter = evaluatorSwingManager.createExpressionPickerController(
740
                txtValuesFilter, btnValuesFilter, btnValuesFilterBookmarks, btnValuesFilterHistory
741
        );
742
        this.pickerValuesFilter.addElement(this.featureStoreElement);
743

    
744
    }
745

    
746
    @Override
747
    public JComponent asJComponent() {
748
        return this;
749
    }
750
    
751
    private void doDataTypeSelection() {
752
        final DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
753
        final I18nManager i18n = ToolsLocator.getI18nManager();
754
        List<ListElement<Integer>> types = new ArrayList<>();
755
        for (DataType dataType : dataManager) {
756
            types.add( new ListElement<>(dataType.getName(), dataType.getType()) );
757
        }
758
        types.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
759
                o1.toString().compareTo(o2.toString())
760
        );
761
        
762
        DefaultListModel<ListElement<Integer>> modelTypes = new DefaultListModel<>();
763
        for (ListElement<Integer> element : types) {
764
            modelTypes.addElement(element);
765
        }
766
        final JList list = new JList();
767
        list.setCellRenderer(new DefaultListCellRenderer() {
768
          @Override
769
          public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
770
              JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
771
              label.setIcon(null);
772
              try {
773
                DataType dataType = dataManager.get((int) value);
774
                IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
775
                if (theme.exists(dataType.getIconName())) {
776
                    label.setIcon(theme.get(dataType.getIconName()));
777
                }
778
              } catch(Exception ex) {
779
                // Do nothing, ignore
780
              }
781
              return label;
782
          }
783
        });
784
        list.setModel(modelTypes);
785
        final JScrollPane scrollpanel = new JScrollPane(list);
786
        WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
787
        Dialog dialog = winManager.createDialog(
788
              scrollpanel, 
789
              i18n.getTranslation("_Data_type_selection"),
790
              i18n.getTranslation("_Select_the_data_type"),
791
              WindowManager_v2.BUTTONS_OK_CANCEL
792
        );
793
        dialog.addActionListener((ActionEvent e) -> {
794
          if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
795
            Integer type = (Integer) ListElement.getSelected(list);
796
            if( type!=null ) {
797
              ListElement.setSelected(cboFieldType, type);
798
              if( ListElement.getSelected(cboFieldType)==null ) {
799
                DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
800
                DataType dataType = dataTypeManager.get(type);
801
                cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
802
                ListElement.setSelected(cboFieldType, dataType.getType());
803
              }
804
            }
805
          }
806
        });
807
        dialog.show(WindowManager.MODE.DIALOG);
808
    }
809

    
810
    @Override
811
    public EditableFeatureAttributeDescriptor fetch(EditableFeatureAttributeDescriptor descriptor) {
812
        I18nManager i18n = ToolsLocator.getI18nManager();
813
        try {
814
            if (!this.chkAllowNulls.isSelected()) {
815
                if (descriptor.allowNull()) {
816
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
817
                    dialogs.messageDialog(
818
                            i18n.getTranslation("_You_have_marked_not_allow_nulls") + "\n"
819
                            + i18n.getTranslation("If_you_are_not_fully_aware_of_the_repercussions_of_this_it_is_advisable_to_allow_nulls"),
820
                            null,
821
                            i18n.getTranslation("_Warning"),
822
                            JOptionPane.INFORMATION_MESSAGE,
823
                            "AllowNullsInFeatureTypeEditing"
824
                    );
825
                }
826
            }
827
            descriptor.setDataType((int) ListElement.getSelected(this.cboFieldType));
828
            descriptor.setName(this.txtFieldName.getText());
829
            descriptor.setAllowNull(this.chkAllowNulls.isSelected());
830
            descriptor.setIsPrimaryKey(this.chkIsPrimaryKey.isSelected());
831
            descriptor.setIsAutomatic(this.chkIsAutomatic.isSelected());
832
            descriptor.setIsReadOnly(this.chkIsReadOnly.isSelected());
833
            descriptor.setIsIndexed(this.chkIsIndexed.isSelected());
834
            descriptor.setSize(this.pickerSize.get(0));
835
            descriptor.setDisplaySize(this.pickerDisplaySize.get(0));
836
            descriptor.setPrecision(this.pickerPrecision.get(0));
837
            descriptor.setScale(this.pickerScale.get(0));
838
            descriptor.setDefaultValue(this.txtDefaultValue.getText());
839
            descriptor.setDataProfileName((String) ListElement.getSelected(this.cboDataProfile));
840
            descriptor.setRelationType((int) ListElement.getSelected(this.cboRelationType));
841
            switch (descriptor.getType()) {
842
                case DataTypes.GEOMETRY:
843
                    GeometryManager geomManager = GeometryLocator.getGeometryManager();
844
                    GeometryType geomType = geomManager.getGeometryType(
845
                            (int) ListElement.getSelected(this.cboGeometryType),
846
                            (int) ListElement.getSelected(this.cboGeometrySubtype)
847
                    );
848
                    descriptor.setGeometryType(geomType);
849
                    descriptor.setSRS(this.pickerCRS.get());
850
                    break;
851
                case DataTypes.INSTANT:
852
                case DataTypes.INTERVAL:
853
                case DataTypes.DATE:
854
                case DataTypes.TIME:
855
                case DataTypes.TIMESTAMP:
856
                    // FIXME
857
                    break;
858
                default:
859
                    break;
860
            }
861
            descriptor.setDataProfileName(
862
                    StringUtils.defaultIfBlank((String) ListElement.getSelected(cboDataProfile), null)
863
            );
864

    
865
            if (this.chkVirtualField.isSelected() ) { //&& this.pickerVirtualField.isEnabled()) {
866
                Expression expression = this.pickerVirtualField.get();
867
                if (expression == null) {
868
                    descriptor.setFeatureAttributeEmulator((String) null);
869
                } else {
870
                    DataManager dataManager = DALLocator.getDataManager();
871
                    FeatureAttributeEmulatorExpression emulator = dataManager.createFeatureAttributeEmulatorExpression(
872
                            descriptor.getFeatureType(),
873
                            expression
874
                    );
875
                    if (!emulator.isValid()) {
876
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
877
                        dialogs.messageDialog(
878
                                i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")+"\n"
879
                                + "\n"
880
                                + emulator.getErrorMessage(),
881
                                i18n.getTranslation("_Warning"),
882
                                JOptionPane.WARNING_MESSAGE
883
                        );
884
                        return null;
885
                    }
886
                    for (String requiredFieldName : emulator.getRequiredFieldNames()) {
887
                        if (StringUtils.equalsIgnoreCase(requiredFieldName, descriptor.getName())) {
888
                            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
889
                            dialogs.messageDialog(
890
                                    i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")
891
                                    + "\n\n"
892
                                    + i18n.getTranslation("_The_expression_contains_a_reference_to_itself"),
893
                                    i18n.getTranslation("_Warning"),
894
                                    JOptionPane.WARNING_MESSAGE
895
                            );
896
                            return null;
897
                        }
898
                    }
899
                    List<String> undefinedSymbols = emulator.getUndefinedSymbols();
900
                    if( undefinedSymbols!=null && !undefinedSymbols.isEmpty() ) {
901
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
902
                        dialogs.messageDialog(
903
                                i18n.getTranslation("_The_expression_has_undefined_symbols_at_this_moment")+"\n"
904
                                + i18n.getTranslation("_This_may_not_be_a_mistake")+"\n"
905
                                + "\n"
906
                                + "("+StringUtils.join(undefinedSymbols,",")+")",
907
                                i18n.getTranslation("_Warning"),
908
                                JOptionPane.WARNING_MESSAGE
909
                        );
910
                    }
911
                    descriptor.setFeatureAttributeEmulator(emulator);
912
                    //
913
                    // No se porque esto de abajo no funciona.
914
                    // Nunca se lanza la excepcion en el get(Feature) de
915
                    // DefaultFeatureAttributeEmulatorExpression.
916
                    //
917
//                    try {
918
//                        emulator.setEnableExceptions(true);
919
//                        descriptor.setFeatureAttributeEmulator(emulator);
920
//                        this.pickerVirtualField.getPreviewSymbolTable().value(descriptor.getName());
921
//                    } catch(Throwable ex) {
922
//                        emulator.setEnableExceptions(false);
923
//                        descriptor.setFeatureAttributeEmulator(null);
924
//                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
925
//                        dialogs.messageDialog(
926
//                                i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")+
927
//                                    "\n"+
928
//                                    ex.getMessage(), 
929
//                                i18n.getTranslation("_Warning"), 
930
//                                JOptionPane.WARNING_MESSAGE
931
//                        );
932
//                        return null;
933
//                    } finally {
934
//                        emulator.setEnableExceptions(false);
935
//                    }
936
                }
937
            }
938
        } catch (Exception ex) {
939
            LOGGER.warn("Can't retrieve information from user form.", ex);
940
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
941
            dialogs.messageDialog(
942
                    i18n.getTranslation("_Cant_retrieve_information_from_user_form")
943
                    + "\n"
944
                    + i18n.getTranslation("_See_log_for_details"),
945
                    i18n.getTranslation("_Warning"),
946
                    JOptionPane.WARNING_MESSAGE
947
            );
948
            return null;
949
        }
950

    
951
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
952
        descriptor.setOrder(this.pickerOrder.get(0));
953
        descriptor.setHidden(this.chkHidden.isSelected());
954
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
955
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
956

    
957
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
958
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
959
        Expression valuesFilter = this.pickerValuesFilter.get();
960
        
961
        descriptor.setAvailableValues(this.availableValuesController.get());
962

    
963
        this.tagsController.getModel().fetch(descriptor.getTags());
964
        this.foreingKeyController.fetch(descriptor.getForeingKey());
965
        return descriptor;
966
    }
967

    
968
    @Override
969
    public void clean() {
970
        this.txtDefaultValue.setText("");
971
        this.txtFieldName.setText("");
972
//        this.pickerFieldName.set(null);
973
        this.pickerIntervalEnd.set(null);
974
        this.pickerIntervalStart.set(null);
975
        this.pickerScale.set(null);
976
        this.pickerSize.set(null);
977
        this.pickerDisplaySize.set(null);
978

    
979
        this.chkAllowNulls.setSelected(false);
980
        this.chkIsAutomatic.setSelected(false);
981
        this.chkIsReadOnly.setSelected(false);
982
        this.chkIsIndexed.setSelected(false);
983
        this.chkIsPrimaryKey.setSelected(false);
984

    
985
        this.chkVirtualField.setSelected(false);
986
        this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
987
        this.pickerVirtualField.setEditable(false);
988
        this.pickerVirtualField.set(null);
989

    
990
        ListElement.setSelected(cboGeometryType, null);
991
        ListElement.setSelected(cboGeometrySubtype, null);
992

    
993
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
994

    
995
        this.cboDataProfile.setSelectedIndex(-1);
996

    
997
        this.cboGroup.setSelectedIndex(-1);
998
        this.pickerOrder.set(null);
999
        this.chkHidden.setSelected(false);
1000
        this.txtLabel.setText("");
1001
        this.txtDescription.setText("");
1002
        this.txtMinValue.setText("");
1003
        this.txtMaxValue.setText("");
1004
        this.availableValuesController.clean();
1005
        this.tagsController.clean();
1006
        this.foreingKeyController.clean();
1007
    }
1008

    
1009
    @Override
1010
    public void put(FeatureAttributeDescriptor descriptor) {
1011
        if (descriptor == null) {
1012
            this.clean();
1013
            return;
1014
        }
1015
        DataType dataType = descriptor.getDataType();
1016
        FeatureType featureType = descriptor.getFeatureType();
1017
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
1018

    
1019
        if (featureType != null) {
1020
            FeatureStore store = descriptor.getFeatureType().getStore();
1021
            this.featureStoreElement.setFeatureStore(store);
1022
            if (store != null) {
1023
                Feature sampleFeature = null;
1024
                try {
1025
                    sampleFeature = store.getFeatureSelection().first();
1026
                    if (sampleFeature == null) {
1027
                        sampleFeature = store.first();
1028
                    }
1029
                } catch (DataException ex) {
1030
                }
1031
                if (sampleFeature != null) {
1032
                    FeatureSymbolTable featureSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable();
1033
                    featureSymbolTable.setFeature(sampleFeature);
1034
                    this.pickerVirtualField.setPreviewSymbolTable(featureSymbolTable.createParent());
1035
                    this.pickerValuesFilter.setPreviewSymbolTable(featureSymbolTable.createParent());
1036
                }
1037
            }
1038
            List<String> groups = new ArrayList<>();
1039
            for (FeatureAttributeDescriptor otherdesc : featureType) {
1040
                String group = otherdesc.getGroup();
1041
                if (!StringUtils.isBlank(group) && !groups.contains(group)) {
1042
                    groups.add(group);
1043
                }
1044
            }
1045
            for (String group : groups) {
1046
                groupModel.addElement(group);
1047
            }
1048
        }
1049

    
1050
        this.txtDefaultValue.setText(Objects.toString(descriptor.getDefaultValue(),""));
1051
        this.txtFieldName.setText(descriptor.getName());
1052
        RelativeInterval interval = (RelativeInterval) descriptor.getInterval();
1053
        if (interval == null) {
1054
            this.pickerIntervalEnd.set(null);
1055
            this.pickerIntervalStart.set(null);
1056
        } else {
1057
            this.pickerIntervalEnd.set(interval.getEnd().toDate());
1058
            this.pickerIntervalStart.set(interval.getStart().toDate());
1059
        }
1060
        if( dataType.supportSize() ) {
1061
          this.pickerSize.set(descriptor.getSize());
1062
        } else {
1063
          this.pickerSize.set(null);
1064
        }
1065
        this.pickerDisplaySize.set(descriptor.getDisplaySize());
1066
        if( dataType.supportPrecision() ) {
1067
          this.pickerPrecision.set(descriptor.getPrecision());
1068
        } else {
1069
          this.pickerPrecision.set(null);
1070
        }
1071
        if( dataType.supportScale()) {
1072
          this.pickerScale.set(descriptor.getScale());
1073
        } else {
1074
          this.pickerScale.set(null);
1075
        }
1076
        this.chkAllowNulls.setSelected(descriptor.allowNull());
1077
        this.chkIsAutomatic.setSelected(descriptor.isAutomatic());
1078
        this.chkIsReadOnly.setSelected(descriptor.isReadOnly());
1079
        this.chkIsIndexed.setSelected(descriptor.isIndexed());
1080
        this.chkIsPrimaryKey.setSelected(descriptor.isPrimaryKey());
1081

    
1082
        this.pickerVirtualField.setEnabled(true);
1083
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1084
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1085
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1086
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1087
            this.chkVirtualField.setSelected(true);
1088
            this.pickerVirtualField.set(expression);
1089
        } else if (descriptor.isComputed()) {
1090
            this.chkVirtualField.setEnabled(false);
1091
            this.chkVirtualField.setSelected(true);
1092
            this.pickerVirtualField.set(null);
1093
        } else {
1094
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1095
            this.chkVirtualField.setSelected(false);
1096
            this.pickerVirtualField.set(null);
1097
        }
1098
        this.pickerVirtualField.setEnabled(true);
1099

    
1100
        Expression expression = descriptor.getAvailableValuesFilter();
1101
        this.pickerValuesFilter.set(expression);
1102

    
1103
        this.pickerCRS.set(descriptor.getSRS());
1104

    
1105
        if (descriptor.getGeomType() != null) {
1106
            ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1107
            ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1108
        }
1109
        ListElement.setSelected(cboFieldType, dataType.getType());
1110
        if( ListElement.getSelected(cboFieldType)==null ) {
1111
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1112
          ListElement.setSelected(cboFieldType, dataType.getType());
1113
        }
1114
 
1115
        ListElement.setSelected(cboRelationType, descriptor.getRelationType());
1116

    
1117
        String profile = descriptor.getDataProfileName();
1118
        if (StringUtils.isBlank(profile)) {
1119
            this.cboDataProfile.setSelectedIndex(-1);
1120
        } else {
1121
            ListElement.setSelected(this.cboDataProfile, profile);
1122
        }
1123

    
1124
        this.cboGroup.setModel(groupModel);
1125
        this.cboGroup.setSelectedItem(StringUtils.defaultIfBlank(descriptor.getGroup(), ""));
1126
        this.pickerOrder.set(descriptor.getOder());
1127
        this.chkHidden.setSelected(descriptor.isHidden());
1128
        if (descriptor.hasLabel()) {
1129
            this.txtLabel.setText(StringUtils.defaultIfBlank(descriptor.getLabel(), ""));
1130
        } else {
1131
            this.txtLabel.setText("");
1132
        }
1133
        if (descriptor.hasDescription()) {
1134
            this.txtDescription.setText(StringUtils.defaultIfBlank(descriptor.getDescription(), ""));
1135
        } else {
1136
            this.txtDescription.setText("");
1137
        }
1138
        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1139
        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1140
        if( descriptor.hasConstantAvailableValues() ) {
1141
          this.availableValuesController.set(descriptor.getAvailableValues());
1142
        } else {
1143
          this.availableValuesController.clean();
1144
        }
1145
        this.tagsController.setModel(new TagsModel(descriptor.getTags()));
1146

    
1147
        this.foreingKeyController.put(descriptor.getForeingKey());
1148
        
1149
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1150
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1151
        }
1152
        this.updateEditableStates();
1153
    }
1154

    
1155
    private DataType getDataType() {
1156
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1157
      if (fieldType == null) {
1158
          return null;
1159
      }
1160
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1161
      return dataType;
1162
    }
1163

    
1164
    private void doFieldTypeChanged() {
1165
      try {
1166
        DataType dataType = this.getDataType();
1167

    
1168
        if( dataType.supportSize() ) {
1169
            this.pickerSize.setEditable(this.mode == MODE_EDIT_ALL);
1170
        } else {
1171
            this.pickerSize.setEditable(false);
1172
            this.pickerSize.set(null);
1173
        }        
1174
        this.pickerDisplaySize.setEditable(this.mode == MODE_EDIT_ALL);
1175
        if( dataType.supportPrecision() ) {
1176
          if( dataType.isPredefinedPrecision() ) {
1177
            this.pickerPrecision.setEditable(false);
1178
          } else {
1179
            this.pickerPrecision.setEditable(this.mode == MODE_EDIT_ALL);
1180
          }
1181
        } else {
1182
            this.pickerPrecision.setEditable(false);
1183
            this.pickerPrecision.set(null);
1184
        }        
1185
        if( dataType.supportScale()) {
1186
            this.pickerScale.setEditable(this.mode == MODE_EDIT_ALL);
1187
        } else {
1188
            this.pickerScale.setEditable(false);
1189
            this.pickerScale.set(null);
1190
        }        
1191
        switch (dataType.getType()) {
1192
          case DataTypes.GEOMETRY:
1193
            this.cboGeometryType.setEnabled(this.mode == MODE_EDIT_ALL);
1194
            this.cboGeometrySubtype.setEnabled(this.mode == MODE_EDIT_ALL);
1195
            this.pickerCRS.setEditable(this.mode == MODE_EDIT_ALL);
1196
            this.cboDateFormat.setEnabled(false);
1197
            this.pickerIntervalStart.setEditable(false);
1198
            this.pickerIntervalEnd.setEditable(false);
1199
            this.tabAditionalFields.setEnabledAt(1, true);
1200
            this.tabAditionalFields.setEnabledAt(2, false);
1201
            break;
1202
          case DataTypes.INSTANT:
1203
          case DataTypes.INTERVAL:
1204
          case DataTypes.DATE:
1205
          case DataTypes.TIME:
1206
          case DataTypes.TIMESTAMP:
1207
            this.cboGeometryType.setEnabled(false);
1208
            this.cboGeometrySubtype.setEnabled(false);
1209
            this.pickerCRS.setEditable(false);
1210
            this.cboDateFormat.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1211
            this.pickerIntervalStart.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1212
            this.pickerIntervalEnd.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1213
            this.tabAditionalFields.setEnabledAt(1, false);
1214
            this.tabAditionalFields.setEnabledAt(2, true);
1215
            break;
1216
          case DataTypes.BYTE:
1217
          case DataTypes.INT:
1218
          case DataTypes.LONG:
1219
          case DataTypes.STRING:
1220
          case DataTypes.FILE:
1221
          case DataTypes.URL:
1222
          case DataTypes.URI:
1223
          case DataTypes.FLOAT:
1224
          case DataTypes.DOUBLE:
1225
          case DataTypes.DECIMAL:
1226
            this.cboGeometryType.setEnabled(false);
1227
            this.cboGeometrySubtype.setEnabled(false);
1228
            this.pickerCRS.setEditable(false);
1229
            this.cboDateFormat.setEnabled(false);
1230
            this.pickerIntervalStart.setEditable(false);
1231
            this.pickerIntervalEnd.setEditable(false);
1232
            this.tabAditionalFields.setEnabledAt(1, false);
1233
            this.tabAditionalFields.setEnabledAt(2, false);
1234
            break;
1235
          default:
1236
            this.cboGeometryType.setEnabled(false);
1237
            this.cboGeometrySubtype.setEnabled(false);
1238
            this.pickerCRS.setEditable(false);
1239
            this.cboDateFormat.setEnabled(false);
1240
            this.pickerIntervalStart.setEditable(false);
1241
            this.pickerIntervalEnd.setEditable(false);
1242
            this.tabAditionalFields.setEnabledAt(1, false);
1243
            this.tabAditionalFields.setEnabledAt(2, false);
1244
        }
1245
      } catch (Exception ex) {
1246
        LOGGER.warn("Problems changing field type.", ex);
1247
      }
1248

    
1249
    }
1250
    
1251
    boolean isVirtualField() {
1252
        return this.chkVirtualField.isSelected();
1253
    }
1254

    
1255
    @Override
1256
    public int getMode() {
1257
        return this.mode;
1258
    }
1259
    
1260
    @Override
1261
    public void setMode(int mode) {
1262
        this.mode = mode;
1263
        updateEditableStates();
1264
    }
1265
    
1266
    private void updateEditableStates() {
1267
        DataType dataType = this.getDataType();
1268
        switch(this.mode) {
1269
            case MODE_EDIT_ALL:
1270
                this.cboRelationType.setEnabled(true);
1271
                this.txtDefaultValue.setEditable(true);
1272
                this.txtFieldName.setEditable(true);
1273
                this.pickerIntervalEnd.setEditable(true);
1274
                this.pickerIntervalStart.setEditable(true);
1275
                this.pickerSize.setEditable(dataType.supportSize());
1276
                this.pickerDisplaySize.setEditable(true);
1277
                if( dataType.isPredefinedPrecision() ) {
1278
                  this.pickerPrecision.setEditable(false);
1279
                  this.pickerPrecision.set(dataType.getMaxPrecision());
1280
                } else {
1281
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
1282
                }
1283
                this.pickerScale.setEditable(dataType.supportScale());
1284
                this.cboDataProfile.setEnabled(true);
1285

    
1286
                this.chkAllowNulls.setEnabled(true);
1287
                this.chkIsAutomatic.setEnabled(true);
1288
                this.chkIsReadOnly.setEnabled(true);
1289
                this.chkIsIndexed.setEnabled(true);
1290
                if( this.isVirtualField() ) {
1291
                    this.chkIsPrimaryKey.setEnabled(false);
1292
                } else {
1293
                    this.chkIsPrimaryKey.setEnabled(true);
1294
                }
1295

    
1296
                this.chkVirtualField.setEnabled(true);
1297
                this.pickerVirtualField.setEditable(true);
1298

    
1299
                this.cboDateFormat.setEnabled(true);
1300
                this.cboFieldType.setEnabled(true);
1301
                this.cboGeometryType.setEnabled(true);
1302
                this.cboGeometrySubtype.setEnabled(true);
1303
                this.pickerCRS.setEditable(true);
1304

    
1305
                this.cboGroup.setEnabled(true);
1306
                this.pickerOrder.setEditable(true);
1307
                this.chkHidden.setEnabled(true);
1308
                this.txtLabel.setEditable(true);
1309
                this.txtDescription.setEditable(true);
1310
                this.txtMinValue.setEditable(false);
1311
                this.txtMaxValue.setEditable(false);
1312
                this.pickerValuesFilter.setEditable(true);
1313
                this.availableValuesController.setEditable(true);
1314
                this.tagsController.setEnabled(true);
1315
                this.foreingKeyController.setEditable(true);
1316
                break;
1317
            case MODE_EDIT_ONLY_METADATA:
1318
                if( this.chkVirtualField.isSelected() ) {
1319
                    this.txtFieldName.setEditable(true);
1320
                    this.pickerScale.setEditable(true);
1321
                    this.pickerSize.setEditable(true);
1322
                    this.pickerVirtualField.setEditable(true);
1323
                    this.cboFieldType.setEnabled(true);
1324
                    this.cboGeometryType.setEnabled(true);
1325
                    this.cboGeometrySubtype.setEnabled(true);
1326
                    this.pickerCRS.setEditable(true);
1327
                } else {
1328
                    this.txtFieldName.setEditable(false);
1329
                    this.pickerPrecision.setEditable(false);
1330
                    this.pickerScale.setEditable(false);
1331
                    this.pickerSize.setEditable(false);
1332
                    this.pickerVirtualField.setEditable(false);
1333
                    this.cboFieldType.setEnabled(false);
1334
                    this.cboGeometryType.setEnabled(false);
1335
                    this.cboGeometrySubtype.setEnabled(false);
1336
                    this.pickerCRS.setEditable(false);
1337
                }
1338

    
1339
                this.cboRelationType.setEnabled(true);
1340
                this.txtDefaultValue.setEditable(true);
1341
                this.pickerIntervalEnd.setEditable(true);
1342
                this.pickerIntervalStart.setEditable(true);
1343

    
1344
                this.cboDataProfile.setEnabled(true);
1345

    
1346
                this.pickerDisplaySize.setEditable(false);
1347
                this.chkAllowNulls.setEnabled(false);
1348
                this.chkIsAutomatic.setEnabled(false);
1349
                this.chkIsReadOnly.setEnabled(false);
1350
                this.chkIsIndexed.setEnabled(false);
1351
                if( this.isVirtualField() ) {
1352
                    this.chkIsPrimaryKey.setEnabled(false);
1353
                } else {
1354
                    this.chkIsPrimaryKey.setEnabled(true);
1355
                }
1356

    
1357
                this.chkVirtualField.setEnabled(false);
1358

    
1359
                this.cboDateFormat.setEnabled(true);
1360

    
1361
                this.cboGroup.setEnabled(true);
1362
                this.pickerOrder.setEditable(true);
1363
                this.chkHidden.setEnabled(true);
1364
                this.txtLabel.setEditable(true);
1365
                this.txtDescription.setEditable(true);
1366
                this.txtMinValue.setEditable(false);
1367
                this.txtMaxValue.setEditable(false);
1368
                this.pickerValuesFilter.setEditable(true);
1369
                this.availableValuesController.setEditable(true);
1370
                this.tagsController.setEnabled(true);
1371
                this.foreingKeyController.setEditable(true);
1372
                break;
1373
            case MODE_SHOW_ONLY:
1374
                this.cboRelationType.setEnabled(false);
1375
                this.txtDefaultValue.setEditable(false);
1376
                this.txtFieldName.setEditable(false);
1377
                this.pickerIntervalEnd.setEditable(false);
1378
                this.pickerIntervalStart.setEditable(false);
1379
                this.pickerPrecision.setEditable(false);
1380
                this.pickerScale.setEditable(false);
1381
                this.pickerSize.setEditable(false);
1382
                this.pickerDisplaySize.setEditable(false);
1383
                this.cboDataProfile.setEnabled(false);
1384

    
1385
                this.chkAllowNulls.setEnabled(false);
1386
                this.chkIsAutomatic.setEnabled(false);
1387
                this.chkIsReadOnly.setEnabled(false);
1388
                this.chkIsIndexed.setEnabled(false);
1389
                this.chkIsPrimaryKey.setEnabled(false);
1390

    
1391
                this.chkVirtualField.setEnabled(false);
1392
                this.pickerVirtualField.setEditable(false);
1393

    
1394
                this.cboDateFormat.setEnabled(false);
1395
                this.cboFieldType.setEnabled(false);
1396
                this.cboGeometryType.setEnabled(false);
1397
                this.cboGeometrySubtype.setEnabled(false);
1398
                this.pickerCRS.setEditable(false);
1399

    
1400
                this.cboGroup.setEnabled(false);
1401
                this.pickerOrder.setEditable(false);
1402
                this.chkHidden.setEnabled(false);
1403
                this.txtLabel.setEditable(false);
1404
                this.txtDescription.setEditable(false);
1405
                this.txtMinValue.setEditable(false);
1406
                this.txtMaxValue.setEditable(false);
1407
                this.pickerValuesFilter.setEditable(false);
1408
                this.availableValuesController.setEditable(false);
1409
                this.tagsController.setEnabled(false);
1410
                this.foreingKeyController.setEditable(false);
1411
                break;
1412
        }
1413
    }
1414

    
1415
    private void doCheckPrecisionAndScale() {
1416
      DataType dataType = this.getDataType();
1417
      
1418
      Integer precision = this.pickerPrecision.get();
1419
      if( precision==null ) {
1420
        precision = 0;
1421
      }
1422
      Integer scale = this.pickerScale.get();
1423
      if( scale == null ) {
1424
        scale = 0;
1425
      }      
1426
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
1427
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
1428
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
1429
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
1430
      } else {
1431
        this.pickerPrecision.setWarning(false);
1432
        this.pickerScale.setWarning(false);
1433
      }
1434
    }
1435

    
1436
    @Override
1437
    public void setNameAsNew(FeatureType featureType) {
1438
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
1439
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
1440
                cloneFeatureType.getNewFieldName(), 
1441
                DataTypes.STRING,
1442
                50);
1443
        this.put(newAttributeDescriptor);
1444
    }
1445

    
1446
    @Override
1447
    public String getName() {
1448
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
1449
    }
1450

    
1451
    @Override
1452
    public ImageIcon loadImage(String imageName) {
1453
        String name = FilenameUtils.getBaseName(imageName);
1454
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1455
        if (theme.exists(name)) {
1456
            return theme.get(name);
1457
        }
1458
        URL url = this.getClass().getResource(name + ".png");
1459
        if (url == null) {
1460
            return null;
1461
        }
1462
        return new ImageIcon(url);
1463
    }
1464

    
1465
  public static void selfRegister() {
1466
    String[][] iconNames = new String[][]{
1467
      new String[]{"dalswing", "picker-datatype"},};
1468
    IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1469
    for (String[] icon : iconNames) {
1470
      URL url = DefaultFeatureAttributeSelectionPanel.class.getResource(icon[1] + ".png");
1471
      theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1472
    }
1473
    
1474
  }
1475

    
1476
}