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

History | View | Annotate | Download (31.8 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.cresques.cts.IProjection;
26
import org.gvsig.configurableactions.ConfigurableActionsMamager;
27
import org.gvsig.expressionevaluator.ExpressionUtils;
28
import org.gvsig.featureform.swing.impl.DefaultJFeatureForm;
29
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
30
import org.gvsig.fmap.dal.feature.EditableFeatureType;
31
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
32
import org.gvsig.fmap.dal.feature.FeatureRule;
33
import org.gvsig.fmap.dal.feature.FeatureStore;
34
import org.gvsig.fmap.dal.feature.FeatureType;
35
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypeAttributePanel;
36
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.Tag;
37
import org.gvsig.fmap.dal.swing.impl.featuretype.tags.TagsModel;
38
import org.gvsig.texteditor.JTextEditor;
39
import org.gvsig.tools.ToolsLocator;
40
import org.gvsig.tools.dataTypes.DataType;
41
import org.gvsig.tools.dataTypes.DataTypes;
42
import org.gvsig.tools.dynobject.DynStruct_v2;
43
import org.gvsig.tools.i18n.I18nManager;
44
import org.gvsig.tools.locator.ReferenceNotRegisteredException;
45
import org.gvsig.tools.swing.api.ChangeListenerHelper;
46
import org.gvsig.tools.swing.api.ToolsSwingLocator;
47
import org.gvsig.tools.swing.api.ToolsSwingManager;
48
import org.gvsig.tools.swing.api.ToolsSwingUtils;
49
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
50
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
51
import org.gvsig.tools.util.ToolsUtilLocator;
52
import org.slf4j.Logger;
53
import org.slf4j.LoggerFactory;
54

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

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

    
66
    private FeatureType originalFeatureType = null;
67
    private JSplitPane splRules;
68
    private JSplitPane splAttributes;
69
    private FeatureRuleController ruleController;
70
    private JSplitPane splTags;
71
    private IProjection defaultProjection;
72

    
73
    private class FeatureTypeTableModel extends AbstractTableModel {
74

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

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

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

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

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

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

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

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

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

    
234
            JTextEditor editor = ToolsSwingLocator.getTextEditorManager().createTextEditor();
235
            editor.setContents(featureType.toJsonBuilder().toString());
236

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
727
        updateButtonState();
728
        doFormFieldPut();       
729
    }
730

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

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

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

    
792
    @Override
793
    public void addChangeListener(ChangeListener listener) {
794
        this.changeListenerHelper.addChangeListener(listener);
795
    }
796

    
797
    @Override
798
    public ChangeListener[] getChangeListeners() {
799
        return this.changeListenerHelper.getChangeListeners();
800
    }
801

    
802
    @Override
803
    public void removeChangeListener(ChangeListener listener) {
804
        this.changeListenerHelper.removeChangeListener(listener);
805
    }
806

    
807
    @Override
808
    public void removeAllChangeListener() {
809
        this.changeListenerHelper.removeAllChangeListener();
810
    }
811

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

    
829
    @Override
830
    public void setDefaultProjection(IProjection projection) {
831
        this.defaultProjection = projection;
832
        if( this.descriptorPanel!=null ) {
833
            this.descriptorPanel.setDefaultProjection(projection);
834
        }
835
    }
836
  
837
  
838
}