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

History | View | Annotate | Download (33 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.util.List;
7
import javax.swing.DefaultListModel;
8
import javax.swing.DefaultListSelectionModel;
9
import javax.swing.ImageIcon;
10
import javax.swing.JButton;
11
import javax.swing.JComboBox;
12
import javax.swing.JComponent;
13
import javax.swing.JList;
14
import javax.swing.JOptionPane;
15
import javax.swing.ListModel;
16
import javax.swing.ListSelectionModel;
17
import javax.swing.event.ChangeEvent;
18
import javax.swing.event.ChangeListener;
19
import javax.swing.event.DocumentEvent;
20
import javax.swing.event.DocumentListener;
21
import javax.swing.event.ListSelectionEvent;
22
import javax.swing.text.JTextComponent;
23
import org.apache.commons.lang.StringUtils;
24
import org.gvsig.expressionevaluator.Expression;
25
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingLocator;
26
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
27
import org.gvsig.expressionevaluator.swing.ExpressionPickerController;
28
import org.gvsig.fmap.dal.DALLocator;
29
import org.gvsig.fmap.dal.exception.DataException;
30
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
31
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
32
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
33
import org.gvsig.fmap.dal.feature.FeatureQuery;
34
import org.gvsig.fmap.dal.feature.FeatureStore;
35
import org.gvsig.fmap.dal.feature.FeatureType;
36
import org.gvsig.fmap.dal.swing.DALSwingLocator;
37
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryCalculatedColumnsPanel;
38
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypeAttributePanel;
39
import static org.gvsig.fmap.dal.swing.impl.DefaultDALSwingLibrary.LIBRARY_NAME;
40
import org.gvsig.tools.ToolsLocator;
41
import org.gvsig.tools.dataTypes.Coercion;
42
import org.gvsig.tools.dataTypes.CoercionException;
43
import org.gvsig.tools.dataTypes.DataType;
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.ToolsSwingUtils;
50
import org.gvsig.tools.swing.api.pickercontroller.DataTypePickerController;
51
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
52
import org.gvsig.tools.swing.api.windowmanager.Dialog;
53
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
54
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
55
import org.gvsig.tools.swing.icontheme.IconTheme;
56
import org.slf4j.Logger;
57
import org.slf4j.LoggerFactory;
58

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

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

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

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

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

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

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

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

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

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

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

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

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

    
222
        }
223

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

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

    
310
        private void doHasChanges() {
311
            this.btnColumnMore.setEnabled(false);
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.getConfig(), 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
        return ToolsSwingUtils.loadImage(this, imageName);
374
    }
375

    
376
    @Override
377
    public void setStore(FeatureStore store) {
378
        try {
379
            this.featureType = store.getDefaultFeatureType();
380
            this.store = store;
381
            this.query = store.createFeatureQuery();
382
            this.columnController.setStore(store);
383
//            this.pckExpression = DALSwingLocator.getManager().createQueryFilterExpresion(store);
384
        } catch (DataException ex) {
385
            throw new RuntimeException("Can't assign store", ex);
386
        }
387
    }
