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 / featurequery / DefaultFeatureQueryCalculatedColumnsPanel.java @ 44794

History | View | Annotate | Download (20.6 KB)

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

    
3
import java.awt.Dimension;
4
import java.awt.event.ActionEvent;
5
import java.awt.event.ActionListener;
6
import java.net.URL;
7
import java.util.List;
8
import javax.swing.DefaultComboBoxModel;
9
import javax.swing.DefaultListModel;
10
import javax.swing.DefaultListSelectionModel;
11
import javax.swing.ImageIcon;
12
import javax.swing.JButton;
13
import javax.swing.JComboBox;
14
import javax.swing.JComponent;
15
import javax.swing.JList;
16
import javax.swing.JOptionPane;
17
import javax.swing.ListModel;
18
import javax.swing.ListSelectionModel;
19
import javax.swing.event.ChangeEvent;
20
import javax.swing.event.ChangeListener;
21
import javax.swing.event.DocumentEvent;
22
import javax.swing.event.DocumentListener;
23
import javax.swing.event.ListSelectionEvent;
24
import javax.swing.text.JTextComponent;
25
import jdk.nashorn.internal.parser.TokenType;
26
import org.apache.commons.io.FilenameUtils;
27
import org.apache.commons.lang.StringUtils;
28
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingLocator;
29
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
30
import org.gvsig.expressionevaluator.swing.ExpressionPickerController;
31
import org.gvsig.expressionevaluator.swing.JExpressionBuilder;
32
import org.gvsig.fmap.dal.DALLocator;
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
35
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
36
import org.gvsig.fmap.dal.feature.EditableFeatureType;
37
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
38
import org.gvsig.fmap.dal.feature.FeatureExtraColumn;
39
import org.gvsig.fmap.dal.feature.FeatureQuery;
40
import org.gvsig.fmap.dal.feature.FeatureStore;
41
import org.gvsig.fmap.dal.feature.FeatureType;
42
import org.gvsig.fmap.dal.swing.DALSwingLocator;
43
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryCalculatedColumnsPanel;
44
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypeAttributePanel;
45
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel;
46
import org.gvsig.fmap.dal.swing.impl.featuretype.DefaultFeatureAttributePanel;
47
import org.gvsig.fmap.dal.swing.impl.featuretype.FeatureAttributeListCellRenderer;
48
import org.gvsig.tools.ToolsLocator;
49
import org.gvsig.tools.dataTypes.DataType;
50
import org.gvsig.tools.dataTypes.DataTypes;
51
import org.gvsig.tools.i18n.I18nManager;
52
import org.gvsig.tools.swing.api.FilteredListModel;
53
import org.gvsig.tools.swing.api.ListElement;
54
import org.gvsig.tools.swing.api.ToolsSwingLocator;
55
import org.gvsig.tools.swing.api.ToolsSwingManager;
56
import org.gvsig.tools.swing.api.pickercontroller.DataTypePickerController;
57
import org.gvsig.tools.swing.api.windowmanager.Dialog;
58
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
59
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
60
import org.gvsig.tools.swing.icontheme.IconTheme;
61
import org.gvsig.tools.util.LabeledValueImpl;
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

    
65
/**
66
 *
67
 * @author jjdelcerro
68
 */
69
public class DefaultFeatureQueryCalculatedColumnsPanel
70
        extends DefaultFeatureQueryCalculatedColumnsPanelView
