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

History | View | Annotate | Download (60.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 java.awt.event.ActionListener;
6
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypeAttributePanel;
7
import java.awt.event.ItemEvent;
8
import java.net.URL;
9
import java.util.ArrayList;
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.ListCellRenderer;
26
import javax.swing.ListModel;
27
import javax.swing.SwingUtilities;
28
import javax.swing.event.ChangeEvent;
29
import javax.swing.event.ListSelectionEvent;
30
import javax.swing.text.JTextComponent;
31
import org.apache.commons.io.FilenameUtils;
32
import org.apache.commons.lang3.StringUtils;
33
import org.cresques.cts.IProjection;
34
import org.gvsig.expressionevaluator.Expression;
35
import org.gvsig.expressionevaluator.ExpressionUtils;
36
import org.gvsig.expressionevaluator.swing.CalculatorController;
37
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingLocator;
38
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
39
import org.gvsig.expressionevaluator.swing.ExpressionPickerController;
40
import org.gvsig.fmap.dal.DALLocator;
41
import org.gvsig.fmap.dal.DataManager;
42
import org.gvsig.fmap.dal.DataStore;
43
import org.gvsig.fmap.dal.DataTypes;
44
import org.gvsig.fmap.dal.StoresRepository;
45
import org.gvsig.fmap.dal.complements.Search;
46
import org.gvsig.fmap.dal.exception.DataException;
47
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
48
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
49
import org.gvsig.fmap.dal.feature.DataProfile;
50
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
51
import org.gvsig.fmap.dal.feature.EditableFeatureType;
52
import org.gvsig.fmap.dal.feature.EditableForeingKey;
53
import org.gvsig.fmap.dal.feature.Feature;
54
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
55
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
56
import org.gvsig.fmap.dal.feature.FeatureStore;
57
import org.gvsig.fmap.dal.feature.FeatureType;
58
import org.gvsig.fmap.dal.feature.ForeingKey;
59
import org.gvsig.fmap.dal.swing.DALSwingLocator;
60
import org.gvsig.fmap.dal.swing.DataSwingManager;
61
import org.gvsig.fmap.dal.swing.expressionevaluator.FeatureStoreElement;
62
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel;
63
import static org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel.MODE_EDIT_ALL;
64
import static org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel.MODE_EDIT_ONLY_METADATA;
65
import static org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel.MODE_SHOW_ONLY;
66
import org.gvsig.fmap.geom.Geometry;
67
import org.gvsig.fmap.geom.GeometryLocator;
68
import org.gvsig.fmap.geom.GeometryManager;
69
import org.gvsig.fmap.geom.type.GeometryType;
70
import org.gvsig.timesupport.RelativeInterval;
71
import org.gvsig.tools.ToolsLocator;
72
import org.gvsig.tools.dataTypes.DataType;
73
import org.gvsig.tools.dataTypes.DataType.NumberPrecisionAndScale;
74
import org.gvsig.tools.dataTypes.DataTypesManager;
75
import org.gvsig.tools.dynobject.DynField;
76
import org.gvsig.tools.dynobject.DynObjectValueItem;
77
import org.gvsig.tools.i18n.I18nManager;
78
import org.gvsig.tools.swing.api.ListElement;
79
import org.gvsig.tools.swing.api.ToolsSwingLocator;
80
import org.gvsig.tools.swing.api.ToolsSwingManager;
81
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
82
import org.gvsig.tools.swing.api.pickercontroller.PickerController;
83
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
84
import org.gvsig.tools.swing.api.windowmanager.Dialog;
85
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
86
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
87
import org.gvsig.tools.swing.icontheme.IconTheme;
88
import org.slf4j.Logger;
89
import org.slf4j.LoggerFactory;
90

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

    
100
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureAttributePanel.class);
101

    
102
    private static class ForeingKeyController {
103

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

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

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

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

    
266
    private static class AvailableValuesController {
267

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

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

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

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

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

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

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

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

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

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

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

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

    
406
    }
407

    
408
    private final List<ListElement<Integer>> fieldTypes;
409
    private final List<ListElement<Integer>> geometryTypes;
410
    private final List<ListElement<Integer>> geometrySubtypes;
411

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

    
425
    private int mode;
426
    private FeatureStoreElement featureStoreElement;
427

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

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

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

    
464
        this.initComponents();
465
    }