388

    
389
    private void initComponents() {
390
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
391

    
392
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
393
        ImageIcon icon = theme.get("picker-datatype");
394
        this.btnColumnDataType.setIcon(icon);
395
        toolsSwingManager.translate(this.lblExpression);
396
        toolsSwingManager.translate(this.lblName);
397
        toolsSwingManager.translate(this.lblType);
398
        toolsSwingManager.translate(this.lblSize);
399
        toolsSwingManager.translate(this.lblPrecision);
400
        toolsSwingManager.translate(this.lblScale);
401
        toolsSwingManager.translate(this.btnApplyChanges);
402
        toolsSwingManager.translate(this.btnColumnMore);
403

    
404
        this.columnController = new ColumnController(
405
                this.txtColumnName,
406
                this.cboColumnDataType,
407
                this.btnColumnDataType,
408
                this.txtColumnExpression,
409
                this.btnColumnExpression,
410
                this.btnColumnExpressionHistory,
411
                this.btnColumnExpressionBookmarks,
412
                this.txtColumnSize,
413
                this.txtColumnPrecision,
414
                this.txtColumnScale,
415
                this.btnApplyChanges,
416
                this.btnColumnMore
417
        );
418
//        this.lstAttributes.setCellRenderer(new FeatureAttributeListCellRenderer());
419

    
420
        this.lstAttributes.addListSelectionListener((ListSelectionEvent e) -> {
421
            if (e.getValueIsAdjusting()) {
422
                return;
423
            }
424
            doSelectAttribute();
425
        });
426

    
427
        Dimension sz = this.getPreferredSize();
428
        if (sz.width < DEFAULT_WIDTH) {
429
            sz.width = DEFAULT_WIDTH;
430
        }
431
        if (sz.height < DEFAULT_HEIGHT) {
432
            sz.height = DEFAULT_HEIGHT;
433
        }
434
        this.setPreferredSize(sz);
435

    
436
        this.lstAttributesModel = new DefaultListModel<ListElement<EditableFeatureAttributeDescriptor>>();
437
//        this.lstAttributesModel = ToolsSwingLocator.getToolsSwingManager().createFilteredListModel();
438
        this.lstAttributes.setModel(lstAttributesModel);
439

    
440
        this.lstAttributes.setSelectionModel(new DefaultListSelectionModel() {
441

    
442
            @Override
443
            public void setSelectionInterval(int index0, int index1) {
444
                if (checkColumnControllerHasChangesWithUser()) {
445
                    super.setSelectionInterval(index0, index1);
446
                    doSelectAttribute();
447
                }
448
            }
449

    
450
        });
451

    
452
        this.btnAdd.addActionListener((ActionEvent e) -> {
453
            if (checkColumnControllerHasChangesWithUser()) {
454
                doAdd();
455
            }
456
        });
457

    
458
        this.btnRemove.addActionListener((ActionEvent e) -> {
459
            doRemove();
460
        });
461

    
462
        this.btnUp.addActionListener((ActionEvent e) -> {
463
            doUp(lstAttributes);
464
        });
465

    
466
        this.btnDown.addActionListener((ActionEvent e) -> {
467
            doDown(lstAttributes);
468
        });
469

    
470
        this.btnApplyChanges.addActionListener((ActionEvent e) -> {
471
            doApplyChanges();
472
        });
473

    
474
        this.btnColumnMore.addActionListener((ActionEvent e) -> {
475
            doColumnMore();
476
        });
477
        
478
    }
479

    
480
    private boolean checkColumnControllerHasChangesWithUser() {
481
        if (this.hasChanges()) {
482
            I18nManager i18n = ToolsLocator.getI18nManager();
483
            String message = i18n.getTranslation("_Changes_has_not_been_saved_Are_you_sure_you_want_to_continue");
484
            String title = i18n.getTranslation("_Changes_not_saved");
485
            int r = ToolsSwingLocator.getThreadSafeDialogsManager().confirmDialog(message, title,
486
                    JOptionPane.YES_NO_OPTION,
487
                    JOptionPane.QUESTION_MESSAGE);
488
            if (r == JOptionPane.NO_OPTION) {
489
                return false;
490
            }
491

    
492
        }
493
        return true;
494
    }
495

    
496
    private void doColumnMore() {
497
        if (this.columnController == null) {
498
            return;
499
        }
500
        final I18nManager i18n = ToolsLocator.getI18nManager();
501
        WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
502
        final FeatureTypeAttributePanel panel = DALSwingLocator.getSwingManager().createFeatureTypeAttributePanel();
503
        panel.clean();
504
        panel.setFeatureType(featureType);
505
        panel.put(actualEditableAttribute);
506
        panel.setMode(FeatureTypeAttributePanel.MODE_VIRTUAL_FIELD);
507
        final Dialog dialog = winManager.createDialog(
508
                panel.asJComponent(),
509
                i18n.getTranslation("_Extra_column"),
510
                null,
511
                WindowManager_v2.BUTTONS_OK_CANCEL
512
        );
513
        dialog.addActionListener((ActionEvent e) -> {
514
            if (dialog.getAction() != WindowManager_v2.BUTTONS_OK) {
515
                return;
516
            }
517
            try {
518
                FeatureAttributeDescriptor prev = actualEditableAttribute.getCopy();
519
                panel.fetch(actualEditableAttribute);
520
                columnController.put(actualEditableAttribute);
521
                if (!prev.equals(actualEditableAttribute)) {
522
                    columnController.doHasChanges();
523
                }
524
            } catch (Exception ex) {
525
                LOGGER.warn("Problems updating feature descriptor.", ex);
526
            }
527
        });
528
        dialog.show(WindowManager.MODE.DIALOG);
529
    }
