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

History | View | Annotate | Download (104 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
    private IProjection defaultProjection;
138

    
139
    private static class ToOneController {
140

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

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

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

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

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

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

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

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

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

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

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

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

    
724
    private static class AvailableValuesController {
725

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

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

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

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

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

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

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

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

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

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

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

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

    
864
    }
865

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

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

    
887
    private int mode;
888
    private FeatureStoreElement featureStoreElement;
889

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

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

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

    
929
        this.initComponents();
930
    }
931

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

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

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

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

    
981
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
982

    
983

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1229
        swingManager.translate(this.lblRelationRepository);
1230

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

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

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

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

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

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

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

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

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

    
1629
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
1630
        descriptor.setOrder(this.pickerOrder.get(0));
1631
        descriptor.setHidden(this.chkHidden.isSelected());
1632
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
1633
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
1634

    
1635
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1636
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1637
        Expression valuesFilter = this.pickerValuesFilter.get();
1638
        
1639
        descriptor.setAvailableValues(this.availableValuesController.get());
1640
        descriptor.setLocale(this.pickerLocale.get());
1641

    
1642
        this.tagsController.getModel().fetch(descriptor.getTags());
1643

    
1644
        this.toOneController.fetch(descriptor);
1645
        this.toManyController.fetch(descriptor);
1646
        if( rdbRelationToOne.isSelected() ) {
1647
            descriptor.setRelationType(this.toOneController.getRelationType());
1648
            descriptor.getForeingKey().setForeingKey(true);
1649
        } else if( rdbRelationToMany.isSelected() ) {
1650
            descriptor.setRelationType(this.toManyController.getRelationType());
1651
            descriptor.getForeingKey().setForeingKey(false);
1652
            descriptor.setFeatureAttributeEmulator(this.toManyController.getExpression());
1653
        } else if( rdbRelationNone.isSelected() ) {
1654
            descriptor.setRelationType(DynField.RELATION_TYPE_NONE);
1655
            descriptor.getForeingKey().setForeingKey(false);
1656
        }
1657

    
1658

    
1659
        return descriptor;
1660
    }
1661

    
1662
    @Override
1663
    public void clean() {
1664
        this.txtDefaultValue.setText("");
1665
        this.chkDefaultValue.setEnabled(true);
1666
        this.txtDefaultValue.setEditable(false);
1667
        this.txtDefaultFormat.setText("");
1668
        this.txtFieldName.setText("");
1669
//        this.pickerFieldName.set(null);
1670
        this.pickerIntervalEnd.set(null);
1671
        this.pickerIntervalStart.set(null);
1672
        this.pickerScale.set(null);
1673
        this.pickerSize.set(null);
1674
        this.pickerDisplaySize.set(null);
1675

    
1676
        this.chkAllowNulls.setSelected(false);
1677
        this.chkIsAutomatic.setSelected(false);
1678
        this.chkIsReadOnly.setSelected(false);
1679
        this.chkIsIndexed.setSelected(false);
1680
        this.chkIsPrimaryKey.setSelected(false);
1681

    
1682
        switch (this.mode){
1683
            case MODE_EDIT_ALL:
1684
            case MODE_EDIT_ONLY_METADATA:
1685
                this.chkVirtualField.setSelected(false);
1686
                this.chkVirtualField.setEnabled(true);
1687
                break;
1688
            case MODE_SHOW_ONLY:
1689
                this.chkVirtualField.setSelected(false);
1690
                this.chkVirtualField.setEnabled(false);
1691
                break;
1692
            case MODE_VIRTUAL_FIELD:
1693
                this.chkVirtualField.setSelected(true);
1694
                this.chkVirtualField.setEnabled(false);
1695
                break;
1696
        }
1697
        this.pickerVirtualFieldGetter.setEditable(false);
1698
        this.pickerVirtualFieldGetter.set(null);
1699

    
1700
        ListElement.setSelected(cboGeometryType, null);
1701
        ListElement.setSelected(cboGeometrySubtype, null);
1702

    
1703
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
1704

    
1705
        this.cboDataProfile.setSelectedIndex(-1);
1706

    
1707
        this.cboGroup.setSelectedIndex(-1);
1708
        this.pickerOrder.set(null);
1709
        this.chkHidden.setSelected(false);
1710
        this.txtLabel.setText("");
1711
        this.txtDescription.setText("");
1712
        this.txtMinValue.setText("");
1713
        this.txtMaxValue.setText("");
1714
        this.availableValuesController.clean();
1715
        this.tagsController.clean();
1716
        this.toOneController.clean();
1717
        
1718
        this.pickerCRS.set(defaultProjection);
1719
    }