466

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

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

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

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

    
508
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
509

    
510
        swingManager.translate(this.lblAllowNulls);
511
        swingManager.translate(this.lblCRS);
512
        swingManager.translate(this.lblDataProfile);
513
        swingManager.translate(this.lblDateFormat);
514
        swingManager.translate(this.lblDefaultValue);
515
        swingManager.translate(this.lblFieldName);
516
        swingManager.translate(this.lblFieldType);
517
        swingManager.translate(this.lblGeometrySubtype);
518
        swingManager.translate(this.lblGeometryType);
519
        swingManager.translate(this.lblInterval);
520
        swingManager.translate(this.lblIntervalEnd);
521
        swingManager.translate(this.lblIntervalStart);
522
        swingManager.translate(this.lblIsAutomatic);
523
        swingManager.translate(this.lblIsPrimaryKey);
524
        swingManager.translate(this.lblPrecision);
525
        swingManager.translate(this.lblScale);
526
        swingManager.translate(this.lblSize);
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.btnAvailableValuesAdd);
541
        swingManager.translate(this.btnAvailableValuesUpdate);
542
        swingManager.translate(this.btnAvailableValuesRemove);
543
        swingManager.translate(this.btnAvailableValuesRemoveAll);
544
        swingManager.translate(this.lblTagsName);
545
        swingManager.translate(this.lblTagsValue);
546

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

    
553
        swingManager.addClearButton(this.txtDefaultValue);
554
        swingManager.addClearButton(this.txtFieldName);
555
        swingManager.addClearButton(this.txtIntervalEnd);
556
        swingManager.addClearButton(this.txtIntervalStart);
557
        swingManager.addClearButton(this.txtScale);
558
        swingManager.addClearButton(this.txtSize);
559
        swingManager.addClearButton(this.txtLabel);
560
        swingManager.addClearButton(this.txtDescription);
561
        swingManager.addClearButton(this.cboGroup);
562
        swingManager.addClearButton(this.txtMaxValue);
563
        swingManager.addClearButton(this.txtMinValue);
564
        swingManager.addClearButton(this.txtAvailableValuesLabel);
565
        swingManager.addClearButton(this.txtAvailableValuesValue);
566

    
567
        swingManager.setDefaultPopupMenu(this.txtDefaultValue);
568
        swingManager.setDefaultPopupMenu(this.txtFieldName);
569
        swingManager.setDefaultPopupMenu(this.txtIntervalEnd);
570
        swingManager.setDefaultPopupMenu(this.txtIntervalStart);
571
        swingManager.setDefaultPopupMenu(this.txtScale);
572
        swingManager.setDefaultPopupMenu(this.txtSize);
573
        swingManager.setDefaultPopupMenu(this.cboDateFormat);
574
        swingManager.setDefaultPopupMenu(this.cboFieldType);
575
        swingManager.setDefaultPopupMenu(this.cboGeometrySubtype);
576
        swingManager.setDefaultPopupMenu(this.cboGeometryType);
577
        swingManager.setDefaultPopupMenu(this.cboDataProfile);
578

    
579
        swingManager.setDefaultPopupMenu(this.cboForeingKeyCodeName);
580
        swingManager.setDefaultPopupMenu(this.cboForeingKeyTableName);
581

    
582
        swingManager.setDefaultPopupMenu(this.cboGroup);
583
        swingManager.setDefaultPopupMenu(this.txtOrder);
584
        swingManager.setDefaultPopupMenu(this.txtLabel);
585
        swingManager.setDefaultPopupMenu(this.txtDescription);
586
        swingManager.setDefaultPopupMenu(this.txtMinValue);
587
        swingManager.setDefaultPopupMenu(this.txtMaxValue);
