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 / searchpanel / DefaultSearchPanel.java @ 45794

History | View | Annotate | Download (68.6 KB)

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

    
3
import java.awt.BorderLayout;
4
import java.awt.Cursor;
5
import java.awt.FlowLayout;
6
import java.awt.Toolkit;
7
import java.awt.datatransfer.Clipboard;
8
import java.awt.datatransfer.StringSelection;
9
import java.awt.event.ActionEvent;
10
import java.awt.event.ActionListener;
11
import java.awt.event.ComponentAdapter;
12
import java.awt.event.ComponentEvent;
13
import java.awt.event.KeyAdapter;
14
import java.awt.event.KeyEvent;
15
import java.net.URL;
16
import java.text.DateFormat;
17
import java.text.SimpleDateFormat;
18
import java.util.ArrayList;
19
import java.util.Calendar;
20
import java.util.Collection;
21
import java.util.Collections;
22
import java.util.Date;
23
import java.util.HashMap;
24
import java.util.List;
25
import java.util.Map;
26
import java.util.Objects;
27
import javax.swing.AbstractAction;
28
import javax.swing.Action;
29
import static javax.swing.Action.ACTION_COMMAND_KEY;
30
import static javax.swing.Action.NAME;
31
import javax.swing.BorderFactory;
32
import javax.swing.ImageIcon;
33
import javax.swing.JButton;
34
import javax.swing.JComponent;
35
import javax.swing.JMenuItem;
36
import javax.swing.JOptionPane;
37
import javax.swing.JPopupMenu;
38
import javax.swing.JTable;
39
import javax.swing.ListSelectionModel;
40
import javax.swing.SwingUtilities;
41
import javax.swing.event.ChangeEvent;
42
import javax.swing.event.ChangeListener;
43
import javax.swing.event.ListSelectionEvent;
44
import javax.swing.event.ListSelectionListener;
45
import javax.swing.table.DefaultTableModel;
46
import javax.swing.table.TableModel;
47
import org.apache.commons.io.FilenameUtils;
48
import org.apache.commons.lang.mutable.MutableObject;
49
import org.apache.commons.lang3.StringUtils;
50
import org.apache.commons.lang3.mutable.MutableLong;
51
import org.gvsig.configurableactions.ConfigurableActionsMamager;
52
import org.gvsig.expressionevaluator.Expression;
53
import org.gvsig.expressionevaluator.ExpressionBuilder;
54
import org.gvsig.expressionevaluator.ExpressionUtils;
55
import static org.gvsig.fmap.dal.DataManager.DAL_USE_LABELS;
56
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_BOTH;
57
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_NO;
58
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_YES;
59
import org.gvsig.fmap.dal.DataStore;
60
import org.gvsig.fmap.dal.DataStoreProviderFactory;
61
import org.gvsig.fmap.dal.complements.Search;
62
import org.gvsig.fmap.dal.exception.DataException;
63
import org.gvsig.fmap.dal.feature.Feature;
64
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
65
import org.gvsig.fmap.dal.feature.FeatureQuery;
66
import org.gvsig.fmap.dal.feature.FeatureStore;
67
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
68
import org.gvsig.fmap.dal.feature.FeatureType;
69
import org.gvsig.fmap.dal.feature.paging.FacadeOfAFeaturePagingHelper;
70
import org.gvsig.fmap.dal.swing.AbstractDALActionFactory.AbstractDALActionContext;
71
import org.gvsig.fmap.dal.swing.DALActionFactory;
72
import org.gvsig.fmap.dal.swing.DALSwingLocator;
73
import org.gvsig.fmap.dal.swing.DataSwingManager;
74
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryCalculatedColumnsPanel;
75
import org.gvsig.fmap.dal.swing.impl.featurequery.DefaultFeatureQueryGroupByPanel;
76
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
77
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel;
78
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel.SearchConditionPanelFactory;
79
import org.gvsig.tools.ToolsLocator;
80
import org.gvsig.tools.dataTypes.DataType;
81
import org.gvsig.tools.dynobject.Tags;
82
import org.gvsig.tools.i18n.I18nManager;
83
import org.gvsig.tools.swing.api.ActionListenerSupport;
84
import org.gvsig.tools.swing.api.ToolsSwingLocator;
85
import org.gvsig.tools.swing.api.ToolsSwingManager;
86
import org.gvsig.tools.swing.api.windowmanager.Dialog;
87
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
88
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
89
import org.gvsig.tools.swing.icontheme.IconTheme;
90
import org.gvsig.tools.util.ToolsUtilLocator;
91
import org.slf4j.Logger;
92
import org.slf4j.LoggerFactory;
93
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryGroupByPanel;
94
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryOrderPanel;
95
import org.gvsig.fmap.dal.swing.featuretable.SimpleFeaturesTableModel;
96
import org.gvsig.fmap.dal.swing.impl.featurequery.DefaultFeatureQueryCalculatedColumnsPanel;
97
import org.gvsig.fmap.dal.swing.featuretype.FeatureAttributesSelectionPanel;
98
import org.gvsig.fmap.dal.swing.impl.featuretable.SimpleFeaturesTableModelImpl;
99
import org.gvsig.fmap.dal.swing.searchPostProcess.SearchPostProcess;
100
import org.gvsig.fmap.dal.swing.searchPostProcess.SearchPostProcessFactory;
101
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
102
import org.gvsig.tools.bookmarksandhistory.Bookmark;
103
import org.gvsig.tools.bookmarksandhistory.Bookmarks;
104
import org.gvsig.tools.bookmarksandhistory.History;
105
import org.gvsig.tools.dispose.Disposable;
106
import org.gvsig.tools.dispose.DisposeUtils;
107
import org.gvsig.tools.dynform.DynFormLocator;
108
import org.gvsig.tools.dynform.JDynForm;
109
import org.gvsig.tools.dynobject.DynObject;
110
import org.gvsig.tools.swing.api.SupportIsEnable;
111
import org.gvsig.tools.swing.api.SupportIsVisible;
112
import org.gvsig.tools.swing.api.ToolsSwingUtils;
113
import org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue;
114
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_GETVALUE;
115
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_SETVALUE;
116
import org.gvsig.tools.swing.api.bookmarkshistory.BookmarksController;
117
import org.gvsig.tools.swing.api.bookmarkshistory.HistoryController;
118
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
119

    
120
/**
121
 *
122
 * @author jjdelcerro
123
 */
124
@SuppressWarnings({"UseSpecificCatch"})
125
public class DefaultSearchPanel
126
        extends DefaultSearchPanelView2
127
        implements FeatureStoreSearchPanel, SupportIsEnable, SupportIsVisible {
128

    
129
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSearchPanel.class);
130

    
131
    static /* friend */ Integer useLabels = null;
132
    private BookmarksController bookmarksController;
133
    private HistoryController historyController;
134
    private FeatureQuery lastQuery;
135
    private Feature lastSelectedFeature;
136

    
137
    public static class UseLabelsYesAction extends AbstractAction {
138

    
139
        @SuppressWarnings("OverridableMethodCallInConstructor")
140
        public UseLabelsYesAction() {
141
            I18nManager i18n = ToolsLocator.getI18nManager();
142

    
143
            this.putValue(NAME, i18n.getTranslation("_Use_labels"));
144
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsYes");
145
        }
146

    
147
        @Override
148
        public Object getValue(String key) {
149
            if (NAME.equals(key)) {
150
                // Cuando se registra la accion aun no se han cargado las traducciones
151
                I18nManager i18n = ToolsLocator.getI18nManager();
152
                return i18n.getTranslation("_Use_labels");
153
            }
154
            return super.getValue(key);
155
        }
156

    
157
        @Override
158
        public void actionPerformed(ActionEvent ae) {
159
            DefaultSearchPanel.useLabels = USE_LABELS_YES;
160
        }
161
    }
162

    
163
    public static class UseLabelsNoAction extends AbstractAction {
164

    
165
        @SuppressWarnings("OverridableMethodCallInConstructor")
166
        public UseLabelsNoAction() {
167
            I18nManager i18n = ToolsLocator.getI18nManager();
168
            this.putValue(NAME, i18n.getTranslation("_Use_names"));
169
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsNo");
170
        }
171

    
172
        @Override
173
        public Object getValue(String key) {
174
            if (NAME.equals(key)) {
175
                // Cuando se registra la accion aun no se han cargado las traducciones
176
                I18nManager i18n = ToolsLocator.getI18nManager();
177
                return i18n.getTranslation("_Use_names");
178
            }
179
            return super.getValue(key);
180
        }
181

    
182
        @Override
183
        public void actionPerformed(ActionEvent ae) {
184
            DefaultSearchPanel.useLabels = USE_LABELS_NO;
185
        }
186
    }