1720

    
1721
    @Override
1722
    public void put(FeatureAttributeDescriptor descriptor) {
1723
        if (descriptor == null) {
1724
            this.clean();
1725
            return;
1726
        }
1727
        DataType dataType = descriptor.getDataType();
1728
        FeatureType featureType = descriptor.getFeatureType();
1729
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
1730

    
1731
        this.pickerCRS.set(defaultProjection);
1732
        
1733
        if (featureType != null) {
1734
            FeatureStore store = descriptor.getFeatureType().getStore();
1735
            this.featureStoreElement.setFeatureStore(store);
1736
            if (store != null) {
1737
                this.sampleFeature = store.getSampleFeature();
1738
                if (sampleFeature != null) {
1739
                    FeatureSymbolTable featureSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable();
1740
                    featureSymbolTable.setFeature(sampleFeature);
1741
                    this.pickerVirtualFieldGetter.getConfig().setPreviewSymbolTable(featureSymbolTable.createParent());
1742
                    this.pickerValuesFilter.getConfig().setPreviewSymbolTable(featureSymbolTable.createParent());
1743
                }
1744
            }
1745
            List<String> groups = new ArrayList<>();
1746
            for (FeatureAttributeDescriptor otherdesc : featureType) {
1747
                String group = otherdesc.getGroup();
1748
                if (!StringUtils.isBlank(group) && !groups.contains(group)) {
1749
                    groups.add(group);
1750
                }
1751
            }
1752
            for (String group : groups) {
1753
                groupModel.addElement(group);
1754
            }
1755
        }
1756

    
1757
        this.previousDefaultValue = Objects.toString(descriptor.getDefaultValue(),null);
1758
        if( this.previousDefaultValue == null ) {
1759
            this.txtDefaultValue.setText("");
1760
            this.chkDefaultValue.setSelected(true);
1761
            this.txtDefaultValue.setEditable(false);
1762
        } else {
1763
            this.txtDefaultValue.setText(this.previousDefaultValue);
1764
            this.chkDefaultValue.setSelected(false);
1765
            this.txtDefaultValue.setEditable(true);
1766
        }
1767
        
1768
        this.txtDefaultFormat.setText(Objects.toString(descriptor.getDefaultFormat(),""));
1769
        this.txtFieldName.setText(descriptor.getName());
1770
        RelativeInterval interval = (RelativeInterval) descriptor.getInterval();
1771
        if (interval == null) {
1772
            this.pickerIntervalEnd.set(null);
1773
            this.pickerIntervalStart.set(null);
1774
        } else {
1775
            this.pickerIntervalEnd.set(interval.getEnd().toDate());
1776
            this.pickerIntervalStart.set(interval.getStart().toDate());
1777
        }
1778
        if( dataType.supportSize() ) {
1779
          this.pickerSize.set(descriptor.getSize());
1780
        } else {
1781
          this.pickerSize.set(null);
1782
        }
1783
        this.pickerDisplaySize.set(descriptor.getDisplaySize());
1784
        if( dataType.supportPrecision() ) {
1785
          this.pickerPrecision.set(descriptor.getPrecision());
1786
        } else {
1787
          this.pickerPrecision.set(null);
1788
        }
1789
        if( dataType.supportScale()) {
1790
          this.pickerScale.set(descriptor.getScale());
1791
        } else {
1792
          this.pickerScale.set(null);
1793
        }
1794
        this.chkAllowNulls.setSelected(descriptor.allowNull());
1795
        this.chkIsAutomatic.setSelected(descriptor.isAutomatic());
1796
        this.chkIsReadOnly.setSelected(descriptor.isReadOnly());
1797
        this.chkIsIndexed.setSelected(descriptor.isIndexed());
1798
        this.chkIsPrimaryKey.setSelected(descriptor.isPrimaryKey());
1799

    
1800
        this.pickerVirtualFieldGetter.setEnabled(true);
1801
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1802
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1803
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1804
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1805
            this.chkVirtualField.setSelected(true);
1806
            this.pickerVirtualFieldGetter.set(expression);
1807
        } else if (descriptor.isComputed()) {
1808
            this.chkVirtualField.setEnabled(false);
1809
            this.chkVirtualField.setSelected(true);
1810
            this.pickerVirtualFieldGetter.set(null);
1811
        } else {
1812
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1813
            this.chkVirtualField.setSelected(false);
1814
            this.pickerVirtualFieldGetter.set(null);
1815
        }
