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 / DefaultFeatureTypePanel.java @ 47390

History | View | Annotate | Download (31.4 KB)

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

    
3
import org.gvsig.fmap.dal.swing.impl.featuretype.featurerule.FeatureRulesModel;
4
import org.gvsig.fmap.dal.swing.impl.featuretype.featurerule.FeatureRuleController;
5
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.TagController;
6
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel;
7
import java.awt.BorderLayout;
8
import java.awt.event.ActionEvent;
9
import java.awt.event.ActionListener;
10
import java.util.ArrayList;
11
import java.util.Objects;
12
import javax.swing.AbstractAction;
13
import static javax.swing.Action.ACTION_COMMAND_KEY;
14
import static javax.swing.Action.NAME;
15
import javax.swing.JComponent;
16
import javax.swing.JOptionPane;
17
import javax.swing.JSplitPane;
18
import javax.swing.SwingUtilities;
19
import javax.swing.event.ChangeListener;
20
import javax.swing.event.ListSelectionEvent;
21
import javax.swing.event.ListSelectionListener;
22
import javax.swing.event.TableModelEvent;
23
import javax.swing.table.AbstractTableModel;
24
import org.apache.commons.lang3.StringUtils;
25
import org.gvsig.configurableactions.ConfigurableActionsMamager;
26
import org.gvsig.expressionevaluator.ExpressionUtils;
27
import org.gvsig.featureform.swing.impl.DefaultJFeatureForm;
28
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
29
import org.gvsig.fmap.dal.feature.EditableFeatureType;
30
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
31
import org.gvsig.fmap.dal.feature.FeatureRule;
32
import org.gvsig.fmap.dal.feature.FeatureStore;
33
import org.gvsig.fmap.dal.feature.FeatureType;
34
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypeAttributePanel;
35
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.Tag;
36
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.TagsModel;
37
import org.gvsig.texteditor.JTextEditor;
38
import org.gvsig.tools.ToolsLocator;
39
import org.gvsig.tools.dataTypes.DataType;
40
import org.gvsig.tools.dataTypes.DataTypes;
41
import org.gvsig.tools.dynobject.DynStruct_v2;
42
import org.gvsig.tools.i18n.I18nManager;
43
import org.gvsig.tools.locator.ReferenceNotRegisteredException;
44
import org.gvsig.tools.swing.api.ChangeListenerHelper;
45
import org.gvsig.tools.swing.api.ToolsSwingLocator;
46
import org.gvsig.tools.swing.api.ToolsSwingManager;
47
import org.gvsig.tools.swing.api.ToolsSwingUtils;
48
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
49
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
50
import org.gvsig.tools.util.ToolsUtilLocator;
51
import org.slf4j.Logger;
52
import org.slf4j.LoggerFactory;
53

    
54
/**
55
 *
56
 * @author jjdelcerro
57
 */
58
public class DefaultFeatureTypePanel 
59
        extends DefaultFeatureTypePanelView
60
        implements FeatureTypePanel
61
    {
62

    
63
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureTypePanel.class);
64

    
65
    private FeatureType originalFeatureType = null;
66
    private JSplitPane splRules;
67
    private JSplitPane splAttributes;
68
    private FeatureRuleController ruleController;
69
    private JSplitPane splTags;
