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

History | View | Annotate | Download (102 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.ItemEvent;
6
import java.util.ArrayList;
7
import java.util.Collections;
8
import java.util.List;
9
import java.util.Locale;
10
import java.util.Objects;
11
import javax.swing.DefaultComboBoxModel;
12
import javax.swing.DefaultListCellRenderer;
13
import javax.swing.DefaultListModel;
14
import javax.swing.ImageIcon;
15
import javax.swing.JButton;
16
import javax.swing.JCheckBox;
17
import javax.swing.JComboBox;
18
import javax.swing.JComponent;
19
import javax.swing.JLabel;
20
import javax.swing.JList;
21
import javax.swing.JOptionPane;
22
import javax.swing.JScrollPane;
23
import javax.swing.JSplitPane;
24
import javax.swing.JTextField;
25
import javax.swing.ListModel;
26
import javax.swing.SwingUtilities;
27
import javax.swing.UIManager;
28
import javax.swing.event.ChangeEvent;
29
import javax.swing.event.ListSelectionEvent;
30
import javax.swing.text.JTextComponent;
31
import org.apache.commons.lang3.ArrayUtils;
32
import org.apache.commons.lang3.StringUtils;
33
import org.apache.commons.lang3.tuple.ImmutablePair;
34
import org.apache.commons.lang3.tuple.Pair;
35
import org.cresques.cts.IProjection;
36
import org.gvsig.expressionevaluator.Code;
37
import org.gvsig.expressionevaluator.Code.Callable;
38
import org.gvsig.expressionevaluator.Code.Constant;
39
import org.gvsig.expressionevaluator.Code.Identifier;
40
import org.gvsig.expressionevaluator.Codes;
41
import org.gvsig.expressionevaluator.Expression;
42
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_GETATTR;
43
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_EQ;
44
import org.gvsig.expressionevaluator.ExpressionUtils;
45
import org.gvsig.expressionevaluator.swing.CalculatorController;
46
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingLocator;
47
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
48
import org.gvsig.expressionevaluator.swing.ExpressionPickerController;
49
import org.gvsig.fmap.dal.DALLocator;
50
import org.gvsig.fmap.dal.DataManager;
51
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT;
52
import org.gvsig.fmap.dal.DataStore;
53
import org.gvsig.fmap.dal.DataStoreProviderFactory;
54
import org.gvsig.fmap.dal.DataTypes;
55
import org.gvsig.fmap.dal.SQLBuilder;
56
import org.gvsig.fmap.dal.StoresRepository;
57
import static org.gvsig.fmap.dal.complements.RelatedFeatures.DAL_RELATED_TABLE;
58
import static org.gvsig.fmap.dal.complements.RelatedFeatures.DAL_RELATED_UNIQUE_FIELD_NAME;
59
import org.gvsig.fmap.dal.exception.DataException;
60
import org.gvsig.fmap.dal.expressionevaluator.DALExpressionBuilder;
61
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
62
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
63
import org.gvsig.fmap.dal.feature.DataProfile;
64
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
65
import org.gvsig.fmap.dal.feature.EditableFeatureType;
66
import org.gvsig.fmap.dal.feature.EditableForeingKey;
67
import org.gvsig.fmap.dal.feature.Feature;
68
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
69
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
70
import org.gvsig.fmap.dal.feature.FeatureStore;
71
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
72
import org.gvsig.fmap.dal.feature.FeatureType;
73
import org.gvsig.fmap.dal.feature.ForeingKey;
74
import org.gvsig.fmap.dal.swing.DALSwingLocator;
75
import org.gvsig.fmap.dal.swing.DataSwingManager;
76
import org.gvsig.fmap.dal.swing.expressionevaluator.FeatureStoreElement;
77
import org.gvsig.fmap.dal.swing.featuretype.AttributeDescriptorAndExpressionPickerController;
78
import org.gvsig.fmap.dal.swing.featuretype.AttributeDescriptorPickerController;
79
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypeAttributePanel;
80
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel;
81
import static org.gvsig.fmap.dal.swing.impl.DefaultDALSwingLibrary.LIBRARY_NAME;
82
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.Tag;
83
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.TagController;
84
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.TagsModel;
85
import org.gvsig.fmap.geom.Geometry;
86
import org.gvsig.fmap.geom.GeometryLocator;
87
import org.gvsig.fmap.geom.GeometryManager;
88
import org.gvsig.fmap.geom.type.GeometryType;
89
import org.gvsig.timesupport.RelativeInterval;
90
import org.gvsig.tools.ToolsLocator;
91
import org.gvsig.tools.dataTypes.DataType;
92
import org.gvsig.tools.dataTypes.DataType.NumberPrecisionAndScale;
93
import org.gvsig.tools.dataTypes.DataTypesManager;
94
import org.gvsig.tools.dynobject.DynField;
95
import org.gvsig.tools.dynobject.DynObjectValueItem;
96
import org.gvsig.tools.dynobject.Tags;
97
import org.gvsig.tools.i18n.I18nManager;
98
import org.gvsig.tools.swing.api.ListElement;
99
import org.gvsig.tools.swing.api.ToolsSwingLocator;
100
import org.gvsig.tools.swing.api.ToolsSwingManager;
101
import org.gvsig.tools.swing.api.ToolsSwingUtils;
102
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
103
import org.gvsig.tools.swing.api.pickercontroller.PickerController;
104
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
105
import org.gvsig.tools.swing.api.windowmanager.Dialog;
106
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
107
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
108
import org.gvsig.tools.swing.icontheme.IconTheme;
109
import org.gvsig.tools.util.LabeledValue;
110
import org.gvsig.tools.util.LabeledValueImpl;
111
import org.slf4j.Logger;
112
import org.slf4j.LoggerFactory;
113

    
114
/**
115
 *
116
 * @author jjdelcerro
117
 */
118
@SuppressWarnings({"UseSpecificCatch"})
119
public class DefaultFeatureAttributePanel
120
        extends DefaultFeatureAttributePanelView
121
        implements FeatureTypeAttributePanel {
122

    
123
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureAttributePanel.class);
124
    
125
    // ----
126
    // Los he eliminado del GUI pero los mantengo aqui por si decido rescatarlos
127
    private final JTextComponent txtMaxValue = new JTextField();
128
    private final JTextComponent txtMinValue = new JTextField();
129
    private final JComponent lblMinValue = new JLabel();
130
    private final JComponent lblMaxValue = new JLabel();
131
    // ----
132
    private Feature sampleFeature;
133
    private String previousDefaultValue;
134
    private ToManyController toManyController;
135
    private JSplitPane splAttrTags;
136
    private FeatureType featureType;
137

    
138
    private static class ToOneController {
139

    
140
        private final JTextComponent txtMyFieldName;
141
        private final JComboBox cboRelationType;
142
        private final JCheckBox chkIsClosedList;
143
        private final JComboBox cboTable;
144
        private final JComboBox cboForeignField;
145
        private final JComboBox cboFormula;
146
        private final JButton btnFormula;
147
        private final JButton btnFormulaHistory;
148
        private final JButton btnFormulaBokkmarks;
149
        private AttributeDescriptorAndExpressionPickerController pickerFormula;
150
        private AttributeDescriptorPickerController pickerCode;
151
        private boolean editable;
152
        private ForeingKey foreingKey;
153
        
154
        public ToOneController(
155
                JTextComponent txtMyFieldName,
156
                JComboBox cboRelationType,
157
                JCheckBox chkIsClosedList,
158
                JComboBox cboTable,
159
                JComboBox cboCode,
160
                JComboBox cboFormula,
161
                JButton btnFormula,
162
                JButton btnFormulaBokkmarks,
163
                JButton btnFormulaHistory
164
        ) {
165
            this.txtMyFieldName = txtMyFieldName;
166
            this.cboRelationType = cboRelationType;
167
            this.chkIsClosedList = chkIsClosedList;
168
            this.cboTable = cboTable;
169
            this.cboForeignField = cboCode;
170
            this.cboFormula = cboFormula;
171
            this.btnFormula = btnFormula;
172
            this.btnFormulaHistory = btnFormulaHistory;
173
            this.btnFormulaBokkmarks = btnFormulaBokkmarks;
174
            this.initComponents();
175
        }
176

    
177
        private void initComponents() {
178
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
179
            I18nManager i18n = ToolsLocator.getI18nManager();
180
    
181
            this.editable = true;
182
            DefaultComboBoxModel<ListElement<Integer>> relationTypeModel = new DefaultComboBoxModel<>();
183
//            relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_None"),DynField.RELATION_TYPE_NONE));
184
            relationTypeModel.addElement(new ListElement<>(DynField.RELATION_TYPE_IDENTITY + " - "+i18n.getTranslation("_Identity_1_1"),DynField.RELATION_TYPE_IDENTITY));
185
            relationTypeModel.addElement(new ListElement<>(DynField.RELATION_TYPE_COLLABORATION + " - "+i18n.getTranslation("_Collaboration_1_1_without_composition"),DynField.RELATION_TYPE_COLLABORATION));
186
            relationTypeModel.addElement(new ListElement<>(DynField.RELATION_TYPE_COLLABORATION_WITH_COMPOSITION + " - "+i18n.getTranslation("_Collaboration_1_1_with_composition"),DynField.RELATION_TYPE_COLLABORATION_WITH_COMPOSITION));
187
//            relationTypeModel.addElement(new ListElement<>(DynField.RELATION_TYPE_AGGREGATE_WITH_COMPOSITION + " - "+i18n.getTranslation("_Aggregate_1_N_without_composition"),DynField.RELATION_TYPE_AGGREGATE_WITH_COMPOSITION));
188
//            relationTypeModel.addElement(new ListElement<>(DynField.RELATION_TYPE_AGGREGATE + " - "+i18n.getTranslation("_Aggregate_1_N_with_composition"),DynField.RELATION_TYPE_AGGREGATE));
189
            this.cboRelationType.setModel(relationTypeModel);
190
            this.cboRelationType.addActionListener((ActionEvent e) -> {
191
                updateEnabledState();
192
            });
193
        
194
            DefaultComboBoxModel<String> model = new DefaultComboBoxModel();
195
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
196
            List<String> tableNames = new ArrayList<>();
197
            for (String tableName : repository.keySet()) {
198
                tableNames.add(tableName);
199
            }
200
            Collections.sort(tableNames);
201
            for (String tableName : tableNames) {
202
                model.addElement(tableName);
203
            }
204
            this.cboTable.setEditable(false);
205
            this.cboTable.setModel(model);
206
            this.cboTable.addItemListener((ItemEvent e) -> {
207
              updateEnabledState();
208
              if (e.getStateChange() != ItemEvent.SELECTED) {
209
                return;
210
              }
211
              Thread th = new Thread(() -> {
212
                doTableChanged();
213
              }, "FeatureTypePanelToOneChangeTable");
214
              th.start();
215
            });
216
            this.pickerCode = dataSwingManager.createAttributeDescriptorPickerController(cboForeignField);
217
            this.pickerCode.addChangeListener((ChangeEvent e) -> {
218
                updateEnabledState();
219
            });
220
            
221
            this.btnFormula.setText("");
222
            this.btnFormulaBokkmarks.setText("");
223
            this.btnFormulaHistory.setText("");
224
            this.pickerFormula = dataSwingManager.createExpressionPickerController(
225
                    null, 
226
                    cboFormula, 
227
                    btnFormula, 
228
                    btnFormulaBokkmarks, 
229
                    btnFormulaHistory
230
            );
231
            this.pickerFormula.setAllowNull(true);
232
        }
233

    
234
        private void doTableChanged() {
235
            String tableName = (String) this.cboTable.getSelectedItem();
236
            if( StringUtils.isBlank(tableName) ) {
237
                return;
238
            }
239
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
240
            DataStore store = repository.getStore(tableName);
241
            if( !(store instanceof FeatureStore) ) {
242
                return;
243
            }
244
            FeatureType featureType;
245
            try {
246
                featureType = ((FeatureStore)store).getDefaultFeatureType();
247
            } catch (DataException ex) {
248
                return;
249
            }
250
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
251
            
252
            this.pickerCode.setAllowNull(true);
253
            this.pickerCode.setFeatureType(featureType);
254
            if (featureType == null) {
255
                return;
256
            }
257
            dataSwingManager.configureExpressionBuilder(this.pickerFormula.getConfig(), ((FeatureStore)store));
258
            SwingUtilities.invokeLater(() -> {
259
              cboForeignField.setSelectedItem(foreingKey.getCodeName());
260
            });
261
        }
262
        
263
        public void updateEnabledState(){
264
            if(this.editable){
265
                if(this.cboRelationType.getSelectedItem() == null) {
266
                    this.cboRelationType.setBackground(ToolsSwingLocator.getToolsSwingManager().getWarningBackgroundColor());
267
                } else {
268
                    this.cboRelationType.setBackground(UIManager.getColor(ToolsSwingManager.COLOR_COMBOBOX_BACKGROUND));
269
                }
270
                if(this.cboTable.getSelectedItem() == null) {
271
                    this.cboTable.setBackground(ToolsSwingLocator.getToolsSwingManager().getWarningBackgroundColor());
272
                } else {
273
                    this.cboTable.setBackground(UIManager.getColor(ToolsSwingManager.COLOR_COMBOBOX_BACKGROUND));
274
                }
275
                if(this.cboForeignField.getSelectedItem() == null) {
276
                    this.cboForeignField.setBackground(ToolsSwingLocator.getToolsSwingManager().getWarningBackgroundColor());
277
                } else {
278
                    this.cboForeignField.setBackground(UIManager.getColor(ToolsSwingManager.COLOR_COMBOBOX_BACKGROUND));
279
                }
280
            } else {
281
                this.cboRelationType.setBackground(UIManager.getColor(ToolsSwingManager.COLOR_COMBOBOX_DISABLEDBACKGROUND));
282
                this.cboTable.setBackground(UIManager.getColor(ToolsSwingManager.COLOR_COMBOBOX_DISABLEDBACKGROUND));
283
                this.cboForeignField.setBackground(UIManager.getColor(ToolsSwingManager.COLOR_COMBOBOX_DISABLEDBACKGROUND));
284
            }
285
        }
286

    
287
        public void setEditable(boolean editable) {
288
            this.cboRelationType.setEnabled(editable);
289
            this.chkIsClosedList.setEnabled(editable);
290
            this.cboTable.setEnabled(editable);
291
            this.cboForeignField.setEnabled(editable);
292
            this.pickerFormula.setEditable(editable);
293
            this.editable = editable;
294
        }
295
        
296
        public void setEnabled(boolean enabled) {
297
            if( !editable ) {
298
                enabled =  false;
299
            }
300
            this.cboRelationType.setEnabled(enabled);
301
            this.chkIsClosedList.setEnabled(enabled);
302
            this.cboTable.setEnabled(enabled);
303
            this.cboForeignField.setEnabled(enabled);
304
            this.pickerFormula.setEditable(enabled);
305
        }
306
        
307
        public void clean() {
308
            this.txtMyFieldName.setText("");
309
            this.cboRelationType.setSelectedIndex(-1);
310
            this.chkIsClosedList.setSelected(false);
311
            this.cboTable.setSelectedItem("");
312
            this.cboForeignField.setSelectedItem("");
313
            this.pickerFormula.set(null);
314
        }
315
        
316
        public void put(FeatureAttributeDescriptor descriptor) {
317
            if( descriptor == null ) {
318
                this.clean();
319
                return;
320
            }
321
            ForeingKey theForeingKey = descriptor.getForeingKey();
322
            if( theForeingKey==null ) {
323
                this.clean();
324
                return;
325
            }
326
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
327
            this.pickerFormula.setFeatureType(repository.getFeatureType(theForeingKey.getTableName()));
328
            this.foreingKey = theForeingKey;
329
            ListElement.setSelected(this.cboRelationType,descriptor.getRelationType());
330
            this.chkIsClosedList.setSelected(theForeingKey.isClosedList());
331
            this.cboTable.setSelectedItem(theForeingKey.getTableName()); 
332
            doTableChanged();
333
            this.pickerCode.set(theForeingKey.getCodeName());
334
            this.pickerFormula.set(theForeingKey.getLabelExpression(null));
335
            this.txtMyFieldName.setText(descriptor.getName());
336
        }
337
        
338
        public void fetch(EditableFeatureAttributeDescriptor descriptor) {
339
            if( descriptor == null ) {
340
                this.clean();
341
                return;
342
            }
343
            EditableForeingKey theForeingKey = descriptor.getForeingKey();
344
            if( theForeingKey==null ) {
345
                return;
346
            }
347
//            foreingKey.setForeingKey(this.chkIsForeingKey.isSelected());
348
            theForeingKey.setClosedList(this.chkIsClosedList.isSelected());
349
            theForeingKey.setTableName((String) this.cboTable.getSelectedItem());
350
            theForeingKey.setCodeName(this.pickerCode.getName());
351
            Expression exp = this.pickerFormula.get();
352
            if( ExpressionUtils.isPhraseEmpty(exp) ) {
353
                theForeingKey.setLabelFormula("");
354
            } else {
355
                theForeingKey.setLabelFormula(exp.getPhrase());
356
            }
357
        }
358

    
359
        public int getRelationType() {
360
            Object n = this.cboRelationType.getSelectedItem();
361
            if( n == null ) {
362
                return DynField.RELATION_TYPE_NONE;
363
            }
364
            return ((LabeledValue<Integer>)n).getValue();
365
        }
366
    }
367
    
368
    private static class ToManyController {
369

    
370
        private final JComboBox cboRelationType;
371
        private final JComboBox cboMyField;
372
        private final JComboBox cboTable;
373
        private final JComboBox cboForeignField;
374
        private final JTextField txtExpression;
375
        private final JButton btnExpression;
376
        private final JButton btnExpressionHistory;
377
        private final JButton btnExpressionBokkmarks;
378
        private ExpressionPickerController pickerExpression;
379
        private AttributeDescriptorPickerController pickerForeignField;
380
        private AttributeDescriptorPickerController pickerMyField;
381
        private boolean editable;
382
        private boolean disableEvents;
383
        private FeatureType featureType;
384
        
385
        public ToManyController(
386
                JComboBox cboRelationType,
387
                JComboBox cboMyField,
388
                JComboBox cboTable,
389
                JComboBox cboForeignField,
390
                JTextField txtExpression,
391
                JButton btnExpression,
392
                JButton btnExpressionBokkmarks,
393
                JButton btnExpressionHistory
394
        ) {
395
            this.disableEvents = false;
396
            this.cboRelationType = cboRelationType;
397
            this.cboMyField = cboMyField;
398
            this.cboTable = cboTable;
399
            this.cboForeignField = cboForeignField;
400
            this.txtExpression = txtExpression;
401
            this.btnExpression = btnExpression;
402
            this.btnExpressionHistory = btnExpressionHistory;
403
            this.btnExpressionBokkmarks = btnExpressionBokkmarks;
404
            this.initComponents();
405
        }
406

    
407
        private void initComponents() {
408
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
409
            I18nManager i18n = ToolsLocator.getI18nManager();
410
    
411
            this.editable = true;
412
            DefaultComboBoxModel<LabeledValueImpl<Integer>> relationTypeModel = new DefaultComboBoxModel<>();
413
//            relationTypeModel.addElement(new ListElement<>(DynField.RELATION_TYPE_IDENTITY + " - "+i18n.getTranslation("_Identity_1_1"),DynField.RELATION_TYPE_IDENTITY));
414
//            relationTypeModel.addElement(new ListElement<>(DynField.RELATION_TYPE_COLLABORATION + " - "+i18n.getTranslation("_Collaboration_1_1_without_composition"),DynField.RELATION_TYPE_COLLABORATION));
415
//            relationTypeModel.addElement(new ListElement<>(DynField.RELATION_TYPE_COLLABORATION_WITH_COMPOSITION + " - "+i18n.getTranslation("_Collaboration_1_1_with_composition"),DynField.RELATION_TYPE_COLLABORATION_WITH_COMPOSITION));
416
            relationTypeModel.addElement(new ListElement<>(DynField.RELATION_TYPE_AGGREGATE_WITH_COMPOSITION + " - "+i18n.getTranslation("_Aggregate_1_N_with_composition"),DynField.RELATION_TYPE_AGGREGATE_WITH_COMPOSITION));
417
            relationTypeModel.addElement(new ListElement<>(DynField.RELATION_TYPE_AGGREGATE + " - "+i18n.getTranslation("_Aggregate_1_N_without_composition"),DynField.RELATION_TYPE_AGGREGATE));
418
            this.cboRelationType.setModel(relationTypeModel);
419
        
420
            this.pickerMyField = dataSwingManager.createAttributeDescriptorPickerController(cboMyField);
421
            this.pickerMyField.setAllowNull(true);
422
            this.pickerMyField.addChangeListener((ChangeEvent e) -> {
423
                if( disableEvents ) {
424
                    return;
425
                }
426
                doUpdateExpression();
427
            });
428
            DefaultComboBoxModel<String> model = new DefaultComboBoxModel();
429
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
430
            List<String> tableNames = new ArrayList<>();
431
            for (String tableName : repository.keySet()) {
432
                tableNames.add(tableName);
433
            }
434
            Collections.sort(tableNames);
435
            for (String tableName : tableNames) {
436
                model.addElement(tableName);
437
            }
438
            this.cboTable.setEditable(false);
439
            this.cboTable.setModel(model);
440
            this.cboTable.addItemListener((ItemEvent e) -> {
441
              if( disableEvents ) {
442
                  return;
443
              }
444
              if (e.getStateChange() != ItemEvent.SELECTED) {
445
                return;
446
              }
447
              Thread th = new Thread(() ->
448
                  { doTableChanged(); },
449
                "FeatureTypePanelToManyTableChanged"
450
              );
451
              th.start();
452
            });
453
            this.pickerForeignField = dataSwingManager.createAttributeDescriptorPickerController(cboForeignField);
454
            this.pickerForeignField.setAllowNull(true);
455
            this.pickerForeignField.addChangeListener((ChangeEvent e) -> {
456
                if( disableEvents ) {
457
                    return;
458
                }
459
                doUpdateExpression();
460
            });
461
            
462
            this.pickerExpression = ExpressionEvaluatorSwingLocator.getManager().createExpressionPickerController(
463
                    txtExpression, 
464
                    btnExpression, 
465
                    btnExpressionBokkmarks, 
466
                    btnExpressionHistory
467
            );
468
        }
469

    
470
        private void doTableChanged() {
471
            String tableName = (String) this.cboTable.getSelectedItem();
472
            if( StringUtils.isBlank(tableName) ) {
473
                return;
474
            }
475
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
476
            DataStore store = repository.getStore(tableName);
477
            if( !(store instanceof FeatureStore) ) {
478
                return;
479
            }
480
            FeatureStore featureStore = (FeatureStore) store;
481
            FeatureType featureType;
482
            try {
483
                featureType = featureStore.getDefaultFeatureType();
484
            } catch (DataException ex) {
485
                return;
486
            }
487
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
488
            
489
            this.pickerForeignField.setFeatureType(featureType);
490
            if (featureType == null) {
491
                return;
492
            }
493
            dataSwingManager.configureExpressionBuilder(this.pickerExpression.getConfig(), featureStore);
494
        }
495
        
496
        private void doUpdateExpression() {
497
            String myField = this.pickerMyField.getName();
498
            if( StringUtils.isBlank(myField) ) {
499
                this.pickerExpression.set(null);
500
                return;
501
            }
502
            String foreignField = this.pickerForeignField.getName();
503
            if( StringUtils.isBlank(foreignField) ) {
504
                this.pickerExpression.set(null);
505
                return;
506
            }
507
            String tableName = this.getTableName();
508
            if( StringUtils.isBlank(tableName) ) {
509
                this.pickerExpression.set(null);
510
                return;
511
            }
512
            DataManager dataManager = DALLocator.getDataManager();
513
            DALExpressionBuilder builder = dataManager.createDALExpressionBuilder();
514
            SQLBuilder.SelectBuilder select = builder.select();
515
            select.from().table().name(tableName);
516
            select.column().all();
517
            select.where().set(builder.expression().eq(
518
                    builder.expression().column(myField),
519
                    builder.expression().getattr(tableName, foreignField)
520
                )
521
            );
522
            this.pickerExpression.set(ExpressionUtils.createExpression(select.toString()));
523
        }
524
        
525
        private String[] getFieldsAndTable(Expression expression) {
526
            if (ExpressionUtils.isEmpty(expression)) {
527
                return null;
528
            }
529
            try {
530
                Code code = expression.getCode();
531
                if( !StringUtils.equalsIgnoreCase(Callable.name(code),FUNCTION_SELECT) ) {
532
                    return null;
533
                }
534
                Code.Callable callable = (Code.Callable) code;
535
                String tableName;
536
                Codes args = callable.parameters();
537
                Code storeName_code = (Code) args.get(1);
538
                if (storeName_code instanceof Code.Identifier) {
539
                    tableName = ((Code.Identifier) storeName_code).name();
540
                } else if (storeName_code instanceof Code.Constant) {
541
                    Code.Constant storeName_const = (Code.Constant) storeName_code;
542
                    if (storeName_const.value() instanceof CharSequence) {
543
                        tableName = storeName_const.value().toString();
544
                    } else {
545
                        return null;
546
                    }
547
                } else {
548
                    return null;
549
                }
550
                if (StringUtils.isBlank(tableName)) {
551
                    return null;
552
                }
553
                String foreignColumnName = null;
554
                String myColumnName = null;
555
                Code where = callable.parameters().get(2); // WHERE
556
                Code myFieldCode = getCode(
557
                        where,
558
                        new ImmutablePair<>(OPERATOR_EQ, 0)
559
                );
560
                if( myFieldCode != null ) {
561
                    myColumnName = Objects.toString(Identifier.name(myFieldCode), null);
562
                }
563
                Code foreingFieldCode = getCode(
564
                        where,
565
                        new ImmutablePair<>(OPERATOR_EQ, 1),
566
                        new ImmutablePair<>(FUNCTION_GETATTR, 1)
567
                );
568
                if( foreingFieldCode != null ) {
569
                    foreignColumnName = Objects.toString(Constant.value(foreingFieldCode), null);
570
                }
571
                return new String[] { myColumnName, tableName,foreignColumnName };
572
            } catch(Throwable t) {
573
                LOGGER.warn("Can't get table and code from expression '"+expression.getPhrase()+"' in toMany controller",t);
574
                return null;
575
            }
576
        }
577
        
578
        private Code getCode(Code code, Pair<String,Integer>... args) {
579
            for (Pair<String, Integer> arg : args) {
580
                if( !StringUtils.equalsIgnoreCase(Callable.name(code),arg.getLeft()) ) {
581
                    return null;
582
                }
583
                code = Callable.parameters(code).get(arg.getRight());
584
            }
585
            return code;
586
        }
587

    
588
        private String getTableName() {
589
            String s = (String) this.cboTable.getSelectedItem();
590
            if( StringUtils.isBlank(s) ) {
591
                return null;
592
            }
593
            return s;
594
        }
595
        
596
        public void setEditable(boolean editable) {
597
            this.cboRelationType.setEnabled(editable);
598
            this.pickerMyField.setEditable(editable);
599
            this.cboTable.setEnabled(editable);
600
            this.pickerForeignField.setEditable(editable);
601
            this.pickerExpression.setEditable(editable);
602
            this.editable = editable;
603
        }
604
        
605
        public void setEnabled(boolean enabled) {
606
            if( !editable ) {
607
                enabled =  false;
608
            }
609
            this.cboRelationType.setEnabled(enabled);
610
            this.pickerMyField.setEnabled(enabled);
611
            this.cboTable.setEnabled(enabled);
612
            this.pickerForeignField.setEnabled(enabled);
613
            this.pickerExpression.setEditable(enabled);
614
        }
615
        
616
        public void clean() {
617
            this.cboRelationType.setSelectedIndex(-1);
618
            this.pickerMyField.clean();
619
            this.cboTable.setSelectedIndex(-1);
620
            this.pickerForeignField.clean();
621
            this.pickerExpression.set(null);
622
        }
623
        
624
        public void put(FeatureAttributeDescriptor descriptor) {
625
            if (descriptor == null) {
626
                this.clean();
627
                return;
628
            }
629
            boolean prevDisableEvents = this.disableEvents;
630
            try {
631
                this.disableEvents = true;
632
                this.pickerMyField.setFeatureType(getFeatureType(descriptor));
633
                ListElement.setSelected(this.cboRelationType, descriptor.getRelationType());
634
                FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
635
                if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
636
                    Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
637
                    String[] fieldsAndTable = this.getFieldsAndTable(expression);
638
                    if (fieldsAndTable == null) {
639
                        this.cboTable.setSelectedIndex(-1);
640
                        this.pickerForeignField.clean();
641
                        return;
642
                    }
643
                    this.pickerMyField.set(fieldsAndTable[0]);
644
                    this.cboTable.setSelectedItem(fieldsAndTable[1]);
645
                    doTableChanged();
646
                    this.pickerForeignField.set(fieldsAndTable[2]);
647
                    this.pickerExpression.set(expression);
648
                } else {
649
                    this.clean();
650
                }
651
            } catch (Throwable t) {
652
                LOGGER.warn("Can't set attribute descriptor in toMany controller",t);
653
            } finally {
654
                this.disableEvents = prevDisableEvents;
655
            }
656
        }
657

    
658
        public void setFeatureType(FeatureType featureType){
659
            this.featureType = featureType;
660
        }
661

    
662
        private FeatureType getFeatureType(FeatureAttributeDescriptor descriptor) {
663
            if(descriptor ==  null || descriptor.getFeatureType() == null){
664
                return this.featureType;
665
            }
666
            return descriptor.getFeatureType();
667
        }
668

    
669
        public void fetch(EditableFeatureAttributeDescriptor descriptor) {
670
            if( descriptor == null ) {
671
                this.clean();
672
                return;
673
            }
674
//            Expression exp = this.pickerExpression.get();
675
//            if( ExpressionUtils.isPhraseEmpty(exp) ) {
676
//                descriptor.setFeatureAttributeEmulator((Expression)null);
677
//            } else {
678
//                descriptor.setFeatureAttributeEmulator(exp);
679
//            }
680
            Tags tags = descriptor.getTags();
681
            if( !tags.has(DAL_RELATED_TABLE) ) {
682
                String tableName =  this.getTableName();
683
                if( StringUtils.isNotBlank(tableName) ) {
684
                    tags.set(DAL_RELATED_TABLE, tableName);                    
685
                }
686
            }
687
            if( !tags.has(DAL_RELATED_UNIQUE_FIELD_NAME) ) {
688
                String tableName = tags.getString(DAL_RELATED_TABLE, null);
689
                if( StringUtils.isNotBlank(tableName) ) {
690
                    try {
691
                        StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
692
                        FeatureType ft = repository.getFeatureType(tableName);
693
                        FeatureAttributeDescriptor[] pk = ft.getPrimaryKey();
694
                        if( !ArrayUtils.isEmpty(pk) && pk.length==1 ) {
695
                            tags.set(DAL_RELATED_UNIQUE_FIELD_NAME, pk[0].getName());
696
                        }
697
                    } catch(Throwable t) {
698
                        LOGGER.warn("Can't get primary key of table '"+tableName+"'.",t);
699
                    }
700
                }
701
            }
702
        }
703
        
704
        public Expression getExpression() {
705
            Expression exp = this.pickerExpression.get();
706
            if( ExpressionUtils.isPhraseEmpty(exp) ) {
707
                return null;
708
            } else {
709
                return exp;
710
            }
711
        }
712
        
713
        public int getRelationType() {
714
            Object n = this.cboRelationType.getSelectedItem();
715
            if( n == null ) {
716
                return DynField.RELATION_TYPE_NONE;
717
            }
718
            return ((LabeledValue<Integer>)n).getValue();
719
        }
720
    }
