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

History | View | Annotate | Download (101 KB)

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

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

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

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

    
140
    private static class ToOneController {
141

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

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

    
229
        private void doTableChanged() {
230
            String tableName = (String) this.cboTable.getSelectedItem();
231
            if( StringUtils.isBlank(tableName) ) {
232
                return;
233
            }
234
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
235
            DataStore store = repository.getStore(tableName);
236
            if( !(store instanceof FeatureStore) ) {
237
                return;
238
            }
239
            FeatureType featureType;
240
            try {
241
                featureType = ((FeatureStore)store).getDefaultFeatureType();
242
            } catch (DataException ex) {
243
                return;
244
            }
245
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
246
            
247
            this.pickerCode.setAllowNull(true);
248
            this.pickerCode.setFeatureType(featureType);
249
            if (featureType == null) {
250
                return;
251
            }
252
            dataSwingManager.configureExpressionBuilder(this.pickerFormula.getConfig(), ((FeatureStore)store));
253
            SwingUtilities.invokeLater(() -> {
254
              cboForeignField.setSelectedItem(foreingKey.getCodeName());
255
            });
256
        }
257

    
258
        public void setEditable(boolean editable) {
259
            this.cboRelationType.setEnabled(editable);
260
            this.chkIsClosedList.setEnabled(editable);
261
            this.cboTable.setEnabled(editable);
262
            this.cboForeignField.setEnabled(editable);
263
            this.pickerFormula.setEditable(editable);
264
            this.editable = editable;
265
        }
266
        
267
        public void setEnabled(boolean enabled) {
268
            if( !editable ) {
269
                enabled =  false;
270
            }
271
            this.cboRelationType.setEnabled(enabled);
272
            this.chkIsClosedList.setEnabled(enabled);
273
            this.cboTable.setEnabled(enabled);
274
            this.cboForeignField.setEnabled(enabled);
275
            this.pickerFormula.setEditable(enabled);
276
        }
277
        
278
        public void clean() {
279
            this.txtMyFieldName.setText("");
280
            this.cboRelationType.setSelectedIndex(-1);
281
            this.chkIsClosedList.setSelected(false);
282
            this.cboTable.setSelectedItem("");
283
            this.cboForeignField.setSelectedItem("");
284
            this.pickerFormula.set(null);
285
        }
286
        
287
        public void put(FeatureAttributeDescriptor descriptor) {
288
            if( descriptor == null ) {
289
                this.clean();
290
                return;
291
            }
292
            ForeingKey foreingKey = descriptor.getForeingKey();
293
            if( foreingKey==null ) {
294
                this.clean();
295
                return;
296
            }
297
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
298
            this.pickerFormula.setFeatureType(repository.getFeatureType(foreingKey.getTableName()));
299
            this.foreingKey = foreingKey;
300
            ListElement.setSelected(this.cboRelationType,descriptor.getRelationType());
301
            this.chkIsClosedList.setSelected(foreingKey.isClosedList());
302
            this.cboTable.setSelectedItem(foreingKey.getTableName()); 
303
            doTableChanged();
304
            this.pickerCode.set(foreingKey.getCodeName());
305
            this.pickerFormula.set(foreingKey.getLabelExpression(null));
306
            this.txtMyFieldName.setText(descriptor.getName());
307
        }
308
        
309
        public void fetch(EditableFeatureAttributeDescriptor descriptor) {
310
            if( descriptor == null ) {
311
                this.clean();
312
                return;
313
            }
314
            EditableForeingKey foreingKey = descriptor.getForeingKey();
315
            if( foreingKey==null ) {
316
                return;
317
            }
318
//            foreingKey.setForeingKey(this.chkIsForeingKey.isSelected());
319
            foreingKey.setClosedList(this.chkIsClosedList.isSelected());
320
            foreingKey.setTableName((String) this.cboTable.getSelectedItem());
321
            foreingKey.setCodeName(this.pickerCode.getName());
322
            Expression exp = this.pickerFormula.get();
323
            if( ExpressionUtils.isPhraseEmpty(exp) ) {
324
                foreingKey.setLabelFormula("");
325
            } else {
326
                foreingKey.setLabelFormula(exp.getPhrase());
327
            }
328
        }
329

    
330
        public int getRelationType() {
331
            Object n = this.cboRelationType.getSelectedItem();
332
            if( n == null ) {
333
                return DynField.RELATION_TYPE_NONE;
334
            }
335
            return ((LabeledValue<Integer>)n).getValue();
336
        }
337
    }
338
    
339
    private static class ToManyController {
340

    
341
        private final JComboBox cboRelationType;
342
        private final JComboBox cboMyField;
343
        private final JComboBox cboTable;
344
        private final JComboBox cboForeignField;
345
        private final JTextField txtExpression;
346
        private final JButton btnExpression;
347
        private final JButton btnExpressionHistory;
348
        private final JButton btnExpressionBokkmarks;
349
        private ExpressionPickerController pickerExpression;
350
        private AttributeDescriptorPickerController pickerForeignField;
351
        private AttributeDescriptorPickerController pickerMyField;
352
        private boolean editable;
353
        private boolean disableEvents;
354
        
355
        public ToManyController(
356
                JComboBox cboRelationType,
357
                JComboBox cboMyField,
358
                JComboBox cboTable,
359
                JComboBox cboForeignField,
360
                JTextField txtExpression,
361
                JButton btnExpression,
362
                JButton btnExpressionBokkmarks,
363
                JButton btnExpressionHistory
364
        ) {
365
            this.disableEvents = false;
366
            this.cboRelationType = cboRelationType;
367
            this.cboMyField = cboMyField;
368
            this.cboTable = cboTable;
369
            this.cboForeignField = cboForeignField;
370
            this.txtExpression = txtExpression;
371
            this.btnExpression = btnExpression;
372
            this.btnExpressionHistory = btnExpressionHistory;
373
            this.btnExpressionBokkmarks = btnExpressionBokkmarks;
374
            this.initComponents();
375
        }
376

    
377
        private void initComponents() {
378
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
379
            I18nManager i18n = ToolsLocator.getI18nManager();
380
    
381
            this.editable = true;
382
            DefaultComboBoxModel<LabeledValueImpl<Integer>> relationTypeModel = new DefaultComboBoxModel<>();
383
//            relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Identity_1_1"),DynField.RELATION_TYPE_IDENTITY));
384
//            relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Collaboration_1_1_without_composition"),DynField.RELATION_TYPE_COLLABORATION));
385
//            relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Collaboration_1_1_with_composition"),DynField.RELATION_TYPE_COLLABORATION_WITH_COMPOSITION));
386
            relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Aggregate_1_N_with_composition"),DynField.RELATION_TYPE_AGGREGATE_WITH_COMPOSITION));
387
            relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Aggregate_1_N_without_composition"),DynField.RELATION_TYPE_AGGREGATE));
388
            this.cboRelationType.setModel(relationTypeModel);
389
        
390
            this.pickerMyField = dataSwingManager.createAttributeDescriptorPickerController(cboMyField);
391
            this.pickerMyField.setAllowNull(true);
392
            this.pickerMyField.addChangeListener((ChangeEvent e) -> {
393
                if( disableEvents ) {
394
                    return;
395
                }
396
                doUpdateExpression();
397
            });
398
            DefaultComboBoxModel<String> model = new DefaultComboBoxModel();
399
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
400
            List<String> tableNames = new ArrayList<>();
401
            for (String tableName : repository.keySet()) {
402
                tableNames.add(tableName);
403
            }
404
            Collections.sort(tableNames);
405
            for (String tableName : tableNames) {
406
                model.addElement(tableName);
407
            }
408
            this.cboTable.setEditable(false);
409
            this.cboTable.setModel(model);
410
            this.cboTable.addItemListener((ItemEvent e) -> {
411
              if( disableEvents ) {
412
                  return;
413
              }
414
              if (e.getStateChange() != ItemEvent.SELECTED) {
415
                return;
416
              }
417
              Thread th = new Thread(() ->
418
                  { doTableChanged(); },
419
                "FeatureTypePanelToManyTableChanged"
420
              );
421
              th.start();
422
            });
423
            this.pickerForeignField = dataSwingManager.createAttributeDescriptorPickerController(cboForeignField);
424
            this.pickerForeignField.setAllowNull(true);
425
            this.pickerForeignField.addChangeListener((ChangeEvent e) -> {
426
                if( disableEvents ) {
427
                    return;
428
                }
429
                doUpdateExpression();
430
            });
431
            
432
            this.pickerExpression = ExpressionEvaluatorSwingLocator.getManager().createExpressionPickerController(
433
                    txtExpression, 
434
                    btnExpression, 
435
                    btnExpressionBokkmarks, 
436
                    btnExpressionHistory
437
            );
438
        }
439

    
440
        private void doTableChanged() {
441
            String tableName = (String) this.cboTable.getSelectedItem();
442
            if( StringUtils.isBlank(tableName) ) {
443
                return;
444
            }
445
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
446
            DataStore store = repository.getStore(tableName);
447
            if( !(store instanceof FeatureStore) ) {
448
                return;
449
            }
450
            FeatureStore featureStore = (FeatureStore) store;
451
            FeatureType featureType;
452
            try {
453
                featureType = featureStore.getDefaultFeatureType();
454
            } catch (DataException ex) {
455
                return;
456
            }
457
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
458
            
459
            this.pickerForeignField.setFeatureType(featureType);
460
            if (featureType == null) {
461
                return;
462
            }
463
            dataSwingManager.configureExpressionBuilder(this.pickerExpression.getConfig(), featureStore);
464
        }
465
        
466
        private void doUpdateExpression() {
467
            String myField = this.pickerMyField.getName();
468
            if( StringUtils.isBlank(myField) ) {
469
                this.pickerExpression.set(null);
470
                return;
471
            }
472
            String foreignField = this.pickerForeignField.getName();
473
            if( StringUtils.isBlank(foreignField) ) {
474
                this.pickerExpression.set(null);
475
                return;
476
            }
477
            String tableName = this.getTableName();
478
            if( StringUtils.isBlank(tableName) ) {
479
                this.pickerExpression.set(null);
480
                return;
481
            }
482
            DataManager dataManager = DALLocator.getDataManager();
483
            DALExpressionBuilder builder = dataManager.createDALExpressionBuilder();
484
            SQLBuilder.SelectBuilder select = builder.select();
485
            select.from().table().name(tableName);
486
            select.column().all();
487
            select.where().set(builder.expression().eq(
488
                    builder.expression().column(myField),
489
                    builder.expression().getattr(tableName, foreignField)
490
                )
491
            );
492
            this.pickerExpression.set(ExpressionUtils.createExpression(select.toString()));
493
        }
494
        
495
        private String[] getFieldsAndTable(Expression expression) {
496
            if (ExpressionUtils.isEmpty(expression)) {
497
                return null;
498
            }
499
            try {
500
                Code code = expression.getCode();
501
                if( !StringUtils.equalsIgnoreCase(Callable.name(code),FUNCTION_SELECT) ) {
502
                    return null;
503
                }
504
                Code.Callable callable = (Code.Callable) code;
505
                String tableName;
506
                Codes args = callable.parameters();
507
                Code storeName_code = (Code) args.get(1);
508
                if (storeName_code instanceof Code.Identifier) {
509
                    tableName = ((Code.Identifier) storeName_code).name();
510
                } else if (storeName_code instanceof Code.Constant) {
511
                    Code.Constant storeName_const = (Code.Constant) storeName_code;
512
                    if (storeName_const.value() instanceof CharSequence) {
513
                        tableName = storeName_const.value().toString();
514
                    } else {
515
                        return null;
516
                    }
517
                } else {
518
                    return null;
519
                }
520
                if (StringUtils.isBlank(tableName)) {
521
                    return null;
522
                }
523
                String foreignColumnName = null;
524
                String myColumnName = null;
525
                Code where = callable.parameters().get(2); // WHERE
526
                Code myFieldCode = getCode(
527
                        where,
528
                        new ImmutablePair<>(OPERATOR_EQ, 0)
529
                );
530
                if( myFieldCode != null ) {
531
                    myColumnName = Objects.toString(Identifier.name(myFieldCode), null);
532
                }
533
                Code foreingFieldCode = getCode(
534
                        where,
535
                        new ImmutablePair<>(OPERATOR_EQ, 1),
536
                        new ImmutablePair<>(FUNCTION_GETATTR, 1)
537
                );
538
                if( foreingFieldCode != null ) {
539
                    foreignColumnName = Objects.toString(Constant.value(foreingFieldCode), null);
540
                }
541
                return new String[] { myColumnName, tableName,foreignColumnName };
542
            } catch(Throwable t) {
543
                LOGGER.warn("Can't get table and code from expression '"+expression.getPhrase()+"' in toMany controller",t);
544
                return null;
545
            }
546
        }
547
        
548
        private Code getCode(Code code, Pair<String,Integer>... args) {
549
            for (Pair<String, Integer> arg : args) {
550
                if( !StringUtils.equalsIgnoreCase(Callable.name(code),arg.getLeft()) ) {
551
                    return null;
552
                }
553
                code = Callable.parameters(code).get(arg.getRight());
554
            }
555
            return code;
556
        }
557

    
558
        private String getTableName() {
559
            String s = (String) this.cboTable.getSelectedItem();
560
            if( StringUtils.isBlank(s) ) {
561
                return null;
562
            }
563
            return s;
564
        }
565
        
566
        public void setEditable(boolean editable) {
567
            this.cboRelationType.setEnabled(editable);
568
            this.pickerMyField.setEditable(editable);
569
            this.cboTable.setEnabled(editable);
570
            this.pickerForeignField.setEditable(editable);
571
            this.pickerExpression.setEditable(editable);
572
            this.editable = editable;
573
        }
574
        
575
        public void setEnabled(boolean enabled) {
576
            if( !editable ) {
577
                enabled =  false;
578
            }
579
            this.cboRelationType.setEnabled(enabled);
580
            this.pickerMyField.setEnabled(enabled);
581
            this.cboTable.setEnabled(enabled);
582
            this.pickerForeignField.setEnabled(enabled);
583
            this.pickerExpression.setEditable(enabled);
584
        }
585
        
586
        public void clean() {
587
            this.cboRelationType.setSelectedIndex(-1);
588
            this.pickerMyField.clean();
589
            this.cboTable.setSelectedIndex(-1);
590
            this.pickerForeignField.clean();
591
            this.pickerExpression.set(null);
592
        }
593
        
594
        public void put(FeatureAttributeDescriptor descriptor) {
595
            if (descriptor == null) {
596
                this.clean();
597
                return;
598
            }
599
            boolean prevDisableEvents = this.disableEvents;
600
            try {
601
                this.disableEvents = true;
602
                this.pickerMyField.setFeatureType(descriptor.getFeatureType());
603
                ListElement.setSelected(this.cboRelationType, descriptor.getRelationType());
604
                FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
605
                if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
606
                    Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
607
                    String[] fieldsAndTable = this.getFieldsAndTable(expression);
608
                    if (fieldsAndTable == null) {
609
                        this.cboTable.setSelectedIndex(-1);
610
                        this.pickerForeignField.clean();
611
                        return;
612
                    }
613
                    this.pickerMyField.set(fieldsAndTable[0]);
614
                    this.cboTable.setSelectedItem(fieldsAndTable[1]);
615
                    doTableChanged();
616
                    this.pickerForeignField.set(fieldsAndTable[2]);
617
                    this.pickerExpression.set(expression);
618
                } else {
619
                    this.clean();
620
                }
621
            } catch (Throwable t) {
622
                LOGGER.warn("Can't set attribute descriptor in toMany controller",t);
623
            } finally {
624
                this.disableEvents = prevDisableEvents;
625
            }
626
        }