70

    
71
    private class FeatureTypeTableModel extends AbstractTableModel {
72

    
73
        private final FeatureType featureType;
74
        private final String[] columnNames = new String[] {
75
          "Name",
76
          "Type",
77
          "Size",
78
          "Precision",
79
          "Scale",
80
          "Default",
81
          "Calculated",
82
          "Key",
83
          "Nulls",
84
          "Hidden",
85
          "Relation"
86
        };
87
        private final Class[] columnClasses = new Class[] {
88
          String.class,
89
          String.class,
90
          Integer.class,
91
          Integer.class,
92
          Integer.class,
93
          String.class,
94
          Boolean.class,
95
          String.class,
96
          Boolean.class,
97
          Boolean.class,
98
          Integer.class
99
        };
100
        
101
        public FeatureTypeTableModel() {
102
            this.featureType = null;
103
        }
104
        
105
        public FeatureTypeTableModel(FeatureType featureType) {
106
            this.featureType = featureType;
107
        }
108
        
109
        @Override
110
        public int getRowCount() {
111
            if( this.featureType==null ) {
112
                return 0;
113
            }
114
            return this.featureType.size();
115
        }
116

    
117
        @Override
118
        public int getColumnCount() {
119
            if( this.featureType==null ) {
120
                return 0;
121
            }
122
            return this.columnNames.length;
123
        }
124

    
125
        @Override
126
        public String getColumnName(int columnIndex) {
127
            if( this.featureType==null ) {
128
                return "";
129
            }
130
            return this.columnNames[columnIndex];
131
        }
132

    
133
        @Override
134
        public Class<?> getColumnClass(int columnIndex) {
135
            if( this.featureType==null ) {
136
                return String.class;
137
            }
138
            return this.columnClasses[columnIndex];
139
        }
140

    
141
        @Override
142
        public boolean isCellEditable(int rowIndex, int columnIndex) {
143
            return false;
144
        }
145

    
146
        @Override
147
        public Object getValueAt(int rowIndex, int columnIndex) {
148
            if( this.featureType==null ) {
149
                return "";
150
            }
151
            FeatureAttributeDescriptor descriptor = this.featureType.getAttributeDescriptor(rowIndex);
152
            DataType dataType = descriptor.getDataType();
153
            switch(columnIndex) {
154
                case 0:
155
                    return descriptor.getName();
156
                case 1:
157
                    return descriptor.getDataTypeName();
158
                case 2:
159
                    if( dataType.supportSize() ) {
160
                      return descriptor.getSize();
161
                    }
162
                    return null;
163
                case 3:
164
                    if( dataType.supportPrecision()) {
165
                      return descriptor.getPrecision();
166
                    }
167
                    return null;
168
                case 4:
169
                    if( dataType.supportScale()) {
170
                      return descriptor.getScale();
171
                    }
172
                    if( dataType.isNumeric() ) {
173
                      return 0;
174
                    }
175
                    return null;
176
                case 5:
177
                    return Objects.toString(descriptor.getDefaultValue(),"");
178
                case 6:
179
                    return descriptor.isComputed();
180
                case 7:
181
                    if( descriptor.isPrimaryKey() ) {
182
                        return "Pk";
183
                    }
184
                    if( descriptor.isForeingKey() ) {
185
                        return "Fk";
186
                    }
187
                    return "";
188
                case 8:
189
                    return descriptor.allowNull();
190
                case 9:
191
                    return descriptor.isHidden();
192
                case 10:
193
                    return descriptor.getRelationType();
194
                default:
195
                    return "";
196
            }
197
        }
198

    
199
        @Override
200
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
201
        }
202
    
203
        public void fireUpdateEvent() {
204
            this.fireTableChanged(new TableModelEvent(this));
205
        }
206
    }
207
    
208
    public static class ViewAsJsonAction extends AbstractAction {
209
        
210
        @SuppressWarnings("OverridableMethodCallInConstructor")
211
        public ViewAsJsonAction() {
212
            I18nManager i18n = ToolsLocator.getI18nManager();
213

    
214
            this.putValue(NAME, i18n.getTranslation("_View_as_Json"));
215
            this.putValue(ACTION_COMMAND_KEY, "ViewAsJson");
216
        }
217

    
218
        @Override
219
        public Object getValue(String key) {
220
            if (NAME.equals(key)) {
221
                // Cuando se registra la accion aun no se han cargado las traducciones
222
                I18nManager i18n = ToolsLocator.getI18nManager();
223
                return i18n.getTranslation("_View_as_Json");
224
            }
225
            return super.getValue(key);
226
        }
227
        @Override
228
        public void actionPerformed(ActionEvent e) {
229
            DefaultFeatureTypePanel featureTypePanel = (DefaultFeatureTypePanel) e.getSource();
230
            FeatureType featureType = featureTypePanel.fetch(null);
231

    
232
            JTextEditor editor = ToolsSwingLocator.getTextEditorManager().createTextEditor();
233
            editor.setContents(featureType.toJsonBuilder().toString());
234

    
235
            WindowManager winmanager = ToolsSwingLocator.getWindowManager();
236
            winmanager.showWindow(
237
                    editor.asJComponent(), 
238
                    "FeatureType - "+featureType.getName(), 
239
                    WindowManager.MODE.WINDOW
240
            );
241
        }
242
        
243
    }
