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

History | View | Annotate | Download (93.7 KB)

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

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

    
121
/**
122
 *
123
 * @author jjdelcerro
124
 */
125
@SuppressWarnings({"UseSpecificCatch"})
126
public class DefaultFeatureAttributePanel
127
        extends DefaultFeatureAttributePanelView
128
        implements FeatureTypeAttributePanel {
129

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

    
144
    private static class ToOneController {
145

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

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

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

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

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

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

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

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

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

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

    
676
    private static class AvailableValuesController {
677

    
678
        private final JList lstValues;
679
        private final JTextComponent txtLabel;
680
        private final JTextComponent txtValue;
681
        private final JButton btnAdd;
682
        private final JButton btnUpdate;
683
        private final JButton btnRemove;
684
        private final JButton btnRemoveAll;
685

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

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

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

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

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

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

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

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

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

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

    
810
        private void doRemoveAll() {
811
            DefaultListModel model = new DefaultListModel();
812
            this.lstValues.setModel(model);
813
            this.lstValues.setSelectedIndex(-1);
814
        }
815

    
816
    }
817

    
818
    private final List<ListElement<Integer>> fieldTypes;
819
    private final List<ListElement<Integer>> geometryTypes;
820
    private final List<ListElement<Integer>> geometrySubtypes;
821

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

    
838
    private int mode;
839
    private FeatureStoreElement featureStoreElement;
840

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

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

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

    
880
        this.initComponents();
881
    }
882

    
883
    private void initComponents() {
884
        final ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
885
        final ExpressionEvaluatorSwingManager evaluatorSwingManager = ExpressionEvaluatorSwingLocator.getManager();
886
        final DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
887
        final I18nManager i18n = ToolsLocator.getI18nManager();
888
        final DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
889

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

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

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

    
932
        this.cboGeometrySubtype.setModel(modelGeomSubtypes);
933

    
934
        swingManager.translate(this.lblAllowNulls);
935
        swingManager.translate(this.lblCRS);
936
        swingManager.translate(this.lblDataProfile);
937
        swingManager.translate(this.lblDateFormat);
938
        swingManager.translate(this.lblDefaultValue);
939
        swingManager.translate(this.lblDefaultFormat);
940
        swingManager.translate(this.lblFieldName);
941
        swingManager.translate(this.lblFieldType);
942
        swingManager.translate(this.lblGeometrySubtype);
943
        swingManager.translate(this.lblGeometryType);
944
        swingManager.translate(this.lblInterval);
945
        swingManager.translate(this.lblIntervalEnd);
946
        swingManager.translate(this.lblIntervalStart);
947
        swingManager.translate(this.lblIsAutomatic);
948
        swingManager.translate(this.lblIsIndexed);
949
        swingManager.translate(this.lblIsReadOnly);
950
        swingManager.translate(this.lblIsPrimaryKey);
951
        swingManager.translate(this.lblPrecision);
952
        swingManager.translate(this.lblScale);
953
        swingManager.translate(this.lblSize);
954
        swingManager.translate(this.lblDisplaySize);
955
        swingManager.translate(this.chkVirtualField);
956
        swingManager.translate(this.lblVirtualField);
957
        swingManager.translate(this.lblVirtualFieldSep);
958
        swingManager.translate(this.lblVirtualFieldGetter);
959
        swingManager.translate(this.lblVirtualFieldSetter);
960
        swingManager.translate(this.tabAditionalFields);
961
        swingManager.translate(this.tabLayout);
962
        swingManager.translate(this.lblGroup);
963
        swingManager.translate(this.lblOrder);
964
        swingManager.translate(this.lblHidden);
965
        swingManager.translate(this.lblLabel);
966
        swingManager.translate(this.lblDescription);
967
        swingManager.translate(this.lblMinValue);
968
        swingManager.translate(this.lblMaxValue);
969
        swingManager.translate(this.lblAvailableValues);
970
        swingManager.translate(this.lblAvailableValuesLabel);
971
        swingManager.translate(this.lblAvailableValuesValue);
972
        swingManager.translate(this.btnAvailableValuesAdd);
973
        swingManager.translate(this.btnAvailableValuesUpdate);
974
        swingManager.translate(this.btnAvailableValuesRemove);
975
        swingManager.translate(this.btnAvailableValuesRemoveAll);
976
        swingManager.translate(this.lblAttrTagsItemName);
977
        swingManager.translate(this.lblAttrTagsItemValue);
978
        swingManager.translate(this.lblAttrTagsItemNotes);
979
        swingManager.translate(this.lblValuesFilter);
980

    
981
        swingManager.translate(this.lblRelationRepository);
982

    
983
        swingManager.translate(this.lblRelationNone);
984
        swingManager.translate(this.lblRelationToOne);
985
        swingManager.translate(this.lblRelationToMany);
986
        
987
        swingManager.translate(this.lblRelationToOneType);
988
        swingManager.translate(this.lblRelationToOneCondition);
989
        swingManager.translate(this.lblRelationToOneLabelFormula);
990
        swingManager.translate(this.lblRelationToOneIsClosedList);
991

    
992
        swingManager.translate(this.lblRelationToManyType);
993
        swingManager.translate(this.lblRelationToManyExpression);
994
        swingManager.translate(this.lblRelationToManyCondition);
995

    
996
//        swingManager.translate(this.chkIsForeingKey);
997

    
998
        swingManager.translate(this.txtDisplaySize);
999
        swingManager.translate(this.txtPrecision);
1000
        swingManager.translate(this.txtScale);
1001
        swingManager.translate(this.txtScale);
1002

    
1003
        swingManager.addClearButton(this.txtDefaultValue);
1004
        swingManager.addClearButton(this.txtDefaultFormat);
1005
        swingManager.addClearButton(this.txtFieldName);
1006
        swingManager.addClearButton(this.txtIntervalEnd);
1007
        swingManager.addClearButton(this.txtIntervalStart);
1008
        swingManager.addClearButton(this.txtScale);
1009
        swingManager.addClearButton(this.txtSize);
1010
        swingManager.addClearButton(this.txtDisplaySize);
1011
        swingManager.addClearButton(this.txtLabel);
1012
        swingManager.addClearButton(this.txtDescription);
1013
        swingManager.addClearButton(this.cboGroup);
1014
        swingManager.addClearButton(this.txtMaxValue);
1015
        swingManager.addClearButton(this.txtMinValue);
1016
        swingManager.addClearButton(this.txtAvailableValuesLabel);
1017
        swingManager.addClearButton(this.txtAvailableValuesValue);
1018

    
1019
        swingManager.setDefaultPopupMenu(this.txtDefaultValue);
1020
        swingManager.setDefaultPopupMenu(this.txtDefaultFormat);
1021
        swingManager.setDefaultPopupMenu(this.txtFieldName);
1022
        swingManager.setDefaultPopupMenu(this.txtIntervalEnd);
1023
        swingManager.setDefaultPopupMenu(this.txtIntervalStart);
1024
        swingManager.setDefaultPopupMenu(this.txtScale);
1025
        swingManager.setDefaultPopupMenu(this.txtSize);
1026
        swingManager.setDefaultPopupMenu(this.txtDisplaySize);
1027
        swingManager.setDefaultPopupMenu(this.cboDateFormat);
1028
        swingManager.setDefaultPopupMenu(this.cboFieldType);
1029
        swingManager.setDefaultPopupMenu(this.cboGeometrySubtype);
1030
        swingManager.setDefaultPopupMenu(this.cboGeometryType);
1031
        swingManager.setDefaultPopupMenu(this.cboDataProfile);
1032

    
1033
//        swingManager.setDefaultPopupMenu(this.cboRelationToOneCodeName);
1034
//        swingManager.setDefaultPopupMenu(this.cboRelationToOneTableName);
1035

    
1036
//        swingManager.setDefaultPopupMenu(this.cboRelationToManyForeignFieldName);
1037
//        swingManager.setDefaultPopupMenu(this.cboRelationToManyTableName);
1038

    
1039
        swingManager.setDefaultPopupMenu(this.cboGroup);
1040
        swingManager.setDefaultPopupMenu(this.txtOrder);
1041
        swingManager.setDefaultPopupMenu(this.txtLabel);
1042
        swingManager.setDefaultPopupMenu(this.txtDescription);
1043
        swingManager.setDefaultPopupMenu(this.txtMinValue);
1044
        swingManager.setDefaultPopupMenu(this.txtMaxValue);
1045
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesLabel);
1046
        swingManager.setDefaultPopupMenu(this.txtAvailableValuesValue);
1047

    
1048
        this.toOneController = new ToOneController(
1049
                txtRelationToOneMyFieldName,
1050
                cboRelationToOneType, 
1051
                chkRelationToOneIsClosedList, 
1052
                cboRelationToOneTableName, 
1053
                cboRelationToOneCodeName, 
1054
                cboRelationToOneFormula, 
1055
                btnRelationToOneFormula,
1056
                btnRelationToOneFormulaBookmarks,
1057
                btnRelationToOneFormulaHistory
1058
        );
1059
        this.toManyController = new ToManyController(
1060
                cboRelationToManyType, 
1061
                cboRelationToManyMyFieldName, 
1062
                cboRelationToManyTableName, 
1063
                cboRelationToManyForeignFieldName, 
1064
                
1065
                txtRelationToManyExpression, 
1066
                
1067
                btnRelationToManyExpression,
1068
                btnRelationToManyExpressionHistory,
1069
                btnRelationToManyExpressionBookmarks
1070
        );
1071
        this.pickerIntervalEnd = swingManager.createDatePickerController(
1072
                this.txtIntervalEnd,
1073
                this.btnIntervalEnd
1074
        );
1075
        this.pickerIntervalStart = swingManager.createDatePickerController(
1076
                this.txtIntervalStart,
1077
                this.btnIntervalStart
1078
        );
1079
        this.pickerSize = evaluatorSwingManager.createCalculatorController(
1080
                this.txtSize, DataTypes.INT
1081
        );
1082
        this.pickerDisplaySize = evaluatorSwingManager.createCalculatorController(this.txtDisplaySize, DataTypes.INT
1083
        );
1084
        this.pickerPrecision = evaluatorSwingManager.createCalculatorController(
1085
                this.txtPrecision, DataTypes.INT
1086
        );
1087
        this.pickerScale = evaluatorSwingManager.createCalculatorController(
1088
                this.txtScale, DataTypes.INT
1089
        );
1090
        this.txtDefaultValue.getComponentPopupMenu().add(evaluatorSwingManager.createJExpressionBuilderAction(txtDefaultValue));
1091
        this.pickerOrder = evaluatorSwingManager.createCalculatorController(
1092
                this.txtOrder, DataTypes.INT
1093
        );
1094

    
1095
        this.availableValuesController = new AvailableValuesController(
1096
                lstAvailableValues,
1097
                txtAvailableValuesLabel,
1098
                txtAvailableValuesValue,
1099
                btnAvailableValuesAdd,
1100
                btnAvailableValuesUpdate,
1101
                btnAvailableValuesRemove,
1102
                btnAvailableValuesRemoveAll
1103
        );
1104
        
1105
        this.tagsController = new DefaultAggregateController<>(
1106
                this.tblAttrTagsItems,
1107
                this.btnAttrTagsModify,
1108
                this.btnAttrTagsDiscard,
1109
                this.btnAttrTagsAccept,
1110
                this.btnAttrTagsNew,
1111
                this.btnAttrTagsDelete,
1112
                new TagController(
1113
                        this.cboAttrTagsItemName,
1114
                        this.cboAttrTagsItemValue,
1115
                        this.lblAttrTagsItemNotesValue
1116
                )
1117
        );        
1118
        this.txtMinValue.setEnabled(false);
1119
        this.txtMaxValue.setEnabled(false);
1120

    
1121
        this.btnVirtualFieldGetter.setText("");
1122
        this.featureStoreElement = dataSwingManager.createFeatureStoreElement();
1123
        this.pickerVirtualFieldGetter = evaluatorSwingManager.createExpressionPickerController(
1124
                txtVirtualFieldGetter, btnVirtualFieldGetter, btnVirtualFieldBookmarksGetter, btnVirtualFieldHistoryGetter
1125
        );
1126
        this.pickerVirtualFieldGetter.getConfig().addElement(this.featureStoreElement);
1127
        this.pickerVirtualFieldSetter = evaluatorSwingManager.createExpressionPickerController(
1128
                txtVirtualFieldSetter, btnVirtualFieldSetter, btnVirtualFieldBookmarksSetter, btnVirtualFieldHistorySetter
1129
        );
1130
        this.pickerVirtualFieldSetter.getConfig().addElement(this.featureStoreElement);
1131
        
1132
        this.chkVirtualField.addChangeListener((ChangeEvent e) -> {
1133
          if (chkVirtualField.isSelected()) {
1134
            pickerVirtualFieldGetter.setEditable(mode==MODE_EDIT_ALL || mode==MODE_EDIT_ONLY_METADATA);
1135
            pickerVirtualFieldSetter.setEditable(false);
1136
          } else {
1137
            pickerVirtualFieldGetter.setEditable(false);
1138
            pickerVirtualFieldSetter.setEditable(false);
1139
          }
1140
        });
1141

    
1142
        this.pickerCRS = dataSwingManager.createProjectionPickerController(
1143
                this.txtCRS, this.btnCRS
1144
        );
1145

    
1146
        this.cboFieldType.addItemListener((ItemEvent e) -> {
1147
          SwingUtilities.invokeLater(() -> {
1148
            doFieldTypeChanged();
1149
          });
1150
        });
1151

    
1152
        this.pickerPrecision.addChangeListener((ChangeEvent e) -> {
1153
          doCheckPrecisionAndScale();
1154
        });
1155
        this.pickerScale.addChangeListener((ChangeEvent e) -> {
1156
          doCheckPrecisionAndScale();
1157
        });
1158

    
1159
        DefaultComboBoxModel dataProfilesModel = new DefaultComboBoxModel<>();
1160
        dataProfilesModel.addElement(new ListElement<>("", null));
1161
        for (DataProfile profile : DALLocator.getDataManager().getDataProfiles()) {
1162
            dataProfilesModel.addElement(new ListElement<>(profile.getName(), profile.getID()));
1163
        }
1164
        this.cboDataProfile.setModel(dataProfilesModel);
1165
        
1166
        this.btnFieldType.addActionListener((ActionEvent e) -> {
1167
          doDataTypeSelection();
1168
        });
1169
        
1170
        this.pickerValuesFilter = evaluatorSwingManager.createExpressionPickerController(
1171
                txtValuesFilter, btnValuesFilter, btnValuesFilterBookmarks, btnValuesFilterHistory
1172
        );
1173
        this.pickerValuesFilter.getConfig().addElement(this.featureStoreElement);
1174
        
1175
        this.chkIsAutomatic.addActionListener((ActionEvent e) -> {
1176
            doIsAutomaticChanged();
1177
        });
1178

    
1179
        this.rdbRelationNone.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1180
        this.rdbRelationToOne.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1181
        this.rdbRelationToMany.addItemListener((ItemEvent e) -> { doChangeRelationType(); });
1182

    
1183
        SwingUtilities.invokeLater( () -> {
1184
                splAttrTags.setDividerLocation(0.4);
1185
            }
1186
        );
1187
        
1188
    }
