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

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

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

    
98
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureAttributePanel.class);
99

    
100
    private static class ForeingKeyController {
101

    
102
        private final JCheckBox chkIsForeingKey;
103
        private final JCheckBox chkIsClosedList;
104
        private final JComboBox cboTable;
105
        private final JComboBox cboCode;
106
        private final JTextField txtFormula;
107
        private final JButton btnFormula;
108
        private ExpressionPickerController pickerFormula;
109
        private boolean editable;
110
        private FeatureStoreElement featureStoreElement;
111
        private ForeingKey foreingKey;
112
        
113
        public ForeingKeyController(
114
                JCheckBox chkIsForeingKey,
115
                JCheckBox chkIsClosedList,
116
                JComboBox cboTable,
117
                JComboBox cboCode,
118
                JTextField txtFormula,
119
                JButton btnFormula
120
        ) {
121
            this.chkIsForeingKey = chkIsForeingKey;
122
            this.chkIsClosedList = chkIsClosedList;
123
            this.cboTable = cboTable;
124
            this.cboCode = cboCode;
125
            this.txtFormula = txtFormula;
126
            this.btnFormula = btnFormula;
127
            this.initComponents();
128
        }
129

    
130
        private void initComponents() {
131
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
132
    
133
            this.editable = true;
134
            
135
            DefaultComboBoxModel<String> model = new DefaultComboBoxModel();
136
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
137
            for (String tableName : repository.keySet()) {
138
                model.addElement(tableName);
139
            }
140
            this.cboTable.setModel(model);
141
            this.cboTable.addItemListener((ItemEvent e) -> {
142
              if (e.getStateChange() != ItemEvent.SELECTED) {
143
                return;
144
              }
145
              Thread th = new Thread(() -> {
146
                doPopulateComboCode();
147
              }, "FeatureTypePanelForeingKeyPopulateComboCode");
148
              th.start();
149
            });
150
            this.btnFormula.setText("");
151
            this.featureStoreElement = dataSwingManager.createFeatureStoreElement();
152
            this.pickerFormula = ExpressionEvaluatorSwingLocator.getManager()
153
                    .createExpressionPickerController(txtFormula, btnFormula);
154
            this.pickerFormula.addElement(this.featureStoreElement);
155
            
156
//            this.chkIsForeingKey.addChangeListener(new ChangeListener() {
157
//                @Override
158
//                public void stateChanged(ChangeEvent e) {
159
//                    if (chkIsForeingKey.isSelected()) {
160
//                        setEnabled(editable);
161
//                    } else {
162
//                        setEnabled(false);
163
//                    }
164
//                }
165
//            });
166
        }
167

    
168
        private void doPopulateComboCode() {
169
            String tableName = (String) this.cboTable.getSelectedItem();
170
            if( StringUtils.isBlank(tableName) ) {
171
                return;
172
            }
173
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
174
            DataStore store = repository.getStore(tableName);
175
            if( !(store instanceof FeatureStore) ) {
176
                return;
177
            }
178
            this.featureStoreElement.setFeatureStore((FeatureStore) store);
179
            FeatureType featureType;
180
            try {
181
                featureType = ((FeatureStore)store).getDefaultFeatureType();
182
            } catch (DataException ex) {
183
                return;
184
            }
185
            Search search = (Search) ToolsLocator.getComplementsManager().get(
186
                    Search.COMPLEMENT_MANE, featureType
187
            );
188
            List<Search.OrderedAttribute> attributes = search.getOrderedAttributes(
189
                    Search.BASIC_TYPES_FILTER,
190
                    Search.LABEL_ORDER, 
191
                    -1
192
            );
193
            final DefaultComboBoxModel model = new DefaultComboBoxModel();
194
            for (Search.OrderedAttribute attribute : attributes) {
195
                model.addElement(attribute.getDescriptor().getName());
196
            }
197
            SwingUtilities.invokeLater(() -> {
198
              cboCode.setModel(model);
199
              cboCode.setSelectedItem(foreingKey.getCodeName());
200
            });
201
        }
202

    
203
        public void setEditable(boolean editable) {
204
            this.chkIsForeingKey.setEnabled(editable);
205
            this.chkIsClosedList.setEnabled(editable);
206
            this.cboTable.setEnabled(editable);
207
            this.cboCode.setEnabled(editable);
208
            this.btnFormula.setEnabled(editable);
209
            this.txtFormula.setEditable(editable);
210
            this.editable = editable;
211
        }
212
        
213
        public void setEnabled(boolean enabled) {
214
            if( !editable ) {
215
                enabled =  false;
216
            }
217
            this.chkIsForeingKey.setEnabled(enabled);
218
            this.chkIsClosedList.setEnabled(enabled);
219
            this.cboTable.setEnabled(enabled);
220
            this.cboCode.setEnabled(enabled);
221
            this.btnFormula.setEnabled(enabled);
222
            this.txtFormula.setEnabled(enabled);
223
        }
224
        
225
        public void clean() {
226
            this.chkIsForeingKey.setSelected(false);
227
            this.chkIsClosedList.setSelected(false);
228
            this.cboTable.setSelectedItem("");
229
            this.cboCode.setSelectedItem("");
230
            this.pickerFormula.set(null);
231
        }
232
        
233
        public void put(ForeingKey foreingKey) {
234
            if( foreingKey==null ) {
235
                this.clean();
236
                return;
237
            }
238
            this.foreingKey = foreingKey;
239
            this.chkIsForeingKey.setSelected(foreingKey.isForeingKey());
240
            this.chkIsClosedList.setSelected(foreingKey.isClosedList());
241
            this.cboTable.setSelectedItem(foreingKey.getTableName());
242
            this.cboCode.setSelectedItem(foreingKey.getCodeName());
243
            this.pickerFormula.set(foreingKey.getLabelExpression(null));
244
        }
245
        
246
        public void fetch(EditableForeingKey foreingKey) {
247
            if( foreingKey==null ) {
248
                return;
249
            }
250
            foreingKey.setForeingKey(this.chkIsForeingKey.isSelected());
251
            foreingKey.setClosedList(this.chkIsClosedList.isSelected());
252
            foreingKey.setTableName((String) this.cboTable.getSelectedItem());
253
            foreingKey.setCodeName((String) this.cboCode.getSelectedItem());
254
            Expression exp = this.pickerFormula.get();
255
            if( ExpressionUtils.isPhraseEmpty(exp) ) {
256
                foreingKey.setLabelFormula("");
257
            } else {
258
                foreingKey.setLabelFormula(exp.getPhrase());
259
            }
260
        }
261
    }
262
    