71
        implements FeatureQueryCalculatedColumnsPanel {
72

    
73
    private class ColumnController implements DocumentListener, ChangeListener, ActionListener {
74

    
75
        private final JTextComponent txtName;
76
        private final JComboBox cboDataType;
77
        private final JButton btnDataType;
78
        private final JButton btnExpressionBookmarks;
79
        private final JButton btnExpressionHistory;
80
        private final JButton btnExpression;
81
        private final JTextComponent txtExpression;
82
        private ExpressionPickerController expPicker;
83
        private DataTypePickerController pickerDataType;
84
        private boolean hasChanges;
85

    
86
        public ColumnController(
87
                JTextComponent txtName,
88
                JComboBox cboDataType,
89
                JButton btnDataType,
90
                JTextComponent txtExpression,
91
                JButton btnExpression,
92
                JButton btnExpressionHistory,
93
                JButton btnExpressionBookmarks
94
        ) {
95
            this.txtName = txtName;
96
            this.cboDataType = cboDataType;
97
            this.btnDataType = btnDataType;
98
            this.txtExpression = txtExpression;
99
            this.btnExpression = btnExpression;
100
            this.btnExpressionHistory = btnExpressionHistory;
101
            this.btnExpressionBookmarks = btnExpressionBookmarks;
102
            this.hasChanges = false;
103
            this.initComponents();
104
            this.setEnabled(false);
105
        }
106

    
107
        public void initComponents() {
108
            this.pickerDataType = ToolsSwingLocator.getToolsSwingManager().createDataTypePickerController(this.cboDataType, this.btnDataType, false);
109

    
110
            ExpressionEvaluatorSwingManager managerExpSwing = ExpressionEvaluatorSwingLocator.getManager();
111
            this.expPicker = managerExpSwing.createExpressionPickerController(
112
                    txtExpression,
113
                    btnExpression,
114
                    btnExpressionBookmarks,
115
                    btnExpressionHistory
116
            );
117

    
118
            this.txtName.getDocument().addDocumentListener(this);
119
            this.cboDataType.addActionListener(this);
120
            this.expPicker.removeAllChangeListener();
121
            this.expPicker.addChangeListener(new ChangeListener() {
122
                @Override
123
                public void stateChanged(ChangeEvent ce) {
124
                    if (!expPicker.isEmpty()) {
125
                        doHasChanges();
126
                    }
127
                }
128
            });
129

    
130
        }
131

    
132
        public boolean hasChanges() {
133
            return this.hasChanges;
134
        }
135

    
136
        public void setEnabled(boolean enabled) {
137
            this.txtName.setEnabled(enabled);
138
            this.expPicker.setEnabled(enabled);
139
            this.cboDataType.setEnabled(enabled);
140

    
141
        }
142

    
143
        public void clean() {
144
            this.txtName.setText("");
145
            this.expPicker.set(null);
146
            this.cboDataType.setSelectedIndex(0);
147

    
148
        }
149

    
150
        public void put(EditableFeatureAttributeDescriptor attr) {
151
            this.clean();
152
            this.txtName.setText(attr.getName());
153
            FeatureAttributeEmulatorExpression emu = (FeatureAttributeEmulatorExpression) attr.getFeatureAttributeEmulator();
154
            if (emu != null) {
155
                this.expPicker.set(emu.getExpression());
156
            }
157
            ListElement.setSelected(cboDataType, attr.getDataType());
158
            this.hasChanges = false;
159
        }
160

    
161
        public EditableFeatureAttributeDescriptor fetch(EditableFeatureAttributeDescriptor attr) {
162
            attr.setName(this.txtName.getText());
163
            attr.setFeatureAttributeEmulator(this.expPicker.get());
164
            attr.setDataType(this.pickerDataType.get());
165
            this.hasChanges = false;
166
            return attr;
167
        }
168

    
169
        private void doHasChanges() {
170
            this.hasChanges = true;
171
        }
172

    
173
        @Override
174
        public void insertUpdate(DocumentEvent de) {
175
            doHasChanges();
176
        }
177

    
178
        @Override
179
        public void removeUpdate(DocumentEvent de) {
180
            doHasChanges();
181
        }
182

    
183
        @Override
184
        public void changedUpdate(DocumentEvent de) {
185
            doHasChanges();
186
        }
187

    
188
        @Override
189
        public void stateChanged(ChangeEvent ce) {
190
            doHasChanges();
191
        }
192

    
193
        @Override
194
        public void actionPerformed(ActionEvent ae) {
195
            doHasChanges();
196
        }
197
    }
198

    
199
    private ColumnController columnController;
200
    private FeatureStore store;
201
    private FeatureType featureType;
202
    private FeatureQuery query;
203
    private JExpressionBuilder pckExpression;
204
    private static String COLUMN_DEFAULT_NAME = "Field";
205
    private EditableFeatureAttributeDescriptor actualEditableAttribute;
206
    private DefaultListModel lstAttributesModel;
207
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureQueryCalculatedColumnsPanel.class);
208

    
209
    public DefaultFeatureQueryCalculatedColumnsPanel() {
210
        this.columnController = null;
211
        this.initComponents();
212
    }
213

    
214
    @Override
215
    public JComponent asJComponent() {
216
        return this;
217
    }
218

    
219
    @Override
220
    public ImageIcon loadImage(String imageName) {
221
        String name = FilenameUtils.getBaseName(imageName);
222
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
223
        if (theme.exists(name)) {
224
            return theme.get(name);
225
        }
226
        URL url = this.getClass().getResource(name + ".png");
227
        if (url == null) {
228
            return null;
229
        }
230
        return new ImageIcon(url);
231
    }