627

    
628
        public void fetch(EditableFeatureAttributeDescriptor descriptor) {
629
            if( descriptor == null ) {
630
                this.clean();
631
                return;
632
            }
633
//            Expression exp = this.pickerExpression.get();
634
//            if( ExpressionUtils.isPhraseEmpty(exp) ) {
635
//                descriptor.setFeatureAttributeEmulator((Expression)null);
636
//            } else {
637
//                descriptor.setFeatureAttributeEmulator(exp);
638
//            }
639
            Tags tags = descriptor.getTags();
640
            if( !tags.has(DAL_RELATED_TABLE) ) {
641
                String tableName =  this.getTableName();
642
                if( StringUtils.isNotBlank(tableName) ) {
643
                    tags.set(DAL_RELATED_TABLE, tableName);                    
644
                }
645
            }
646
            if( !tags.has(DAL_RELATED_UNIQUE_FIELD_NAME) ) {
647
                String tableName = tags.getString(DAL_RELATED_TABLE, null);
648
                if( StringUtils.isNotBlank(tableName) ) {
649
                    try {
650
                        StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
651
                        FeatureType ft = repository.getFeatureType(tableName);
652
                        FeatureAttributeDescriptor[] pk = ft.getPrimaryKey();
653
                        if( !ArrayUtils.isEmpty(pk) && pk.length==1 ) {
654
                            tags.set(DAL_RELATED_UNIQUE_FIELD_NAME, pk[0].getName());
655
                        }
656
                    } catch(Throwable t) {
657
                        LOGGER.warn("Can't get primary key of table '"+tableName+"'.",t);
658
                    }
659
                }
660
            }
661
        }
662
        
663
        public Expression getExpression() {
664
            Expression exp = this.pickerExpression.get();
665
            if( ExpressionUtils.isPhraseEmpty(exp) ) {
666
                return null;
667
            } else {
668
                return exp;
669
            }
670
        }
671
        
672
        public int getRelationType() {
673
            Object n = this.cboRelationType.getSelectedItem();
674
            if( n == null ) {
675
                return DynField.RELATION_TYPE_NONE;
676
            }
677
            return ((LabeledValue<Integer>)n).getValue();
678
        }
679
    }
680
    
681

    
682
    private static class AvailableValuesController {
683

    
684
        private final JList lstValues;
685
        private final JTextComponent txtLabel;
686
        private final JTextComponent txtValue;
687
        private final JButton btnAdd;
688
        private final JButton btnUpdate;
689
        private final JButton btnRemove;
690
        private final JButton btnRemoveAll;
691

    
692
        public AvailableValuesController(
693
                JList lstValues,
694
                JTextComponent txtLabel,
695
                JTextComponent txtValue,
696
                JButton btnAdd,
697
                JButton btnUpdate,
698
                JButton btnRemove,
699
                JButton btnRemoveAll
700
        ) {
701
            this.lstValues = lstValues;
702
            this.txtLabel = txtLabel;
703
            this.txtValue = txtValue;
704
            this.btnAdd = btnAdd;
705
            this.btnUpdate = btnUpdate;
706
            this.btnRemove = btnRemove;
707
            this.btnRemoveAll = btnRemoveAll;
708

    
709
            this.lstValues.addListSelectionListener((ListSelectionEvent e) -> {
710
              doValuesChanged();
711
            });
712
            this.btnAdd.addActionListener((ActionEvent e) -> {
713
              doAdd();
714
            });
715
            this.btnUpdate.addActionListener((ActionEvent e) -> {
716
              doUpdate();
717
            });
718
            this.btnRemove.addActionListener((ActionEvent e) -> {
719
              doRemove();
720
            });
721
            this.btnRemoveAll.addActionListener((ActionEvent e) -> {
722
              doRemoveAll();
723
            });
724
        }
725

    
726
        public void clean() {
727
            this.lstValues.setModel(new DefaultListModel());
728
            this.txtLabel.setText("");
729
            this.txtValue.setText("");
730
            this.lstValues.setSelectedIndex(-1);
731
        }
732

    
733
        public DynObjectValueItem[] get() {
734
            ListModel<DynObjectValueItem> model = this.lstValues.getModel();
735
            if( model.getSize()==0 ) {
736
              return null;
737
            }
738
            DynObjectValueItem[] values = new DynObjectValueItem[model.getSize()];
739
            for (int i = 0; i < model.getSize(); i++) {
740
                values[i] = model.getElementAt(i);
741
            }
742
            return values;
743
        }
744

    
745
        public void set(DynObjectValueItem[] availableValues) {
746
            DefaultListModel model = new DefaultListModel();
747
            if (availableValues != null) {
748
                for (DynObjectValueItem availableValue : availableValues) {
749
                    model.addElement(availableValue);
750
                }
751
            }
752
            this.lstValues.setModel(model);
753
            if (model.getSize() > 0) {
754
                this.lstValues.setSelectedIndex(0);
755
            } else {
756
                this.lstValues.setSelectedIndex(-1);
757
            }
758
        }
759

    
760
        public void setEditable(boolean editable) {
761
            this.lstValues.setEnabled(editable);
762
            this.txtLabel.setEditable(editable);
763
            this.txtValue.setEditable(editable);
764
            this.btnAdd.setEnabled(editable);
765
            this.btnUpdate.setEnabled(editable);
766
            this.btnRemove.setEnabled(editable);
767
            this.btnRemoveAll.setEnabled(editable);
768
        }
769

    
770
        private void doValuesChanged() {
771
            DynObjectValueItem value = (DynObjectValueItem) this.lstValues.getSelectedValue();
772
            if (value == null) {
773
                this.txtLabel.setText("");
774
                this.txtValue.setText("");
775
                this.btnAdd.setEnabled(true);
776
                this.btnUpdate.setEnabled(false);
777
                this.btnRemove.setEnabled(false);
778
                return;
779
            }
780
            this.txtLabel.setText(value.getLabel());
781
            this.txtValue.setText(Objects.toString(value.getValue(), ""));
782
            this.btnAdd.setEnabled(true);
783
            this.btnUpdate.setEnabled(true);
784
            this.btnRemove.setEnabled(true);
785
        }
786

    
787
        private void doAdd() {
788
            DynObjectValueItem value = new DynObjectValueItem("Value", "Label");
789
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
790
            model.addElement(value);
791
            this.lstValues.setSelectedIndex(model.getSize() - 1);
792
        }
793

    
794
        private void doUpdate() {
795
            DynObjectValueItem value = (DynObjectValueItem) this.lstValues.getSelectedValue();
796
            if (value == null) {
797
                return; // EEhh?? esto no deberia pasar
798
            }
799
            value.setLabel(this.txtLabel.getText());
800
            value.setValue(this.txtValue.getText());
801
        }
802

    
803
        private void doRemove() {
804
            int n = this.lstValues.getSelectedIndex();
805
            if (n < 0) {
806
                return; // EEhh?? esto no deberia pasar
807
            }
808
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
809
            model.removeElementAt(n);
810
            if (--n < 0) {
811
                n = 0;
812
            }
813
            this.lstValues.setSelectedIndex(n);
814
        }
815

    
816
        private void doRemoveAll() {
817
            DefaultListModel model = new DefaultListModel();
818
            this.lstValues.setModel(model);
819
            this.lstValues.setSelectedIndex(-1);
820
        }
821

    
822
    }