530

    
531
    public boolean checkPanel(StringBuilder msg) {
532
        I18nManager i18n = ToolsLocator.getI18nManager();
533
        if (this.hasChanges()) {
534
            int r = ToolsSwingLocator.getThreadSafeDialogsManager().confirmDialog(
535
                    i18n.getTranslation("_Changes_has_not_been_saved_Are_you_sure_you_want_to_continue"),
536
                    i18n.getTranslation("_Changes_not_saved"),
537
                    JOptionPane.YES_NO_OPTION,
538
                    JOptionPane.QUESTION_MESSAGE);
539
            if (r == JOptionPane.NO_OPTION) {
540
                return false;
541
            }
542
        }
543
        return true;
544
    }
545

    
546
    public boolean hasChanges() {
547
        return this.columnController.hasChanges();
548
    }
549

    
550
    private void doSelectAttribute() {
551
        int index = this.lstAttributes.getSelectedIndex();
552

    
553
        ListModel model = this.lstAttributesModel;
554
        this.btnUp.setEnabled(index >= 1);
555
        this.btnDown.setEnabled(index >= 0 && index < this.lstAttributesModel.getSize() - 1);
556
        
557
        EditableFeatureAttributeDescriptor value = null;
558
        if (this.lstAttributes.getSelectedValue() != null) {
559
            ListElement<EditableFeatureAttributeDescriptor> selectedValue = (ListElement<EditableFeatureAttributeDescriptor>) this.lstAttributes.getSelectedValue();
560
            if (selectedValue != null) {
561
                value = selectedValue.getValue();
562
            }
563
        }
564
        if (value == null) {
565
            this.columnController.clean();
566
            this.columnController.setEnabled(false);
567
            this.actualEditableAttribute = null;
568

    
569
        } else {
570
            //EditableFeatureAttributeDescriptor value = node.getValue();
571
            this.actualEditableAttribute = value;
572
            columnController.setEnabled(true);
573
            columnController.put(value);
574
        }
575
    }
576

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

    
595
        this.query.getExtraColumn().clear();
596
        for (int i = 0; i < lstAttributesModel.getSize(); i++) {
597
            ListElement<EditableFeatureAttributeDescriptor> element = (ListElement<EditableFeatureAttributeDescriptor>) lstAttributesModel.get(i);
598
            EditableFeatureAttributeDescriptor newExtraColumn = this.query.getExtraColumn().add(element.getValue().getName(), element.getValue().getType());
599
            newExtraColumn.copyFrom(element.getValue());
600
        }
601
        query.copyFrom(this.query);
602

    
603
        return query;
604
    }
605

    
606
    @Override
607
    public FeatureQuery fetch() {
608
        return this.fetch(null);
609
    }
610

    
611
    @Override
612
    public void put(FeatureQuery query) {
613
        this.query.copyFrom(query);
614
        addExtraColumns(this.query);
615
    }
616

    
617
    private void addExtraColumns(FeatureQuery query) {
618
        List<EditableFeatureAttributeDescriptor> cols = query.getExtraColumn().getColumns();
619
        if (cols == null || cols.isEmpty()) {
620
            return;
621
        }
622
        for (EditableFeatureAttributeDescriptor col : cols) {
623
            ListElement lf = new AttributeListElement(col);
624
            this.lstAttributesModel.addElement(lf);
625
        }
626
        if (this.lstAttributesModel.getSize() > 0) {
627
            this.lstAttributes.setSelectedIndex(0);
628
        }
629
    }
630

    
631
    public static void selfRegister() {
632
//        boolean n = ToolsSwingUtils.registerIcons( 
633
//                DefaultFeatureQueryOrderPanel.class,
634
//                null,
635
//                LIBRARY_NAME,
636
//                new String[]{ "featurequery", "featurequery-column-add"},
637
//                new String[]{ "featurequery", "featurequery-column-remove"},
638
//                new String[]{ "featurequery", "featurequery-column-down"},
639
//                new String[]{ "featurequery", "featurequery-column-up"}
640
//        );          
641
    }
