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

History | View | Annotate | Download (97.3 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_without_composition"),DynField.RELATION_TYPE_AGGREGATE_WITH_COMPOSITION));
387
            relationTypeModel.addElement(new ListElement<>(i18n.getTranslation("_Aggregate_1_N_with_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 int getRelationType() {
664
            Object n = this.cboRelationType.getSelectedItem();
665
            if( n == null ) {
666
                return DynField.RELATION_TYPE_NONE;
667
            }
668
            return ((LabeledValue<Integer>)n).getValue();
669
        }
670
    }
671
    
672

    
673
    private static class AvailableValuesController {
674

    
675
        private final JList lstValues;
676
        private final JTextComponent txtLabel;
677
        private final JTextComponent txtValue;
678
        private final JButton btnAdd;
679
        private final JButton btnUpdate;
680
        private final JButton btnRemove;
681
        private final JButton btnRemoveAll;
682

    
683
        public AvailableValuesController(
684
                JList lstValues,
685
                JTextComponent txtLabel,
686
                JTextComponent txtValue,
687
                JButton btnAdd,
688
                JButton btnUpdate,
689
                JButton btnRemove,
690
                JButton btnRemoveAll
691
        ) {
692
            this.lstValues = lstValues;
693
            this.txtLabel = txtLabel;
694
            this.txtValue = txtValue;
695
            this.btnAdd = btnAdd;
696
            this.btnUpdate = btnUpdate;
697
            this.btnRemove = btnRemove;
698
            this.btnRemoveAll = btnRemoveAll;
699

    
700
            this.lstValues.addListSelectionListener((ListSelectionEvent e) -> {
701
              doValuesChanged();
702
            });
703
            this.btnAdd.addActionListener((ActionEvent e) -> {
704
              doAdd();
705
            });
706
            this.btnUpdate.addActionListener((ActionEvent e) -> {
707
              doUpdate();
708
            });
709
            this.btnRemove.addActionListener((ActionEvent e) -> {
710
              doRemove();
711
            });
712
            this.btnRemoveAll.addActionListener((ActionEvent e) -> {
713
              doRemoveAll();
714
            });
715
        }
716

    
717
        public void clean() {
718
            this.lstValues.setModel(new DefaultListModel());
719
            this.txtLabel.setText("");
720
            this.txtValue.setText("");
721
            this.lstValues.setSelectedIndex(-1);
722
        }
723

    
724
        public DynObjectValueItem[] get() {
725
            ListModel<DynObjectValueItem> model = this.lstValues.getModel();
726
            if( model.getSize()==0 ) {
727
              return null;
728
            }
729
            DynObjectValueItem[] values = new DynObjectValueItem[model.getSize()];
730
            for (int i = 0; i < model.getSize(); i++) {
731
                values[i] = model.getElementAt(i);
732
            }
733
            return values;
734
        }
735

    
736
        public void set(DynObjectValueItem[] availableValues) {
737
            DefaultListModel model = new DefaultListModel();
738
            if (availableValues != null) {
739
                for (DynObjectValueItem availableValue : availableValues) {
740
                    model.addElement(availableValue);
741
                }
742
            }
743
            this.lstValues.setModel(model);
744
            if (model.getSize() > 0) {
745
                this.lstValues.setSelectedIndex(0);
746
            } else {
747
                this.lstValues.setSelectedIndex(-1);
748
            }
749
        }
750

    
751
        public void setEditable(boolean editable) {
752
            this.lstValues.setEnabled(editable);
753
            this.txtLabel.setEditable(editable);
754
            this.txtValue.setEditable(editable);
755
            this.btnAdd.setEnabled(editable);
756
            this.btnUpdate.setEnabled(editable);
757
            this.btnRemove.setEnabled(editable);
758
            this.btnRemoveAll.setEnabled(editable);
759
        }
760

    
761
        private void doValuesChanged() {
762
            DynObjectValueItem value = (DynObjectValueItem) this.lstValues.getSelectedValue();
763
            if (value == null) {
764
                this.txtLabel.setText("");
765
                this.txtValue.setText("");
766
                this.btnAdd.setEnabled(true);
767
                this.btnUpdate.setEnabled(false);
768
                this.btnRemove.setEnabled(false);
769
                return;
770
            }
771
            this.txtLabel.setText(value.getLabel());
772
            this.txtValue.setText(Objects.toString(value.getValue(), ""));
773
            this.btnAdd.setEnabled(true);
774
            this.btnUpdate.setEnabled(true);
775
            this.btnRemove.setEnabled(true);
776
        }
777

    
778
        private void doAdd() {
779
            DynObjectValueItem value = new DynObjectValueItem("Value", "Label");
780
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
781
            model.addElement(value);
782
            this.lstValues.setSelectedIndex(model.getSize() - 1);
783
        }
784

    
785
        private void doUpdate() {
786
            DynObjectValueItem value = (DynObjectValueItem) this.lstValues.getSelectedValue();
787
            if (value == null) {
788
                return; // EEhh?? esto no deberia pasar
789
            }
790
            value.setLabel(this.txtLabel.getText());
791
            value.setValue(this.txtValue.getText());
792
        }
793

    
794
        private void doRemove() {
795
            int n = this.lstValues.getSelectedIndex();
796
            if (n < 0) {
797
                return; // EEhh?? esto no deberia pasar
798
            }
799
            DefaultListModel model = (DefaultListModel) this.lstValues.getModel();
800
            model.removeElementAt(n);
801
            if (--n < 0) {
802
                n = 0;
803
            }
804
            this.lstValues.setSelectedIndex(n);
805
        }
806

    
807
        private void doRemoveAll() {
808
            DefaultListModel model = new DefaultListModel();
809
            this.lstValues.setModel(model);
810
            this.lstValues.setSelectedIndex(-1);
811
        }
812

    
813
    }
814

    
815
    private final List<ListElement<Integer>> fieldTypes;
816
    private final List<ListElement<Integer>> geometryTypes;
817
    private final List<ListElement<Integer>> geometrySubtypes;
818

    
819
    private DatePickerController pickerIntervalEnd;
820
    private DatePickerController pickerIntervalStart;
821
    private CalculatorController<Integer> pickerSize;
822
    private CalculatorController<Integer> pickerDisplaySize;
823
    private CalculatorController<Integer> pickerPrecision;
824
    private CalculatorController<Integer> pickerScale;
825
    private PickerController<Locale> pickerLocale;
826
    private PickerController<IProjection> pickerCRS;
827
    private ExpressionPickerController pickerVirtualFieldGetter;
828
    private ExpressionPickerController pickerVirtualFieldSetter;
829
    private ExpressionPickerController pickerDefaultFormat;
830
    private CalculatorController<Integer> pickerOrder;
831
    private AvailableValuesController availableValuesController;
832
    private AggregateController<Tag> tagsController;
833
    private ToOneController toOneController;
834
    private ExpressionPickerController pickerValuesFilter;
835

    
836
    private int mode;
837
    private FeatureStoreElement featureStoreElement;
838

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

    
858
        this.geometryTypes = new ArrayList<>();
859
        this.geometryTypes.add(new ListElement("Point", Geometry.TYPES.POINT));
860
        this.geometryTypes.add(new ListElement("Line", Geometry.TYPES.LINE));
861
        this.geometryTypes.add(new ListElement("Polygon", Geometry.TYPES.POLYGON));
862
        this.geometryTypes.add(new ListElement("MultiPoint", Geometry.TYPES.MULTIPOINT));
863
        this.geometryTypes.add(new ListElement("MultiLine", Geometry.TYPES.MULTILINE));
864
        this.geometryTypes.add(new ListElement("MultiPolygon", Geometry.TYPES.MULTIPOLYGON));
865
        this.geometryTypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
866
                  o1.toString().compareTo(o2.toString())
867
        );
868

    
869
        this.geometrySubtypes = new ArrayList<>();
870
        this.geometrySubtypes.add(new ListElement("2D", Geometry.SUBTYPES.GEOM2D));
871
        this.geometrySubtypes.add(new ListElement("2DM", Geometry.SUBTYPES.GEOM2DM));
872
        this.geometrySubtypes.add(new ListElement("3D", Geometry.SUBTYPES.GEOM3D));
873
        this.geometrySubtypes.add(new ListElement("3DM", Geometry.SUBTYPES.GEOM3DM));
874
        this.geometrySubtypes.sort((ListElement<Integer> o1, ListElement<Integer> o2) -> 
875
                o1.toString().compareTo(o2.toString())
876
        );
877

    
878
        this.initComponents();
879
    }