823

    
824
    private final List<ListElement<Integer>> fieldTypes;
825
    private final List<ListElement<Integer>> geometryTypes;
826
    private final List<ListElement<Integer>> geometrySubtypes;
827

    
828
    private DatePickerController pickerIntervalEnd;
829
    private DatePickerController pickerIntervalStart;
830
    private CalculatorController<Integer> pickerSize;
831
    private CalculatorController<Integer> pickerDisplaySize;
832
    private CalculatorController<Integer> pickerPrecision;
833
    private CalculatorController<Integer> pickerScale;
834
    private PickerController<Locale> pickerLocale;
835
    private PickerController<IProjection> pickerCRS;
836
    private ExpressionPickerController pickerVirtualFieldGetter;
837
    private ExpressionPickerController pickerVirtualFieldSetter;
838
    private ExpressionPickerController pickerDefaultFormat;
839
    private CalculatorController<Integer> pickerOrder;
840
    private AvailableValuesController availableValuesController;
841
    private AggregateController<Tag> tagsController;
842
    private ToOneController toOneController;
843
    private ExpressionPickerController pickerValuesFilter;
844

    
845
    private int mode;
846
    private FeatureStoreElement featureStoreElement;
847

    
848
    public DefaultFeatureAttributePanel() {
849
        this.mode = FeatureTypePanel.MODE_SHOW_ONLY;
850
        DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
851
        // se deber?a de utilizar el datatypepicker
852
        this.fieldTypes = new ArrayList<>();
853
        fieldTypes.add( new ListElement<>("Decimal", DataTypes.DECIMAL) );
854
        fieldTypes.add( new ListElement<>("Integer", DataTypes.INTEGER) );
855
        fieldTypes.add( new ListElement<>("Long", DataTypes.LONG) );
856
        fieldTypes.add( new ListElement<>("String", DataTypes.STRING) );
857
        fieldTypes.add( new ListElement<>("Boolean", DataTypes.BOOLEAN) );
858
        fieldTypes.add( new ListElement<>("Date", DataTypes.DATE) );
859
        fieldTypes.add( new ListElement<>("Date/Time (Timestamp)", DataTypes.TIMESTAMP) );
860
//        for (DataType dataType : dataManager) {
861
//            fieldTypes.add( new ListElement<>(dataType.getName(), dataType.getType()) );
862
//        }
863
        fieldTypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
864
                o1.toString().compareTo(o2.toString())
865
        );
866

    
867
        this.geometryTypes = new ArrayList<>();
868
        this.geometryTypes.add(new ListElement("Point", Geometry.TYPES.POINT));
869
        this.geometryTypes.add(new ListElement("Line", Geometry.TYPES.LINE));
870
        this.geometryTypes.add(new ListElement("Polygon", Geometry.TYPES.POLYGON));
871
        this.geometryTypes.add(new ListElement("MultiPoint", Geometry.TYPES.MULTIPOINT));
872
        this.geometryTypes.add(new ListElement("MultiLine", Geometry.TYPES.MULTILINE));
873
        this.geometryTypes.add(new ListElement("MultiPolygon", Geometry.TYPES.MULTIPOLYGON));
874
        this.geometryTypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
875
                  o1.toString().compareTo(o2.toString())
876
        );
877

    
878
        this.geometrySubtypes = new ArrayList<>();
879
        this.geometrySubtypes.add(new ListElement("2D", Geometry.SUBTYPES.GEOM2D));
880
        this.geometrySubtypes.add(new ListElement("2DM", Geometry.SUBTYPES.GEOM2DM));
881
        this.geometrySubtypes.add(new ListElement("3D", Geometry.SUBTYPES.GEOM3D));
882
        this.geometrySubtypes.add(new ListElement("3DM", Geometry.SUBTYPES.GEOM3DM));
883
        this.geometrySubtypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
884
                o1.toString().compareTo(o2.toString())
885
        );
886

    
887
        this.initComponents();
888
    }
889

    
890
    private void initComponents() {
891
        final ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
892
        final ExpressionEvaluatorSwingManager evaluatorSwingManager = ExpressionEvaluatorSwingLocator.getManager();
893
        final DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
894
        final DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
895

    
896
        this.translate();
897
        
898
        ToolsSwingUtils.ensureMaxRows(this.gridAttrTagsTable, 10);
899
        this.splAttrTags = ToolsSwingUtils.createVerticalSplit(
900
                this.grdAttrTags,
901
                this.gridAttrTagsTable, false,
902
                this.gridAttrTagsItem, true
903
        );
904
        
905
        DefaultComboBoxModel<ListElement<Integer>> modelTypes = new DefaultComboBoxModel<>();
906
        for (ListElement<Integer> element : fieldTypes) {
907
            modelTypes.addElement(element);
908
        }
909
        this.cboFieldType.setModel(modelTypes);
910
        this.cboFieldType.setRenderer(new DefaultListCellRenderer() {
911
          @Override
912
          public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
913
              JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
914
              label.setIcon(null);
915
              try {
916
                DataType dataType = dataTypeManager.get((int) value);
917
                IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
918
                if (theme.exists(dataType.getIconName())) {
919
                    label.setIcon(theme.get(dataType.getIconName()));
920
                }
921
              } catch(Exception ex) {
922
                // Do nothing, ignore
923
              }
924
              return label;
925
          }
926
        });
927

    
928
        DefaultComboBoxModel<ListElement<Integer>> modelGeomTypes = new DefaultComboBoxModel<>();
929
        for (ListElement<Integer> element : this.geometryTypes) {
930
            modelGeomTypes.addElement(element);
931
        }
932
        this.cboGeometryType.setModel(modelGeomTypes);
933

    
934
        DefaultComboBoxModel<ListElement<Integer>> modelGeomSubtypes = new DefaultComboBoxModel<>();
935
        for (ListElement<Integer> element : this.geometrySubtypes) {
936
            modelGeomSubtypes.addElement(element);
937
        }
938

    
939
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
940

    
941

    
942
        swingManager.addClearButton(this.txtDefaultValue);
943
        swingManager.addClearButton(this.txtDefaultFormat);
944
        swingManager.addClearButton(this.txtFieldName);
945
        swingManager.addClearButton(this.txtIntervalEnd);
946
        swingManager.addClearButton(this.txtIntervalStart);
947
        swingManager.addClearButton(this.txtScale);
948
        swingManager.addClearButton(this.txtSize);
949
        swingManager.addClearButton(this.txtDisplaySize);
950
        swingManager.addClearButton(this.txtLabel);
951
        swingManager.addClearButton(this.txtDescription);
952
        swingManager.addClearButton(this.cboGroup);
953
        swingManager.addClearButton(this.txtMaxValue);
954
        swingManager.addClearButton(this.txtMinValue);
955
        swingManager.addClearButton(this.txtAvailableValuesLabel);
956
        swingManager.addClearButton(this.txtAvailableValuesValue);
957

    
958
        swingManager.setDefaultPopupMenu(this.txtDefaultValue);
959
        swingManager.setDefaultPopupMenu(this.txtDefaultFormat);
960
        swingManager.setDefaultPopupMenu(this.txtFieldName);
961
        swingManager.setDefaultPopupMenu(this.txtIntervalEnd);
962
        swingManager.setDefaultPopupMenu(this.txtIntervalStart);
963
        swingManager.setDefaultPopupMenu(this.txtScale);
964
        swingManager.setDefaultPopupMenu(this.txtSize);
965
        swingManager.setDefaultPopupMenu(this.txtDisplaySize);
966
        swingManager.setDefaultPopupMenu(this.cboDateFormat);
967
        swingManager.setDefaultPopupMenu(this.cboFieldType);
968
        swingManager.setDefaultPopupMenu(this.cboGeometrySubtype);
969
        swingManager.setDefaultPopupMenu(this.cboGeometryType);
970
        swingManager.setDefaultPopupMenu(this.cboDataProfile);
971

    
972
//        swingManager.setDefaultPopupMenu(this.cboRelationToOneCodeName);
973
//        swingManager.setDefaultPopupMenu(this.cboRelationToOneTableName);
974

    
975
//        swingManager.setDefaultPopupMenu(this.cboRelationToManyForeignFieldName);
976
//        swingManager.setDefaultPopupMenu(this.cboRelationToManyTableName);
977

    
978
        swingManager.setDefaultPopupMenu(this.cboGroup);
979
        swingManager.setDefaultPopupMenu(this.txtOrder);
980
        swingManager.setDefaultPopupMenu(this.txtLabel);
981
        swingManager.setDefaultPopupMenu(this.txtDescription);
982
        swingManager.setDefaultPopupMenu(this.txtMinValue);
983
        swingManager.setDefaultPopupMenu(this.txtMaxValue);
984
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesLabel);
985
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesValue);
986

    
987
        this.toOneController = new ToOneController(
988
                txtRelationToOneMyFieldName,
989
                cboRelationToOneType, 
990
                chkRelationToOneIsClosedList, 
991
                cboRelationToOneTableName, 
992
                cboRelationToOneCodeName, 
993
                cboRelationToOneFormula, 
994
                btnRelationToOneFormula,
995
                btnRelationToOneFormulaBookmarks,
996
                btnRelationToOneFormulaHistory
997
        );
998
        this.toManyController = new ToManyController(
999
                cboRelationToManyType, 
1000
                cboRelationToManyMyFieldName, 
1001
                cboRelationToManyTableName, 
1002
                cboRelationToManyForeignFieldName, 
1003
                
1004
                txtRelationToManyExpression, 
1005
                
1006
                btnRelationToManyExpression,
1007
                btnRelationToManyExpressionHistory,
1008
                btnRelationToManyExpressionBookmarks
1009
        );
1010
        this.pickerIntervalEnd = swingManager.createDatePickerController(
1011
                this.txtIntervalEnd,
1012
                this.btnIntervalEnd
1013
        );
1014
        this.pickerIntervalStart = swingManager.createDatePickerController(
1015
                this.txtIntervalStart,
1016
                this.btnIntervalStart
1017
        );
1018
        this.pickerSize = evaluatorSwingManager.createCalculatorController(
1019
                this.txtSize, DataTypes.INT
1020
        );
1021
        this.pickerDisplaySize = evaluatorSwingManager.createCalculatorController(this.txtDisplaySize, DataTypes.INT
1022
        );
1023
        this.pickerPrecision = evaluatorSwingManager.createCalculatorController(
1024
                this.txtPrecision, DataTypes.INT
1025
        );
1026
        this.pickerScale = evaluatorSwingManager.createCalculatorController(
1027
                this.txtScale, DataTypes.INT
1028
        );
