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 @ 45994

History | View | Annotate | Download (65.5 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 ExpressionPickerController pickerDefaultFormat;
442
    private CalculatorController<Integer> pickerOrder;
443
    private AvailableValuesController availableValuesController;
444
    private AggregateController<Tag> tagsController;
445
    private ForeingKeyController foreingKeyController;
446
    private ExpressionPickerController pickerValuesFilter;
447

    
448
    private int mode;
449
    private FeatureStoreElement featureStoreElement;
450

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

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

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

    
489
        this.initComponents();
490
    }
491

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

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

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

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

    
533
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
534

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

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

    
585
        swingManager.translate(this.txtDisplaySize);
586
        swingManager.translate(this.txtPrecision);
587
        swingManager.translate(this.txtScale);
588
        swingManager.translate(this.txtScale);
589

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

    
606
        swingManager.setDefaultPopupMenu(this.txtDefaultValue);
607
        swingManager.setDefaultPopupMenu(this.txtDefaultFormat);
608
        swingManager.setDefaultPopupMenu(this.txtFieldName);
609
        swingManager.setDefaultPopupMenu(this.txtIntervalEnd);
610
        swingManager.setDefaultPopupMenu(this.txtIntervalStart);
611
        swingManager.setDefaultPopupMenu(this.txtScale);
612
        swingManager.setDefaultPopupMenu(this.txtSize);
613
        swingManager.setDefaultPopupMenu(this.txtDisplaySize);
614
        swingManager.setDefaultPopupMenu(this.cboDateFormat);
615
        swingManager.setDefaultPopupMenu(this.cboFieldType);
616
        swingManager.setDefaultPopupMenu(this.cboGeometrySubtype);
617
        swingManager.setDefaultPopupMenu(this.cboGeometryType);
618
        swingManager.setDefaultPopupMenu(this.cboDataProfile);
619

    
620
        swingManager.setDefaultPopupMenu(this.cboForeingKeyCodeName);
621
        swingManager.setDefaultPopupMenu(this.cboForeingKeyTableName);
622

    
623
        swingManager.setDefaultPopupMenu(this.cboGroup);
624
        swingManager.setDefaultPopupMenu(this.txtOrder);
625
        swingManager.setDefaultPopupMenu(this.txtLabel);
626
        swingManager.setDefaultPopupMenu(this.txtDescription);
627
        swingManager.setDefaultPopupMenu(this.txtMinValue);
628
        swingManager.setDefaultPopupMenu(this.txtMaxValue);
629
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesLabel);
630
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesValue);
631

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

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

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

    
706
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
707
                this.txtCRS, this.btnCRS
708
        );
709

    
710
        this.cboFieldType.addItemListener((ItemEvent e) -> {
711
          SwingUtilities.invokeLater(() -> {
712
            doFieldTypeChanged();
713
          });
714
        });
715

    
716
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
717
          doCheckPrecisionAndScale();
718
        });
719
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
720
          doCheckPrecisionAndScale();
721
        });
722

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

    
742

    
743
        this.pickerValuesFilter = evaluatorSwingManager.createExpressionPickerController(
744
                txtValuesFilter, btnValuesFilter, btnValuesFilterBookmarks, btnValuesFilterHistory
745
        );
746
        this.pickerValuesFilter.addElement(this.featureStoreElement);
747

    
748
    }
749

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

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

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

    
956
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
957
        descriptor.setOrder(this.pickerOrder.get(0));
958
        descriptor.setHidden(this.chkHidden.isSelected());
959
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
960
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
961

    
962
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
963
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
964
        Expression valuesFilter = this.pickerValuesFilter.get();
965
        
966
        descriptor.setAvailableValues(this.availableValuesController.get());
967

    
968
        this.tagsController.getModel().fetch(descriptor.getTags());
969
        this.foreingKeyController.fetch(descriptor.getForeingKey());
970
        return descriptor;
971
    }
972

    
973
    @Override
974
    public void clean() {
975
        this.txtDefaultValue.setText("");
976
        this.txtDefaultFormat.setText("");
977
        this.txtFieldName.setText("");
978
//        this.pickerFieldName.set(null);
979
        this.pickerIntervalEnd.set(null);
980
        this.pickerIntervalStart.set(null);
981
        this.pickerScale.set(null);
982
        this.pickerSize.set(null);
983
        this.pickerDisplaySize.set(null);
984

    
985
        this.chkAllowNulls.setSelected(false);
986
        this.chkIsAutomatic.setSelected(false);
987
        this.chkIsReadOnly.setSelected(false);
988
        this.chkIsIndexed.setSelected(false);
989
        this.chkIsPrimaryKey.setSelected(false);
990

    
991
        this.chkVirtualField.setSelected(false);
992
        this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
993
        this.pickerVirtualField.setEditable(false);
994
        this.pickerVirtualField.set(null);
995

    
996
        ListElement.setSelected(cboGeometryType, null);
997
        ListElement.setSelected(cboGeometrySubtype, null);
998

    
999
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
1000

    
1001
        this.cboDataProfile.setSelectedIndex(-1);
1002

    
1003
        this.cboGroup.setSelectedIndex(-1);
1004
        this.pickerOrder.set(null);
1005
        this.chkHidden.setSelected(false);
1006
        this.txtLabel.setText("");
1007
        this.txtDescription.setText("");
1008
        this.txtMinValue.setText("");
1009
        this.txtMaxValue.setText("");
1010
        this.availableValuesController.clean();
1011
        this.tagsController.clean();
1012
        this.foreingKeyController.clean();
1013
    }