721
    
722

    
723
    private static class AvailableValuesController {
724

    
725
        private final JList lstValues;
726
        private final JTextComponent txtLabel;
727
        private final JTextComponent txtValue;
728
        private final JButton btnAdd;
729
        private final JButton btnUpdate;
730
        private final JButton btnRemove;
731
        private final JButton btnRemoveAll;
732

    
733
        public AvailableValuesController(
734
                JList lstValues,
735
                JTextComponent txtLabel,
736
                JTextComponent txtValue,
737
                JButton btnAdd,
738
                JButton btnUpdate,
739
                JButton btnRemove,
740
                JButton btnRemoveAll
741
        ) {
742
            this.lstValues = lstValues;
743
            this.txtLabel = txtLabel;
744
            this.txtValue = txtValue;
745
            this.btnAdd = btnAdd;
746
            this.btnUpdate = btnUpdate;
747
            this.btnRemove = btnRemove;
748
            this.btnRemoveAll = btnRemoveAll;
749

    
750
            this.lstValues.addListSelectionListener((ListSelectionEvent e) -> {
751
              doValuesChanged();
752
            });
753
            this.btnAdd.addActionListener((ActionEvent e) -> {
754
              doAdd();
755
            });
756
            this.btnUpdate.addActionListener((ActionEvent e) -> {
757
              doUpdate();
758
            });
759
            this.btnRemove.addActionListener((ActionEvent e) -> {
760
              doRemove();
761
            });
762
            this.btnRemoveAll.addActionListener((ActionEvent e) -> {
763
              doRemoveAll();
764
            });
765
        }
766

    
767
        public void clean() {
768
            this.lstValues.setModel(new DefaultListModel());
769
            this.txtLabel.setText("");
770
            this.txtValue.setText("");
771
            this.lstValues.setSelectedIndex(-1);
772
        }
773

    
774
        public DynObjectValueItem[] get() {
775
            ListModel<DynObjectValueItem> model = this.lstValues.getModel();
776
            if( model.getSize()==0 ) {
777
              return null;
778
            }
779
            DynObjectValueItem[] values = new DynObjectValueItem[model.getSize()];
780
            for (int i = 0; i < model.getSize(); i++) {
781
                values[i] = model.getElementAt(i);
782
            }
783
            return values;
784
        }
785

    
786
        public void set(DynObjectValueItem[] availableValues) {
787
            DefaultListModel model = new DefaultListModel();
788
            if (availableValues != null) {
789
                for (DynObjectValueItem availableValue : availableValues) {
790
                    model.addElement(availableValue);
791
                }
792
            }
793
            this.lstValues.setModel(model);
794
            if (model.getSize() > 0) {
795
                this.lstValues.setSelectedIndex(0);
796
            } else {
797
                this.lstValues.setSelectedIndex(-1);
798
            }
799
        }
800

    
801
        public void setEditable(boolean editable) {
802
            this.lstValues.setEnabled(editable);
803
            this.txtLabel.setEditable(editable);
804
            this.txtValue.setEditable(editable);
805
            this.btnAdd.setEnabled(editable);
806
            this.btnUpdate.setEnabled(editable);
807
            this.btnRemove.setEnabled(editable);
808
            this.btnRemoveAll.setEnabled(editable);
809
        }
810

    
811
        private void doValuesChanged() {
812
            DynObjectValueItem value = (DynObjectValueItem) this.lstValues.getSelectedValue();
813
            if (value == null) {
814
                this.txtLabel.setText("");
815
                this.txtValue.setText("");
816
                this.btnAdd.setEnabled(true);
817
                this.btnUpdate.setEnabled(false);
818
                this.btnRemove.setEnabled(false);
819
                return;
820
            }
821
            this.txtLabel.setText(value.getLabel());
822
            this.txtValue.setText(Objects.toString(value.getValue(), ""));
823
            this.btnAdd.setEnabled(true);
824
            this.btnUpdate.setEnabled(true);
825
            this.btnRemove.setEnabled(true);
826
        }
827

    
828
        private void doAdd() {
829
            DynObjectValueItem value = new DynObjectValueItem("Value", "Label");
830
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
831
            model.addElement(value);
832
            this.lstValues.setSelectedIndex(model.getSize() - 1);
833
        }
834

    
835
        private void doUpdate() {
836
            DynObjectValueItem value = (DynObjectValueItem) this.lstValues.getSelectedValue();
837
            if (value == null) {
838
                return; // EEhh?? esto no deberia pasar
839
            }
840
            value.setLabel(this.txtLabel.getText());
841
            value.setValue(this.txtValue.getText());
842
        }
843

    
844
        private void doRemove() {
845
            int n = this.lstValues.getSelectedIndex();
846
            if (n < 0) {
847
                return; // EEhh?? esto no deberia pasar
848
            }
849
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
850
            model.removeElementAt(n);
851
            if (--n < 0) {
852
                n = 0;
853
            }
854
            this.lstValues.setSelectedIndex(n);
855
        }
856

    
857
        private void doRemoveAll() {
858
            DefaultListModel model = new DefaultListModel();
859
            this.lstValues.setModel(model);
860
            this.lstValues.setSelectedIndex(-1);
861
        }
862

    
863
    }