1816
        this.pickerVirtualFieldGetter.setEnabled(true);
1817

    
1818
        Expression expression = descriptor.getAvailableValuesFilter();
1819
        this.pickerValuesFilter.set(expression);
1820

    
1821
        if( descriptor.getType() == DataTypes.GEOMETRY ) {
1822
            if( descriptor.getSRS()==null ) {
1823
                this.pickerCRS.set(defaultProjection);
1824
            } else {
1825
                this.pickerCRS.set(descriptor.getSRS());
1826
            }
1827
            if (descriptor.getGeomType() != null) {
1828
                ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1829
                ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1830
            }
1831
        } else {
1832
            this.pickerCRS.set(defaultProjection);
1833
            ListElement.setSelected(cboGeometryType, null);
1834
            ListElement.setSelected(cboGeometrySubtype, null);
1835
        }
1836
        ListElement.setSelected(cboFieldType, dataType.getType());
1837
        if( ListElement.getSelected(cboFieldType)==null ) {
1838
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1839
          ListElement.setSelected(cboFieldType, dataType.getType());
1840
        }
1841
 
1842
        String profile = descriptor.getDataProfileName();
1843
        if (StringUtils.isBlank(profile)) {
1844
            this.cboDataProfile.setSelectedIndex(-1);
1845
        } else {
1846
            ListElement.setSelected(this.cboDataProfile, profile);
1847
        }
1848

    
1849
        this.cboGroup.setModel(groupModel);
1850
        this.cboGroup.setSelectedItem(StringUtils.defaultIfBlank(descriptor.getGroup(), ""));
1851
        this.pickerOrder.set(descriptor.getOder());
1852
        this.chkHidden.setSelected(descriptor.isHidden());
1853
        if (descriptor.hasLabel()) {
1854
            this.txtLabel.setText(StringUtils.defaultIfBlank(descriptor.getLabel(), ""));
1855
        } else {
1856
            this.txtLabel.setText("");
1857
        }
1858
        if (descriptor.hasDescription()) {
1859
            this.txtDescription.setText(StringUtils.defaultIfBlank(descriptor.getDescription(), ""));
1860
        } else {
1861
            this.txtDescription.setText("");
1862
        }
1863
        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1864
        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1865
        if( descriptor.hasConstantAvailableValues() ) {
1866
          this.availableValuesController.set(descriptor.getAvailableValues());
1867
        } else {
1868
          this.availableValuesController.clean();
1869
        }
1870
        this.tagsController.setModel(new TagsModel(descriptor.getTags()));
1871
        this.pickerLocale.set(descriptor.getLocale());
1872

    
1873
        this.toOneController.put(descriptor);
1874
        this.toManyController.put(descriptor);
1875
        switch(descriptor.getRelationType()) {
1876
            case DynField.RELATION_TYPE_NONE:
1877
                this.rdbRelationNone.setSelected(true);
1878
                this.rdbRelationToOne.setSelected(false);
1879
                this.rdbRelationToMany.setSelected(false); 
1880
                  // No los borramos, solo quedan deshabilitados, para no peder la informacion que contengan
1881
//                this.toOneController.clean(); 
1882
//                this.toManyController.clean();
1883
                break;
1884
            case DynField.RELATION_TYPE_IDENTITY:
1885
            case DynField.RELATION_TYPE_COLLABORATION:
1886
            case DynField.RELATION_TYPE_COLLABORATION_WITH_COMPOSITION:
1887
                this.rdbRelationNone.setSelected(false);
1888
                this.rdbRelationToOne.setSelected(true);
1889
                this.rdbRelationToMany.setSelected(false);
1890
//                this.toManyController.clean();
1891
                break;
1892
            case DynField.RELATION_TYPE_COMPOSITION:
1893
            case DynField.RELATION_TYPE_AGGREGATE:
1894
                this.rdbRelationNone.setSelected(false);
1895
                this.rdbRelationToOne.setSelected(false);
1896
                this.rdbRelationToMany.setSelected(true);
1897
                this.pickerVirtualFieldGetter.setEnabled(false);
1898
//                this.pickerVirtualFieldGetter.set(null);
1899
//                this.toOneController.clean();
1900
                break;
1901
              
1902
        }
