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

History | View | Annotate | Download (63.7 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.geom.Geometry;
66
import org.gvsig.fmap.geom.GeometryLocator;
67
import org.gvsig.fmap.geom.GeometryManager;
68
import org.gvsig.fmap.geom.type.GeometryType;
69
import org.gvsig.timesupport.RelativeInterval;
70
import org.gvsig.tools.ToolsLocator;
71
import org.gvsig.tools.dataTypes.DataType;
72
import org.gvsig.tools.dataTypes.DataType.NumberPrecisionAndScale;
73
import org.gvsig.tools.dataTypes.DataTypesManager;
74
import org.gvsig.tools.dynobject.DynField;
75
import org.gvsig.tools.dynobject.DynObjectValueItem;
76
import org.gvsig.tools.i18n.I18nManager;
77
import org.gvsig.tools.swing.api.ListElement;
78
import org.gvsig.tools.swing.api.ToolsSwingLocator;
79
import org.gvsig.tools.swing.api.ToolsSwingManager;
80
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
81
import org.gvsig.tools.swing.api.pickercontroller.PickerController;
82
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
83
import org.gvsig.tools.swing.api.windowmanager.Dialog;
84
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
85
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
86
import org.gvsig.tools.swing.icontheme.IconTheme;
87
import org.slf4j.Logger;
88
import org.slf4j.LoggerFactory;
89

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

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

    
109
    private static class ForeingKeyController {
110

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

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

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

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

    
286
    private static class AvailableValuesController {
287

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

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

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

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

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

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

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

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

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

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

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

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

    
426
    }
427

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

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

    
446
    private int mode;
447
    private FeatureStoreElement featureStoreElement;
448

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

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

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

    
487
        this.initComponents();
488
    }
489

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

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

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

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

    
531
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
532

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

    
573
        swingManager.translate(this.lblForeingKeyCodeName);
574
        swingManager.translate(this.lblForeingKeyLabelFormula);
575
        swingManager.translate(this.lblForeingKeyTableName);
576
        swingManager.translate(this.lblIsClosedList);
577
        swingManager.translate(this.chkIsForeingKey);
578

    
579
        swingManager.translate(this.txtDisplaySize);
580
        swingManager.translate(this.txtPrecision);
581
        swingManager.translate(this.txtScale);
582
        swingManager.translate(this.txtScale);
583

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

    
599
        swingManager.setDefaultPopupMenu(this.txtDefaultValue);
600
        swingManager.setDefaultPopupMenu(this.txtFieldName);
601
        swingManager.setDefaultPopupMenu(this.txtIntervalEnd);
602
        swingManager.setDefaultPopupMenu(this.txtIntervalStart);
603
        swingManager.setDefaultPopupMenu(this.txtScale);
604
        swingManager.setDefaultPopupMenu(this.txtSize);
605
        swingManager.setDefaultPopupMenu(this.txtDisplaySize);
606
        swingManager.setDefaultPopupMenu(this.cboDateFormat);
607
        swingManager.setDefaultPopupMenu(this.cboFieldType);
608
        swingManager.setDefaultPopupMenu(this.cboGeometrySubtype);
609
        swingManager.setDefaultPopupMenu(this.cboGeometryType);
610
        swingManager.setDefaultPopupMenu(this.cboDataProfile);
611

    
612
        swingManager.setDefaultPopupMenu(this.cboForeingKeyCodeName);
613
        swingManager.setDefaultPopupMenu(this.cboForeingKeyTableName);
614

    
615
        swingManager.setDefaultPopupMenu(this.cboGroup);
616
        swingManager.setDefaultPopupMenu(this.txtOrder);
617
        swingManager.setDefaultPopupMenu(this.txtLabel);
618
        swingManager.setDefaultPopupMenu(this.txtDescription);
619
        swingManager.setDefaultPopupMenu(this.txtMinValue);
620
        swingManager.setDefaultPopupMenu(this.txtMaxValue);
621
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesLabel);
622
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesValue);
623

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

    
658
        this.availableValuesController = new AvailableValuesController(
659
                lstAvailableValues,
660
                txtAvailableValuesLabel,
661
                txtAvailableValuesValue,
662
                btnAvailableValuesAdd,
663
                btnAvailableValuesUpdate,
664
                btnAvailableValuesRemove,
665
                btnAvailableValuesRemoveAll
666
        );