187

    
188
    public static class UseLabelsBothAction extends AbstractAction {
189

    
190
        @SuppressWarnings("OverridableMethodCallInConstructor")
191
        public UseLabelsBothAction() {
192
            I18nManager i18n = ToolsLocator.getI18nManager();
193

    
194
            this.putValue(NAME, i18n.getTranslation("_Use_labels_and_names"));
195
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsBoth");
196
        }
197

    
198
        @Override
199
        public Object getValue(String key) {
200
            if (NAME.equals(key)) {
201
                // Cuando se registra la accion aun no se han cargado las traducciones
202
                I18nManager i18n = ToolsLocator.getI18nManager();
203
                return i18n.getTranslation("_Use_labels_and_names");
204
            }
205
            return super.getValue(key);
206
        }
207

    
208
        @Override
209
        public void actionPerformed(ActionEvent ae) {
210
            DefaultSearchPanel.useLabels = USE_LABELS_BOTH;
211
        }
212
    }
213

    
214
    public static class SelectColumnsAction extends AbstractAction {
215

    
216
        @SuppressWarnings("OverridableMethodCallInConstructor")
217
        public SelectColumnsAction() {
218
            I18nManager i18n = ToolsLocator.getI18nManager();
219

    
220
            this.putValue(NAME, i18n.getTranslation("_Select_columns_to_display"));
221
            this.putValue(ACTION_COMMAND_KEY, "SelectColumns");
222
        }
223

    
224
        @Override
225
        public Object getValue(String key) {
226
            if (NAME.equals(key)) {
227
                // Cuando se registra la accion aun no se han cargado las traducciones
228
                I18nManager i18n = ToolsLocator.getI18nManager();
229
                return i18n.getTranslation("_Select_columns_to_display");
230
            }
231
            return super.getValue(key);
232
        }
233

    
234
        @Override
235
        public void actionPerformed(ActionEvent ae) {
236
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
237
            panel.doSelectResultColumnNames();
238
        }
239
    }
240

    
241
    public static class CalculatedColumnsAction extends AbstractAction {
242

    
243
        @SuppressWarnings("OverridableMethodCallInConstructor")
244
        public CalculatedColumnsAction() {
245
            I18nManager i18n = ToolsLocator.getI18nManager();
246

    
247
            this.putValue(NAME, i18n.getTranslation("_Calculated_columns"));
248
            this.putValue(ACTION_COMMAND_KEY, "CalculatedColumns");
249
        }
250

    
251
        @Override
252
        public Object getValue(String key) {
253
            if (NAME.equals(key)) {
254
                // Cuando se registra la accion aun no se han cargado las traducciones
255
                I18nManager i18n = ToolsLocator.getI18nManager();
256
                return i18n.getTranslation("_Calculated_columns");
257
            }
258
            return super.getValue(key);
259
        }
260

    
261
        @Override
262
        public void actionPerformed(ActionEvent ae) {
263
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
264
            panel.doCalculatedColumns();
265
        }
266
    }
267

    
268
    public static class GroupByAction extends AbstractAction {
269

    
270
        @SuppressWarnings("OverridableMethodCallInConstructor")
271
        public GroupByAction() {
272
            I18nManager i18n = ToolsLocator.getI18nManager();
273

    
274
            this.putValue(NAME, i18n.getTranslation("_Group_by"));
275
            this.putValue(ACTION_COMMAND_KEY, "GroupBy");
276
        }
277

    
278
        @Override
279
        public Object getValue(String key) {
280
            if (NAME.equals(key)) {
281
                // Cuando se registra la accion aun no se han cargado las traducciones
282
                I18nManager i18n = ToolsLocator.getI18nManager();
283
                return i18n.getTranslation("_Group_by");
284
            }
285
            return super.getValue(key);
286
        }
287

    
288
        @Override
289
        public void actionPerformed(ActionEvent ae) {
290
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
291
            panel.doGroupBy();
292
        }
293
    }
294

    
295
    public static class OrderByAction extends AbstractAction {
296

    
297
        @SuppressWarnings("OverridableMethodCallInConstructor")
298
        public OrderByAction() {
299
            I18nManager i18n = ToolsLocator.getI18nManager();
300

    
301
            this.putValue(NAME, i18n.getTranslation("_Order_by"));
302
            this.putValue(ACTION_COMMAND_KEY, "SelectOrderBy");
303
        }
304

    
305
        @Override
306
        public Object getValue(String key) {
307
            if (NAME.equals(key)) {
308
                // Cuando se registra la accion aun no se han cargado las traducciones
309
                I18nManager i18n = ToolsLocator.getI18nManager();
310
                return i18n.getTranslation("_Order_by");
311
            }
312
            return super.getValue(key);
313
        }
314

    
315
        @Override
316
        public void actionPerformed(ActionEvent ae) {
317
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
318
            panel.doOrderBy();
319
        }
320
    }
321
    
322
    private class TablePopupMenu extends JPopupMenu {
323
            public final JTable table;
324
            public TablePopupMenu(JTable inputTable) {
325
                this.table = inputTable;
326
                I18nManager i18n = ToolsLocator.getI18nManager();
327
                JMenuItem copyRowsActionMenu = new JMenuItem(i18n.getTranslation("_Copy_rows"));
328
                copyRowsActionMenu.addActionListener(new ActionListener() {
329

    
330
                    @Override
331
                    public void actionPerformed(ActionEvent e) {
332
                        doCopyRows(table);
333
                    }
334
                });
335
                this.add(copyRowsActionMenu);
336
            }
337
        }
338
            
339
    private class ActionButtons {
340

    
341
        private final DALActionFactory factory;
342
        private final Action action;
343
        private final JButton button;
344

    
345
        public ActionButtons(DALActionFactory factory, Action action, JButton button) {
346
            this.factory = factory;
347
            this.action = action;
348
            this.button = button;
349
        }
350
    }
351

    
352
    public static class SearchActionContext extends AbstractDALActionContext {
353

    
354
        private final DefaultSearchPanel panel;
355

    
356
        public SearchActionContext(DefaultSearchPanel panel) {
357
            super(FeatureStoreSearchPanel.ACTION_CONTEXT_NAME);
358
            this.panel = panel;
359
        }
360

    
361
        @Override
362
        public DataStore getStore() {
363
            if (this.panel.currentPostProcess == null || this.panel.tabResults.getSelectedIndex() == 0) {
364
                return this.panel.getStore();
365
            } else {
366
                return this.panel.postProcessStore;
367
//                DataSwingManager manager = DALSwingLocator.getDataSwingManager();
368
//                SearchPostProcessFactory factory= manager.getSearchPostProcess(this.panel.currentPostProcess);
369
//                SearchParameters searchParams = this.panel.parameters.getCopy();
370
//                if (factory.hasProcessParameters()){
371
//                    SearchPostProcess.SearchPostProcessResult searchPostProcessResult = this.panel.doExecuteSearchPostProcess(this.panel.store, this.panel.parameters.getQuery(), factory, this.panel.postProcessParams, searchParams);
372
//                    return searchPostProcessResult.getStore();
373
//                }
374
//                SearchPostProcess.SearchPostProcessResult searchPostProcessResult = this.panel.doExecuteSearchPostProcess(this.panel.store, this.panel.parameters.getQuery(), factory, null, searchParams);
375
//                return searchPostProcessResult.getStore();
376
            }
377
        }
378

    
379
        @Override
380
        public JComponent getActionButton(String actionName) {
381
            return this.panel.getActionButton(actionName);
382
        }
383

    
384
        @Override
385
        public int getSelectedsCount() {
386
            return this.panel.getSelectedFeatureCount();
387
        }
388

    
389
        @Override
390
        public Expression getFilterForSelecteds() {
391
            return this.panel.getFilterForSelectedFeature();
392
        }
393

    
394
        @Override
395
        public FeatureQuery getQuery() {
396
            if (this.panel.currentPostProcess == null || this.panel.tabResults.getSelectedIndex() == 0) {
397
                return this.panel.parameters.getQuery();
398
            } else {
399
                return this.panel.postProcessQuery;
400
//                DataSwingManager manager = DALSwingLocator.getDataSwingManager();
401
//                SearchPostProcessFactory factory= manager.getSearchPostProcess(this.panel.currentPostProcess);
402
//                SearchParameters searchParams =this.panel.parameters.getCopy();
403
//                if (factory.hasProcessParameters()){
404
//                    SearchPostProcess.SearchPostProcessResult searchPostProcessResult = this.panel.doExecuteSearchPostProcess(this.panel.store, this.panel.parameters.getQuery(), factory, this.panel.postProcessParams, searchParams);
405
//                    return searchPostProcessResult.getQuery();
406
//                }
407
//                SearchPostProcess.SearchPostProcessResult searchPostProcessResult = this.panel.doExecuteSearchPostProcess(this.panel.store, this.panel.parameters.getQuery(), factory, null, searchParams);
408
//                return searchPostProcessResult.getQuery();
409
            }
410
        }
411
    }