232

    
233
    @Override
234
    public void setStore(FeatureStore store) {
235
        try {
236
            this.featureType = store.getDefaultFeatureType();
237
            this.store = store;
238
            this.query = store.createFeatureQuery();
239
            this.pckExpression = DALSwingLocator.getManager().createQueryFilterExpresion(store);
240
        } catch (DataException ex) {
241
            throw new RuntimeException("Can't assign store", ex);
242
        }
243
    }
244

    
245
    private void initComponents() {
246
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
247

    
248
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
249
        ImageIcon icon = theme.get("picker-datatype");
250
        this.btnColumnDataType.setIcon(icon);
251
        toolsSwingManager.translate(this.lblExpression);
252
        toolsSwingManager.translate(this.lblName);
253
        toolsSwingManager.translate(this.lblType);
254

    
255
        this.columnController = new ColumnController(
256
                this.txtColumnName,
257
                this.cboColumnDataType,
258
                this.btnColumnDataType,
259
                this.txtColumnExpression,
260
                this.btnColumnExpression,
261
                this.btnColumnExpressionHistory,
262
                this.btnColumnExpressionBookmarks
263
        );
264
//        this.lstAttributes.setCellRenderer(new FeatureAttributeListCellRenderer());
265

    
266
        this.lstAttributes.addListSelectionListener((ListSelectionEvent e) -> {
267
            if (e.getValueIsAdjusting()) {
268
                return;
269
            }
270
            doSelectAttribute();
271
        });
272

    
273
        Dimension sz = this.getPreferredSize();
274
        if (sz.width < DEFAULT_WIDTH) {
275
            sz.width = DEFAULT_WIDTH;
276
        }
277
        if (sz.height < DEFAULT_HEIGHT) {
278
            sz.height = DEFAULT_HEIGHT;
279
        }
280
        this.setPreferredSize(sz);
281

    
282
        this.lstAttributesModel = new DefaultListModel<ListElement<EditableFeatureAttributeDescriptor>>();
283
//        this.lstAttributesModel = ToolsSwingLocator.getToolsSwingManager().createFilteredListModel();
284
        this.lstAttributes.setModel(lstAttributesModel);
285

    
286
        this.lstAttributes.setSelectionModel(new DefaultListSelectionModel() {
287

    
288
            @Override
289
            public void setSelectionInterval(int index0, int index1) {
290
                if (checkColumnControllerHasChangesWithUser()) {
291
                    super.setSelectionInterval(index0, index1);
292
                    doSelectAttribute();
293
                }
294
            }
295

    
296
        });
297

    
298
        this.btnAdd.addActionListener((ActionEvent e) -> {
299
            doAdd();
300
        });
301

    
302
        this.btnRemove.addActionListener((ActionEvent e) -> {
303
            doRemove();
304
        });
305

    
306
        this.btnUp.addActionListener((ActionEvent e) -> {
307
            doUp(lstAttributes);
308
        });
309

    
310
        this.btnDown.addActionListener((ActionEvent e) -> {
311
            doDown(lstAttributes);
312
        });
313

    
314
        this.btnApplyChanges.addActionListener((ActionEvent e) -> {
315
            doApplyChanges();
316
        });
317

    
318
        this.btnColumnMore.addActionListener((ActionEvent e) -> {
319
            doColumnMore();
320
        });
321

    
322
    }
323

    
324
    private boolean checkColumnControllerHasChangesWithUser() {
325
        if (columnController.hasChanges()) {
326
            I18nManager i18n = ToolsLocator.getI18nManager();
327
            String message = i18n.getTranslation("_Changes_has_not_been_saved_Are_you_sure_you_want_to_continue");
328
            String title = i18n.getTranslation("_Changes_not_saved");
329
            int r = ToolsSwingLocator.getThreadSafeDialogsManager().confirmDialog(message, title,
330
                    JOptionPane.YES_NO_OPTION,
331
                    JOptionPane.QUESTION_MESSAGE);
332
            if (r == JOptionPane.NO_OPTION) {
333
                return false;
334
            }
335

    
336
        }
337
        return true;
338
    }