1029
        this.pickerLocale = swingManager.createLocalePickerController(this.cboLocale);
1030
        
1031
        this.txtDefaultValue.getComponentPopupMenu().add(evaluatorSwingManager.createJExpressionBuilderAction(txtDefaultValue));
1032
        this.pickerOrder = evaluatorSwingManager.createCalculatorController(
1033
                this.txtOrder, DataTypes.INT
1034
        );
1035

    
1036
        this.availableValuesController = new AvailableValuesController(
1037
                lstAvailableValues,
1038
                txtAvailableValuesLabel,
1039
                txtAvailableValuesValue,
1040
                btnAvailableValuesAdd,
1041
                btnAvailableValuesUpdate,
1042
                btnAvailableValuesRemove,
1043
                btnAvailableValuesRemoveAll
1044
        );
1045
        
1046
        this.tagsController = new DefaultAggregateController<>(
1047
                this.tblAttrTagsItems,
1048
                this.btnAttrTagsModify,
1049
                this.btnAttrTagsDiscard,
1050
                this.btnAttrTagsAccept,
1051
                this.btnAttrTagsNew,
1052
                this.btnAttrTagsDelete,
1053
                new TagController(
1054
                        this.cboAttrTagsItemName,
1055
                        this.cboAttrTagsItemValue,
1056
                        this.lblAttrTagsItemNotesValue
1057
                )
1058
        );        
1059
        this.txtMinValue.setEnabled(false);
1060
        this.txtMaxValue.setEnabled(false);
1061

    
1062
        this.btnVirtualFieldGetter.setText("");
1063
        this.featureStoreElement = dataSwingManager.createFeatureStoreElement();
1064
        this.pickerVirtualFieldGetter = evaluatorSwingManager.createExpressionPickerController(
1065
                txtVirtualFieldGetter, btnVirtualFieldGetter, btnVirtualFieldBookmarksGetter, btnVirtualFieldHistoryGetter
1066
        );
1067
        this.pickerVirtualFieldGetter.getConfig().addElement(this.featureStoreElement);
1068
        this.pickerVirtualFieldSetter = evaluatorSwingManager.createExpressionPickerController(
1069
                txtVirtualFieldSetter, btnVirtualFieldSetter, btnVirtualFieldBookmarksSetter, btnVirtualFieldHistorySetter
1070
        );
1071
        this.pickerVirtualFieldSetter.getConfig().addElement(this.featureStoreElement);
1072
        
1073
        this.chkVirtualField.addChangeListener((ChangeEvent e) -> {
1074
          if (chkVirtualField.isSelected()) {
1075
            pickerVirtualFieldGetter.setEditable(mode==MODE_EDIT_ALL || mode==MODE_EDIT_ONLY_METADATA || mode==MODE_VIRTUAL_FIELD);
1076
            pickerVirtualFieldSetter.setEditable(false);
1077
          } else {
1078
            pickerVirtualFieldGetter.setEditable(false);
1079
            pickerVirtualFieldSetter.setEditable(false);
1080
          }
1081
        });
1082

    
1083
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
1084
                this.txtCRS, this.btnCRS
1085
        );
1086

    
1087
        this.cboFieldType.addItemListener((ItemEvent e) -> {
1088
          SwingUtilities.invokeLater(() -> {
1089
            doFieldTypeChanged();
1090
          });
1091
        });
1092

    
1093
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
1094
          doCheckPrecisionAndScale();
1095
        });
1096
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
1097
          doCheckPrecisionAndScale();
1098
        });
1099

    
1100
        DefaultComboBoxModel dataProfilesModel = new DefaultComboBoxModel<>();
1101
        dataProfilesModel.addElement(new ListElement<>("", null));
1102
        for (DataProfile profile : DALLocator.getDataManager().getDataProfiles()) {
1103
            dataProfilesModel.addElement(new ListElement<>(profile.getName(), profile.getID()));
1104
        }
1105
        this.cboDataProfile.setModel(dataProfilesModel);
1106
        
1107
        this.btnFieldType.addActionListener((ActionEvent e) -> {
1108
          doDataTypeSelection();
1109
        });
1110
        
1111
        this.pickerValuesFilter = evaluatorSwingManager.createExpressionPickerController(
1112
                txtValuesFilter, btnValuesFilter, btnValuesFilterBookmarks, btnValuesFilterHistory
1113
        );
1114
        this.pickerValuesFilter.getConfig().addElement(this.featureStoreElement);
1115
        
1116
        this.chkIsAutomatic.addActionListener((ActionEvent e) -> {
1117
            doIsAutomaticChanged();
1118
        });
1119

    
1120
        this.rdbRelationNone.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1121
        this.rdbRelationToOne.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1122
        this.rdbRelationToMany.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1123

    
1124
        this.chkDefaultValue.addActionListener((ActionEvent e) -> {
1125
            txtDefaultValue.setEditable(!chkDefaultValue.isSelected());
1126
        });
1127
        
1128
        SwingUtilities.invokeLater( () -> {
1129
                splAttrTags.setDividerLocation(0.4);
1130
            }
1131
        );
1132
        
1133
    }
1134

    
1135
    private void translate() {
1136
        final ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
1137
        final I18nManager i18n = ToolsLocator.getI18nManager();
1138
    
1139
        swingManager.translate(this.lblAllowNulls);
1140
        swingManager.translate(this.lblCRS);
1141
        swingManager.translate(this.lblDataProfile);
1142
        swingManager.translate(this.lblDateFormat);
1143
        swingManager.translate(this.lblDefaultValue);
1144
        swingManager.translate(this.chkDefaultValue);
1145
        swingManager.translate(this.lblDefaultFormat);
1146
        swingManager.translate(this.lblFieldName);
1147
        swingManager.translate(this.lblFieldType);
1148
        swingManager.translate(this.lblGeometrySubtype);
1149
        swingManager.translate(this.lblGeometryType);
1150
        swingManager.translate(this.lblInterval);
1151
        swingManager.translate(this.lblIntervalEnd);
1152
        swingManager.translate(this.lblIntervalStart);
1153
        swingManager.translate(this.lblIsAutomatic);
1154
        swingManager.translate(this.lblIsIndexed);
1155
        swingManager.translate(this.lblIsReadOnly);
1156
        swingManager.translate(this.lblIsPrimaryKey);
1157
        swingManager.translate(this.lblPrecision);
1158
        swingManager.translate(this.lblScale);
1159
        swingManager.translate(this.lblSize);
1160
        swingManager.translate(this.lblDisplaySize);
1161
        swingManager.translate(this.chkVirtualField);
1162
        swingManager.translate(this.lblVirtualField);
1163
        swingManager.translate(this.lblVirtualFieldSep);
1164
        swingManager.translate(this.lblVirtualFieldGetter);
1165
        swingManager.translate(this.lblVirtualFieldSetter);
1166
        swingManager.translate(this.tabAditionalFields);
1167
        swingManager.translate(this.tabLayout);
1168
        swingManager.translate(this.lblGroup);
1169
        swingManager.translate(this.lblOrder);
1170
        swingManager.translate(this.lblHidden);
1171
        swingManager.translate(this.lblLabel);
1172
        swingManager.translate(this.lblDescription);
1173
        swingManager.translate(this.lblMinValue);
1174
        swingManager.translate(this.lblMaxValue);
1175
        swingManager.translate(this.lblAvailableValues);
1176
        swingManager.translate(this.lblAvailableValuesLabel);
1177
        swingManager.translate(this.lblAvailableValuesValue);
1178
        swingManager.translate(this.btnAvailableValuesAdd);
1179
        swingManager.translate(this.btnAvailableValuesUpdate);
1180
        swingManager.translate(this.btnAvailableValuesRemove);
1181
        swingManager.translate(this.btnAvailableValuesRemoveAll);
1182
        swingManager.translate(this.lblAttrTagsItemName);
1183
        swingManager.translate(this.lblAttrTagsItemValue);
1184
        swingManager.translate(this.lblAttrTagsItemNotes);
1185
        swingManager.translate(this.lblValuesFilter);
1186

    
1187
        swingManager.translate(this.lblRelationRepository);
1188

    
1189
        swingManager.translate(this.lblRelationNone);
1190
        swingManager.translate(this.lblRelationToOne);
1191
        swingManager.translate(this.lblRelationToMany);
1192
        
1193
        swingManager.translate(this.lblRelationToOneType);
1194
        swingManager.translate(this.lblRelationToOneCondition);
1195
        swingManager.translate(this.lblRelationToOneLabelFormula);
1196
        swingManager.translate(this.lblRelationToOneIsClosedList);
1197

    
1198
        swingManager.translate(this.lblRelationToManyType);
1199
        swingManager.translate(this.lblRelationToManyExpression);
1200
        swingManager.translate(this.lblRelationToManyCondition);
1201

    
1202
//        swingManager.translate(this.chkIsForeingKey);
1203

    
1204
        swingManager.translate(this.txtDisplaySize);
1205
        swingManager.translate(this.txtPrecision);
1206
        swingManager.translate(this.txtScale);
1207
        swingManager.translate(this.txtScale);
1208
        swingManager.translate(this.lblLocale);
1209

    
1210
        swingManager.translate(this.rdbRelationToMany);
1211
        
1212
        this.lblRelationToMany.setText( this.lblRelationToMany.getText() +
1213
                "  ("+
1214
                i18n.getTranslation("_Requires_that_it_be_a_calculated_field_of_list_type") +
1215
                ")"
1216
                );
1217
    }
1218
    
1219
    private int getRelationType() {
1220
        if( this.rdbRelationNone.isSelected() ) {
1221
            return DynField.RELATION_TYPE_NONE;
1222
        } 
1223
        if( this.rdbRelationToOne.isSelected() ) {
1224
            return this.toOneController.getRelationType();
1225
        } 
1226
        if( this.rdbRelationToMany.isSelected() ) {
1227
            return this.toManyController.getRelationType();
1228
        }
1229
        return DynField.RELATION_TYPE_NONE;
1230
    }
1231

    
1232
    private void doChangeRelationType() {
1233
        boolean enabled;
1234
        switch(this.getMode() ) {
1235
            case MODE_EDIT_ONLY_METADATA:
1236
            case MODE_EDIT_ALL:
1237
            case MODE_VIRTUAL_FIELD:
1238
                enabled = true;
1239
                break;
1240
            case MODE_SHOW_ONLY:
1241
            default:
1242
                enabled = false;
1243
                break;
1244
        }
1245

    
1246
        this.rdbRelationNone.setEnabled(enabled);
1247
        this.rdbRelationToOne.setEnabled(enabled && !this.isVirtualField());
1248
        this.rdbRelationToMany.setEnabled(enabled && (this.isVirtualField() || this.getDataType().getType()==DataTypes.LIST));
1249
        
1250
        if( this.rdbRelationNone.isSelected() ) {
1251
            this.pickerVirtualFieldGetter.setEnabled(enabled);
1252
            this.toOneController.setEnabled(false);
1253
            this.toManyController.setEnabled(false);
1254
        } else if( this.rdbRelationToOne.isSelected() ) {
1255
            this.pickerVirtualFieldGetter.setEnabled(enabled);
1256
            this.toManyController.setEnabled(false);
1257
            if( this.isVirtualField() ) {
1258
                this.rdbRelationNone.setSelected(true);
1259
            } else {
1260
                this.toOneController.setEditable(enabled);
1261
                this.toOneController.setEnabled(enabled);
1262
            }
1263
        } else if( this.rdbRelationToMany.isSelected() ) {
1264
            if( !this.isVirtualField() || this.getDataType().getType()!=DataTypes.LIST ) {
1265
                this.rdbRelationNone.setSelected(true);
1266
            } else {
1267
                this.pickerVirtualFieldGetter.setEnabled(false);
1268
                this.toOneController.setEnabled(false);
1269
                this.toManyController.setEditable(enabled);
1270
                this.toManyController.setEnabled(enabled);
1271
            }
1272
        }
1273
    }