412

    
413
//    private class SearchPostProcessListener implements ActionListener {
414
//
415
//        private final FeatureStore input;
416
//        private final SearchPostProcessFactory factory;
417
//        private final FeatureQuery query;
418
//
419
//        public SearchPostProcessListener(
420
//                FeatureStore input,
421
//                FeatureQuery query,
422
//                SearchPostProcessFactory factory
423
//        ) {
424
//            this.input = input;
425
//            this.query = query;
426
//            this.factory = factory;
427
//        }
428
//
429
//        @Override
430
//        public void actionPerformed(ActionEvent e) {
431
//            // habilita la pesta�a del tab con los resultados del post procesado
432
//            if (this.factory.hasProcessParameters()) {
433
//                DynObject parameters = this.factory.createProcessParameters(this.input);
434
//                JDynForm form = DynFormLocator.getDynFormManager().createJDynForm(parameters);
435
//                form.asJComponent().setPreferredSize(new Dimension(350, 250));
436
//
437
//                I18nManager i18n = ToolsLocator.getI18nManager();
438
//                WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
439
//
440
//                Dialog dialog = windowManager.createDialog(
441
//                        form.asJComponent(),
442
//                        i18n.getTranslation("_create_parameters"),
443
//                        i18n.getTranslation("_parameters_list"),
444
//                        WindowManager_v2.BUTTONS_OK_CANCEL);
445
//
446
//                dialog.addActionListener((ActionEvent e2) -> {
447
//                    if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
448
//                        form.getValues(parameters); // actualiza el valor de lo los parametros con los valores introducidos por el usuario
449
//                        doExecuteSearchPostProcess(this.input, this.query, this.factory, parameters);
450
//                        postProcessParams = parameters;
451
//                    }
452
//                });
453
//
454
//                dialog.show(WindowManager.MODE.DIALOG);
455
//
456
//            } else {
457
//                doExecuteSearchPostProcess(this.input, this.query, this.factory, null);
458
//            }
459
//        }
460
//    }
461

    
462
    private FeatureStore store;
463
    private final ActionListenerSupport acctionListeners;
464
    private final Map<String, ActionButtons> actions;
465
    private boolean showActions = true;
466
    private DefaultSearchParameters parameters;
467

    
468
    private List<SearchConditionPanel> conditionPanels;
469

    
470
    public static final int PANEL_SIMPLIFIED = 0;
471
    public static final int PANEL_ADVANCED = 1;
472
    private static final String BOOKMARKSANDHISTORY_NAME = "SearchPanel";
473
    private final Bookmarks<Object> bookmarks;
474
    private final History<Object> history;
475
    private boolean filterOnlyMode;
476

    
477
    private String currentPostProcess;
478

    
479
    private DynObject postProcessParams;
480
    private FeatureStore postProcessStore;
481
    private FeatureQuery postProcessQuery;
482
    private SimpleFeaturesTableModel resultModel;
483
    private SimpleFeaturesTableModel resultPostProcessModel;
484

    
485
    private boolean processing;
486

    
487
    private JComponent configurableActions;
488

    
489
    public DefaultSearchPanel(FeatureStore store) {
490
        this.store = store;
491
        this.filterOnlyMode = false;
492
        DisposeUtils.bind(store);
493
        this.acctionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
494
        this.actions = new HashMap<>();
495
        this.parameters = new DefaultSearchParameters();
496
        FeatureQuery featureQuery = this.store.createFeatureQuery();
497
        featureQuery.retrievesAllAttributes();
498
        this.parameters.setQuery(featureQuery);
499
        this.currentPostProcess = null;
500
        this.postProcessParams = null;
501
        this.postProcessStore = null;
502
        this.postProcessQuery = null;
503
        this.processing = false;
504
        this.configurableActions = null;
505
        this.resultModel = null;
506
        this.resultPostProcessModel = null;
507

    
508
        Search search = (Search) ToolsLocator.getComplementsManager().get(
509
                Search.COMPLEMENT_MANE, getFeatureType()
510
        );
511
        List<Search.OrderedAttribute> attributos = search.getOrderedAttributes(
512
                Search.BASIC_TYPES_FILTER,
513
                Search.STR_INT_LONG_LABEL_ORDER,
514
                12
515
        );
516
        for (Search.OrderedAttribute attrdesc : attributos) {
517
            this.parameters.getResultColumnNames().add(attrdesc.getDescriptor().getName());
518
        }
519
        this.bookmarks = ToolsLocator.getBookmarksAndHistoryManager().getBookmarksGroup(BOOKMARKSANDHISTORY_NAME);
520
        this.history = ToolsLocator.getBookmarksAndHistoryManager().getHistoryGroup(BOOKMARKSANDHISTORY_NAME);
521
    }
522

    
523
    @Override
524
    public void dispose() {
525
        DisposeUtils.disposeQuietly(store);
526
        TableModel m = this.tblResults.getModel();
527
        if (m instanceof Disposable) {
528
            DisposeUtils.disposeQuietly((Disposable) m);
529
        }
530
        this.store = null;
531
        this.tblResults.setModel(new DefaultTableModel());
532
    }
533

    
534
    @Override
535
    public JComponent asJComponent() {
536
        if (this.conditionPanels == null) {
537
            this.initComponents();
538
        }
539
        return this;
540
    }
541

    
542
    private void addActions() {
543
        if (!this.showActions) {
544
            return;
545
        }
546
        this.pnlActions.removeAll();
547
        this.pnlActions.setLayout(new FlowLayout(FlowLayout.TRAILING, 8, 4));
548
        SearchActionContext actionContext = new SearchActionContext(this);
549
        Collection<DALActionFactory> factories = DALSwingLocator.getSwingManager().getStoreActions();
550
        for (DALActionFactory factory : factories) {
551
            Action action = factory.createAction(actionContext);
552
            JButton button = new JButton(action);
553
            this.actions.put(factory.getName(), new ActionButtons(factory, action, button));
554
            button.setBorder(BorderFactory.createEmptyBorder());
555
            button.setBorderPainted(false);
556
            button.setFocusPainted(false);
557
            button.setContentAreaFilled(false);
558
            button.setCursor(new Cursor(Cursor.HAND_CURSOR));
559
            this.pnlActions.add(button);
560
        }
561
        this.pnlActions.revalidate();
562
        this.pnlActions.repaint();
563
    }
564

    
565
    @Override
566
    public void addActionListener(ActionListener listener) {
567
        this.acctionListeners.addActionListener(listener);
568
    }
569

    
570
    @Override
571
    public ActionListener[] getActionListeners() {
572
        return this.acctionListeners.getActionListeners();
573
    }
574

    
575
    @Override
576
    public void removeActionListener(ActionListener listener) {
577
        this.acctionListeners.removeActionListener(listener);
578
    }
579

    
580
    @Override
581
    public void removeAllActionListener() {
582
        this.acctionListeners.removeAllActionListener();
583
    }
584

    
585
    @Override
586
    public void fireActionEvent(ActionEvent event) {
587
        this.acctionListeners.fireActionEvent(event);
588
    }
589

    
590
    @Override
591
    public boolean hasActionListeners() {
592
        return this.acctionListeners.hasActionListeners();
593
    }
