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

History | View | Annotate | Download (20.4 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.DefaultListModel;
9
import javax.swing.DefaultListSelectionModel;
10
import javax.swing.ImageIcon;
11
import javax.swing.JButton;
12
import javax.swing.JComboBox;
13
import javax.swing.JComponent;
14
import javax.swing.JList;
15
import javax.swing.JOptionPane;
16
import javax.swing.ListModel;
17
import javax.swing.ListSelectionModel;
18
import javax.swing.event.ChangeEvent;
19
import javax.swing.event.ChangeListener;
20
import javax.swing.event.DocumentEvent;
21
import javax.swing.event.DocumentListener;
22
import javax.swing.event.ListSelectionEvent;
23
import javax.swing.text.JTextComponent;
24
import org.apache.commons.io.FilenameUtils;
25
import org.apache.commons.lang.StringUtils;
26
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingLocator;
27
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
28
import org.gvsig.expressionevaluator.swing.ExpressionPickerController;
29
import org.gvsig.expressionevaluator.swing.JExpressionBuilder;
30
import org.gvsig.fmap.dal.DALLocator;
31
import org.gvsig.fmap.dal.exception.DataException;
32
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
33
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
34
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
35
import org.gvsig.fmap.dal.feature.FeatureQuery;
36
import org.gvsig.fmap.dal.feature.FeatureStore;
37
import org.gvsig.fmap.dal.feature.FeatureType;
38
import org.gvsig.fmap.dal.swing.DALSwingLocator;
39
import org.gvsig.fmap.dal.swing.expressionevaluator.FeatureStoreElement;
40
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryCalculatedColumnsPanel;
41
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypeAttributePanel;
42
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel;
43
import org.gvsig.tools.ToolsLocator;
44
import org.gvsig.tools.dataTypes.DataTypes;
45
import org.gvsig.tools.i18n.I18nManager;
46
import org.gvsig.tools.swing.api.ListElement;
47
import org.gvsig.tools.swing.api.ToolsSwingLocator;
48
import org.gvsig.tools.swing.api.ToolsSwingManager;
49
import org.gvsig.tools.swing.api.pickercontroller.DataTypePickerController;
50
import org.gvsig.tools.swing.api.windowmanager.Dialog;
51
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
52
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
53
import org.gvsig.tools.swing.icontheme.IconTheme;
54
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
56

    
57
/**
58
 *
59
 * @author jjdelcerro
60
 */
61
public class DefaultFeatureQueryCalculatedColumnsPanel
62
        extends DefaultFeatureQueryCalculatedColumnsPanelView
63
        implements FeatureQueryCalculatedColumnsPanel {
64

    
65
    private class ColumnController implements DocumentListener, ChangeListener, ActionListener {
66

    
67
        private final JTextComponent txtName;
68
        private final JComboBox cboDataType;
69
        private final JButton btnDataType;
70
        private final JButton btnExpressionBookmarks;
71
        private final JButton btnExpressionHistory;
72
        private final JButton btnExpression;
73
        private final JTextComponent txtExpression;
74
        private ExpressionPickerController expPicker;
75
        private DataTypePickerController pickerDataType;
76
        private boolean hasChanges;
77

    
78
        public ColumnController(
79
                JTextComponent txtName,
80
                JComboBox cboDataType,
81
                JButton btnDataType,
82
                JTextComponent txtExpression,
83
                JButton btnExpression,
84
                JButton btnExpressionHistory,
85
                JButton btnExpressionBookmarks
86
        ) {
87
            this.txtName = txtName;
88
            this.cboDataType = cboDataType;
89
            this.btnDataType = btnDataType;
90
            this.txtExpression = txtExpression;
91
            this.btnExpression = btnExpression;
92
            this.btnExpressionHistory = btnExpressionHistory;
93
            this.btnExpressionBookmarks = btnExpressionBookmarks;
94
            this.hasChanges = false;
95
            this.initComponents();
96
            this.setEnabled(false);
97
        }
98

    
99
        public void initComponents() {
100
            this.pickerDataType = ToolsSwingLocator.getToolsSwingManager().createDataTypePickerController(this.cboDataType, this.btnDataType, false);
101

    
102
            ExpressionEvaluatorSwingManager managerExpSwing = ExpressionEvaluatorSwingLocator.getManager();
103
            this.expPicker = managerExpSwing.createExpressionPickerController(
104
                    txtExpression,
105
                    btnExpression,
106
                    btnExpressionBookmarks,
107
                    btnExpressionHistory
108
            );
109
            
110

    
111
            this.txtName.getDocument().addDocumentListener(this);
112
            this.cboDataType.addActionListener(this);
113
            this.txtExpression.getDocument().addDocumentListener(this);
114
            //Todo: que el listener expresion lo gestion el picker
115

    
116
        }
117

    
118
        public boolean hasChanges() {
119
            return this.hasChanges;
120
        }
121

    
122
        public void setEnabled(boolean enabled) {
123
            this.txtName.setEnabled(enabled);
124
            this.expPicker.setEnabled(enabled);
125
            this.cboDataType.setEnabled(enabled);
126

    
127
        }
128

    
129
        public void clean() {
130
            this.txtName.setText("");
131
            this.expPicker.set(null);
132
            this.cboDataType.setSelectedIndex(0);
133

    
134
        }
135

    
136
        public void put(EditableFeatureAttributeDescriptor attr) {
137
            this.clean();
138
            this.txtName.setText(attr.getName());
139
            FeatureAttributeEmulatorExpression emu = (FeatureAttributeEmulatorExpression) attr.getFeatureAttributeEmulator();
140
            if (emu != null) {
141
                this.expPicker.set(emu.getExpression());
142
            }
143
            ListElement.setSelected(cboDataType, attr.getDataType());
144
            this.hasChanges = false;
145
        }
146

    
147
        public EditableFeatureAttributeDescriptor fetch(EditableFeatureAttributeDescriptor attr) {
148
            attr.setName(this.txtName.getText());
149
            attr.setFeatureAttributeEmulator(this.expPicker.get());
150
            attr.setDataType(this.pickerDataType.get());
151
            this.hasChanges = false;
152
            return attr;
153
        }
154

    
155
        private void doHasChanges() {
156
            this.hasChanges = true;
157
        }
158

    
159
        @Override
160
        public void insertUpdate(DocumentEvent de) {
161
            doHasChanges();
162
        }
163

    
164
        @Override
165
        public void removeUpdate(DocumentEvent de) {
166
            doHasChanges();
167
        }
168

    
169
        @Override
170
        public void changedUpdate(DocumentEvent de) {
171
            doHasChanges();
172
        }
173

    
174
        @Override
175
        public void stateChanged(ChangeEvent ce) {
176
            doHasChanges();
177
        }
178

    
179
        @Override
180
        public void actionPerformed(ActionEvent ae) {
181
            doHasChanges();
182
        }
183
        
184
        public void setStore(FeatureStore store) {
185
             FeatureStoreElement calculatedStoreElement = DALSwingLocator.getSwingManager()
186
                    .createFeatureStoreElement();
187
            calculatedStoreElement.setFeatureStore(store);
188
            this.expPicker.removeAllSymbolTables();
189
            this.expPicker.addElement(calculatedStoreElement);
190
        }
191
    }
192

    
193
    private ColumnController columnController;
194
    private FeatureStore store;
195
    private FeatureType featureType;
196
    private FeatureQuery query;
197
    private JExpressionBuilder pckExpression;
198
    private static String COLUMN_DEFAULT_NAME = "Field";
199
    private EditableFeatureAttributeDescriptor actualEditableAttribute;
200
    private DefaultListModel lstAttributesModel;
201
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureQueryCalculatedColumnsPanel.class);
202

    
203
    public DefaultFeatureQueryCalculatedColumnsPanel() {
204
        this.columnController = null;
205
        this.initComponents();
206
    }
207

    
208
    @Override
209
    public JComponent asJComponent() {
210
        return this;
211
    }
212

    
213
    @Override
214
    public ImageIcon loadImage(String imageName) {
215
        String name = FilenameUtils.getBaseName(imageName);
216
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
217
        if (theme.exists(name)) {
218
            return theme.get(name);
219
        }
220
        URL url = this.getClass().getResource(name + ".png");
221
        if (url == null) {
222
            return null;
223
        }
224
        return new ImageIcon(url);
225
    }
226

    
227
    @Override
228
    public void setStore(FeatureStore store) {
229
        try {
230
            this.featureType = store.getDefaultFeatureType();
231
            this.store = store;
232
            this.query = store.createFeatureQuery();
233
            this.columnController.setStore(store);
234
            this.pckExpression = DALSwingLocator.getManager().createQueryFilterExpresion(store);
235
        } catch (DataException ex) {
236
            throw new RuntimeException("Can't assign store", ex);
237
        }
238
    }
239

    
240
    private void initComponents() {
241
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
242

    
243
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
244
        ImageIcon icon = theme.get("picker-datatype");
245
        this.btnColumnDataType.setIcon(icon);
246
        toolsSwingManager.translate(this.lblExpression);
247
        toolsSwingManager.translate(this.lblName);
248
        toolsSwingManager.translate(this.lblType);
249

    
250
        this.columnController = new ColumnController(
251
                this.txtColumnName,
252
                this.cboColumnDataType,
253
                this.btnColumnDataType,
254
                this.txtColumnExpression,
255
                this.btnColumnExpression,
256
                this.btnColumnExpressionHistory,
257
                this.btnColumnExpressionBookmarks
258
        );
259
//        this.lstAttributes.setCellRenderer(new FeatureAttributeListCellRenderer());
260

    
261
        this.lstAttributes.addListSelectionListener((ListSelectionEvent e) -> {
262
            if (e.getValueIsAdjusting()) {
263
                return;
264
            }
265
            doSelectAttribute();
266
        });
267

    
268
        Dimension sz = this.getPreferredSize();
269
        if (sz.width < DEFAULT_WIDTH) {
270
            sz.width = DEFAULT_WIDTH;
271
        }
272
        if (sz.height < DEFAULT_HEIGHT) {
273
            sz.height = DEFAULT_HEIGHT;
274
        }
275
        this.setPreferredSize(sz);
276

    
277
        this.lstAttributesModel = new DefaultListModel<ListElement<EditableFeatureAttributeDescriptor>>();
278
//        this.lstAttributesModel = ToolsSwingLocator.getToolsSwingManager().createFilteredListModel();
279
        this.lstAttributes.setModel(lstAttributesModel);
280

    
281
        this.lstAttributes.setSelectionModel(new DefaultListSelectionModel() {
282

    
283
            @Override
284
            public void setSelectionInterval(int index0, int index1) {
285
                if (checkColumnControllerHasChangesWithUser()) {
286
                    super.setSelectionInterval(index0, index1);
287
                    doSelectAttribute();
288
                }
289
            }
290

    
291
        });
292

    
293
        this.btnAdd.addActionListener((ActionEvent e) -> {
294
            doAdd();
295
        });
296

    
297
        this.btnRemove.addActionListener((ActionEvent e) -> {
298
            doRemove();
299
        });
300

    
301
        this.btnUp.addActionListener((ActionEvent e) -> {
302
            doUp(lstAttributes);
303
        });
304

    
305
        this.btnDown.addActionListener((ActionEvent e) -> {
306
            doDown(lstAttributes);
307
        });
308

    
309
        this.btnApplyChanges.addActionListener((ActionEvent e) -> {
310
            doApplyChanges();
311
        });
312

    
313
        this.btnColumnMore.addActionListener((ActionEvent e) -> {
314
            doColumnMore();
315
        });
316

    
317
    }
318

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

    
331
        }
