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

History | View | Annotate | Download (62.7 KB)

1
package org.gvsig.fmap.dal.swing.impl.featuretype;
2

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

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

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

    
109
    private static class ForeingKeyController {
110

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

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

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

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

    
286
    private static class AvailableValuesController {
287

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

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

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

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

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

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

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

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

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

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

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

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

    
426
    }
427

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

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

    
445
    private int mode;
446
    private FeatureStoreElement featureStoreElement;
447

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

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

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

    
486
        this.initComponents();
487
    }
488

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

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

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

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

    
530
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
531

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

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

    
577
        swingManager.translate(this.txtDisplaySize);
578
        swingManager.translate(this.txtPrecision);
579
        swingManager.translate(this.txtScale);
580
        swingManager.translate(this.txtScale);
581

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

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

    
610
        swingManager.setDefaultPopupMenu(this.cboForeingKeyCodeName);
611
        swingManager.setDefaultPopupMenu(this.cboForeingKeyTableName);
612

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

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

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

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

    
690
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
691
                this.txtCRS, this.btnCRS
692
        );
693

    
694
        this.cboFieldType.addItemListener((ItemEvent e) -> {
695
          SwingUtilities.invokeLater(() -> {
696
            doFieldTypeChanged();
697
          });
698
        });
699

    
700
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
701
          doCheckPrecisionAndScale();
702
        });
703
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
704
          doCheckPrecisionAndScale();
705
        });
706

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

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

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

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

    
930
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
931
        descriptor.setOrder(this.pickerOrder.get(0));
932
        descriptor.setHidden(this.chkHidden.isSelected());
933
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
934
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
935

    
936
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
937
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
938
        descriptor.setAvailableValues(this.availableValuesController.get());
939

    
940
        this.tagsController.fetch(descriptor.getTags());
941
        this.foreingKeyController.fetch(descriptor.getForeingKey());
942
        return descriptor;
943
    }
944

    
945
    @Override
946
    public void clean() {
947
        this.txtDefaultValue.setText("");
948
        this.txtFieldName.setText("");
949
//        this.pickerFieldName.set(null);
950
        this.pickerIntervalEnd.set(null);
951
        this.pickerIntervalStart.set(null);
952
        this.pickerScale.set(null);
953
        this.pickerSize.set(null);
954
        this.pickerDisplaySize.set(null);
955

    
956
        this.chkAllowNulls.setSelected(false);
957
        this.chkIsAutomatic.setSelected(false);
958
        this.chkIsPrimaryKey.setSelected(false);
959

    
960
        this.chkVirtualField.setSelected(false);
961
        this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
962
        this.pickerVirtualField.setEditable(false);
963
        this.pickerVirtualField.set(null);
964

    
965
        ListElement.setSelected(cboGeometryType, null);
966
        ListElement.setSelected(cboGeometrySubtype, null);
967

    
968
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
969

    
970
        this.cboDataProfile.setSelectedIndex(-1);
971

    
972
        this.cboGroup.setSelectedIndex(-1);
973
        this.pickerOrder.set(null);
974
        this.chkHidden.setSelected(false);
975
        this.txtLabel.setText("");
976
        this.txtDescription.setText("");
977
        this.txtMinValue.setText("");
978
        this.txtMaxValue.setText("");
979
        this.availableValuesController.clean();
980
        this.tagsController.clean();
981
        this.foreingKeyController.clean();
982
    }
983

    
984
    @Override
