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

History | View | Annotate | Download (65.8 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.dynform.spi.DynFormSPILocator;
78
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
79
import org.gvsig.tools.dynobject.DynField;
80
import org.gvsig.tools.dynobject.DynObjectValueItem;
81
import org.gvsig.tools.i18n.I18nManager;
82
import org.gvsig.tools.locator.ReferenceNotRegisteredException;
83
import org.gvsig.tools.swing.api.ListElement;
84
import org.gvsig.tools.swing.api.ToolsSwingLocator;
85
import org.gvsig.tools.swing.api.ToolsSwingManager;
86
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
87
import org.gvsig.tools.swing.api.pickercontroller.PickerController;
88
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
89
import org.gvsig.tools.swing.api.windowmanager.Dialog;
90
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
91
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
92
import org.gvsig.tools.swing.icontheme.IconTheme;
93
import org.slf4j.Logger;
94
import org.slf4j.LoggerFactory;
95

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

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

    
116
    private static class ForeingKeyController {
117

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

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

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

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

    
291
    private static class AvailableValuesController {
292

    
293
        private final JList lstValues;
294
        private final JTextComponent txtLabel;
295
        private final JTextComponent txtValue;
296
        private final JButton btnAdd;
297
        private final JButton btnUpdate;
298
        private final JButton btnRemove;
299
        private final JButton btnRemoveAll;
300

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

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

    
335
        public void clean() {
336
            this.lstValues.setModel(new DefaultListModel());
337
            this.txtLabel.setText("");
338
            this.txtValue.setText("");
339
            this.lstValues.setSelectedIndex(-1);
340
        }
341

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

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

    
369
        public void setEditable(boolean editable) {
370
            this.lstValues.setEnabled(editable);
371
            this.txtLabel.setEditable(editable);
372
            this.txtValue.setEditable(editable);
373
            this.btnAdd.setEnabled(editable);
374
            this.btnUpdate.setEnabled(editable);
375
            this.btnRemove.setEnabled(editable);
376
            this.btnRemoveAll.setEnabled(editable);
377
        }
378

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

    
396
        private void doAdd() {
397
            DynObjectValueItem value = new DynObjectValueItem("Value", "Label");
398
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
399
            model.addElement(value);
400
            this.lstValues.setSelectedIndex(model.getSize() - 1);
401
        }
402

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

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

    
425
        private void doRemoveAll() {
426
            DefaultListModel model = new DefaultListModel();
427
            this.lstValues.setModel(model);
428
            this.lstValues.setSelectedIndex(-1);
429
        }
430

    
431
    }
432

    
433
    private final List<ListElement<Integer>> fieldTypes;
434
    private final List<ListElement<Integer>> geometryTypes;
435
    private final List<ListElement<Integer>> geometrySubtypes;
436

    
437
    private DatePickerController pickerIntervalEnd;
438
    private DatePickerController pickerIntervalStart;
439
    private CalculatorController<Integer> pickerSize;
440
    private CalculatorController<Integer> pickerDisplaySize;
441
    private CalculatorController<Integer> pickerPrecision;
442
    private CalculatorController<Integer> pickerScale;
443
    private PickerController<IProjection> pickerCRS;
444
    private ExpressionPickerController pickerVirtualField;
445
    private ExpressionPickerController pickerDefaultFormat;
446
    private CalculatorController<Integer> pickerOrder;
447
    private AvailableValuesController availableValuesController;
448
    private AggregateController<Tag> tagsController;
449
    private ForeingKeyController foreingKeyController;
450
    private ExpressionPickerController pickerValuesFilter;
451

    
452
    private int mode;
453
    private FeatureStoreElement featureStoreElement;
454

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

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

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

    
493
        this.initComponents();
494
    }
495

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

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

    
526
        DefaultComboBoxModel<ListElement<Integer>> modelGeomTypes = new DefaultComboBoxModel<>();
527
        for (ListElement<Integer> element : this.geometryTypes) {
528
            modelGeomTypes.addElement(element);
529
        }
530
        this.cboGeometryType.setModel(modelGeomTypes);
531

    
532
        DefaultComboBoxModel<ListElement<Integer>> modelGeomSubtypes = new DefaultComboBoxModel<>();
533
        for (ListElement<Integer> element : this.geometrySubtypes) {
534
            modelGeomSubtypes.addElement(element);
535
        }
536

    
537
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
538

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

    
583
        swingManager.translate(this.lblForeingKeyCodeName);
584
        swingManager.translate(this.lblForeingKeyLabelFormula);
585
        swingManager.translate(this.lblForeingKeyTableName);
586
        swingManager.translate(this.lblIsClosedList);
587
        swingManager.translate(this.chkIsForeingKey);
588

    
589
        swingManager.translate(this.txtDisplaySize);
590
        swingManager.translate(this.txtPrecision);
591
        swingManager.translate(this.txtScale);
592
        swingManager.translate(this.txtScale);
593

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

    
610
        swingManager.setDefaultPopupMenu(this.txtDefaultValue);
611
        swingManager.setDefaultPopupMenu(this.txtDefaultFormat);
612
        swingManager.setDefaultPopupMenu(this.txtFieldName);
613
        swingManager.setDefaultPopupMenu(this.txtIntervalEnd);
614
        swingManager.setDefaultPopupMenu(this.txtIntervalStart);
615
        swingManager.setDefaultPopupMenu(this.txtScale);
616
        swingManager.setDefaultPopupMenu(this.txtSize);
617
        swingManager.setDefaultPopupMenu(this.txtDisplaySize);
618
        swingManager.setDefaultPopupMenu(this.cboDateFormat);
619
        swingManager.setDefaultPopupMenu(this.cboFieldType);
620
        swingManager.setDefaultPopupMenu(this.cboGeometrySubtype);
621
        swingManager.setDefaultPopupMenu(this.cboGeometryType);
622
        swingManager.setDefaultPopupMenu(this.cboDataProfile);
623

    
624
        swingManager.setDefaultPopupMenu(this.cboForeingKeyCodeName);
625
        swingManager.setDefaultPopupMenu(this.cboForeingKeyTableName);
626

    
627
        swingManager.setDefaultPopupMenu(this.cboGroup);
628
        swingManager.setDefaultPopupMenu(this.txtOrder);
629
        swingManager.setDefaultPopupMenu(this.txtLabel);
630
        swingManager.setDefaultPopupMenu(this.txtDescription);
631
        swingManager.setDefaultPopupMenu(this.txtMinValue);
632
        swingManager.setDefaultPopupMenu(this.txtMaxValue);
633
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesLabel);
634
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesValue);
635

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

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

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

    
710
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
711
                this.txtCRS, this.btnCRS