263

    
264
    private static class AvailableValuesController {
265

    
266
        private final JList lstValues;
267
        private final JTextComponent txtLabel;
268
        private final JTextComponent txtValue;
269
        private final JButton btnAdd;
270
        private final JButton btnUpdate;
271
        private final JButton btnRemove;
272
        private final JButton btnRemoveAll;
273

    
274
        public AvailableValuesController(
275
                JList lstValues,
276
                JTextComponent txtLabel,
277
                JTextComponent txtValue,
278
                JButton btnAdd,
279
                JButton btnUpdate,
280
                JButton btnRemove,
281
                JButton btnRemoveAll
282
        ) {
283
            this.lstValues = lstValues;
284
            this.txtLabel = txtLabel;
285
            this.txtValue = txtValue;
286
            this.btnAdd = btnAdd;
287
            this.btnUpdate = btnUpdate;
288
            this.btnRemove = btnRemove;
289
            this.btnRemoveAll = btnRemoveAll;
290

    
291
            this.lstValues.addListSelectionListener((ListSelectionEvent e) -> {
292
              doValuesChanged();
293
            });
294
            this.btnAdd.addActionListener((ActionEvent e) -> {
295
              doAdd();
296
            });
297
            this.btnUpdate.addActionListener((ActionEvent e) -> {
298
              doUpdate();
299
            });
300
            this.btnRemove.addActionListener((ActionEvent e) -> {
301
              doRemove();
302
            });
303
            this.btnRemoveAll.addActionListener((ActionEvent e) -> {
304
              doRemoveAll();
305
            });
306
        }
307

    
308
        public void clean() {
309
            this.lstValues.setModel(new DefaultListModel());
310
            this.txtLabel.setText("");
311
            this.txtValue.setText("");
312
            this.lstValues.setSelectedIndex(-1);
313
        }
314

    
315
        public DynObjectValueItem[] get() {
316
            ListModel<DynObjectValueItem> model = this.lstValues.getModel();
317
            if( model.getSize()==0 ) {
318
              return null;
319
            }
320
            DynObjectValueItem[] values = new DynObjectValueItem[model.getSize()];
321
            for (int i = 0; i < model.getSize(); i++) {
322
                values[i] = model.getElementAt(i);
323
            }
324
            return values;
325
        }
326

    
327
        public void set(DynObjectValueItem[] availableValues) {
328
            DefaultListModel model = new DefaultListModel();
329
            if (availableValues != null) {
330
                for (DynObjectValueItem availableValue : availableValues) {
331
                    model.addElement(availableValue);
332
                }
333
            }
334
            this.lstValues.setModel(model);
335
            if (model.getSize() > 0) {
336
                this.lstValues.setSelectedIndex(0);
337
            } else {
338
                this.lstValues.setSelectedIndex(-1);
339
            }
340
        }
341

    
342
        public void setEditable(boolean editable) {
343
            this.lstValues.setEnabled(editable);
344
            this.txtLabel.setEditable(editable);
345
            this.txtValue.setEditable(editable);
346
            this.btnAdd.setEnabled(editable);
347
            this.btnUpdate.setEnabled(editable);
348
            this.btnRemove.setEnabled(editable);
349
            this.btnRemoveAll.setEnabled(editable);
350
        }
351

    
352
        private void doValuesChanged() {
353
            DynObjectValueItem value = (DynObjectValueItem) this.lstValues.getSelectedValue();
354
            if (value == null) {
355
                this.txtLabel.setText("");
356
                this.txtValue.setText("");
357
                this.btnAdd.setEnabled(true);
358
                this.btnUpdate.setEnabled(false);
359
                this.btnRemove.setEnabled(false);
360
                return;
361
            }
362
            this.txtLabel.setText(value.getLabel());
363
            this.txtValue.setText(Objects.toString(value.getValue(), ""));
364
            this.btnAdd.setEnabled(true);
365
            this.btnUpdate.setEnabled(true);
366
            this.btnRemove.setEnabled(true);
367
        }
368

    
369
        private void doAdd() {
370
            DynObjectValueItem value = new DynObjectValueItem("Value", "Label");
371
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
372
            model.addElement(value);
373
            this.lstValues.setSelectedIndex(model.getSize() - 1);
374
        }
375

    
376
        private void doUpdate() {
377
            DynObjectValueItem value = (DynObjectValueItem) this.lstValues.getSelectedValue();
378
            if (value == null) {
379
                return; // EEhh?? esto no deberia pasar
380
            }
381
            value.setLabel(this.txtLabel.getText());
382
            value.setValue(this.txtValue.getText());
383
        }
384

    
385
        private void doRemove() {
386
            int n = this.lstValues.getSelectedIndex();
387
            if (n < 0) {
388
                return; // EEhh?? esto no deberia pasar
389
            }
390
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
391
            model.removeElementAt(n);
392
            if (--n < 0) {
393
                n = 0;
394
            }
395
            this.lstValues.setSelectedIndex(n);
396
        }
397

    
398
        private void doRemoveAll() {
399
            DefaultListModel model = new DefaultListModel();
400
            this.lstValues.setModel(model);
401
            this.lstValues.setSelectedIndex(-1);
402
        }
403

    
404
    }
405

    
406
    private final List<ListElement<Integer>> fieldTypes;
407
    private final List<ListElement<Integer>> geometryTypes;
408
    private final List<ListElement<Integer>> geometrySubtypes;
409

    
410
    private DatePickerController pickerIntervalEnd;
411
    private DatePickerController pickerIntervalStart;
412
    private CalculatorController<Integer> pickerSize;
413
    private CalculatorController<Integer> pickerRequiredBytes;
414
    private CalculatorController<Integer> pickerPrecision;
415
    private CalculatorController<Integer> pickerScale;
416
    private CalculatorController<Object> pickerDefaultValue;
417
    private PickerController<IProjection> pickerCRS;
418
    private ExpressionPickerController pickerVirtualField;
419
    private CalculatorController<Integer> pickerOrder;
420
    private AvailableValuesController availableValuesController;
421
    private TagsController tagsController;
422
    private ForeingKeyController foreingKeyController;
423

    
424
    private int mode;
425
    private FeatureStoreElement featureStoreElement;
426

    
427
    public DefaultFeatureAttributePanel() {
428
        this.mode = FeatureTypePanel.MODE_SHOW_ONLY;
429
        DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
430
        this.fieldTypes = new ArrayList<>();
431
        fieldTypes.add( new ListElement<>("Decimal", DataTypes.DECIMAL) );
432
        fieldTypes.add( new ListElement<>("Integer", DataTypes.INTEGER) );
433
        fieldTypes.add( new ListElement<>("String", DataTypes.STRING) );
434
        fieldTypes.add( new ListElement<>("Boolean", DataTypes.BOOLEAN) );
435
        fieldTypes.add( new ListElement<>("Date/Time", DataTypes.TIMESTAMP) );
436
//        for (DataType dataType : dataManager) {
437
//            fieldTypes.add( new ListElement<>(dataType.getName(), dataType.getType()) );
438
//        }
439
        fieldTypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
440
                o1.toString().compareTo(o2.toString())
441
        );
442

    
443
        this.geometryTypes = new ArrayList<>();
444
        this.geometryTypes.add(new ListElement("Point", Geometry.TYPES.POINT));
445
        this.geometryTypes.add(new ListElement("Line", Geometry.TYPES.LINE));