985
    public void put(FeatureAttributeDescriptor descriptor) {
986
        if (descriptor == null) {
987
            this.clean();
988
            return;
989
        }
990
        DataType dataType = descriptor.getDataType();
991
        FeatureType featureType = descriptor.getFeatureType();
992
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
993

    
994
        if (featureType != null) {
995
            FeatureStore store = descriptor.getFeatureType().getStore();
996
            this.featureStoreElement.setFeatureStore(store);
997
            if (store != null) {
998
                Feature sampleFeature = null;
999
                try {
1000
                    sampleFeature = store.getFeatureSelection().first();
1001
                    if (sampleFeature == null) {
1002
                        sampleFeature = store.first();
1003
                    }
1004
                } catch (DataException ex) {
1005
                }
1006
                if (sampleFeature != null) {
1007
                    FeatureSymbolTable featureSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable();
1008
                    featureSymbolTable.setFeature(sampleFeature);
1009
                    this.pickerVirtualField.setPreviewSymbolTable(featureSymbolTable.createParent());
1010
                }
1011
            }
1012
            List<String> groups = new ArrayList<>();
1013
            for (FeatureAttributeDescriptor otherdesc : featureType) {
1014
                String group = otherdesc.getGroup();
1015
                if (!StringUtils.isBlank(group) && !groups.contains(group)) {
1016
                    groups.add(group);
1017
                }
1018
            }
1019
            for (String group : groups) {
1020
                groupModel.addElement(group);
1021
            }
1022
        }
1023

    
1024
        this.txtDefaultValue.setText(Objects.toString(descriptor.getDefaultValue(),""));
1025
        this.txtFieldName.setText(descriptor.getName());
1026
        RelativeInterval interval = (RelativeInterval) descriptor.getInterval();
1027
        if (interval == null) {
1028
            this.pickerIntervalEnd.set(null);
1029
            this.pickerIntervalStart.set(null);
1030
        } else {
1031
            this.pickerIntervalEnd.set(interval.getEnd().toDate());
1032
            this.pickerIntervalStart.set(interval.getStart().toDate());
1033
        }
1034
        if( dataType.supportSize() ) {
1035
          this.pickerSize.set(descriptor.getSize());
1036
        } else {
1037
          this.pickerSize.set(null);
1038
        }
1039
        this.pickerDisplaySize.set(descriptor.getDisplaySize());
1040
        if( dataType.supportPrecision() ) {
1041
          this.pickerPrecision.set(descriptor.getPrecision());
1042
        } else {
1043
          this.pickerPrecision.set(null);
1044
        }
1045
        if( dataType.supportScale()) {
1046
          this.pickerScale.set(descriptor.getScale());
1047
        } else {
1048
          this.pickerScale.set(null);
1049
        }
1050
        this.chkAllowNulls.setSelected(descriptor.allowNull());
1051
        this.chkIsAutomatic.setSelected(descriptor.isAutomatic());
1052
        this.chkIsPrimaryKey.setSelected(descriptor.isPrimaryKey());
1053

    
1054
        this.pickerVirtualField.setEnabled(true);
1055
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1056
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1057
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1058
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1059
            this.chkVirtualField.setSelected(true);
1060
            this.pickerVirtualField.set(expression);
1061
        } else if (descriptor.isComputed()) {
1062
            this.chkVirtualField.setEnabled(false);
1063
            this.chkVirtualField.setSelected(true);
1064
            this.pickerVirtualField.set(null);
1065
        } else {
1066
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1067
            this.chkVirtualField.setSelected(false);
1068
            this.pickerVirtualField.set(null);
1069
        }
1070

    
1071
        this.pickerCRS.set(descriptor.getSRS());
1072

    
1073
        if (descriptor.getGeomType() != null) {
1074
            ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1075
            ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1076
        }
1077
        ListElement.setSelected(cboFieldType, dataType.getType());
1078
        if( ListElement.getSelected(cboFieldType)==null ) {
1079
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1080
          ListElement.setSelected(cboFieldType, dataType.getType());
1081
        }
1082
 
1083
        ListElement.setSelected(cboRelationType, descriptor.getRelationType());
1084

    
1085
        String profile = descriptor.getDataProfileName();
1086
        if (StringUtils.isBlank(profile)) {
1087
            this.cboDataProfile.setSelectedIndex(-1);
1088
        } else {
1089
            ListElement.setSelected(this.cboDataProfile, profile);
1090
        }
1091

    
1092
        this.cboGroup.setModel(groupModel);
1093
        this.cboGroup.setSelectedItem(StringUtils.defaultIfBlank(descriptor.getGroup(), ""));
1094
        this.pickerOrder.set(descriptor.getOder());
1095
        this.chkHidden.setSelected(descriptor.isHidden());
1096
        if (descriptor.hasLabel()) {
1097
            this.txtLabel.setText(StringUtils.defaultIfBlank(descriptor.getLabel(), ""));
1098
        } else {
1099
            this.txtLabel.setText("");
1100
        }
1101
        if (descriptor.hasDescription()) {
1102
            this.txtDescription.setText(StringUtils.defaultIfBlank(descriptor.getDescription(), ""));
1103
        } else {
1104
            this.txtDescription.setText("");
1105
        }
1106
        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1107
        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1108
        if( descriptor.hasConstantAvailableValues() ) {
1109
          this.availableValuesController.set(descriptor.getAvailableValues());
1110
        } else {
1111
          this.availableValuesController.clean();
1112
        }
1113
        this.tagsController.set(descriptor.getTags());
1114

    
1115
        this.foreingKeyController.put(descriptor.getForeingKey());
1116
        
1117
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1118
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1119
        }
1120
        this.updateEditableStates();
1121
    }