712
        );
713

    
714
        this.cboFieldType.addItemListener((ItemEvent e) -> {
715
          SwingUtilities.invokeLater(() -> {
716
            doFieldTypeChanged();
717
          });
718
        });
719

    
720
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
721
          doCheckPrecisionAndScale();
722
        });
723
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
724
          doCheckPrecisionAndScale();
725
        });
726

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

    
746

    
747
        this.pickerValuesFilter = evaluatorSwingManager.createExpressionPickerController(
748
                txtValuesFilter, btnValuesFilter, btnValuesFilterBookmarks, btnValuesFilterHistory
749
        );
750
        this.pickerValuesFilter.addElement(this.featureStoreElement);
751

    
752
    }
753

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

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

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

    
960
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
961
        descriptor.setOrder(this.pickerOrder.get(0));
962
        descriptor.setHidden(this.chkHidden.isSelected());
963
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
964
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
965

    
966
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
967
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
968
        Expression valuesFilter = this.pickerValuesFilter.get();
969
        
970
        descriptor.setAvailableValues(this.availableValuesController.get());
971

    
972
        this.tagsController.getModel().fetch(descriptor.getTags());
973
        this.foreingKeyController.fetch(descriptor.getForeingKey());
974
        return descriptor;
975
    }
976

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

    
989
        this.chkAllowNulls.setSelected(false);
990
        this.chkIsAutomatic.setSelected(false);
991
        this.chkIsReadOnly.setSelected(false);
992
        this.chkIsIndexed.setSelected(false);
993
        this.chkIsPrimaryKey.setSelected(false);
994

    
995
        this.chkVirtualField.setSelected(false);
996
        this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
997
        this.pickerVirtualField.setEditable(false);
998
        this.pickerVirtualField.set(null);
999

    
1000
        ListElement.setSelected(cboGeometryType, null);
1001
        ListElement.setSelected(cboGeometrySubtype, null);
1002

    
1003
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
1004

    
1005
        this.cboDataProfile.setSelectedIndex(-1);
1006

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

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

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

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

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

    
1111
        Expression expression = descriptor.getAvailableValuesFilter();
1112
        this.pickerValuesFilter.set(expression);