864

    
865
    private final List<ListElement<Integer>> fieldTypes;
866
    private final List<ListElement<Integer>> geometryTypes;
867
    private final List<ListElement<Integer>> geometrySubtypes;
868

    
869
    private DatePickerController pickerIntervalEnd;
870
    private DatePickerController pickerIntervalStart;
871
    private CalculatorController<Integer> pickerSize;
872
    private CalculatorController<Integer> pickerDisplaySize;
873
    private CalculatorController<Integer> pickerPrecision;
874
    private CalculatorController<Integer> pickerScale;
875
    private PickerController<Locale> pickerLocale;
876
    private PickerController<IProjection> pickerCRS;
877
    private ExpressionPickerController pickerVirtualFieldGetter;
878
    private ExpressionPickerController pickerVirtualFieldSetter;
879
    private ExpressionPickerController pickerDefaultFormat;
880
    private CalculatorController<Integer> pickerOrder;
881
    private AvailableValuesController availableValuesController;
882
    private AggregateController<Tag> tagsController;
883
    private ToOneController toOneController;
884
    private ExpressionPickerController pickerValuesFilter;
885

    
886
    private int mode;
887
    private FeatureStoreElement featureStoreElement;
888

    
889
    public DefaultFeatureAttributePanel() {
890
        this.mode = FeatureTypePanel.MODE_SHOW_ONLY;
891
        DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
892
        // se deber?a de utilizar el datatypepicker
893
        this.fieldTypes = new ArrayList<>();
894
        fieldTypes.add( new ListElement<>("Decimal", DataTypes.DECIMAL) );
895
        fieldTypes.add( new ListElement<>("Integer", DataTypes.INTEGER) );
896
        fieldTypes.add( new ListElement<>("Long", DataTypes.LONG) );
897
        fieldTypes.add( new ListElement<>("String", DataTypes.STRING) );
898
        fieldTypes.add( new ListElement<>("Boolean", DataTypes.BOOLEAN) );
899
        fieldTypes.add( new ListElement<>("Date", DataTypes.DATE) );
900
        fieldTypes.add( new ListElement<>("Date/Time (Timestamp)", DataTypes.TIMESTAMP) );
901
//        for (DataType dataType : dataManager) {
902
//            fieldTypes.add( new ListElement<>(dataType.getName(), dataType.getType()) );
903
//        }
904
        fieldTypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
905
                o1.toString().compareTo(o2.toString())
906
        );