244

    
245
    public static class PreviewFormAction extends AbstractAction {
246
        
247
        @SuppressWarnings("OverridableMethodCallInConstructor")
248
        public PreviewFormAction() {
249
            I18nManager i18n = ToolsLocator.getI18nManager();
250

    
251
            this.putValue(NAME, i18n.getTranslation("_Preview_form"));
252
            this.putValue(ACTION_COMMAND_KEY, "PreviewForm");
253
        }
254

    
255
        @Override
256
        public Object getValue(String key) {
257
            if (NAME.equals(key)) {
258
                // Cuando se registra la accion aun no se han cargado las traducciones
259
                I18nManager i18n = ToolsLocator.getI18nManager();
260
                return i18n.getTranslation("_Preview_form");
261
            }
262
            return super.getValue(key);
263
        }
264
        @Override
265
        public void actionPerformed(ActionEvent e) {
266
            DefaultFeatureTypePanel featureTypePanel = (DefaultFeatureTypePanel) e.getSource();
267
            FeatureType featureType = featureTypePanel.fetch(null);
268

    
269
            DefaultJFeatureForm form = new DefaultJFeatureForm();
270
            form.setFeatureType(featureType);
271
            
272
            WindowManager winmanager = ToolsSwingLocator.getWindowManager();
273
            winmanager.showWindow(
274
                    form.asJComponent(), 
275
                    ToolsSwingUtils.makeTitle("Form preview",featureType.getName(),null), 
276
                    WindowManager.MODE.WINDOW
277
            );
278
        }
279
        
280
    }
281

    
282
    public static class ForceSynchronizeAction extends AbstractAction {
283
        
284
        @SuppressWarnings("OverridableMethodCallInConstructor")
285
        public ForceSynchronizeAction() {
286
            I18nManager i18n = ToolsLocator.getI18nManager();
287

    
288
            this.putValue(NAME, i18n.getTranslation("_Force_synchronize"));
289
            this.putValue(ACTION_COMMAND_KEY, "ForceSynchronize");
290
        }
291

    
292
        @Override
293
        public Object getValue(String key) {
294
            if (NAME.equals(key)) {
295
                // Cuando se registra la accion aun no se han cargado las traducciones
296
                I18nManager i18n = ToolsLocator.getI18nManager();
297
                return i18n.getTranslation("_Force_synchronize");
298
            }
299
            return super.getValue(key);
300
        }
301
        @Override
302
        public void actionPerformed(ActionEvent e) {
303
            DefaultFeatureTypePanel featureTypePanel = (DefaultFeatureTypePanel) e.getSource();
304
            featureTypePanel.featureType.forceStrongChanges();
305
        }
306
        
307
    }
308
    
309
    private DefaultFeatureAttributePanel descriptorPanel;
310
    private EditableFeatureType featureType;
311
    private int mode;
312
    private FeatureTypeTableModel tableModel;
313
    private FeatureStore store;
314
    private int currentRow;
315
    private boolean fieldSelectionAllowed;
316
    private AggregateController<Tag> tagsController;
317
    private ChangeListenerHelper changeListenerHelper;
318
    private AggregateController<FeatureRule> rulesController;
319
        
320
    public DefaultFeatureTypePanel() {
321
        this.mode = MODE_SHOW_ONLY;
322
        this.currentRow = -1;
323
        this.fieldSelectionAllowed = true;
324
        this.initComponents();
325
    }
326
    
327
    @SuppressWarnings("Convert2Lambda")