588
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesLabel);
589
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesValue);
590

    
591
        this.foreingKeyController = new ForeingKeyController(
592
                chkIsForeingKey, 
593
                chkIsClosedList, 
594
                cboForeingKeyTableName, 
595
                cboForeingKeyCodeName, 
596
                txtForeingKeyFormula, 
597
                btnForeingKeyFormula
598
        );
599
        this.pickerIntervalEnd = swingManager.createDatePickerController(
600
                this.txtIntervalEnd,
601
                this.btnIntervalEnd
602
        );
603
        this.pickerIntervalStart = swingManager.createDatePickerController(
604
                this.txtIntervalStart,
605
                this.btnIntervalStart
606
        );
607
        this.pickerSize = evaluatorManager.createCalculatorController(
608
                this.txtSize, DataTypes.INT
609
        );
610
        this.pickerPrecision = evaluatorManager.createCalculatorController(
611
                this.txtPrecision, DataTypes.INT
612
        );
613
        this.pickerScale = evaluatorManager.createCalculatorController(
614
                this.txtScale, DataTypes.INT
615
        );
616
        this.pickerDefaultValue = evaluatorManager.createCalculatorController(
617
                this.txtDefaultValue, DataTypes.OBJECT
618
        );
619
        this.pickerOrder = evaluatorManager.createCalculatorController(
620
                this.txtOrder, DataTypes.INT
621
        );
622

    
623
        this.availableValuesController = new AvailableValuesController(
624
                lstAvailableValues,
625
                txtAvailableValuesLabel,
626
                txtAvailableValuesValue,
627
                btnAvailableValuesAdd,
628
                btnAvailableValuesUpdate,
629
                btnAvailableValuesRemove,
630
                btnAvailableValuesRemoveAll
631
        );
632
        this.tagsController = new TagsController(
633
                tblTags,
634
                cboTagsName,
635
                cboTagsValue,
636
                btnTagsAdd,
637
                btnTagsUpdate,
638
                btnTagsRemove,
639
                lblTagsDescription
640
        );
641
        this.txtMinValue.setEnabled(false);
642
        this.txtMaxValue.setEnabled(false);
643

    
644
        this.btnVirtualField.setText("");
645
        this.featureStoreElement = dataSwingManager.createFeatureStoreElement();
646
        this.pickerVirtualField = ExpressionEvaluatorSwingLocator.getManager()
647
                .createExpressionPickerController(txtVirtualField, btnVirtualField);
648
        this.pickerVirtualField.addElement(this.featureStoreElement);
649
        this.chkVirtualField.addChangeListener((ChangeEvent e) -> {
650
          if (chkVirtualField.isSelected()) {
651
            pickerVirtualField.setEditable(mode==MODE_EDIT_ALL || mode==MODE_EDIT_ONLY_METADATA);
652
          } else {
653
            pickerVirtualField.setEditable(false);
654
          }
655
        });
656

    
657
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
658
                this.txtCRS, this.btnCRS
659
        );
660

    
661
        this.cboFieldType.addItemListener((ItemEvent e) -> {
662
          SwingUtilities.invokeLater(() -> {
663
            doFieldTypeChanged();
664
          });
665
        });
666

    
667
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
668
          doCheckPrecisionAndScale();
669
        });
670
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
671
          doCheckPrecisionAndScale();
672
        });
673

    
674
        DefaultComboBoxModel dataProfilesModel = new DefaultComboBoxModel<>();
675
        dataProfilesModel.addElement(new ListElement<>("", null));
676
        for (DataProfile profile : DALLocator.getDataManager().getDataProfiles()) {
677
            dataProfilesModel.addElement(new ListElement<>(profile.getName(), profile.getID()));
678
        }
679
        this.cboDataProfile.setModel(dataProfilesModel);
680
        
681
        this.btnFieldType.addActionListener((ActionEvent e) -> {
682
          doDataTypeSelection();
683
        });
684
        
685
        DefaultComboBoxModel<ListElement<Integer>> relationTypeModel = new DefaultComboBoxModel<>();