880

    
881
    private void initComponents() {
882
        final ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
883
        final ExpressionEvaluatorSwingManager evaluatorSwingManager = ExpressionEvaluatorSwingLocator.getManager();
884
        final DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
885
        final DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
886

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

    
919
        DefaultComboBoxModel<ListElement<Integer>> modelGeomTypes = new DefaultComboBoxModel<>();
920
        for (ListElement<Integer> element : this.geometryTypes) {
921
            modelGeomTypes.addElement(element);
922
        }
923
        this.cboGeometryType.setModel(modelGeomTypes);
924

    
925
        DefaultComboBoxModel<ListElement<Integer>> modelGeomSubtypes = new DefaultComboBoxModel<>();
926
        for (ListElement<Integer> element : this.geometrySubtypes) {
927
            modelGeomSubtypes.addElement(element);
928
        }
929

    
930
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
931

    
932

    
933
        swingManager.addClearButton(this.txtDefaultValue);
934
        swingManager.addClearButton(this.txtDefaultFormat);
935
        swingManager.addClearButton(this.txtFieldName);
936
        swingManager.addClearButton(this.txtIntervalEnd);
937
        swingManager.addClearButton(this.txtIntervalStart);
938
        swingManager.addClearButton(this.txtScale);
939
        swingManager.addClearButton(this.txtSize);
940
        swingManager.addClearButton(this.txtDisplaySize);
941
        swingManager.addClearButton(this.txtLabel);
942
        swingManager.addClearButton(this.txtDescription);
943
        swingManager.addClearButton(this.cboGroup);
944
        swingManager.addClearButton(this.txtMaxValue);
945
        swingManager.addClearButton(this.txtMinValue);
946
        swingManager.addClearButton(this.txtAvailableValuesLabel);
947
        swingManager.addClearButton(this.txtAvailableValuesValue);
948

    
949
        swingManager.setDefaultPopupMenu(this.txtDefaultValue);
950
        swingManager.setDefaultPopupMenu(this.txtDefaultFormat);
951
        swingManager.setDefaultPopupMenu(this.txtFieldName);
952
        swingManager.setDefaultPopupMenu(this.txtIntervalEnd);
953
        swingManager.setDefaultPopupMenu(this.txtIntervalStart);
954
        swingManager.setDefaultPopupMenu(this.txtScale);
955
        swingManager.setDefaultPopupMenu(this.txtSize);
956
        swingManager.setDefaultPopupMenu(this.txtDisplaySize);
957
        swingManager.setDefaultPopupMenu(this.cboDateFormat);
958
        swingManager.setDefaultPopupMenu(this.cboFieldType);
959
        swingManager.setDefaultPopupMenu(this.cboGeometrySubtype);
960
        swingManager.setDefaultPopupMenu(this.cboGeometryType);
961
        swingManager.setDefaultPopupMenu(this.cboDataProfile);
962

    
963
//        swingManager.setDefaultPopupMenu(this.cboRelationToOneCodeName);
964
//        swingManager.setDefaultPopupMenu(this.cboRelationToOneTableName);
965

    
966
//        swingManager.setDefaultPopupMenu(this.cboRelationToManyForeignFieldName);
967
//        swingManager.setDefaultPopupMenu(this.cboRelationToManyTableName);
968

    
969
        swingManager.setDefaultPopupMenu(this.cboGroup);
970
        swingManager.setDefaultPopupMenu(this.txtOrder);
971
        swingManager.setDefaultPopupMenu(this.txtLabel);
972
        swingManager.setDefaultPopupMenu(this.txtDescription);
973
        swingManager.setDefaultPopupMenu(this.txtMinValue);
974
        swingManager.setDefaultPopupMenu(this.txtMaxValue);
975
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesLabel);
976
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesValue);
977

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

    
1027
        this.availableValuesController = new AvailableValuesController(
1028
                lstAvailableValues,
1029
                txtAvailableValuesLabel,
1030
                txtAvailableValuesValue,
1031
                btnAvailableValuesAdd,
1032
                btnAvailableValuesUpdate,
1033
                btnAvailableValuesRemove,
1034
                btnAvailableValuesRemoveAll
1035
        );
