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

History | View | Annotate | Download (28.7 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 java.util.logging.Level;
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 org.apache.commons.io.FilenameUtils;
26
import org.apache.commons.lang.StringUtils;
27
import org.gvsig.expressionevaluator.Expression;
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.fmap.dal.DALLocator;
32
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
34
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
35
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
36
import org.gvsig.fmap.dal.feature.FeatureQuery;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.dal.feature.FeatureType;
39
import org.gvsig.fmap.dal.swing.DALSwingLocator;
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.Coercion;
45
import org.gvsig.tools.dataTypes.CoercionException;
46
import org.gvsig.tools.dataTypes.DataType;
47
import org.gvsig.tools.dataTypes.DataTypes;
48
import org.gvsig.tools.i18n.I18nManager;
49
import org.gvsig.tools.swing.api.ListElement;
50
import org.gvsig.tools.swing.api.ToolsSwingLocator;
51
import org.gvsig.tools.swing.api.ToolsSwingManager;
52
import org.gvsig.tools.swing.api.pickercontroller.DataTypePickerController;
53
import org.gvsig.tools.swing.api.windowmanager.Dialog;
54
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
55
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
56
import org.gvsig.tools.swing.icontheme.IconTheme;
57
import org.slf4j.Logger;
58
import org.slf4j.LoggerFactory;
59

    
60
/**
61
 *
62
 * @author jjdelcerro
63
 */
64
public class DefaultFeatureQueryCalculatedColumnsPanel
65
        extends DefaultFeatureQueryCalculatedColumnsPanelView
66
        implements FeatureQueryCalculatedColumnsPanel {
67
    
68
    private class AttributeListElement extends ListElement {
69
        
70
        public AttributeListElement(FeatureAttributeDescriptor value) {
71
            super(value.getLabel(), value);
72
        }
73
        
74
        @Override
75
        public String getLabel() {
76
            return ((FeatureAttributeDescriptor) this.getValue()).getName();
77
        }
78
        
79
    }
80

    
81
    private class ColumnController implements DocumentListener, ChangeListener, ActionListener {
82

    
83
        private final JTextComponent txtName;
84
        private final JComboBox cboDataType;
85
        private final JButton btnDataType;
86
        private final JButton btnExpressionBookmarks;
87
        private final JButton btnExpressionHistory;
88
        private final JButton btnExpression;
89
        private final JTextComponent txtExpression;
90
        private ExpressionPickerController expPicker;
91
        private DataTypePickerController pickerDataType;
92
        private boolean hasChanges;
93
        private final JTextComponent txtSize;
94
        private final JTextComponent txtPrecision;
95
        private final JTextComponent txtScale;
96
        
97
        private final Logger LOGGER = LoggerFactory.getLogger(ColumnController.class);
98
        private final JButton btnColumnMore;
99
        private final JButton btnApplyChanges;
100

    
101
        public ColumnController(
102
                JTextComponent txtName,
103
                JComboBox cboDataType,
104
                JButton btnDataType,
105
                JTextComponent txtExpression,
106
                JButton btnExpression,
107
                JButton btnExpressionHistory,
108
                JButton btnExpressionBookmarks,
109
                JTextComponent txtSize,
110
                JTextComponent txtPrecision,
111
                JTextComponent txtScale,
112
                JButton btnApplyChanges,
113
                JButton btnColumnMore
114
        ) {
115
            this.txtName = txtName;
116
            this.cboDataType = cboDataType;
117
            this.btnDataType = btnDataType;
118
            this.txtExpression = txtExpression;
119
            this.btnExpression = btnExpression;
120
            this.btnExpressionHistory = btnExpressionHistory;
121
            this.btnExpressionBookmarks = btnExpressionBookmarks;
122
            this.txtSize = txtSize;
123
            this.txtPrecision = txtPrecision;
124
            this.txtScale = txtScale;
125
            this.btnApplyChanges = btnApplyChanges;
126
            this.btnColumnMore = btnColumnMore;
127
            this.hasChanges = false;
128
            this.initComponents();
129
            this.setEnabled(false);
130
        }
131

    
132
        public void initComponents() {
133
            this.pickerDataType = ToolsSwingLocator.getToolsSwingManager().createDataTypePickerController(this.cboDataType, this.btnDataType, false);
134

    
135
            ExpressionEvaluatorSwingManager managerExpSwing = ExpressionEvaluatorSwingLocator.getManager();
136
            this.expPicker = managerExpSwing.createExpressionPickerController(
137
                    txtExpression,
138
                    btnExpression,
139
                    btnExpressionBookmarks,
140
                    btnExpressionHistory
141
            );
142
            
143

    
144
            this.txtName.getDocument().addDocumentListener(this);
145
            this.cboDataType.addActionListener(this);
146
            this.txtExpression.getDocument().addDocumentListener(this);
147
            this.txtSize.getDocument().addDocumentListener(this);
148
            this.txtPrecision.getDocument().addDocumentListener(this);
149
            this.txtScale.getDocument().addDocumentListener(this);
150
            //Todo: que el listener expresion lo gestion el picker
151
            
152
            this.cboDataType.addActionListener(new ActionListener() {
153
                @Override
154
                public void actionPerformed(ActionEvent ae) {
155
                    doSetDefaultValuesForDataType();
156
                    doEnabledByDataType();
157
                }
158
            });
159

    
160
        }
161
        
162
        public void doEnabledByDataType() {
163
            JComboBox comboBox = cboDataType;
164
            if (comboBox.getSelectedItem()==null) {
165
                return;
166
            }
167
            DataType dataType = (DataType) comboBox.getSelectedItem();
168
            txtSize.setEnabled(dataType.supportSize());
169
            txtPrecision.setEnabled(dataType.supportPrecision());
170
            txtScale.setEnabled(dataType.supportScale());
171
        }
172
        
173
        public void doSetDefaultValuesForDataType() {
174
            if (this.cboDataType.getSelectedItem()==null) {
175
                return;
176
            }
177
            DataType dataType = (DataType) this.cboDataType.getSelectedItem();
178
            if (dataType.supportSize() && txtSize.getText().isEmpty()) {
179
                txtSize.setText(String.valueOf(dataType.getDefaultSize()));
180
            } else if (!dataType.supportSize()) {
181
                txtSize.setText("");
182
            }
183

    
184
            if (dataType.supportPrecision() && txtPrecision.getText().isEmpty()) {
185
                txtPrecision.setText(String.valueOf(dataType.getDefaultPrecision()));
186
            } else if (!dataType.supportPrecision()) {
187
                txtPrecision.setText("");
188
            }
189

    
190
            if (dataType.supportScale() && txtScale.getText().isEmpty()) {
191
                txtScale.setText(String.valueOf(dataType.getDefaultScale()));
192
            } else if (!dataType.supportScale()) {
193
                txtScale.setText("");
194
            }
195
        }
196

    
197
        public boolean hasChanges() {
198
            return this.hasChanges;
199
        }
200

    
201
        public void setEnabled(boolean enabled) {
202
            this.txtName.setEnabled(enabled);
203
            this.expPicker.setEnabled(enabled);
204
            this.cboDataType.setEnabled(enabled);
205
            this.txtSize.setEnabled(enabled);
206
            this.txtPrecision.setEnabled(enabled);
207
            this.txtScale.setEnabled(enabled);
208
            this.btnApplyChanges.setEnabled(enabled);
209
            this.btnColumnMore.setEnabled(enabled);
210
        }
211

    
212
        public void clean() {
213
            this.txtName.setText("");
214
            this.expPicker.set(null);
215
            this.cboDataType.setSelectedIndex(0);
216
            this.txtSize.setText("");
217
            this.txtPrecision.setText("");
218
            this.txtScale.setText("");
219
            this.btnApplyChanges.setEnabled(false);
220
            this.btnColumnMore.setEnabled(false);
221
            this.hasChanges = false;
222

    
223
        }
224

    
225
        public void put(EditableFeatureAttributeDescriptor attr) {
226
            this.clean();
227
            this.txtName.setText(attr.getName());
228
            FeatureAttributeEmulatorExpression emu = (FeatureAttributeEmulatorExpression) attr.getFeatureAttributeEmulator();
229
            if (emu != null) {
230
                try {
231
                    this.expPicker.set(emu.getExpression().clone());
232
                } catch (CloneNotSupportedException ex) {
233
                    LOGGER.warn("Not able to clone expression.", ex);
234
                    throw new RuntimeException(ex);
235
                }
236
            }
237
            this.pickerDataType.set(attr.getDataType());
238
            Coercion coerceString = ToolsLocator.getDataTypesManager().get(DataTypes.STRING).getCoercion();
239
            txtSize.setEnabled(attr.getDataType().supportSize());
240
            if (attr.getDataType().supportSize()) {
241
                try {
242
                    this.txtSize.setText((String) coerceString.coerce(attr.getSize()));
243
                } catch (CoercionException ex) {
244
                    LOGGER.warn("Not able to coerce text to integer from size box.", ex);
245
                }
246
            }
247
            txtPrecision.setEnabled(attr.getDataType().supportPrecision());
248
            if (attr.getDataType().supportPrecision()) {
249
                try {
250
                    this.txtPrecision.setText((String) coerceString.coerce(attr.getPrecision()));
251
                } catch (CoercionException ex) {
252
                    LOGGER.warn("Not able to coerce text to integer from precision box.", ex);
253
                }
254
            }
255
            txtScale.setEnabled(attr.getDataType().supportScale());
256
            if (attr.getDataType().supportScale()) {
257
                try {
258
                    this.txtScale.setText((String) coerceString.coerce(attr.getScale()));
259
                } catch (CoercionException ex) {
260
                    LOGGER.warn("Not able to coerce text to integer from scale box.", ex);
261
                }
262
            }
263
//            doEnabledByDataType();
264
            this.btnColumnMore.setEnabled(true);
265
            this.btnApplyChanges.setEnabled(false);
266
            this.hasChanges = false;
267
        }
268

    
269
        public EditableFeatureAttributeDescriptor fetch(EditableFeatureAttributeDescriptor attr) {
270
            attr.setName(this.txtName.getText());
271
            try {
272
                Expression exp = this.expPicker.get();
273
                if (exp!=null) {
274
                    attr.setFeatureAttributeEmulator(exp.clone());
275
                } else {
276
                    attr.setFeatureAttributeEmulator((Expression) null);
277
                }
278
            } catch (CloneNotSupportedException ex) {
279
                LOGGER.warn("Not able to clone expression.", ex);
280
                throw new RuntimeException(ex);
281
            }
282
            attr.setDataType(this.pickerDataType.get());
283
            Coercion coerceInteger = ToolsLocator.getDataTypesManager().get(DataTypes.INTEGER).getCoercion();
284
            try {
285
                if (attr.getDataType().supportSize()) {
286
                    attr.setSize((int) coerceInteger.coerce(this.txtSize.getText()));
287
                }
288
            } catch (CoercionException ex) {
289
                LOGGER.warn("Not able to coerce text to integer from size box.", ex);
290
            }
291
            try {
292
                if (attr.getDataType().supportPrecision()) {
293
                    attr.setPrecision((int) coerceInteger.coerce(this.txtPrecision.getText()));
294
                }
295
            } catch (CoercionException ex) {
296
                LOGGER.warn("Not able to coerce text to integer from precision box.", ex);
297
            }
298
            try {
299
                if (attr.getDataType().supportScale()) {
300
                    attr.setScale((int) coerceInteger.coerce(this.txtScale.getText()));
301
                }
302
            } catch (CoercionException ex) {
303
                LOGGER.warn("Not able to coerce text to integer from scale box.", ex);
304
            }
305
            this.hasChanges = false;
306
            this.btnColumnMore.setEnabled(true);
307
            this.btnApplyChanges.setEnabled(false);
308
            return attr;
309
        }
310

    
311
        private void doHasChanges() {
312
            this.btnApplyChanges.setEnabled(true);
313
            this.hasChanges = true;
314
        }
315

    
316
        @Override
317
        public void insertUpdate(DocumentEvent de) {
318
            doHasChanges();
319
        }
320

    
321
        @Override
322
        public void removeUpdate(DocumentEvent de) {
323
            doHasChanges();
324
        }
325

    
326
        @Override
327
        public void changedUpdate(DocumentEvent de) {
328
            doHasChanges();
329
        }
330

    
331
        @Override
332
        public void stateChanged(ChangeEvent ce) {
333
            doHasChanges();
334
        }
335

    
336
        @Override
337
        public void actionPerformed(ActionEvent ae) {
338
            doHasChanges();
339
        }
340
        
341
        public void setStore(FeatureStore store) {
342
          DALSwingLocator.getManager().configureExpressionBuilder(expPicker, store);
343
//             FeatureStoreElement calculatedStoreElement = DALSwingLocator.getSwingManager()
344
//                    .createFeatureStoreElement();
345
//            calculatedStoreElement.setFeatureStore(store);
346
//            this.expPicker.removeAllSymbolTables();
347
//            this.expPicker.addElement(calculatedStoreElement);
348
        }
349
    }
350

    
351
    private ColumnController columnController;
352
    private FeatureStore store;
353
    private FeatureType featureType;
354
    private FeatureQuery query;
355
//    private JExpressionBuilder pckExpression;
356
    private static final String COLUMN_DEFAULT_NAME = "Field";
357
    private EditableFeatureAttributeDescriptor actualEditableAttribute;
358
    private DefaultListModel lstAttributesModel;
359
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureQueryCalculatedColumnsPanel.class);
360

    
361
    public DefaultFeatureQueryCalculatedColumnsPanel() {
362
        this.columnController = null;
363
        this.initComponents();
364
    }
365

    
366
    @Override
367
    public JComponent asJComponent() {
368
        return this;
369
    }
370

    
371
    @Override
372
    public ImageIcon loadImage(String imageName) {
373
        String name = FilenameUtils.getBaseName(imageName);
374
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
375
        if (theme.exists(name)) {
376
            return theme.get(name);
377
        }
378
        URL url = this.getClass().getResource(name + ".png");
379
        if (url == null) {
380
            return null;
381
        }
382
        return new ImageIcon(url);
383
    }
384

    
385
    @Override
386
    public void setStore(FeatureStore store) {
387
        try {
388
            this.featureType = store.getDefaultFeatureType();
389
            this.store = store;
390
            this.query = store.createFeatureQuery();
391
            this.columnController.setStore(store);
392
//            this.pckExpression = DALSwingLocator.getManager().createQueryFilterExpresion(store);
393
        } catch (DataException ex) {
394
            throw new RuntimeException("Can't assign store", ex);
395
        }
396
    }
397

    
398
    private void initComponents() {
399
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
400

    
401
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
402
        ImageIcon icon = theme.get("picker-datatype");
403
        this.btnColumnDataType.setIcon(icon);
404
        toolsSwingManager.translate(this.lblExpression);
405
        toolsSwingManager.translate(this.lblName);
406
        toolsSwingManager.translate(this.lblType);
407
        toolsSwingManager.translate(this.lblSize);
408
        toolsSwingManager.translate(this.lblPrecision);
409
        toolsSwingManager.translate(this.lblScale);
410
        toolsSwingManager.translate(this.btnApplyChanges);
411
        toolsSwingManager.translate(this.btnColumnMore);
412

    
413
        this.columnController = new ColumnController(
414
                this.txtColumnName,
415
                this.cboColumnDataType,
416
                this.btnColumnDataType,
417
                this.txtColumnExpression,
418
                this.btnColumnExpression,
419
                this.btnColumnExpressionHistory,
420
                this.btnColumnExpressionBookmarks,
421
                this.txtColumnSize,
422
                this.txtColumnPrecision,
423
                this.txtColumnScale,
424
                this.btnApplyChanges,
425
                this.btnColumnMore
426
        );
427
//        this.lstAttributes.setCellRenderer(new FeatureAttributeListCellRenderer());
428

    
429
        this.lstAttributes.addListSelectionListener((ListSelectionEvent e) -> {
430
            if (e.getValueIsAdjusting()) {
431
                return;
432
            }
433
            doSelectAttribute();
434
        });
435

    
436
        Dimension sz = this.getPreferredSize();
437
        if (sz.width < DEFAULT_WIDTH) {
438
            sz.width = DEFAULT_WIDTH;
439
        }
440
        if (sz.height < DEFAULT_HEIGHT) {
441
            sz.height = DEFAULT_HEIGHT;
442
        }
443
        this.setPreferredSize(sz);
444

    
445
        this.lstAttributesModel = new DefaultListModel<ListElement<EditableFeatureAttributeDescriptor>>();
446
//        this.lstAttributesModel = ToolsSwingLocator.getToolsSwingManager().createFilteredListModel();
447
        this.lstAttributes.setModel(lstAttributesModel);
448

    
449
        this.lstAttributes.setSelectionModel(new DefaultListSelectionModel() {
450

    
451
            @Override
452
            public void setSelectionInterval(int index0, int index1) {
453
                if (checkColumnControllerHasChangesWithUser()) {
454
                    super.setSelectionInterval(index0, index1);
455
                    doSelectAttribute();
456
                }
457
            }
458

    
459
        });
460

    
461
        this.btnAdd.addActionListener((ActionEvent e) -> {
462
            if (checkColumnControllerHasChangesWithUser()) {
463
                doAdd();
464
            }
465
        });
466

    
467
        this.btnRemove.addActionListener((ActionEvent e) -> {
468
            doRemove();
469
        });
470

    
471
        this.btnUp.addActionListener((ActionEvent e) -> {
472
            doUp(lstAttributes);
473
        });
474

    
475
        this.btnDown.addActionListener((ActionEvent e) -> {
476
            doDown(lstAttributes);
477
        });
478

    
479
        this.btnApplyChanges.addActionListener((ActionEvent e) -> {
480
            doApplyChanges();
481
        });
482

    
483
        this.btnColumnMore.addActionListener((ActionEvent e) -> {
484
            doColumnMore();
485
        });
486
        
487
    }
488

    
489
    private boolean checkColumnControllerHasChangesWithUser() {
490
        if (this.hasChanges()) {
491
            I18nManager i18n = ToolsLocator.getI18nManager();
492
            String message = i18n.getTranslation("_Changes_has_not_been_saved_Are_you_sure_you_want_to_continue");
493
            String title = i18n.getTranslation("_Changes_not_saved");
494
            int r = ToolsSwingLocator.getThreadSafeDialogsManager().confirmDialog(message, title,
495
                    JOptionPane.YES_NO_OPTION,
496
                    JOptionPane.QUESTION_MESSAGE);
497
            if (r == JOptionPane.NO_OPTION) {
498
                return false;
499
            }
500

    
501
        }
502
        return true;
503
    }
504

    
505
    private void doColumnMore() {
506
        if (this.columnController == null) {
507
            return;
508
        }
509
        final I18nManager i18n = ToolsLocator.getI18nManager();
510
        WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
511
        final FeatureTypeAttributePanel panel = DALSwingLocator.getSwingManager().createFeatureTypeAttributePanel();
512
        panel.clean();
513
//                panel.setNameAsNew(featureType);
514
        panel.put(actualEditableAttribute);
515
        panel.setMode(FeatureTypePanel.MODE_EDIT_ALL);
516
        final Dialog dialog = winManager.createDialog(
517
                panel.asJComponent(),
518
                i18n.getTranslation("_Extra_column"),
519
                null,
520
                WindowManager_v2.BUTTONS_OK_CANCEL
521
        );
522
        dialog.addActionListener(new ActionListener() {
523
            @Override
524
            public void actionPerformed(ActionEvent e) {
525
                if (dialog.getAction() != WindowManager_v2.BUTTONS_OK) {
526
                    return;
527
                }
528
                try {
529
                    FeatureAttributeDescriptor prev = actualEditableAttribute.getCopy();
530
                    panel.fetch(actualEditableAttribute);
531
                    columnController.put(actualEditableAttribute);
532
                    if (!prev.equals(actualEditableAttribute)) {
533
                        columnController.doHasChanges();
534
                    }
535
                } catch (Exception ex) {
536
                    LOGGER.warn("Problems updating feature descriptor.", ex);
537
                }
538
            }
539
        });
540
        dialog.show(WindowManager.MODE.DIALOG);
541
    }
542

    
543
    public boolean checkPanel(StringBuilder msg) {
544
        I18nManager i18n = ToolsLocator.getI18nManager();
545
        if (this.hasChanges()) {
546
            int r = ToolsSwingLocator.getThreadSafeDialogsManager().confirmDialog(
547
                    i18n.getTranslation("_Changes_has_not_been_saved_Are_you_sure_you_want_to_continue"),
548
                    i18n.getTranslation("_Changes_not_saved"),
549
                    JOptionPane.YES_NO_OPTION,
550
                    JOptionPane.QUESTION_MESSAGE);
551
            if (r == JOptionPane.NO_OPTION) {
552
                return false;
553
            }
554
        }
555
        return true;
556
    }
557

    
558
    public boolean hasChanges() {
559
        return this.columnController.hasChanges();
560
    }
561

    
562
    private void doSelectAttribute() {
563
        EditableFeatureAttributeDescriptor value = null;
564
        if (this.lstAttributes.getSelectedValue() != null) {
565
            ListElement<EditableFeatureAttributeDescriptor> selectedValue = (ListElement<EditableFeatureAttributeDescriptor>) this.lstAttributes.getSelectedValue();
566
            if (selectedValue != null) {
567
                value = selectedValue.getValue();
568
            }
569
        }
570
        if (value == null) {
571
            this.columnController.clean();
572
            this.columnController.setEnabled(false);
573
            this.actualEditableAttribute = null;
574

    
575
        } else {
576
            //EditableFeatureAttributeDescriptor value = node.getValue();
577
            this.actualEditableAttribute = value;
578
            columnController.setEnabled(true);
579
            columnController.put(value);
580
        }
581
    }
582

    
583
    @Override
584
    public FeatureQuery fetch(FeatureQuery query) {
585
        if (hasChanges()) {
586
            I18nManager i18n = ToolsLocator.getI18nManager();
587
            String message = i18n.getTranslation("_Changes_has_not_been_saved_Do_you_want_to_save_them_before_continue");
588
            String title = i18n.getTranslation("_Changes_not_saved");
589
            int r = ToolsSwingLocator.getThreadSafeDialogsManager().confirmDialog(message, title,
590
                    JOptionPane.YES_NO_OPTION,
591
                    JOptionPane.QUESTION_MESSAGE);
592
            if (r == JOptionPane.YES_NO_OPTION) {
593
                doApplyChanges();
594
            }
595
        }
596
        
597
        if (query == null) {
598
            return this.query.getCopy();
599
        }
600

    
601
        this.query.getExtraColumn().clear();
602
        for (int i = 0; i < lstAttributesModel.getSize(); i++) {
603
            ListElement<EditableFeatureAttributeDescriptor> element = (ListElement<EditableFeatureAttributeDescriptor>) lstAttributesModel.get(i);
604
            EditableFeatureAttributeDescriptor newExtraColumn = this.query.getExtraColumn().add(element.getValue().getName());
605
            newExtraColumn.copyFrom(element.getValue());
606
        }
607
        query.copyFrom(this.query);
608

    
609
        return query;
610
    }
611

    
612
    @Override
613
    public FeatureQuery fetch() {
614
        return this.fetch(null);
615
    }
616

    
617
    @Override
618
    public void put(FeatureQuery query) {
619
        this.query.copyFrom(query);
620
        addExtraColumns(this.query);
621
    }
622

    
623
    private void addExtraColumns(FeatureQuery query) {
624
        List<EditableFeatureAttributeDescriptor> cols = query.getExtraColumn().getColumns();
625
        if (cols == null || cols.isEmpty()) {
626
            return;
627
        }
628
        for (EditableFeatureAttributeDescriptor col : cols) {
629
            ListElement lf = new AttributeListElement(col);
630
            this.lstAttributesModel.addElement(lf);
631
        }
632
        if (this.lstAttributesModel.getSize() > 0) {
633
            this.lstAttributes.setSelectedIndex(0);
634
        }
635
    }
636

    
637
    public static void selfRegister() {
638
        String[][] iconNames = new String[][]{
639
            new String[]{"dalswing", "featurequery-column-add"},
640
            new String[]{"dalswing", "featurequery-column-remove"},
641
            new String[]{"dalswing", "featurequery-column-down"},
642
            new String[]{"dalswing", "featurequery-column-up"}
643
        };
644
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
645
        for (String[] icon : iconNames) {
646
            URL url = DefaultFeatureQueryOrderPanel.class.getResource(icon[1] + ".png");
647
            theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
648
        }
649
    }
650

    
651
    private void doAdd() {
652
        EditableFeatureAttributeDescriptor newAttr = DALLocator.getDataManager().createFeatureAttributeDescriptor();
653
        newAttr.setName(COLUMN_DEFAULT_NAME);
654
        newAttr.setDataType(DataTypes.STRING);
655
        if (newAttr.getDataType().supportSize()) {
656
            newAttr.setSize(newAttr.getDataType().getDefaultSize());
657
        }
658
        int id = 0;
659
        while (checkIfValueExistInModel(newAttr.getName(), this.lstAttributesModel)) {
660
            String newName = COLUMN_DEFAULT_NAME + "_" + id;
661
            id += 1;
662
            newAttr.setName(newName);
663
        }
664
        this.columnController.put(newAttr);
665
        this.columnController.setEnabled(true);
666

    
667
        this.lstAttributesModel.addElement(new AttributeListElement(newAttr));
668
        ListElement.setSelected(this.lstAttributes, newAttr);
669
        this.lstAttributes.revalidate();
670
        this.lstAttributes.repaint();
671
        this.actualEditableAttribute = newAttr;
672

    
673
    }
674

    
675
    private boolean checkIfValueExistInModel(String name, ListModel<ListElement<EditableFeatureAttributeDescriptor>> model) {
676
        for (int i = 0; i < model.getSize(); i++) {
677
            EditableFeatureAttributeDescriptor element = model.getElementAt(i).getValue();
678
            if (StringUtils.equals(element.getLabel(), name)) {
679
                return true;
680
            }
681

    
682
        }
683
        return false;
684
    }
685

    
686
    private void doRemove() {
687
        ListSelectionModel lsm = lstAttributes.getSelectionModel();
688
        DefaultListModel model = (DefaultListModel) this.lstAttributes.getModel();
689
        int actualIndex = lsm.getMinSelectionIndex();
690
        Object selectedValue = this.lstAttributes.getSelectedValue();
691
        this.lstAttributesModel.removeElement(selectedValue);
692
        this.columnController.clean();
693

    
694
        int size = model.size();
695
        if (size == 0) {
696
            //List is empty: disable delete, up, and down buttons.
697
        } else {
698
            //Adjust the selection.
699
            if (model.getSize() == 0) {
700

    
701
            } else if (actualIndex >= model.getSize()) {
702
                lstAttributes.setSelectedIndex(model.getSize() - 1);
703
            } else {
704
                lstAttributes.setSelectedIndex(actualIndex);
705
            }
706
        }
707
    }
708

    
709
    private void doApplyChanges() {
710
        this.columnController.fetch(this.actualEditableAttribute);
711
        this.lstAttributes.invalidate();
712
        this.lstAttributes.repaint();
713
    }
714

    
715
    private void doUp(JList lstColumns) {
716
        int moveMe = lstColumns.getSelectedIndex();
717
        if (moveMe != 0) {
718
            //not already at top
719
            swap(lstColumns, moveMe, moveMe - 1);
720
            lstColumns.setSelectedIndex(moveMe - 1);
721
            lstColumns.ensureIndexIsVisible(moveMe - 1);
722
        }
723
    }
724

    
725
    private void doDown(JList lstColumns) {
726
        int moveMe = lstColumns.getSelectedIndex();
727
        if (moveMe != lstColumns.getModel().getSize() - 1) {
728
            //not already at bottom
729
            swap(lstColumns, moveMe, moveMe + 1);
730
            lstColumns.setSelectedIndex(moveMe + 1);
731
            lstColumns.ensureIndexIsVisible(moveMe + 1);
732
        }
733
    }
734

    
735
    private void swap(JList lstColumns, int a, int b) {
736
        DefaultListModel model = (DefaultListModel) lstColumns.getModel();
737
        Object aObject = model.getElementAt(a);
738
        Object bObject = model.getElementAt(b);
739
        model.set(a, bObject);
740
        model.set(b, aObject);
741
    }
742
}