339

    
340
    private void doColumnMore() {
341
        if (this.columnController == null) {
342
            return;
343
        }
344
        final I18nManager i18n = ToolsLocator.getI18nManager();
345
        WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
346
        final FeatureTypeAttributePanel panel = DALSwingLocator.getSwingManager().createFeatureTypeAttributePanel();
347
        panel.clean();
348
//                panel.setNameAsNew(featureType);
349
        panel.put(actualEditableAttribute);
350
        panel.setMode(FeatureTypePanel.MODE_EDIT_ALL);
351
        final Dialog dialog = winManager.createDialog(
352
                panel.asJComponent(),
353
                i18n.getTranslation("_Extra_column"),
354
                null,
355
                WindowManager_v2.BUTTONS_OK_CANCEL
356
        );
357
        dialog.addActionListener(new ActionListener() {
358
            @Override
359
            public void actionPerformed(ActionEvent e) {
360
                if (dialog.getAction() != WindowManager_v2.BUTTONS_OK) {
361
                    return;
362
                }
363
                try {
364
                    FeatureAttributeDescriptor prev = actualEditableAttribute.getCopy();
365
                    panel.fetch(actualEditableAttribute);
366
                    columnController.put(actualEditableAttribute);
367
                    if (!prev.equals(actualEditableAttribute)) {
368
                        columnController.doHasChanges();
369
                    }
370
                } catch (Exception ex) {
371
                    LOGGER.warn("Problems updating feature descriptor.", ex);
372
                }
373
            }
374
        });
375
        dialog.show(WindowManager.MODE.DIALOG);
376
    }
377

    
378
    public boolean checkPanel(StringBuilder msg) {
379
        I18nManager i18n = ToolsLocator.getI18nManager();
380
        if (this.hasChanges()) {
381
            int r = ToolsSwingLocator.getThreadSafeDialogsManager().confirmDialog(
382
                    i18n.getTranslation("_Changes_has_not_been_saved_Are_you_sure_you_want_to_continue"),
383
                    i18n.getTranslation("_Changes_not_saved"),
384
                    JOptionPane.YES_NO_OPTION,
385
                    JOptionPane.QUESTION_MESSAGE);
386
            if (r == JOptionPane.NO_OPTION) {
387
                return false;
388
            }
389
        }
390
        return true;
391
    }
392

    
393
    public boolean hasChanges() {
394
        return this.columnController.hasChanges();
395
    }
396

    
397
    private void doSelectAttribute() {
398
        EditableFeatureAttributeDescriptor value = null;
399
        if (this.lstAttributes.getSelectedValue() != null) {
400
            ListElement<EditableFeatureAttributeDescriptor> selectedValue = (ListElement<EditableFeatureAttributeDescriptor>) this.lstAttributes.getSelectedValue();
401
            if (selectedValue != null) {
402
                value = selectedValue.getValue();
403
            }
404
        }
405
        if (value == null) {
406
            this.columnController.clean();
407
            this.columnController.setEnabled(false);
408
            this.actualEditableAttribute = null;
409

    
410
        } else {
411
            //EditableFeatureAttributeDescriptor value = node.getValue();
412
            this.actualEditableAttribute = value;
413
            columnController.put(value);
414
            columnController.setEnabled(true);
415
        }
416
    }
417

    
418
    @Override
419
    public FeatureQuery fetch(FeatureQuery query) {
420
        if (query == null) {
421
            return this.query.getCopy();
422
        }
423

    
424
        this.query.getExtraColumn().clear();
425
        for (int i = 0; i < lstAttributesModel.getSize(); i++) {
426
            ListElement<EditableFeatureAttributeDescriptor> element = (ListElement<EditableFeatureAttributeDescriptor>) lstAttributesModel.get(i);
427
            EditableFeatureAttributeDescriptor newExtraColumn = this.query.getExtraColumn().add(element.getValue().getName());
428
            newExtraColumn.copyFrom(element.getValue());
429
        }
430
        query.copyFrom(this.query);
431

    
432
        return query;
433
    }
434

    
435
    @Override
436
    public FeatureQuery fetch() {
437
        return this.fetch(null);
438
    }
439

    
440
    @Override
441
    public void put(FeatureQuery query) {
442
        this.query.copyFrom(query);
443
        addExtraColumns(this.query);
444
    }
445

    
446
    private void addExtraColumns(FeatureQuery query) {
447
        List<EditableFeatureAttributeDescriptor> cols = query.getExtraColumn().getColumns();
448
        if (cols == null || cols.isEmpty()) {
449
            return;
450
        }
451
        for (EditableFeatureAttributeDescriptor col : cols) {
452
            ListElement lf = new ListElement(col.getLabel(), col);
453
            this.lstAttributesModel.addElement(lf);
454
        }
455
        if (this.lstAttributesModel.getSize() > 0) {
456
            this.lstAttributes.setSelectedIndex(0);
457
        }
458
    }