328
    private void initComponents() {
329
        ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
330
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
331
        JComponent c = cfgActionsManager.getConfigurableActionsComponent(CONFIGURABLE_PANEL_ID, this);
332
        this.pnlCfgActions.setLayout(new BorderLayout(0,0));
333
        this.pnlCfgActions.add(c, BorderLayout.CENTER);
334

    
335
        this.splRules = ToolsSwingUtils.createVerticalSplit(
336
                this.gridRules, 
337
                this.gridRulesTable, false,
338
                this.gridRulesDetail, true
339
        );
340
        this.splAttributes = ToolsSwingUtils.createVerticalSplit(
341
                this.gridAttributes,
342
                this.gridAttributesTable, false,
343
                this.gridAttributesDetail, true
344
        );
345
        this.splTags = ToolsSwingUtils.createVerticalSplit(
346
                this.gridTags,
347
                this.gridTagsItems, false,
348
                this.gridTagsItem, true
349
        );
350
        
351
        this.changeListenerHelper = swingManager.createChangeListenerHelper();
352
        
353
        swingManager.translate(this.btnDelete);
354
        swingManager.translate(this.btnFormFieldAccept);
355
        swingManager.translate(this.btnFormFieldDiscard);
356
        swingManager.translate(this.btnFormFieldModify);
357
        swingManager.translate(this.btnNew);
358
        swingManager.translate(this.lblLabel);
359
        swingManager.translate(this.lblDescription);
360
        swingManager.translate(this.lblTags);
361
        swingManager.translate(this.tabFeatureType);
362
        swingManager.translate(this.lblRulesDefaultRules);
363
        swingManager.translate(this.lblRulesCustomRules);
364
        swingManager.translate(this.chkRulesValidateFeatureBeforeInsert);
365
        swingManager.translate(this.chkRulesValidateFeaturesAtFinishEditing);
366
        swingManager.translate(this.lblRuleName);
367
        swingManager.translate(this.lblRuleDescription);
368
        swingManager.translate(this.lblRuleCheckAtFinishEditing);
369
        swingManager.translate(this.lblRuleCheckAtUpdate);
370
        swingManager.translate(this.lblRuleCheckAtEditFeature);
371
        swingManager.translate(this.lblRuleValidation);
372
        swingManager.translate(this.btnRulesNew);
373
        swingManager.translate(this.btnRulesDelete);
374
        swingManager.translate(this.btnRuleFormFieldModify);
375
        swingManager.translate(this.btnRuleFormFieldAccept);
376
        swingManager.translate(this.btnRuleFormFieldDiscard);
377
        swingManager.translate(this.btnRuleValidation);
378
        swingManager.translate(this.btnRuleValidationBookmarks);
379
        swingManager.translate(this.btnRuleValidationHistory);
380
        swingManager.translate(this.lblTagsItemName);
381
        swingManager.translate(this.lblTagsItemValue);
382
        swingManager.translate(this.lblTagsItemNotes);
383
                
384
        this.tableModel = new FeatureTypeTableModel();
385
        this.tblFields.setModel(this.tableModel);
386
        this.tblFields.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
387
            @Override
388
            public void valueChanged(ListSelectionEvent e) {
389
                if( e.getValueIsAdjusting() ) {
390
                    return;
391
                }
392
                doChangeFieldSelection();
393
            }
394
        });
395
        this.descriptorPanel = new DefaultFeatureAttributePanel();
396
        this.pnlField.setLayout(new BorderLayout());
397
        this.pnlField.add(this.descriptorPanel, BorderLayout.CENTER);
398
        this.descriptorPanel.setEnabled(false);
399

    
400
        this.btnFormFieldModify.addActionListener(new ActionListener() {
401
            @Override
402
            public void actionPerformed(ActionEvent e) {
403
                doFormFieldModify();
404
            }
405
        });
406
        this.btnFormFieldDiscard.addActionListener(new ActionListener() {
407
            @Override
408
            public void actionPerformed(ActionEvent e) {
409
                doFormFieldDiscard();
410
            }
411
        });
412
        this.btnFormFieldAccept.addActionListener(new ActionListener() {
413
            @Override
414
            public void actionPerformed(ActionEvent e) {
415
                doFormFieldAccept();
416
            }
417
        });
418
        this.btnNew.addActionListener(new ActionListener() {
419
            @Override
420
            public void actionPerformed(ActionEvent e) {
421
                doNewField();
422
            }
423
        });