907

    
908
        this.geometryTypes = new ArrayList<>();
909
        this.geometryTypes.add(new ListElement("Point", Geometry.TYPES.POINT));
910
        this.geometryTypes.add(new ListElement("Line", Geometry.TYPES.LINE));
911
        this.geometryTypes.add(new ListElement("Polygon", Geometry.TYPES.POLYGON));
912
        this.geometryTypes.add(new ListElement("MultiPoint", Geometry.TYPES.MULTIPOINT));
913
        this.geometryTypes.add(new ListElement("MultiLine", Geometry.TYPES.MULTILINE));
914
        this.geometryTypes.add(new ListElement("MultiPolygon", Geometry.TYPES.MULTIPOLYGON));
915
        this.geometryTypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
916
                  o1.toString().compareTo(o2.toString())
917
        );
918

    
919
        this.geometrySubtypes = new ArrayList<>();
920
        this.geometrySubtypes.add(new ListElement("2D", Geometry.SUBTYPES.GEOM2D));
921
        this.geometrySubtypes.add(new ListElement("2DM", Geometry.SUBTYPES.GEOM2DM));
922
        this.geometrySubtypes.add(new ListElement("3D", Geometry.SUBTYPES.GEOM3D));
923
        this.geometrySubtypes.add(new ListElement("3DM", Geometry.SUBTYPES.GEOM3DM));
924
        this.geometrySubtypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
925
                o1.toString().compareTo(o2.toString())
926
        );
927

    
928
        this.initComponents();
929
    }
930

    
931
    private void initComponents() {
932
        final ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
933
        final ExpressionEvaluatorSwingManager evaluatorSwingManager = ExpressionEvaluatorSwingLocator.getManager();
934
        final DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
935
        final DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
936

    
937
        this.translate();
938
        
939
        ToolsSwingUtils.ensureMaxRows(this.gridAttrTagsTable, 10);
940
        this.splAttrTags = ToolsSwingUtils.createVerticalSplit(
941
                this.grdAttrTags,
942
                this.gridAttrTagsTable, false,
943
                this.gridAttrTagsItem, true
944
        );
945
        
946
        DefaultComboBoxModel<ListElement<Integer>> modelTypes = new DefaultComboBoxModel<>();
947
        for (ListElement<Integer> element : fieldTypes) {
948
            modelTypes.addElement(element);
949
        }
950
        this.cboFieldType.setModel(modelTypes);
951
        this.cboFieldType.setRenderer(new DefaultListCellRenderer() {
952
          @Override
953
          public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
954
              JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
955
              label.setIcon(null);
956
              try {
957
                DataType dataType = dataTypeManager.get((int) value);
958
                IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
959
                if (theme.exists(dataType.getIconName())) {
960
                    label.setIcon(theme.get(dataType.getIconName()));
961
                }
962
              } catch(Exception ex) {
963
                // Do nothing, ignore
964
              }
965
              return label;
966
          }
967
        });
968

    
969
        DefaultComboBoxModel<ListElement<Integer>> modelGeomTypes = new DefaultComboBoxModel<>();
970
        for (ListElement<Integer> element : this.geometryTypes) {
971
            modelGeomTypes.addElement(element);
972
        }
973
        this.cboGeometryType.setModel(modelGeomTypes);
974

    
975
        DefaultComboBoxModel<ListElement<Integer>> modelGeomSubtypes = new DefaultComboBoxModel<>();
976
        for (ListElement<Integer> element : this.geometrySubtypes) {
977
            modelGeomSubtypes.addElement(element);
978
        }
979

    
980
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
981

    
982

    
983
        swingManager.addClearButton(this.txtDefaultValue);
984
        swingManager.addClearButton(this.txtDefaultFormat);
985
        swingManager.addClearButton(this.txtFieldName);
986
        swingManager.addClearButton(this.txtIntervalEnd);
987
        swingManager.addClearButton(this.txtIntervalStart);
988
        swingManager.addClearButton(this.txtScale);
989
        swingManager.addClearButton(this.txtSize);
990
        swingManager.addClearButton(this.txtDisplaySize);
991
        swingManager.addClearButton(this.txtLabel);
992
        swingManager.addClearButton(this.txtDescription);
993
        swingManager.addClearButton(this.cboGroup);
994
        swingManager.addClearButton(this.txtMaxValue);
995
        swingManager.addClearButton(this.txtMinValue);
996
        swingManager.addClearButton(this.txtAvailableValuesLabel);
997
        swingManager.addClearButton(this.txtAvailableValuesValue);
998

    
999
        swingManager.setDefaultPopupMenu(this.txtDefaultValue);
1000
        swingManager.setDefaultPopupMenu(this.txtDefaultFormat);
1001
        swingManager.setDefaultPopupMenu(this.txtFieldName);
1002
        swingManager.setDefaultPopupMenu(this.txtIntervalEnd);
1003
        swingManager.setDefaultPopupMenu(this.txtIntervalStart);
1004
        swingManager.setDefaultPopupMenu(this.txtScale);
1005
        swingManager.setDefaultPopupMenu(this.txtSize);
1006
        swingManager.setDefaultPopupMenu(this.txtDisplaySize);
1007
        swingManager.setDefaultPopupMenu(this.cboDateFormat);
1008
        swingManager.setDefaultPopupMenu(this.cboFieldType);
1009
        swingManager.setDefaultPopupMenu(this.cboGeometrySubtype);
1010
        swingManager.setDefaultPopupMenu(this.cboGeometryType);
1011
        swingManager.setDefaultPopupMenu(this.cboDataProfile);
1012

    
1013
//        swingManager.setDefaultPopupMenu(this.cboRelationToOneCodeName);
1014
//        swingManager.setDefaultPopupMenu(this.cboRelationToOneTableName);
1015

    
1016
//        swingManager.setDefaultPopupMenu(this.cboRelationToManyForeignFieldName);
1017
//        swingManager.setDefaultPopupMenu(this.cboRelationToManyTableName);
1018

    
1019
        swingManager.setDefaultPopupMenu(this.cboGroup);
1020
        swingManager.setDefaultPopupMenu(this.txtOrder);
1021
        swingManager.setDefaultPopupMenu(this.txtLabel);
1022
        swingManager.setDefaultPopupMenu(this.txtDescription);
1023
        swingManager.setDefaultPopupMenu(this.txtMinValue);
1024
        swingManager.setDefaultPopupMenu(this.txtMaxValue);
1025
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesLabel);
1026
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesValue);
1027

    
1028
        this.toOneController = new ToOneController(
1029
                txtRelationToOneMyFieldName,
1030
                cboRelationToOneType, 
1031
                chkRelationToOneIsClosedList, 
1032
                cboRelationToOneTableName, 
1033
                cboRelationToOneCodeName, 
1034
                cboRelationToOneFormula, 
1035
                btnRelationToOneFormula,
1036
                btnRelationToOneFormulaBookmarks,
1037
                btnRelationToOneFormulaHistory
1038
        );
1039
        this.toManyController = new ToManyController(
1040
                cboRelationToManyType, 
1041
                cboRelationToManyMyFieldName, 
1042
                cboRelationToManyTableName, 
1043
                cboRelationToManyForeignFieldName, 
1044
                
1045
                txtRelationToManyExpression, 
1046
                
1047
                btnRelationToManyExpression,
1048
                btnRelationToManyExpressionHistory,
1049
                btnRelationToManyExpressionBookmarks
1050
        );
1051
        this.pickerIntervalEnd = swingManager.createDatePickerController(
1052
                this.txtIntervalEnd,
1053
                this.btnIntervalEnd
1054
        );
1055
        this.pickerIntervalStart = swingManager.createDatePickerController(
1056
                this.txtIntervalStart,
1057
                this.btnIntervalStart
1058
        );
1059
        this.pickerSize = evaluatorSwingManager.createCalculatorController(
1060
                this.txtSize, DataTypes.INT
1061
        );
1062
        this.pickerDisplaySize = evaluatorSwingManager.createCalculatorController(this.txtDisplaySize, DataTypes.INT
1063
        );
1064
        this.pickerPrecision = evaluatorSwingManager.createCalculatorController(
1065
                this.txtPrecision, DataTypes.INT
1066
        );
1067
        this.pickerScale = evaluatorSwingManager.createCalculatorController(
1068
                this.txtScale, DataTypes.INT
1069
        );
1070
        this.pickerLocale = swingManager.createLocalePickerController(this.cboLocale);
1071
        
1072
        this.txtDefaultValue.getComponentPopupMenu().add(evaluatorSwingManager.createJExpressionBuilderAction(txtDefaultValue));
1073
        this.pickerOrder = evaluatorSwingManager.createCalculatorController(
1074
                this.txtOrder, DataTypes.INT
1075
        );
1076

    
1077
        this.availableValuesController = new AvailableValuesController(
1078
                lstAvailableValues,
1079
                txtAvailableValuesLabel,
1080
                txtAvailableValuesValue,
1081
                btnAvailableValuesAdd,
1082
                btnAvailableValuesUpdate,
1083
                btnAvailableValuesRemove,
1084
                btnAvailableValuesRemoveAll
1085
        );
1086
        
1087
        this.tagsController = new DefaultAggregateController<>(
1088
                this.tblAttrTagsItems,
1089
                this.btnAttrTagsModify,
1090
                this.btnAttrTagsDiscard,
1091
                this.btnAttrTagsAccept,
1092
                this.btnAttrTagsNew,
1093
                this.btnAttrTagsDelete,
1094
                new TagController(
1095
                        this.cboAttrTagsItemName,
1096
                        this.cboAttrTagsItemValue,
1097
                        this.lblAttrTagsItemNotesValue
1098
                )
1099
        );        
1100
        this.txtMinValue.setEnabled(false);
1101
        this.txtMaxValue.setEnabled(false);
1102

    
1103
        this.btnVirtualFieldGetter.setText("");
1104
        this.featureStoreElement = dataSwingManager.createFeatureStoreElement();
1105
        this.pickerVirtualFieldGetter = evaluatorSwingManager.createExpressionPickerController(
1106
                txtVirtualFieldGetter, btnVirtualFieldGetter, btnVirtualFieldBookmarksGetter, btnVirtualFieldHistoryGetter
1107
        );
1108
        this.pickerVirtualFieldGetter.getConfig().addElement(this.featureStoreElement);
1109
        this.pickerVirtualFieldSetter = evaluatorSwingManager.createExpressionPickerController(
1110
                txtVirtualFieldSetter, btnVirtualFieldSetter, btnVirtualFieldBookmarksSetter, btnVirtualFieldHistorySetter
1111
        );
1112
        this.pickerVirtualFieldSetter.getConfig().addElement(this.featureStoreElement);
1113
        
1114
        this.chkVirtualField.addChangeListener((ChangeEvent e) -> {
1115
          if (chkVirtualField.isSelected()) {
1116
            pickerVirtualFieldGetter.setEditable(mode==MODE_EDIT_ALL || mode==MODE_EDIT_ONLY_METADATA || mode==MODE_VIRTUAL_FIELD);
1117
            pickerVirtualFieldSetter.setEditable(false);
1118
          } else {
1119
            pickerVirtualFieldGetter.setEditable(false);
1120
            pickerVirtualFieldSetter.setEditable(false);
1121
          }
1122
        });
1123

    
1124
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
1125
                this.txtCRS, this.btnCRS
1126
        );
1127

    
1128
        this.cboFieldType.addItemListener((ItemEvent e) -> {
1129
          SwingUtilities.invokeLater(() -> {
1130
            doFieldTypeChanged();
1131
          });
1132
        });
1133

    
1134
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
1135
          doCheckPrecisionAndScale();
1136
        });
1137
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
1138
          doCheckPrecisionAndScale();
1139
        });