594

    
595
    private void initComponents() {
596
        this.conditionPanels = new ArrayList<>();
597

    
598
        ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
599
        swingManager.translate(this.tabSearchMode);
600
        swingManager.translate(this.tabResults);
601
        swingManager.translate(this.btnSearch);
602
        swingManager.translate(this.btnClear);
603
        swingManager.translate(this.btnSearchPostProcess);
604
        swingManager.translate(this.lblExpressionDeBusqueda);
605
        swingManager.translate(this.btnAddAccumulatedFilter);
606
        swingManager.translate(this.btnRemoveAccumulatedFilter);
607
        swingManager.translate(this.btnViewAccumulatedFilter);
608

    
609
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
610
        this.configurableActions = cfgActionsManager.getConfigurableActionsComponent(CONFIGURABLE_PANEL_ID, this);
611
        this.pnlCfgActions.setLayout(new BorderLayout(0, 0));
612
        this.pnlCfgActions.add(configurableActions, BorderLayout.CENTER);
613

    
614
        this.conditionPanels.add(
615
                new SearchConditionPanelSimplified(
616
                        parameters,
617
                        store,
618
                        btnAddAccumulatedFilter,
619
                        btnRemoveAccumulatedFilter,
620
                        btnViewAccumulatedFilter,
621
                        lblField1,
622
                        lblExtraFields1,
623
                        lblRelationalOperator1,
624
                        cboValue1,
625
                        lblNull1,
626
                        lblLogicalOperators1,
627
                        lblField2,
628
                        lblExtraFields2,
629
                        lblRelationalOperator2,
630
                        cboValue2,
631
                        lblNull2,
632
                        lblLogicalOperators2,
633
                        lblField3,
634
                        lblExtraFields3,
635
                        lblRelationalOperator3,
636
                        cboValue3,
637
                        lblNull3,
638
                        lblLogicalOperators3,
639
                        lblField4,
640
                        lblExtraFields4,
641
                        lblRelationalOperator4,
642
                        cboValue4,
643
                        lblNull4,
644
                        null
645
                )
646
        );
647
        this.conditionPanels.add(
648
                new SearchConditionPanelAdvanced(
649
                        this.store,
650
                        txtAdvancedExpression,
651
                        btnAdvancedExpression,
652
                        btnAdvancedExpressionHistory,
653
                        btnAdvancedExpressionBookmarks
654
                )
655
        );
656
        for (SearchConditionPanelFactory factory : DALSwingLocator.getManager().getSearchConditionPanels()) {
657
            String factoryName = "unknown";
658
            try {
659
                factoryName = factory.getName();
660
                if (factory.isApplicable(store)) {
661
                    SearchConditionPanel panel = factory.create(this);
662
                    this.conditionPanels.add(panel);
663
                    this.tabSearchMode.add(factory.getName(), panel.asJComponent());
664
                }
665
            } catch (Throwable th) {
666
                LOGGER.warn("Can't create search panel '" + factoryName + "'.");
667
            }
668
        }
669

    
670
        this.btnSearch.addActionListener((ActionEvent e) -> {
671
            this.tabResults.setEnabledAt(1, false);
672
            search();
673
        });
674

    
675
        this.tblResults.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
676
            try {
677
                lastSelectedFeature = resultModel.getFeatureAt(tblResults.getSelectedRow());
678
            } catch(Throwable th ) {
679
                LOGGER.debug("Can't retrieve last selected feature.",th);
680
            }
681
            for (ActionButtons actionButton : actions.values()) {
682
                if (actionButton.action instanceof ListSelectionListener) {
683
                    ((ListSelectionListener) actionButton.action).valueChanged(e);
684
                }
685
            }
686
        });
687
        this.btnClear.addActionListener((ActionEvent e) -> {
688
            clear();
689
        });
690
        addActions();
691

    
692
        swingManager.createTableColumnAdjuster(tblResults);
693
        swingManager.createTableColumnAdjuster(tblSearchPostProcessResults);
694

    
695
//        this.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
696
        ToolsSwingUtils.ensureRowsCols(this, 20, 100, 30, 120);
697

    
698
        this.bookmarksController = ToolsSwingLocator.getToolsSwingManager().createBookmarksController(this.bookmarks, btnBookmarks);
699
        this.historyController = ToolsSwingLocator.getToolsSwingManager().createHistoryController(this.history, btnHistory);
700

    
701
        this.historyController.setFilter(null);
702

    
703
        ActionListener bookmarksAndHistoryListener = new ActionListener() {
704
            @Override
705
            public void actionPerformed(ActionEvent e) {
706
                ActionEventWithCurrentValue<DefaultSearchParameters> b = (ActionEventWithCurrentValue<DefaultSearchParameters>) e;
707
                switch (b.getID()) {
708
                    case ID_GETVALUE:
709
                        DefaultSearchParameters actualParams = (DefaultSearchParameters) fetch(null);
710
                        b.setCurrentValue(actualParams);
711
                        break;
712

    
713
                    case ID_SETVALUE:
714
                        if (b.getCurrentValue() == null) {
715
                            return;
716
                        }
717
                        DefaultSearchParameters searchParams;
718
                        try {
719
                            searchParams = b.getCurrentValue().getCopy();
720
                        } catch (Exception ex) {
721
                            LOGGER.warn("Not been able to clone export parameters", ex);
722
                            return;
723
                        }
724
                        clear();
725
                        put(searchParams);
726
                        Thread th = new Thread(() -> {
727
                            doSearch(searchParams);
728
                        });
729
                        th.start();
730
                        break;
731
                }
732

    
733
            }
734
        };
735
        this.historyController.addActionListener(bookmarksAndHistoryListener);
736
        this.bookmarksController.addActionListener(bookmarksAndHistoryListener);
737
        this.addComponentListener(new ComponentAdapter() {
738
            @Override
739
            public void componentHidden(ComponentEvent e) {
740
                dispose();
741
            }
742
        });
743

    
744
        this.btnSearchPostProcess.addActionListener(new ActionListener() {
745
            @Override
746
            public void actionPerformed(ActionEvent e) {
747
                try {
748
                    doSelectSearchPostprocess();
749
                } catch (DataException ex) {
750
                    LOGGER.warn("Can't select a Search Post Process", ex);
751
                }
752
            }
753
        });
754

    
755
        this.tabResults.setEnabledAt(1, false);
756

    
757
        this.tblResults.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
758
        this.tblResults.addKeyListener(new KeyAdapter() {
759
            @Override
760
            public void keyPressed(KeyEvent e) {
761
                if( e.getKeyCode()==KeyEvent.VK_F4 ) {
762
                    doShowCellInDialog();
763
                }
764
            }
765
        });        
766
        
767
        this.tblResults.setComponentPopupMenu(new TablePopupMenu(this.tblResults));
768
        this.tblSearchPostProcessResults.setComponentPopupMenu(new TablePopupMenu(this.tblSearchPostProcessResults));
769
                
770
        //this.tblResults.add
771
        if (this.bookmarks.hasBookmark(this.store.getName())) {
772
            Bookmark<DefaultSearchParameters> initBookmark = this.bookmarks.get(this.store.getName());
773
            DefaultSearchParameters initSearchParams = initBookmark.getValue().getCopy();
774
            put(initSearchParams);
775
            Thread th = new Thread(() -> {
776
                doSearch(initSearchParams);
777
            });
778
            th.start();
779
            return;
780
        }
781
        
782
        this.tabResults.addChangeListener(new ChangeListener() {
783
            public void stateChanged(ChangeEvent evt) {
784
                SwingUtilities.invokeLater(() -> {
785
                    if(tabResults.getSelectedIndex()==0){
786
                        updateNumberElementsMsg(resultModel);
787
                    }else{
788
                        updateNumberElementsMsg(resultPostProcessModel);
789
                    }
790
                });
791
            }
792
        });
793
        if( this.filterOnlyMode ) {
794
            this.btnSearchPostProcess.setVisible(false);
795
        }
796
        clear();
797
        search();
798
    }
799
    
800
    private void doShowCellInDialog() {
801
        int row = this.tblResults.getSelectedRow();
802
        if( row < 0 ) {
803
            return;
804
        }
805
        int col = this.tblResults.getSelectedColumn();
806
        if( col < 0 ) {
807
            return;
808
        }
809
        String s = Objects.toString(this.tblResults.getValueAt(row, col),null);
810
        if( StringUtils.isBlank(s) ) {
811
            return;
812
        }
813
        ToolsSwingLocator.getToolsSwingManager().showZoomDialog(
814
            this, 
815
            this.tblResults.getColumnName(col), 
816
            s,
817
            false
818
        );
819
    }
820

    
821
    private FeatureType getFeatureType() {
822
        try {
823
            return store.getDefaultFeatureType();
824
        } catch (Exception ex) {
825
            throw new RuntimeException("Can't retrieve the feature type.", ex);
826
        }
827
    }
828

    
829
    @Override
830
    public void setEnabled(boolean enabled) {
831
        if (this.conditionPanels == null) {
832
            this.initComponents();
833
        }
834
        for (SearchConditionPanel conditionPanel : conditionPanels) {
835
            conditionPanel.setEnabled(enabled);
836
        }
837

    
838
        this.btnClear.setEnabled(enabled);
839
        this.btnSearch.setEnabled(enabled);
840
        for (ActionButtons actionButton : actions.values()) {
841
            actionButton.action.setEnabled(enabled);
842
        }
843
        this.btnSearchPostProcess.setEnabled(enabled);
844
        //bookmarkController,historyController,configurableActions
845
    }
846

    
847
    @Override