424
        this.btnDelete.addActionListener(new ActionListener() {
425
            @Override
426
            public void actionPerformed(ActionEvent e) {
427
                doDeleteField();
428
            }
429
        });
430
        
431
        this.tagsController = new DefaultAggregateController<>(
432
                this.tblTagsItems,
433
                this.btnTagsModify,
434
                this.btnTagsDiscard,
435
                this.btnTagsAccept,
436
                this.btnTagsNew,
437
                this.btnTagsDelete,
438
                new TagController(
439
                        this.cboTagsItemName,
440
                        this.cboTagsItemValue,
441
                        this.lblTagsItemNotesValue
442
                )
443
        );
444

    
445
        this.ruleController = new FeatureRuleController(
446
                txtRuleName,
447
                txtRuleDescription,
448
                chkRuleCheckAtFinishEditing,
449
                chkRuleCheckAtUpdate,
450
                chkRuleCheckAtEditFeature,
451
                txtRuleValidation,
452
                btnRuleValidation,
453
                btnRuleValidationBookmarks, 
454
                btnRuleValidationHistory
455
        );
456
                
457
        this.rulesController = new DefaultAggregateController<>(
458
                this.tblRules, 
459
                this.btnRuleFormFieldModify, 
460
                this.btnRuleFormFieldDiscard, 
461
                this.btnRuleFormFieldAccept, 
462
                this.btnRulesNew, 
463
                this.btnRulesDelete,
464
                ruleController
465
        );
466

    
467
        if( this.tblFields.getRowCount()>0 ) {
468
            this.tblFields.getSelectionModel().setSelectionInterval(0, 0);
469
            doFormFieldPut();
470
        }
471
        this.tabFeatureType.setSelectedIndex(1);
472
        ToolsSwingUtils.ensureRowsCols(this, 30, 120, 45, 150);
473
        SwingUtilities.invokeLater( () -> {
474
                splAttributes.setDividerLocation(0.3);
475
            }
476
        );
477
        
478
    }
479
       
480
    private boolean doFormFieldFetch() {
481
        int row = this.tblFields.getSelectedRow();
482
        if (row < 0) {
483
            return true;
484
        }
485
        FeatureAttributeDescriptor descriptor = this.featureType.getAttributeDescriptor(row);
486
        int previousType = descriptor.getType();
487
        if (descriptor instanceof EditableFeatureAttributeDescriptor) {
488
            if (this.descriptorPanel.fetch((EditableFeatureAttributeDescriptor) descriptor) == null) {
489
                return false;
490
            }
491
            this.tableModel.fireUpdateEvent();
492
        }
493
        FeatureAttributeDescriptor oldDescriptor = null;
494
        if (this.originalFeatureType != null) {
495
            oldDescriptor = this.originalFeatureType.getAttributeDescriptor(descriptor.getName());
496
        }
497
        if (oldDescriptor != null
498
                && oldDescriptor.getDataType() != descriptor.getDataType()
499
                && previousType != descriptor.getType()) {
500
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
501
            I18nManager i18manager = ToolsLocator.getI18nManager();
502
            StringBuilder message = new StringBuilder();
503

    
504
            String[] messageArgs = new String[]{oldDescriptor.getName()};
505
            message.append(i18manager.getTranslation("_Already_existed_a_field_named_XfieldnameX_but_with_different_data_type", messageArgs));
506
            message.append(".\n");
507
            message.append(i18manager.getTranslation("_Values_of_data_will_try_to_coerce_to_this_type"));
508
            dialogs.messageDialog(
509
                    message.toString(),
510
                    null,
511
                    i18manager.getTranslation("_Values_will_change"),
512
                    JOptionPane.INFORMATION_MESSAGE,
513
                    "feature-type-manager-field-already-exist-in-previous-schema");
514
        }
515

    
516
        return true;
517
    }
518
    
519
    private void doFormFieldPut() {
520
        int row = this.tblFields.getSelectedRow();
521
        if( row<0 ) {
522
            return;
523
        }
524
        FeatureAttributeDescriptor descriptor = this.featureType.getAttributeDescriptor(row);
525
        this.currentRow = row;
526
        this.descriptorPanel.put(descriptor);
527
        updateButtonState();
528
        if( descriptor instanceof EditableFeatureAttributeDescriptor ) {
529
            this.btnFormFieldModify.setEnabled((this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA) && this.tblFields.getSelectedRowCount()==1);
530
        } else {
531
            this.btnFormFieldModify.setEnabled(false);
532
        }
533
    }