667
        this.tagsController = new TagsController(
668
                tblTags,
669
                cboTagsName,
670
                cboTagsValue,
671
                btnTagsAdd,
672
                btnTagsUpdate,
673
                btnTagsRemove,
674
                lblTagsDescription
675
        );
676
        this.txtMinValue.setEnabled(false);
677
        this.txtMaxValue.setEnabled(false);
678

    
679
        this.btnVirtualField.setText("");
680
        this.featureStoreElement = dataSwingManager.createFeatureStoreElement();
681
        this.pickerVirtualField = evaluatorSwingManager.createExpressionPickerController(
682
                txtVirtualField, btnVirtualField, btnVirtualFieldBookmarks, btnVirtualFieldHistory
683
        );
684
        this.pickerVirtualField.addElement(this.featureStoreElement);
685
        this.chkVirtualField.addChangeListener((ChangeEvent e) -> {
686
          if (chkVirtualField.isSelected()) {
687
            pickerVirtualField.setEditable(mode==MODE_EDIT_ALL || mode==MODE_EDIT_ONLY_METADATA);
688
          } else {
689
            pickerVirtualField.setEditable(false);
690
          }
691
        });
692

    
693
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
694
                this.txtCRS, this.btnCRS
695
        );
696

    
697
        this.cboFieldType.addItemListener((ItemEvent e) -> {
698
          SwingUtilities.invokeLater(() -> {
699
            doFieldTypeChanged();
700
          });
701
        });
702

    
703
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
704
          doCheckPrecisionAndScale();
705
        });
706
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
707
          doCheckPrecisionAndScale();
708
        });
709

    
710
        DefaultComboBoxModel dataProfilesModel = new DefaultComboBoxModel<>();
711
        dataProfilesModel.addElement(new ListElement<>("", null));
712
        for (DataProfile profile : DALLocator.getDataManager().getDataProfiles()) {
713
            dataProfilesModel.addElement(new ListElement<>(profile.getName(), profile.getID()));
714
        }
715
        this.cboDataProfile.setModel(dataProfilesModel);
716
        
717
        this.btnFieldType.addActionListener((ActionEvent e) -> {
718
          doDataTypeSelection();
719
        });
720
        
721
        DefaultComboBoxModel<ListElement<Integer>> relationTypeModel = new DefaultComboBoxModel<>();
722
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_None"),DynField.RELATION_TYPE_NONE));
723
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Identity_1_1"),DynField.RELATION_TYPE_IDENTITY));
724
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Collaboration_1_1"),DynField.RELATION_TYPE_COLLABORATION));
725
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Composition_1_N"),DynField.RELATION_TYPE_COMPOSITION));
726
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Aggregate_1_N"),DynField.RELATION_TYPE_AGGREGATE));
727
        this.cboRelationType.setModel(relationTypeModel);
728

    
729

    
730
        this.pickerValuesFilter = evaluatorSwingManager.createExpressionPickerController(
731
                txtValuesFilter, btnValuesFilter, btnValuesFilterBookmarks, btnValuesFilterHistory
732
        );
733
        this.pickerValuesFilter.addElement(this.featureStoreElement);
734

    
735
    }
736

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

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

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

    
940
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
941
        descriptor.setOrder(this.pickerOrder.get(0));
942
        descriptor.setHidden(this.chkHidden.isSelected());
943
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
944
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
945

    
946
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
947
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
948
        Expression valuesFilter = this.pickerValuesFilter.get();
949
        
950
        descriptor.setAvailableValues(this.availableValuesController.get());
951

    
952
        this.tagsController.fetch(descriptor.getTags());
953
        this.foreingKeyController.fetch(descriptor.getForeingKey());
954
        return descriptor;
955
    }
956

    
957
    @Override