446
        this.geometryTypes.add(new ListElement("Polygon", Geometry.TYPES.POLYGON));
447
        this.geometryTypes.add(new ListElement("MultiPoint", Geometry.TYPES.MULTIPOINT));
448
        this.geometryTypes.add(new ListElement("MultiLine", Geometry.TYPES.MULTILINE));
449
        this.geometryTypes.add(new ListElement("MultiPolygon", Geometry.TYPES.MULTIPOLYGON));
450
        this.geometryTypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
451
                  o1.toString().compareTo(o2.toString())
452
        );
453

    
454
        this.geometrySubtypes = new ArrayList<>();
455
        this.geometrySubtypes.add(new ListElement("2D", Geometry.SUBTYPES.GEOM2D));
456
        this.geometrySubtypes.add(new ListElement("2DM", Geometry.SUBTYPES.GEOM3D));
457
        this.geometrySubtypes.add(new ListElement("3D", Geometry.SUBTYPES.GEOM2DM));
458
        this.geometrySubtypes.add(new ListElement("3DM", Geometry.SUBTYPES.GEOM3DM));
459
        this.geometrySubtypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
460
                o1.toString().compareTo(o2.toString())
461
        );
462

    
463
        this.initComponents();
464
    }
465

    
466
    private void initComponents() {
467
        final ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
468
        final ExpressionEvaluatorSwingManager evaluatorManager = ExpressionEvaluatorSwingLocator.getManager();
469
        final DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
470
        final I18nManager i18n = ToolsLocator.getI18nManager();
471
        final DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
472

    
473
        DefaultComboBoxModel<ListElement<Integer>> modelTypes = new DefaultComboBoxModel<>();
474
        for (ListElement<Integer> element : fieldTypes) {
475
            modelTypes.addElement(element);
476
        }
477
        this.cboFieldType.setModel(modelTypes);
478
        this.cboFieldType.setRenderer(new DefaultListCellRenderer() {
479
          @Override
480
          public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
481
              JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
482
              label.setIcon(null);
483
              try {
484
                DataType dataType = dataTypeManager.get((int) value);
485
                IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
486
                if (theme.exists(dataType.getIconName())) {
487
                    label.setIcon(theme.get(dataType.getIconName()));
488
                }
489
              } catch(Exception ex) {
490
                // Do nothing, ignore
491
              }
492
              return label;
493
          }
494
        });
495

    
496
        DefaultComboBoxModel<ListElement<Integer>> modelGeomTypes = new DefaultComboBoxModel<>();
497
        for (ListElement<Integer> element : this.geometryTypes) {
498
            modelGeomTypes.addElement(element);
499
        }
500
        this.cboGeometryType.setModel(modelGeomTypes);
501

    
502
        DefaultComboBoxModel<ListElement<Integer>> modelGeomSubtypes = new DefaultComboBoxModel<>();
503
        for (ListElement<Integer> element : this.geometrySubtypes) {
504
            modelGeomSubtypes.addElement(element);
505
        }
506

    
507
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
508

    
509
        swingManager.translate(this.lblAllowNulls);
510
        swingManager.translate(this.lblCRS);
511
        swingManager.translate(this.lblDataProfile);
512
        swingManager.translate(this.lblDateFormat);
513
        swingManager.translate(this.lblDefaultValue);
514
        swingManager.translate(this.lblFieldName);
515
        swingManager.translate(this.lblFieldType);
516
        swingManager.translate(this.lblGeometrySubtype);
517
        swingManager.translate(this.lblGeometryType);
518
        swingManager.translate(this.lblInterval);
519
        swingManager.translate(this.lblIntervalEnd);
520
        swingManager.translate(this.lblIntervalStart);
521
        swingManager.translate(this.lblIsAutomatic);
522
        swingManager.translate(this.lblIsPrimaryKey);
523
        swingManager.translate(this.lblPrecision);
524
        swingManager.translate(this.lblScale);
525
        swingManager.translate(this.lblSize);
526
        swingManager.translate(this.lblRequiredBytes);
527
        swingManager.translate(this.chkVirtualField);
528
        swingManager.translate(this.tabAditionalFields);
529
        swingManager.translate(this.tabLayout);
530
        swingManager.translate(this.lblGroup);
531
        swingManager.translate(this.lblOrder);
532
        swingManager.translate(this.lblHidden);
533
        swingManager.translate(this.lblLabel);
534
        swingManager.translate(this.lblDescription);
535
        swingManager.translate(this.lblMinValue);
536
        swingManager.translate(this.lblMaxValue);
537
        swingManager.translate(this.lblAvailableValues);
538
        swingManager.translate(this.lblAvailableValuesLabel);
539
        swingManager.translate(this.lblAvailableValuesValue);
540
        swingManager.translate(this.lblRelationType);
541
        swingManager.translate(this.btnAvailableValuesAdd);
542
        swingManager.translate(this.btnAvailableValuesUpdate);
543
        swingManager.translate(this.btnAvailableValuesRemove);
544
        swingManager.translate(this.btnAvailableValuesRemoveAll);
545
        swingManager.translate(this.lblTagsName);
546
        swingManager.translate(this.lblTagsValue);
547

    
548
        swingManager.translate(this.lblForeingKeyCodeName);
549
        swingManager.translate(this.lblForeingKeyLabelFormula);
550
        swingManager.translate(this.lblForeingKeyTableName);
551
        swingManager.translate(this.lblIsClosedList);
552
        swingManager.translate(this.chkIsForeingKey);
553

    
554
        swingManager.translate(this.txtRequiredBytes);
555
        swingManager.translate(this.txtPrecision);
556
        swingManager.translate(this.txtScale);
557
        swingManager.translate(this.txtScale);
558

    
559
        swingManager.addClearButton(this.txtDefaultValue);
560
        swingManager.addClearButton(this.txtFieldName);
561
        swingManager.addClearButton(this.txtIntervalEnd);
562
        swingManager.addClearButton(this.txtIntervalStart);
563
        swingManager.addClearButton(this.txtScale);
564
        swingManager.addClearButton(this.txtSize);
565
        swingManager.addClearButton(this.txtRequiredBytes);
566
        swingManager.addClearButton(this.txtLabel);
567
        swingManager.addClearButton(this.txtDescription);
568
        swingManager.addClearButton(this.cboGroup);
569
        swingManager.addClearButton(this.txtMaxValue);
570
        swingManager.addClearButton(this.txtMinValue);
571
        swingManager.addClearButton(this.txtAvailableValuesLabel);
572
        swingManager.addClearButton(this.txtAvailableValuesValue);
573

    
574
        swingManager.setDefaultPopupMenu(this.txtDefaultValue);
575
        swingManager.setDefaultPopupMenu(this.txtFieldName);
576
        swingManager.setDefaultPopupMenu(this.txtIntervalEnd);
577
        swingManager.setDefaultPopupMenu(this.txtIntervalStart);
578
        swingManager.setDefaultPopupMenu(this.txtScale);