642

    
643
    private void doAdd() {
644
        int id = 0;
645
        String newName = COLUMN_DEFAULT_NAME;
646
        while (checkIfValueExistInModel(newName, this.lstAttributesModel)) {
647
            newName = COLUMN_DEFAULT_NAME + "_" + id;
648
            id += 1;
649
        }
650
        EditableFeatureAttributeDescriptor newAttr = DALLocator.getDataManager().createFeatureAttributeDescriptor(
651
                newName,
652
                DataTypes.STRING
653
        );
654
        if (newAttr.getDataType().supportSize()) {
655
            newAttr.setSize(newAttr.getDataType().getDefaultSize());
656
        }
657
        this.columnController.put(newAttr);
658
        this.columnController.setEnabled(true);
659

    
660
        this.lstAttributesModel.addElement(new AttributeListElement(newAttr));
661
        ListElement.setSelected(this.lstAttributes, newAttr);
662
        this.lstAttributes.revalidate();
663
        this.lstAttributes.repaint();
664
        this.actualEditableAttribute = newAttr;
665

    
666
    }
667

    
668
    private boolean checkIfValueExistInModel(String name, ListModel<ListElement<EditableFeatureAttributeDescriptor>> model) {
669
        for (int i = 0; i < model.getSize(); i++) {
670
            EditableFeatureAttributeDescriptor element = model.getElementAt(i).getValue();
671
            if (StringUtils.equals(element.getLabel(), name)) {
672
                return true;
673
            }
674

    
675
        }
676
        return false;
677
    }