1189
    
1190
    private int getRelationType() {
1191
        if( this.rdbRelationNone.isSelected() ) {
1192
            return DynField.RELATION_TYPE_NONE;
1193
        } 
1194
        if( this.rdbRelationToOne.isSelected() ) {
1195
            return this.toOneController.getRelationType();
1196
        } 
1197
        if( this.rdbRelationToMany.isSelected() ) {
1198
            return this.toManyController.getRelationType();
1199
        }
1200
        return DynField.RELATION_TYPE_NONE;
1201
    }
1202

    
1203
    private void doChangeRelationType() {
1204
        boolean enabled;
1205
        switch(this.getMode() ) {
1206
            case MODE_EDIT_ONLY_METADATA:
1207
            case MODE_EDIT_ALL:
1208
                enabled = true;
1209
                break;
1210
            case MODE_SHOW_ONLY:
1211
            default:
1212
                enabled = false;
1213
                break;
1214
        }
1215

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

    
1344
    @Override
1345
    public EditableFeatureAttributeDescriptor fetch(EditableFeatureAttributeDescriptor descriptor) {
1346
        I18nManager i18n = ToolsLocator.getI18nManager();
1347
        try {
1348
            if (!this.chkAllowNulls.isSelected()) {
1349
                if (descriptor.allowNull()) {
1350
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1351
                    dialogs.messageDialog(
1352
                            i18n.getTranslation("_You_have_marked_not_allow_nulls") + "\n"
1353
                            + i18n.getTranslation("If_you_are_not_fully_aware_of_the_repercussions_of_this_it_is_advisable_to_allow_nulls"),
1354
                            null,
1355
                            i18n.getTranslation("_Warning"),
1356
                            JOptionPane.INFORMATION_MESSAGE,
1357
                            "AllowNullsInFeatureTypeEditing"
1358
                    );
1359
                }
1360
            }
1361
            descriptor.setDataType((int) ListElement.getSelected(this.cboFieldType));
1362
            int maxAttributeNameSize = getMaxAttributeSize(descriptor);
1363
            String attrName = this.txtFieldName.getText();
1364
            if(maxAttributeNameSize > -1 && StringUtils.length(attrName) > maxAttributeNameSize){
1365
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1366
                    dialogs.messageDialog(
1367
                            i18n.getTranslation("_Attribute_name_is_too_long") + "\n"
1368
                            + i18n.getTranslation("_max_size_allowed_for_this_table_is_{0}",new String[]{String.valueOf(maxAttributeNameSize)}),
1369
                            null,
1370
                            i18n.getTranslation("_Warning"),
1371
                            JOptionPane.WARNING_MESSAGE
1372
                    );
1373
                    return null;
1374
            }
1375
            descriptor.setName(attrName);
1376
            descriptor.setAllowNull(this.chkAllowNulls.isSelected());
1377
            descriptor.setIsPrimaryKey(this.chkIsPrimaryKey.isSelected());
1378
            descriptor.setIsAutomatic(this.chkIsAutomatic.isSelected());
1379
            descriptor.setIsReadOnly(this.chkIsReadOnly.isSelected());
1380
            descriptor.setIsIndexed(this.chkIsIndexed.isSelected());
1381
            descriptor.setSize(this.pickerSize.get(0));
1382
            descriptor.setDisplaySize(this.pickerDisplaySize.get(0));
1383
            descriptor.setPrecision(this.pickerPrecision.get(0));
1384
            descriptor.setScale(this.pickerScale.get(0));
1385
            
1386
            String defaultValue = this.txtDefaultValue.getText();
1387
            switch(this.mode) {
1388
                case MODE_EDIT_ONLY_METADATA:
1389
                    if( !ExpressionUtils.isDynamicText(defaultValue) ) {
1390
                        if( !StringUtils.equals(this.previousDefaultValue, defaultValue)) {
1391
                            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1392
                            dialogs.messageDialog(
1393
                                    i18n.getTranslation("_In_metadata_editing_only_mode_it_is_only_allowed_to_indicate_default_values_with_dynamic_expressions"),
1394
                                    null,
1395
                                    i18n.getTranslation("_Warning"),
1396
                                    JOptionPane.WARNING_MESSAGE
1397
                            );
1398
                            return null;
1399
                        }
1400
                    }
1401
                case MODE_EDIT_ALL:
1402
                case MODE_SHOW_ONLY:
1403
                    descriptor.setDefaultValue(defaultValue);
1404
                    
1405
            }
1406
            
1407
            descriptor.setDefaultFormat(this.txtDefaultFormat.getText());
1408
            descriptor.setDataProfileName((String) ListElement.getSelected(this.cboDataProfile));
1409
            switch (descriptor.getType()) {
1410
                case DataTypes.GEOMETRY:
1411
                    GeometryManager geomManager = GeometryLocator.getGeometryManager();
1412
                    GeometryType geomType = geomManager.getGeometryType(
1413
                            (int) ListElement.getSelected(this.cboGeometryType),
1414
                            (int) ListElement.getSelected(this.cboGeometrySubtype)
1415
                    );
1416
                    descriptor.setGeometryType(geomType);
1417
                    descriptor.setSRS(this.pickerCRS.get());
1418
                    break;
1419
                case DataTypes.INSTANT:
1420
                case DataTypes.INTERVAL:
1421
                case DataTypes.DATE:
1422
                case DataTypes.TIME:
1423
                case DataTypes.TIMESTAMP:
1424
                    // FIXME
1425
                    break;
1426
                default:
1427
                    break;
1428
            }
1429
            descriptor.setDataProfileName(
1430
                    StringUtils.defaultIfBlank((String) ListElement.getSelected(cboDataProfile), null)
1431
            );
1432

    
1433
            if (this.chkVirtualField.isSelected() ) { //&& this.pickerVirtualField.isEnabled()) {
1434
                Expression expression = this.pickerVirtualFieldGetter.get();
1435
                if (expression == null) {
1436
                    descriptor.setFeatureAttributeEmulator((String) null);
1437
                } else {
1438
                    DataManager dataManager = DALLocator.getDataManager();
1439
                    FeatureAttributeEmulatorExpression emulator = dataManager.createFeatureAttributeEmulatorExpression(
1440
                            descriptor.getFeatureType(),
1441
                            expression
1442
                    );
1443
                    if (!emulator.isValid()) {
1444
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1445
                        dialogs.messageDialog(
1446
                                i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")+"\n"
1447
                                + "\n"
1448
                                + emulator.getErrorMessage(),
1449
                                i18n.getTranslation("_Warning"),
1450
                                JOptionPane.WARNING_MESSAGE
1451
                        );
1452
                        return null;
1453
                    }
1454
                    for (String requiredFieldName : emulator.getRequiredFieldNames()) {
1455
                        if (StringUtils.equalsIgnoreCase(requiredFieldName, descriptor.getName())) {
1456
                            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1457
                            dialogs.messageDialog(
1458
                                    i18n.getTranslation("_The_expression_of_virtual_field_is_not_valid")
1459
                                    + "\n\n"
1460
                                    + i18n.getTranslation("_The_expression_contains_a_reference_to_itself"),
1461
                                    i18n.getTranslation("_Warning"),
1462
                                    JOptionPane.WARNING_MESSAGE
1463
                            );
1464
                            return null;
1465
                        }
1466
                    }
1467
                    List<String> undefinedSymbols = emulator.getUndefinedSymbols();
1468
                    if( undefinedSymbols!=null && !undefinedSymbols.isEmpty() ) {
1469
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1470
                        dialogs.messageDialog(
1471
                                i18n.getTranslation("_The_expression_has_undefined_symbols_at_this_moment")+"\n"
1472
                                + i18n.getTranslation("_This_may_not_be_a_mistake")+"\n"
1473
                                + "\n"
1474
                                + "("+StringUtils.join(undefinedSymbols,",")+")",
1475
                                i18n.getTranslation("_Warning"),
1476
                                JOptionPane.WARNING_MESSAGE
1477
                        );
1478
                    }
1479
                    //
1480
                    // No se porque esto de abajo no funciona.
1481
                    // Nunca se lanza la excepcion en el get(Feature) de
1482
                    // DefaultFeatureAttributeEmulatorExpression.
1483
                    //
1484
                    try {
1485
                        emulator.setEnableExceptions(true);
1486
//                        descriptor.setFeatureAttributeEmulator(emulator);
1487
                        emulator.get(this.sampleFeature);
1488
                    } catch(Throwable ex) {
1489
//                        emulator.setEnableExceptions(false);
1490
//                        descriptor.setFeatureAttributeEmulator(null);
1491
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1492
                        dialogs.messageDialog(
1493
                                i18n.getTranslation("_The_expression_can_not_be_evaluated_right_now_It_could_be_valid_when_all_changes_has_been_applied")+
1494
                                    "\n"+
1495
                                    ex.getMessage(), 
1496
                                i18n.getTranslation("_Warning"), 
1497
                                JOptionPane.WARNING_MESSAGE
1498
                        );
1499
//                        return null;
1500
                    } finally {
1501
                        emulator.setEnableExceptions(false);
1502
                    }
1503
                    descriptor.setFeatureAttributeEmulator(emulator);
1504
                }
1505
            }
1506
        } catch (Exception ex) {
1507
            LOGGER.warn("Can't retrieve information from user form.", ex);
1508
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1509
            dialogs.messageDialog(
1510
                    i18n.getTranslation("_Cant_retrieve_information_from_user_form")
1511
                    + "\n"
1512
                    + i18n.getTranslation("_See_log_for_details"),
1513
                    i18n.getTranslation("_Warning"),
1514
                    JOptionPane.WARNING_MESSAGE
1515
            );
1516
            return null;
1517
        }
1518

    
1519
        descriptor.setGroup(StringUtils.defaultIfBlank((String) this.cboGroup.getSelectedItem(), null));
1520
        descriptor.setOrder(this.pickerOrder.get(0));
1521
        descriptor.setHidden(this.chkHidden.isSelected());
1522
        descriptor.setLabel(StringUtils.defaultIfBlank(this.txtLabel.getText(), null));
1523
        descriptor.setDescription(StringUtils.defaultIfBlank(this.txtDescription.getText(), null));
1524

    
1525
//        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1526
//        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1527
        Expression valuesFilter = this.pickerValuesFilter.get();
1528
        
1529
        descriptor.setAvailableValues(this.availableValuesController.get());
1530

    
1531
        this.tagsController.getModel().fetch(descriptor.getTags());
1532

    
1533
        this.toOneController.fetch(descriptor);
1534
        this.toManyController.fetch(descriptor);
1535
        if( rdbRelationToOne.isSelected() ) {
1536
            descriptor.setRelationType(this.toOneController.getRelationType());
1537
            descriptor.getForeingKey().setForeingKey(true);
1538
        } else if( rdbRelationToMany.isSelected() ) {
1539
            descriptor.setRelationType(this.toManyController.getRelationType());
1540
            descriptor.getForeingKey().setForeingKey(false);
1541
        } else if( rdbRelationNone.isSelected() ) {
1542
            descriptor.setRelationType(DynField.RELATION_TYPE_NONE);
1543
            descriptor.getForeingKey().setForeingKey(false);
1544
        }
1545

    
1546

    
1547
        return descriptor;
1548
    }
1549

    
1550
    @Override
1551
    public void clean() {
1552
        this.txtDefaultValue.setText("");
1553
        this.txtDefaultFormat.setText("");
1554
        this.txtFieldName.setText("");
1555
//        this.pickerFieldName.set(null);
1556
        this.pickerIntervalEnd.set(null);
1557
        this.pickerIntervalStart.set(null);
1558
        this.pickerScale.set(null);
1559
        this.pickerSize.set(null);
1560
        this.pickerDisplaySize.set(null);
1561

    
1562
        this.chkAllowNulls.setSelected(false);
1563
        this.chkIsAutomatic.setSelected(false);
1564
        this.chkIsReadOnly.setSelected(false);
1565
        this.chkIsIndexed.setSelected(false);
1566
        this.chkIsPrimaryKey.setSelected(false);
1567

    
1568
        this.chkVirtualField.setSelected(false);
1569
        this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
1570
        this.pickerVirtualFieldGetter.setEditable(false);
1571
        this.pickerVirtualFieldGetter.set(null);
1572

    
1573
        ListElement.setSelected(cboGeometryType, null);
1574
        ListElement.setSelected(cboGeometrySubtype, null);
1575

    
1576
        ListElement.setSelected(cboFieldType, DataTypes.STRING);
1577

    
1578
        this.cboDataProfile.setSelectedIndex(-1);
1579

    
1580
        this.cboGroup.setSelectedIndex(-1);
1581
        this.pickerOrder.set(null);
1582
        this.chkHidden.setSelected(false);
1583
        this.txtLabel.setText("");
1584
        this.txtDescription.setText("");
1585
        this.txtMinValue.setText("");
1586
        this.txtMaxValue.setText("");
1587
        this.availableValuesController.clean();
1588
        this.tagsController.clean();
1589
        this.toOneController.clean();
1590
    }
1591

    
1592
    @Override
1593
    public void put(FeatureAttributeDescriptor descriptor) {
1594
        if (descriptor == null) {
1595
            this.clean();
1596
            return;
1597
        }
1598
        DataType dataType = descriptor.getDataType();
1599
        FeatureType featureType = descriptor.getFeatureType();
1600
        DefaultComboBoxModel groupModel = new DefaultComboBoxModel();
1601

    
1602
        if (featureType != null) {
1603
            FeatureStore store = descriptor.getFeatureType().getStore();
1604
            this.featureStoreElement.setFeatureStore(store);
1605
            if (store != null) {
1606
                this.sampleFeature = store.getSampleFeature();
1607
                if (sampleFeature != null) {
1608
                    FeatureSymbolTable featureSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable();
1609
                    featureSymbolTable.setFeature(sampleFeature);
1610
                    this.pickerVirtualFieldGetter.getConfig().setPreviewSymbolTable(featureSymbolTable.createParent());
1611
                    this.pickerValuesFilter.getConfig().setPreviewSymbolTable(featureSymbolTable.createParent());
1612
                }
1613
            }
1614
            List<String> groups = new ArrayList<>();
1615
            for (FeatureAttributeDescriptor otherdesc : featureType) {
1616
                String group = otherdesc.getGroup();
1617
                if (!StringUtils.isBlank(group) && !groups.contains(group)) {
1618
                    groups.add(group);
1619
                }
1620
            }
1621
            for (String group : groups) {
1622
                groupModel.addElement(group);
1623
            }
1624
        }
1625

    
1626
        this.previousDefaultValue = Objects.toString(descriptor.getDefaultValue(),"");
1627
        this.txtDefaultValue.setText(this.previousDefaultValue);
1628
        this.txtDefaultFormat.setText(Objects.toString(descriptor.getDefaultFormat(),""));
1629
        this.txtFieldName.setText(descriptor.getName());
1630
        RelativeInterval interval = (RelativeInterval) descriptor.getInterval();
1631
        if (interval == null) {
1632
            this.pickerIntervalEnd.set(null);
1633
            this.pickerIntervalStart.set(null);
1634
        } else {
1635
            this.pickerIntervalEnd.set(interval.getEnd().toDate());
1636
            this.pickerIntervalStart.set(interval.getStart().toDate());
1637
        }
1638
        if( dataType.supportSize() ) {
1639
          this.pickerSize.set(descriptor.getSize());
1640
        } else {
1641
          this.pickerSize.set(null);
1642
        }
1643
        this.pickerDisplaySize.set(descriptor.getDisplaySize());
1644
        if( dataType.supportPrecision() ) {
1645
          this.pickerPrecision.set(descriptor.getPrecision());
1646
        } else {
1647
          this.pickerPrecision.set(null);
1648
        }
1649
        if( dataType.supportScale()) {
1650
          this.pickerScale.set(descriptor.getScale());
1651
        } else {
1652
          this.pickerScale.set(null);
1653
        }
1654
        this.chkAllowNulls.setSelected(descriptor.allowNull());
1655
        this.chkIsAutomatic.setSelected(descriptor.isAutomatic());
1656
        this.chkIsReadOnly.setSelected(descriptor.isReadOnly());
1657
        this.chkIsIndexed.setSelected(descriptor.isIndexed());
1658
        this.chkIsPrimaryKey.setSelected(descriptor.isPrimaryKey());
1659

    
1660
        this.pickerVirtualFieldGetter.setEnabled(true);
1661
        FeatureAttributeEmulator attrEmulator = descriptor.getFeatureAttributeEmulator();
1662
        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
1663
            Expression expression = ((FeatureAttributeEmulatorExpression) attrEmulator).getExpression();
1664
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1665
            this.chkVirtualField.setSelected(true);
1666
            this.pickerVirtualFieldGetter.set(expression);
1667
        } else if (descriptor.isComputed()) {
1668
            this.chkVirtualField.setEnabled(false);
1669
            this.chkVirtualField.setSelected(true);
1670
            this.pickerVirtualFieldGetter.set(null);
1671
        } else {
1672
            this.chkVirtualField.setEnabled(this.mode==MODE_EDIT_ALL);
1673
            this.chkVirtualField.setSelected(false);
1674
            this.pickerVirtualFieldGetter.set(null);
1675
        }
1676
        this.pickerVirtualFieldGetter.setEnabled(true);
1677

    
1678
        Expression expression = descriptor.getAvailableValuesFilter();
1679
        this.pickerValuesFilter.set(expression);
1680

    
1681
        this.pickerCRS.set(descriptor.getSRS());
1682

    
1683
        if (descriptor.getGeomType() != null) {
1684
            ListElement.setSelected(cboGeometryType, descriptor.getGeomType().getType());
1685
            ListElement.setSelected(cboGeometrySubtype, descriptor.getGeomType().getSubType());
1686
        }
1687
        ListElement.setSelected(cboFieldType, dataType.getType());
1688
        if( ListElement.getSelected(cboFieldType)==null ) {
1689
          cboFieldType.addItem(new ListElement<>(dataType.getName(), dataType.getType()));
1690
          ListElement.setSelected(cboFieldType, dataType.getType());
1691
        }
1692
 
1693
        String profile = descriptor.getDataProfileName();
1694
        if (StringUtils.isBlank(profile)) {
1695
            this.cboDataProfile.setSelectedIndex(-1);
1696
        } else {
1697
            ListElement.setSelected(this.cboDataProfile, profile);
1698
        }
1699

    
1700
        this.cboGroup.setModel(groupModel);
1701
        this.cboGroup.setSelectedItem(StringUtils.defaultIfBlank(descriptor.getGroup(), ""));
1702
        this.pickerOrder.set(descriptor.getOder());
1703
        this.chkHidden.setSelected(descriptor.isHidden());
1704
        if (descriptor.hasLabel()) {
1705
            this.txtLabel.setText(StringUtils.defaultIfBlank(descriptor.getLabel(), ""));
1706
        } else {
1707
            this.txtLabel.setText("");
1708
        }
1709
        if (descriptor.hasDescription()) {
1710
            this.txtDescription.setText(StringUtils.defaultIfBlank(descriptor.getDescription(), ""));
1711
        } else {
1712
            this.txtDescription.setText("");
1713
        }
1714
        this.txtMinValue.setText(Objects.toString(descriptor.getMinValue(), ""));
1715
        this.txtMinValue.setText(Objects.toString(descriptor.getMaxValue(), ""));
1716
        if( descriptor.hasConstantAvailableValues() ) {
1717
          this.availableValuesController.set(descriptor.getAvailableValues());
1718
        } else {
1719
          this.availableValuesController.clean();
1720
        }
1721
        this.tagsController.setModel(new TagsModel(descriptor.getTags()));
1722

    
1723
        this.toOneController.put(descriptor);
1724
        this.toManyController.put(descriptor);
1725
        switch(descriptor.getRelationType()) {
1726
            case DynField.RELATION_TYPE_NONE:
1727
                this.rdbRelationNone.setSelected(true);
1728
                this.rdbRelationToOne.setSelected(false);
1729
                this.rdbRelationToMany.setSelected(false); 
1730
                  // No los borramos, solo quedan deshabilitados, para no peder la informacion que contengan
1731
//                this.toOneController.clean(); 
1732
//                this.toManyController.clean();
1733
                break;
1734
            case DynField.RELATION_TYPE_IDENTITY:
1735
            case DynField.RELATION_TYPE_COLLABORATION:
1736
                this.rdbRelationNone.setSelected(false);
1737
                this.rdbRelationToOne.setSelected(true);
1738
                this.rdbRelationToMany.setSelected(false);
1739
//                this.toManyController.clean();
1740
                break;
1741
            case DynField.RELATION_TYPE_COMPOSITION:
1742
            case DynField.RELATION_TYPE_AGGREGATE:
1743
                this.rdbRelationNone.setSelected(false);
1744
                this.rdbRelationToOne.setSelected(false);
1745
                this.rdbRelationToMany.setSelected(true);
1746
                this.pickerVirtualFieldGetter.setEnabled(false);
1747
//                this.pickerVirtualFieldGetter.set(null);
1748
//                this.toOneController.clean();
1749
                break;
1750
              
1751
        }
1752
        
1753
        if (!(descriptor instanceof EditableFeatureAttributeDescriptor)) {
1754
            this.setMode(FeatureTypePanel.MODE_SHOW_ONLY);
1755
        }
1756
        this.updateEditableStates();
1757
    }