686
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_None"),DynField.RELATION_TYPE_NONE));
687
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Identity_1_1"),DynField.RELATION_TYPE_IDENTITY));
688
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Collaboration_1_1"),DynField.RELATION_TYPE_COLLABORATION));
689
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Composition_1_N"),DynField.RELATION_TYPE_COMPOSITION));
690
        relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Aggregate_1_N"),DynField.RELATION_TYPE_AGGREGATE));
691
        this.cboRelationType.setModel(relationTypeModel);
692
    }
693

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

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

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

    
896
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
897
        descriptor.setOrder(this.pickerOrder.get(0));
898
        descriptor.setHidden(this.chkHidden.isSelected());
899
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
900
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
901

    
902
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
903
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
904
        descriptor.setAvailableValues(this.availableValuesController.get());
905

    
906
        this.tagsController.fetch(descriptor.getTags());
907
        this.foreingKeyController.fetch(descriptor.getForeingKey());
908
        return descriptor;
909
    }
910

    
911
    @Override
912
    public void clean() {
913
        this.pickerDefaultValue.set(null);
914
        this.txtFieldName.setText("");
915
//        this.pickerFieldName.set(null);
916
        this.pickerIntervalEnd.set(null);
917
        this.pickerIntervalStart.set(null);
918
        this.pickerScale.set(null);
919
        this.pickerSize.set(null);
920

    
921
        this.chkAllowNulls.setSelected(false);
922
        this.chkIsAutomatic.setSelected(false);
923
        this.chkIsPrimaryKey.setSelected(false);
924

    
925
        this.chkVirtualField.setSelected(false);
926
        this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
927
        this.pickerVirtualField.setEditable(false);
928
        this.pickerVirtualField.set(null);
929

    
930
        ListElement.setSelected(cboGeometryType, null);
931
        ListElement.setSelected(cboGeometrySubtype, null);
932

    
933
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
934

    
935
        this.cboDataProfile.setSelectedIndex(-1);
936

    
937
        this.cboGroup.setSelectedIndex(-1);
938
        this.pickerOrder.set(null);
939
        this.chkHidden.setSelected(false);
940
        this.txtLabel.setText("");
941
        this.txtDescription.setText("");
942
        this.txtMinValue.setText("");
943
        this.txtMaxValue.setText("");
944
        this.availableValuesController.clean();
945
        this.tagsController.clean();
946
        this.foreingKeyController.clean();
947
    }
948

    
949
    @Override