1274
    
1275
    @Override
1276
    public JComponent asJComponent() {
1277
        return this;
1278
    }
1279
    
1280
    private void doIsAutomaticChanged() {
1281
        if( this.chkIsAutomatic.isSelected() ) {
1282
            DataType type = this.getDataType();
1283
            String defaultValue;
1284
            if( this.chkDefaultValue.isSelected() ) {
1285
                defaultValue = null;
1286
            } else {
1287
                defaultValue = this.txtDefaultValue.getText();
1288
            }
1289
            if( type.getType()!=DataTypes.LONG || StringUtils.isNotBlank(defaultValue) ) {
1290
                final I18nManager i18n = ToolsLocator.getI18nManager();
1291
                ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1292
                dialogs.messageDialog(
1293
                        i18n.getTranslation("_The_automatic_fields_must_be_of_type_long_and_do_not_support_default_values") +
1294
                            "\n" +
1295
                            i18n.getTranslation("_The_type_and_the_default_value_will_be_changed_to_adapt_them_to_these_needs"), 
1296
                        (String[])null, 
1297
                        i18n.getTranslation("_Warning"), 
1298
                        JOptionPane.INFORMATION_MESSAGE, 
1299
                        "_Automatic_field_flag_force_the_type_to_long_and_an_empty_default_value"
1300
                );
1301
                ListElement.setSelected(cboFieldType,DataTypes.LONG);
1302
                this.txtDefaultValue.setText("");
1303
            }
1304
        }
1305
        updateEditableStates();
1306
    }
1307
    
1308
    private void doDataTypeSelection() {
1309
        final DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
1310
        final I18nManager i18n = ToolsLocator.getI18nManager();
1311
        List<ListElement<Integer>> types = new ArrayList<>();
1312
        for (DataType dataType : dataManager) {
1313
            types.add( new ListElement<>(dataType.getName(), dataType.getType()) );
1314
        }
1315
        types.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
1316
                o1.toString().compareTo(o2.toString())
1317
        );
1318
        
1319
        DefaultListModel<ListElement<Integer>> modelTypes = new DefaultListModel<>();
1320
        for (ListElement<Integer> element : types) {
1321
            modelTypes.addElement(element);
1322
        }
1323
        final JList list = new JList();
1324
        list.setCellRenderer(new DefaultListCellRenderer() {
1325
          @Override
1326
          public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
1327
              JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1328
              label.setIcon(null);
1329
              try {
1330
                DataType dataType = dataManager.get((int) value);
1331
                IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1332
                if (theme.exists(dataType.getIconName())) {
1333
                    label.setIcon(theme.get(dataType.getIconName()));
1334
                }
1335
              } catch(Exception ex) {
1336
                // Do nothing, ignore
1337
              }
1338
              return label;
1339
          }
1340
        });
1341
        list.setModel(modelTypes);
1342
        final JScrollPane scrollpanel = new JScrollPane(list);
1343
        WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1344
        Dialog dialog = winManager.createDialog(
1345
              scrollpanel, 
1346
              i18n.getTranslation("_Data_type_selection"),
1347
              i18n.getTranslation("_Select_the_data_type"),
1348
              WindowManager_v2.BUTTONS_OK_CANCEL
1349
        );
1350
        dialog.addActionListener((ActionEvent e) -> {
1351
          if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
1352
            Integer type = (Integer) ListElement.getSelected(list);
1353
            if( type!=null ) {
1354
              ListElement.setSelected(cboFieldType, type);
1355
              if( ListElement.getSelected(cboFieldType)==null ) {
1356
                DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
1357
                DataType dataType = dataTypeManager.get(type);
1358
                cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1359
                ListElement.setSelected(cboFieldType, dataType.getType());
1360
              }
1361
            }
1362
          }
1363
        });
1364
        dialog.show(WindowManager.MODE.DIALOG);
1365
    }
1366
    
1367
    private int getMaxAttributeSize(EditableFeatureAttributeDescriptor descriptor) {
1368
        FeatureStore store = descriptor.getStore();
1369
        if(store == null){
1370
            return -1;
1371
        }
1372
        DataStoreProviderFactory providerFactory = store.getProviderFactory();
1373
        if(providerFactory == null){
1374
            return -1;
1375
        }
1376
        return ((FeatureStoreProviderFactory)providerFactory).getMaxAttributeNameSize();
1377
    }
1378

    
1379
    @Override
1380
    public EditableFeatureAttributeDescriptor fetch(EditableFeatureAttributeDescriptor descriptor) {
1381
        I18nManager i18n = ToolsLocator.getI18nManager();
1382
        try {
1383
            if (this.pickerPrecision.get() != null && this.pickerDisplaySize.get() != null) {
1384
                if (this.pickerPrecision.get() > this.pickerDisplaySize.get()) {
1385
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1386
                    int n = dialogs.confirmDialog(
1387
                            i18n.getTranslation("_The_precision_is_greater_than_the_display_size") + "\n"
1388
                                    + i18n.getTranslation("_This_can_cause_problems_with_some_data_providers_like_SHP_or_DBF")+ "\n"
1389
                                    + i18n.getTranslation("_Do_you_want_to_continue_accepting_the_current_values"),
1390
                            i18n.getTranslation("_Warning"),
1391
                            JOptionPane.YES_NO_OPTION,
1392
                            JOptionPane.WARNING_MESSAGE
1393
                    );
1394
                    if(n != JOptionPane.YES_OPTION){
1395
                        return null;
1396
                    }
1397
                }
1398
            }
1399
            if (!this.chkAllowNulls.isSelected()) {
1400
                if (descriptor.allowNull()) {
1401
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1402
                    dialogs.messageDialog(
1403
                            i18n.getTranslation("_You_have_marked_not_allow_nulls") + "\n"
1404
                            + i18n.getTranslation("If_you_are_not_fully_aware_of_the_repercussions_of_this_it_is_advisable_to_allow_nulls"),
1405
                            null,
1406
                            i18n.getTranslation("_Warning"),
1407
                            JOptionPane.INFORMATION_MESSAGE,
1408
                            "AllowNullsInFeatureTypeEditing"
1409
                    );
1410
                }
1411
            }
1412
            descriptor.setDataType((int) ListElement.getSelected(this.cboFieldType));
1413
            int maxAttributeNameSize = getMaxAttributeSize(descriptor);
1414
            String attrName = this.txtFieldName.getText();
1415
            if(maxAttributeNameSize > -1 && StringUtils.length(attrName) > maxAttributeNameSize){
1416
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1417
                    dialogs.messageDialog(
1418
                            i18n.getTranslation("_Attribute_name_is_too_long") + "\n"
1419
                            + i18n.getTranslation("_max_size_allowed_for_this_table_is_{0}",new String[]{String.valueOf(maxAttributeNameSize)}),
1420
                            null,
1421
                            i18n.getTranslation("_Warning"),
1422
                            JOptionPane.WARNING_MESSAGE
1423
                    );
1424
                    return null;
1425
            }
1426
            descriptor.setName(attrName);
1427
            descriptor.setAllowNull(this.chkAllowNulls.isSelected());
1428
            descriptor.setIsPrimaryKey(this.chkIsPrimaryKey.isSelected());
1429
            descriptor.setIsAutomatic(this.chkIsAutomatic.isSelected());
1430
            descriptor.setIsReadOnly(this.chkIsReadOnly.isSelected());
1431
            descriptor.setIsIndexed(this.chkIsIndexed.isSelected());
1432
            descriptor.setSize(this.pickerSize.get(0));
1433
            descriptor.setDisplaySize(this.pickerDisplaySize.get(0));
1434
            descriptor.setPrecision(this.pickerPrecision.get(0));
1435
            descriptor.setScale(this.pickerScale.get(0));
1436
            
1437
            String defaultValue;
1438
            if( this.chkDefaultValue.isSelected() ) {
1439
                defaultValue = null;
1440
            } else {
1441
                defaultValue = this.txtDefaultValue.getText();
1442
            }
1443
            switch(this.mode) {
1444
                case MODE_EDIT_ONLY_METADATA:
1445
                    if( !ExpressionUtils.isDynamicText(defaultValue) ) {
1446
                        if( !StringUtils.equals(this.previousDefaultValue, defaultValue)) {
1447
                            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1448
                            dialogs.messageDialog(
1449
                                    i18n.getTranslation("_In_metadata_editing_only_mode_it_is_only_allowed_to_indicate_default_values_with_dynamic_expressions"),
1450
                                    null,
1451
                                    i18n.getTranslation("_Warning"),
1452
                                    JOptionPane.WARNING_MESSAGE
1453
                            );
1454
                            return null;
1455
                        }
1456
                    }
1457
                case MODE_EDIT_ALL:
1458
                case MODE_SHOW_ONLY:
1459
                case MODE_VIRTUAL_FIELD:
1460
                    descriptor.setDefaultValue(defaultValue);
1461
            }
1462
            
1463
            descriptor.setDefaultFormat(this.txtDefaultFormat.getText());
1464
            descriptor.setDataProfileName((String) ListElement.getSelected(this.cboDataProfile));
1465
            switch (descriptor.getType()) {
1466
                case DataTypes.GEOMETRY:
1467
                    GeometryManager geomManager = GeometryLocator.getGeometryManager();
1468
                    GeometryType geomType = geomManager.getGeometryType(
1469
                            (int) ListElement.getSelected(this.cboGeometryType),
1470
                            (int) ListElement.getSelected(this.cboGeometrySubtype)
1471
                    );
1472
                    descriptor.setGeometryType(geomType);
1473
                    descriptor.setSRS(this.pickerCRS.get());
1474
                    break;
1475
                case DataTypes.INSTANT:
1476
                case DataTypes.INTERVAL:
1477
                case DataTypes.DATE:
1478
                case DataTypes.TIME:
1479
                case DataTypes.TIMESTAMP:
1480
                    // FIXME
1481
                    break;
1482
                default:
1483
                    break;
1484
            }
1485
            descriptor.setDataProfileName(
1486
                    StringUtils.defaultIfBlank((String) ListElement.getSelected(cboDataProfile), null)
1487
            );
1488

    
1489
            if (this.chkVirtualField.isSelected() ) { //&& this.pickerVirtualField.isEnabled()) {
1490
                Expression expression = this.pickerVirtualFieldGetter.get();
1491
                if (expression == null) {
1492
                    descriptor.setFeatureAttributeEmulator((String) null);
1493
                } else {
1494
                    DataManager dataManager = DALLocator.getDataManager();
1495
                    FeatureAttributeEmulatorExpression emulator = dataManager.createFeatureAttributeEmulatorExpression(
1496
                            descriptor.getFeatureType(),
1497
                            expression
1498
                    );
1499
                    if (!emulator.isValid()) {
1500
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1501
                        dialogs.messageDialog(
1502
                                i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")+"\n"
1503
                                + "\n"
1504
                                + emulator.getErrorMessage(),
1505
                                i18n.getTranslation("_Warning"),
1506
                                JOptionPane.WARNING_MESSAGE
1507
                        );
1508
                        return null;
1509
                    }
1510
                    for (String requiredFieldName : emulator.getRequiredFieldNames()) {
1511
                        if (StringUtils.equalsIgnoreCase(requiredFieldName, descriptor.getName())) {
1512
                            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1513
                            dialogs.messageDialog(
1514
                                    i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")
1515
                                    + "\n\n"
1516
                                    + i18n.getTranslation("_The_expression_contains_a_reference_to_itself"),
1517
                                    i18n.getTranslation("_Warning"),
1518
                                    JOptionPane.WARNING_MESSAGE
1519
                            );
1520
                            return null;
1521
                        }
1522
                    }
1523
                    List<String> undefinedSymbols = emulator.getUndefinedSymbols();
1524
                    if( undefinedSymbols!=null && !undefinedSymbols.isEmpty() ) {
1525
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1526
                        dialogs.messageDialog(
1527
                                i18n.getTranslation("_The_expression_has_undefined_symbols_at_this_moment")+"\n"
1528
                                + i18n.getTranslation("_This_may_not_be_a_mistake")+"\n"
1529
                                + "\n"
1530
                                + "("+StringUtils.join(undefinedSymbols,",")+")",
1531
                                i18n.getTranslation("_Warning"),
1532
                                JOptionPane.WARNING_MESSAGE
1533
                        );
1534
                    }
1535
                    //
1536
                    // No se porque esto de abajo no funciona.
1537
                    // Nunca se lanza la excepcion en el get(Feature) de
1538
                    // DefaultFeatureAttributeEmulatorExpression.
1539
                    //
1540
                    try {
1541
                        emulator.setEnableExceptions(true);
1542
//                        descriptor.setFeatureAttributeEmulator(emulator);
1543
                        emulator.get(this.sampleFeature);
1544
                    } catch(Throwable ex) {
1545
//                        emulator.setEnableExceptions(false);
1546
//                        descriptor.setFeatureAttributeEmulator(null);
1547
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1548
                        dialogs.messageDialog(
1549
                                i18n.getTranslation("_The_expression_can_not_be_evaluated_right_now_It_could_be_valid_when_all_changes_has_been_applied")+
1550
                                    "\n"+
1551
                                    ex.getMessage(), 
1552
                                i18n.getTranslation("_Warning"), 
1553
                                JOptionPane.WARNING_MESSAGE
1554
                        );
1555
//                        return null;
1556
                    } finally {
1557
                        emulator.setEnableExceptions(false);
1558
                    }
1559
                    descriptor.setFeatureAttributeEmulator(emulator);
1560
                }
1561
            }
1562
        } catch (Exception ex) {
1563
            LOGGER.warn("Can't retrieve information from user form.", ex);
1564
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1565
            dialogs.messageDialog(
1566
                    i18n.getTranslation("_Cant_retrieve_information_from_user_form")
1567
                    + "\n"
1568
                    + i18n.getTranslation("_See_log_for_details"),
1569
                    i18n.getTranslation("_Warning"),
1570
                    JOptionPane.WARNING_MESSAGE
1571
            );
1572
            return null;
1573
        }
1574

    
1575
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
1576
        descriptor.setOrder(this.pickerOrder.get(0));
1577
        descriptor.setHidden(this.chkHidden.isSelected());
1578
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
1579
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
1580

    
1581
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1582
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1583
        Expression valuesFilter = this.pickerValuesFilter.get();
1584
        
1585
        descriptor.setAvailableValues(this.availableValuesController.get());
1586
        descriptor.setLocale(this.pickerLocale.get());
1587

    
1588
        this.tagsController.getModel().fetch(descriptor.getTags());
1589

    
1590
        this.toOneController.fetch(descriptor);
1591
        this.toManyController.fetch(descriptor);
1592
        if( rdbRelationToOne.isSelected() ) {
1593
            descriptor.setRelationType(this.toOneController.getRelationType());
1594
            descriptor.getForeingKey().setForeingKey(true);
1595
        } else if( rdbRelationToMany.isSelected() ) {
1596
            descriptor.setRelationType(this.toManyController.getRelationType());
1597
            descriptor.getForeingKey().setForeingKey(false);
1598
            descriptor.setFeatureAttributeEmulator(this.toManyController.getExpression());
1599
        } else if( rdbRelationNone.isSelected() ) {
1600
            descriptor.setRelationType(DynField.RELATION_TYPE_NONE);
1601
            descriptor.getForeingKey().setForeingKey(false);
1602
        }
1603

    
1604

    
1605
        return descriptor;
1606
    }