332
        return true;
333
    }
334

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

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

    
388
    public boolean hasChanges() {
389
        return this.columnController.hasChanges();
390
    }
391

    
392
    private void doSelectAttribute() {
393
        EditableFeatureAttributeDescriptor value = null;
394
        if (this.lstAttributes.getSelectedValue() != null) {
395
            ListElement<EditableFeatureAttributeDescriptor> selectedValue = (ListElement<EditableFeatureAttributeDescriptor>) this.lstAttributes.getSelectedValue();
396
            if (selectedValue != null) {
397
                value = selectedValue.getValue();
398
            }
399
        }
400
        if (value == null) {
401
            this.columnController.clean();
402
            this.columnController.setEnabled(false);
403
            this.actualEditableAttribute = null;
404

    
405
        } else {
406
            //EditableFeatureAttributeDescriptor value = node.getValue();
407
            this.actualEditableAttribute = value;
408
            columnController.put(value);
409
            columnController.setEnabled(true);
410
        }
411
    }
412

    
413
    @Override
414
    public FeatureQuery fetch(FeatureQuery query) {
415
        if (query == null) {
416
            return this.query.getCopy();
417
        }
418

    
419
        this.query.getExtraColumn().clear();
420
        for (int i = 0; i < lstAttributesModel.getSize(); i++) {
421
            ListElement<EditableFeatureAttributeDescriptor> element = (ListElement<EditableFeatureAttributeDescriptor>) lstAttributesModel.get(i);
422
            EditableFeatureAttributeDescriptor newExtraColumn = this.query.getExtraColumn().add(element.getValue().getName());
423
            newExtraColumn.copyFrom(element.getValue());
424
        }
425
        query.copyFrom(this.query);
426

    
427
        return query;
428
    }