1140

    
1141
        DefaultComboBoxModel dataProfilesModel = new DefaultComboBoxModel<>();
1142
        dataProfilesModel.addElement(new ListElement<>("", null));
1143
        for (DataProfile profile : DALLocator.getDataManager().getDataProfiles()) {
1144
            dataProfilesModel.addElement(new ListElement<>(profile.getName(), profile.getID()));
1145
        }
1146
        this.cboDataProfile.setModel(dataProfilesModel);
1147
        
1148
        this.btnFieldType.addActionListener((ActionEvent e) -> {
1149
          doDataTypeSelection();
1150
        });
1151
        
1152
        this.pickerValuesFilter = evaluatorSwingManager.createExpressionPickerController(
1153
                txtValuesFilter, btnValuesFilter, btnValuesFilterBookmarks, btnValuesFilterHistory
1154
        );
1155
        this.pickerValuesFilter.getConfig().addElement(this.featureStoreElement);
1156
        
1157
        this.chkIsAutomatic.addActionListener((ActionEvent e) -> {
1158
            doIsAutomaticChanged();
1159
        });
1160

    
1161
        this.rdbRelationNone.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1162
        this.rdbRelationToOne.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1163
        this.rdbRelationToMany.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1164

    
1165
        this.chkDefaultValue.addActionListener((ActionEvent e) -> {
1166
            txtDefaultValue.setEditable(!chkDefaultValue.isSelected());
1167
        });
1168
        
1169
        SwingUtilities.invokeLater( () -> {
1170
                splAttrTags.setDividerLocation(0.4);
1171
            }
1172
        );
1173
        ToolsSwingUtils.ensureRowsCols(this, 16,95);
1174
    }
1175

    
1176
    private void translate() {
1177
        final ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
1178
        final I18nManager i18n = ToolsLocator.getI18nManager();
1179
    
1180
        swingManager.translate(this.lblAllowNulls);
1181
        swingManager.translate(this.lblCRS);
1182
        swingManager.translate(this.lblDataProfile);
1183
        swingManager.translate(this.lblDateFormat);
1184
        swingManager.translate(this.lblDefaultValue);
1185
        swingManager.translate(this.chkDefaultValue);
1186
        swingManager.translate(this.lblDefaultFormat);
1187
        swingManager.translate(this.lblFieldName);
1188
        swingManager.translate(this.lblFieldType);
1189
        swingManager.translate(this.lblGeometrySubtype);
1190
        swingManager.translate(this.lblGeometryType);
1191
        swingManager.translate(this.lblInterval);
1192
        swingManager.translate(this.lblIntervalEnd);
1193
        swingManager.translate(this.lblIntervalStart);
1194
        swingManager.translate(this.lblIsAutomatic);
1195
        swingManager.translate(this.lblIsIndexed);
1196
        swingManager.translate(this.lblIsReadOnly);
1197
        swingManager.translate(this.lblIsPrimaryKey);
1198
        swingManager.translate(this.lblPrecision);
1199
        swingManager.translate(this.lblScale);
1200
        swingManager.translate(this.lblSize);
1201
        swingManager.translate(this.lblDisplaySize);
1202
        swingManager.translate(this.chkVirtualField);
1203
        swingManager.translate(this.lblVirtualField);
1204
        swingManager.translate(this.lblVirtualFieldSep);
1205
        swingManager.translate(this.lblVirtualFieldGetter);
1206
        swingManager.translate(this.lblVirtualFieldSetter);
1207
        swingManager.translate(this.tabAditionalFields);
1208
        swingManager.translate(this.tabLayout);
1209
        swingManager.translate(this.lblGroup);
1210
        swingManager.translate(this.lblOrder);
1211
        swingManager.translate(this.lblHidden);
1212
        swingManager.translate(this.lblLabel);
1213
        swingManager.translate(this.lblDescription);
1214
        swingManager.translate(this.lblMinValue);
1215
        swingManager.translate(this.lblMaxValue);
1216
        swingManager.translate(this.lblAvailableValues);
1217
        swingManager.translate(this.lblAvailableValuesLabel);
1218
        swingManager.translate(this.lblAvailableValuesValue);
1219
        swingManager.translate(this.btnAvailableValuesAdd);
1220
        swingManager.translate(this.btnAvailableValuesUpdate);
1221
        swingManager.translate(this.btnAvailableValuesRemove);
1222
        swingManager.translate(this.btnAvailableValuesRemoveAll);
1223
        swingManager.translate(this.lblAttrTagsItemName);
1224
        swingManager.translate(this.lblAttrTagsItemValue);
1225
        swingManager.translate(this.lblAttrTagsItemNotes);
1226
        swingManager.translate(this.lblValuesFilter);
1227

    
1228
        swingManager.translate(this.lblRelationRepository);
1229

    
1230
        swingManager.translate(this.lblRelationNone);
1231
        swingManager.translate(this.lblRelationToOne);
1232
        swingManager.translate(this.lblRelationToMany);
1233
        
1234
        swingManager.translate(this.lblRelationToOneType);
1235
        swingManager.translate(this.lblRelationToOneCondition);
1236
        swingManager.translate(this.lblRelationToOneLabelFormula);
1237
        swingManager.translate(this.lblRelationToOneIsClosedList);
1238

    
1239
        swingManager.translate(this.lblRelationToManyType);
1240
        swingManager.translate(this.lblRelationToManyExpression);
1241
        swingManager.translate(this.lblRelationToManyCondition);
1242

    
1243
//        swingManager.translate(this.chkIsForeingKey);
1244

    
1245
        swingManager.translate(this.txtDisplaySize);
1246
        swingManager.translate(this.txtPrecision);
1247
        swingManager.translate(this.txtScale);
1248
        swingManager.translate(this.txtScale);
1249
        swingManager.translate(this.lblLocale);
1250

    
1251
        swingManager.translate(this.rdbRelationToMany);
1252
        
1253
        this.lblRelationToMany.setText( this.lblRelationToMany.getText() +
1254
                "  ("+
1255
                i18n.getTranslation("_Requires_that_it_be_a_calculated_field_of_list_type") +
1256
                ")"
1257
                );
1258
        swingManager.translate(this.lblRelationVirtual);
1259
        swingManager.translate(this.lblRelationReferences1);
1260
        swingManager.translate(this.lblRelationReferences2);
1261
    }
1262
    
1263
    private int getRelationType() {
1264
        if( this.rdbRelationNone.isSelected() ) {
1265
            return DynField.RELATION_TYPE_NONE;
1266
        } 
1267
        if( this.rdbRelationToOne.isSelected() ) {
1268
            return this.toOneController.getRelationType();
1269
        } 
1270
        if( this.rdbRelationToMany.isSelected() ) {
1271
            return this.toManyController.getRelationType();
1272
        }
1273
        return DynField.RELATION_TYPE_NONE;
1274
    }
1275

    
1276
    private void doChangeRelationType() {
1277
        boolean enabled;
1278
        switch(this.getMode() ) {
1279
            case MODE_EDIT_ONLY_METADATA:
1280
            case MODE_EDIT_ALL:
1281
            case MODE_VIRTUAL_FIELD:
1282
                enabled = true;
1283
                break;
1284
            case MODE_SHOW_ONLY:
1285
            default:
1286
                enabled = false;
1287
                break;
1288
        }
1289

    
1290
        this.rdbRelationNone.setEnabled(enabled);
1291
        this.rdbRelationToOne.setEnabled(enabled && !(this.getDataType().isObject() || this.getDataType().isContainer()));
1292
        this.rdbRelationToMany.setEnabled(enabled && (this.isVirtualField() || this.getDataType().getType()==DataTypes.LIST));
1293
        
1294
        if( this.rdbRelationNone.isSelected() ) {
1295
            this.pickerVirtualFieldGetter.setEnabled(enabled);
1296
            this.toOneController.setEnabled(false);
1297
            this.toManyController.setEnabled(false);
1298
        } else if( this.rdbRelationToOne.isSelected() ) {
1299
            this.pickerVirtualFieldGetter.setEnabled(enabled);
1300
            this.toManyController.setEnabled(false);
1301
            this.toOneController.setEditable(enabled);
1302
            this.toOneController.setEnabled(enabled);
1303
        } else if( this.rdbRelationToMany.isSelected() ) {
1304
            if( !this.isVirtualField() || this.getDataType().getType()!=DataTypes.LIST ) {
1305
                this.rdbRelationNone.setSelected(true);
1306
            } else {
1307
                this.pickerVirtualFieldGetter.setEnabled(false);
1308
                this.toOneController.setEnabled(false);
1309
                this.toManyController.setEditable(enabled);
1310
                this.toManyController.setEnabled(enabled);
1311
            }
1312
        }
1313
        this.toOneController.updateEnabledState();
1314
    }
1315
    
1316
    @Override
1317
    public JComponent asJComponent() {
1318
        return this;
1319
    }
1320
    
1321
    private void doIsAutomaticChanged() {
1322
        if( this.chkIsAutomatic.isSelected() ) {
1323
            DataType type = this.getDataType();
1324
            String defaultValue;
1325
            if( this.chkDefaultValue.isSelected() ) {
1326
                defaultValue = null;
1327
            } else {
1328
                defaultValue = this.txtDefaultValue.getText();
1329
            }
1330
            if( type.getType()!=DataTypes.LONG || StringUtils.isNotBlank(defaultValue) ) {
1331
                final I18nManager i18n = ToolsLocator.getI18nManager();
1332
                ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1333
                dialogs.messageDialog(
1334
                        i18n.getTranslation("_The_automatic_fields_must_be_of_type_long_and_do_not_support_default_values") +
1335
                            "\n" +
1336
                            i18n.getTranslation("_The_type_and_the_default_value_will_be_changed_to_adapt_them_to_these_needs"), 
1337
                        (String[])null, 
1338
                        i18n.getTranslation("_Warning"), 
1339
                        JOptionPane.INFORMATION_MESSAGE, 
1340
                        "_Automatic_field_flag_force_the_type_to_long_and_an_empty_default_value"
1341
                );
1342
                ListElement.setSelected(cboFieldType,DataTypes.LONG);
1343
                this.txtDefaultValue.setText("");
1344
            }
1345
        }
1346
        updateEditableStates();
1347
    }
1348
    
1349
    private void doDataTypeSelection() {
1350
        final DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
1351
        final I18nManager i18n = ToolsLocator.getI18nManager();
1352
        List<ListElement<Integer>> types = new ArrayList<>();
1353
        for (DataType dataType : dataManager) {
1354
            types.add( new ListElement<>(dataType.getName(), dataType.getType()) );
1355
        }
1356
        types.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
1357
                o1.toString().compareTo(o2.toString())
1358
        );
1359
        
1360
        DefaultListModel<ListElement<Integer>> modelTypes = new DefaultListModel<>();
1361
        for (ListElement<Integer> element : types) {
1362
            modelTypes.addElement(element);
1363
        }
1364
        final JList list = new JList();
1365
        list.setCellRenderer(new DefaultListCellRenderer() {
1366
          @Override
1367
          public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
1368
              JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1369
              label.setIcon(null);
1370
              try {
1371
                DataType dataType = dataManager.get((int) value);
1372
                IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1373
                if (theme.exists(dataType.getIconName())) {
1374
                    label.setIcon(theme.get(dataType.getIconName()));
1375
                }
1376
              } catch(Exception ex) {
1377
                // Do nothing, ignore
1378
              }
1379
              return label;
1380
          }
1381
        });
1382
        list.setModel(modelTypes);
1383
        final JScrollPane scrollpanel = new JScrollPane(list);
1384
        WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1385
        Dialog dialog = winManager.createDialog(
1386
              scrollpanel, 
1387
              i18n.getTranslation("_Data_type_selection"),
1388
              i18n.getTranslation("_Select_the_data_type"),
1389
              WindowManager_v2.BUTTONS_OK_CANCEL
1390
        );
1391
        dialog.addActionListener((ActionEvent e) -> {
1392
          if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
1393
            Integer type = (Integer) ListElement.getSelected(list);
1394
            if( type!=null ) {
1395
              ListElement.setSelected(cboFieldType, type);
1396
              if( ListElement.getSelected(cboFieldType)==null ) {
1397
                DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
1398
                DataType dataType = dataTypeManager.get(type);
1399
                cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1400
                ListElement.setSelected(cboFieldType, dataType.getType());
1401
              }
1402
            }
1403
          }
1404
        });
1405
        dialog.show(WindowManager.MODE.DIALOG);
1406
    }
1407
    
1408
    private int getMaxAttributeSize(EditableFeatureAttributeDescriptor descriptor) {
1409
        FeatureStore store = descriptor.getStore();
1410
        if(store == null){
1411
            return -1;
1412
        }
1413
        DataStoreProviderFactory providerFactory = store.getProviderFactory();
1414
        if(providerFactory == null){
1415
            return -1;
1416
        }
1417
        return ((FeatureStoreProviderFactory)providerFactory).getMaxAttributeNameSize();
1418
    }