1607

    
1608
    @Override
1609
    public void clean() {
1610
        this.txtDefaultValue.setText("");
1611
        this.chkDefaultValue.setEnabled(true);
1612
        this.txtDefaultValue.setEditable(false);
1613
        this.txtDefaultFormat.setText("");
1614
        this.txtFieldName.setText("");
1615
//        this.pickerFieldName.set(null);
1616
        this.pickerIntervalEnd.set(null);
1617
        this.pickerIntervalStart.set(null);
1618
        this.pickerScale.set(null);
1619
        this.pickerSize.set(null);
1620
        this.pickerDisplaySize.set(null);
1621

    
1622
        this.chkAllowNulls.setSelected(false);
1623
        this.chkIsAutomatic.setSelected(false);
1624
        this.chkIsReadOnly.setSelected(false);
1625
        this.chkIsIndexed.setSelected(false);
1626
        this.chkIsPrimaryKey.setSelected(false);
1627

    
1628
        switch (this.mode){
1629
            case MODE_EDIT_ALL:
1630
            case MODE_EDIT_ONLY_METADATA:
1631
                this.chkVirtualField.setSelected(false);
1632
                this.chkVirtualField.setEnabled(true);
1633
                break;
1634
            case MODE_SHOW_ONLY:
1635
                this.chkVirtualField.setSelected(false);
1636
                this.chkVirtualField.setEnabled(false);
1637
                break;
1638
            case MODE_VIRTUAL_FIELD:
1639
                this.chkVirtualField.setSelected(true);
1640
                this.chkVirtualField.setEnabled(false);
1641
                break;
1642
        }
1643
        this.pickerVirtualFieldGetter.setEditable(false);
1644
        this.pickerVirtualFieldGetter.set(null);
1645

    
1646
        ListElement.setSelected(cboGeometryType, null);
1647
        ListElement.setSelected(cboGeometrySubtype, null);
1648

    
1649
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
1650

    
1651
        this.cboDataProfile.setSelectedIndex(-1);
1652

    
1653
        this.cboGroup.setSelectedIndex(-1);
1654
        this.pickerOrder.set(null);
1655
        this.chkHidden.setSelected(false);
1656
        this.txtLabel.setText("");
1657
        this.txtDescription.setText("");
1658
        this.txtMinValue.setText("");
1659
        this.txtMaxValue.setText("");
1660
        this.availableValuesController.clean();
1661
        this.tagsController.clean();
1662
        this.toOneController.clean();
1663
    }
1664

    
1665
    @Override
1666
    public void put(FeatureAttributeDescriptor descriptor) {
1667
        if (descriptor == null) {
1668
            this.clean();
1669
            return;
1670
        }
1671
        DataType dataType = descriptor.getDataType();
1672
        FeatureType featureType = descriptor.getFeatureType();
1673
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
1674

    
1675
        if (featureType != null) {
1676
            FeatureStore store = descriptor.getFeatureType().getStore();
1677
            this.featureStoreElement.setFeatureStore(store);
1678
            if (store != null) {
1679
                this.sampleFeature = store.getSampleFeature();
1680
                if (sampleFeature != null) {
1681
                    FeatureSymbolTable featureSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable();
1682
                    featureSymbolTable.setFeature(sampleFeature);
1683
                    this.pickerVirtualFieldGetter.getConfig().setPreviewSymbolTable(featureSymbolTable.createParent());
1684
                    this.pickerValuesFilter.getConfig().setPreviewSymbolTable(featureSymbolTable.createParent());
1685
                }
1686
            }
1687
            List<String> groups = new ArrayList<>();
1688
            for (FeatureAttributeDescriptor otherdesc : featureType) {
1689
                String group = otherdesc.getGroup();
1690
                if (!StringUtils.isBlank(group) && !groups.contains(group)) {
1691
                    groups.add(group);
1692
                }
1693
            }
1694
            for (String group : groups) {
1695
                groupModel.addElement(group);
1696
            }
1697
        }
1698

    
1699
        this.previousDefaultValue = Objects.toString(descriptor.getDefaultValue(),null);
1700
        if( this.previousDefaultValue == null ) {
1701
            this.txtDefaultValue.setText("");
1702
            this.chkDefaultValue.setSelected(true);
1703
            this.txtDefaultValue.setEditable(false);
1704
        } else {
1705
            this.txtDefaultValue.setText(this.previousDefaultValue);
1706
            this.chkDefaultValue.setSelected(false);
1707
            this.txtDefaultValue.setEditable(true);
1708
        }
1709
        
1710
        this.txtDefaultFormat.setText(Objects.toString(descriptor.getDefaultFormat(),""));
1711
        this.txtFieldName.setText(descriptor.getName());
1712
        RelativeInterval interval = (RelativeInterval) descriptor.getInterval();
1713
        if (interval == null) {
1714
            this.pickerIntervalEnd.set(null);
1715
            this.pickerIntervalStart.set(null);
1716
        } else {
1717
            this.pickerIntervalEnd.set(interval.getEnd().toDate());
1718
            this.pickerIntervalStart.set(interval.getStart().toDate());
1719
        }
1720
        if( dataType.supportSize() ) {
1721
          this.pickerSize.set(descriptor.getSize());
1722
        } else {
1723
          this.pickerSize.set(null);
1724
        }
1725
        this.pickerDisplaySize.set(descriptor.getDisplaySize());
1726
        if( dataType.supportPrecision() ) {
1727
          this.pickerPrecision.set(descriptor.getPrecision());
1728
        } else {
1729
          this.pickerPrecision.set(null);
1730
        }
1731
        if( dataType.supportScale()) {
1732
          this.pickerScale.set(descriptor.getScale());
1733
        } else {
1734
          this.pickerScale.set(null);
1735
        }
1736
        this.chkAllowNulls.setSelected(descriptor.allowNull());
1737
        this.chkIsAutomatic.setSelected(descriptor.isAutomatic());
1738
        this.chkIsReadOnly.setSelected(descriptor.isReadOnly());
1739
        this.chkIsIndexed.setSelected(descriptor.isIndexed());
1740
        this.chkIsPrimaryKey.setSelected(descriptor.isPrimaryKey());
1741

    
1742
        this.pickerVirtualFieldGetter.setEnabled(true);
1743
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1744
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1745
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1746
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1747
            this.chkVirtualField.setSelected(true);
1748
            this.pickerVirtualFieldGetter.set(expression);
1749
        } else if (descriptor.isComputed()) {
1750
            this.chkVirtualField.setEnabled(false);
1751
            this.chkVirtualField.setSelected(true);
1752
            this.pickerVirtualFieldGetter.set(null);
1753
        } else {
1754
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1755
            this.chkVirtualField.setSelected(false);
1756
            this.pickerVirtualFieldGetter.set(null);
1757
        }