1036
        
1037
        this.tagsController = new DefaultAggregateController<>(
1038
                this.tblAttrTagsItems,
1039
                this.btnAttrTagsModify,
1040
                this.btnAttrTagsDiscard,
1041
                this.btnAttrTagsAccept,
1042
                this.btnAttrTagsNew,
1043
                this.btnAttrTagsDelete,
1044
                new TagController(
1045
                        this.cboAttrTagsItemName,
1046
                        this.cboAttrTagsItemValue,
1047
                        this.lblAttrTagsItemNotesValue
1048
                )
1049
        );        
1050
        this.txtMinValue.setEnabled(false);
1051
        this.txtMaxValue.setEnabled(false);
1052

    
1053
        this.btnVirtualFieldGetter.setText("");
1054
        this.featureStoreElement = dataSwingManager.createFeatureStoreElement();
1055
        this.pickerVirtualFieldGetter = evaluatorSwingManager.createExpressionPickerController(
1056
                txtVirtualFieldGetter, btnVirtualFieldGetter, btnVirtualFieldBookmarksGetter, btnVirtualFieldHistoryGetter
1057
        );
1058
        this.pickerVirtualFieldGetter.getConfig().addElement(this.featureStoreElement);
1059
        this.pickerVirtualFieldSetter = evaluatorSwingManager.createExpressionPickerController(
1060
                txtVirtualFieldSetter, btnVirtualFieldSetter, btnVirtualFieldBookmarksSetter, btnVirtualFieldHistorySetter
1061
        );
1062
        this.pickerVirtualFieldSetter.getConfig().addElement(this.featureStoreElement);
1063
        
1064
        this.chkVirtualField.addChangeListener((ChangeEvent e) -> {
1065
          if (chkVirtualField.isSelected()) {
1066
            pickerVirtualFieldGetter.setEditable(mode==MODE_EDIT_ALL || mode==MODE_EDIT_ONLY_METADATA);
1067
            pickerVirtualFieldSetter.setEditable(false);
1068
          } else {
1069
            pickerVirtualFieldGetter.setEditable(false);
1070
            pickerVirtualFieldSetter.setEditable(false);
1071
          }
1072
        });
1073

    
1074
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
1075
                this.txtCRS, this.btnCRS
1076
        );
1077

    
1078
        this.cboFieldType.addItemListener((ItemEvent e) -> {
1079
          SwingUtilities.invokeLater(() -> {
1080
            doFieldTypeChanged();
1081
          });
1082
        });
1083

    
1084
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
1085
          doCheckPrecisionAndScale();
1086
        });
1087
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
1088
          doCheckPrecisionAndScale();
1089
        });
1090

    
1091
        DefaultComboBoxModel dataProfilesModel = new DefaultComboBoxModel<>();
1092
        dataProfilesModel.addElement(new ListElement<>("", null));
1093
        for (DataProfile profile : DALLocator.getDataManager().getDataProfiles()) {
1094
            dataProfilesModel.addElement(new ListElement<>(profile.getName(), profile.getID()));
1095
        }
1096
        this.cboDataProfile.setModel(dataProfilesModel);
1097
        
1098
        this.btnFieldType.addActionListener((ActionEvent e) -> {
1099
          doDataTypeSelection();
1100
        });
1101
        
1102
        this.pickerValuesFilter = evaluatorSwingManager.createExpressionPickerController(
1103
                txtValuesFilter, btnValuesFilter, btnValuesFilterBookmarks, btnValuesFilterHistory
1104
        );
1105
        this.pickerValuesFilter.getConfig().addElement(this.featureStoreElement);
1106
        
1107
        this.chkIsAutomatic.addActionListener((ActionEvent e) -> {
1108
            doIsAutomaticChanged();
1109
        });
1110

    
1111
        this.rdbRelationNone.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1112
        this.rdbRelationToOne.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1113
        this.rdbRelationToMany.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1114

    
1115
        this.chkDefaultValue.addActionListener((ActionEvent e) -> {
1116
            txtDefaultValue.setEditable(!chkDefaultValue.isSelected());
1117
        });
1118
        
1119
        SwingUtilities.invokeLater( () -> {
1120
                splAttrTags.setDividerLocation(0.4);
1121
            }
1122
        );
1123
        
1124
    }
1125

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

    
1178
        swingManager.translate(this.lblRelationRepository);
1179

    
1180
        swingManager.translate(this.lblRelationNone);
1181
        swingManager.translate(this.lblRelationToOne);
1182
        swingManager.translate(this.lblRelationToMany);
1183
        
1184
        swingManager.translate(this.lblRelationToOneType);
1185
        swingManager.translate(this.lblRelationToOneCondition);
1186
        swingManager.translate(this.lblRelationToOneLabelFormula);
1187
        swingManager.translate(this.lblRelationToOneIsClosedList);
1188

    
1189
        swingManager.translate(this.lblRelationToManyType);