1419

    
1420
    @Override
1421
    public EditableFeatureAttributeDescriptor fetch(EditableFeatureAttributeDescriptor descriptor) {
1422
        I18nManager i18n = ToolsLocator.getI18nManager();
1423
        try {
1424
            if (this.pickerPrecision.get() != null && this.pickerDisplaySize.get() != null) {
1425
                if (this.pickerPrecision.get() > this.pickerDisplaySize.get()) {
1426
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1427
                    int n = dialogs.confirmDialog(
1428
                            i18n.getTranslation("_The_precision_is_greater_than_the_display_size") + "\n"
1429
                                    + i18n.getTranslation("_This_can_cause_problems_with_some_data_providers_like_SHP_or_DBF")+ "\n"
1430
                                    + i18n.getTranslation("_Do_you_want_to_continue_accepting_the_current_values"),
1431
                            i18n.getTranslation("_Warning"),
1432
                            JOptionPane.YES_NO_OPTION,
1433
                            JOptionPane.WARNING_MESSAGE
1434
                    );
1435
                    if(n != JOptionPane.YES_OPTION){
1436
                        return null;
1437
                    }
1438
                }
1439
            }
1440
            if (!this.chkAllowNulls.isSelected()) {
1441
                if (descriptor.allowNull()) {
1442
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1443
                    dialogs.messageDialog(
1444
                            i18n.getTranslation("_You_have_marked_not_allow_nulls") + "\n"
1445
                            + i18n.getTranslation("If_you_are_not_fully_aware_of_the_repercussions_of_this_it_is_advisable_to_allow_nulls"),
1446
                            null,
1447
                            i18n.getTranslation("_Warning"),
1448
                            JOptionPane.INFORMATION_MESSAGE,
1449
                            "AllowNullsInFeatureTypeEditing"
1450
                    );
1451
                }
1452
            }
1453
            descriptor.setDataType((int) ListElement.getSelected(this.cboFieldType));
1454
            int maxAttributeNameSize = getMaxAttributeSize(descriptor);
1455
            String attrName = this.txtFieldName.getText();
1456
            if(maxAttributeNameSize > -1 && StringUtils.length(attrName) > maxAttributeNameSize){
1457
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1458
                    dialogs.messageDialog(
1459
                            i18n.getTranslation("_Attribute_name_is_too_long") + "\n"
1460
                            + i18n.getTranslation("_max_size_allowed_for_this_table_is_{0}",new String[]{String.valueOf(maxAttributeNameSize)}),
1461
                            null,
1462
                            i18n.getTranslation("_Warning"),
1463
                            JOptionPane.WARNING_MESSAGE
1464
                    );
1465
                    return null;
1466
            }
1467
            descriptor.setName(attrName);
1468
            descriptor.setAllowNull(this.chkAllowNulls.isSelected());
1469
            descriptor.setIsPrimaryKey(this.chkIsPrimaryKey.isSelected());
1470
            descriptor.setIsAutomatic(this.chkIsAutomatic.isSelected());
1471
            descriptor.setIsReadOnly(this.chkIsReadOnly.isSelected());
1472
            descriptor.setIsIndexed(this.chkIsIndexed.isSelected());
1473
            descriptor.setSize(this.pickerSize.get(0));
1474
            descriptor.setDisplaySize(this.pickerDisplaySize.get(0));
1475
            descriptor.setPrecision(this.pickerPrecision.get(0));
1476
            descriptor.setScale(this.pickerScale.get(0));
1477
            
1478
            String defaultValue;
1479
            if( this.chkDefaultValue.isSelected() ) {
1480
                defaultValue = null;
1481
            } else {
1482
                defaultValue = this.txtDefaultValue.getText();
1483
            }
1484
            switch(this.mode) {
1485
                case MODE_EDIT_ONLY_METADATA:
1486
                    if( !ExpressionUtils.isDynamicText(defaultValue) ) {
1487
                        if( !StringUtils.equals(this.previousDefaultValue, defaultValue)) {
1488
                            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1489
                            dialogs.messageDialog(
1490
                                    i18n.getTranslation("_In_metadata_editing_only_mode_it_is_only_allowed_to_indicate_default_values_with_dynamic_expressions"),
1491
                                    null,
1492
                                    i18n.getTranslation("_Warning"),
1493
                                    JOptionPane.WARNING_MESSAGE
1494
                            );
1495
                            return null;
1496
                        }
1497
                    }
1498
                case MODE_EDIT_ALL:
1499
                case MODE_SHOW_ONLY:
1500
                case MODE_VIRTUAL_FIELD:
1501
                    descriptor.setDefaultValue(defaultValue);
1502
            }
1503
            
1504
            descriptor.setDefaultFormat(this.txtDefaultFormat.getText());
1505
            descriptor.setDataProfileName((String) ListElement.getSelected(this.cboDataProfile));
1506
            switch (descriptor.getType()) {
1507
                case DataTypes.GEOMETRY:
1508
                    GeometryManager geomManager = GeometryLocator.getGeometryManager();
1509
                    GeometryType geomType = geomManager.getGeometryType(
1510
                            (int) ListElement.getSelected(this.cboGeometryType),
1511
                            (int) ListElement.getSelected(this.cboGeometrySubtype)
1512
                    );
1513
                    descriptor.setGeometryType(geomType);
1514
                    descriptor.setSRS(this.pickerCRS.get());
1515
                    break;
1516
                case DataTypes.INSTANT:
1517
                case DataTypes.INTERVAL:
1518
                case DataTypes.DATE:
1519
                case DataTypes.TIME:
1520
                case DataTypes.TIMESTAMP:
1521
                    // FIXME
1522
                    break;
1523
                default:
1524
                    break;
1525
            }
1526
            descriptor.setDataProfileName(
1527
                    StringUtils.defaultIfBlank((String) ListElement.getSelected(cboDataProfile), null)
1528
            );
1529

    
1530
            if (this.chkVirtualField.isSelected() ) { //&& this.pickerVirtualField.isEnabled()) {
1531
                Expression expression = this.pickerVirtualFieldGetter.get();
1532
                if (expression == null) {
1533
                    descriptor.setFeatureAttributeEmulator((String) null);
1534
                } else {
1535
                    DataManager dataManager = DALLocator.getDataManager();
1536
                    FeatureAttributeEmulatorExpression emulator = dataManager.createFeatureAttributeEmulatorExpression(
1537
                            getFeatureType(descriptor),
1538
                            expression
1539
                    );
1540
                    if (!emulator.isValid()) {
1541
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1542
                        dialogs.messageDialog(
1543
                                i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")+"\n"
1544
                                + "\n"
1545
                                + emulator.getErrorMessage(),
1546
                                i18n.getTranslation("_Warning"),
1547
                                JOptionPane.WARNING_MESSAGE
1548
                        );
1549
                        return null;
1550
                    }
1551
                    for (String requiredFieldName : emulator.getRequiredFieldNames()) {
1552
                        if (StringUtils.equalsIgnoreCase(requiredFieldName, descriptor.getName())) {
1553
                            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1554
                            dialogs.messageDialog(
1555
                                    i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")
1556
                                    + "\n\n"
1557
                                    + i18n.getTranslation("_The_expression_contains_a_reference_to_itself"),
1558
                                    i18n.getTranslation("_Warning"),
1559
                                    JOptionPane.WARNING_MESSAGE
1560
                            );
1561
                            return null;
1562
                        }
1563
                    }
1564
                    List<String> undefinedSymbols = emulator.getUndefinedSymbols();
1565
                    if( undefinedSymbols!=null && !undefinedSymbols.isEmpty() ) {
1566
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1567
                        dialogs.messageDialog(
1568
                                i18n.getTranslation("_The_expression_has_undefined_symbols_at_this_moment")+"\n"
1569
                                + i18n.getTranslation("_This_may_not_be_a_mistake")+"\n"
1570
                                + "\n"
1571
                                + "("+StringUtils.join(undefinedSymbols,",")+")",
1572
                                i18n.getTranslation("_Warning"),
1573
                                JOptionPane.WARNING_MESSAGE
1574
                        );
1575
                    }
1576
                    //
1577
                    // No se porque esto de abajo no funciona.
1578
                    // Nunca se lanza la excepcion en el get(Feature) de
1579
                    // DefaultFeatureAttributeEmulatorExpression.
1580
                    //
1581
                    try {
1582
                        emulator.setEnableExceptions(true);
1583
//                        descriptor.setFeatureAttributeEmulator(emulator);
1584
                        emulator.get(this.sampleFeature);
1585
                    } catch(Throwable ex) {
1586
//                        emulator.setEnableExceptions(false);
1587
//                        descriptor.setFeatureAttributeEmulator(null);
1588
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1589
                        dialogs.messageDialog(
1590
                                i18n.getTranslation("_The_expression_can_not_be_evaluated_right_now_It_could_be_valid_when_all_changes_has_been_applied")+
1591
                                    "\n"+
1592
                                    ex.getMessage(), 
1593
                                i18n.getTranslation("_Warning"), 
1594
                                JOptionPane.WARNING_MESSAGE
1595
                        );
1596
//                        return null;
1597
                    } finally {
1598
                        emulator.setEnableExceptions(false);
1599
                    }
1600
                    descriptor.setFeatureAttributeEmulator(emulator);
1601
                }
1602
            }
1603
        } catch (Exception ex) {
1604
            LOGGER.warn("Can't retrieve information from user form.", ex);
1605
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1606
            dialogs.messageDialog(
1607
                    i18n.getTranslation("_Cant_retrieve_information_from_user_form")
1608
                    + "\n"
1609
                    + i18n.getTranslation("_See_log_for_details"),
1610
                    i18n.getTranslation("_Warning"),
1611
                    JOptionPane.WARNING_MESSAGE
1612
            );
1613
            return null;
1614
        }
1615

    
1616
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
1617
        descriptor.setOrder(this.pickerOrder.get(0));
1618
        descriptor.setHidden(this.chkHidden.isSelected());
1619
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
1620
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
1621

    
1622
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1623
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1624
        Expression valuesFilter = this.pickerValuesFilter.get();
1625
        
1626
        descriptor.setAvailableValues(this.availableValuesController.get());
1627
        descriptor.setLocale(this.pickerLocale.get());
1628

    
1629
        this.tagsController.getModel().fetch(descriptor.getTags());
1630

    
1631
        this.toOneController.fetch(descriptor);
1632
        this.toManyController.fetch(descriptor);
1633
        if( rdbRelationToOne.isSelected() ) {
1634
            descriptor.setRelationType(this.toOneController.getRelationType());
1635
            descriptor.getForeingKey().setForeingKey(true);
1636
        } else if( rdbRelationToMany.isSelected() ) {
1637
            descriptor.setRelationType(this.toManyController.getRelationType());
1638
            descriptor.getForeingKey().setForeingKey(false);
1639
            descriptor.setFeatureAttributeEmulator(this.toManyController.getExpression());
1640
        } else if( rdbRelationNone.isSelected() ) {
1641
            descriptor.setRelationType(DynField.RELATION_TYPE_NONE);
1642
            descriptor.getForeingKey().setForeingKey(false);
1643
        }
1644

    
1645

    
1646
        return descriptor;
1647
    }
1648

    
1649
    @Override
1650
    public void clean() {
1651
        this.txtDefaultValue.setText("");
1652
        this.chkDefaultValue.setEnabled(true);
1653
        this.txtDefaultValue.setEditable(false);
1654
        this.txtDefaultFormat.setText("");
1655
        this.txtFieldName.setText("");
1656
//        this.pickerFieldName.set(null);
1657
        this.pickerIntervalEnd.set(null);
1658
        this.pickerIntervalStart.set(null);
1659
        this.pickerScale.set(null);
1660
        this.pickerSize.set(null);
1661
        this.pickerDisplaySize.set(null);
1662

    
1663
        this.chkAllowNulls.setSelected(false);
1664
        this.chkIsAutomatic.setSelected(false);
1665
        this.chkIsReadOnly.setSelected(false);
1666
        this.chkIsIndexed.setSelected(false);
1667
        this.chkIsPrimaryKey.setSelected(false);
1668

    
1669
        switch (this.mode){
1670
            case MODE_EDIT_ALL:
1671
            case MODE_EDIT_ONLY_METADATA:
1672
                this.chkVirtualField.setSelected(false);
1673
                this.chkVirtualField.setEnabled(true);
1674
                break;
1675
            case MODE_SHOW_ONLY:
1676
                this.chkVirtualField.setSelected(false);
1677
                this.chkVirtualField.setEnabled(false);
1678
                break;
1679
            case MODE_VIRTUAL_FIELD:
1680
                this.chkVirtualField.setSelected(true);
1681
                this.chkVirtualField.setEnabled(false);
1682
                break;
1683
        }
1684
        this.pickerVirtualFieldGetter.setEditable(false);
1685
        this.pickerVirtualFieldGetter.set(null);
1686

    
1687
        ListElement.setSelected(cboGeometryType, null);
1688
        ListElement.setSelected(cboGeometrySubtype, null);
1689

    
1690
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
1691

    
1692
        this.cboDataProfile.setSelectedIndex(-1);
1693

    
1694
        this.cboGroup.setSelectedIndex(-1);
1695
        this.pickerOrder.set(null);
1696
        this.chkHidden.setSelected(false);
1697
        this.txtLabel.setText("");
1698
        this.txtDescription.setText("");
1699
        this.txtMinValue.setText("");
1700
        this.txtMaxValue.setText("");
1701
        this.availableValuesController.clean();
1702
        this.tagsController.clean();
1703
        this.toOneController.clean();
1704
    }