958
    public void clean() {
959
        this.txtDefaultValue.setText("");
960
        this.txtFieldName.setText("");
961
//        this.pickerFieldName.set(null);
962
        this.pickerIntervalEnd.set(null);
963
        this.pickerIntervalStart.set(null);
964
        this.pickerScale.set(null);
965
        this.pickerSize.set(null);
966
        this.pickerDisplaySize.set(null);
967

    
968
        this.chkAllowNulls.setSelected(false);
969
        this.chkIsAutomatic.setSelected(false);
970
        this.chkIsPrimaryKey.setSelected(false);
971

    
972
        this.chkVirtualField.setSelected(false);
973
        this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
974
        this.pickerVirtualField.setEditable(false);
975
        this.pickerVirtualField.set(null);
976

    
977
        ListElement.setSelected(cboGeometryType, null);
978
        ListElement.setSelected(cboGeometrySubtype, null);
979

    
980
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
981

    
982
        this.cboDataProfile.setSelectedIndex(-1);
983

    
984
        this.cboGroup.setSelectedIndex(-1);
985
        this.pickerOrder.set(null);
986
        this.chkHidden.setSelected(false);
987
        this.txtLabel.setText("");
988
        this.txtDescription.setText("");
989
        this.txtMinValue.setText("");
990
        this.txtMaxValue.setText("");
991
        this.availableValuesController.clean();
992
        this.tagsController.clean();
993
        this.foreingKeyController.clean();
994
    }
995

    
996
    @Override
997
    public void put(FeatureAttributeDescriptor descriptor) {
998
        if (descriptor == null) {
999
            this.clean();
1000
            return;
1001
        }
1002
        DataType dataType = descriptor.getDataType();
1003
        FeatureType featureType = descriptor.getFeatureType();
1004
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
1005

    
1006
        if (featureType != null) {
1007
            FeatureStore store = descriptor.getFeatureType().getStore();
1008
            this.featureStoreElement.setFeatureStore(store);
1009
            if (store != null) {
1010
                Feature sampleFeature = null;
1011
                try {
1012
                    sampleFeature = store.getFeatureSelection().first();
1013
                    if (sampleFeature == null) {
1014
                        sampleFeature = store.first();
1015
                    }
1016
                } catch (DataException ex) {
1017
                }
1018
                if (sampleFeature != null) {
1019
                    FeatureSymbolTable featureSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable();
1020
                    featureSymbolTable.setFeature(sampleFeature);
1021
                    this.pickerVirtualField.setPreviewSymbolTable(featureSymbolTable.createParent());
1022
                    this.pickerValuesFilter.setPreviewSymbolTable(featureSymbolTable.createParent());
1023
                }
1024
            }
1025
            List<String> groups = new ArrayList<>();
1026
            for (FeatureAttributeDescriptor otherdesc : featureType) {
1027
                String group = otherdesc.getGroup();
1028
                if (!StringUtils.isBlank(group) && !groups.contains(group)) {
1029
                    groups.add(group);
1030
                }
1031
            }
1032
            for (String group : groups) {
1033
                groupModel.addElement(group);
1034
            }
1035
        }
1036

    
1037
        this.txtDefaultValue.setText(Objects.toString(descriptor.getDefaultValue(),""));
1038
        this.txtFieldName.setText(descriptor.getName());
1039
        RelativeInterval interval = (RelativeInterval) descriptor.getInterval();
1040
        if (interval == null) {
1041
            this.pickerIntervalEnd.set(null);
1042
            this.pickerIntervalStart.set(null);
1043
        } else {
1044
            this.pickerIntervalEnd.set(interval.getEnd().toDate());
1045
            this.pickerIntervalStart.set(interval.getStart().toDate());
1046
        }
1047
        if( dataType.supportSize() ) {
1048
          this.pickerSize.set(descriptor.getSize());
1049
        } else {
1050
          this.pickerSize.set(null);
1051
        }
1052
        this.pickerDisplaySize.set(descriptor.getDisplaySize());
1053
        if( dataType.supportPrecision() ) {
1054
          this.pickerPrecision.set(descriptor.getPrecision());
1055
        } else {
1056
          this.pickerPrecision.set(null);
1057
        }
1058
        if( dataType.supportScale()) {
1059
          this.pickerScale.set(descriptor.getScale());
1060
        } else {
1061
          this.pickerScale.set(null);
1062
        }
1063
        this.chkAllowNulls.setSelected(descriptor.allowNull());
1064
        this.chkIsAutomatic.setSelected(descriptor.isAutomatic());
1065
        this.chkIsPrimaryKey.setSelected(descriptor.isPrimaryKey());
1066

    
1067
        this.pickerVirtualField.setEnabled(true);
1068
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1069
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1070
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1071
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1072
            this.chkVirtualField.setSelected(true);
1073
            this.pickerVirtualField.set(expression);
1074
        } else if (descriptor.isComputed()) {
1075
            this.chkVirtualField.setEnabled(false);
1076
            this.chkVirtualField.setSelected(true);
1077
            this.pickerVirtualField.set(null);
1078
        } else {
1079
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1080
            this.chkVirtualField.setSelected(false);
1081
            this.pickerVirtualField.set(null);
1082
        }