1190
        swingManager.translate(this.lblRelationToManyExpression);
1191
        swingManager.translate(this.lblRelationToManyCondition);
1192

    
1193
//        swingManager.translate(this.chkIsForeingKey);
1194

    
1195
        swingManager.translate(this.txtDisplaySize);
1196
        swingManager.translate(this.txtPrecision);
1197
        swingManager.translate(this.txtScale);
1198
        swingManager.translate(this.txtScale);
1199
        swingManager.translate(this.lblLocale);
1200

    
1201
        swingManager.translate(this.rdbRelationToMany);
1202
        
1203
        this.lblRelationToMany.setText( this.lblRelationToMany.getText() +
1204
                "  ("+
1205
                i18n.getTranslation("_Requires_that_it_be_a_calculated_field_of_list_type") +
1206
                ")"
1207
                );
1208
    }
1209
    
1210
    private int getRelationType() {
1211
        if( this.rdbRelationNone.isSelected() ) {
1212
            return DynField.RELATION_TYPE_NONE;
1213
        } 
1214
        if( this.rdbRelationToOne.isSelected() ) {
1215
            return this.toOneController.getRelationType();
1216
        } 
1217
        if( this.rdbRelationToMany.isSelected() ) {
1218
            return this.toManyController.getRelationType();
1219
        }
1220
        return DynField.RELATION_TYPE_NONE;
1221
    }
1222

    
1223
    private void doChangeRelationType() {
1224
        boolean enabled;
1225
        switch(this.getMode() ) {
1226
            case MODE_EDIT_ONLY_METADATA:
1227
            case MODE_EDIT_ALL:
1228
                enabled = true;
1229
                break;
1230
            case MODE_SHOW_ONLY:
1231
            default:
1232
                enabled = false;
1233
                break;
1234
        }
1235

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

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

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

    
1564
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
1565
        descriptor.setOrder(this.pickerOrder.get(0));
1566
        descriptor.setHidden(this.chkHidden.isSelected());
1567
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
1568
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
1569

    
1570
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1571
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1572
        Expression valuesFilter = this.pickerValuesFilter.get();
1573
        
1574
        descriptor.setAvailableValues(this.availableValuesController.get());
1575
        descriptor.setLocale(this.pickerLocale.get());
1576

    
1577
        this.tagsController.getModel().fetch(descriptor.getTags());
1578

    
1579
        this.toOneController.fetch(descriptor);
1580
        this.toManyController.fetch(descriptor);
1581
        if( rdbRelationToOne.isSelected() ) {
1582
            descriptor.setRelationType(this.toOneController.getRelationType());
1583
            descriptor.getForeingKey().setForeingKey(true);
1584
        } else if( rdbRelationToMany.isSelected() ) {
1585
            descriptor.setRelationType(this.toManyController.getRelationType());
1586
            descriptor.getForeingKey().setForeingKey(false);
1587
        } else if( rdbRelationNone.isSelected() ) {
1588
            descriptor.setRelationType(DynField.RELATION_TYPE_NONE);
1589
            descriptor.getForeingKey().setForeingKey(false);
1590
        }
1591

    
1592

    
1593
        return descriptor;
1594
    }
1595

    
1596
    @Override
1597
    public void clean() {
1598
        this.txtDefaultValue.setText("");
1599
        this.chkDefaultValue.setEnabled(true);
1600
        this.txtDefaultValue.setEditable(false);
1601
        this.txtDefaultFormat.setText("");
1602
        this.txtFieldName.setText("");
1603
//        this.pickerFieldName.set(null);
1604
        this.pickerIntervalEnd.set(null);
1605
        this.pickerIntervalStart.set(null);
1606
        this.pickerScale.set(null);
1607
        this.pickerSize.set(null);
1608
        this.pickerDisplaySize.set(null);
1609

    
1610
        this.chkAllowNulls.setSelected(false);
1611
        this.chkIsAutomatic.setSelected(false);
1612
        this.chkIsReadOnly.setSelected(false);
1613
        this.chkIsIndexed.setSelected(false);
1614
        this.chkIsPrimaryKey.setSelected(false);
1615

    
1616
        this.chkVirtualField.setSelected(false);
1617
        this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
1618
        this.pickerVirtualFieldGetter.setEditable(false);
1619
        this.pickerVirtualFieldGetter.set(null);
1620

    
1621
        ListElement.setSelected(cboGeometryType, null);
1622
        ListElement.setSelected(cboGeometrySubtype, null);
1623

    
1624
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
1625

    
1626
        this.cboDataProfile.setSelectedIndex(-1);
1627

    
1628
        this.cboGroup.setSelectedIndex(-1);
1629
        this.pickerOrder.set(null);
1630
        this.chkHidden.setSelected(false);
1631
        this.txtLabel.setText("");
1632
        this.txtDescription.setText("");
1633
        this.txtMinValue.setText("");
1634
        this.txtMaxValue.setText("");
1635
        this.availableValuesController.clean();
1636
        this.tagsController.clean();
1637
        this.toOneController.clean();
1638
    }
1639

    
1640
    @Override