1705

    
1706
    @Override
1707
    public void put(FeatureAttributeDescriptor descriptor) {
1708
        if (descriptor == null) {
1709
            this.clean();
1710
            return;
1711
        }
1712
        DataType dataType = descriptor.getDataType();
1713
        FeatureType featureType = descriptor.getFeatureType();
1714
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
1715

    
1716
        if (featureType != null) {
1717
            FeatureStore store = descriptor.getFeatureType().getStore();
1718
            this.featureStoreElement.setFeatureStore(store);
1719
            if (store != null) {
1720
                this.sampleFeature = store.getSampleFeature();
1721
                if (sampleFeature != null) {
1722
                    FeatureSymbolTable featureSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable();
1723
                    featureSymbolTable.setFeature(sampleFeature);
1724
                    this.pickerVirtualFieldGetter.getConfig().setPreviewSymbolTable(featureSymbolTable.createParent());
1725
                    this.pickerValuesFilter.getConfig().setPreviewSymbolTable(featureSymbolTable.createParent());
1726
                }
1727
            }
1728
            List<String> groups = new ArrayList<>();
1729
            for (FeatureAttributeDescriptor otherdesc : featureType) {
1730
                String group = otherdesc.getGroup();
1731
                if (!StringUtils.isBlank(group) && !groups.contains(group)) {
1732
                    groups.add(group);
1733
                }
1734
            }
1735
            for (String group : groups) {
1736
                groupModel.addElement(group);
1737
            }
1738
        }
1739

    
1740
        this.previousDefaultValue = Objects.toString(descriptor.getDefaultValue(),null);
1741
        if( this.previousDefaultValue == null ) {
1742
            this.txtDefaultValue.setText("");
1743
            this.chkDefaultValue.setSelected(true);
1744
            this.txtDefaultValue.setEditable(false);
1745
        } else {
1746
            this.txtDefaultValue.setText(this.previousDefaultValue);
1747
            this.chkDefaultValue.setSelected(false);
1748
            this.txtDefaultValue.setEditable(true);
1749
        }
1750
        
1751
        this.txtDefaultFormat.setText(Objects.toString(descriptor.getDefaultFormat(),""));
1752
        this.txtFieldName.setText(descriptor.getName());
1753
        RelativeInterval interval = (RelativeInterval) descriptor.getInterval();
1754
        if (interval == null) {
1755
            this.pickerIntervalEnd.set(null);
1756
            this.pickerIntervalStart.set(null);
1757
        } else {
1758
            this.pickerIntervalEnd.set(interval.getEnd().toDate());
1759
            this.pickerIntervalStart.set(interval.getStart().toDate());
1760
        }
1761
        if( dataType.supportSize() ) {
1762
          this.pickerSize.set(descriptor.getSize());
1763
        } else {
1764
          this.pickerSize.set(null);
1765
        }
1766
        this.pickerDisplaySize.set(descriptor.getDisplaySize());
1767
        if( dataType.supportPrecision() ) {
1768
          this.pickerPrecision.set(descriptor.getPrecision());
1769
        } else {
1770
          this.pickerPrecision.set(null);
1771
        }
1772
        if( dataType.supportScale()) {
1773
          this.pickerScale.set(descriptor.getScale());
1774
        } else {
1775
          this.pickerScale.set(null);
1776
        }
1777
        this.chkAllowNulls.setSelected(descriptor.allowNull());
1778
        this.chkIsAutomatic.setSelected(descriptor.isAutomatic());
1779
        this.chkIsReadOnly.setSelected(descriptor.isReadOnly());
1780
        this.chkIsIndexed.setSelected(descriptor.isIndexed());
1781
        this.chkIsPrimaryKey.setSelected(descriptor.isPrimaryKey());
1782

    
1783
        this.pickerVirtualFieldGetter.setEnabled(true);
1784
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1785
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1786
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1787
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1788
            this.chkVirtualField.setSelected(true);
1789
            this.pickerVirtualFieldGetter.set(expression);
1790
        } else if (descriptor.isComputed()) {
1791
            this.chkVirtualField.setEnabled(false);
1792
            this.chkVirtualField.setSelected(true);
1793
            this.pickerVirtualFieldGetter.set(null);
1794
        } else {
1795
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1796
            this.chkVirtualField.setSelected(false);
1797
            this.pickerVirtualFieldGetter.set(null);
1798
        }
1799
        this.pickerVirtualFieldGetter.setEnabled(true);
1800

    
1801
        Expression expression = descriptor.getAvailableValuesFilter();
1802
        this.pickerValuesFilter.set(expression);
1803

    
1804
        this.pickerCRS.set(descriptor.getSRS());
1805

    
1806
        if (descriptor.getGeomType() != null) {
1807
            ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1808
            ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1809
        }
1810
        ListElement.setSelected(cboFieldType, dataType.getType());
1811
        if( ListElement.getSelected(cboFieldType)==null ) {
1812
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1813
          ListElement.setSelected(cboFieldType, dataType.getType());
1814
        }
1815
 
1816
        String profile = descriptor.getDataProfileName();
1817
        if (StringUtils.isBlank(profile)) {
1818
            this.cboDataProfile.setSelectedIndex(-1);
1819
        } else {
1820
            ListElement.setSelected(this.cboDataProfile, profile);
1821
        }
1822

    
1823
        this.cboGroup.setModel(groupModel);
1824
        this.cboGroup.setSelectedItem(StringUtils.defaultIfBlank(descriptor.getGroup(), ""));
1825
        this.pickerOrder.set(descriptor.getOder());
1826
        this.chkHidden.setSelected(descriptor.isHidden());
1827
        if (descriptor.hasLabel()) {
1828
            this.txtLabel.setText(StringUtils.defaultIfBlank(descriptor.getLabel(), ""));
1829
        } else {
1830
            this.txtLabel.setText("");
1831
        }
1832
        if (descriptor.hasDescription()) {
1833
            this.txtDescription.setText(StringUtils.defaultIfBlank(descriptor.getDescription(), ""));
1834
        } else {
1835
            this.txtDescription.setText("");
1836
        }
1837
        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1838
        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1839
        if( descriptor.hasConstantAvailableValues() ) {
1840
          this.availableValuesController.set(descriptor.getAvailableValues());
1841
        } else {
1842
          this.availableValuesController.clean();
1843
        }
1844
        this.tagsController.setModel(new TagsModel(descriptor.getTags()));
1845
        this.pickerLocale.set(descriptor.getLocale());
1846

    
1847
        this.toOneController.put(descriptor);
1848
        this.toManyController.put(descriptor);
1849
        switch(descriptor.getRelationType()) {
1850
            case DynField.RELATION_TYPE_NONE:
1851
                this.rdbRelationNone.setSelected(true);
1852
                this.rdbRelationToOne.setSelected(false);
1853
                this.rdbRelationToMany.setSelected(false); 
1854
                  // No los borramos, solo quedan deshabilitados, para no peder la informacion que contengan
1855
//                this.toOneController.clean(); 
1856
//                this.toManyController.clean();
1857
                break;
1858
            case DynField.RELATION_TYPE_IDENTITY:
1859
            case DynField.RELATION_TYPE_COLLABORATION:
1860
            case DynField.RELATION_TYPE_COLLABORATION_WITH_COMPOSITION:
1861
                this.rdbRelationNone.setSelected(false);
1862
                this.rdbRelationToOne.setSelected(true);
1863
                this.rdbRelationToMany.setSelected(false);
1864
//                this.toManyController.clean();
1865
                break;
1866
            case DynField.RELATION_TYPE_COMPOSITION:
1867
            case DynField.RELATION_TYPE_AGGREGATE:
1868
                this.rdbRelationNone.setSelected(false);
1869
                this.rdbRelationToOne.setSelected(false);
1870
                this.rdbRelationToMany.setSelected(true);
1871
                this.pickerVirtualFieldGetter.setEnabled(false);
1872
//                this.pickerVirtualFieldGetter.set(null);
1873
//                this.toOneController.clean();
1874
                break;
1875
              
1876
        }
1877
        
1878
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1879
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1880
        }
1881
        this.updateEditableStates();
1882
    }
1883
    
1884
    public void setFeatureType(FeatureType featureType){
1885
        this.featureType = featureType;
1886
        this.toManyController.setFeatureType(featureType);
1887
    }
1888
    
1889
    private FeatureType getFeatureType(FeatureAttributeDescriptor descriptor) {
1890
        if(descriptor ==  null || descriptor.getFeatureType() == null){
1891
            return this.featureType;
1892
        }
1893
        return descriptor.getFeatureType();
1894
    }
1895

    
1896
    private DataType getDataType() {
1897
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1898
      if (fieldType == null) {
1899
          return null;
1900
      }
1901
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1902
      return dataType;
1903
    }
1904

    
1905
    private void doFieldTypeChanged() {
1906
      try {
1907
        DataType dataType = this.getDataType();
1908

    
1909
        if( dataType.supportSize() ) {
1910
            this.pickerSize.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1911
        } else {
1912
            this.pickerSize.setEditable(false);
1913
            this.pickerSize.set(null);
1914
        }        
1915
        this.pickerDisplaySize.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1916
        if( dataType.supportPrecision() ) {
1917
          if( dataType.isPredefinedPrecision() ) {
1918
            this.pickerPrecision.setEditable(false);
1919
          } else {
1920
            this.pickerPrecision.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1921
          }
1922
        } else {
1923
            this.pickerPrecision.setEditable(false);
1924
            this.pickerPrecision.set(null);
1925
        }        
1926
        if( dataType.supportScale()) {
1927
            this.pickerScale.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1928
        } else {
1929
            this.pickerScale.setEditable(false);
1930
            this.pickerScale.set(null);
1931
        }        
1932
        switch (dataType.getType()) {
1933
          case DataTypes.GEOMETRY:
1934
            this.cboGeometryType.setEnabled(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1935
            this.cboGeometrySubtype.setEnabled(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1936
            this.pickerCRS.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1937
            this.cboDateFormat.setEnabled(false);
1938
            this.pickerIntervalStart.setEditable(false);
1939
            this.pickerIntervalEnd.setEditable(false);
1940
            this.tabAditionalFields.setEnabledAt(1, true);
1941
            this.tabAditionalFields.setEnabledAt(2, false);
1942
            break;
1943
          case DataTypes.INSTANT:
1944
          case DataTypes.INTERVAL:
1945
          case DataTypes.DATE:
1946
          case DataTypes.TIME:
1947
          case DataTypes.TIMESTAMP:
1948
            this.cboGeometryType.setEnabled(false);
1949
            this.cboGeometrySubtype.setEnabled(false);
1950
            this.pickerCRS.setEditable(false);
1951
            this.cboDateFormat.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA || this.isVirtualField());
1952
            this.pickerIntervalStart.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA || this.isVirtualField());
1953
            this.pickerIntervalEnd.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA || this.isVirtualField());
1954
            this.tabAditionalFields.setEnabledAt(1, false);
1955
            this.tabAditionalFields.setEnabledAt(2, true);
1956
            break;
1957
          case DataTypes.BYTE:
1958
          case DataTypes.INT:
1959
          case DataTypes.LONG:
1960
          case DataTypes.STRING:
1961
          case DataTypes.FILE:
1962
          case DataTypes.URL:
1963
          case DataTypes.URI:
1964
          case DataTypes.FLOAT:
1965
          case DataTypes.DOUBLE:
1966
          case DataTypes.DECIMAL:
1967
            this.cboGeometryType.setEnabled(false);
1968
            this.cboGeometrySubtype.setEnabled(false);
1969
            this.pickerCRS.setEditable(false);
1970
            this.cboDateFormat.setEnabled(false);
1971
            this.pickerIntervalStart.setEditable(false);
1972
            this.pickerIntervalEnd.setEditable(false);
1973
            this.tabAditionalFields.setEnabledAt(1, false);
1974
            this.tabAditionalFields.setEnabledAt(2, false);
1975
            break;
1976
          default:
1977
            this.cboGeometryType.setEnabled(false);
1978
            this.cboGeometrySubtype.setEnabled(false);
1979
            this.pickerCRS.setEditable(false);
1980
            this.cboDateFormat.setEnabled(false);
1981
            this.pickerIntervalStart.setEditable(false);
1982
            this.pickerIntervalEnd.setEditable(false);
1983
            this.tabAditionalFields.setEnabledAt(1, false);
1984
            this.tabAditionalFields.setEnabledAt(2, false);
1985
        }
1986
//        updateRelationState();
1987
        doChangeRelationType();
1988
      } catch (Exception ex) {
1989
        LOGGER.warn("Problems changing field type.", ex);
1990
      }