1758
        this.pickerVirtualFieldGetter.setEnabled(true);
1759

    
1760
        Expression expression = descriptor.getAvailableValuesFilter();
1761
        this.pickerValuesFilter.set(expression);
1762

    
1763
        this.pickerCRS.set(descriptor.getSRS());
1764

    
1765
        if (descriptor.getGeomType() != null) {
1766
            ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1767
            ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1768
        }
1769
        ListElement.setSelected(cboFieldType, dataType.getType());
1770
        if( ListElement.getSelected(cboFieldType)==null ) {
1771
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1772
          ListElement.setSelected(cboFieldType, dataType.getType());
1773
        }
1774
 
1775
        String profile = descriptor.getDataProfileName();
1776
        if (StringUtils.isBlank(profile)) {
1777
            this.cboDataProfile.setSelectedIndex(-1);
1778
        } else {
1779
            ListElement.setSelected(this.cboDataProfile, profile);
1780
        }
1781

    
1782
        this.cboGroup.setModel(groupModel);
1783
        this.cboGroup.setSelectedItem(StringUtils.defaultIfBlank(descriptor.getGroup(), ""));
1784
        this.pickerOrder.set(descriptor.getOder());
1785
        this.chkHidden.setSelected(descriptor.isHidden());
1786
        if (descriptor.hasLabel()) {
1787
            this.txtLabel.setText(StringUtils.defaultIfBlank(descriptor.getLabel(), ""));
1788
        } else {
1789
            this.txtLabel.setText("");
1790
        }
1791
        if (descriptor.hasDescription()) {
1792
            this.txtDescription.setText(StringUtils.defaultIfBlank(descriptor.getDescription(), ""));
1793
        } else {
1794
            this.txtDescription.setText("");
1795
        }
1796
        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1797
        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1798
        if( descriptor.hasConstantAvailableValues() ) {
1799
          this.availableValuesController.set(descriptor.getAvailableValues());
1800
        } else {
1801
          this.availableValuesController.clean();
1802
        }
1803
        this.tagsController.setModel(new TagsModel(descriptor.getTags()));
1804
        this.pickerLocale.set(descriptor.getLocale());
1805

    
1806
        this.toOneController.put(descriptor);
1807
        this.toManyController.put(descriptor);
1808
        switch(descriptor.getRelationType()) {
1809
            case DynField.RELATION_TYPE_NONE:
1810
                this.rdbRelationNone.setSelected(true);
1811
                this.rdbRelationToOne.setSelected(false);
1812
                this.rdbRelationToMany.setSelected(false); 
1813
                  // No los borramos, solo quedan deshabilitados, para no peder la informacion que contengan
1814
//                this.toOneController.clean(); 
1815
//                this.toManyController.clean();
1816
                break;
1817
            case DynField.RELATION_TYPE_IDENTITY:
1818
            case DynField.RELATION_TYPE_COLLABORATION:
1819
                this.rdbRelationNone.setSelected(false);
1820
                this.rdbRelationToOne.setSelected(true);
1821
                this.rdbRelationToMany.setSelected(false);
1822
//                this.toManyController.clean();
1823
                break;
1824
            case DynField.RELATION_TYPE_COMPOSITION:
1825
            case DynField.RELATION_TYPE_AGGREGATE:
1826
                this.rdbRelationNone.setSelected(false);
1827
                this.rdbRelationToOne.setSelected(false);
1828
                this.rdbRelationToMany.setSelected(true);
1829
                this.pickerVirtualFieldGetter.setEnabled(false);
1830
//                this.pickerVirtualFieldGetter.set(null);
1831
//                this.toOneController.clean();
1832
                break;
1833
              
1834
        }
1835
        
1836
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1837
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1838
        }
1839
        this.updateEditableStates();
1840
    }
1841

    
1842
    private DataType getDataType() {
1843
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1844
      if (fieldType == null) {
1845
          return null;
1846
      }
1847
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1848
      return dataType;
1849
    }
1850

    
1851
    private void doFieldTypeChanged() {
1852
      try {
1853
        DataType dataType = this.getDataType();
1854

    
1855
        if( dataType.supportSize() ) {
1856
            this.pickerSize.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1857
        } else {
1858
            this.pickerSize.setEditable(false);
1859
            this.pickerSize.set(null);
1860
        }        
1861
        this.pickerDisplaySize.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1862
        if( dataType.supportPrecision() ) {
1863
          if( dataType.isPredefinedPrecision() ) {
1864
            this.pickerPrecision.setEditable(false);
1865
          } else {
1866
            this.pickerPrecision.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1867
          }
1868
        } else {
1869
            this.pickerPrecision.setEditable(false);
1870
            this.pickerPrecision.set(null);
1871
        }        
1872
        if( dataType.supportScale()) {
1873
            this.pickerScale.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1874
        } else {
1875
            this.pickerScale.setEditable(false);
1876
            this.pickerScale.set(null);
1877
        }        
1878
        switch (dataType.getType()) {
1879
          case DataTypes.GEOMETRY:
1880
            this.cboGeometryType.setEnabled(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1881
            this.cboGeometrySubtype.setEnabled(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1882
            this.pickerCRS.setEditable(this.mode == MODE_EDIT_ALL || this.isVirtualField());
1883
            this.cboDateFormat.setEnabled(false);
1884
            this.pickerIntervalStart.setEditable(false);
1885
            this.pickerIntervalEnd.setEditable(false);
1886
            this.tabAditionalFields.setEnabledAt(1, true);
1887
            this.tabAditionalFields.setEnabledAt(2, false);
1888
            break;
1889
          case DataTypes.INSTANT:
1890
          case DataTypes.INTERVAL:
1891
          case DataTypes.DATE:
1892
          case DataTypes.TIME:
1893
          case DataTypes.TIMESTAMP:
1894
            this.cboGeometryType.setEnabled(false);
1895
            this.cboGeometrySubtype.setEnabled(false);
1896
            this.pickerCRS.setEditable(false);
1897
            this.cboDateFormat.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA || this.isVirtualField());
1898
            this.pickerIntervalStart.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA || this.isVirtualField());
1899
            this.pickerIntervalEnd.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA || this.isVirtualField());
1900
            this.tabAditionalFields.setEnabledAt(1, false);
1901
            this.tabAditionalFields.setEnabledAt(2, true);
1902
            break;
1903
          case DataTypes.BYTE:
1904
          case DataTypes.INT:
1905
          case DataTypes.LONG:
1906
          case DataTypes.STRING:
1907
          case DataTypes.FILE:
1908
          case DataTypes.URL:
1909
          case DataTypes.URI:
1910
          case DataTypes.FLOAT:
1911
          case DataTypes.DOUBLE:
1912
          case DataTypes.DECIMAL:
1913
            this.cboGeometryType.setEnabled(false);
1914
            this.cboGeometrySubtype.setEnabled(false);
1915
            this.pickerCRS.setEditable(false);
1916
            this.cboDateFormat.setEnabled(false);
1917
            this.pickerIntervalStart.setEditable(false);
1918
            this.pickerIntervalEnd.setEditable(false);
1919
            this.tabAditionalFields.setEnabledAt(1, false);
1920
            this.tabAditionalFields.setEnabledAt(2, false);
1921
            break;
1922
          default:
1923
            this.cboGeometryType.setEnabled(false);
1924
            this.cboGeometrySubtype.setEnabled(false);
1925
            this.pickerCRS.setEditable(false);
1926
            this.cboDateFormat.setEnabled(false);
1927
            this.pickerIntervalStart.setEditable(false);
1928
            this.pickerIntervalEnd.setEditable(false);
1929
            this.tabAditionalFields.setEnabledAt(1, false);
1930
            this.tabAditionalFields.setEnabledAt(2, false);
1931
        }
1932
//        updateRelationState();
1933
        doChangeRelationType();
1934
      } catch (Exception ex) {
1935
        LOGGER.warn("Problems changing field type.", ex);
1936
      }
1937

    
1938
    }
1939
    
1940
    boolean isVirtualField() {
1941
        return this.chkVirtualField.isSelected();
1942
    }
1943

    
1944
    @Override
1945
    public int getMode() {
1946
        return this.mode;
1947
    }
1948
    
1949
    @Override
1950
    public void setMode(int mode) {
1951
        this.mode = mode;
1952
        updateEditableStates();
1953
    }
1954
    