1641
    public void put(FeatureAttributeDescriptor descriptor) {
1642
        if (descriptor == null) {
1643
            this.clean();
1644
            return;
1645
        }
1646
        DataType dataType = descriptor.getDataType();
1647
        FeatureType featureType = descriptor.getFeatureType();
1648
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
1649

    
1650
        if (featureType != null) {
1651
            FeatureStore store = descriptor.getFeatureType().getStore();
1652
            this.featureStoreElement.setFeatureStore(store);
1653
            if (store != null) {
1654
                this.sampleFeature = store.getSampleFeature();
1655
                if (sampleFeature != null) {
1656
                    FeatureSymbolTable featureSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable();
1657
                    featureSymbolTable.setFeature(sampleFeature);
1658
                    this.pickerVirtualFieldGetter.getConfig().setPreviewSymbolTable(featureSymbolTable.createParent());
1659
                    this.pickerValuesFilter.getConfig().setPreviewSymbolTable(featureSymbolTable.createParent());
1660
                }
1661
            }
1662
            List<String> groups = new ArrayList<>();
1663
            for (FeatureAttributeDescriptor otherdesc : featureType) {
1664
                String group = otherdesc.getGroup();
1665
                if (!StringUtils.isBlank(group) && !groups.contains(group)) {
1666
                    groups.add(group);
1667
                }
1668
            }
1669
            for (String group : groups) {
1670
                groupModel.addElement(group);
1671
            }
1672
        }
1673

    
1674
        this.previousDefaultValue = Objects.toString(descriptor.getDefaultValue(),null);
1675
        if( this.previousDefaultValue == null ) {
1676
            this.txtDefaultValue.setText("");
1677
            this.chkDefaultValue.setSelected(true);
1678
            this.txtDefaultValue.setEditable(false);
1679
        } else {
1680
            this.txtDefaultValue.setText(this.previousDefaultValue);
1681
            this.chkDefaultValue.setSelected(false);
1682
            this.txtDefaultValue.setEditable(true);
1683
        }
1684
        
1685
        this.txtDefaultFormat.setText(Objects.toString(descriptor.getDefaultFormat(),""));
1686
        this.txtFieldName.setText(descriptor.getName());
1687
        RelativeInterval interval = (RelativeInterval) descriptor.getInterval();
1688
        if (interval == null) {
1689
            this.pickerIntervalEnd.set(null);
1690
            this.pickerIntervalStart.set(null);
1691
        } else {
1692
            this.pickerIntervalEnd.set(interval.getEnd().toDate());
1693
            this.pickerIntervalStart.set(interval.getStart().toDate());
1694
        }
1695
        if( dataType.supportSize() ) {
1696
          this.pickerSize.set(descriptor.getSize());
1697
        } else {
1698
          this.pickerSize.set(null);
1699
        }
1700
        this.pickerDisplaySize.set(descriptor.getDisplaySize());
1701
        if( dataType.supportPrecision() ) {
1702
          this.pickerPrecision.set(descriptor.getPrecision());
1703
        } else {
1704
          this.pickerPrecision.set(null);
1705
        }
1706
        if( dataType.supportScale()) {
1707
          this.pickerScale.set(descriptor.getScale());
1708
        } else {
1709
          this.pickerScale.set(null);
1710
        }
1711
        this.chkAllowNulls.setSelected(descriptor.allowNull());
1712
        this.chkIsAutomatic.setSelected(descriptor.isAutomatic());
1713
        this.chkIsReadOnly.setSelected(descriptor.isReadOnly());
1714
        this.chkIsIndexed.setSelected(descriptor.isIndexed());
1715
        this.chkIsPrimaryKey.setSelected(descriptor.isPrimaryKey());
1716

    
1717
        this.pickerVirtualFieldGetter.setEnabled(true);
1718
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1719
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1720
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1721
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1722
            this.chkVirtualField.setSelected(true);
1723
            this.pickerVirtualFieldGetter.set(expression);
1724
        } else if (descriptor.isComputed()) {
1725
            this.chkVirtualField.setEnabled(false);
1726
            this.chkVirtualField.setSelected(true);
1727
            this.pickerVirtualFieldGetter.set(null);
1728
        } else {
1729
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1730
            this.chkVirtualField.setSelected(false);
1731
            this.pickerVirtualFieldGetter.set(null);
1732
        }
1733
        this.pickerVirtualFieldGetter.setEnabled(true);
1734

    
1735
        Expression expression = descriptor.getAvailableValuesFilter();
1736
        this.pickerValuesFilter.set(expression);
1737

    
1738
        this.pickerCRS.set(descriptor.getSRS());
1739

    
1740
        if (descriptor.getGeomType() != null) {
1741
            ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1742
            ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1743
        }
1744
        ListElement.setSelected(cboFieldType, dataType.getType());
1745
        if( ListElement.getSelected(cboFieldType)==null ) {
1746
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1747
          ListElement.setSelected(cboFieldType, dataType.getType());
1748
        }
1749
 
1750
        String profile = descriptor.getDataProfileName();
1751
        if (StringUtils.isBlank(profile)) {
1752
            this.cboDataProfile.setSelectedIndex(-1);
1753
        } else {
1754
            ListElement.setSelected(this.cboDataProfile, profile);
1755
        }
1756

    
1757
        this.cboGroup.setModel(groupModel);
1758
        this.cboGroup.setSelectedItem(StringUtils.defaultIfBlank(descriptor.getGroup(), ""));
1759
        this.pickerOrder.set(descriptor.getOder());
1760
        this.chkHidden.setSelected(descriptor.isHidden());
1761
        if (descriptor.hasLabel()) {
1762
            this.txtLabel.setText(StringUtils.defaultIfBlank(descriptor.getLabel(), ""));
1763
        } else {
1764
            this.txtLabel.setText("");
1765
        }
1766
        if (descriptor.hasDescription()) {
1767
            this.txtDescription.setText(StringUtils.defaultIfBlank(descriptor.getDescription(), ""));
1768
        } else {
1769
            this.txtDescription.setText("");
1770
        }
1771
        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1772
        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1773
        if( descriptor.hasConstantAvailableValues() ) {
1774
          this.availableValuesController.set(descriptor.getAvailableValues());
1775
        } else {
1776
          this.availableValuesController.clean();
1777
        }
1778
        this.tagsController.setModel(new TagsModel(descriptor.getTags()));
1779
        this.pickerLocale.set(descriptor.getLocale());
1780

    
1781
        this.toOneController.put(descriptor);
1782
        this.toManyController.put(descriptor);