1083
        this.pickerVirtualField.setEnabled(true);
1084

    
1085
        Expression expression = descriptor.getAvailableValuesFilter();
1086
        this.pickerValuesFilter.set(expression);
1087

    
1088
        this.pickerCRS.set(descriptor.getSRS());
1089

    
1090
        if (descriptor.getGeomType() != null) {
1091
            ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1092
            ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1093
        }
1094
        ListElement.setSelected(cboFieldType, dataType.getType());
1095
        if( ListElement.getSelected(cboFieldType)==null ) {
1096
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1097
          ListElement.setSelected(cboFieldType, dataType.getType());
1098
        }
1099
 
1100
        ListElement.setSelected(cboRelationType, descriptor.getRelationType());
1101

    
1102
        String profile = descriptor.getDataProfileName();
1103
        if (StringUtils.isBlank(profile)) {
1104
            this.cboDataProfile.setSelectedIndex(-1);
1105
        } else {
1106
            ListElement.setSelected(this.cboDataProfile, profile);
1107
        }
1108

    
1109
        this.cboGroup.setModel(groupModel);
1110
        this.cboGroup.setSelectedItem(StringUtils.defaultIfBlank(descriptor.getGroup(), ""));
1111
        this.pickerOrder.set(descriptor.getOder());
1112
        this.chkHidden.setSelected(descriptor.isHidden());
1113
        if (descriptor.hasLabel()) {
1114
            this.txtLabel.setText(StringUtils.defaultIfBlank(descriptor.getLabel(), ""));
1115
        } else {
1116
            this.txtLabel.setText("");
1117
        }
1118
        if (descriptor.hasDescription()) {
1119
            this.txtDescription.setText(StringUtils.defaultIfBlank(descriptor.getDescription(), ""));
1120
        } else {
1121
            this.txtDescription.setText("");
1122
        }
1123
        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1124
        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1125
        if( descriptor.hasConstantAvailableValues() ) {
1126
          this.availableValuesController.set(descriptor.getAvailableValues());
1127
        } else {
1128
          this.availableValuesController.clean();
1129
        }
1130
        this.tagsController.set(descriptor.getTags());
1131

    
1132
        this.foreingKeyController.put(descriptor.getForeingKey());
1133
        
1134
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1135
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1136
        }
1137
        this.updateEditableStates();
1138
    }
1139

    
1140
    private DataType getDataType() {
1141
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1142
      if (fieldType == null) {
1143
          return null;
1144
      }
1145
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1146
      return dataType;
1147
    }