848
    public void clear() {
849
        this.lblMsg.setText("");
850
        if (this.conditionPanels == null) {
851
            return;
852
        }
853
        for (SearchConditionPanel conditionPanel : conditionPanels) {
854
            conditionPanel.clear();
855
        }
856
        FeatureQuery emptyQuery = this.store.createFeatureQuery();
857
        emptyQuery.retrievesAllAttributes();
858
        this.parameters.setQuery(emptyQuery);
859
        // Mantener las columnas visualizadas
860
        // Elimina las que no existen en el store como campos calculados que
861
        // pudieran existir en el fquery
862
        List<String> resultColumnNames = this.parameters.getResultColumnNames();
863
        ArrayList<String> toDeleteAlreadyDontExist = new ArrayList<>();
864
        for (String resultColumnName : resultColumnNames) {
865
            try {
866
                FeatureAttributeDescriptor attr = this.store.getDefaultFeatureType().getAttributeDescriptor(resultColumnName);
867
                if (attr == null) {
868
                    toDeleteAlreadyDontExist.add(resultColumnName);
869
                }
870
            } catch (DataException ex) {
871

    
872
            }
873
        }
874
        resultColumnNames.removeAll(toDeleteAlreadyDontExist);
875
        resetTable();
876
    }
877

    
878
    @Override
879
    public FeatureQuery getLastQuery() {
880
        return this.lastQuery;
881
    }
882

    
883
    public boolean isValid(StringBuilder message) {
884
        int searchMode = this.tabSearchMode.getSelectedIndex();
885
        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
886
        boolean valid = panel.isValid(message);
887
        return valid;
888
    }
889
    
890
    public void search() {
891
        StringBuilder message = new StringBuilder();
892
        if (!this.isValid(message)) {
893
            ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
894
            dialogManager.messageDialog(
895
                    "_The_specified_search_condition_is_not_valid",
896
                    "_Search",
897
                    JOptionPane.WARNING_MESSAGE
898
            );
899
            return;
900
        }
901
        lblMsg.setText(ToolsLocator.getI18nManager().getTranslation("_Searching")+"...");
902
        setEnabled(false);
903
        Thread th = new Thread(() -> {
904
            try {
905
            SearchParameters searchParams;
906
            try {
907
                searchParams = this.fetch(this.parameters.getCopy()); // esto lo actualiza a la ultima // decidir si se devuelve clonado
908

    
909
                Date date = Calendar.getInstance().getTime();
910
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
911
                String strDate = dateFormat.format(date);
912
                searchParams.setName("Params: " + strDate);
913
            } catch (Exception ex) {
914
                LOGGER.warn("Not able to create search parameters.", ex);
915
                lblMsg.setText(ToolsLocator.getI18nManager().getTranslation("_Errors_fetching_new_query")+"...");
916
                resetTable();
917
                return;
918
            }
919
            doSearch(searchParams);
920
                        } catch (Exception ex) {
921
                LOGGER.warn("Search panel has errors during the search", ex);
922
                resetTable();
923
            } finally {
924
                SwingUtilities.invokeLater(() -> {
925
                    setEnabled(true);
926
                });
927
            }
928
        });
929
        th.start();
930
    }
931
    
932
     private void doSearch(SearchParameters searchParams)  {
933
            final MutableObject model = new MutableObject(null);       
934
            final MutableLong rowCount=new MutableLong();
935
            try {
936
                final List<Feature> features;
937
                 FeatureQuery myQuery;
938
//                myQuery = this.getQuery().getCopy();
939
                this.tabResults.setSelectedIndex(0);
940
                List<String> resultColumnNames = searchParams.getResultColumnNames();
941
                myQuery = searchParams.getQuery().getCopy();
942
                features = store.getFeatures(myQuery, 50);
943
                FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
944
                FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
945
                // al modelo le pasamos el ftype de esas features
946
                SimpleFeaturesTableModel tableModel = new SimpleFeaturesTableModelImpl(
947
                        ftype,
948
                        resultColumnNames,
949
                        features
950
                );
951
                model.setValue(tableModel);
952
                rowCount.setValue(tableModel.getRowCount());
953
            } catch (Exception ex) {
954
                LOGGER.warn("Search not able to be executed. Can't get features or create table model", ex);
955
                lblMsg.setText(ToolsLocator.getI18nManager().getTranslation("_Errors_getting_new_feature_set") + "...");
956
                resetTable();
957
            } finally {
958
                SwingUtilities.invokeLater(() -> {
959
                    I18nManager i18n = ToolsLocator.getI18nManager();
960
                    try {
961
                        TableModel oldmodel = tblResults.getModel();
962
                        resultModel = (SimpleFeaturesTableModel) model.getValue();
963
                        tblResults.setModel(resultModel);
964
                        resultModel.setCellRenderers(tblResults);
965
                        if (oldmodel instanceof SimpleFeaturesTableModelImpl) {
966
                            ((SimpleFeaturesTableModelImpl) oldmodel).dispose();
967
                        }
968
                        updateNumberElementsMsg(resultModel);
969
//                        if (resultModel.hasErrors()) {
970
//                            lblMsg.setText(i18n.getTranslation("_Errors_occurred_during_search"));
971
//                        } else {
972
//                            lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), rowCount.getValue()));
973
//                        }
974
                        if (this.parameters != null && this.parameters.getQuery() != null) {
975
                            this.history.add(searchParams);                   
976
                        }
977
                    } catch (Exception ex) {
978
                        LOGGER.warn(" Errors occurred during search getting old model", ex);
979
                        lblMsg.setText(i18n.getTranslation("_Errors_occurred_during_search"));
980
                    } finally {
981
                        setEnabled(true);
982
                    }
983
                });
984
            }
985
     }
986

    
987
    private void resetTable() {
988
        if(!SwingUtilities.isEventDispatchThread()) {
989
            SwingUtilities.invokeLater(this::resetTable);
990
            return;
991
        }
992
        List<String> resultColumnNames = null;
993
        try {
994
            resultColumnNames = this.parameters.getResultColumnNames();
995
        } catch(Exception ex) {
996
            
997
        }
998
        FeatureType ftype = this.store.getDefaultFeatureTypeQuietly();
999
        SimpleFeaturesTableModelImpl emptyTableModel = new SimpleFeaturesTableModelImpl(
1000
                ftype,
1001
                resultColumnNames,
1002
                null
1003
        );
1004
        this.tblResults.setModel(emptyTableModel);
1005
        
1006
    }
1007

    
1008
    public void setResultColumnNames(List<String> names) {
1009
        this.parameters.getResultColumnNames().clear();
1010
        this.parameters.getResultColumnNames().addAll(names);
1011
        if (this.conditionPanels == null) {
1012
            return;
1013
        }
1014
        SimpleFeaturesTableModelImpl model;
1015
//        model = (SimpleFeaturesTableModel) this.tblResults.getModel();
1016
        List<Feature> features = store.getFeatures(this.parameters.getQuery());
1017
        FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
1018
        FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
1019
        model = new SimpleFeaturesTableModelImpl(
1020
                ftype,
1021
                this.parameters.getResultColumnNames(),
1022
                features
1023
        );
1024
        tblResults.setModel(model);
1025
    }
1026

    
1027
    @Override
1028
    public boolean setFilter(Expression filter) {
1029
        try {
1030
            if (this.conditionPanels == null) {
1031
                this.initComponents();
1032
            }
1033
            if (ExpressionUtils.isPhraseEmpty(filter)) {
1034
                this.clear();
1035
                return true;
1036
            }
1037
            int panel = 0;
1038
            int selected = PANEL_ADVANCED;
1039
            for (SearchConditionPanel conditionPanel : conditionPanels) {
1040
                if (panel != PANEL_ADVANCED && conditionPanel.set(filter)) {
1041
                    selected = panel;
1042
                }
1043
                panel++;
1044
            }
1045
            this.tabSearchMode.setSelectedIndex(selected);
1046

    
1047
//            SimpleFeaturesTableModel model = new SimpleFeaturesTableModel(this.getStore());
1048
//            tblResults.setModel(model);
1049
//            lblMsg.setText("");
1050
            return true;
1051
        } catch (Exception ex) {
1052
            LOGGER.warn("Can't set current search", ex);
1053
            return false;
1054
        }
1055
    }
1056

    
1057
    @Override
1058
    public List<SearchConditionPanel> getConditionPanels() {
1059
        return Collections.unmodifiableList(this.conditionPanels);
1060
    }
1061

    
1062
    @Override
1063
    public SearchConditionPanel getConditionPanel(String name) {
1064
        for (SearchConditionPanel panel : conditionPanels) {
1065
            if (StringUtils.equalsIgnoreCase(name, panel.getFactory().getName())) {
1066
                return panel;
1067
            }
1068
        }
1069
        return null;
1070
    }
1071

    
1072

    
1073
 @Override