534
    
535
    private void updateButtonState() {
536
        this.descriptorPanel.setEnabled(true);
537
        this.descriptorPanel.setMode(MODE_SHOW_ONLY);
538
        this.btnFormFieldAccept.setEnabled(false);
539
        this.btnFormFieldDiscard.setEnabled(false);
540
        
541
        switch(this.mode) {
542
            case MODE_EDIT_ALL:
543
                this.btnDelete.setEnabled(true);
544
                this.btnFormFieldModify.setEnabled(true);
545
                this.btnNew.setEnabled(true);
546
                this.tagsController.setEnabled(true);
547
                this.rulesController.setEnabled(true);
548
                this.txtLabel.setEditable(true);
549
                this.txtDescription.setEditable(true);
550
                break;
551
            case MODE_EDIT_ONLY_METADATA:
552
                this.btnDelete.setEnabled(this.descriptorPanel.isVirtualField());
553
                this.btnFormFieldModify.setEnabled(true);
554
                this.btnNew.setEnabled(true);
555
                this.tagsController.setEnabled(true);
556
                this.rulesController.setEnabled(true);
557
                this.txtLabel.setEditable(true);
558
                this.txtDescription.setEditable(true);
559
                break;
560
            case MODE_SHOW_ONLY:
561
                this.btnDelete.setEnabled(false);
562
                this.btnFormFieldModify.setEnabled(false);
563
                this.btnNew.setEnabled(false);
564
                this.tagsController.setEnabled(false);
565
                this.rulesController.setEnabled(false);
566
                this.txtLabel.setEditable(false);
567
                this.txtDescription.setEditable(false);
568
                break;
569
        }
570
    }
571
    
572
    private void doFormFieldModify() {
573
        int row = this.tblFields.getSelectedRow();
574
        if( row<0 ) {
575
            return;
576
        }
577
        FeatureAttributeDescriptor descriptor = this.featureType.getAttributeDescriptor(row);
578
        this.descriptorPanel.put(descriptor);
579
        this.descriptorPanel.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
580
        this.btnFormFieldAccept.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
581
        this.btnFormFieldDiscard.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
582
        this.btnFormFieldModify.setEnabled(false);
583
        this.btnNew.setEnabled(false);
584
        this.btnDelete.setEnabled(false);
585
        if( descriptor instanceof EditableFeatureAttributeDescriptor ) {
586
            this.descriptorPanel.setMode(this.mode);
587
        } else {
588
            this.descriptorPanel.setMode(MODE_SHOW_ONLY);
589
        }
590
        this.fieldSelectionAllowed = false;
591
        this.changeListenerHelper.fireEvent();
592
    }
593
    
594
    @Override
595
    public boolean isEditing() {
596
        return btnFormFieldAccept.isEnabled() || this.rulesController.isEditing();
597
    }
598
    
599
    private void doFormFieldAccept() {
600
        int row = this.tblFields.getSelectedRow();
601
        if( row<0 ) {
602
            return;
603
        }
604
        if( doFormFieldFetch() ) {
605
            this.updateButtonState();
606
            this.tblFields.getSelectionModel().setSelectionInterval(row, row);
607
            this.tblFields.scrollRectToVisible(this.tblFields.getCellRect(row, 0, true));
608
            this.fieldSelectionAllowed = true;
609
        }
610
        this.changeListenerHelper.fireEvent();
611
    }
612
    
613
    private void doFormFieldDiscard() {
614
        doFormFieldPut();
615
        this.updateButtonState();
616
        this.fieldSelectionAllowed = true;
617
        this.changeListenerHelper.fireEvent();
618
    }