579
        swingManager.setDefaultPopupMenu(this.txtSize);
580
        swingManager.setDefaultPopupMenu(this.txtRequiredBytes);
581
        swingManager.setDefaultPopupMenu(this.cboDateFormat);
582
        swingManager.setDefaultPopupMenu(this.cboFieldType);
583
        swingManager.setDefaultPopupMenu(this.cboGeometrySubtype);
584
        swingManager.setDefaultPopupMenu(this.cboGeometryType);
585
        swingManager.setDefaultPopupMenu(this.cboDataProfile);
586

    
587
        swingManager.setDefaultPopupMenu(this.cboForeingKeyCodeName);
588
        swingManager.setDefaultPopupMenu(this.cboForeingKeyTableName);
589

    
590
        swingManager.setDefaultPopupMenu(this.cboGroup);
591
        swingManager.setDefaultPopupMenu(this.txtOrder);
592
        swingManager.setDefaultPopupMenu(this.txtLabel);
593
        swingManager.setDefaultPopupMenu(this.txtDescription);
594
        swingManager.setDefaultPopupMenu(this.txtMinValue);
595
        swingManager.setDefaultPopupMenu(this.txtMaxValue);
596
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesLabel);
597
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesValue);
598

    
599
        this.foreingKeyController = new ForeingKeyController(
600
                chkIsForeingKey, 
601
                chkIsClosedList, 
602
                cboForeingKeyTableName, 
603
                cboForeingKeyCodeName, 
604
                txtForeingKeyFormula, 
605
                btnForeingKeyFormula
606
        );
607
        this.pickerIntervalEnd = swingManager.createDatePickerController(
608
                this.txtIntervalEnd,
609
                this.btnIntervalEnd
610
        );
611
        this.pickerIntervalStart = swingManager.createDatePickerController(
612
                this.txtIntervalStart,
613
                this.btnIntervalStart
614
        );
615
        this.pickerSize = evaluatorManager.createCalculatorController(
616
                this.txtSize, DataTypes.INT
617
        );
618
        this.pickerRequiredBytes = evaluatorManager.createCalculatorController(
619
                this.txtRequiredBytes, DataTypes.INT
620
        );
621
        this.pickerPrecision = evaluatorManager.createCalculatorController(
622
                this.txtPrecision, DataTypes.INT
623
        );
624
        this.pickerScale = evaluatorManager.createCalculatorController(
625
                this.txtScale, DataTypes.INT
626
        );
627
        this.pickerDefaultValue = evaluatorManager.createCalculatorController(
628
                this.txtDefaultValue, DataTypes.OBJECT
629
        );
630
        this.pickerOrder = evaluatorManager.createCalculatorController(
631
                this.txtOrder, DataTypes.INT
632
        );
633

    
634
        this.availableValuesController = new AvailableValuesController(
635
                lstAvailableValues,
636
                txtAvailableValuesLabel,
637
                txtAvailableValuesValue,
638
                btnAvailableValuesAdd,
639
                btnAvailableValuesUpdate,
640
                btnAvailableValuesRemove,
641
                btnAvailableValuesRemoveAll
642
        );
643
        this.tagsController = new TagsController(
644
                tblTags,
645
                cboTagsName,
646
                cboTagsValue,
647
                btnTagsAdd,
648
                btnTagsUpdate,
649
                btnTagsRemove,
650
                lblTagsDescription
651
        );
652
        this.txtMinValue.setEnabled(false);
653
        this.txtMaxValue.setEnabled(false);
654

    
655
        this.btnVirtualField.setText("");
656
        this.featureStoreElement = dataSwingManager.createFeatureStoreElement();
657
        this.pickerVirtualField = ExpressionEvaluatorSwingLocator.getManager()
658
                .createExpressionPickerController(txtVirtualField, btnVirtualField);
659
        this.pickerVirtualField.addElement(this.featureStoreElement);
660
        this.chkVirtualField.addChangeListener((ChangeEvent e) -> {
661
          if (chkVirtualField.isSelected()) {
662
            pickerVirtualField.setEditable(mode==MODE_EDIT_ALL || mode==MODE_EDIT_ONLY_METADATA);
663
          } else {
664
            pickerVirtualField.setEditable(false);
665
          }
666
        });
667

    
668
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
669
                this.txtCRS, this.btnCRS
670
        );
671

    
672
        this.cboFieldType.addItemListener((ItemEvent e) -> {
673
          SwingUtilities.invokeLater(() -> {
674
            doFieldTypeChanged();
675
          });
676
        });
677

    
678
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
679
          doCheckPrecisionAndScale();
680
        });
681
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
682
          doCheckPrecisionAndScale();
683
        });
684

    
685
        DefaultComboBoxModel dataProfilesModel = new DefaultComboBoxModel<>();
686
        dataProfilesModel.addElement(new ListElement<>("", null));
687
        for (DataProfile profile : DALLocator.getDataManager().getDataProfiles()) {
688
            dataProfilesModel.addElement(new ListElement<>(profile.getName(), profile.getID()));
689
        }
690
        this.cboDataProfile.setModel(dataProfilesModel);
691
        
692
        this.btnFieldType.addActionListener((ActionEvent e) -> {
693
          doDataTypeSelection();
694
        });
695
        
696
        DefaultComboBoxModel<ListElement<Integer>> relationTypeModel = new DefaultComboBoxModel<>();
697
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_None"),DynField.RELATION_TYPE_NONE));
698
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Identity_1_1"),DynField.RELATION_TYPE_IDENTITY));
699
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Collaboration_1_1"),DynField.RELATION_TYPE_COLLABORATION));
700
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Composition_1_N"),DynField.RELATION_TYPE_COMPOSITION));
701
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Aggregate_1_N"),DynField.RELATION_TYPE_AGGREGATE));
702
        this.cboRelationType.setModel(relationTypeModel);
703
    }
704

    
705
    @Override
706
    public JComponent asJComponent() {
707
        return this;
708
    }
709
    
710
    private void doDataTypeSelection() {
711
        final DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
712
        final I18nManager i18n = ToolsLocator.getI18nManager();
713
        List<ListElement<Integer>> types = new ArrayList<>();
714
        for (DataType dataType : dataManager) {
715
            types.add( new ListElement<>(dataType.getName(), dataType.getType()) );
716
        }
717
        types.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
718
                o1.toString().compareTo(o2.toString())
719
        );
720
        
721
        DefaultListModel<ListElement<Integer>> modelTypes = new DefaultListModel<>();
722
        for (ListElement<Integer> element : types) {
723
            modelTypes.addElement(element);
724
        }
725
        final JList list = new JList();
726
        list.setCellRenderer(new DefaultListCellRenderer() {
727
          @Override
728
          public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
729
              JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
730
              label.setIcon(null);
731
              try {
732
                DataType dataType = dataManager.get((int) value);
733
                IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
734
                if (theme.exists(dataType.getIconName())) {
735
                    label.setIcon(theme.get(dataType.getIconName()));
736
                }
737
              } catch(Exception ex) {
738
                // Do nothing, ignore
739
              }
740
              return label;
741
          }
742
        });