1758

    
1759
    private DataType getDataType() {
1760
      Integer fieldType = (Integer) ListElement.getSelected(this.cboFieldType);
1761
      if (fieldType == null) {
1762
          return null;
1763
      }
1764
      DataType dataType = ToolsLocator.getDataTypesManager().get(fieldType);
1765
      return dataType;
1766
    }
1767

    
1768
    private void doFieldTypeChanged() {
1769
      try {
1770
        DataType dataType = this.getDataType();
1771

    
1772
        if( dataType.supportSize() ) {
1773
            this.pickerSize.setEditable(this.mode == MODE_EDIT_ALL);
1774
        } else {
1775
            this.pickerSize.setEditable(false);
1776
            this.pickerSize.set(null);
1777
        }        
1778
        this.pickerDisplaySize.setEditable(this.mode == MODE_EDIT_ALL);
1779
        if( dataType.supportPrecision() ) {
1780
          if( dataType.isPredefinedPrecision() ) {
1781
            this.pickerPrecision.setEditable(false);
1782
          } else {
1783
            this.pickerPrecision.setEditable(this.mode == MODE_EDIT_ALL);
1784
          }
1785
        } else {
1786
            this.pickerPrecision.setEditable(false);
1787
            this.pickerPrecision.set(null);
1788
        }        
1789
        if( dataType.supportScale()) {
1790
            this.pickerScale.setEditable(this.mode == MODE_EDIT_ALL);
1791
        } else {
1792
            this.pickerScale.setEditable(false);
1793
            this.pickerScale.set(null);
1794
        }        
1795
        switch (dataType.getType()) {
1796
          case DataTypes.GEOMETRY:
1797
            this.cboGeometryType.setEnabled(this.mode == MODE_EDIT_ALL);
1798
            this.cboGeometrySubtype.setEnabled(this.mode == MODE_EDIT_ALL);
1799
            this.pickerCRS.setEditable(this.mode == MODE_EDIT_ALL);
1800
            this.cboDateFormat.setEnabled(false);
1801
            this.pickerIntervalStart.setEditable(false);
1802
            this.pickerIntervalEnd.setEditable(false);
1803
            this.tabAditionalFields.setEnabledAt(1, true);
1804
            this.tabAditionalFields.setEnabledAt(2, false);
1805
            break;
1806
          case DataTypes.INSTANT:
1807
          case DataTypes.INTERVAL:
1808
          case DataTypes.DATE:
1809
          case DataTypes.TIME:
1810
          case DataTypes.TIMESTAMP:
1811
            this.cboGeometryType.setEnabled(false);
1812
            this.cboGeometrySubtype.setEnabled(false);
1813
            this.pickerCRS.setEditable(false);
1814
            this.cboDateFormat.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1815
            this.pickerIntervalStart.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1816
            this.pickerIntervalEnd.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
1817
            this.tabAditionalFields.setEnabledAt(1, false);
1818
            this.tabAditionalFields.setEnabledAt(2, true);
1819
            break;
1820
          case DataTypes.BYTE:
1821
          case DataTypes.INT:
1822
          case DataTypes.LONG:
1823
          case DataTypes.STRING:
1824
          case DataTypes.FILE:
1825
          case DataTypes.URL:
1826
          case DataTypes.URI:
1827
          case DataTypes.FLOAT:
1828
          case DataTypes.DOUBLE:
1829
          case DataTypes.DECIMAL:
1830
            this.cboGeometryType.setEnabled(false);
1831
            this.cboGeometrySubtype.setEnabled(false);
1832
            this.pickerCRS.setEditable(false);
1833
            this.cboDateFormat.setEnabled(false);
1834
            this.pickerIntervalStart.setEditable(false);
1835
            this.pickerIntervalEnd.setEditable(false);
1836
            this.tabAditionalFields.setEnabledAt(1, false);
1837
            this.tabAditionalFields.setEnabledAt(2, false);
1838
            break;
1839
          default:
1840
            this.cboGeometryType.setEnabled(false);
1841
            this.cboGeometrySubtype.setEnabled(false);
1842
            this.pickerCRS.setEditable(false);
1843
            this.cboDateFormat.setEnabled(false);
1844
            this.pickerIntervalStart.setEditable(false);
1845
            this.pickerIntervalEnd.setEditable(false);
1846
            this.tabAditionalFields.setEnabledAt(1, false);
1847
            this.tabAditionalFields.setEnabledAt(2, false);
1848
        }
1849
//        updateRelationState();
1850
        doChangeRelationType();
1851
      } catch (Exception ex) {
1852
        LOGGER.warn("Problems changing field type.", ex);
1853
      }
1854

    
1855
    }