1113

    
1114
        this.pickerCRS.set(descriptor.getSRS());
1115

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

    
1128
        String profile = descriptor.getDataProfileName();
1129
        if (StringUtils.isBlank(profile)) {
1130
            this.cboDataProfile.setSelectedIndex(-1);
1131
        } else {
1132
            ListElement.setSelected(this.cboDataProfile, profile);
1133
        }
1134

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

    
1158
        this.foreingKeyController.put(descriptor.getForeingKey());
1159
        
1160
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1161
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1162
        }
1163
        this.updateEditableStates();
1164
    }
1165

    
1166
    private DataType getDataType() {
1167
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1168
      if (fieldType == null) {
1169
          return null;
1170
      }
1171
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1172
      return dataType;
1173
    }
1174

    
1175
    private void doFieldTypeChanged() {
1176
      try {
1177
        DataType dataType = this.getDataType();
1178

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

    
1260
    }
1261
    
1262
    boolean isVirtualField() {
1263
        return this.chkVirtualField.isSelected();
1264
    }
1265

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

    
1298
                this.chkAllowNulls.setEnabled(true);
1299
                this.chkIsAutomatic.setEnabled(true);
1300
                this.chkIsReadOnly.setEnabled(true);
1301
                this.chkIsIndexed.setEnabled(true);
1302
                if( this.isVirtualField() ) {
1303
                    this.chkIsPrimaryKey.setEnabled(false);
1304
                } else {
1305
                    this.chkIsPrimaryKey.setEnabled(true);
1306
                }
1307

    
1308
                this.chkVirtualField.setEnabled(true);
1309
                this.pickerVirtualField.setEditable(true);
1310

    
1311
                this.cboDateFormat.setEnabled(true);
1312
                this.cboFieldType.setEnabled(true);
1313
                this.cboGeometryType.setEnabled(true);
1314
                this.cboGeometrySubtype.setEnabled(true);
1315
                this.pickerCRS.setEditable(true);
1316

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

    
1351
                this.cboRelationType.setEnabled(true);
1352
                this.txtDefaultValue.setEditable(true);
1353
                this.txtDefaultFormat.setEditable(true);
1354
                this.pickerIntervalEnd.setEditable(true);
1355
                this.pickerIntervalStart.setEditable(true);
1356

    
1357
                this.cboDataProfile.setEnabled(true);
1358

    
1359
                this.pickerDisplaySize.setEditable(false);
1360
                this.chkAllowNulls.setEnabled(false);
1361
                this.chkIsAutomatic.setEnabled(false);
1362
                this.chkIsReadOnly.setEnabled(false);
1363
                this.chkIsIndexed.setEnabled(false);
1364
                if( this.isVirtualField() ) {
1365
                    this.chkIsPrimaryKey.setEnabled(false);
1366
                } else {
1367
                    this.chkIsPrimaryKey.setEnabled(true);
1368
                }
1369

    
1370
                this.chkVirtualField.setEnabled(false);
1371

    
1372
                this.cboDateFormat.setEnabled(true);
1373

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

    
1399
                this.chkAllowNulls.setEnabled(false);
1400
                this.chkIsAutomatic.setEnabled(false);
1401
                this.chkIsReadOnly.setEnabled(false);
1402
                this.chkIsIndexed.setEnabled(false);
1403
                this.chkIsPrimaryKey.setEnabled(false);
1404

    
1405
                this.chkVirtualField.setEnabled(false);
1406
                this.pickerVirtualField.setEditable(false);
1407

    
1408
                this.cboDateFormat.setEnabled(false);
1409
                this.cboFieldType.setEnabled(false);
1410
                this.cboGeometryType.setEnabled(false);
1411
                this.cboGeometrySubtype.setEnabled(false);
1412
                this.pickerCRS.setEditable(false);
1413

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

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

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

    
1460
    @Override
1461
    public String getName() {
1462
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
1463
    }
1464

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

    
1479
  public static void selfRegister() {
1480
    IconTheme theme;
1481
    try {
1482
        theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1483
    } catch(ReferenceNotRegisteredException ex) {
1484
        return;
1485
    }
1486
    String[][] iconNames = new String[][]{
1487
      new String[]{"dalswing", "picker-datatype"},};
1488
    for (String[] icon : iconNames) {
1489
      URL url = DefaultFeatureAttributeSelectionPanel.class.getResource(icon[1] + ".png");
1490
      theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1491
    }
1492
    
1493
  }
1494

    
1495
}