743
        list.setModel(modelTypes);
744
        final JScrollPane scrollpanel = new JScrollPane(list);
745
        WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
746
        Dialog dialog = winManager.createDialog(
747
              scrollpanel, 
748
              i18n.getTranslation("_Data_type_selection"),
749
              i18n.getTranslation("_Select_the_data_type"),
750
              WindowManager_v2.BUTTONS_OK_CANCEL
751
        );
752
        dialog.addActionListener((ActionEvent e) -> {
753
          if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
754
            Integer type = (Integer) ListElement.getSelected(list);
755
            if( type!=null ) {
756
              ListElement.setSelected(cboFieldType, type);
757
              if( ListElement.getSelected(cboFieldType)==null ) {
758
                DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
759
                DataType dataType = dataTypeManager.get(type);
760
                cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
761
                ListElement.setSelected(cboFieldType, dataType.getType());
762
              }
763
            }
764
          }
765
        });
766
        dialog.show(WindowManager.MODE.DIALOG);
767
    }
768

    
769
    @Override
770
    public EditableFeatureAttributeDescriptor fetch(EditableFeatureAttributeDescriptor descriptor) {
771
        I18nManager i18n = ToolsLocator.getI18nManager();
772
        try {
773
            if (!this.chkAllowNulls.isSelected()) {
774
                if (descriptor.allowNull()) {
775
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
776
                    dialogs.messageDialog(
777
                            i18n.getTranslation("_You_have_marked_not_allow_nulls") + "\n"
778
                            + i18n.getTranslation("If_you_are_not_fully_aware_of_the_repercussions_of_this_it_is_advisable_to_allow_nulls"),
779
                            null,
780
                            i18n.getTranslation("_Warning"),
781
                            JOptionPane.INFORMATION_MESSAGE,
782
                            "AllowNullsInFeatureTypeEditing"
783
                    );
784
                }
785
            }
786
            descriptor.setDataType((int) ListElement.getSelected(this.cboFieldType));
787
            descriptor.setName(this.txtFieldName.getText());
788
            descriptor.setAllowNull(this.chkAllowNulls.isSelected());
789
            descriptor.setIsPrimaryKey(this.chkIsPrimaryKey.isSelected());
790
            descriptor.setIsAutomatic(this.chkIsAutomatic.isSelected());
791
            descriptor.setSize(this.pickerSize.get(0));
792
            descriptor.setRequiredBytes(this.pickerRequiredBytes.get(0));
793
            descriptor.setPrecision(this.pickerPrecision.get(0));
794
            descriptor.setScale(this.pickerScale.get(0));
795
            descriptor.setDefaultValue(this.pickerDefaultValue.get());
796
            descriptor.setDataProfileName((String) ListElement.getSelected(this.cboDataProfile));
797
            descriptor.setRelationType((int) ListElement.getSelected(this.cboRelationType));
798
            switch (descriptor.getType()) {
799
                case DataTypes.GEOMETRY:
800
                    GeometryManager geomManager = GeometryLocator.getGeometryManager();
801
                    GeometryType geomType = geomManager.getGeometryType(
802
                            (int) ListElement.getSelected(this.cboGeometryType),
803
                            (int) ListElement.getSelected(this.cboGeometrySubtype)
804
                    );
805
                    descriptor.setGeometryType(geomType);
806
                    descriptor.setSRS(this.pickerCRS.get());
807
                    break;
808
                case DataTypes.INSTANT:
809
                case DataTypes.INTERVAL:
810
                case DataTypes.DATE:
811
                case DataTypes.TIME:
812
                case DataTypes.TIMESTAMP:
813
                    // FIXME
814
                    break;
815
                default:
816
                    break;
817
            }
818
            descriptor.setDataProfileName(
819
                    StringUtils.defaultIfBlank((String) ListElement.getSelected(cboDataProfile), null)
820
            );
821

    
822
            if (this.chkVirtualField.isSelected() ) { //&& this.pickerVirtualField.isEnabled()) {
823
                Expression expression = this.pickerVirtualField.get();
824
                if (expression == null) {
825
                    descriptor.setFeatureAttributeEmulator((String) null);
826
                } else {
827
                    DataManager dataManager = DALLocator.getDataManager();
828
                    FeatureAttributeEmulatorExpression emulator = dataManager.createFeatureAttributeEmulatorExpression(
829
                            descriptor.getFeatureType(),
830
                            expression
831
                    );
832
                    if (!emulator.isValid()) {
833
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
834
                        dialogs.messageDialog(
835
                                i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")+"\n"
836
                                + "\n"
837
                                + emulator.getErrorMessage(),
838
                                i18n.getTranslation("_Warning"),
839
                                JOptionPane.WARNING_MESSAGE
840
                        );
841
                        return null;
842
                    }
843
                    for (String requiredFieldName : emulator.getRequiredFieldNames()) {
844
                        if (StringUtils.equalsIgnoreCase(requiredFieldName, descriptor.getName())) {
845
                            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
846
                            dialogs.messageDialog(
847
                                    i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")
848
                                    + "\n\n"
849
                                    + i18n.getTranslation("_The_expression_contains_a_reference_to_itself"),
850
                                    i18n.getTranslation("_Warning"),
851
                                    JOptionPane.WARNING_MESSAGE
852
                            );
853
                            return null;
854
                        }
855
                    }
856
                    List<String> undefinedSymbols = emulator.getUndefinedSymbols();
857
                    if( undefinedSymbols!=null && !undefinedSymbols.isEmpty() ) {
858
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
859
                        dialogs.messageDialog(
860
                                i18n.getTranslation("_The_expression_has_undefined_symbols_at_this_moment")+"\n"
861
                                + i18n.getTranslation("_This_may_not_be_a_mistake")+"\n"
862
                                + "\n"
863
                                + "("+StringUtils.join(undefinedSymbols,",")+")",
864
                                i18n.getTranslation("_Warning"),
865
                                JOptionPane.WARNING_MESSAGE
866
                        );
867
                    }
868
                    descriptor.setFeatureAttributeEmulator(emulator);
869
                    //
870
                    // No se porque esto de abajo no funciona.
871
                    // Nunca se lanza la excepcion en el get(Feature) de
872
                    // DefaultFeatureAttributeEmulatorExpression.
873
                    //
874
//                    try {
875
//                        emulator.setEnableExceptions(true);
876
//                        descriptor.setFeatureAttributeEmulator(emulator);
877
//                        this.pickerVirtualField.getPreviewSymbolTable().value(descriptor.getName());
878
//                    } catch(Throwable ex) {
879
//                        emulator.setEnableExceptions(false);
880
//                        descriptor.setFeatureAttributeEmulator(null);
881
//                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
882
//                        dialogs.messageDialog(
883
//                                i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")+
884
//                                    "\n"+
885
//                                    ex.getMessage(), 
886
//                                i18n.getTranslation("_Warning"), 
887
//                                JOptionPane.WARNING_MESSAGE
888
//                        );
889
//                        return null;
890
//                    } finally {
891
//                        emulator.setEnableExceptions(false);
892
//                    }
893
                }
894
            }
895
        } catch (Exception ex) {
896
            LOGGER.warn("Can't retrieve information from user form.", ex);
897
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
898
            dialogs.messageDialog(
899
                    i18n.getTranslation("_Cant_retrieve_information_from_user_form")
900
                    + "\n"
901
                    + i18n.getTranslation("_See_log_for_details"),
902
                    i18n.getTranslation("_Warning"),
903
                    JOptionPane.WARNING_MESSAGE
904
            );
905
            return null;
906
        }
907

    
908
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
909
        descriptor.setOrder(this.pickerOrder.get(0));
910
        descriptor.setHidden(this.chkHidden.isSelected());
911
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
912
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
913

    
914
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
915
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
916
        descriptor.setAvailableValues(this.availableValuesController.get());
917

    
918
        this.tagsController.fetch(descriptor.getTags());
919
        this.foreingKeyController.fetch(descriptor.getForeingKey());
920
        return descriptor;
921
    }