1991

    
1992
    }
1993
    
1994
    boolean isVirtualField() {
1995
        return this.chkVirtualField.isSelected();
1996
    }
1997

    
1998
    @Override
1999
    public int getMode() {
2000
        return this.mode;
2001
    }
2002
    
2003
    @Override
2004
    public void setMode(int mode) {
2005
        this.mode = mode;
2006
        updateEditableStates();
2007
    }
2008
    
2009
    private void updateEditableStates() {
2010
        DataType dataType = this.getDataType();
2011
        switch(this.mode) {
2012
            case MODE_EDIT_ALL:
2013
                this.txtDefaultValue.setEditable(!this.chkIsAutomatic.isSelected());
2014
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2015
                this.txtDefaultFormat.setEditable(true);
2016
                this.txtFieldName.setEditable(true);
2017
                this.pickerIntervalEnd.setEditable(true);
2018
                this.pickerIntervalStart.setEditable(true);
2019
                this.pickerSize.setEditable(dataType.supportSize());
2020
                this.pickerDisplaySize.setEditable(true);
2021
                if( dataType.isPredefinedPrecision() ) {
2022
                  this.pickerPrecision.setEditable(false);
2023
                  this.pickerPrecision.set(dataType.getMaxPrecision());
2024
                } else {
2025
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
2026
                }
2027
                this.pickerScale.setEditable(dataType.supportScale());
2028
                this.cboDataProfile.setEnabled(true);
2029

    
2030
                this.chkAllowNulls.setEnabled(true);
2031
                this.chkIsAutomatic.setEnabled(true);
2032
                this.chkIsReadOnly.setEnabled(true);
2033
                this.chkIsIndexed.setEnabled(true);
2034
                if( this.isVirtualField() ) {
2035
                    this.chkIsPrimaryKey.setEnabled(false);
2036
                } else {
2037
                    this.chkIsPrimaryKey.setEnabled(true);
2038
                }
2039

    
2040
                this.chkVirtualField.setEnabled(true);
2041
                this.pickerVirtualFieldGetter.setEditable(true);
2042

    
2043
                this.cboDateFormat.setEnabled(true);
2044
                this.cboFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
2045
                this.btnFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
2046
                this.cboGeometryType.setEnabled(true);
2047
                this.cboGeometrySubtype.setEnabled(true);
2048
                this.pickerCRS.setEditable(true);
2049

    
2050
                this.cboGroup.setEnabled(true);
2051
                this.pickerOrder.setEditable(true);
2052
                this.chkHidden.setEnabled(true);
2053
                this.txtLabel.setEditable(true);
2054
                this.txtDescription.setEditable(true);
2055
                this.txtMinValue.setEditable(false);
2056
                this.txtMaxValue.setEditable(false);
2057
                this.pickerValuesFilter.setEditable(true);
2058
                this.availableValuesController.setEditable(true);
2059
                this.tagsController.setEnabled(true);
2060
                this.pickerLocale.setEnabled(true);
2061
                break;
2062
            case MODE_EDIT_ONLY_METADATA:
2063
                if( this.chkVirtualField.isSelected() ) {
2064
                    this.txtFieldName.setEditable(true);
2065
                    this.pickerScale.setEditable(true);
2066
                    this.pickerSize.setEditable(true);
2067
                    this.pickerVirtualFieldGetter.setEditable(true);
2068
                    this.cboFieldType.setEnabled(true);
2069
                    this.btnFieldType.setEnabled(true);
2070
                    this.cboGeometryType.setEnabled(true);
2071
                    this.cboGeometrySubtype.setEnabled(true);
2072
                    this.pickerCRS.setEditable(true);
2073
                } else {
2074
                    this.txtFieldName.setEditable(false);
2075
                    this.pickerPrecision.setEditable(false);
2076
                    this.pickerScale.setEditable(false);
2077
                    this.pickerSize.setEditable(false);
2078
                    this.pickerVirtualFieldGetter.setEditable(false);
2079
                    this.cboFieldType.setEnabled(false);
2080
                    this.btnFieldType.setEnabled(false);
2081
                    this.cboGeometryType.setEnabled(false);
2082
                    this.cboGeometrySubtype.setEnabled(false);
2083
                    this.pickerCRS.setEditable(false);
2084
                }
2085

    
2086
                this.pickerLocale.setEnabled(true);
2087
                this.txtDefaultValue.setEditable(true);
2088
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2089
                this.txtDefaultFormat.setEditable(true);
2090
                this.pickerIntervalEnd.setEditable(true);
2091
                this.pickerIntervalStart.setEditable(true);
2092

    
2093
                this.cboDataProfile.setEnabled(true);
2094

    
2095
                this.pickerDisplaySize.setEditable(false);
2096
                this.chkAllowNulls.setEnabled(false);
2097
                this.chkIsAutomatic.setEnabled(false);
2098
                this.chkIsReadOnly.setEnabled(false);
2099
                this.chkIsIndexed.setEnabled(false);
2100
//                if( this.isVirtualField() ) {
2101
                    this.chkIsPrimaryKey.setEnabled(false);
2102
//                } else {
2103
//                    this.chkIsPrimaryKey.setEnabled(true);
2104
//                }
2105

    
2106
                this.chkVirtualField.setEnabled(false);
2107

    
2108
                this.cboDateFormat.setEnabled(true);
2109

    
2110
                this.cboGroup.setEnabled(true);
2111
                this.pickerOrder.setEditable(true);
2112
                this.chkHidden.setEnabled(true);
2113
                this.txtLabel.setEditable(true);
2114
                this.txtDescription.setEditable(true);
2115
                this.txtMinValue.setEditable(false);
2116
                this.txtMaxValue.setEditable(false);
2117
                this.pickerValuesFilter.setEditable(true);
2118
                this.availableValuesController.setEditable(true);
2119
                this.tagsController.setEnabled(true);
2120
                break;
2121
            case MODE_SHOW_ONLY:
2122
                this.txtDefaultValue.setEditable(false);
2123
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2124
                this.txtDefaultFormat.setEditable(false);
2125
                this.txtFieldName.setEditable(false);
2126
                this.pickerIntervalEnd.setEditable(false);
2127
                this.pickerIntervalStart.setEditable(false);
2128
                this.pickerPrecision.setEditable(false);
2129
                this.pickerScale.setEditable(false);
2130
                this.pickerSize.setEditable(false);
2131
                this.pickerDisplaySize.setEditable(false);
2132
                this.cboDataProfile.setEnabled(false);
2133
                this.pickerLocale.setEnabled(false);
2134

    
2135
                this.chkAllowNulls.setEnabled(false);
2136
                this.chkIsAutomatic.setEnabled(false);
2137
                this.chkIsReadOnly.setEnabled(false);
2138
                this.chkIsIndexed.setEnabled(false);
2139
                this.chkIsPrimaryKey.setEnabled(false);
2140

    
2141
                this.chkVirtualField.setEnabled(false);
2142
                this.pickerVirtualFieldGetter.setEditable(false);
2143

    
2144
                this.cboDateFormat.setEnabled(false);
2145
                this.cboFieldType.setEnabled(false);
2146
                this.btnFieldType.setEnabled(false);
2147
                this.cboGeometryType.setEnabled(false);
2148
                this.cboGeometrySubtype.setEnabled(false);
2149
                this.pickerCRS.setEditable(false);
2150

    
2151
                this.cboGroup.setEnabled(false);
2152
                this.pickerOrder.setEditable(false);
2153
                this.chkHidden.setEnabled(false);
2154
                this.txtLabel.setEditable(false);
2155
                this.txtDescription.setEditable(false);
2156
                this.txtMinValue.setEditable(false);
2157
                this.txtMaxValue.setEditable(false);
2158
                this.pickerValuesFilter.setEditable(false);
2159
                this.availableValuesController.setEditable(false);
2160
                this.tagsController.setEnabled(false);
2161
                break;
2162
            case MODE_VIRTUAL_FIELD:
2163
                this.txtDefaultValue.setEditable(!this.chkIsAutomatic.isSelected());
2164
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2165
                this.txtDefaultFormat.setEditable(true);
2166
                this.txtFieldName.setEditable(true);
2167
                this.pickerIntervalEnd.setEditable(true);
2168
                this.pickerIntervalStart.setEditable(true);
2169
                this.pickerSize.setEditable(dataType.supportSize());
2170
                this.pickerDisplaySize.setEditable(true);
2171
                if( dataType.isPredefinedPrecision() ) {
2172
                  this.pickerPrecision.setEditable(false);
2173
                  this.pickerPrecision.set(dataType.getMaxPrecision());
2174
                } else {
2175
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
2176
                }
2177
                this.pickerScale.setEditable(dataType.supportScale());
2178
                this.cboDataProfile.setEnabled(true);
2179

    
2180
                this.chkAllowNulls.setEnabled(true);
2181
                this.chkIsAutomatic.setEnabled(true);
2182
                this.chkIsReadOnly.setEnabled(true);
2183
                this.chkIsIndexed.setEnabled(true);
2184
                if( this.isVirtualField() ) {
2185
                    this.chkIsPrimaryKey.setEnabled(false);
2186
                } else {
2187
                    this.chkIsPrimaryKey.setEnabled(true);
2188
                }
2189

    
2190
                this.chkVirtualField.setEnabled(false);
2191
                this.chkVirtualField.setSelected(true);
2192
                this.pickerVirtualFieldGetter.setEditable(true);
2193

    
2194
                this.cboDateFormat.setEnabled(true);
2195
                this.cboFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
2196
                this.btnFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
2197
                this.cboGeometryType.setEnabled(true);
2198
                this.cboGeometrySubtype.setEnabled(true);
2199
                this.pickerCRS.setEditable(true);
2200

    
2201
                this.cboGroup.setEnabled(true);
2202
                this.pickerOrder.setEditable(true);
2203
                this.chkHidden.setEnabled(true);
2204
                this.txtLabel.setEditable(true);
2205
                this.txtDescription.setEditable(true);
2206
                this.txtMinValue.setEditable(false);
2207
                this.txtMaxValue.setEditable(false);
2208
                this.pickerValuesFilter.setEditable(true);
2209
                this.availableValuesController.setEditable(true);
2210
                this.tagsController.setEnabled(true);
2211
                this.pickerLocale.setEnabled(true);
2212
                break;
2213
        }
2214
        this.txtDisplaySize.setBackground(UIManager.getColor(ToolsSwingManager.COLOR_TEXTFIELD_BACKGROUND));
2215
        if(this.pickerPrecision.get() != null && this.pickerDisplaySize.get() != null){
2216
            if(this.pickerPrecision.get() > this.pickerDisplaySize.get()){
2217
                this.txtDisplaySize.setBackground(ToolsSwingLocator.getToolsSwingManager().getWarningBackgroundColor());
2218
            }
2219
        }
2220
        doChangeRelationType();
2221
    }
2222
    
2223
    private void doCheckPrecisionAndScale() {
2224
      DataType dataType = this.getDataType();
2225
      
2226
      Integer precision = this.pickerPrecision.get();
2227
      if( precision==null ) {
2228
        precision = 0;
2229
      }
2230
      Integer scale = this.pickerScale.get();
2231
      if( scale == null ) {
2232
        scale = 0;
2233
      }      
2234
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
2235
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
2236
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
2237
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
2238
      } else {
2239
        this.pickerPrecision.setWarning(false);
2240
        this.pickerScale.setWarning(false);
2241
      }
2242
    }
2243

    
2244
    @Override
2245
    public void setNameAsNew(FeatureType featureType) {
2246
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
2247
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
2248
                cloneFeatureType.getNewFieldName(), 
2249
                DataTypes.STRING,
2250
                50);
2251
        this.put(newAttributeDescriptor);
2252
    }
2253

    
2254
    @Override
2255
    public String getName() {
2256
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
2257
    }
2258

    
2259
    @Override
2260
    public ImageIcon loadImage(String imageName) {
2261
        return ToolsSwingUtils.loadImage(this, imageName);
2262
    }
2263

    
2264
  public static void selfRegister() {
2265
    boolean n = ToolsSwingUtils.registerIcons( 
2266
            DefaultFeatureAttributeSelectionPanel.class,
2267
            null,
2268
            LIBRARY_NAME,
2269
            new String[]{ "picker", "picker-datatype", "picker-datatype"}
2270
    );      
2271
  }
2272

    
2273
}