950
    public void put(FeatureAttributeDescriptor descriptor) {
951
        if (descriptor == null) {
952
            this.clean();
953
            return;
954
        }
955
        DataType dataType = descriptor.getDataType();
956
        FeatureType featureType = descriptor.getFeatureType();
957
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
958

    
959
        if (featureType != null) {
960
            FeatureStore store = descriptor.getFeatureType().getStore();
961
            this.featureStoreElement.setFeatureStore(store);
962
            if (store != null) {
963
                Feature sampleFeature = null;
964
                try {
965
                    sampleFeature = store.getFeatureSelection().first();
966
                    if (sampleFeature == null) {
967
                        sampleFeature = store.first();
968
                    }
969
                } catch (DataException ex) {
970
                }
971
                if (sampleFeature != null) {
972
                    FeatureSymbolTable featureSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable();
973
                    featureSymbolTable.setFeature(sampleFeature);
974
                    this.pickerVirtualField.setPreviewSymbolTable(featureSymbolTable.createParent());
975
                }
976
            }
977
            List<String> groups = new ArrayList<>();
978
            for (FeatureAttributeDescriptor otherdesc : featureType) {
979
                String group = otherdesc.getGroup();
980
                if (!StringUtils.isBlank(group) && !groups.contains(group)) {
981
                    groups.add(group);
982
                }
983
            }
984
            for (String group : groups) {
985
                groupModel.addElement(group);
986
            }
987
        }
988

    
989
        this.pickerDefaultValue.set(descriptor.getDefaultValue());
990
        this.txtFieldName.setText(descriptor.getName());
991
        RelativeInterval interval = (RelativeInterval) descriptor.getInterval();
992
        if (interval == null) {
993
            this.pickerIntervalEnd.set(null);
994
            this.pickerIntervalStart.set(null);
995
        } else {
996
            this.pickerIntervalEnd.set(interval.getEnd().toDate());
997
            this.pickerIntervalStart.set(interval.getStart().toDate());
998
        }
999
        if( dataType.supportSize() ) {
1000
          this.pickerSize.set(descriptor.getSize());
1001
        } else {
1002
          this.pickerSize.set(null);
1003
        }
1004
        if( dataType.supportPrecision() ) {
1005
          this.pickerPrecision.set(descriptor.getPrecision());
1006
        } else {
1007
          this.pickerPrecision.set(null);
1008
        }
1009
        if( dataType.supportScale()) {
1010
          this.pickerScale.set(descriptor.getScale());
1011
        } else {
1012
          this.pickerScale.set(null);
1013
        }
1014
        this.chkAllowNulls.setSelected(descriptor.allowNull());
1015
        this.chkIsAutomatic.setSelected(descriptor.isAutomatic());
1016
        this.chkIsPrimaryKey.setSelected(descriptor.isPrimaryKey());
1017

    
1018
        this.pickerVirtualField.setEnabled(true);
1019
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1020
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1021
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1022
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1023
            this.chkVirtualField.setSelected(true);
1024
            this.pickerVirtualField.set(expression);
1025
        } else if (descriptor.isComputed()) {
1026
            this.chkVirtualField.setEnabled(false);
1027
            this.chkVirtualField.setSelected(true);
1028
            this.pickerVirtualField.set(null);
1029
        } else {
1030
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1031
            this.chkVirtualField.setSelected(false);
1032
            this.pickerVirtualField.set(null);
1033
        }
1034

    
1035
        this.pickerCRS.set(descriptor.getSRS());
1036

    
1037
        if (descriptor.getGeomType() != null) {
1038
            ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1039
            ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1040
        }
1041
        ListElement.setSelected(cboFieldType, dataType.getType());
1042
        if( ListElement.getSelected(cboFieldType)==null ) {
1043
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1044
          ListElement.setSelected(cboFieldType, dataType.getType());
1045
        }
1046
 
1047
        ListElement.setSelected(cboRelationType, descriptor.getRelationType());
1048

    
1049
        String profile = descriptor.getDataProfileName();
1050
        if (StringUtils.isBlank(profile)) {
1051
            this.cboDataProfile.setSelectedIndex(-1);
1052
        } else {
1053
            ListElement.setSelected(this.cboDataProfile, profile);
1054
        }
1055

    
1056
        this.cboGroup.setModel(groupModel);
1057
        this.cboGroup.setSelectedItem(StringUtils.defaultIfBlank(descriptor.getGroup(), ""));
1058
        this.pickerOrder.set(descriptor.getOder());
1059
        this.chkHidden.setSelected(descriptor.isHidden());
1060
        if (descriptor.hasLabel()) {
1061
            this.txtLabel.setText(StringUtils.defaultIfBlank(descriptor.getLabel(), ""));
1062
        } else {
1063
            this.txtLabel.setText("");
1064
        }
1065
        if (descriptor.hasDescription()) {
1066
            this.txtDescription.setText(StringUtils.defaultIfBlank(descriptor.getDescription(), ""));
1067
        } else {
1068
            this.txtDescription.setText("");
1069
        }
1070
        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1071
        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1072
        if( descriptor.hasConstantAvailableValues() ) {
1073
          this.availableValuesController.set(descriptor.getAvailableValues());
1074
        } else {
1075
          this.availableValuesController.clean();
1076
        }
1077
        this.tagsController.set(descriptor.getTags());
1078

    
1079
        this.foreingKeyController.put(descriptor.getForeingKey());
1080
        
1081
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1082
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1083
        }
1084
        this.updateEditableStates();
1085
    }
1086

    
1087
    private DataType getDataType() {
1088
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1089
      if (fieldType == null) {
1090
          return null;
1091
      }
1092
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1093
      return dataType;
1094
    }