922

    
923
    @Override
924
    public void clean() {
925
        this.pickerDefaultValue.set(null);
926
        this.txtFieldName.setText("");
927
//        this.pickerFieldName.set(null);
928
        this.pickerIntervalEnd.set(null);
929
        this.pickerIntervalStart.set(null);
930
        this.pickerScale.set(null);
931
        this.pickerSize.set(null);
932
        this.pickerRequiredBytes.set(null);
933

    
934
        this.chkAllowNulls.setSelected(false);
935
        this.chkIsAutomatic.setSelected(false);
936
        this.chkIsPrimaryKey.setSelected(false);
937

    
938
        this.chkVirtualField.setSelected(false);
939
        this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
940
        this.pickerVirtualField.setEditable(false);
941
        this.pickerVirtualField.set(null);
942

    
943
        ListElement.setSelected(cboGeometryType, null);
944
        ListElement.setSelected(cboGeometrySubtype, null);
945

    
946
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
947

    
948
        this.cboDataProfile.setSelectedIndex(-1);
949

    
950
        this.cboGroup.setSelectedIndex(-1);
951
        this.pickerOrder.set(null);
952
        this.chkHidden.setSelected(false);
953
        this.txtLabel.setText("");
954
        this.txtDescription.setText("");
955
        this.txtMinValue.setText("");
956
        this.txtMaxValue.setText("");
957
        this.availableValuesController.clean();
958
        this.tagsController.clean();
959
        this.foreingKeyController.clean();
960
    }
961

    
962
    @Override
963
    public void put(FeatureAttributeDescriptor descriptor) {
964
        if (descriptor == null) {
965
            this.clean();
966
            return;
967
        }
968
        DataType dataType = descriptor.getDataType();
969
        FeatureType featureType = descriptor.getFeatureType();
970
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
971

    
972
        if (featureType != null) {
973
            FeatureStore store = descriptor.getFeatureType().getStore();
974
            this.featureStoreElement.setFeatureStore(store);
975
            if (store != null) {
976
                Feature sampleFeature = null;
977
                try {
978
                    sampleFeature = store.getFeatureSelection().first();
979
                    if (sampleFeature == null) {
980
                        sampleFeature = store.first();
981
                    }
982
                } catch (DataException ex) {
983
                }
984
                if (sampleFeature != null) {
985
                    FeatureSymbolTable featureSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable();
986
                    featureSymbolTable.setFeature(sampleFeature);
987
                    this.pickerVirtualField.setPreviewSymbolTable(featureSymbolTable.createParent());
988
                }
989
            }
990
            List<String> groups = new ArrayList<>();
991
            for (FeatureAttributeDescriptor otherdesc : featureType) {
992
                String group = otherdesc.getGroup();
993
                if (!StringUtils.isBlank(group) && !groups.contains(group)) {
994
                    groups.add(group);
995
                }
996
            }
997
            for (String group : groups) {
998
                groupModel.addElement(group);
999
            }
1000
        }
1001

    
1002
        this.pickerDefaultValue.set(descriptor.getDefaultValue());
1003
        this.txtFieldName.setText(descriptor.getName());
1004
        RelativeInterval interval = (RelativeInterval) descriptor.getInterval();
1005
        if (interval == null) {
1006
            this.pickerIntervalEnd.set(null);
1007
            this.pickerIntervalStart.set(null);
1008
        } else {
1009
            this.pickerIntervalEnd.set(interval.getEnd().toDate());
1010
            this.pickerIntervalStart.set(interval.getStart().toDate());
1011
        }
1012
        if( dataType.supportSize() ) {
1013
          this.pickerSize.set(descriptor.getSize());
1014
        } else {
1015
          this.pickerSize.set(null);
1016
        }
1017
        this.pickerRequiredBytes.set(descriptor.getRequiredBytes());
1018
        if( dataType.supportPrecision() ) {
1019
          this.pickerPrecision.set(descriptor.getPrecision());
1020
        } else {
1021
          this.pickerPrecision.set(null);
1022
        }
1023
        if( dataType.supportScale()) {
1024
          this.pickerScale.set(descriptor.getScale());
1025
        } else {
1026
          this.pickerScale.set(null);
1027
        }
1028
        this.chkAllowNulls.setSelected(descriptor.allowNull());
1029
        this.chkIsAutomatic.setSelected(descriptor.isAutomatic());
1030
        this.chkIsPrimaryKey.setSelected(descriptor.isPrimaryKey());
1031

    
1032
        this.pickerVirtualField.setEnabled(true);
1033
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1034
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1035
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1036
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1037
            this.chkVirtualField.setSelected(true);
1038
            this.pickerVirtualField.set(expression);
1039
        } else if (descriptor.isComputed()) {
1040
            this.chkVirtualField.setEnabled(false);
1041
            this.chkVirtualField.setSelected(true);
1042
            this.pickerVirtualField.set(null);
1043
        } else {
1044
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1045
            this.chkVirtualField.setSelected(false);
1046
            this.pickerVirtualField.set(null);
1047
        }
1048

    
1049
        this.pickerCRS.set(descriptor.getSRS());
1050

    
1051
        if (descriptor.getGeomType() != null) {
1052
            ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1053
            ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1054
        }
1055
        ListElement.setSelected(cboFieldType, dataType.getType());
1056
        if( ListElement.getSelected(cboFieldType)==null ) {
1057
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1058
          ListElement.setSelected(cboFieldType, dataType.getType());
1059
        }
1060
 
1061
        ListElement.setSelected(cboRelationType, descriptor.getRelationType());
1062

    
1063
        String profile = descriptor.getDataProfileName();
1064
        if (StringUtils.isBlank(profile)) {
1065
            this.cboDataProfile.setSelectedIndex(-1);
1066
        } else {
1067
            ListElement.setSelected(this.cboDataProfile, profile);
1068
        }