678

    
679
    private void doRemove() {
680
        AttributeListElement selectedValue = (AttributeListElement) this.lstAttributes.getSelectedValue();
681
        if( selectedValue == null ) {
682
            return;
683
        }
684
        FeatureAttributeDescriptor attr = selectedValue.getValue();
685
        if( attr == null ) {
686
            return;
687
        }
688
        boolean removeFromAggregateFunctions = false;
689
        boolean removeFromOrder = false;
690
        boolean removeFromGroupByColums = false;
691
        if( this.query.getAggregateFunctions().containsKey(attr.getName()) ) {
692
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
693
            int n = dialogs.confirmDialog(
694
                    "El campo '"+attr.getName()+"' se esta usando en una funcion de agregado. ? Dese borrarlo igualmente ?", 
695
                    "Eliminar campo", 
696
                    JOptionPane.YES_NO_OPTION, 
697
                    JOptionPane.QUESTION_MESSAGE, 
698
                    "_FeatureQueryCalculatedColumns_remove_used_column"
699
            );
700
            if( n != JOptionPane.YES_OPTION ) {
701
                return;
702
            }
703
            n = dialogs.confirmDialog(
704
                    "? Desea eliminar la funcion de agregado donde se esta usando el campo '"+attr.getName()+"' ?", 
705
                    "Eliminar campo", 
706
                    JOptionPane.YES_NO_OPTION, 
707
                    JOptionPane.QUESTION_MESSAGE, 
708
                    "_FeatureQueryCalculatedColumns_remove_aggregate_function_when_remove_column"
709
            );
710
            if( n == JOptionPane.YES_OPTION ) {
711
                removeFromAggregateFunctions = true;
712
            } else {
713
                LOGGER.info("It has been decided not to delete the aggregate function of a deleted field");
714
            }
715
        }
716
        if( this.query.getGroupByColumns().contains(attr.getName()) ) {
717
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
718
            int n = dialogs.confirmDialog(
719
                    "El campo '"+attr.getName()+"' se esta usando como campo de agrupacion. ? Dese borrarlo igualmente ?", 
720
                    "Eliminar campo", 
721
                    JOptionPane.YES_NO_OPTION, 
722
                    JOptionPane.QUESTION_MESSAGE, 
723
                    "_FeatureQueryCalculatedColumns_remove_used_column"
724
            );
725
            if( n != JOptionPane.YES_OPTION ) {
726
                return;
727
            }
728
            n = dialogs.confirmDialog(
729
                    "? Desea eliminar la agrupacion por el campo '"+attr.getName()+"' ?", 
730
                    "Eliminar campo", 
731
                    JOptionPane.YES_NO_OPTION, 
732
                    JOptionPane.QUESTION_MESSAGE, 
733
                    "_FeatureQueryCalculatedColumns_remove_group_by_column_when_remove_column"
734
            );
735
            if( n == JOptionPane.YES_OPTION ) {
736
                removeFromGroupByColums = true;
737
            } else {
738
                LOGGER.info("It has been decided not to delete the group by a deleted field");
739
            }
740
        }
741
        if( this.query.getOrder().contains(attr.getName()) ) {
742
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
743
            int n = dialogs.confirmDialog(
744
                    "El campo '"+attr.getName()+"' se esta usando para establecer el orden. ? Dese borrarlo igualmente ?", 
745
                    "Eliminar campo", 
746
                    JOptionPane.YES_NO_OPTION, 
747
                    JOptionPane.QUESTION_MESSAGE, 
748
                    "_FeatureQueryCalculatedColumns_remove_used_column"
749
            );
750
            if( n != JOptionPane.YES_OPTION ) {
751
                return;
752
            }
753

    
754
            n = dialogs.confirmDialog(
755
                    "? Desea eliminar el uso del campo '"+attr.getName()+"' en la ordenacion ?", 
756
                    "Eliminar campo", 
757
                    JOptionPane.YES_NO_OPTION, 
758
                    JOptionPane.QUESTION_MESSAGE, 
759
                    "_FeatureQueryCalculatedColumns_remove_order_when_remove_column"
760
            );
761
            if( n == JOptionPane.YES_OPTION ) {
762
                removeFromOrder = true;
763
            } else {
764
                LOGGER.info("It has been decided not to delete the order by a deleted field");
765
            }
766
        }
767
        if( removeFromAggregateFunctions ) {
768
           this.query.removeAggregateFunction(attr.getName());
769
        }
770
        if( removeFromOrder ) {
771
            int index = this.query.getOrder().getIndex(attr.getName());
772
            this.query.getOrder().remove(index);
773
        }
774
        if( removeFromGroupByColums ) {
775
            this.query.removeGroupByColumn(attr.getName());
776
        }
777
        
778
        ListSelectionModel lsm = lstAttributes.getSelectionModel();
779
        DefaultListModel model = (DefaultListModel) this.lstAttributes.getModel();
780
        int actualIndex = lsm.getMinSelectionIndex();
781
        this.lstAttributesModel.removeElement(selectedValue);
782
        this.columnController.clean();
783

    
784
        int size = model.size();
785
        if (size == 0) {
786
            //List is empty: disable delete, up, and down buttons.
787
        } else {
788
            //Adjust the selection.
789
            if (model.getSize() == 0) {
790

    
791
            } else if (actualIndex >= model.getSize()) {
792
                lstAttributes.setSelectedIndex(model.getSize() - 1);
793
            } else {
794
                lstAttributes.setSelectedIndex(actualIndex);
795
            }
796
        }
797
    }
798

    
799
    private void doApplyChanges() {
800
        this.columnController.fetch(this.actualEditableAttribute);
801
        this.lstAttributes.invalidate();
802
        this.lstAttributes.repaint();
803
    }
804

    
805
    private void doUp(JList lstColumns) {
806
        int moveMe = lstColumns.getSelectedIndex();
807
        if (moveMe != 0) {
808
            //not already at top
809
            swap(lstColumns, moveMe, moveMe - 1);
810
            lstColumns.setSelectedIndex(moveMe - 1);
811
            lstColumns.ensureIndexIsVisible(moveMe - 1);
812
        }
813
    }
814

    
815
    private void doDown(JList lstColumns) {
816
        int moveMe = lstColumns.getSelectedIndex();
817
        if (moveMe != lstColumns.getModel().getSize() - 1) {
818
            //not already at bottom
819
            swap(lstColumns, moveMe, moveMe + 1);
820
            lstColumns.setSelectedIndex(moveMe + 1);
821
            lstColumns.ensureIndexIsVisible(moveMe + 1);
822
        }
823
    }
824

    
825
    private void swap(JList lstColumns, int a, int b) {
826
        DefaultListModel model = (DefaultListModel) lstColumns.getModel();
827
        Object aObject = model.getElementAt(a);
828
        Object bObject = model.getElementAt(b);
829
        model.set(a, bObject);
830
        model.set(b, aObject);
831
    }
832
}