1122

    
1123
    private DataType getDataType() {
1124
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1125
      if (fieldType == null) {
1126
          return null;
1127
      }
1128
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1129
      return dataType;
1130
    }
1131

    
1132
    private void doFieldTypeChanged() {
1133
      try {
1134
        DataType dataType = this.getDataType();
1135

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

    
1217
    }
1218
    
1219
    boolean isVirtualField() {
1220
        return this.chkVirtualField.isSelected();
1221
    }
1222

    
1223
    @Override
1224
    public int getMode() {
1225
        return this.mode;
1226
    }
1227
    
1228
    @Override
1229
    public void setMode(int mode) {
1230
        this.mode = mode;
1231
        updateEditableStates();
1232
    }
1233
    
1234
    private void updateEditableStates() {
1235
        DataType dataType = this.getDataType();
1236
        switch(this.mode) {
1237
            case MODE_EDIT_ALL:
1238
                this.cboRelationType.setEnabled(true);
1239
                this.txtDefaultValue.setEditable(true);
1240
                this.txtFieldName.setEditable(true);
1241
                this.pickerIntervalEnd.setEditable(true);
1242
                this.pickerIntervalStart.setEditable(true);
1243
                this.pickerSize.setEditable(dataType.supportSize());
1244
                this.pickerDisplaySize.setEditable(true);
1245
                if( dataType.isPredefinedPrecision() ) {
1246
                  this.pickerPrecision.setEditable(false);
1247
                  this.pickerPrecision.set(dataType.getMaxPrecision());
1248
                } else {
1249
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
1250
                }
1251
                this.pickerScale.setEditable(dataType.supportScale());
1252
                this.cboDataProfile.setEnabled(true);
1253

    
1254
                this.chkAllowNulls.setEnabled(true);
1255
                this.chkIsAutomatic.setEnabled(true);
1256
                if( this.isVirtualField() ) {
1257
                    this.chkIsPrimaryKey.setEnabled(false);
1258
                } else {
1259
                    this.chkIsPrimaryKey.setEnabled(true);
1260
                }
1261

    
1262
                this.chkVirtualField.setEnabled(true);
1263
                this.pickerVirtualField.setEditable(true);
1264

    
1265
                this.cboDateFormat.setEnabled(true);
1266
                this.cboFieldType.setEnabled(true);
1267
                this.cboGeometryType.setEnabled(true);
1268
                this.cboGeometrySubtype.setEnabled(true);
1269
                this.pickerCRS.setEditable(true);
1270

    
1271
                this.cboGroup.setEnabled(true);
1272
                this.pickerOrder.setEditable(true);
1273
                this.chkHidden.setEnabled(true);
1274
                this.txtLabel.setEditable(true);
1275
                this.txtDescription.setEditable(true);
1276
                this.txtMinValue.setEditable(false);
1277
                this.txtMaxValue.setEditable(false);
1278
                this.availableValuesController.setEditable(true);
1279
                this.tagsController.setEditable(true);
1280
                this.foreingKeyController.setEditable(true);
1281
                break;
1282
            case MODE_EDIT_ONLY_METADATA:
1283
                if( this.chkVirtualField.isSelected() ) {
1284
                    this.txtFieldName.setEditable(true);
1285
                    this.pickerScale.setEditable(true);
1286
                    this.pickerSize.setEditable(true);
1287
                    this.pickerVirtualField.setEditable(true);
1288
                    this.cboFieldType.setEnabled(true);
1289
                    this.cboGeometryType.setEnabled(true);
1290
                    this.cboGeometrySubtype.setEnabled(true);
1291
                    this.pickerCRS.setEditable(true);
1292
                } else {
1293
                    this.txtFieldName.setEditable(false);
1294
                    this.pickerPrecision.setEditable(false);
1295
                    this.pickerScale.setEditable(false);
1296
                    this.pickerSize.setEditable(false);
1297
                    this.pickerVirtualField.setEditable(false);
1298
                    this.cboFieldType.setEnabled(false);
1299
                    this.cboGeometryType.setEnabled(false);
1300
                    this.cboGeometrySubtype.setEnabled(false);
1301
                    this.pickerCRS.setEditable(false);
1302
                }
1303

    
1304
                this.cboRelationType.setEnabled(true);
1305
                this.txtDefaultValue.setEditable(true);
1306
                this.pickerIntervalEnd.setEditable(true);
1307
                this.pickerIntervalStart.setEditable(true);
1308

    
1309
                this.cboDataProfile.setEnabled(true);
1310

    
1311
                this.pickerDisplaySize.setEditable(false);
1312
                this.chkAllowNulls.setEnabled(false);
1313
                this.chkIsAutomatic.setEnabled(false);
1314
                if( this.isVirtualField() ) {
1315
                    this.chkIsPrimaryKey.setEnabled(false);
1316
                } else {
1317
                    this.chkIsPrimaryKey.setEnabled(true);
1318
                }
1319

    
1320
                this.chkVirtualField.setEnabled(false);
1321

    
1322
                this.cboDateFormat.setEnabled(true);
1323

    
1324
                this.cboGroup.setEnabled(true);
1325
                this.pickerOrder.setEditable(true);
1326
                this.chkHidden.setEnabled(true);
1327
                this.txtLabel.setEditable(true);
1328
                this.txtDescription.setEditable(true);
1329
                this.txtMinValue.setEditable(false);
1330
                this.txtMaxValue.setEditable(false);
1331
                this.availableValuesController.setEditable(true);
1332
                this.tagsController.setEditable(true);
1333
                this.foreingKeyController.setEditable(true);
1334
                break;
1335
            case MODE_SHOW_ONLY:
1336
                this.cboRelationType.setEnabled(false);
1337
                this.txtDefaultValue.setEditable(false);
1338
                this.txtFieldName.setEditable(false);
1339
                this.pickerIntervalEnd.setEditable(false);
1340
                this.pickerIntervalStart.setEditable(false);
1341
                this.pickerPrecision.setEditable(false);
1342
                this.pickerScale.setEditable(false);
1343
                this.pickerSize.setEditable(false);
1344
                this.pickerDisplaySize.setEditable(false);
1345
                this.cboDataProfile.setEnabled(false);
1346

    
1347
                this.chkAllowNulls.setEnabled(false);
1348
                this.chkIsAutomatic.setEnabled(false);
1349
                this.chkIsPrimaryKey.setEnabled(false);
1350

    
1351
                this.chkVirtualField.setEnabled(false);
1352
                this.pickerVirtualField.setEditable(false);
1353

    
1354
                this.cboDateFormat.setEnabled(false);
1355
                this.cboFieldType.setEnabled(false);
1356
                this.cboGeometryType.setEnabled(false);
1357
                this.cboGeometrySubtype.setEnabled(false);
1358
                this.pickerCRS.setEditable(false);
1359

    
1360
                this.cboGroup.setEnabled(false);
1361
                this.pickerOrder.setEditable(false);
1362
                this.chkHidden.setEnabled(false);
1363
                this.txtLabel.setEditable(false);
1364
                this.txtDescription.setEditable(false);
1365
                this.txtMinValue.setEditable(false);
1366
                this.txtMaxValue.setEditable(false);
1367
                this.availableValuesController.setEditable(false);
1368
                this.tagsController.setEditable(false);
1369
                this.foreingKeyController.setEditable(false);
1370
                break;
1371
        }
1372
    }
1373

    
1374
    private void doCheckPrecisionAndScale() {
1375
      DataType dataType = this.getDataType();
1376
      
1377
      Integer precision = this.pickerPrecision.get();
1378
      if( precision==null ) {
1379
        precision = 0;
1380
      }
1381
      Integer scale = this.pickerScale.get();
1382
      if( scale == null ) {
1383
        scale = 0;
1384
      }      
1385
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
1386
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
1387
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
1388
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
1389
      } else {
1390
        this.pickerPrecision.setWarning(false);
1391
        this.pickerScale.setWarning(false);
1392
      }
1393
    }
1394

    
1395
    @Override
1396
    public void setNameAsNew(FeatureType featureType) {
1397
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
1398
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
1399
                cloneFeatureType.getNewFieldName(), 
1400
                DataTypes.STRING);
1401
        this.put(newAttributeDescriptor);
1402
    }
1403

    
1404
    @Override
1405
    public String getName() {
1406
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
1407
    }
1408

    
1409
    @Override
1410
    public ImageIcon loadImage(String imageName) {
1411
        String name = FilenameUtils.getBaseName(imageName);
1412
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1413
        if (theme.exists(name)) {
1414
            return theme.get(name);
1415
        }
1416
        URL url = this.getClass().getResource(name + ".png");
1417
        if (url == null) {
1418
            return null;
1419
        }
1420
        return new ImageIcon(url);
1421
    }
1422

    
1423
  public static void selfRegister() {
1424
    String[][] iconNames = new String[][]{
1425
      new String[]{"dalswing", "picker-datatype"},};
1426
    IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1427
    for (String[] icon : iconNames) {
1428
      URL url = DefaultFeatureAttributeSelectionPanel.class.getResource(icon[1] + ".png");
1429
      theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1430
    }
1431
    
1432
  }
1433

    
1434
}