1069

    
1070
        this.cboGroup.setModel(groupModel);
1071
        this.cboGroup.setSelectedItem(StringUtils.defaultIfBlank(descriptor.getGroup(), ""));
1072
        this.pickerOrder.set(descriptor.getOder());
1073
        this.chkHidden.setSelected(descriptor.isHidden());
1074
        if (descriptor.hasLabel()) {
1075
            this.txtLabel.setText(StringUtils.defaultIfBlank(descriptor.getLabel(), ""));
1076
        } else {
1077
            this.txtLabel.setText("");
1078
        }
1079
        if (descriptor.hasDescription()) {
1080
            this.txtDescription.setText(StringUtils.defaultIfBlank(descriptor.getDescription(), ""));
1081
        } else {
1082
            this.txtDescription.setText("");
1083
        }
1084
        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1085
        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1086
        if( descriptor.hasConstantAvailableValues() ) {
1087
          this.availableValuesController.set(descriptor.getAvailableValues());
1088
        } else {
1089
          this.availableValuesController.clean();
1090
        }
1091
        this.tagsController.set(descriptor.getTags());
1092

    
1093
        this.foreingKeyController.put(descriptor.getForeingKey());
1094
        
1095
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1096
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1097
        }
1098
        this.updateEditableStates();
1099
    }
1100

    
1101
    private DataType getDataType() {
1102
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1103
      if (fieldType == null) {
1104
          return null;
1105
      }
1106
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1107
      return dataType;
1108
    }
1109

    
1110
    private void doFieldTypeChanged() {
1111
      try {
1112
        DataType dataType = this.getDataType();
1113

    
1114
        if( dataType.supportSize() ) {
1115
            this.pickerSize.setEditable(this.mode == MODE_EDIT_ALL);
1116
        } else {
1117
            this.pickerSize.setEditable(false);
1118
            this.pickerSize.set(null);
1119
        }        
1120
        this.pickerRequiredBytes.setEditable(this.mode == MODE_EDIT_ALL);
1121
        if( dataType.supportPrecision() ) {
1122
          if( dataType.isPredefinedPrecision() ) {
1123
            this.pickerPrecision.setEditable(false);
1124
          } else {
1125
            this.pickerPrecision.setEditable(this.mode == MODE_EDIT_ALL);
1126
          }
1127
        } else {
1128
            this.pickerPrecision.setEditable(false);
1129
            this.pickerPrecision.set(null);
1130
        }        
1131
        if( dataType.supportScale()) {
1132
            this.pickerScale.setEditable(this.mode == MODE_EDIT_ALL);
1133
        } else {
1134
            this.pickerScale.setEditable(false);
1135
            this.pickerScale.set(null);
1136
        }        
1137
        switch (dataType.getType()) {
1138
          case DataTypes.GEOMETRY:
1139
            this.cboGeometryType.setEnabled(this.mode == MODE_EDIT_ALL);
1140
            this.cboGeometrySubtype.setEnabled(this.mode == MODE_EDIT_ALL);
1141
            this.pickerCRS.setEditable(this.mode == MODE_EDIT_ALL);
1142
            this.cboDateFormat.setEnabled(false);
1143
            this.pickerIntervalStart.setEditable(false);
1144
            this.pickerIntervalEnd.setEditable(false);
1145
            this.tabAditionalFields.setEnabledAt(1, true);
1146
            this.tabAditionalFields.setEnabledAt(2, false);
1147
            break;
1148
          case DataTypes.INSTANT:
1149
          case DataTypes.INTERVAL:
1150
          case DataTypes.DATE:
1151
          case DataTypes.TIME:
1152
          case DataTypes.TIMESTAMP:
1153
            this.cboGeometryType.setEnabled(false);
1154
            this.cboGeometrySubtype.setEnabled(false);
1155
            this.pickerCRS.setEditable(false);
1156
            this.cboDateFormat.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1157
            this.pickerIntervalStart.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1158
            this.pickerIntervalEnd.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1159
            this.tabAditionalFields.setEnabledAt(1, false);
1160
            this.tabAditionalFields.setEnabledAt(2, true);
1161
            break;
1162
          case DataTypes.BYTE:
1163
          case DataTypes.INT:
1164
          case DataTypes.LONG:
1165
          case DataTypes.STRING:
1166
          case DataTypes.FILE:
1167
          case DataTypes.URL:
1168
          case DataTypes.URI:
1169
          case DataTypes.FLOAT:
1170
          case DataTypes.DOUBLE:
1171
          case DataTypes.DECIMAL:
1172
            this.cboGeometryType.setEnabled(false);
1173
            this.cboGeometrySubtype.setEnabled(false);
1174
            this.pickerCRS.setEditable(false);
1175
            this.cboDateFormat.setEnabled(false);
1176
            this.pickerIntervalStart.setEditable(false);
1177
            this.pickerIntervalEnd.setEditable(false);
1178
            this.tabAditionalFields.setEnabledAt(1, false);
1179
            this.tabAditionalFields.setEnabledAt(2, false);
1180
            break;
1181
          default:
1182
            this.cboGeometryType.setEnabled(false);
1183
            this.cboGeometrySubtype.setEnabled(false);
1184
            this.pickerCRS.setEditable(false);
1185
            this.cboDateFormat.setEnabled(false);
1186
            this.pickerIntervalStart.setEditable(false);
1187
            this.pickerIntervalEnd.setEditable(false);
1188
            this.tabAditionalFields.setEnabledAt(1, false);
1189
            this.tabAditionalFields.setEnabledAt(2, false);
1190
        }
1191
      } catch (Exception ex) {
1192
        LOGGER.warn("Problems changing field type.", ex);
1193
      }
1194

    
1195
    }
1196
    
1197
    boolean isVirtualField() {
1198
        return this.chkVirtualField.isSelected();
1199
    }
1200

    
1201
    @Override
1202
    public int getMode() {
1203
        return this.mode;
1204
    }
1205
    
1206
    @Override
1207
    public void setMode(int mode) {
1208
        this.mode = mode;
1209
        updateEditableStates();
1210
    }
1211
    