1856
    
1857
    boolean isVirtualField() {
1858
        return this.chkVirtualField.isSelected();
1859
    }
1860

    
1861
    @Override
1862
    public int getMode() {
1863
        return this.mode;
1864
    }
1865
    
1866
    @Override
1867
    public void setMode(int mode) {
1868
        this.mode = mode;
1869
        updateEditableStates();
1870
    }
1871
    
1872
    private void updateEditableStates() {
1873
        DataType dataType = this.getDataType();
1874
        switch(this.mode) {
1875
            case MODE_EDIT_ALL:
1876
                this.txtDefaultValue.setEditable(!this.chkIsAutomatic.isSelected());
1877
                this.txtDefaultFormat.setEditable(true);
1878
                this.txtFieldName.setEditable(true);
1879
                this.pickerIntervalEnd.setEditable(true);
1880
                this.pickerIntervalStart.setEditable(true);
1881
                this.pickerSize.setEditable(dataType.supportSize());
1882
                this.pickerDisplaySize.setEditable(true);
1883
                if( dataType.isPredefinedPrecision() ) {
1884
                  this.pickerPrecision.setEditable(false);
1885
                  this.pickerPrecision.set(dataType.getMaxPrecision());
1886
                } else {
1887
                  this.pickerPrecision.setEditable(dataType.supportPrecision());
1888
                }
1889
                this.pickerScale.setEditable(dataType.supportScale());
1890
                this.cboDataProfile.setEnabled(true);
1891

    
1892
                this.chkAllowNulls.setEnabled(true);
1893
                this.chkIsAutomatic.setEnabled(true);
1894
                this.chkIsReadOnly.setEnabled(true);
1895
                this.chkIsIndexed.setEnabled(true);
1896
                if( this.isVirtualField() ) {
1897
                    this.chkIsPrimaryKey.setEnabled(false);
1898
                } else {
1899
                    this.chkIsPrimaryKey.setEnabled(true);
1900
                }
1901

    
1902
                this.chkVirtualField.setEnabled(true);
1903
                this.pickerVirtualFieldGetter.setEditable(true);
1904

    
1905
                this.cboDateFormat.setEnabled(true);
1906
                this.cboFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
1907
                this.btnFieldType.setEnabled(!this.chkIsAutomatic.isSelected());
1908
                this.cboGeometryType.setEnabled(true);
1909
                this.cboGeometrySubtype.setEnabled(true);
1910
                this.pickerCRS.setEditable(true);
1911

    
1912
                this.cboGroup.setEnabled(true);
1913
                this.pickerOrder.setEditable(true);
1914
                this.chkHidden.setEnabled(true);
1915
                this.txtLabel.setEditable(true);
1916
                this.txtDescription.setEditable(true);
1917
                this.txtMinValue.setEditable(false);
1918
                this.txtMaxValue.setEditable(false);
1919
                this.pickerValuesFilter.setEditable(true);
1920
                this.availableValuesController.setEditable(true);
1921
                this.tagsController.setEnabled(true);
1922
                break;
1923
            case MODE_EDIT_ONLY_METADATA:
1924
                if( this.chkVirtualField.isSelected() ) {
1925
                    this.txtFieldName.setEditable(true);
1926
                    this.pickerScale.setEditable(true);
1927
                    this.pickerSize.setEditable(true);
1928
                    this.pickerVirtualFieldGetter.setEditable(true);
1929
                    this.cboFieldType.setEnabled(true);
1930
                    this.btnFieldType.setEnabled(true);
1931
                    this.cboGeometryType.setEnabled(true);
1932
                    this.cboGeometrySubtype.setEnabled(true);
1933
                    this.pickerCRS.setEditable(true);
1934
                } else {
1935
                    this.txtFieldName.setEditable(false);
1936
                    this.pickerPrecision.setEditable(false);
1937
                    this.pickerScale.setEditable(false);
1938
                    this.pickerSize.setEditable(false);
1939
                    this.pickerVirtualFieldGetter.setEditable(false);
1940
                    this.cboFieldType.setEnabled(false);
1941
                    this.btnFieldType.setEnabled(false);
1942
                    this.cboGeometryType.setEnabled(false);
1943
                    this.cboGeometrySubtype.setEnabled(false);
1944
                    this.pickerCRS.setEditable(false);
1945
                }
1946

    
1947
                this.txtDefaultValue.setEditable(true);
1948
                this.txtDefaultFormat.setEditable(true);
1949
                this.pickerIntervalEnd.setEditable(true);
1950
                this.pickerIntervalStart.setEditable(true);
1951

    
1952
                this.cboDataProfile.setEnabled(true);
1953

    
1954
                this.pickerDisplaySize.setEditable(false);
1955
                this.chkAllowNulls.setEnabled(false);
1956
                this.chkIsAutomatic.setEnabled(false);
1957
                this.chkIsReadOnly.setEnabled(false);
1958
                this.chkIsIndexed.setEnabled(false);
1959
//                if( this.isVirtualField() ) {
1960
                    this.chkIsPrimaryKey.setEnabled(false);
1961
//                } else {
1962
//                    this.chkIsPrimaryKey.setEnabled(true);
1963
//                }
1964

    
1965
                this.chkVirtualField.setEnabled(false);
1966

    
1967
                this.cboDateFormat.setEnabled(true);
1968

    
1969
                this.cboGroup.setEnabled(true);
1970
                this.pickerOrder.setEditable(true);
1971
                this.chkHidden.setEnabled(true);
1972
                this.txtLabel.setEditable(true);
1973
                this.txtDescription.setEditable(true);
1974
                this.txtMinValue.setEditable(false);
1975
                this.txtMaxValue.setEditable(false);
1976
                this.pickerValuesFilter.setEditable(true);
1977
                this.availableValuesController.setEditable(true);
1978
                this.tagsController.setEnabled(true);
1979
                break;
1980
            case MODE_SHOW_ONLY:
1981
                this.txtDefaultValue.setEditable(false);
1982
                this.txtDefaultFormat.setEditable(false);
1983
                this.txtFieldName.setEditable(false);
1984
                this.pickerIntervalEnd.setEditable(false);
1985
                this.pickerIntervalStart.setEditable(false);
1986
                this.pickerPrecision.setEditable(false);
1987
                this.pickerScale.setEditable(false);
1988
                this.pickerSize.setEditable(false);
1989
                this.pickerDisplaySize.setEditable(false);
1990
                this.cboDataProfile.setEnabled(false);
1991

    
1992
                this.chkAllowNulls.setEnabled(false);
1993
                this.chkIsAutomatic.setEnabled(false);
1994
                this.chkIsReadOnly.setEnabled(false);
1995
                this.chkIsIndexed.setEnabled(false);
1996
                this.chkIsPrimaryKey.setEnabled(false);
1997

    
1998
                this.chkVirtualField.setEnabled(false);
1999
                this.pickerVirtualFieldGetter.setEditable(false);
2000

    
2001
                this.cboDateFormat.setEnabled(false);
2002
                this.cboFieldType.setEnabled(false);
2003
                this.btnFieldType.setEnabled(false);
2004
                this.cboGeometryType.setEnabled(false);
2005
                this.cboGeometrySubtype.setEnabled(false);
2006
                this.pickerCRS.setEditable(false);
2007

    
2008
                this.cboGroup.setEnabled(false);
2009
                this.pickerOrder.setEditable(false);
2010
                this.chkHidden.setEnabled(false);
2011
                this.txtLabel.setEditable(false);
2012
                this.txtDescription.setEditable(false);
2013
                this.txtMinValue.setEditable(false);
2014
                this.txtMaxValue.setEditable(false);
2015
                this.pickerValuesFilter.setEditable(false);
2016
                this.availableValuesController.setEditable(false);
2017
                this.tagsController.setEnabled(false);
2018
                break;
2019
        }
2020
        updateRelationState();
2021
    }