1014

    
1015
    @Override
1016
    public void put(FeatureAttributeDescriptor descriptor) {
1017
        if (descriptor == null) {
1018
            this.clean();
1019
            return;
1020
        }
1021
        DataType dataType = descriptor.getDataType();
1022
        FeatureType featureType = descriptor.getFeatureType();
1023
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
1024

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

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

    
1089
        this.pickerVirtualField.setEnabled(true);
1090
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1091
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1092
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1093
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1094
            this.chkVirtualField.setSelected(true);
1095
            this.pickerVirtualField.set(expression);
1096
        } else if (descriptor.isComputed()) {
1097
            this.chkVirtualField.setEnabled(false);
1098
            this.chkVirtualField.setSelected(true);
1099
            this.pickerVirtualField.set(null);
1100
        } else {
1101
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1102
            this.chkVirtualField.setSelected(false);
1103
            this.pickerVirtualField.set(null);
1104
        }
1105
        this.pickerVirtualField.setEnabled(true);
1106

    
1107
        Expression expression = descriptor.getAvailableValuesFilter();
1108
        this.pickerValuesFilter.set(expression);
1109

    
1110
        this.pickerCRS.set(descriptor.getSRS());
1111

    
1112
        if (descriptor.getGeomType() != null) {
1113
            ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1114
            ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1115
        }
1116
        ListElement.setSelected(cboFieldType, dataType.getType());
1117
        if( ListElement.getSelected(cboFieldType)==null ) {
1118
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1119
          ListElement.setSelected(cboFieldType, dataType.getType());
1120
        }
1121
 
1122
        ListElement.setSelected(cboRelationType, descriptor.getRelationType());
1123

    
1124
        String profile = descriptor.getDataProfileName();
1125
        if (StringUtils.isBlank(profile)) {
1126
            this.cboDataProfile.setSelectedIndex(-1);
1127
        } else {
1128
            ListElement.setSelected(this.cboDataProfile, profile);
1129
        }
1130

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

    
1154
        this.foreingKeyController.put(descriptor.getForeingKey());
1155
        
1156
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1157
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1158
        }
1159
        this.updateEditableStates();
1160
    }
1161

    
1162
    private DataType getDataType() {
1163
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1164
      if (fieldType == null) {
1165
          return null;
1166
      }
1167
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1168
      return dataType;
1169
    }