1783
        switch(descriptor.getRelationType()) {
1784
            case DynField.RELATION_TYPE_NONE:
1785
                this.rdbRelationNone.setSelected(true);
1786
                this.rdbRelationToOne.setSelected(false);
1787
                this.rdbRelationToMany.setSelected(false); 
1788
                  // No los borramos, solo quedan deshabilitados, para no peder la informacion que contengan
1789
//                this.toOneController.clean(); 
1790
//                this.toManyController.clean();
1791
                break;
1792
            case DynField.RELATION_TYPE_IDENTITY:
1793
            case DynField.RELATION_TYPE_COLLABORATION:
1794
                this.rdbRelationNone.setSelected(false);
1795
                this.rdbRelationToOne.setSelected(true);
1796
                this.rdbRelationToMany.setSelected(false);
1797
//                this.toManyController.clean();
1798
                break;
1799
            case DynField.RELATION_TYPE_COMPOSITION:
1800
            case DynField.RELATION_TYPE_AGGREGATE:
1801
                this.rdbRelationNone.setSelected(false);
1802
                this.rdbRelationToOne.setSelected(false);
1803
                this.rdbRelationToMany.setSelected(true);
1804
                this.pickerVirtualFieldGetter.setEnabled(false);
1805
//                this.pickerVirtualFieldGetter.set(null);
1806
//                this.toOneController.clean();
1807
                break;
1808
              
1809
        }
1810
        
1811
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1812
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1813
        }
1814
        this.updateEditableStates();
1815
    }
1816

    
1817
    private DataType getDataType() {
1818
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1819
      if (fieldType == null) {
1820
          return null;
1821
      }
1822
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1823
      return dataType;
1824
    }
1825

    
1826
    private void doFieldTypeChanged() {
1827
      try {
1828
        DataType dataType = this.getDataType();
1829

    
1830
        if( dataType.supportSize() ) {
1831
            this.pickerSize.setEditable(this.mode == MODE_EDIT_ALL);
1832
        } else {
1833
            this.pickerSize.setEditable(false);
1834
            this.pickerSize.set(null);
1835
        }        
1836
        this.pickerDisplaySize.setEditable(this.mode == MODE_EDIT_ALL);
1837
        if( dataType.supportPrecision() ) {
1838
          if( dataType.isPredefinedPrecision() ) {
1839
            this.pickerPrecision.setEditable(false);
1840
          } else {
1841
            this.pickerPrecision.setEditable(this.mode == MODE_EDIT_ALL);
1842
          }
1843
        } else {
1844
            this.pickerPrecision.setEditable(false);
1845
            this.pickerPrecision.set(null);
1846
        }        
1847
        if( dataType.supportScale()) {
1848
            this.pickerScale.setEditable(this.mode == MODE_EDIT_ALL);
1849
        } else {
1850
            this.pickerScale.setEditable(false);
1851
            this.pickerScale.set(null);
1852
        }        
1853
        switch (dataType.getType()) {
1854
          case DataTypes.GEOMETRY:
1855
            this.cboGeometryType.setEnabled(this.mode == MODE_EDIT_ALL);
1856
            this.cboGeometrySubtype.setEnabled(this.mode == MODE_EDIT_ALL);
1857
            this.pickerCRS.setEditable(this.mode == MODE_EDIT_ALL);
1858
            this.cboDateFormat.setEnabled(false);
1859
            this.pickerIntervalStart.setEditable(false);
1860
            this.pickerIntervalEnd.setEditable(false);
1861
            this.tabAditionalFields.setEnabledAt(1, true);
1862
            this.tabAditionalFields.setEnabledAt(2, false);
1863
            break;
1864
          case DataTypes.INSTANT:
1865
          case DataTypes.INTERVAL:
1866
          case DataTypes.DATE:
1867
          case DataTypes.TIME:
1868
          case DataTypes.TIMESTAMP:
1869
            this.cboGeometryType.setEnabled(false);
1870
            this.cboGeometrySubtype.setEnabled(false);
1871
            this.pickerCRS.setEditable(false);
1872
            this.cboDateFormat.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1873
            this.pickerIntervalStart.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1874
            this.pickerIntervalEnd.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1875
            this.tabAditionalFields.setEnabledAt(1, false);
1876
            this.tabAditionalFields.setEnabledAt(2, true);
1877
            break;
1878
          case DataTypes.BYTE:
1879
          case DataTypes.INT:
1880
          case DataTypes.LONG:
1881
          case DataTypes.STRING:
1882
          case DataTypes.FILE:
1883
          case DataTypes.URL:
1884
          case DataTypes.URI:
1885
          case DataTypes.FLOAT:
1886
          case DataTypes.DOUBLE:
1887
          case DataTypes.DECIMAL:
1888
            this.cboGeometryType.setEnabled(false);
1889
            this.cboGeometrySubtype.setEnabled(false);
1890
            this.pickerCRS.setEditable(false);
1891
            this.cboDateFormat.setEnabled(false);
1892
            this.pickerIntervalStart.setEditable(false);
1893
            this.pickerIntervalEnd.setEditable(false);
1894
            this.tabAditionalFields.setEnabledAt(1, false);
1895
            this.tabAditionalFields.setEnabledAt(2, false);
1896
            break;
1897
          default:
1898
            this.cboGeometryType.setEnabled(false);
1899
            this.cboGeometrySubtype.setEnabled(false);
1900
            this.pickerCRS.setEditable(false);
1901
            this.cboDateFormat.setEnabled(false);
1902
            this.pickerIntervalStart.setEditable(false);
1903
            this.pickerIntervalEnd.setEditable(false);
1904
            this.tabAditionalFields.setEnabledAt(1, false);
1905
            this.tabAditionalFields.setEnabledAt(2, false);
1906
        }
1907
//        updateRelationState();
1908
        doChangeRelationType();
1909
      } catch (Exception ex) {
1910
        LOGGER.warn("Problems changing field type.", ex);
1911
      }
1912

    
1913
    }
1914
    
1915
    boolean isVirtualField() {
1916
        return this.chkVirtualField.isSelected();
1917
    }