1903
        
1904
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1905
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1906
        }
1907
        this.updateEditableStates();
1908
    }
1909
    
1910
    public void setFeatureType(FeatureType featureType){
1911
        this.featureType = featureType;
1912
        this.toManyController.setFeatureType(featureType);
1913
    }
1914
    
1915
    private FeatureType getFeatureType(FeatureAttributeDescriptor descriptor) {
1916
        if(descriptor ==  null || descriptor.getFeatureType() == null){
1917
            return this.featureType;
1918
        }
1919
        return descriptor.getFeatureType();
1920
    }
1921

    
1922
    private DataType getDataType() {
1923
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1924
      if (fieldType == null) {
1925
          return null;
1926
      }
1927
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1928
      return dataType;
1929
    }
1930

    
1931
    private void doFieldTypeChanged() {
1932
      try {
1933
        DataType dataType = this.getDataType();
1934

    
1935
        if( dataType.supportSize() ) {
1936
            this.pickerSize.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1937
        } else {
1938
            this.pickerSize.setEditable(false);
1939
            this.pickerSize.set(null);
1940
        }        
1941
        this.pickerDisplaySize.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1942
        if( dataType.supportPrecision() ) {
1943
          if( dataType.isPredefinedPrecision() ) {
1944
            this.pickerPrecision.setEditable(false);
1945
          } else {
1946
            this.pickerPrecision.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1947
          }
1948
        } else {
1949
            this.pickerPrecision.setEditable(false);
1950
            this.pickerPrecision.set(null);
1951
        }        
1952
        if( dataType.supportScale()) {
1953
            this.pickerScale.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1954
        } else {
1955
            this.pickerScale.setEditable(false);
1956
            this.pickerScale.set(null);
1957
        }        
1958
        switch (dataType.getType()) {
1959
          case DataTypes.GEOMETRY:
1960
            this.cboGeometryType.setEnabled(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1961
            this.cboGeometrySubtype.setEnabled(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1962
            this.pickerCRS.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1963
            this.cboDateFormat.setEnabled(false);
1964
            this.pickerIntervalStart.setEditable(false);
1965
            this.pickerIntervalEnd.setEditable(false);
1966
            this.tabAditionalFields.setEnabledAt(1, true);
1967
            this.tabAditionalFields.setEnabledAt(2, false);
1968
            
1969
            break;
1970
          case DataTypes.INSTANT:
1971
          case DataTypes.INTERVAL:
1972
          case DataTypes.DATE:
1973
          case DataTypes.TIME:
1974
          case DataTypes.TIMESTAMP:
1975
            this.cboGeometryType.setEnabled(false);
1976
            this.cboGeometrySubtype.setEnabled(false);
1977
            this.pickerCRS.setEditable(false);
1978
            this.cboDateFormat.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA || this.isVirtualField());
1979
            this.pickerIntervalStart.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA || this.isVirtualField());
1980
            this.pickerIntervalEnd.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA || this.isVirtualField());
1981
            this.tabAditionalFields.setEnabledAt(1, false);
1982
            this.tabAditionalFields.setEnabledAt(2, true);
1983
            break;
1984
          case DataTypes.BYTE:
1985
          case DataTypes.INT:
1986
          case DataTypes.LONG:
1987
          case DataTypes.STRING:
1988
          case DataTypes.FILE:
1989
          case DataTypes.URL:
1990
          case DataTypes.URI:
1991
          case DataTypes.FLOAT:
1992
          case DataTypes.DOUBLE:
1993
          case DataTypes.DECIMAL:
1994
            this.cboGeometryType.setEnabled(false);
1995
            this.cboGeometrySubtype.setEnabled(false);
1996
            this.pickerCRS.setEditable(false);
1997
            this.cboDateFormat.setEnabled(false);
1998
            this.pickerIntervalStart.setEditable(false);
1999
            this.pickerIntervalEnd.setEditable(false);
2000
            this.tabAditionalFields.setEnabledAt(1, false);
2001
            this.tabAditionalFields.setEnabledAt(2, false);
2002
            break;
2003
          default:
2004
            this.cboGeometryType.setEnabled(false);
2005
            this.cboGeometrySubtype.setEnabled(false);
2006
            this.pickerCRS.setEditable(false);
2007
            this.cboDateFormat.setEnabled(false);
2008
            this.pickerIntervalStart.setEditable(false);
2009
            this.pickerIntervalEnd.setEditable(false);
2010
            this.tabAditionalFields.setEnabledAt(1, false);
2011
            this.tabAditionalFields.setEnabledAt(2, false);
2012
        }
2013
//        updateRelationState();
2014
        doChangeRelationType();
2015
      } catch (Exception ex) {
2016
        LOGGER.warn("Problems changing field type.", ex);
2017
      }