2022
    
2023
    private void updateRelationState() {
2024
        switch(this.mode) {
2025
            case MODE_EDIT_ALL:
2026
            case MODE_EDIT_ONLY_METADATA:
2027
                if( this.isVirtualField() ) {
2028
                    this.toOneController.setEditable(false);
2029
                    this.rdbRelationToOne.setEnabled(false);
2030
                    this.toManyController.setEditable(this.getDataType().getType() == DataTypes.LIST);
2031
                    this.rdbRelationToMany.setEnabled(this.getDataType().getType() == DataTypes.LIST);
2032
                } else {
2033
                    this.toOneController.setEditable(true);
2034
                    this.rdbRelationToOne.setEnabled(true);
2035
                    this.toManyController.setEditable(false);
2036
                    this.rdbRelationToMany.setEnabled(false);
2037
                }
2038
                this.rdbRelationNone.setEnabled(true);
2039
                if( this.rdbRelationToMany.isSelected() ) {
2040
                    this.pickerVirtualFieldGetter.setEnabled(false);
2041
//                    this.pickerVirtualFieldGetter.set(null);
2042
                }
2043
                break;
2044
            case MODE_SHOW_ONLY:
2045
            default:
2046
                this.toOneController.setEditable(false);
2047
                this.toManyController.setEditable(false);
2048
                this.rdbRelationToOne.setEnabled(false);
2049
                this.rdbRelationToMany.setEnabled(false);
2050
                this.rdbRelationNone.setEnabled(false);
2051
                if( this.rdbRelationToMany.isSelected() ) {
2052
                    this.pickerVirtualFieldGetter.setEnabled(false);
2053
//                    this.pickerVirtualFieldGetter.set(null);
2054
                }
2055
                break;
2056
        }
2057
    }