619

    
620
    private void doChangeFieldSelection() {
621
        int row = this.tblFields.getSelectedRow();
622
        if( row<0 ) {
623
            return;
624
        }
625
        if( !this.fieldSelectionAllowed ) {
626
            if( row !=this.currentRow ) {
627
                I18nManager i18n = ToolsLocator.getI18nManager();
628
                JOptionPane.showMessageDialog(
629
                    this, 
630
                    i18n.getTranslation("_Before_changing_field_accept_or_discard_the_changes"), 
631
                    i18n.getTranslation("_Warning"), 
632
                    JOptionPane.WARNING_MESSAGE
633
                );
634
                this.tblFields.getSelectionModel().setSelectionInterval(
635
                        this.currentRow, 
636
                        this.currentRow
637
                );
638
            }
639
            return;
640
        }
641
        doFormFieldPut();   
642
    }
643
    
644
    @Override
645
    public JComponent asJComponent() {
646
        return this;
647
    }
648

    
649
    @Override
650
    public int getMode() {
651
        return this.mode;
652
    }
653
    
654
    @Override
655
    public void setMode(int mode) {
656
        this.mode = mode;
657
        updateButtonState();
658
    }
659

    
660
    @Override
661
    public EditableFeatureType fetch(EditableFeatureType type) {
662
        if( type == null ) {
663
            type = (EditableFeatureType) this.featureType.getCopy();
664
        } else {
665
            type.removeAll();
666
            type.copyFrom(this.featureType);
667
        }
668
        type.setLabel(
669
            StringUtils.defaultIfBlank(this.txtLabel.getText(), null)
670
        );
671
        type.setDescription(
672
            StringUtils.defaultIfBlank(this.txtDescription.getText(), null)
673
        );
674
        this.tagsController.getModel().fetch(type.getTags());
675
        type.setCheckFeaturesAtInsert(this.chkRulesValidateFeatureBeforeInsert.isSelected());
676
        type.setCheckFeaturesAtFinishEditing(this.chkRulesValidateFeaturesAtFinishEditing.isSelected());
677
        return type;
678
    }
679

    
680
    @Override
681
    public void put(FeatureType type) {
682
        this.featureType = null;
683
        this.originalFeatureType = null;
684
        if (type == null) {
685
            this.store = null;
686
            this.rulesController.clean();
687
            this.tagsController.clean();
688
            this.chkRulesValidateFeatureBeforeInsert.setSelected(true);
689
            this.chkRulesValidateFeaturesAtFinishEditing.setSelected(false);
690
        } else {
691
            FeatureType ftypeToCompare = type.getOriginalFeatureType();
692
            if (ftypeToCompare == null) {
693
                ftypeToCompare = type;
694
            }
695
            this.originalFeatureType = ftypeToCompare.getCopy();
696
            this.featureType = (EditableFeatureType) type.getCopy();
697
            this.rulesController.setModel(new FeatureRulesModel(this.featureType.getRules()));
698
            this.chkRulesValidateFeatureBeforeInsert.setSelected(type.isCheckFeaturesAtInsert());
699
            this.chkRulesValidateFeaturesAtFinishEditing.setSelected(type.isCheckFeaturesAtFinishEditing());
700
            // Nos quedamos una referencia para evitar que se destruya, ya que
701
            // el featureType se guarda solo una WeakReference.
702
            this.store = type.getStore();
703
            this.ruleController.setFeatureStore(this.store);
704
            this.txtLabel.setText(
705
                    StringUtils.defaultIfBlank(((DynStruct_v2) type).getLabel(), "")
706
            );
707
            this.txtDescription.setText(
708
                    StringUtils.defaultIfBlank(((DynStruct_v2) type).getDescription(), "")
709
            );
710
            this.tagsController.setModel( new TagsModel(((DynStruct_v2) type).getTags()));
711
        }
712
        if( !(type instanceof EditableFeatureType) ) {
713
            this.setMode(MODE_SHOW_ONLY);
714
        }
715
        this.tableModel = new FeatureTypeTableModel(this.featureType);
716
        this.tblFields.setModel(this.tableModel);
717
        if( type!=null && !type.isEmpty() ) {
718
            this.tblFields.getSelectionModel().setSelectionInterval(0, 0);
719
        }
720
        SwingUtilities.invokeLater(() -> {
721
            this.splAttributes.setDividerLocation(0.3);
722
        });
723

    
724
        updateButtonState();
725
        doFormFieldPut();       
726
    }