429

    
430
    @Override
431
    public FeatureQuery fetch() {
432
        return this.fetch(null);
433
    }
434

    
435
    @Override
436
    public void put(FeatureQuery query) {
437
        this.query.copyFrom(query);
438
        addExtraColumns(this.query);
439
    }
440

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

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

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

    
484
        this.lstAttributesModel.addElement(new ListElement(newAttr.getName(), newAttr));
485
        ListElement.setSelected(this.lstAttributes, newAttr);
486
        this.actualEditableAttribute = newAttr;
487

    
488
    }
489

    
490
    private boolean checkIfValueExistInModel(String name, ListModel<ListElement<EditableFeatureAttributeDescriptor>> model) {
491
        for (int i = 0; i < model.getSize(); i++) {
492
            EditableFeatureAttributeDescriptor element = model.getElementAt(i).getValue();
493
            if (StringUtils.equals(element.getLabel(), name)) {
494
                return true;
495
            }
496

    
497
        }
498
        return false;
499
    }
500

    
501
    private void doRemove() {
502
        ListSelectionModel lsm = lstAttributes.getSelectionModel();
503
        DefaultListModel model = (DefaultListModel) this.lstAttributes.getModel();
504
        int actualIndex = lsm.getMinSelectionIndex();
505
        Object selectedValue = this.lstAttributes.getSelectedValue();
506
        this.lstAttributesModel.removeElement(selectedValue);
507
        this.columnController.clean();
508

    
509
        int size = model.size();
510
        if (size == 0) {
511
            //List is empty: disable delete, up, and down buttons.
512
        } else {
513
            //Adjust the selection.
514
            if (model.getSize() == 0) {
515

    
516
            } else if (actualIndex >= model.getSize()) {
517
                lstAttributes.setSelectedIndex(model.getSize() - 1);
518
            } else {
519
                lstAttributes.setSelectedIndex(actualIndex);
520
            }
521
        }
522
    }