1074
    public Expression getFilterForSelectedFeature() {
1075
        if (this.conditionPanels == null) {
1076
            return null;
1077
        }
1078
        if (this.tabResults.getSelectedIndex() == 0) {
1079
            int selectedRow = this.tblResults.getSelectedRow();
1080
            if (selectedRow < 0) {
1081
                return null;
1082
            }
1083
            try {
1084
                List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblResults.getModel()).getFeatures();
1085
                Feature feature = features.get(selectedRow);
1086

    
1087
                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1088
                FeatureType ftype = this.store.getDefaultFeatureType();
1089
                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1090
                    builder.and(
1091
                            builder.eq(
1092
                                    builder.column(attrdesc.getName()),
1093
                                    builder.constant(feature.get(attrdesc.getName()))
1094
                            )
1095
                    );
1096
                }
1097
                Expression filter = ExpressionUtils.createExpression(builder.toString());
1098
                return filter;
1099
            } catch (Exception ex) {
1100
                LOGGER.warn("Can't build search for the selected feature.", ex);
1101
                return null;
1102
            }
1103
        } else {
1104
            if (this.currentPostProcess == null) {
1105
                return null;
1106
            }
1107
            int selectedRow = this.tblSearchPostProcessResults.getSelectedRow();
1108
            if (selectedRow < 0) {
1109
                return null;
1110
            }
1111
            try {
1112
                List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblSearchPostProcessResults.getModel()).getFeatures();
1113
                Feature feature = features.get(selectedRow);
1114

    
1115
                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1116
                FeatureType ftype = this.postProcessStore.getDefaultFeatureType();
1117
                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1118
                    builder.and(
1119
                            builder.eq(
1120
                                    builder.column(attrdesc.getName()),
1121
                                    builder.constant(feature.get(attrdesc.getName()))
1122
                            )
1123
                    );
1124
                }
1125
                Expression filter = ExpressionUtils.createExpression(builder.toString());
1126
                return filter;
1127
            } catch (Exception ex) {
1128
                LOGGER.warn("Can't build search for the selected feature.", ex);
1129
                return null;
1130
            }
1131
        }
1132

    
1133
    }
1134
    
1135
    @Override
1136
    public FeatureStore getStore() {
1137
        return store;
1138
    }
1139

    
1140
    private void doOrderBy() {
1141
        I18nManager i18n = ToolsLocator.getI18nManager();
1142
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1143
        FeatureQueryOrderPanel orderPanel = DALSwingLocator.getDataSwingManager().createFeatureStoreOrderPanel();
1144
        orderPanel.setStore(store);
1145
        orderPanel.put(parameters.getQuery());
1146
        Dialog dialog = windowManager.createDialog(
1147
                orderPanel.asJComponent(),
1148
                i18n.getTranslation("_Select_order"),
1149
                null,
1150
                WindowManager_v2.BUTTONS_OK_CANCEL
1151
        );
1152
        dialog.addActionListener((ActionEvent e) -> {
1153
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
1154
                orderPanel.fetch(this.parameters.getQuery());
1155
                search();
1156
            }
1157
        });
1158
        dialog.show(WindowManager.MODE.DIALOG);
1159
    }
1160
       
1161
    private void doCopyRows(JTable table) {
1162
        
1163
        SimpleFeaturesTableModel model = null;
1164
        if (table.getModel() instanceof SimpleFeaturesTableModel) {
1165
            model = (SimpleFeaturesTableModel) table.getModel();
1166
        }
1167

    
1168
        String LINE_BREAK = System.lineSeparator();
1169
        String CELL_BREAK = "\t";
1170
        char DELIMITER = '"';
1171
        
1172
        Clipboard CLIPBOARD = Toolkit.getDefaultToolkit().getSystemClipboard();
1173
        
1174
        int[] selection = table.getSelectedRows();
1175
        for (int i = 0; i < selection.length; i++) {
1176
          selection[i] = table.convertRowIndexToModel(selection[i]);
1177
        }
1178
   
1179
        int numCols = table.getColumnCount();
1180
        StringBuilder excelStr = new StringBuilder();
1181
        boolean valueIsNumeric;
1182

    
1183
        for (int j = 0; j < numCols; j++) {
1184

    
1185
            excelStr.append(DELIMITER);
1186
            excelStr.append(escape(table.getColumnName(j), LINE_BREAK, CELL_BREAK));
1187
            excelStr.append(DELIMITER);
1188

    
1189
            if (j < numCols - 1) {
1190
                excelStr.append(CELL_BREAK);
1191
            }
1192
        }
1193
        excelStr.append(LINE_BREAK);
1194
        for (int i : selection) {
1195
            for (int j = 0; j < numCols; j++) {
1196
                valueIsNumeric = false;
1197
                if (model != null) {
1198
                    FeatureAttributeDescriptor descriptor = model.getFeatureDescriptor(j);
1199
                    if (descriptor.getDataType().isNumeric()) {
1200
                        if (!descriptor.hasAvailableValues()) {
1201
                            valueIsNumeric = true;
1202
                        }
1203
                    }
1204
                }
1205
                if (!valueIsNumeric) {
1206
                    excelStr.append(DELIMITER);
1207
                }
1208

    
1209
                excelStr.append(escape(table.getValueAt(i, j), LINE_BREAK, CELL_BREAK));
1210

    
1211
                if (!valueIsNumeric) {
1212
                    excelStr.append(DELIMITER);
1213
                }
1214
                if (j < numCols - 1) {
1215
                    excelStr.append(CELL_BREAK);
1216
                }
1217
            }
1218
            excelStr.append(LINE_BREAK);
1219
        }
1220

    
1221
        StringSelection sel = new StringSelection(excelStr.toString());
1222
        CLIPBOARD.setContents(sel, sel);
1223
    }
1224

    
1225
    private String escape(Object cell,String LINE_BREAK, String CELL_BREAK) {
1226
        return (cell == null ? "" : cell.toString()
1227
                .replace(CELL_BREAK, " ")
1228
                );
1229
    }
1230
       
1231
    @Override
1232
    public ImageIcon loadImage(String imageName) {
1233
        String name = FilenameUtils.getBaseName(imageName);
1234
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
1235
        if (theme.exists(name)) {
1236
            return theme.get(name);
1237
        }
1238
        URL url = this.getClass().getResource(name + ".png");
1239
        if (url == null) {
1240
            return null;
1241
        }
1242
        return new ImageIcon(url);
1243
    }
1244

    
1245
    @Override
1246
    public int getSelectedFeatureCount() {
1247
        if (this.conditionPanels == null) {
1248
            return 0;
1249
        }
1250
        if (this.currentPostProcess == null || this.tabResults.getSelectedIndex() == 0) {
1251
            return this.tblResults.getSelectedRowCount();
1252
        }
1253
        return this.tblSearchPostProcessResults.getSelectedRowCount();
1254
    }
1255

    
1256
    @Override
1257
    public JComponent getActionButton(String name) {
1258
        ActionButtons actionButton = this.actions.get(name);
1259
        if (actionButton == null) {
1260
            return null;
1261
        }
1262
        return actionButton.button;
1263
    }
1264

    
1265
    @Override
1266
    public void setShowActions(boolean showActions) {
1267
        this.showActions = showActions;
1268
    }
1269

    
1270
    @Override
1271
    public boolean isShowActions() {
1272
        return this.showActions;
1273
    }
1274

    
1275
    public static String getAttributeDescriptorLabel(FeatureAttributeDescriptor attrdesc, String tableName) {
1276
        String theLabel;
1277
        int theUseLabels;
1278
        if (useLabels == null) {
1279
            Tags tags = attrdesc.getTags();
1280
            if (tags.has(DAL_USE_LABELS)) {
1281
                theUseLabels = tags.getInt(DAL_USE_LABELS, USE_LABELS_NO);
1282
            } else {
1283
                if (attrdesc.getFeatureType()!=null) {
1284
                    tags = attrdesc.getFeatureType().getTags();
1285
                    theUseLabels = tags.getInt(DAL_USE_LABELS, USE_LABELS_NO);
1286
                } else {
1287
                    theUseLabels = USE_LABELS_NO;
1288
                }
1289
            }
1290
        } else {
1291
            theUseLabels = useLabels;
1292
        }
1293
        switch (theUseLabels) {
1294
            case USE_LABELS_YES:
1295
                if (StringUtils.isBlank(tableName)) {
1296
                    theLabel = attrdesc.getLocalizedLabel();
1297
                } else {
1298
                    theLabel = String.format("%s [%s]", attrdesc.getLocalizedLabel(), tableName);
1299
                }
1300
                break;
1301
            default:
1302
            case USE_LABELS_NO:
1303
                if (StringUtils.isBlank(tableName)) {
1304
                    theLabel = attrdesc.getName();
1305
                } else {
1306
                    theLabel = String.format("%s [%s]", attrdesc.getName(), tableName);
1307
                }
1308
                break;
1309
            case USE_LABELS_BOTH:
1310
                if (StringUtils.isBlank(tableName)) {
1311
                    theLabel = String.format("%s [%s]", attrdesc.getLocalizedLabel(), attrdesc.getName());
1312
                } else {
1313
                    theLabel = String.format("%s [%s/%s]", attrdesc.getLocalizedLabel(), attrdesc.getName(), tableName);
1314
                }
1315
                break;
1316
        }
1317
        return theLabel;
1318
    }