1095

    
1096
    private void doFieldTypeChanged() {
1097
      try {
1098
        DataType dataType = this.getDataType();
1099

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

    
1180
    }
1181
    
1182
    boolean isVirtualField() {
1183
        return this.chkVirtualField.isSelected();
1184
    }
1185

    
1186
    @Override
1187
    public int getMode() {
1188
        return this.mode;
1189
    }
1190
    
1191
    @Override
1192
    public void setMode(int mode) {
1193
        this.mode = mode;
1194
        updateEditableStates();
1195
    }
1196
    
1197
    private void updateEditableStates() {
1198
        DataType dataType = this.getDataType();
1199
        switch(this.mode) {
1200
            case MODE_EDIT_ALL:
1201
                this.pickerDefaultValue.setEditable(true);
1202
                this.txtFieldName.setEditable(true);
1203
                this.pickerIntervalEnd.setEditable(true);
1204
                this.pickerIntervalStart.setEditable(true);
1205
                this.pickerSize.setEditable(dataType.supportSize());
1206
                if( dataType.isPredefinedPrecision() ) {
1207
                  this.pickerPrecision.setEditable(false);
1208
                  this.pickerPrecision.set(dataType.getMaxPrecision());
1209
                } else {
1210
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
1211
                }
1212
                this.pickerScale.setEditable(dataType.supportScale());
1213
                this.cboDataProfile.setEnabled(true);
1214

    
1215
                this.chkAllowNulls.setEnabled(true);
1216
                this.chkIsAutomatic.setEnabled(true);
1217
                if( this.isVirtualField() ) {
1218
                    this.chkIsPrimaryKey.setEnabled(false);
1219
                } else {
1220
                    this.chkIsPrimaryKey.setEnabled(true);
1221
                }
1222

    
1223
                this.chkVirtualField.setEnabled(true);
1224
                this.pickerVirtualField.setEditable(true);
1225

    
1226
                this.cboDateFormat.setEnabled(true);
1227
                this.cboFieldType.setEnabled(true);
1228
                this.cboGeometryType.setEnabled(true);
1229
                this.cboGeometrySubtype.setEnabled(true);
1230
                this.pickerCRS.setEditable(true);
1231

    
1232
                this.cboGroup.setEnabled(true);
1233
                this.pickerOrder.setEditable(true);
1234
                this.chkHidden.setEnabled(true);
1235
                this.txtLabel.setEditable(true);
1236
                this.txtDescription.setEditable(true);
1237
                this.txtMinValue.setEditable(false);
1238
                this.txtMaxValue.setEditable(false);
1239
                this.availableValuesController.setEditable(true);
1240
                this.tagsController.setEditable(true);
1241
                this.foreingKeyController.setEditable(true);
1242
                break;
1243
            case MODE_EDIT_ONLY_METADATA:
1244
                if( this.chkVirtualField.isSelected() ) {
1245
                    this.txtFieldName.setEditable(true);
1246
                    this.pickerScale.setEditable(true);
1247
                    this.pickerSize.setEditable(true);
1248
                    this.pickerVirtualField.setEditable(true);
1249
                    this.cboFieldType.setEnabled(true);
1250
                    this.cboGeometryType.setEnabled(true);
1251
                    this.cboGeometrySubtype.setEnabled(true);
1252
                    this.pickerCRS.setEditable(true);
1253
                } else {
1254
                    this.txtFieldName.setEditable(false);
1255
                    this.pickerPrecision.setEditable(false);
1256
                    this.pickerScale.setEditable(false);
1257
                    this.pickerSize.setEditable(false);
1258
                    this.pickerVirtualField.setEditable(false);
1259
                    this.cboFieldType.setEnabled(false);
1260
                    this.cboGeometryType.setEnabled(false);
1261
                    this.cboGeometrySubtype.setEnabled(false);
1262
                    this.pickerCRS.setEditable(false);
1263
                }
1264

    
1265
                this.pickerDefaultValue.setEditable(true);
1266
                this.pickerIntervalEnd.setEditable(true);
1267
                this.pickerIntervalStart.setEditable(true);
1268

    
1269
                this.cboDataProfile.setEnabled(true);
1270

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

    
1279
                this.chkVirtualField.setEnabled(false);
1280

    
1281
                this.cboDateFormat.setEnabled(true);
1282

    
1283
                this.cboGroup.setEnabled(true);
1284
                this.pickerOrder.setEditable(true);
1285
                this.chkHidden.setEnabled(true);
1286
                this.txtLabel.setEditable(true);
1287
                this.txtDescription.setEditable(true);
1288
                this.txtMinValue.setEditable(false);
1289
                this.txtMaxValue.setEditable(false);
1290
                this.availableValuesController.setEditable(true);
1291
                this.tagsController.setEditable(true);
1292
                this.foreingKeyController.setEditable(true);
1293
                break;
1294
            case MODE_SHOW_ONLY:
1295
                this.pickerDefaultValue.setEditable(false);
1296
                this.txtFieldName.setEditable(false);
1297
                this.pickerIntervalEnd.setEditable(false);
1298
                this.pickerIntervalStart.setEditable(false);
1299
                this.pickerPrecision.setEditable(false);
1300
                this.pickerScale.setEditable(false);
1301
                this.pickerSize.setEditable(false);
1302
                this.cboDataProfile.setEnabled(false);
1303

    
1304
                this.chkAllowNulls.setEnabled(false);
1305
                this.chkIsAutomatic.setEnabled(false);
1306
                this.chkIsPrimaryKey.setEnabled(false);
1307

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

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

    
1317
                this.cboGroup.setEnabled(false);
1318
                this.pickerOrder.setEditable(false);
1319
                this.chkHidden.setEnabled(false);
1320
                this.txtLabel.setEditable(false);
1321
                this.txtDescription.setEditable(false);
1322
                this.txtMinValue.setEditable(false);
1323
                this.txtMaxValue.setEditable(false);
1324
                this.availableValuesController.setEditable(false);
1325
                this.tagsController.setEditable(false);
1326
                this.foreingKeyController.setEditable(false);
1327
                break;
1328
        }
1329
    }
1330

    
1331
    private void doCheckPrecisionAndScale() {
1332
      DataType dataType = this.getDataType();
1333
      
1334
      Integer precision = this.pickerPrecision.get();
1335
      if( precision==null ) {
1336
        precision = 0;
1337
      }
1338
      Integer scale = this.pickerScale.get();
1339
      if( scale == null ) {
1340
        scale = 0;
1341
      }      
1342
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
1343
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
1344
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
1345
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
1346
      } else {
1347
        this.pickerPrecision.setWarning(false);
1348
        this.pickerScale.setWarning(false);
1349
      }
1350
    }
1351

    
1352
    @Override
1353
    public void setNameAsNew(FeatureType featureType) {
1354
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
1355
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
1356
                cloneFeatureType.getNewFieldName(), 
1357
                DataTypes.STRING);
1358
        this.put(newAttributeDescriptor);
1359
    }
1360

    
1361
    @Override
1362
    public String getName() {
1363
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
1364
    }
1365

    
1366
    @Override
1367
    public ImageIcon loadImage(String imageName) {
1368
        String name = FilenameUtils.getBaseName(imageName);
1369
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1370
        if (theme.exists(name)) {
1371
            return theme.get(name);
1372
        }
1373
        URL url = this.getClass().getResource(name + ".png");
1374
        if (url == null) {
1375
            return null;
1376
        }
1377
        return new ImageIcon(url);
1378
    }
1379

    
1380
  public static void selfRegister() {
1381
    String[][] iconNames = new String[][]{
1382
      new String[]{"dalswing", "picker-datatype"},};
1383
    IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1384
    for (String[] icon : iconNames) {
1385
      URL url = DefaultFeatureAttributeSelectionPanel.class.getResource(icon[1] + ".png");
1386
      theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1387
    }
1388
    
1389
  }
1390

    
1391
}