523

    
524
    private void doApplyChanges() {
525
        this.columnController.fetch(this.actualEditableAttribute);
526
        this.lstAttributes.invalidate();
527
    }
528

    
529
    private void doUp(JList lstColumns) {
530
        int moveMe = lstColumns.getSelectedIndex();
531
        if (moveMe != 0) {
532
            //not already at top
533
            swap(lstColumns, moveMe, moveMe - 1);
534
            lstColumns.setSelectedIndex(moveMe - 1);
535
            lstColumns.ensureIndexIsVisible(moveMe - 1);
536
        }
537
    }
538

    
539
    private void doDown(JList lstColumns) {
540
        int moveMe = lstColumns.getSelectedIndex();
541
        if (moveMe != lstColumns.getModel().getSize() - 1) {
542
            //not already at bottom
543
            swap(lstColumns, moveMe, moveMe + 1);
544
            lstColumns.setSelectedIndex(moveMe + 1);
545
            lstColumns.ensureIndexIsVisible(moveMe + 1);
546
        }
547
    }
548

    
549
    private void swap(JList lstColumns, int a, int b) {
550
        DefaultListModel model = (DefaultListModel) lstColumns.getModel();
551
        Object aObject = model.getElementAt(a);
552
        Object bObject = model.getElementAt(b);
553
        model.set(a, bObject);
554
        model.set(b, aObject);
555
    }
556
}