2018

    
2019
    }
2020
    
2021
    boolean isVirtualField() {
2022
        return this.chkVirtualField.isSelected();
2023
    }
2024

    
2025
    @Override
2026
    public int getMode() {
2027
        return this.mode;
2028
    }
2029
    
2030
    @Override
2031
    public void setMode(int mode) {
2032
        this.mode = mode;
2033
        updateEditableStates();
2034
    }
2035
    
2036
    private void updateEditableStates() {
2037
        DataType dataType = this.getDataType();
2038
        switch(this.mode) {
2039
            case MODE_EDIT_ALL:
2040
                this.txtDefaultValue.setEditable(!this.chkIsAutomatic.isSelected());
2041
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2042
                this.txtDefaultFormat.setEditable(true);
2043
                this.txtFieldName.setEditable(true);
2044
                this.pickerIntervalEnd.setEditable(true);
2045
                this.pickerIntervalStart.setEditable(true);
2046
                this.pickerSize.setEditable(dataType.supportSize());
2047
                this.pickerDisplaySize.setEditable(true);
2048
                if( dataType.isPredefinedPrecision() ) {
2049
                  this.pickerPrecision.setEditable(false);
2050
                  this.pickerPrecision.set(dataType.getMaxPrecision());
2051
                } else {
2052
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
2053
                }
2054
                this.pickerScale.setEditable(dataType.supportScale());
2055
                this.cboDataProfile.setEnabled(true);
2056

    
2057
                this.chkAllowNulls.setEnabled(true);
2058
                this.chkIsAutomatic.setEnabled(true);
2059
                this.chkIsReadOnly.setEnabled(true);
2060
                this.chkIsIndexed.setEnabled(true);
2061
                if( this.isVirtualField() ) {
2062
                    this.chkIsPrimaryKey.setEnabled(false);
2063
                } else {
2064
                    this.chkIsPrimaryKey.setEnabled(true);
2065
                }
2066

    
2067
                this.chkVirtualField.setEnabled(true);
2068
                this.pickerVirtualFieldGetter.setEditable(true);
2069

    
2070
                this.cboDateFormat.setEnabled(true);
2071
                this.cboFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
2072
                this.btnFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
2073
                this.cboGeometryType.setEnabled(true);
2074
                this.cboGeometrySubtype.setEnabled(true);
2075
                this.pickerCRS.setEditable(true);
2076

    
2077
                this.cboGroup.setEnabled(true);
2078
                this.pickerOrder.setEditable(true);
2079
                this.chkHidden.setEnabled(true);
2080
                this.txtLabel.setEditable(true);
2081
                this.txtDescription.setEditable(true);
2082
                this.txtMinValue.setEditable(false);
2083
                this.txtMaxValue.setEditable(false);
2084
                this.pickerValuesFilter.setEditable(true);
2085
                this.availableValuesController.setEditable(true);
2086
                this.tagsController.setEnabled(true);
2087
                this.pickerLocale.setEnabled(true);
2088
                break;
2089
            case MODE_EDIT_ONLY_METADATA:
2090
                if( this.chkVirtualField.isSelected() ) {
2091
                    this.txtFieldName.setEditable(true);
2092
                    this.pickerScale.setEditable(true);
2093
                    this.pickerSize.setEditable(true);
2094
                    this.pickerVirtualFieldGetter.setEditable(true);
2095
                    this.cboFieldType.setEnabled(true);
2096
                    this.btnFieldType.setEnabled(true);
2097
                    this.cboGeometryType.setEnabled(true);
2098
                    this.cboGeometrySubtype.setEnabled(true);
2099
                    this.pickerCRS.setEditable(true);
2100
                } else {
2101
                    this.txtFieldName.setEditable(false);
2102
                    this.pickerPrecision.setEditable(false);
2103
                    this.pickerScale.setEditable(false);
2104
                    this.pickerSize.setEditable(false);
2105
                    this.pickerVirtualFieldGetter.setEditable(false);
2106
                    this.cboFieldType.setEnabled(false);
2107
                    this.btnFieldType.setEnabled(false);
2108
                    this.cboGeometryType.setEnabled(false);
2109
                    this.cboGeometrySubtype.setEnabled(false);
2110
                    this.pickerCRS.setEditable(false);
2111
                }
2112

    
2113
                this.pickerLocale.setEnabled(true);
2114
                this.txtDefaultValue.setEditable(true);
2115
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2116
                this.txtDefaultFormat.setEditable(true);
2117
                this.pickerIntervalEnd.setEditable(true);
2118
                this.pickerIntervalStart.setEditable(true);
2119

    
2120
                this.cboDataProfile.setEnabled(true);
2121

    
2122
                this.pickerDisplaySize.setEditable(false);
2123
                this.chkAllowNulls.setEnabled(false);
2124
                this.chkIsAutomatic.setEnabled(false);
2125
                this.chkIsReadOnly.setEnabled(false);
2126
                this.chkIsIndexed.setEnabled(false);
2127
//                if( this.isVirtualField() ) {
2128
                    this.chkIsPrimaryKey.setEnabled(false);
2129
//                } else {
2130
//                    this.chkIsPrimaryKey.setEnabled(true);
2131
//                }
2132

    
2133
                this.chkVirtualField.setEnabled(false);
2134

    
2135
                this.cboDateFormat.setEnabled(true);
2136

    
2137
                this.cboGroup.setEnabled(true);
2138
                this.pickerOrder.setEditable(true);
2139
                this.chkHidden.setEnabled(true);
2140
                this.txtLabel.setEditable(true);
2141
                this.txtDescription.setEditable(true);
2142
                this.txtMinValue.setEditable(false);
2143
                this.txtMaxValue.setEditable(false);
2144
                this.pickerValuesFilter.setEditable(true);
2145
                this.availableValuesController.setEditable(true);
2146
                this.tagsController.setEnabled(true);
2147
                break;
2148
            case MODE_SHOW_ONLY:
2149
                this.txtDefaultValue.setEditable(false);
2150
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2151
                this.txtDefaultFormat.setEditable(false);
2152
                this.txtFieldName.setEditable(false);
2153
                this.pickerIntervalEnd.setEditable(false);
2154
                this.pickerIntervalStart.setEditable(false);
2155
                this.pickerPrecision.setEditable(false);
2156
                this.pickerScale.setEditable(false);
2157
                this.pickerSize.setEditable(false);
2158
                this.pickerDisplaySize.setEditable(false);
2159
                this.cboDataProfile.setEnabled(false);
2160
                this.pickerLocale.setEnabled(false);
2161

    
2162
                this.chkAllowNulls.setEnabled(false);
2163
                this.chkIsAutomatic.setEnabled(false);
2164
                this.chkIsReadOnly.setEnabled(false);
2165
                this.chkIsIndexed.setEnabled(false);
2166
                this.chkIsPrimaryKey.setEnabled(false);
2167

    
2168
                this.chkVirtualField.setEnabled(false);
2169
                this.pickerVirtualFieldGetter.setEditable(false);
2170

    
2171
                this.cboDateFormat.setEnabled(false);
2172
                this.cboFieldType.setEnabled(false);
2173
                this.btnFieldType.setEnabled(false);
2174
                this.cboGeometryType.setEnabled(false);
2175
                this.cboGeometrySubtype.setEnabled(false);
2176
                this.pickerCRS.setEditable(false);
2177

    
2178
                this.cboGroup.setEnabled(false);
2179
                this.pickerOrder.setEditable(false);
2180
                this.chkHidden.setEnabled(false);
2181
                this.txtLabel.setEditable(false);
2182
                this.txtDescription.setEditable(false);
2183
                this.txtMinValue.setEditable(false);
2184
                this.txtMaxValue.setEditable(false);
2185
                this.pickerValuesFilter.setEditable(false);
2186
                this.availableValuesController.setEditable(false);
2187
                this.tagsController.setEnabled(false);
2188
                break;
2189
            case MODE_VIRTUAL_FIELD:
2190
                this.txtDefaultValue.setEditable(!this.chkIsAutomatic.isSelected());
2191
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2192
                this.txtDefaultFormat.setEditable(true);
2193
                this.txtFieldName.setEditable(true);
2194
                this.pickerIntervalEnd.setEditable(true);
2195
                this.pickerIntervalStart.setEditable(true);
2196
                this.pickerSize.setEditable(dataType.supportSize());
2197
                this.pickerDisplaySize.setEditable(true);
2198
                if( dataType.isPredefinedPrecision() ) {
2199
                  this.pickerPrecision.setEditable(false);
2200
                  this.pickerPrecision.set(dataType.getMaxPrecision());
2201
                } else {
2202
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
2203
                }
2204
                this.pickerScale.setEditable(dataType.supportScale());
2205
                this.cboDataProfile.setEnabled(true);
2206

    
2207
                this.chkAllowNulls.setEnabled(true);
2208
                this.chkIsAutomatic.setEnabled(true);
2209
                this.chkIsReadOnly.setEnabled(true);
2210
                this.chkIsIndexed.setEnabled(true);
2211
                if( this.isVirtualField() ) {
2212
                    this.chkIsPrimaryKey.setEnabled(false);
2213
                } else {
2214
                    this.chkIsPrimaryKey.setEnabled(true);
2215
                }
2216

    
2217
                this.chkVirtualField.setEnabled(false);
2218
                this.chkVirtualField.setSelected(true);
2219
                this.pickerVirtualFieldGetter.setEditable(true);
2220

    
2221
                this.cboDateFormat.setEnabled(true);
2222
                this.cboFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
2223
                this.btnFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
2224
                this.cboGeometryType.setEnabled(true);
2225
                this.cboGeometrySubtype.setEnabled(true);
2226
                this.pickerCRS.setEditable(true);
2227

    
2228
                this.cboGroup.setEnabled(true);
2229
                this.pickerOrder.setEditable(true);
2230
                this.chkHidden.setEnabled(true);
2231
                this.txtLabel.setEditable(true);
2232
                this.txtDescription.setEditable(true);
2233
                this.txtMinValue.setEditable(false);
2234
                this.txtMaxValue.setEditable(false);
2235
                this.pickerValuesFilter.setEditable(true);
2236
                this.availableValuesController.setEditable(true);
2237
                this.tagsController.setEnabled(true);
2238
                this.pickerLocale.setEnabled(true);
2239
                break;
2240
        }
2241
        this.txtDisplaySize.setBackground(UIManager.getColor(ToolsSwingManager.COLOR_TEXTFIELD_BACKGROUND));
2242
        if(this.pickerPrecision.get() != null && this.pickerDisplaySize.get() != null){
2243
            if(this.pickerPrecision.get() > this.pickerDisplaySize.get()){
2244
                this.txtDisplaySize.setBackground(ToolsSwingLocator.getToolsSwingManager().getWarningBackgroundColor());
2245
            }
2246
        }
2247
        doChangeRelationType();
2248
    }