1955
    private void updateEditableStates() {
1956
        DataType dataType = this.getDataType();
1957
        switch(this.mode) {
1958
            case MODE_EDIT_ALL:
1959
                this.txtDefaultValue.setEditable(!this.chkIsAutomatic.isSelected());
1960
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
1961
                this.txtDefaultFormat.setEditable(true);
1962
                this.txtFieldName.setEditable(true);
1963
                this.pickerIntervalEnd.setEditable(true);
1964
                this.pickerIntervalStart.setEditable(true);
1965
                this.pickerSize.setEditable(dataType.supportSize());
1966
                this.pickerDisplaySize.setEditable(true);
1967
                if( dataType.isPredefinedPrecision() ) {
1968
                  this.pickerPrecision.setEditable(false);
1969
                  this.pickerPrecision.set(dataType.getMaxPrecision());
1970
                } else {
1971
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
1972
                }
1973
                this.pickerScale.setEditable(dataType.supportScale());
1974
                this.cboDataProfile.setEnabled(true);
1975

    
1976
                this.chkAllowNulls.setEnabled(true);
1977
                this.chkIsAutomatic.setEnabled(true);
1978
                this.chkIsReadOnly.setEnabled(true);
1979
                this.chkIsIndexed.setEnabled(true);
1980
                if( this.isVirtualField() ) {
1981
                    this.chkIsPrimaryKey.setEnabled(false);
1982
                } else {
1983
                    this.chkIsPrimaryKey.setEnabled(true);
1984
                }
1985

    
1986
                this.chkVirtualField.setEnabled(true);
1987
                this.pickerVirtualFieldGetter.setEditable(true);
1988

    
1989
                this.cboDateFormat.setEnabled(true);
1990
                this.cboFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
1991
                this.btnFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
1992
                this.cboGeometryType.setEnabled(true);
1993
                this.cboGeometrySubtype.setEnabled(true);
1994
                this.pickerCRS.setEditable(true);
1995

    
1996
                this.cboGroup.setEnabled(true);
1997
                this.pickerOrder.setEditable(true);
1998
                this.chkHidden.setEnabled(true);
1999
                this.txtLabel.setEditable(true);
2000
                this.txtDescription.setEditable(true);
2001
                this.txtMinValue.setEditable(false);
2002
                this.txtMaxValue.setEditable(false);
2003
                this.pickerValuesFilter.setEditable(true);
2004
                this.availableValuesController.setEditable(true);
2005
                this.tagsController.setEnabled(true);
2006
                this.pickerLocale.setEnabled(true);
2007
                break;
2008
            case MODE_EDIT_ONLY_METADATA:
2009
                if( this.chkVirtualField.isSelected() ) {
2010
                    this.txtFieldName.setEditable(true);
2011
                    this.pickerScale.setEditable(true);
2012
                    this.pickerSize.setEditable(true);
2013
                    this.pickerVirtualFieldGetter.setEditable(true);
2014
                    this.cboFieldType.setEnabled(true);
2015
                    this.btnFieldType.setEnabled(true);
2016
                    this.cboGeometryType.setEnabled(true);
2017
                    this.cboGeometrySubtype.setEnabled(true);
2018
                    this.pickerCRS.setEditable(true);
2019
                } else {
2020
                    this.txtFieldName.setEditable(false);
2021
                    this.pickerPrecision.setEditable(false);
2022
                    this.pickerScale.setEditable(false);
2023
                    this.pickerSize.setEditable(false);
2024
                    this.pickerVirtualFieldGetter.setEditable(false);
2025
                    this.cboFieldType.setEnabled(false);
2026
                    this.btnFieldType.setEnabled(false);
2027
                    this.cboGeometryType.setEnabled(false);
2028
                    this.cboGeometrySubtype.setEnabled(false);
2029
                    this.pickerCRS.setEditable(false);
2030
                }
2031

    
2032
                this.pickerLocale.setEnabled(true);
2033
                this.txtDefaultValue.setEditable(true);
2034
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2035
                this.txtDefaultFormat.setEditable(true);
2036
                this.pickerIntervalEnd.setEditable(true);
2037
                this.pickerIntervalStart.setEditable(true);
2038

    
2039
                this.cboDataProfile.setEnabled(true);
2040

    
2041
                this.pickerDisplaySize.setEditable(false);
2042
                this.chkAllowNulls.setEnabled(false);
2043
                this.chkIsAutomatic.setEnabled(false);
2044
                this.chkIsReadOnly.setEnabled(false);
2045
                this.chkIsIndexed.setEnabled(false);
2046
//                if( this.isVirtualField() ) {
2047
                    this.chkIsPrimaryKey.setEnabled(false);
2048
//                } else {
2049
//                    this.chkIsPrimaryKey.setEnabled(true);
2050
//                }
2051

    
2052
                this.chkVirtualField.setEnabled(false);
2053

    
2054
                this.cboDateFormat.setEnabled(true);
2055

    
2056
                this.cboGroup.setEnabled(true);
2057
                this.pickerOrder.setEditable(true);
2058
                this.chkHidden.setEnabled(true);
2059
                this.txtLabel.setEditable(true);
2060
                this.txtDescription.setEditable(true);
2061
                this.txtMinValue.setEditable(false);
2062
                this.txtMaxValue.setEditable(false);
2063
                this.pickerValuesFilter.setEditable(true);
2064
                this.availableValuesController.setEditable(true);
2065
                this.tagsController.setEnabled(true);
2066
                break;
2067
            case MODE_SHOW_ONLY:
2068
                this.txtDefaultValue.setEditable(false);
2069
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2070
                this.txtDefaultFormat.setEditable(false);
2071
                this.txtFieldName.setEditable(false);
2072
                this.pickerIntervalEnd.setEditable(false);
2073
                this.pickerIntervalStart.setEditable(false);
2074
                this.pickerPrecision.setEditable(false);
2075
                this.pickerScale.setEditable(false);
2076
                this.pickerSize.setEditable(false);
2077
                this.pickerDisplaySize.setEditable(false);
2078
                this.cboDataProfile.setEnabled(false);
2079
                this.pickerLocale.setEnabled(false);
2080

    
2081
                this.chkAllowNulls.setEnabled(false);
2082
                this.chkIsAutomatic.setEnabled(false);
2083
                this.chkIsReadOnly.setEnabled(false);
2084
                this.chkIsIndexed.setEnabled(false);
2085
                this.chkIsPrimaryKey.setEnabled(false);
2086

    
2087
                this.chkVirtualField.setEnabled(false);
2088
                this.pickerVirtualFieldGetter.setEditable(false);
2089

    
2090
                this.cboDateFormat.setEnabled(false);
2091
                this.cboFieldType.setEnabled(false);
2092
                this.btnFieldType.setEnabled(false);
2093
                this.cboGeometryType.setEnabled(false);
2094
                this.cboGeometrySubtype.setEnabled(false);
2095
                this.pickerCRS.setEditable(false);
2096

    
2097
                this.cboGroup.setEnabled(false);
2098
                this.pickerOrder.setEditable(false);
2099
                this.chkHidden.setEnabled(false);
2100
                this.txtLabel.setEditable(false);
2101
                this.txtDescription.setEditable(false);
2102
                this.txtMinValue.setEditable(false);
2103
                this.txtMaxValue.setEditable(false);
2104
                this.pickerValuesFilter.setEditable(false);
2105
                this.availableValuesController.setEditable(false);
2106
                this.tagsController.setEnabled(false);
2107
                break;
2108
            case MODE_VIRTUAL_FIELD:
2109
                this.txtDefaultValue.setEditable(!this.chkIsAutomatic.isSelected());
2110
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2111
                this.txtDefaultFormat.setEditable(true);
2112
                this.txtFieldName.setEditable(true);
2113
                this.pickerIntervalEnd.setEditable(true);
2114
                this.pickerIntervalStart.setEditable(true);
2115
                this.pickerSize.setEditable(dataType.supportSize());
2116
                this.pickerDisplaySize.setEditable(true);
2117
                if( dataType.isPredefinedPrecision() ) {
2118
                  this.pickerPrecision.setEditable(false);
2119
                  this.pickerPrecision.set(dataType.getMaxPrecision());
2120
                } else {
2121
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
2122
                }
2123
                this.pickerScale.setEditable(dataType.supportScale());
2124
                this.cboDataProfile.setEnabled(true);
2125

    
2126
                this.chkAllowNulls.setEnabled(true);
2127
                this.chkIsAutomatic.setEnabled(true);
2128
                this.chkIsReadOnly.setEnabled(true);
2129
                this.chkIsIndexed.setEnabled(true);
2130
                if( this.isVirtualField() ) {
2131
                    this.chkIsPrimaryKey.setEnabled(false);
2132
                } else {
2133
                    this.chkIsPrimaryKey.setEnabled(true);
2134
                }
2135

    
2136
                this.chkVirtualField.setEnabled(false);
2137
                this.chkVirtualField.setSelected(true);
2138
                this.pickerVirtualFieldGetter.setEditable(true);
2139

    
2140
                this.cboDateFormat.setEnabled(true);
2141
                this.cboFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
2142
                this.btnFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
2143
                this.cboGeometryType.setEnabled(true);
2144
                this.cboGeometrySubtype.setEnabled(true);
2145
                this.pickerCRS.setEditable(true);
2146

    
2147
                this.cboGroup.setEnabled(true);
2148
                this.pickerOrder.setEditable(true);
2149
                this.chkHidden.setEnabled(true);
2150
                this.txtLabel.setEditable(true);
2151
                this.txtDescription.setEditable(true);
2152
                this.txtMinValue.setEditable(false);
2153
                this.txtMaxValue.setEditable(false);
2154
                this.pickerValuesFilter.setEditable(true);
2155
                this.availableValuesController.setEditable(true);
2156
                this.tagsController.setEnabled(true);
2157
                this.pickerLocale.setEnabled(true);
2158
                break;
2159
        }
2160
        this.txtDisplaySize.setBackground(UIManager.getColor(ToolsSwingManager.COLOR_TEXTFIELD_BACKGROUND));
2161
        if(this.pickerPrecision.get() != null && this.pickerDisplaySize.get() != null){
2162
            if(this.pickerPrecision.get() > this.pickerDisplaySize.get()){
2163
                this.txtDisplaySize.setBackground(ToolsSwingLocator.getToolsSwingManager().getWarningBackgroundColor());
2164
            }
2165
        }
2166
        updateRelationState();
2167
    }
2168
    
2169
    private void updateRelationState() {
2170
        switch(this.mode) {
2171
            case MODE_EDIT_ALL:
2172
            case MODE_EDIT_ONLY_METADATA:
2173
            case MODE_VIRTUAL_FIELD:
2174
                if( this.isVirtualField() ) {
2175
                    this.toOneController.setEditable(false);
2176
                    this.rdbRelationToOne.setEnabled(false);
2177
                    this.toManyController.setEditable(this.getDataType().getType() == DataTypes.LIST);
2178
                    this.rdbRelationToMany.setEnabled(this.getDataType().getType() == DataTypes.LIST);
2179
                } else {
2180
                    this.toOneController.setEditable(true);
2181
                    this.rdbRelationToOne.setEnabled(true);
2182
                    this.toManyController.setEditable(false);
2183
                    this.rdbRelationToMany.setEnabled(false);
2184
                }
2185
                this.rdbRelationNone.setEnabled(true);
2186
                if( this.rdbRelationToMany.isSelected() ) {
2187
                    this.pickerVirtualFieldGetter.setEnabled(false);
2188
//                    this.pickerVirtualFieldGetter.set(null);
2189
                } else {
2190
                    this.pickerVirtualFieldGetter.setEnabled(true);
2191
                }
2192
                break;
2193
            case MODE_SHOW_ONLY:
2194
            default:
2195
                this.toOneController.setEditable(false);
2196
                this.toManyController.setEditable(false);
2197
                this.rdbRelationToOne.setEnabled(false);
2198
                this.rdbRelationToMany.setEnabled(false);
2199
                this.rdbRelationNone.setEnabled(false);
2200
                if( this.rdbRelationToMany.isSelected() ) {
2201
                    this.pickerVirtualFieldGetter.setEnabled(false);
2202
//                    this.pickerVirtualFieldGetter.set(null);
2203
                }
2204
                break;
2205
        }
2206
    }
2207

    
2208
    private void doCheckPrecisionAndScale() {
2209
      DataType dataType = this.getDataType();
2210
      
2211
      Integer precision = this.pickerPrecision.get();
2212
      if( precision==null ) {
2213
        precision = 0;
2214
      }
2215
      Integer scale = this.pickerScale.get();
2216
      if( scale == null ) {
2217
        scale = 0;
2218
      }      
2219
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
2220
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
2221
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
2222
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
2223
      } else {
2224
        this.pickerPrecision.setWarning(false);
2225
        this.pickerScale.setWarning(false);
2226
      }
2227
    }
2228

    
2229
    @Override
2230
    public void setNameAsNew(FeatureType featureType) {
2231
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
2232
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
2233
                cloneFeatureType.getNewFieldName(), 
2234
                DataTypes.STRING,
2235
                50);
2236
        this.put(newAttributeDescriptor);
2237
    }
2238

    
2239
    @Override
2240
    public String getName() {
2241
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
2242
    }
2243

    
2244
    @Override
2245
    public ImageIcon loadImage(String imageName) {
2246
        return ToolsSwingUtils.loadImage(this, imageName);
2247
    }
2248

    
2249
  public static void selfRegister() {
2250
    boolean n = ToolsSwingUtils.registerIcons( 
2251
            DefaultFeatureAttributeSelectionPanel.class,
2252
            null,
2253
            LIBRARY_NAME,
2254
            new String[]{ "picker", "picker-datatype"}
2255
    );      
2256
  }
2257

    
2258
}