2058

    
2059
    private void doCheckPrecisionAndScale() {
2060
      DataType dataType = this.getDataType();
2061
      
2062
      Integer precision = this.pickerPrecision.get();
2063
      if( precision==null ) {
2064
        precision = 0;
2065
      }
2066
      Integer scale = this.pickerScale.get();
2067
      if( scale == null ) {
2068
        scale = 0;
2069
      }      
2070
      NumberPrecisionAndScale r = dataType.fixPrecisionAndScale(precision, scale);
2071
      if( r.getPrecision()!=precision || r.getScale()!=scale ) {
2072
        this.pickerPrecision.setWarning(true, "The precision/scale are not valids");
2073
        this.pickerScale.setWarning(true, "The precision/scale are not valids");
2074
      } else {
2075
        this.pickerPrecision.setWarning(false);
2076
        this.pickerScale.setWarning(false);
2077
      }
2078
    }
2079

    
2080
    @Override
2081
    public void setNameAsNew(FeatureType featureType) {
2082
        EditableFeatureType cloneFeatureType = featureType.getCopy().getEditable();
2083
        EditableFeatureAttributeDescriptor newAttributeDescriptor = cloneFeatureType.add(
2084
                cloneFeatureType.getNewFieldName(), 
2085
                DataTypes.STRING,
2086
                50);
2087
        this.put(newAttributeDescriptor);
2088
    }
2089

    
2090
    @Override
2091
    public String getName() {
2092
        return StringUtils.defaultIfBlank(this.txtFieldName.getText(), null);
2093
    }
2094

    
2095
    @Override
2096
    public ImageIcon loadImage(String imageName) {
2097
        return ToolsSwingUtils.loadImage(this, imageName);
2098
    }
2099

    
2100
  public static void selfRegister() {
2101
    boolean n = ToolsSwingUtils.registerIcons( 
2102
            DefaultFeatureAttributeSelectionPanel.class,
2103
            null,
2104
            LIBRARY_NAME,
2105
            new String[]{ "picker", "picker-datatype"}
2106
    );      
2107
  }
2108

    
2109
}