459

    
460
    public static void selfRegister() {
461
        String[][] iconNames = new String[][]{
462
            new String[]{"dalswing", "common-applychanges"},
463
            new String[]{"dalswing", "common-more"},
464
            new String[]{"dalswing", "featurequery-column-add"},
465
            new String[]{"dalswing", "featurequery-column-remove"},
466
            new String[]{"dalswing", "featurequery-column-down"},
467
            new String[]{"dalswing", "featurequery-column-up"}
468
        };
469
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
470
        for (String[] icon : iconNames) {
471
            URL url = DefaultFeatureQueryOrderPanel.class.getResource(icon[1] + ".png");
472
            theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
473
        }
474
    }
475

    
476
    private void doAdd() {
477
        EditableFeatureAttributeDescriptor newAttr = DALLocator.getDataManager().createFeatureAttributeDescriptor();
478
        newAttr.setName(COLUMN_DEFAULT_NAME);
479
        newAttr.setDataType(DataTypes.STRING);
480
        int id = 0;
481
        while (checkIfValueExistInModel(newAttr.getName(), this.lstAttributesModel)) {
482
            String newName = COLUMN_DEFAULT_NAME + "_" + id;
483
            id += 1;
484
            newAttr.setName(newName);
485
        }
486
        this.columnController.put(newAttr);
487
        this.columnController.setEnabled(true);
488

    
489
        this.lstAttributesModel.addElement(new ListElement(newAttr.getName(), newAttr));
490
        ListElement.setSelected(this.lstAttributes, newAttr);
491
        this.actualEditableAttribute = newAttr;
492

    
493
    }
494

    
495
    private boolean checkIfValueExistInModel(String name, ListModel<ListElement<EditableFeatureAttributeDescriptor>> model) {
496
        for (int i = 0; i < model.getSize(); i++) {
497
            EditableFeatureAttributeDescriptor element = model.getElementAt(i).getValue();
498
            if (StringUtils.equals(element.getLabel(), name)) {
499
                return true;
500
            }
501

    
502
        }
503
        return false;
504
    }
505

    
506
    private void doRemove() {
507
        ListSelectionModel lsm = lstAttributes.getSelectionModel();
508
        DefaultListModel model = (DefaultListModel) this.lstAttributes.getModel();
509
        int actualIndex = lsm.getMinSelectionIndex();
510
        Object selectedValue = this.lstAttributes.getSelectedValue();
511
        this.lstAttributesModel.removeElement(selectedValue);
512
        this.columnController.clean();
513

    
514
        int size = model.size();
515
        if (size == 0) {
516
            //List is empty: disable delete, up, and down buttons.
517
        } else {
518
            //Adjust the selection.
519
            if (model.getSize() == 0) {
520

    
521
            } else if (actualIndex >= model.getSize()) {
522
                lstAttributes.setSelectedIndex(model.getSize() - 1);
523
            } else {
524
                lstAttributes.setSelectedIndex(actualIndex);
525
            }
526
        }
527
    }
528

    
529
    private void doApplyChanges() {
530
        this.columnController.fetch(this.actualEditableAttribute);
531
        this.lstAttributes.invalidate();
532
    }
533

    
534
    private void doUp(JList lstColumns) {
535
        int moveMe = lstColumns.getSelectedIndex();
536
        if (moveMe != 0) {
537
            //not already at top
538
            swap(lstColumns, moveMe, moveMe - 1);
539
            lstColumns.setSelectedIndex(moveMe - 1);
540
            lstColumns.ensureIndexIsVisible(moveMe - 1);
541
        }
542
    }
543

    
544
    private void doDown(JList lstColumns) {
545
        int moveMe = lstColumns.getSelectedIndex();
546
        if (moveMe != lstColumns.getModel().getSize() - 1) {
547
            //not already at bottom
548
            swap(lstColumns, moveMe, moveMe + 1);
549
            lstColumns.setSelectedIndex(moveMe + 1);
550
            lstColumns.ensureIndexIsVisible(moveMe + 1);
551
        }
552
    }
553

    
554
    private void swap(JList lstColumns, int a, int b) {
555
        DefaultListModel model = (DefaultListModel) lstColumns.getModel();
556
        Object aObject = model.getElementAt(a);
557
        Object bObject = model.getElementAt(b);
558
        model.set(a, bObject);
559
        model.set(b, aObject);
560
    }
561
}