1212
    private void updateEditableStates() {
1213
        DataType dataType = this.getDataType();
1214
        switch(this.mode) {
1215
            case MODE_EDIT_ALL:
1216
                this.pickerDefaultValue.setEditable(true);
1217
                this.txtFieldName.setEditable(true);
1218
                this.pickerIntervalEnd.setEditable(true);
1219
                this.pickerIntervalStart.setEditable(true);
1220
                this.pickerSize.setEditable(dataType.supportSize());
1221
                this.pickerRequiredBytes.setEditable(true);
1222
                if( dataType.isPredefinedPrecision() ) {
1223
                  this.pickerPrecision.setEditable(false);
1224
                  this.pickerPrecision.set(dataType.getMaxPrecision());
1225
                } else {
1226
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
1227
                }
1228
                this.pickerScale.setEditable(dataType.supportScale());
1229
                this.cboDataProfile.setEnabled(true);
1230

    
1231
                this.chkAllowNulls.setEnabled(true);
1232
                this.chkIsAutomatic.setEnabled(true);
1233
                if( this.isVirtualField() ) {
1234
                    this.chkIsPrimaryKey.setEnabled(false);
1235
                } else {
1236
                    this.chkIsPrimaryKey.setEnabled(true);
1237
                }
1238

    
1239
                this.chkVirtualField.setEnabled(true);
1240
                this.pickerVirtualField.setEditable(true);
1241

    
1242
                this.cboDateFormat.setEnabled(true);
1243
                this.cboFieldType.setEnabled(true);
1244
                this.cboGeometryType.setEnabled(true);
1245
                this.cboGeometrySubtype.setEnabled(true);
1246
                this.pickerCRS.setEditable(true);
1247

    
1248
                this.cboGroup.setEnabled(true);
1249
                this.pickerOrder.setEditable(true);
1250
                this.chkHidden.setEnabled(true);
1251
                this.txtLabel.setEditable(true);
1252
                this.txtDescription.setEditable(true);
1253
                this.txtMinValue.setEditable(false);
1254
                this.txtMaxValue.setEditable(false);
1255
                this.availableValuesController.setEditable(true);
1256
                this.tagsController.setEditable(true);
1257
                this.foreingKeyController.setEditable(true);
1258
                break;
1259
            case MODE_EDIT_ONLY_METADATA:
1260
                if( this.chkVirtualField.isSelected() ) {
1261
                    this.txtFieldName.setEditable(true);
1262
                    this.pickerScale.setEditable(true);
1263
                    this.pickerSize.setEditable(true);
1264
                    this.pickerVirtualField.setEditable(true);
1265
                    this.cboFieldType.setEnabled(true);
1266
                    this.cboGeometryType.setEnabled(true);
1267
                    this.cboGeometrySubtype.setEnabled(true);
1268
                    this.pickerCRS.setEditable(true);
1269
                } else {
1270
                    this.txtFieldName.setEditable(false);
1271
                    this.pickerPrecision.setEditable(false);
1272
                    this.pickerScale.setEditable(false);
1273
                    this.pickerSize.setEditable(false);
1274
                    this.pickerVirtualField.setEditable(false);
1275
                    this.cboFieldType.setEnabled(false);
1276
                    this.cboGeometryType.setEnabled(false);
1277
                    this.cboGeometrySubtype.setEnabled(false);
1278
                    this.pickerCRS.setEditable(false);
1279
                }
1280

    
1281
                this.pickerDefaultValue.setEditable(true);
1282
                this.pickerIntervalEnd.setEditable(true);
1283
                this.pickerIntervalStart.setEditable(true);
1284

    
1285
                this.cboDataProfile.setEnabled(true);
1286

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

    
1296
                this.chkVirtualField.setEnabled(false);
1297

    
1298
                this.cboDateFormat.setEnabled(true);
1299

    
1300
                this.cboGroup.setEnabled(true);
1301
                this.pickerOrder.setEditable(true);
1302
                this.chkHidden.setEnabled(true);
1303
                this.txtLabel.setEditable(true);
1304
                this.txtDescription.setEditable(true);
1305
                this.txtMinValue.setEditable(false);
1306
                this.txtMaxValue.setEditable(false);
1307
                this.availableValuesController.setEditable(true);
1308
                this.tagsController.setEditable(true);
1309
                this.foreingKeyController.setEditable(true);
1310
                break;
1311
            case MODE_SHOW_ONLY:
1312
                this.pickerDefaultValue.setEditable(false);
1313
                this.txtFieldName.setEditable(false);
1314
                this.pickerIntervalEnd.setEditable(false);
1315
                this.pickerIntervalStart.setEditable(false);
1316
                this.pickerPrecision.setEditable(false);
1317
                this.pickerScale.setEditable(false);
1318
                this.pickerSize.setEditable(false);
1319
                this.pickerRequiredBytes.setEditable(false);
1320
                this.cboDataProfile.setEnabled(false);
1321

    
1322
                this.chkAllowNulls.setEnabled(false);
1323
                this.chkIsAutomatic.setEnabled(false);
1324
                this.chkIsPrimaryKey.setEnabled(false);
1325

    
1326
                this.chkVirtualField.setEnabled(false);
1327
                this.pickerVirtualField.setEditable(false);
1328

    
1329
                this.cboDateFormat.setEnabled(false);
1330
                this.cboFieldType.setEnabled(false);
1331
                this.cboGeometryType.setEnabled(false);
1332
                this.cboGeometrySubtype.setEnabled(false);
1333
                this.pickerCRS.setEditable(false);
1334

    
1335
                this.cboGroup.setEnabled(false);
1336
                this.pickerOrder.setEditable(false);
1337
                this.chkHidden.setEnabled(false);
1338
                this.txtLabel.setEditable(false);
1339
                this.txtDescription.setEditable(false);
1340
                this.txtMinValue.setEditable(false);
1341
                this.txtMaxValue.setEditable(false);
1342
                this.availableValuesController.setEditable(false);
1343
                this.tagsController.setEditable(false);
1344
                this.foreingKeyController.setEditable(false);
1345
                break;
1346
        }
1347
    }
1348

    
1349
    private void doCheckPrecisionAndScale() {
1350
      DataType dataType = this.getDataType();
1351
      
1352
      Integer precision = this.pickerPrecision.get();
1353
      if( precision==null ) {
1354
        precision = 0;
1355
      }
1356
      Integer scale = this.pickerScale.get();
1357
      if( scale == null ) {
1358
        scale = 0;
1359
      }      
1360
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
1361
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
1362
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
1363
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
1364
      } else {
1365
        this.pickerPrecision.setWarning(false);
1366
        this.pickerScale.setWarning(false);
1367
      }
1368
    }
1369

    
1370
    @Override
1371
    public void setNameAsNew(FeatureType featureType) {
1372
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
1373
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
1374
                cloneFeatureType.getNewFieldName(), 
1375
                DataTypes.STRING);
1376
        this.put(newAttributeDescriptor);
1377
    }
1378

    
1379
    @Override
1380
    public String getName() {
1381
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
1382
    }
1383

    
1384
    @Override
1385
    public ImageIcon loadImage(String imageName) {
1386
        String name = FilenameUtils.getBaseName(imageName);
1387
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1388
        if (theme.exists(name)) {
1389
            return theme.get(name);
1390
        }
1391
        URL url = this.getClass().getResource(name + ".png");
1392
        if (url == null) {
1393
            return null;
1394
        }
1395
        return new ImageIcon(url);
1396
    }
1397

    
1398
  public static void selfRegister() {
1399
    String[][] iconNames = new String[][]{
1400
      new String[]{"dalswing", "picker-datatype"},};
1401
    IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1402
    for (String[] icon : iconNames) {
1403
      URL url = DefaultFeatureAttributeSelectionPanel.class.getResource(icon[1] + ".png");
1404
      theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1405
    }
1406
    
1407
  }
1408

    
1409
}