1319

    
1320
    private void doCalculatedColumns() {
1321
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1322
        I18nManager i18n = ToolsLocator.getI18nManager();
1323
        final FeatureQueryCalculatedColumnsPanel panel = new DefaultFeatureQueryCalculatedColumnsPanel();
1324
        panel.setStore(this.store);
1325
        panel.put(this.parameters.getQuery());
1326
        final Dialog dialog = winmanager.createDialog(
1327
                panel.asJComponent(),
1328
                i18n.getTranslation("_Calculated_columns"),
1329
                null,
1330
                WindowManager_v2.BUTTONS_OK_CANCEL
1331
        );
1332
        dialog.addActionListener((ActionEvent e) -> {
1333
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1334
                panel.fetch(this.parameters.getQuery());
1335
                search();
1336
            }
1337
        });
1338
        dialog.show(WindowManager.MODE.DIALOG);
1339
    }
1340

    
1341
    private void doGroupBy() {
1342
        DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
1343
        int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
1344
        if (allowGroupBy != DataType.YES) {
1345
            // FIXME: mensaje al usaurio.
1346
            I18nManager i18n = ToolsLocator.getI18nManager();
1347
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1348
            dialogs.messageDialog(
1349
                    i18n.getTranslation("_The_group_function_is_not_available_for_this_table"),
1350
                    i18n.getTranslation("_Information"),
1351
                    JOptionPane.INFORMATION_MESSAGE
1352
            );
1353
            return;
1354
        }
1355

    
1356
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1357
        I18nManager i18n = ToolsLocator.getI18nManager();
1358
        final FeatureQueryGroupByPanel panelGroupBy = new DefaultFeatureQueryGroupByPanel();
1359
        panelGroupBy.setStore(this.store);
1360
        panelGroupBy.put(this.parameters.getQuery());
1361
        final Dialog dialog = winmanager.createDialog(
1362
                panelGroupBy.asJComponent(),
1363
                i18n.getTranslation("_Select_group_columns_and_aggregate_functions"),
1364
                null,
1365
                WindowManager_v2.BUTTONS_OK_CANCEL
1366
        );
1367
        dialog.addActionListener((ActionEvent e) -> {
1368
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1369
                panelGroupBy.fetch(this.parameters.getQuery());
1370
                search();
1371
            }
1372
        });
1373
        dialog.show(WindowManager.MODE.DIALOG);
1374
    }
1375

    
1376
    private void doSelectResultColumnNames() {
1377
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1378
        I18nManager i18n = ToolsLocator.getI18nManager();
1379
        final FeatureAttributesSelectionPanel panelSelectColumns = DALSwingLocator.getManager().createFeatureAttributeSelectionPanel();
1380
        panelSelectColumns.allowCalculatedAttributes(false);
1381
        FeatureType ftype = this.getFeatureType();
1382
        try {
1383
            Feature f = store.findFirst(this.parameters.getQuery());
1384
            if (f != null) {
1385
                ftype = f.getType();
1386
            }
1387
        } catch (Throwable ex) {
1388
            LOGGER.warn("Can't retrieve the feature type from the first feature.", ex);
1389
        }
1390
        panelSelectColumns.setFeatureType(ftype);
1391
        panelSelectColumns.setSelectedNames(this.parameters.getResultColumnNames());
1392
        final Dialog dialog = winmanager.createDialog(
1393
                panelSelectColumns.asJComponent(),
1394
                i18n.getTranslation("_Select_the_columns_to_display"),
1395
                null,
1396
                WindowManager_v2.BUTTONS_OK_CANCEL
1397
        );
1398
        dialog.addActionListener((ActionEvent e) -> {
1399
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1400
                this.setResultColumnNames(panelSelectColumns.getSelectedNames());
1401
            }
1402
        });
1403
        dialog.show(WindowManager.MODE.DIALOG);
1404
    }
1405

    
1406
    @Override
1407
    public void put(SearchParameters inParams) {
1408
        this.parameters = (DefaultSearchParameters) inParams;
1409
        for (SearchConditionPanel conditionPanel : this.conditionPanels) {
1410
            try {
1411
                conditionPanel.put(inParams);
1412
            } catch (Exception ex) {
1413
                LOGGER.warn("Can't open panel", ex);
1414
            }
1415
        }
1416
        this.tabSearchMode.setSelectedIndex(inParams.getSearchMode());
1417
//        this.resetTable();
1418

    
1419
    }
1420

    
1421
    private FeatureQuery getQuery() {
1422
        FeatureQuery query;
1423
        try {
1424
            int searchMode = this.tabSearchMode.getSelectedIndex();
1425
            SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1426
            Expression filter = panel.get();
1427
            if (searchMode != PANEL_ADVANCED) {
1428
                this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1429
            }
1430
            query = (FeatureQuery) this.parameters.getQuery().clone();
1431
            query.retrievesAllAttributes();
1432
            if (ExpressionUtils.isPhraseEmpty(filter)) {
1433
                return query;
1434
            }
1435
            query.setFilter(filter);
1436
            query.retrievesAllAttributes();
1437
            return query;
1438
        } catch (Exception ex) {
1439
            LOGGER.warn("Can't build query.", ex);
1440
            return null;
1441
        }
1442
    }
1443

    
1444
    @Override
1445
    public SearchParameters fetch(SearchParameters outParams) {
1446
        // Actualiza el fquery del parameters con los paneles
1447
        for (SearchConditionPanel conditionPanel : conditionPanels) {
1448
            try {
1449
                conditionPanel.fetch(this.parameters);
1450
            } catch (Exception ex) {
1451
                LOGGER.warn("Panel not able to fetch values", ex);
1452
            }
1453
        }
1454

    
1455
        // Actualiza el filtro con el panel activo
1456
        int searchMode = this.tabSearchMode.getSelectedIndex();
1457
        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1458
        Expression filter = panel.get();
1459
        if (searchMode != PANEL_ADVANCED) {
1460
            this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1461
        }
1462
        this.parameters.setSearchMode(searchMode);
1463
        FeatureQuery query = (FeatureQuery) this.parameters.getQuery();
1464
        this.lastQuery = query.getCopy();
1465
        query.retrievesAllAttributes();
1466
        query.clearFilter();
1467
        if (!ExpressionUtils.isPhraseEmpty(filter)) {
1468
            query.setFilter(filter);
1469
            query.retrievesAllAttributes();
1470
        }
1471

    
1472
        if (outParams == null) {
1473
            return this.parameters.getCopy();
1474
        }
1475
        outParams.copyFrom(this.parameters.getCopy());
1476
        return outParams;
1477
    }
1478

    
1479
    public static void selfRegister() {
1480
        String[][] iconNames = new String[][]{
1481
            new String[]{"dalswing", "featurestore-column"},
1482
            new String[]{"dalswing", "featurestore-foreing-key"},
1483
            new String[]{"dalswing", "featurestore-table"},
1484
            new String[]{"Common", "common-showform"},
1485
            new String[]{"dalswing", "search-action-select"},
1486
            new String[]{"dalswing", "search-action-select-add"},
1487
            new String[]{"dalswing", "search-action-select-filter"},        
1488
            new String[]{"dalswing", "search-nullbehavior-null"},
1489
            new String[]{"dalswing", "search-nullbehavior-true"},
1490
            new String[]{"dalswing", "search-nullbehavior-false2"}
1491
       
1492
        };
1493
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1494
        for (String[] icon : iconNames) {
1495
            URL url = DefaultSearchPanel.class.getResource(icon[1] + ".png");
1496
            theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1497
        }
1498

    
1499
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
1500
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsYesAction());
1501
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsNoAction());
1502
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsBothAction());
1503
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new SelectColumnsAction());
1504
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new CalculatedColumnsAction());
1505
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new GroupByAction());
1506
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new OrderByAction());
1507
    }
1508
    