2249
    
2250
    private void doCheckPrecisionAndScale() {
2251
      DataType dataType = this.getDataType();
2252
      
2253
      Integer precision = this.pickerPrecision.get();
2254
      if( precision==null ) {
2255
        precision = 0;
2256
      }
2257
      Integer scale = this.pickerScale.get();
2258
      if( scale == null ) {
2259
        scale = 0;
2260
      }      
2261
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
2262
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
2263
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
2264
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
2265
      } else {
2266
        this.pickerPrecision.setWarning(false);
2267
        this.pickerScale.setWarning(false);
2268
      }
2269
    }
2270

    
2271
    @Override
2272
    public void setNameAsNew(FeatureType featureType) {
2273
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
2274
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
2275
                cloneFeatureType.getNewFieldName(), 
2276
                DataTypes.STRING,
2277
                50);
2278
        this.put(newAttributeDescriptor);
2279
    }
2280

    
2281
    @Override
2282
    public String getName() {
2283
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
2284
    }
2285

    
2286
    @Override
2287
    public ImageIcon loadImage(String imageName) {
2288
        return ToolsSwingUtils.loadImage(this, imageName);
2289
    }
2290

    
2291
  public static void selfRegister() {
2292
    boolean n = ToolsSwingUtils.registerIcons( 
2293
            DefaultFeatureAttributeSelectionPanel.class,
2294
            null,
2295
            LIBRARY_NAME,
2296
            new String[]{ "picker", "picker-datatype", "picker-datatype"}
2297
    );      
2298
  }
2299

    
2300
  public void setDefaultProjection(IProjection projection) {
2301
      this.defaultProjection = projection;
2302
  }
2303
}