1918

    
1919
    @Override
1920
    public int getMode() {
1921
        return this.mode;
1922
    }
1923
    
1924
    @Override
1925
    public void setMode(int mode) {
1926
        this.mode = mode;
1927
        updateEditableStates();
1928
    }
1929
    
1930
    private void updateEditableStates() {
1931
        DataType dataType = this.getDataType();
1932
        switch(this.mode) {
1933
            case MODE_EDIT_ALL:
1934
                this.txtDefaultValue.setEditable(!this.chkIsAutomatic.isSelected());
1935
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
1936
                this.txtDefaultFormat.setEditable(true);
1937
                this.txtFieldName.setEditable(true);
1938
                this.pickerIntervalEnd.setEditable(true);
1939
                this.pickerIntervalStart.setEditable(true);
1940
                this.pickerSize.setEditable(dataType.supportSize());
1941
                this.pickerDisplaySize.setEditable(true);
1942
                if( dataType.isPredefinedPrecision() ) {
1943
                  this.pickerPrecision.setEditable(false);
1944
                  this.pickerPrecision.set(dataType.getMaxPrecision());
1945
                } else {
1946
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
1947
                }
1948
                this.pickerScale.setEditable(dataType.supportScale());
1949
                this.cboDataProfile.setEnabled(true);
1950

    
1951
                this.chkAllowNulls.setEnabled(true);
1952
                this.chkIsAutomatic.setEnabled(true);
1953
                this.chkIsReadOnly.setEnabled(true);
1954
                this.chkIsIndexed.setEnabled(true);
1955
                if( this.isVirtualField() ) {
1956
                    this.chkIsPrimaryKey.setEnabled(false);
1957
                } else {
1958
                    this.chkIsPrimaryKey.setEnabled(true);
1959
                }
1960

    
1961
                this.chkVirtualField.setEnabled(true);
1962
                this.pickerVirtualFieldGetter.setEditable(true);
1963

    
1964
                this.cboDateFormat.setEnabled(true);
1965
                this.cboFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
1966
                this.btnFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
1967
                this.cboGeometryType.setEnabled(true);
1968
                this.cboGeometrySubtype.setEnabled(true);
1969
                this.pickerCRS.setEditable(true);
1970

    
1971
                this.cboGroup.setEnabled(true);
1972
                this.pickerOrder.setEditable(true);
1973
                this.chkHidden.setEnabled(true);
1974
                this.txtLabel.setEditable(true);
1975
                this.txtDescription.setEditable(true);
1976
                this.txtMinValue.setEditable(false);
1977
                this.txtMaxValue.setEditable(false);
1978
                this.pickerValuesFilter.setEditable(true);
1979
                this.availableValuesController.setEditable(true);
1980
                this.tagsController.setEnabled(true);
1981
                this.pickerLocale.setEnabled(true);
1982
                break;
1983
            case MODE_EDIT_ONLY_METADATA:
1984
                if( this.chkVirtualField.isSelected() ) {
1985
                    this.txtFieldName.setEditable(true);
1986
                    this.pickerScale.setEditable(true);
1987
                    this.pickerSize.setEditable(true);
1988
                    this.pickerVirtualFieldGetter.setEditable(true);
1989
                    this.cboFieldType.setEnabled(true);
1990
                    this.btnFieldType.setEnabled(true);
1991
                    this.cboGeometryType.setEnabled(true);
1992
                    this.cboGeometrySubtype.setEnabled(true);
1993
                    this.pickerCRS.setEditable(true);
1994
                } else {
1995
                    this.txtFieldName.setEditable(false);
1996
                    this.pickerPrecision.setEditable(false);
1997
                    this.pickerScale.setEditable(false);
1998
                    this.pickerSize.setEditable(false);
1999
                    this.pickerVirtualFieldGetter.setEditable(false);
2000
                    this.cboFieldType.setEnabled(false);
2001
                    this.btnFieldType.setEnabled(false);
2002
                    this.cboGeometryType.setEnabled(false);
2003
                    this.cboGeometrySubtype.setEnabled(false);
2004
                    this.pickerCRS.setEditable(false);
2005
                }
2006

    
2007
                this.pickerLocale.setEnabled(true);
2008
                this.txtDefaultValue.setEditable(true);
2009
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2010
                this.txtDefaultFormat.setEditable(true);
2011
                this.pickerIntervalEnd.setEditable(true);
2012
                this.pickerIntervalStart.setEditable(true);
2013

    
2014
                this.cboDataProfile.setEnabled(true);
2015

    
2016
                this.pickerDisplaySize.setEditable(false);
2017
                this.chkAllowNulls.setEnabled(false);
2018
                this.chkIsAutomatic.setEnabled(false);
2019
                this.chkIsReadOnly.setEnabled(false);
2020
                this.chkIsIndexed.setEnabled(false);
2021
//                if( this.isVirtualField() ) {
2022
                    this.chkIsPrimaryKey.setEnabled(false);
2023
//                } else {
2024
//                    this.chkIsPrimaryKey.setEnabled(true);
2025
//                }
2026

    
2027
                this.chkVirtualField.setEnabled(false);
2028

    
2029
                this.cboDateFormat.setEnabled(true);
2030

    
2031
                this.cboGroup.setEnabled(true);
2032
                this.pickerOrder.setEditable(true);
2033
                this.chkHidden.setEnabled(true);
2034
                this.txtLabel.setEditable(true);
2035
                this.txtDescription.setEditable(true);
2036
                this.txtMinValue.setEditable(false);
2037
                this.txtMaxValue.setEditable(false);
2038
                this.pickerValuesFilter.setEditable(true);
2039
                this.availableValuesController.setEditable(true);
2040
                this.tagsController.setEnabled(true);
2041
                break;
2042
            case MODE_SHOW_ONLY:
2043
                this.txtDefaultValue.setEditable(false);
2044
                this.chkDefaultValue.setEnabled(this.txtDefaultValue.isEditable());
2045
                this.txtDefaultFormat.setEditable(false);
2046
                this.txtFieldName.setEditable(false);
2047
                this.pickerIntervalEnd.setEditable(false);
2048
                this.pickerIntervalStart.setEditable(false);
2049
                this.pickerPrecision.setEditable(false);
2050
                this.pickerScale.setEditable(false);
2051
                this.pickerSize.setEditable(false);
2052
                this.pickerDisplaySize.setEditable(false);
2053
                this.cboDataProfile.setEnabled(false);
2054
                this.pickerLocale.setEnabled(false);
2055

    
2056
                this.chkAllowNulls.setEnabled(false);
2057
                this.chkIsAutomatic.setEnabled(false);
2058
                this.chkIsReadOnly.setEnabled(false);
2059
                this.chkIsIndexed.setEnabled(false);
2060
                this.chkIsPrimaryKey.setEnabled(false);
2061

    
2062
                this.chkVirtualField.setEnabled(false);
2063
                this.pickerVirtualFieldGetter.setEditable(false);
2064

    
2065
                this.cboDateFormat.setEnabled(false);
2066
                this.cboFieldType.setEnabled(false);
2067
                this.btnFieldType.setEnabled(false);
2068
                this.cboGeometryType.setEnabled(false);
2069
                this.cboGeometrySubtype.setEnabled(false);
2070
                this.pickerCRS.setEditable(false);
2071

    
2072
                this.cboGroup.setEnabled(false);
2073
                this.pickerOrder.setEditable(false);
2074
                this.chkHidden.setEnabled(false);
2075
                this.txtLabel.setEditable(false);
2076
                this.txtDescription.setEditable(false);
2077
                this.txtMinValue.setEditable(false);
2078
                this.txtMaxValue.setEditable(false);
2079
                this.pickerValuesFilter.setEditable(false);
2080
                this.availableValuesController.setEditable(false);
2081
                this.tagsController.setEnabled(false);
2082
                break;
2083
        }
2084
        this.txtDisplaySize.setBackground(UIManager.getColor(ToolsSwingManager.COLOR_TEXTFIELD_BACKGROUND));
2085
        if(this.pickerPrecision.get() != null && this.pickerDisplaySize.get() != null){
2086
            if(this.pickerPrecision.get() > this.pickerDisplaySize.get()){
2087
                this.txtDisplaySize.setBackground(ToolsSwingLocator.getToolsSwingManager().getWarningBackgroundColor());
2088
            }
2089
        }
2090
        updateRelationState();
2091
    }