1509
    private void doSelectSearchPostprocess() throws DataException {
1510
        DataSwingManager manager = DALSwingLocator.getDataSwingManager();
1511
        Map<String, SearchPostProcessFactory> searchPostProcessFactoryMap = manager.getSearchPostProcess();
1512

    
1513
        JPopupMenu menu = new JPopupMenu();
1514
        for (String factory : searchPostProcessFactoryMap.keySet()) {
1515
            JMenuItem item;
1516
            item = new JMenuItem(factory);
1517
            SearchParameters searchParams = this.fetch(this.parameters.getCopy());
1518
            FeatureQuery myQuery = searchParams.getQuery().getCopy();
1519
//            item.addActionListener(new SearchPostProcessListener(this.store, myQuery, manager.getSearchPostProcess(factory)));
1520
            item.addActionListener((ActionEvent e) -> {
1521
                doSearchPostProcess(store, myQuery, manager.getSearchPostProcess(factory), searchParams );
1522
            });
1523
            menu.add(item);
1524
        }
1525
        menu.show(this.btnSearchPostProcess, 0, this.btnSearchPostProcess.getHeight());
1526
    }
1527

    
1528
    private void doExecuteSearchPostProcess(
1529
            FeatureStore input,
1530
            FeatureQuery query,
1531
            SearchPostProcessFactory factory,
1532
            DynObject parameters
1533
            ) {
1534
        Thread task = new Thread(() -> {
1535
            try {
1536
                this.processing = true;
1537
                this.updateComponentState();
1538
                SearchPostProcess process = factory.createProcess(factory, input, query, parameters);
1539

    
1540
                if (parameters != null) {
1541
                    process.setParameters(parameters);
1542
                }
1543
                //Ejecutar el execute en thread para no bloquear el software
1544
                SearchPostProcess.SearchPostProcessResult output = process.execute(input, query, parameters);
1545
                this.postProcessStore = output.getStore();
1546
                this.postProcessQuery = output.getQuery();
1547
                this.currentPostProcess = factory.getName();
1548
                SwingUtilities.invokeLater(() -> { // Añade a la cola de eventos un evento a ejecutar de código
1549
                    doLoadSearchPostProccessResults(this.postProcessStore);
1550
                });
1551
            }catch (Exception ex){
1552
                LOGGER.warn("SearchPostProcess not able to be executed.", ex);
1553
                resetPostProcessTable();
1554
                
1555
            } finally {
1556
                this.processing = false;
1557
                this.updateComponentState();
1558
            }
1559
        }, "ExecuteSearchPostProcess");
1560

    
1561
        task.start();
1562

    
1563
    }
1564

    
1565
    private void doLoadSearchPostProccessResults(FeatureStore input) {
1566

    
1567
        final List<Feature> featuresSearchPostProccessResults;
1568
        final FeatureQuery finalQuery;
1569
        finalQuery = null;
1570
        try {  
1571
            this.tabResults.setEnabledAt(1, true);
1572
            this.tabResults.setSelectedIndex(1);
1573
            featuresSearchPostProccessResults = input.getFeatures(finalQuery, 20);
1574
            FacadeOfAFeaturePagingHelper facadeSearchPostProccessResults = (FacadeOfAFeaturePagingHelper) featuresSearchPostProccessResults;
1575
            FeatureType ftypeSearchPostProccessResults = facadeSearchPostProccessResults.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
1576
            // al modelo le pasamos el ftype de esas features
1577
            resultPostProcessModel = new SimpleFeaturesTableModelImpl(
1578
                    ftypeSearchPostProccessResults,
1579
                    this.parameters.getResultColumnNames(),
1580
                    featuresSearchPostProccessResults
1581
            );
1582

    
1583
            I18nManager i18n = ToolsLocator.getI18nManager();
1584
            TableModel oldmodel = tblSearchPostProcessResults.getModel();
1585
            tblSearchPostProcessResults.setModel(resultPostProcessModel);
1586
            if (oldmodel instanceof SimpleFeaturesTableModel) {
1587
                ((SimpleFeaturesTableModel) oldmodel).dispose();
1588
            }
1589
            updateNumberElementsMsg(resultPostProcessModel);
1590
//            if (resultPostProcessModel.hasErrors()) {
1591
//                lblMsg.setText("_Errors_occurred_load_search_post_process");
1592
//            } else {
1593
//                lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), resultPostProcessModel.getRowCount()));
1594
//            }
1595
        } catch (Exception ex) {
1596
            resetPostProcessTable();
1597
            LOGGER.warn("SearchPostProcess not able to be executed. Can't get features or create table model", ex);
1598
        }
1599
    }
1600

    
1601
    private void updateComponentState() {
1602
        if (!SwingUtilities.isEventDispatchThread()) {
1603
            SwingUtilities.invokeLater(this::updateComponentState);
1604
            return;
1605
        }
1606
        this.setEnabled(!processing);
1607
    }
1608
    
1609
    private void resetPostProcessTable() {
1610
        if(!SwingUtilities.isEventDispatchThread()) {
1611
            SwingUtilities.invokeLater(this::resetPostProcessTable);
1612
            return;
1613
        }
1614
       
1615
        this.tblSearchPostProcessResults.setModel(new DefaultTableModel());
1616
    }
1617
    
1618
    private void doSearchPostProcess(FeatureStore store, FeatureQuery query, SearchPostProcessFactory factory, SearchParameters searchParams){
1619
        if (factory.hasProcessParameters()) {
1620
                DynObject parametersPostProcess = factory.createProcessParameters(store, query, searchParams);
1621
                JDynForm form = DynFormLocator.getDynFormManager().createJDynForm(parametersPostProcess);
1622
                form.setLayoutMode(JDynForm.USE_SEPARATORS);
1623

    
1624
                I18nManager i18n = ToolsLocator.getI18nManager();
1625
                WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1626

    
1627
                Dialog dialog = windowManager.createDialog(
1628
                        form.asJComponent(),
1629
                        i18n.getTranslation("_Postprocess_parameters"),
1630
                        i18n.getTranslation(
1631
                                "_Parameters_for_XpostprocessNameX_postprocess_on_XtableNameX",
1632
                                new String[] {
1633
                                    factory.getName(),
1634
                                    this.store.getName()
1635
                                }
1636
                        ),
1637
                        WindowManager_v2.BUTTONS_OK_CANCEL);
1638
                
1639
                ToolsSwingUtils.ensureRowsCols(dialog.asJComponent(), 20, 60, 30,100);
1640
                dialog.addActionListener((ActionEvent e2) -> {
1641
                    if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
1642
                        form.getValues(parametersPostProcess); // actualiza el valor de lo los parametros con los valores introducidos por el usuario
1643
                        doExecuteSearchPostProcess(store, query, factory, parametersPostProcess);
1644
                        this.postProcessParams = parametersPostProcess;
1645
                    }
1646
                });
1647

    
1648
                dialog.show(WindowManager.MODE.DIALOG);
1649

    
1650
            } else {
1651
                doExecuteSearchPostProcess(store, query, factory, null);
1652
            }
1653
    }
1654
    
1655
    private void updateNumberElementsMsg( SimpleFeaturesTableModel model){
1656
        I18nManager i18n = ToolsLocator.getI18nManager();
1657
        
1658
        if (model.hasErrors()) {
1659
            lblMsg.setText(i18n.getTranslation("_Errors_occurred_load_search_post_process"));
1660
        } else {
1661
            lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), model.getRowCount()));
1662
        }
1663
    }
1664
    
1665
    @Override
1666
    public boolean isVisible(Object component) {
1667
       if( this.filterOnlyMode ) {
1668
            if( component instanceof GroupByAction ) {
1669
                return false;
1670
            }
1671
//            if( component instanceof OrderByAction ) {
1672
//                return false;
1673
//            }
1674
            if( component instanceof CalculatedColumnsAction ) {
1675
                return false;
1676
            }
1677
        }
1678
        return true;
1679
    }
1680

    
1681
    @Override
1682
    public boolean isEnabled(Object component) {
1683
        if( component instanceof GroupByAction ) {
1684
            DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
1685
            int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
1686
            if (allowGroupBy != DataType.YES) {
1687
                return false;
1688
            }
1689
        }
1690
        return true;
1691
    }
1692

    
1693
    @Override
1694
    public void setFilterOnlyMode(boolean filterOnlyMode) {
1695
        if( this.conditionPanels!=null ) {
1696
            throw new IllegalStateException("Cannot change filter-only-mode after invoking asJComponent.");
1697
        }
1698
        this.filterOnlyMode = filterOnlyMode;
1699
        this.showActions = false;
1700
    }
1701

    
1702
    @Override
1703
    public boolean isFilterOnlyMode() {
1704
        return this.filterOnlyMode;
1705
    }
1706

    
1707
    @Override
1708
    public Feature getLastSelectedFeature() {
1709
        return this.lastSelectedFeature;
1710
    }
1711

    
1712
}
1713