1170

    
1171
    private void doFieldTypeChanged() {
1172
      try {
1173
        DataType dataType = this.getDataType();
1174

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

    
1256
    }
1257
    
1258
    boolean isVirtualField() {
1259
        return this.chkVirtualField.isSelected();
1260
    }
1261

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

    
1294
                this.chkAllowNulls.setEnabled(true);
1295
                this.chkIsAutomatic.setEnabled(true);
1296
                this.chkIsReadOnly.setEnabled(true);
1297
                this.chkIsIndexed.setEnabled(true);
1298
                if( this.isVirtualField() ) {
1299
                    this.chkIsPrimaryKey.setEnabled(false);
1300
                } else {
1301
                    this.chkIsPrimaryKey.setEnabled(true);
1302
                }
1303

    
1304
                this.chkVirtualField.setEnabled(true);
1305
                this.pickerVirtualField.setEditable(true);
1306

    
1307
                this.cboDateFormat.setEnabled(true);
1308
                this.cboFieldType.setEnabled(true);
1309
                this.cboGeometryType.setEnabled(true);
1310
                this.cboGeometrySubtype.setEnabled(true);
1311
                this.pickerCRS.setEditable(true);
1312

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

    
1347
                this.cboRelationType.setEnabled(true);
1348
                this.txtDefaultValue.setEditable(true);
1349
                this.txtDefaultFormat.setEditable(true);
1350
                this.pickerIntervalEnd.setEditable(true);
1351
                this.pickerIntervalStart.setEditable(true);
1352

    
1353
                this.cboDataProfile.setEnabled(true);
1354

    
1355
                this.pickerDisplaySize.setEditable(false);
1356
                this.chkAllowNulls.setEnabled(false);
1357
                this.chkIsAutomatic.setEnabled(false);
1358
                this.chkIsReadOnly.setEnabled(false);
1359
                this.chkIsIndexed.setEnabled(false);
1360
                if( this.isVirtualField() ) {
1361
                    this.chkIsPrimaryKey.setEnabled(false);
1362
                } else {
1363
                    this.chkIsPrimaryKey.setEnabled(true);
1364
                }
1365

    
1366
                this.chkVirtualField.setEnabled(false);
1367

    
1368
                this.cboDateFormat.setEnabled(true);
1369

    
1370
                this.cboGroup.setEnabled(true);
1371
                this.pickerOrder.setEditable(true);
1372
                this.chkHidden.setEnabled(true);
1373
                this.txtLabel.setEditable(true);
1374
                this.txtDescription.setEditable(true);
1375
                this.txtMinValue.setEditable(false);
1376
                this.txtMaxValue.setEditable(false);
1377
                this.pickerValuesFilter.setEditable(true);
1378
                this.availableValuesController.setEditable(true);
1379
                this.tagsController.setEnabled(true);
1380
                this.foreingKeyController.setEditable(true);
1381
                break;
1382
            case MODE_SHOW_ONLY:
1383
                this.cboRelationType.setEnabled(false);
1384
                this.txtDefaultValue.setEditable(false);
1385
                this.txtDefaultFormat.setEditable(false);
1386
                this.txtFieldName.setEditable(false);
1387
                this.pickerIntervalEnd.setEditable(false);
1388
                this.pickerIntervalStart.setEditable(false);
1389
                this.pickerPrecision.setEditable(false);
1390
                this.pickerScale.setEditable(false);
1391
                this.pickerSize.setEditable(false);
1392
                this.pickerDisplaySize.setEditable(false);
1393
                this.cboDataProfile.setEnabled(false);
1394

    
1395
                this.chkAllowNulls.setEnabled(false);
1396
                this.chkIsAutomatic.setEnabled(false);
1397
                this.chkIsReadOnly.setEnabled(false);
1398
                this.chkIsIndexed.setEnabled(false);
1399
                this.chkIsPrimaryKey.setEnabled(false);
1400

    
1401
                this.chkVirtualField.setEnabled(false);
1402
                this.pickerVirtualField.setEditable(false);
1403

    
1404
                this.cboDateFormat.setEnabled(false);
1405
                this.cboFieldType.setEnabled(false);
1406
                this.cboGeometryType.setEnabled(false);
1407
                this.cboGeometrySubtype.setEnabled(false);
1408
                this.pickerCRS.setEditable(false);
1409

    
1410
                this.cboGroup.setEnabled(false);
1411
                this.pickerOrder.setEditable(false);
1412
                this.chkHidden.setEnabled(false);
1413
                this.txtLabel.setEditable(false);
1414
                this.txtDescription.setEditable(false);
1415
                this.txtMinValue.setEditable(false);
1416
                this.txtMaxValue.setEditable(false);
1417
                this.pickerValuesFilter.setEditable(false);
1418
                this.availableValuesController.setEditable(false);
1419
                this.tagsController.setEnabled(false);
1420
                this.foreingKeyController.setEditable(false);
1421
                break;
1422
        }
1423
    }
1424

    
1425
    private void doCheckPrecisionAndScale() {
1426
      DataType dataType = this.getDataType();
1427
      
1428
      Integer precision = this.pickerPrecision.get();
1429
      if( precision==null ) {
1430
        precision = 0;
1431
      }
1432
      Integer scale = this.pickerScale.get();
1433
      if( scale == null ) {
1434
        scale = 0;
1435
      }      
1436
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
1437
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
1438
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
1439
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
1440
      } else {
1441
        this.pickerPrecision.setWarning(false);
1442
        this.pickerScale.setWarning(false);
1443
      }
1444
    }
1445

    
1446
    @Override
1447
    public void setNameAsNew(FeatureType featureType) {
1448
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
1449
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
1450
                cloneFeatureType.getNewFieldName(), 
1451
                DataTypes.STRING,
1452
                50);
1453
        this.put(newAttributeDescriptor);
1454
    }
1455

    
1456
    @Override
1457
    public String getName() {
1458
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
1459
    }
1460

    
1461
    @Override
1462
    public ImageIcon loadImage(String imageName) {
1463
        String name = FilenameUtils.getBaseName(imageName);
1464
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1465
        if (theme.exists(name)) {
1466
            return theme.get(name);
1467
        }
1468
        URL url = this.getClass().getResource(name + ".png");
1469
        if (url == null) {
1470
            return null;
1471
        }
1472
        return new ImageIcon(url);
1473
    }
1474

    
1475
  public static void selfRegister() {
1476
    String[][] iconNames = new String[][]{
1477
      new String[]{"dalswing", "picker-datatype"},};
1478
    IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1479
    for (String[] icon : iconNames) {
1480
      URL url = DefaultFeatureAttributeSelectionPanel.class.getResource(icon[1] + ".png");
1481
      theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1482
    }
1483
    
1484
  }
1485

    
1486
}