2092
    
2093
    private void updateRelationState() {
2094
        switch(this.mode) {
2095
            case MODE_EDIT_ALL:
2096
            case MODE_EDIT_ONLY_METADATA:
2097
                if( this.isVirtualField() ) {
2098
                    this.toOneController.setEditable(false);
2099
                    this.rdbRelationToOne.setEnabled(false);
2100
                    this.toManyController.setEditable(this.getDataType().getType() == DataTypes.LIST);
2101
                    this.rdbRelationToMany.setEnabled(this.getDataType().getType() == DataTypes.LIST);
2102
                } else {
2103
                    this.toOneController.setEditable(true);
2104
                    this.rdbRelationToOne.setEnabled(true);
2105
                    this.toManyController.setEditable(false);
2106
                    this.rdbRelationToMany.setEnabled(false);
2107
                }
2108
                this.rdbRelationNone.setEnabled(true);
2109
                if( this.rdbRelationToMany.isSelected() ) {
2110
                    this.pickerVirtualFieldGetter.setEnabled(false);
2111
//                    this.pickerVirtualFieldGetter.set(null);
2112
                }
2113
                break;
2114
            case MODE_SHOW_ONLY:
2115
            default:
2116
                this.toOneController.setEditable(false);
2117
                this.toManyController.setEditable(false);
2118
                this.rdbRelationToOne.setEnabled(false);
2119
                this.rdbRelationToMany.setEnabled(false);
2120
                this.rdbRelationNone.setEnabled(false);
2121
                if( this.rdbRelationToMany.isSelected() ) {
2122
                    this.pickerVirtualFieldGetter.setEnabled(false);
2123
//                    this.pickerVirtualFieldGetter.set(null);
2124
                }
2125
                break;
2126
        }
2127
    }
2128

    
2129
    private void doCheckPrecisionAndScale() {
2130
      DataType dataType = this.getDataType();
2131
      
2132
      Integer precision = this.pickerPrecision.get();
2133
      if( precision==null ) {
2134
        precision = 0;
2135
      }
2136
      Integer scale = this.pickerScale.get();
2137
      if( scale == null ) {
2138
        scale = 0;
2139
      }      
2140
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
2141
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
2142
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
2143
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
2144
      } else {
2145
        this.pickerPrecision.setWarning(false);
2146
        this.pickerScale.setWarning(false);
2147
      }
2148
    }
2149

    
2150
    @Override
2151
    public void setNameAsNew(FeatureType featureType) {
2152
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
2153
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
2154
                cloneFeatureType.getNewFieldName(), 
2155
                DataTypes.STRING,
2156
                50);
2157
        this.put(newAttributeDescriptor);
2158
    }
2159

    
2160
    @Override
2161
    public String getName() {
2162
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
2163
    }
2164

    
2165
    @Override
2166
    public ImageIcon loadImage(String imageName) {
2167
        return ToolsSwingUtils.loadImage(this, imageName);
2168
    }
2169

    
2170
  public static void selfRegister() {
2171
    boolean n = ToolsSwingUtils.registerIcons( 
2172
            DefaultFeatureAttributeSelectionPanel.class,
2173
            null,
2174
            LIBRARY_NAME,
2175
            new String[]{ "picker", "picker-datatype"}
2176
    );      
2177
  }
2178

    
2179
}