1148

    
1149
    private void doFieldTypeChanged() {
1150
      try {
1151
        DataType dataType = this.getDataType();
1152

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

    
1234
    }
1235
    
1236
    boolean isVirtualField() {
1237
        return this.chkVirtualField.isSelected();
1238
    }
1239

    
1240
    @Override
1241
    public int getMode() {
1242
        return this.mode;
1243
    }
1244
    
1245
    @Override
1246
    public void setMode(int mode) {
1247
        this.mode = mode;
1248
        updateEditableStates();
1249
    }
1250
    
1251
    private void updateEditableStates() {
1252
        DataType dataType = this.getDataType();
1253
        switch(this.mode) {
1254
            case MODE_EDIT_ALL:
1255
                this.cboRelationType.setEnabled(true);
1256
                this.txtDefaultValue.setEditable(true);
1257
                this.txtFieldName.setEditable(true);
1258
                this.pickerIntervalEnd.setEditable(true);
1259
                this.pickerIntervalStart.setEditable(true);
1260
                this.pickerSize.setEditable(dataType.supportSize());
1261
                this.pickerDisplaySize.setEditable(true);
1262
                if( dataType.isPredefinedPrecision() ) {
1263
                  this.pickerPrecision.setEditable(false);
1264
                  this.pickerPrecision.set(dataType.getMaxPrecision());
1265
                } else {
1266
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
1267
                }
1268
                this.pickerScale.setEditable(dataType.supportScale());
1269
                this.cboDataProfile.setEnabled(true);
1270

    
1271
                this.chkAllowNulls.setEnabled(true);
1272
                this.chkIsAutomatic.setEnabled(true);
1273
                if( this.isVirtualField() ) {
1274
                    this.chkIsPrimaryKey.setEnabled(false);
1275
                } else {
1276
                    this.chkIsPrimaryKey.setEnabled(true);
1277
                }
1278

    
1279
                this.chkVirtualField.setEnabled(true);
1280
                this.pickerVirtualField.setEditable(true);
1281

    
1282
                this.cboDateFormat.setEnabled(true);
1283
                this.cboFieldType.setEnabled(true);
1284
                this.cboGeometryType.setEnabled(true);
1285
                this.cboGeometrySubtype.setEnabled(true);
1286
                this.pickerCRS.setEditable(true);
1287

    
1288
                this.cboGroup.setEnabled(true);
1289
                this.pickerOrder.setEditable(true);
1290
                this.chkHidden.setEnabled(true);
1291
                this.txtLabel.setEditable(true);
1292
                this.txtDescription.setEditable(true);
1293
                this.txtMinValue.setEditable(false);
1294
                this.txtMaxValue.setEditable(false);
1295
                this.pickerValuesFilter.setEditable(true);
1296
                this.availableValuesController.setEditable(true);
1297
                this.tagsController.setEditable(true);
1298
                this.foreingKeyController.setEditable(true);
1299
                break;
1300
            case MODE_EDIT_ONLY_METADATA:
1301
                if( this.chkVirtualField.isSelected() ) {
1302
                    this.txtFieldName.setEditable(true);
1303
                    this.pickerScale.setEditable(true);
1304
                    this.pickerSize.setEditable(true);
1305
                    this.pickerVirtualField.setEditable(true);
1306
                    this.cboFieldType.setEnabled(true);
1307
                    this.cboGeometryType.setEnabled(true);
1308
                    this.cboGeometrySubtype.setEnabled(true);
1309
                    this.pickerCRS.setEditable(true);
1310
                } else {
1311
                    this.txtFieldName.setEditable(false);
1312
                    this.pickerPrecision.setEditable(false);
1313
                    this.pickerScale.setEditable(false);
1314
                    this.pickerSize.setEditable(false);
1315
                    this.pickerVirtualField.setEditable(false);
1316
                    this.cboFieldType.setEnabled(false);
1317
                    this.cboGeometryType.setEnabled(false);
1318
                    this.cboGeometrySubtype.setEnabled(false);
1319
                    this.pickerCRS.setEditable(false);
1320
                }
1321

    
1322
                this.cboRelationType.setEnabled(true);
1323
                this.txtDefaultValue.setEditable(true);
1324
                this.pickerIntervalEnd.setEditable(true);
1325
                this.pickerIntervalStart.setEditable(true);
1326

    
1327
                this.cboDataProfile.setEnabled(true);
1328

    
1329
                this.pickerDisplaySize.setEditable(false);
1330
                this.chkAllowNulls.setEnabled(false);
1331
                this.chkIsAutomatic.setEnabled(false);
1332
                if( this.isVirtualField() ) {
1333
                    this.chkIsPrimaryKey.setEnabled(false);
1334
                } else {
1335
                    this.chkIsPrimaryKey.setEnabled(true);
1336
                }
1337

    
1338
                this.chkVirtualField.setEnabled(false);
1339

    
1340
                this.cboDateFormat.setEnabled(true);
1341

    
1342
                this.cboGroup.setEnabled(true);
1343
                this.pickerOrder.setEditable(true);
1344
                this.chkHidden.setEnabled(true);
1345
                this.txtLabel.setEditable(true);
1346
                this.txtDescription.setEditable(true);
1347
                this.txtMinValue.setEditable(false);
1348
                this.txtMaxValue.setEditable(false);
1349
                this.pickerValuesFilter.setEditable(true);
1350
                this.availableValuesController.setEditable(true);
1351
                this.tagsController.setEditable(true);
1352
                this.foreingKeyController.setEditable(true);
1353
                break;
1354
            case MODE_SHOW_ONLY:
1355
                this.cboRelationType.setEnabled(false);
1356
                this.txtDefaultValue.setEditable(false);
1357
                this.txtFieldName.setEditable(false);
1358
                this.pickerIntervalEnd.setEditable(false);
1359
                this.pickerIntervalStart.setEditable(false);
1360
                this.pickerPrecision.setEditable(false);
1361
                this.pickerScale.setEditable(false);
1362
                this.pickerSize.setEditable(false);
1363
                this.pickerDisplaySize.setEditable(false);
1364
                this.cboDataProfile.setEnabled(false);
1365

    
1366
                this.chkAllowNulls.setEnabled(false);
1367
                this.chkIsAutomatic.setEnabled(false);
1368
                this.chkIsPrimaryKey.setEnabled(false);
1369

    
1370
                this.chkVirtualField.setEnabled(false);
1371
                this.pickerVirtualField.setEditable(false);
1372

    
1373
                this.cboDateFormat.setEnabled(false);
1374
                this.cboFieldType.setEnabled(false);
1375
                this.cboGeometryType.setEnabled(false);
1376
                this.cboGeometrySubtype.setEnabled(false);
1377
                this.pickerCRS.setEditable(false);
1378

    
1379
                this.cboGroup.setEnabled(false);
1380
                this.pickerOrder.setEditable(false);
1381
                this.chkHidden.setEnabled(false);
1382
                this.txtLabel.setEditable(false);
1383
                this.txtDescription.setEditable(false);
1384
                this.txtMinValue.setEditable(false);
1385
                this.txtMaxValue.setEditable(false);
1386
                this.pickerValuesFilter.setEditable(false);
1387
                this.availableValuesController.setEditable(false);
1388
                this.tagsController.setEditable(false);
1389
                this.foreingKeyController.setEditable(false);
1390
                break;
1391
        }
1392
    }
1393

    
1394
    private void doCheckPrecisionAndScale() {
1395
      DataType dataType = this.getDataType();
1396
      
1397
      Integer precision = this.pickerPrecision.get();
1398
      if( precision==null ) {
1399
        precision = 0;
1400
      }
1401
      Integer scale = this.pickerScale.get();
1402
      if( scale == null ) {
1403
        scale = 0;
1404
      }      
1405
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
1406
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
1407
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
1408
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
1409
      } else {
1410
        this.pickerPrecision.setWarning(false);
1411
        this.pickerScale.setWarning(false);
1412
      }
1413
    }
1414

    
1415
    @Override
1416
    public void setNameAsNew(FeatureType featureType) {
1417
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
1418
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
1419
                cloneFeatureType.getNewFieldName(), 
1420
                DataTypes.STRING,
1421
                50);
1422
        this.put(newAttributeDescriptor);
1423
    }
1424

    
1425
    @Override
1426
    public String getName() {
1427
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
1428
    }
1429

    
1430
    @Override
1431
    public ImageIcon loadImage(String imageName) {
1432
        String name = FilenameUtils.getBaseName(imageName);
1433
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1434
        if (theme.exists(name)) {
1435
            return theme.get(name);
1436
        }
1437
        URL url = this.getClass().getResource(name + ".png");
1438
        if (url == null) {
1439
            return null;
1440
        }
1441
        return new ImageIcon(url);
1442
    }
1443

    
1444
  public static void selfRegister() {
1445
    String[][] iconNames = new String[][]{
1446
      new String[]{"dalswing", "picker-datatype"},};
1447
    IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1448
    for (String[] icon : iconNames) {
1449
      URL url = DefaultFeatureAttributeSelectionPanel.class.getResource(icon[1] + ".png");
1450
      theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1451
    }
1452
    
1453
  }
1454

    
1455
}