727

    
728
    private void doNewField() {
729
        EditableFeatureType eft = (EditableFeatureType)this.featureType;
730
        EditableFeatureAttributeDescriptor descriptor = eft.add(
731
                this.featureType.getNewFieldName(), 
732
                DataTypes.STRING,
733
                50
734
        );
735
        if( this.mode == MODE_EDIT_ONLY_METADATA ) {
736
            descriptor.setFeatureAttributeEmulator(ExpressionUtils.createExpression("NULL"));
737
        }
738
        this.tableModel.fireUpdateEvent();
739
        int row = descriptor.getIndex();
740
        this.tblFields.getSelectionModel().addSelectionInterval(row,row);
741
        this.tblFields.scrollRectToVisible(this.tblFields.getCellRect(row, 0, true));
742
        updateButtonState();
743

    
744
        this.descriptorPanel.put(descriptor);
745
        this.descriptorPanel.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
746
        this.btnFormFieldAccept.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
747
        this.btnFormFieldDiscard.setEnabled(this.mode == MODE_EDIT_ALL || this.mode == MODE_EDIT_ONLY_METADATA);
748
        this.btnFormFieldModify.setEnabled(false);
749
        this.btnNew.setEnabled(false);
750
        this.btnDelete.setEnabled(false);
751
        if (descriptor instanceof EditableFeatureAttributeDescriptor) {
752
            if(this.mode == MODE_EDIT_ONLY_METADATA) {
753
                this.descriptorPanel.setMode(FeatureTypeAttributePanel.MODE_VIRTUAL_FIELD);
754
            } else {
755
                this.descriptorPanel.setMode(this.mode);
756
            }
757
        } else {
758
            this.descriptorPanel.setMode(MODE_SHOW_ONLY);
759
        }
760
        this.fieldSelectionAllowed = false;
761

    
762
        this.changeListenerHelper.fireEvent();
763
    }
764
    
765
    private void doDeleteField() {
766
        int row = this.tblFields.getSelectedRow();
767
        int[] rows = this.tblFields.getSelectedRows();
768
        ArrayList FeatureAttributeDescriptor;
769
        ArrayList<String> descriptors = new ArrayList<>();
770
        for (int rowDescriptor : rows) {
771
            if (rowDescriptor < 0) {
772
                continue;
773
            }
774
            descriptors.add(this.featureType.getAttributeDescriptor(rowDescriptor).getName());
775
        }
776
        for (String descriptor : descriptors) {
777
            ((EditableFeatureType)this.featureType).remove(descriptor);
778
        }
779
        this.tableModel.fireUpdateEvent();
780
        if( row >= this.tblFields.getRowCount()) {
781
            row = this.tblFields.getRowCount()-1;
782
        }
783
        this.tblFields.getSelectionModel().addSelectionInterval(row,row);
784
        updateButtonState();
785
        doFormFieldPut();       
786
        this.changeListenerHelper.fireEvent();
787
    }
788

    
789
    @Override
790
    public void addChangeListener(ChangeListener listener) {
791
        this.changeListenerHelper.addChangeListener(listener);
792
    }
793

    
794
    @Override
795
    public ChangeListener[] getChangeListeners() {
796
        return this.changeListenerHelper.getChangeListeners();
797
    }
798

    
799
    @Override
800
    public void removeChangeListener(ChangeListener listener) {
801
        this.changeListenerHelper.removeChangeListener(listener);
802
    }
803

    
804
    @Override
805
    public void removeAllChangeListener() {
806
        this.changeListenerHelper.removeAllChangeListener();
807
    }
808

    
809
    @Override
810
    public boolean hasChangeListeners() {
811
        return this.changeListenerHelper.hasChangeListeners();
812
    }
813
    
814
  public static void selfRegister() {
815
        ConfigurableActionsMamager cfgActionsManager;
816
        try {
817
            cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
818
        } catch(ReferenceNotRegisteredException ex) {
819
            return;
820
        }
821
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new ViewAsJsonAction());
822
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new PreviewFormAction());
823
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new ForceSynchronizeAction());        
824
  }
825
}