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

History | View | Annotate | Download (87 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.event.ActionEvent;
7
import java.awt.event.ActionListener;
8
import java.awt.event.ComponentAdapter;
9
import java.awt.event.ComponentEvent;
10
import java.awt.event.KeyAdapter;
11
import java.awt.event.KeyEvent;
12
import java.io.ByteArrayOutputStream;
13
import java.io.File;
14
import java.nio.charset.Charset;
15
import java.sql.SQLException;
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.Iterator;
25
import java.util.List;
26
import java.util.Map;
27
import java.util.Objects;
28
import javax.swing.AbstractAction;
29
import javax.swing.Action;
30
import static javax.swing.Action.ACTION_COMMAND_KEY;
31
import static javax.swing.Action.NAME;
32
import javax.swing.BorderFactory;
33
import javax.swing.ImageIcon;
34
import javax.swing.JButton;
35
import javax.swing.JComponent;
36
import static javax.swing.JFileChooser.FILES_ONLY;
37
import javax.swing.JMenuItem;
38
import javax.swing.JOptionPane;
39
import static javax.swing.JOptionPane.YES_OPTION;
40
import javax.swing.JPopupMenu;
41
import javax.swing.JTable;
42
import javax.swing.ListSelectionModel;
43
import javax.swing.SwingUtilities;
44
import javax.swing.event.ChangeEvent;
45
import javax.swing.event.ListSelectionEvent;
46
import javax.swing.event.ListSelectionListener;
47
import javax.swing.filechooser.FileFilter;
48
import javax.swing.table.DefaultTableModel;
49
import javax.swing.table.TableCellRenderer;
50
import javax.swing.table.TableModel;
51
import org.apache.commons.io.FilenameUtils;
52
import org.apache.commons.lang.mutable.MutableObject;
53
import org.apache.commons.lang3.ArrayUtils;
54
import org.apache.commons.lang3.StringUtils;
55
import org.apache.commons.lang3.mutable.MutableLong;
56
import org.apache.commons.lang3.tuple.ImmutablePair;
57
import org.apache.commons.lang3.tuple.Pair;
58
import org.gvsig.configurableactions.ConfigurableActionsMamager;
59
import org.gvsig.expressionevaluator.Expression;
60
import org.gvsig.expressionevaluator.ExpressionBuilder;
61
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
62
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
63
import org.gvsig.expressionevaluator.ExpressionUtils;
64
import static org.gvsig.filedialogchooser.FileDialogChooser.SAVE_DIALOG;
65
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_BOTH;
66
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_NO;
67
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_YES;
68
import org.gvsig.fmap.dal.DataStore;
69
import org.gvsig.fmap.dal.DataStoreProviderFactory;
70
import org.gvsig.fmap.dal.complements.Search;
71
import org.gvsig.fmap.dal.exception.DataException;
72
import org.gvsig.fmap.dal.feature.Feature;
73
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
74
import org.gvsig.fmap.dal.feature.FeatureQuery;
75
import org.gvsig.fmap.dal.feature.FeatureSelection;
76
import org.gvsig.fmap.dal.feature.FeatureSet;
77
import org.gvsig.fmap.dal.feature.FeatureStore;
78
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
79
import org.gvsig.fmap.dal.feature.FeatureType;
80
import org.gvsig.fmap.dal.feature.paging.FacadeOfAFeaturePagingHelper;
81
import org.gvsig.fmap.dal.swing.AbstractDALActionFactory.AbstractDALActionContext;
82
import org.gvsig.fmap.dal.swing.DALActionFactory;
83
import org.gvsig.fmap.dal.swing.DALSwingLocator;
84
import org.gvsig.fmap.dal.swing.DataSwingManager;
85
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryCalculatedColumnsPanel;
86
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryOrderPanel;
87
import org.gvsig.fmap.dal.swing.featuretable.SimpleFeaturesTableModel;
88
import org.gvsig.fmap.dal.swing.featuretype.FeatureAttributesSelectionPanel;
89
import org.gvsig.fmap.dal.swing.impl.DefaultDALSwingLibrary;
90
import static org.gvsig.fmap.dal.swing.impl.DefaultDALSwingLibrary.LIBRARY_NAME;
91
import org.gvsig.fmap.dal.swing.impl.featurequery.DefaultFeatureQueryCalculatedColumnsPanel;
92
import org.gvsig.fmap.dal.swing.impl.featuretable.SimpleFeaturesTableModelImpl;
93
import org.gvsig.fmap.dal.swing.searchPostProcess.SearchPostProcess;
94
import org.gvsig.fmap.dal.swing.searchPostProcess.SearchPostProcessFactory;
95
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
96
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel;
97
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel.SearchConditionPanelFactory;
98
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
99
import org.gvsig.tools.ToolsLocator;
100
import org.gvsig.tools.bookmarksandhistory.Bookmark;
101
import org.gvsig.tools.bookmarksandhistory.Bookmarks;
102
import org.gvsig.tools.bookmarksandhistory.History;
103
import org.gvsig.tools.dataTypes.DataType;
104
import org.gvsig.tools.dispose.Disposable;
105
import org.gvsig.tools.dispose.DisposeUtils;
106
import org.gvsig.tools.dynform.DynFormLocator;
107
import org.gvsig.tools.dynform.JDynForm;
108
import org.gvsig.tools.dynobject.DynObject;
109
import org.gvsig.tools.folders.FoldersManager;
110
import org.gvsig.tools.i18n.I18nManager;
111
import org.gvsig.tools.swing.api.ActionListenerSupport;
112
import org.gvsig.tools.swing.api.Component;
113
import org.gvsig.tools.swing.api.SupportIsEnable;
114
import org.gvsig.tools.swing.api.SupportIsVisible;
115
import org.gvsig.tools.swing.api.ToolsSwingLocator;
116
import org.gvsig.tools.swing.api.ToolsSwingManager;
117
import org.gvsig.tools.swing.api.ToolsSwingUtils;
118
import org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue;
119
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_GETVALUE;
120
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_SETNAME;
121
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_SETVALUE;
122
import org.gvsig.tools.swing.api.bookmarkshistory.BookmarksController;
123
import org.gvsig.tools.swing.api.bookmarkshistory.BookmarksController.BookmarkEvent;
124
import org.gvsig.tools.swing.api.bookmarkshistory.HistoryController;
125
import org.gvsig.tools.swing.api.task.TaskStatusController;
126
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
127
import org.gvsig.tools.swing.api.windowmanager.Dialog;
128
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
129
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
130
import org.gvsig.tools.task.SimpleTaskStatus;
131
import org.gvsig.tools.util.ListBuilder;
132
import org.gvsig.tools.util.PropertiesSupportHelper;
133
import org.gvsig.tools.util.ToolsUtilLocator;
134
import org.slf4j.Logger;
135
import org.slf4j.LoggerFactory;
136

    
137
/**
138
 *
139
 * @author jjdelcerro
140
 */
141
@SuppressWarnings({"UseSpecificCatch"})
142
public class DefaultSearchPanel
143
        extends DefaultSearchPanelView2
144
        implements FeatureStoreSearchPanel, SupportIsEnable, SupportIsVisible {
145

    
146
        private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSearchPanel.class);
147
        
148
        private static final String EXPORT_TO_TSV_TITLE="_Export_to_TSV";
149
        private static final String EXPORT_TO_TSV_LASTPATHID="exporttotsv.lastpath";
150
        private static final String TSV_EXTENSION="tsv";
151

    
152
        private BookmarksController bookmarksController;
153
        private HistoryController historyController;
154
        private FeatureQuery lastQuery;
155
        private Feature lastSelectedFeature;
156
        private final PropertiesSupportHelper propertiesHelper;
157
        private TaskStatusController taskStatusController;
158
        private boolean automaticallySearch;
159
        private String lastErrorMessage;
160
        private boolean initialized;
161
        private boolean postProcessEnabled;
162
        private boolean groupByEnabled;
163
        
164
        private Map<String,AdditionalResultsPanel> additionalResultsPanels;
165
        
166
        private static class AdditionalResultsPanel implements Component {
167
            
168
            private final String name;
169
            private final String title;
170
            private int index;
171
            private final Component component;
172
            
173
            public AdditionalResultsPanel(String name, String title, Component component, int index) {
174
                this.name = name;
175
                this.title = title;
176
                this.component = component;
177
                this.index = index;
178
            }
179
            
180
            public AdditionalResultsPanel(String name, String title, Component component) {
181
                this(name, title, component,-1);
182
            }
183
            
184
            public String getName() {
185
                return this.name;
186
            }
187

    
188
            public String getTitle() {
189
                return title;
190
            }
191
        
192
            public int getIndex() {
193
                return this.index;
194
            }
195

    
196
            @Override
197
            public JComponent asJComponent() {
198
                return this.component.asJComponent();
199
            }
200
            
201
            public void setIndex(int index) {
202
                this.index = index;
203
            }
204
            
205
            public void fireActionEvent(ActionEvent e) {                
206
                if( this.component instanceof ActionListenerSupport ) {
207
                    ((ActionListenerSupport)this.component).fireActionEvent(e);
208
                }
209
            }
210
            
211
            public void doDispose() {
212
                DisposeUtils.dispose(this.component);
213
            }
214
        }
215

    
216
        public static class UseLabelsYesAction extends AbstractAction {
217

    
218
                @SuppressWarnings("OverridableMethodCallInConstructor")
219
                public UseLabelsYesAction() {
220
                        I18nManager i18n = ToolsLocator.getI18nManager();
221

    
222
                        this.putValue(NAME, i18n.getTranslation("_Use_labels"));
223
                        this.putValue(ACTION_COMMAND_KEY, "UseLabelsYes");
224
                }
225

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

    
236
                @Override
237
                public void actionPerformed(ActionEvent ae) {
238
                    DALSwingLocator.getDataSwingManager().setUseLabels(USE_LABELS_YES);
239
                }
240
        }
241

    
242
        public static class UseLabelsNoAction extends AbstractAction {
243

    
244
                @SuppressWarnings("OverridableMethodCallInConstructor")
245
                public UseLabelsNoAction() {
246
                        I18nManager i18n = ToolsLocator.getI18nManager();
247
                        this.putValue(NAME, i18n.getTranslation("_Use_names"));
248
                        this.putValue(ACTION_COMMAND_KEY, "UseLabelsNo");
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("_Use_names");
257
                        }
258
                        return super.getValue(key);
259
                }
260

    
261
                @Override
262
                public void actionPerformed(ActionEvent ae) {
263
                    DALSwingLocator.getDataSwingManager().setUseLabels(USE_LABELS_NO);
264
                }
265
        }
266

    
267
        public static class UseLabelsBothAction extends AbstractAction {
268

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

    
273
                        this.putValue(NAME, i18n.getTranslation("_Use_labels_and_names"));
274
                        this.putValue(ACTION_COMMAND_KEY, "UseLabelsBoth");
275
                }
276

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

    
287
                @Override
288
                public void actionPerformed(ActionEvent ae) {
289
                    DALSwingLocator.getDataSwingManager().setUseLabels(USE_LABELS_BOTH);
290
                }
291
        }
292

    
293
        public static class SelectColumnsAction extends AbstractAction {
294

    
295
                @SuppressWarnings("OverridableMethodCallInConstructor")
296
                public SelectColumnsAction() {
297
                        I18nManager i18n = ToolsLocator.getI18nManager();
298

    
299
                        this.putValue(NAME, i18n.getTranslation("_Select_columns_to_display"));
300
                        this.putValue(ACTION_COMMAND_KEY, "SelectColumns");
301
                }
302

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

    
313
                @Override
314
                public void actionPerformed(ActionEvent ae) {
315
                        DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
316
                        panel.doSelectResultColumnNames();
317
                }
318
        }
319

    
320
        public static class CalculatedColumnsAction extends AbstractAction {
321

    
322
                @SuppressWarnings("OverridableMethodCallInConstructor")
323
                public CalculatedColumnsAction() {
324
                        I18nManager i18n = ToolsLocator.getI18nManager();
325

    
326
                        this.putValue(NAME, i18n.getTranslation("_Calculated_columns"));
327
                        this.putValue(ACTION_COMMAND_KEY, "CalculatedColumns");
328
                }
329

    
330
                @Override
331
                public Object getValue(String key) {
332
                        if (NAME.equals(key)) {
333
                                // Cuando se registra la accion aun no se han cargado las traducciones
334
                                I18nManager i18n = ToolsLocator.getI18nManager();
335
                                return i18n.getTranslation("_Calculated_columns");
336
                        }
337
                        return super.getValue(key);
338
                }
339

    
340
                @Override
341
                public void actionPerformed(ActionEvent ae) {
342
                        DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
343
                        panel.doCalculatedColumns();
344
                }
345
        }
346

    
347
        public static class GroupByAction extends AbstractAction {
348

    
349
                @SuppressWarnings("OverridableMethodCallInConstructor")
350
                public GroupByAction() {
351
                        I18nManager i18n = ToolsLocator.getI18nManager();
352

    
353
                        this.putValue(NAME, i18n.getTranslation("_Group_by"));
354
                        this.putValue(ACTION_COMMAND_KEY, "GroupBy");
355
                }
356

    
357
                @Override
358
                public Object getValue(String key) {
359
                        if (NAME.equals(key)) {
360
                                // Cuando se registra la accion aun no se han cargado las traducciones
361
                                I18nManager i18n = ToolsLocator.getI18nManager();
362
                                return i18n.getTranslation("_Group_by");
363
                        }
364
                        return super.getValue(key);
365
                }
366

    
367
                @Override
368
                public void actionPerformed(ActionEvent ae) {
369
                        DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
370
                        panel.doGroupBy();
371
                }
372
        }
373

    
374
        public static class OrderByAction extends AbstractAction {
375

    
376
                @SuppressWarnings("OverridableMethodCallInConstructor")
377
                public OrderByAction() {
378
                        I18nManager i18n = ToolsLocator.getI18nManager();
379

    
380
                        this.putValue(NAME, i18n.getTranslation("_Order_by"));
381
                        this.putValue(ACTION_COMMAND_KEY, "SelectOrderBy");
382
                }
383

    
384
                @Override
385
                public Object getValue(String key) {
386
                        if (NAME.equals(key)) {
387
                                // Cuando se registra la accion aun no se han cargado las traducciones
388
                                I18nManager i18n = ToolsLocator.getI18nManager();
389
                                return i18n.getTranslation("_Order_by");
390
                        }
391
                        return super.getValue(key);
392
                }
393

    
394
                @Override
395
                public void actionPerformed(ActionEvent ae) {
396
                        DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
397
                        panel.doOrderBy();
398
                }
399
        }
400

    
401
        public static class PropertiesAction extends AbstractAction {
402

    
403
                @SuppressWarnings("OverridableMethodCallInConstructor")
404
                public PropertiesAction() {
405
                        I18nManager i18n = ToolsLocator.getI18nManager();
406

    
407
                        this.putValue(NAME, i18n.getTranslation("_Properties"));
408
                        this.putValue(ACTION_COMMAND_KEY, "Properties");
409
                }
410

    
411
                @Override
412
                public Object getValue(String key) {
413
                        if (NAME.equals(key)) {
414
                                // Cuando se registra la accion aun no se han cargado las traducciones
415
                                I18nManager i18n = ToolsLocator.getI18nManager();
416
                                return i18n.getTranslation("_Properties");
417
                        }
418
                        return super.getValue(key);
419
                }
420

    
421
                @Override
422
                public void actionPerformed(ActionEvent ae) {
423
                        DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
424
                        panel.doShowProperties();
425
                }
426
        }
427

    
428
        private class TablePopupMenu extends JPopupMenu {
429

    
430
                public final JTable table;
431

    
432
                @SuppressWarnings("OverridableMethodCallInConstructor")
433
                public TablePopupMenu(JTable inputTable) {
434
                        this.table = inputTable;
435
                        I18nManager i18n = ToolsLocator.getI18nManager();
436
                        JMenuItem copyRowsActionMenu = new JMenuItem(i18n.getTranslation("_Copy_rows"));
437
                        copyRowsActionMenu.addActionListener((ActionEvent e) -> {
438
                                doCopyRows(table);
439
                        });
440
                        this.add(copyRowsActionMenu);
441
                        JMenuItem exportTSVActionMenu = new JMenuItem(i18n.getTranslation(EXPORT_TO_TSV_TITLE));
442
                        exportTSVActionMenu.addActionListener((ActionEvent e) -> {
443
                                doExportTSV(table);
444
                        });
445
                        this.add(exportTSVActionMenu);
446
                }
447
        }
448

    
449
        private class ActionButtons {
450

    
451
                private final DALActionFactory factory;
452
                private final Action action;
453
                private final JButton button;
454

    
455
                public ActionButtons(DALActionFactory factory, Action action, JButton button) {
456
                        this.factory = factory;
457
                        this.action = action;
458
                        this.button = button;
459
                }
460
        }
461

    
462
        public static class SearchActionContext extends AbstractDALActionContext {
463

    
464
                private final DefaultSearchPanel panel;
465

    
466
                public SearchActionContext(DefaultSearchPanel panel) {
467
                        super(FeatureStoreSearchPanel.ACTION_CONTEXT_NAME);
468
                        this.panel = panel;
469
                }
470

    
471
                @Override
472
                public DataStore getStore() {
473
                        if (this.panel.currentPostProcess != null && this.panel.tabResults.getSelectedIndex() == 1) {
474
                                return this.panel.postProcessStore;
475
                        } else {
476
                                return this.panel.getStore();
477
                        }
478
                }
479

    
480
                @Override
481
                public JComponent getActionButton(String actionName) {
482
                        return this.panel.getActionButton(actionName);
483
                }
484

    
485
                @Override
486
                public int getSelectedsCount() {
487
                        return this.panel.getSelectedFeatureCount();
488
                }
489

    
490
                @Override
491
                public Expression getFilterForSelecteds() {
492
                        return this.panel.getFilterForSelectedFeatures();
493
                }
494

    
495
                @Override
496
                public FeatureSelection getSelecteds() {
497
                        return this.panel.getSelectedFeatures();
498
                }
499

    
500
                @Override
501
                public FeatureQuery getQuery() {
502
                        if (this.panel.currentPostProcess != null && this.panel.tabResults.getSelectedIndex() == 1) {
503
                            return this.panel.postProcessQuery;
504
                        } else {
505
                            SearchParameters searchParams = this.panel.parameters;                            
506
                            FeatureQuery query = searchParams.getQueryToApply();
507
                            if( panel.useSelection() ) {
508
                                query = panel.addSelection(panel.store, query);
509
                            }
510
                            return query;
511
                        }
512
                }
513
        }
514

    
515
        private FeatureStore store;
516
        private final ActionListenerSupport acctionListeners;
517
        private final Map<String, ActionButtons> actions;
518
        private boolean showActions = true;
519
        private DefaultSearchParameters parameters;
520

    
521
        private List<SearchConditionPanel> conditionPanels;
522

    
523
        public static final int PANEL_SIMPLIFIED = 0;
524
        public static final int PANEL_ADVANCED = 1;
525
        private static final String BOOKMARKSANDHISTORY_NAME = "SearchPanel";
526
        private final Bookmarks<Object> bookmarks;
527
        private final History<Object> history;
528
        private boolean filterOnlyMode;
529

    
530
        private String currentPostProcess;
531

    
532
        private DynObject postProcessParams;
533
        private FeatureStore postProcessStore;
534
        private FeatureQuery postProcessQuery;
535
        private SimpleFeaturesTableModel resultModel;
536
        private SimpleFeaturesTableModel resultPostProcessModel;
537

    
538
        private boolean processing;
539
        private JComponent configurableActions;
540

    
541
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
542
        public DefaultSearchPanel(FeatureStore store) {
543
                this.store = store;
544
                this.filterOnlyMode = false;
545
                DisposeUtils.bind(store);
546
                this.acctionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
547
                this.actions = new HashMap<>();
548
                this.parameters = new DefaultSearchParameters();
549
                this.additionalResultsPanels = new HashMap<>();
550
                FeatureQuery featureQuery = this.store.createFeatureQuery();
551
                featureQuery.retrievesAllAttributes();
552
                this.parameters.setQuery(featureQuery);
553
                this.currentPostProcess = null;
554
                this.postProcessParams = null;
555
                this.postProcessStore = null;
556
                this.postProcessQuery = null;
557
                this.processing = false;
558
                this.configurableActions = null;
559
                this.resultModel = null;
560
                this.resultPostProcessModel = null;
561
                this.propertiesHelper = new PropertiesSupportHelper();
562
                this.propertiesHelper.setProperty("SearchPanel", this);
563
                this.automaticallySearch = true;
564
                this.postProcessEnabled = true;
565
                this.groupByEnabled = true;
566

    
567
                Search search = (Search) ToolsLocator.getComplementsManager().get(
568
                        Search.COMPLEMENT_MANE, getFeatureType()
569
                );
570
                List<Search.OrderedAttribute> attributos = search.getOrderedAttributes(
571
                        Search.BASIC_TYPES_FILTER,
572
                        Search.STR_INT_LONG_LABEL_ORDER,
573
                        12
574
                );
575
                for (Search.OrderedAttribute attrdesc : attributos) {
576
                        this.parameters.getResultColumnNames().add(attrdesc.getDescriptor().getName());
577
                }
578
                this.bookmarks = ToolsLocator.getBookmarksAndHistoryManager().getBookmarksGroup(BOOKMARKSANDHISTORY_NAME);
579
                this.history = ToolsLocator.getBookmarksAndHistoryManager().getHistoryGroup(BOOKMARKSANDHISTORY_NAME);
580
                this.initComponents0();
581
                this.initialized = false;
582
        }
583

    
584
        @Override
585
        public void dispose() {
586
                DisposeUtils.disposeQuietly(store);
587
                TableModel m = this.tblResults.getModel();
588
                if (m instanceof Disposable) {
589
                        DisposeUtils.disposeQuietly((Disposable) m);
590
                }
591
                this.store = null;
592
                this.tblResults.setModel(new DefaultTableModel());
593
                for (AdditionalResultsPanel additionalResultsPanel : this.additionalResultsPanels.values()) {
594
                    additionalResultsPanel.doDispose();
595
                }                
596
        }
597

    
598
        @Override
599
        public JComponent asJComponent() {
600
                if (!this.initialized) { //this.conditionPanels == null) {
601
                        this.initComponents1();
602
                }
603
                return this;
604
        }
605

    
606
        private void addActions() {
607
                if (!this.showActions) {
608
                        return;
609
                }
610
                this.pnlActions.removeAll();
611
                this.pnlActions.setLayout(new FlowLayout(FlowLayout.TRAILING, 8, 4));
612
                SearchActionContext actionContext = new SearchActionContext(this);
613
                actionContext.set("searchpanel", this);
614
                Collection<DALActionFactory> factories = DALSwingLocator.getSwingManager().getApplicableStoreActions(actionContext);
615
                for (DALActionFactory factory : factories) {
616
                    Action action = factory.createAction(actionContext);
617
                    JButton button = new JButton(action);
618
                    this.actions.put(factory.getName(), new ActionButtons(factory, action, button));
619
                    button.setBorder(BorderFactory.createEmptyBorder());
620
                    button.setBorderPainted(false);
621
                    button.setFocusPainted(false);
622
                    button.setContentAreaFilled(false);
623
                    button.setCursor(new Cursor(Cursor.HAND_CURSOR));
624
                    this.pnlActions.add(button);
625
                }
626
                this.pnlActions.revalidate();
627
                this.pnlActions.repaint();
628
        }
629

    
630
        @Override
631
        public void addActionListener(ActionListener listener) {
632
                this.acctionListeners.addActionListener(listener);
633
        }
634

    
635
        @Override
636
        public ActionListener[] getActionListeners() {
637
                return this.acctionListeners.getActionListeners();
638
        }
639

    
640
        @Override
641
        public void removeActionListener(ActionListener listener) {
642
                this.acctionListeners.removeActionListener(listener);
643
        }
644

    
645
        @Override
646
        public void removeAllActionListener() {
647
                this.acctionListeners.removeAllActionListener();
648
        }
649

    
650
        @Override
651
        public void fireActionEvent(ActionEvent event) {
652
                this.acctionListeners.fireActionEvent(event);
653
        }
654

    
655
        @Override
656
        public boolean hasActionListeners() {
657
                return this.acctionListeners.hasActionListeners();
658
        }
659

    
660
        private void initComponents0() {
661
                this.conditionPanels = new ArrayList<>();
662
                this.taskStatusController = ToolsSwingLocator.getTaskStatusSwingManager().createTaskStatusController(
663
                        this.lblStatusTitle,
664
                        this.lblMsg,
665
                        this.pgbStatus);
666
        }
667

    
668
        private void initComponents1() {
669

    
670
                ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
671
                swingManager.translate(this.tabSearchMode);
672
                swingManager.translate(this.tabResults);
673
                swingManager.translate(this.btnSearch);
674
                swingManager.translate(this.btnClear);
675
                swingManager.translate(this.btnSearchPostProcess);
676
                swingManager.translate(this.lblExpressionDeBusqueda);
677
                swingManager.translate(this.btnAddAccumulatedFilter);
678
                swingManager.translate(this.btnRemoveAccumulatedFilter);
679
                swingManager.translate(this.btnViewAccumulatedFilter);
680
                swingManager.translate(this.chkUseSelection);
681

    
682
                ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
683
                this.configurableActions = cfgActionsManager.getConfigurableActionsComponent(CONFIGURABLE_PANEL_ID, this);
684
                this.pnlCfgActions.setLayout(new BorderLayout(0, 0));
685
                this.pnlCfgActions.add(configurableActions, BorderLayout.CENTER);
686

    
687
                this.pgbStatus.setVisible(false);
688

    
689
                this.conditionPanels.add(
690
                        new SearchConditionPanelSimplified(
691
                                parameters,
692
                                store,
693
                                this.pnlConditionField,
694
                                btnAddAccumulatedFilter,
695
                                btnRemoveAccumulatedFilter,
696
                                btnViewAccumulatedFilter
697
                        )
698
                );
699

    
700
                SearchConditionPanelAdvanced advancedPanel = new SearchConditionPanelAdvanced(
701
                        this.store,
702
                        txtAdvancedExpression,
703
                        btnAdvancedExpression,
704
                        btnAdvancedExpressionHistory,
705
                        btnAdvancedExpressionBookmarks
706
                );
707
                this.conditionPanels.add(advancedPanel);
708

    
709
                for (SearchConditionPanelFactory factory : DALSwingLocator.getManager().getSearchConditionPanels()) {
710
                        String factoryName = "unknown";
711
                        try {
712
                                factoryName = factory.getName();
713
                                if (factory.isApplicable(store)) {
714
                                        SearchConditionPanel panel = factory.create(this);
715
                                        this.conditionPanels.add(panel);
716
                                        this.tabSearchMode.add(factory.getName(), panel.asJComponent());
717
                                }
718
                        } catch (Throwable th) {
719
                                LOGGER.warn("Can't create search panel '" + factoryName + "'.", th);
720
                        }
721
                }
722

    
723
                this.btnSearch.addActionListener((ActionEvent e) -> {
724
                        this.tabResults.setEnabledAt(1, false);
725
                        search();
726
                });
727

    
728
                this.tblResults.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
729
                        try {
730
                                lastSelectedFeature = resultModel.getFeatureAt(tblResults.getSelectedRow());
731
                        } catch (Throwable th) {
732
                                LOGGER.debug("Can't retrieve last selected feature.", th);
733
                        }
734
                        for (ActionButtons actionButton : actions.values()) {
735
                                if (actionButton.action instanceof ListSelectionListener) {
736
                                        ((ListSelectionListener) actionButton.action).valueChanged(e);
737
                                }
738
                        }
739
                });
740
                this.btnClear.addActionListener((ActionEvent e) -> {
741
                        clear();
742
                });
743
                addActions();
744

    
745
                //swingManager.createTableColumnAdjuster(tblResults);
746
                //swingManager.createTableColumnAdjuster(tblSearchPostProcessResults);
747
//        this.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
748
                ToolsSwingUtils.ensureRowsCols(this, 20, 100, 30, 120);
749

    
750
                this.bookmarksController = ToolsSwingLocator.getToolsSwingManager().createBookmarksController(this.bookmarks, btnBookmarks);
751
                this.historyController = ToolsSwingLocator.getToolsSwingManager().createHistoryController(this.history, btnHistory);
752

    
753
                this.historyController.setFilter(null);
754

    
755
                this.historyController.addActionListener((ActionEvent e) -> {
756
                        ActionEventWithCurrentValue<DefaultSearchParameters> b = (ActionEventWithCurrentValue<DefaultSearchParameters>) e;
757
                        switch (b.getID()) {
758
                                case ID_GETVALUE:
759
                                        DefaultSearchParameters actualParams = (DefaultSearchParameters) fetch(null);
760
                                        b.setCurrentValue(actualParams);
761
                                        break;
762

    
763
                                case ID_SETVALUE:
764
                                        if (b.getCurrentValue() == null) {
765
                                                return;
766
                                        }
767
                                        putParametersAndSearch(b.getCurrentValue());
768
                                        break;
769
                        }
770
                });
771
                this.bookmarksController.addActionListener((ActionEvent e) -> {
772
                        BookmarkEvent<DefaultSearchParameters> b = (BookmarkEvent<DefaultSearchParameters>) e;
773
                        switch (b.getID()) {
774
                                case ID_GETVALUE:
775
                                    LOGGER.info("Save bookmark");
776
                                        DefaultSearchParameters actualParams = (DefaultSearchParameters) fetch(null);
777
                                        b.setCurrentValue(actualParams);
778
                                        break;
779

    
780
                                case ID_SETVALUE:
781
                                    LOGGER.info("Restore bookmark");
782
                                        if (b.getCurrentValue() == null) {
783
                                                return;
784
                                        }
785
                                        b.getBookmark().used();
786
                                        b.getCurrentValue().setName(b.getBookmark().getName());
787
                                        putParametersAndSearch(b.getCurrentValue());
788
                                        break;
789
                                case ID_SETNAME:
790
                                    LOGGER.info("Rename bookmark");
791
                                        if (b.getCurrentValue() == null) {
792
                                                return;
793
                                        }
794
                                        b.getCurrentValue().setName(b.getBookmark().getName());
795
                                        break;
796
                        }
797
                });
798
                this.addComponentListener(new ComponentAdapter() {
799
                        @Override
800
                        public void componentHidden(ComponentEvent e) {
801
                                dispose();
802
                        }
803
                });
804

    
805
                this.btnSearchPostProcess.addActionListener((ActionEvent e) -> {
806
                        try {
807
                                doSelectSearchPostprocess();
808
                        } catch (DataException ex) {
809
                                LOGGER.warn("Can't select a Search Post Process", ex);
810
                        }
811
                });
812

    
813
                this.tabResults.setEnabledAt(1, false);
814
                this.tblResults.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
815
                this.tblResults.addKeyListener(new KeyAdapter() {
816
                        @Override
817
                        public void keyPressed(KeyEvent e) {
818
                                if (e.getKeyCode() == KeyEvent.VK_F4) {
819
                                        doShowCellInDialog();
820
                                }
821
                        }
822
                });
823
                this.tblResults.setComponentPopupMenu(new TablePopupMenu(this.tblResults));
824
                this.tabResults.addChangeListener((ChangeEvent evt) -> {
825
                        SwingUtilities.invokeLater(() -> {
826
                                switch(tabResults.getSelectedIndex()) {
827
                                    case 1:
828
                                        updateNumberElementsMsg(resultPostProcessModel);
829
                                        break;
830
                                    case 0:
831
                                    default:
832
                                        updateNumberElementsMsg(resultModel);
833
                                }
834
                        });
835
                });
836
                this.tblResults.getTableHeader().setReorderingAllowed(false);
837
                
838
                this.tblSearchPostProcessResults.setComponentPopupMenu(new TablePopupMenu(this.tblSearchPostProcessResults));
839
                this.tblSearchPostProcessResults.getTableHeader().setReorderingAllowed(false);
840

    
841
                if (this.filterOnlyMode || !this.postProcessEnabled) {
842
                        this.btnSearchPostProcess.setVisible(false);
843
                }
844
                
845
                for (SearchResultsPanelFactory factory : DALSwingLocator.getManager().getSearchResultsPanels()) {
846
                        String factoryName = "unknown";
847
                        try {
848
                            factoryName = factory.getName();
849
                            this.addResultPanel(
850
                                    factory.getName(),
851
                                    factory.getTitle(),
852
                                    factory.create(this)
853
                                );
854
                        } catch (Throwable th) {
855
                                LOGGER.warn("Can't create results panel '" + factoryName + "'.",th);
856
                        }
857
                }
858
                for (AdditionalResultsPanel panel : this.additionalResultsPanels.values()) {
859
                    panel.setIndex(this.tabResults.getTabCount());
860
                    this.tabResults.addTab(panel.getTitle(), panel.asJComponent());
861
                }
862

    
863
                this.initialized = true;
864
                
865
                if (this.automaticallySearch){
866
                    if (this.bookmarks.hasBookmark(this.store.getName())) {
867
                            Bookmark<DefaultSearchParameters> initBookmark = this.bookmarks.get(this.store.getName());
868
                            initBookmark.used();
869
                            putParametersAndSearch(initBookmark.getValue());
870
                    } else {
871
                        clear();
872
                        search();
873
                    }
874
                } else {
875
                    clear();
876
                    
877
                }
878
        }
879
        
880
    private void putParametersAndSearch(DefaultSearchParameters searchParams) {
881
        DefaultSearchParameters params;
882
        try {
883
            params = searchParams.getCopy();
884
            FeatureType featType = this.getFeatureType();
885
            StringBuilder errMessage = new StringBuilder();
886
            boolean onlyEssentials = false;
887
            boolean isValid = params.isValid(featType, errMessage);
888
            if(!isValid){
889
                ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
890
                I18nManager i18n = ToolsLocator.getI18nManager();
891
                int n = dialogs.confirmDialog(
892
                        i18n.getTranslation("_The_validation_of_the_search_parameters_has_returned_the_following_errors")+":\n\n"+errMessage.toString()+"\n"+i18n.getTranslation("_You_want_the_application_to_try_to_resolve_them_before_launching_the_query"),
893
                        i18n.getTranslation("_Validation_of_search_parameters"),
894
                        JOptionPane.YES_NO_OPTION,
895
                        JOptionPane.WARNING_MESSAGE,
896
                        "_Fix_search_parameters"
897
                );
898
                if( n != JOptionPane.YES_OPTION ) {
899
                    onlyEssentials = true;
900
                } else {
901
                    LOGGER.info("It has been decided do not resolve errors in parameters of search");
902
                }
903
                
904
            }
905
            params.fix(featType, onlyEssentials);
906
        } catch (Exception ex) {
907
            LOGGER.warn("Not been able to clone export parameters", ex);
908
            return;
909
        }
910
        SearchParameters panelParams;
911
        try {
912
            clear();
913
            put(params);
914
            panelParams = this.fetch(this.parameters.getCopy()); 
915
        } catch (Exception ex) {
916
                LOGGER.warn("Not able to create search parameters.", ex);
917
                this.taskStatusController.setTitle(ToolsLocator.getI18nManager().getTranslation("_Errors_fetching_new_query") + "...");
918
                resetTable();
919
                return;
920
        }
921
        Thread th = new Thread(() -> {
922
            doSearch(panelParams);
923
        });
924
        th.start();
925

    
926
    }
927

    
928
        private void doShowCellInDialog() {
929
                int row = this.tblResults.getSelectedRow();
930
                if (row < 0) {
931
                        return;
932
                }
933
                int col = this.tblResults.getSelectedColumn();
934
                if (col < 0) {
935
                        return;
936
                }
937
                String s = Objects.toString(this.tblResults.getValueAt(row, col), null);
938
                if (StringUtils.isBlank(s)) {
939
                        return;
940
                }
941
                ToolsSwingLocator.getToolsSwingManager().showZoomDialog(
942
                        this,
943
                        this.tblResults.getColumnName(col),
944
                        s,
945
                        false
946
                );
947
        }
948

    
949
        @Override
950
        public FeatureType getFeatureType() {
951
                try {
952
                        return store.getDefaultFeatureType();
953
                } catch (Exception ex) {
954
                        throw new RuntimeException("Can't retrieve the feature type.", ex);
955
                }
956
        }
957

    
958
        @Override
959
        public void setEnabled(boolean enabled) {
960
                if (!SwingUtilities.isEventDispatchThread()) {
961
                        SwingUtilities.invokeLater(() -> {
962
                                setEnabled(enabled);
963
                        });
964
                        return;
965
                }
966

    
967
                if (!this.initialized) { //this.conditionPanels == null) {
968
                        this.initComponents1();
969
                }
970
                for (SearchConditionPanel conditionPanel : conditionPanels) {
971
                        conditionPanel.setEnabled(enabled);
972
                }
973

    
974
                this.btnClear.setEnabled(enabled);
975
                this.btnSearch.setEnabled(enabled);
976
                for (ActionButtons actionButton : actions.values()) {
977
                        actionButton.action.setEnabled(enabled);
978
                }
979
                this.btnSearchPostProcess.setEnabled(enabled);
980
                //bookmarkController,historyController,configurableActions
981
        }
982

    
983
        @Override
984
        public void clear() {
985
                this.taskStatusController.setTitle("");
986
                if (!this.initialized) { //this.conditionPanels == null) {
987
                        return;
988
                }
989
                for (SearchConditionPanel conditionPanel : conditionPanels) {
990
                        conditionPanel.clear();
991
                }
992
                FeatureQuery emptyQuery = this.store.createFeatureQuery();
993
                emptyQuery.retrievesAllAttributes();
994
                this.parameters.setQuery(emptyQuery);
995
                // Mantener las columnas visualizadas
996
                // Elimina las que no existen en el store como campos calculados que
997
                // pudieran existir en el fquery
998
                List<String> resultColumnNames = this.parameters.getResultColumnNames();
999
                ArrayList<String> toDeleteAlreadyDontExist = new ArrayList<>();
1000
                for (String resultColumnName : resultColumnNames) {
1001
                        try {
1002
                                FeatureAttributeDescriptor attr = this.store.getDefaultFeatureType().getAttributeDescriptor(resultColumnName);
1003
                                if (attr == null) {
1004
                                        toDeleteAlreadyDontExist.add(resultColumnName);
1005
                                }
1006
                        } catch (DataException ex) {
1007

    
1008
                        }
1009
                }
1010
                resultColumnNames.removeAll(toDeleteAlreadyDontExist);
1011
                resetTable();
1012
        }
1013

    
1014
        @Override
1015
        public FeatureQuery getLastQuery() {
1016
                return this.lastQuery;
1017
        }
1018

    
1019
        public boolean isValid(StringBuilder message) {
1020
                int searchMode = this.tabSearchMode.getSelectedIndex();
1021
                SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1022
                boolean valid = panel.isValid(message);
1023
                return valid;
1024
        }
1025

    
1026
        public String getWarnings() {
1027
                int searchMode = this.tabSearchMode.getSelectedIndex();
1028
                SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1029
                String s = panel.getWarnings();
1030
                if( StringUtils.isBlank(s) ) {
1031
                    return null;
1032
                }
1033
                return s;
1034
        }
1035
        
1036
        @Override
1037
        public int search() {
1038
                StringBuilder message = new StringBuilder();
1039
                if (!this.isValid(message)) {
1040
                        ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
1041
                        dialogManager.messageDialog(
1042
                                "_The_specified_search_condition_is_not_valid",
1043
                                "_Search",
1044
                                JOptionPane.WARNING_MESSAGE
1045
                        );
1046
                        return STATUS_NOT_VALID;
1047
                }
1048
                String warnings = this.getWarnings();
1049
                if( StringUtils.isNotBlank(warnings) ) {
1050
                        ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
1051
                        int n = dialogManager.confirmDialog(
1052
                                "The indicated search can cause problems." + 
1053
                                        "\n" + warnings + "\n" +
1054
                                        "Do you want to run it anyway?",
1055
                                "_Search",
1056
                                JOptionPane.YES_NO_OPTION,
1057
                                JOptionPane.WARNING_MESSAGE
1058
                        );
1059
                        if( n == JOptionPane.NO_OPTION ) {
1060
                            return STATUS_OK;
1061
                        }
1062
                }
1063
                lblMsg.setText(ToolsLocator.getI18nManager().getTranslation("_Searching") + "...");
1064
                setEnabled(false);
1065
                Thread th = new Thread(() -> {
1066
                        try {
1067
                                SearchParameters searchParams;
1068
                                try {
1069
                                        searchParams = this.fetch(this.parameters.getCopy()); // esto lo actualiza a la ultima // decidir si se devuelve clonado
1070

    
1071
                                        Date date = Calendar.getInstance().getTime();
1072
                                        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
1073
                                        String strDate = dateFormat.format(date);
1074
                                        searchParams.setName("Params: " + strDate);
1075
                                } catch (Exception ex) {
1076
                                        LOGGER.warn("Not able to create search parameters.", ex);
1077
                                        this.taskStatusController.setTitle(ToolsLocator.getI18nManager().getTranslation("_Errors_fetching_new_query") + "...");
1078
                                        resetTable();
1079
                                        return;
1080
                                }
1081
                                doSearch(searchParams);
1082
                        } catch (Exception ex) {
1083
                                LOGGER.warn("Search panel has errors during the search", ex);
1084
                                resetTable();
1085
                        } finally {
1086
                                SwingUtilities.invokeLater(() -> {
1087
                                        setEnabled(true);
1088
                                });
1089
                        }
1090
                });
1091
                th.start();
1092
                return STATUS_OK;
1093
        }
1094

    
1095
        @Override
1096
        public int search(SearchParameters searchParams) {
1097
            ((DefaultSearchParameters)searchParams).fix(this.getFeatureType());
1098
            return doSearch(searchParams);
1099
        }
1100
        
1101
        private synchronized int doSearch(SearchParameters searchParams) {
1102
                final MutableObject model = new MutableObject(null);
1103
                final MutableLong rowCount = new MutableLong();
1104
                Cursor savedCursor = this.getCursor();
1105
                SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("");
1106
                status.setAutoremove(true);
1107
                status.add();
1108
                this.taskStatusController.bind(status);
1109
                List<Feature> features = null;
1110
                try {
1111
                    LOGGER.info("Do search");
1112
                        status.setTitle(ToolsLocator.getI18nManager().getTranslation("_Processing_search"));
1113
                        SwingUtilities.invokeLater(() -> {
1114
                            if(this.initialized){
1115
                                this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1116
                            }
1117
                        });
1118
                        List<String> resultColumnNames = searchParams.getResultColumnNames();
1119
                        FeatureQuery myQuery = searchParams.getQueryToApply();
1120
                        if( this.useSelection() ) {
1121
                            myQuery = this.addSelection(this.store, myQuery);
1122
                        }
1123
                        features = store.getFeatures(myQuery, 50);
1124
                        FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
1125
                        FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
1126
                        // al modelo le pasamos el ftype de esas features
1127
                        SimpleFeaturesTableModel tableModel = new SimpleFeaturesTableModelImpl(
1128
                                ftype,
1129
                                resultColumnNames,
1130
                                features
1131
                        );
1132
                        model.setValue(tableModel);
1133
                        rowCount.setValue(features.size());
1134
                        if(rowCount.longValue() > 0){
1135
                            //Force to get first row in this thread
1136
                            Feature f = features.get(0);
1137
                        }
1138
                        resultModel = (SimpleFeaturesTableModel) model.getValue();
1139
                        SwingUtilities.invokeLater(() -> {
1140
                            if(this.initialized){
1141
                                I18nManager i18n = ToolsLocator.getI18nManager();
1142
                                try {
1143
                                        if( this.tabResults.getSelectedIndex()==1 ) {
1144
                                            this.tabResults.setSelectedIndex(0);
1145
                                        }
1146
                                        TableModel oldmodel = tblResults.getModel();
1147
                                        tblResults.setModel(resultModel);
1148
                                        resultModel.setCellRenderers(tblResults, getCustomRenderers(searchParams));
1149
                                        if (oldmodel instanceof SimpleFeaturesTableModelImpl) {
1150
                                                ((SimpleFeaturesTableModelImpl) oldmodel).dispose();
1151
                                        }
1152
                                        if (resultModel.hasErrors()) {
1153
                                                status.setTitle(i18n.getTranslation("_Errors_occurred_during_search"));
1154
                                        } else {
1155
                                                status.setTitle(String.format("%d " + i18n.getTranslation("_elements"), rowCount.getValue()));
1156
                                        }
1157
                                        if (this.parameters != null && this.parameters.getQuery() != null) {
1158
                                                this.history.add(searchParams);
1159
                                        }
1160
                                        this.fireSearchEvent();
1161
                                } catch (Exception ex) {
1162
                                        LOGGER.warn(" Errors occurred during search getting old model", ex);
1163
                                        status.setTitle(i18n.getTranslation("_Errors_occurred_during_search"));
1164
                                } finally {
1165
                                        setEnabled(true);
1166
                                        status.terminate();
1167
                                        this.setCursor(savedCursor);
1168
                                }
1169
                            }
1170
                        });
1171
                        
1172
                } catch (Exception ex) {
1173
                        LOGGER.warn("Search not able to be executed. Can't get features or create table model", ex);
1174
                        status.setTitle(ToolsLocator.getI18nManager().getTranslation("_Errors_getting_new_feature_set") + "...");
1175
                        status.abort();
1176
                        DisposeUtils.disposeQuietly(features);
1177
                        this.lastErrorMessage = this.getLastErrorMessage(ex);
1178
                        if(StringUtils.isNotBlank(this.lastErrorMessage)){
1179
                            status.setTitle(this.lastErrorMessage);
1180
                        }
1181
                        resetTable();
1182
                        return STATUS_ERROR1;
1183
                }
1184
                return STATUS_OK;
1185
        }
1186

    
1187
        @Override
1188
        public SimpleFeaturesTableModel getResultsTableModel() {
1189
            return this.resultModel;
1190
        }
1191
        
1192
        private Map<String, TableCellRenderer> getCustomRenderers(SearchParameters parameters) {
1193
                FeatureType ft = this.store.getDefaultFeatureTypeQuietly();
1194
                HashMap<String, TableCellRenderer> renderers = new HashMap<>();
1195
                for (FeatureAttributeDescriptor attr : ft) {
1196
                        if (attr.getDataType().isNumeric()) {
1197
//                renderers.put(attr.getName(), new ColorRangeRenderer(attr, 20, 50));
1198
                        }
1199
                }
1200
                return renderers;
1201
        }
1202

    
1203
        private void resetTable() {
1204
                if (!SwingUtilities.isEventDispatchThread()) {
1205
                        SwingUtilities.invokeLater(() -> {
1206
                            if(this.initialized){
1207
                                resetTable();
1208
                            }
1209
                        });
1210
                        return;
1211
                }
1212
                List<String> resultColumnNames = null;
1213
                try {
1214
                        resultColumnNames = this.parameters.getResultColumnNames();
1215
                } catch (Exception ex) {
1216

    
1217
                }
1218
                FeatureType ftype = this.store.getDefaultFeatureTypeQuietly();
1219
                SimpleFeaturesTableModelImpl emptyTableModel = new SimpleFeaturesTableModelImpl(
1220
                        ftype,
1221
                        resultColumnNames,
1222
                        null
1223
                );
1224
                this.tblResults.setModel(emptyTableModel);
1225

    
1226
        }
1227

    
1228
        public void setResultColumnNames(List<String> names) {
1229
                this.parameters.getResultColumnNames().clear();
1230
                this.parameters.getResultColumnNames().addAll(names);
1231
//        if (this.conditionPanels == null) {
1232
//            return;
1233
//        }
1234
//        SimpleFeaturesTableModelImpl model;
1235
////        model = (SimpleFeaturesTableModel) this.tblResults.getModel();
1236
//        List<Feature> features = store.getFeatures(this.parameters.getQuery());
1237
//        FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
1238
//        FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
1239
//        model = new SimpleFeaturesTableModelImpl(
1240
//                ftype,
1241
//                this.parameters.getResultColumnNames(),
1242
//                features
1243
//        );
1244
//        tblResults.setModel(model);
1245
        }
1246

    
1247
        @Override
1248
        public boolean setFilter(Expression filter) {
1249
                try {
1250
                        if (!this.initialized) { //this.conditionPanels == null) {
1251
                                this.initComponents1();
1252
                        }
1253
                        if (ExpressionUtils.isPhraseEmpty(filter)) {
1254
                                this.clear();
1255
                                return true;
1256
                        }
1257
                        int panel = 0;
1258
                        int selected = PANEL_ADVANCED;
1259
                        for (SearchConditionPanel conditionPanel : conditionPanels) {
1260
                                if (panel != PANEL_ADVANCED && conditionPanel.set(filter)) {
1261
                                        selected = panel;
1262
                                }
1263
                                panel++;
1264
                        }
1265
                        this.tabSearchMode.setSelectedIndex(selected);
1266

    
1267
//            SimpleFeaturesTableModel model = new SimpleFeaturesTableModel(this.getStore());
1268
//            tblResults.setModel(model);
1269
//            lblMsg.setText("");
1270
                        return true;
1271
                } catch (Exception ex) {
1272
                        LOGGER.warn("Can't set current search", ex);
1273
                        return false;
1274
                }
1275
        }
1276

    
1277
        @Override
1278
        public List<SearchConditionPanel> getConditionPanels() {
1279
                return Collections.unmodifiableList(this.conditionPanels);
1280
        }
1281

    
1282
        @Override
1283
        public SearchConditionPanel getConditionPanel(String name) {
1284
                if (conditionPanels == null) {
1285
                        return null;
1286
                }
1287
                for (SearchConditionPanel panel : conditionPanels) {
1288
                        if (StringUtils.equalsIgnoreCase(name, panel.getFactory().getName())) {
1289
                                return panel;
1290
                        }
1291
                }
1292
                return null;
1293
        }
1294

    
1295
        public FeatureSelection getSelectedFeatures() {
1296
                if (!this.initialized) {
1297
                        return null;
1298
                }
1299
                int[] selectedRows = this.tblResults.getSelectedRows();
1300
                if( ArrayUtils.isEmpty(selectedRows) ) {
1301
                    return null;
1302
                }
1303
                if (this.tabResults.getSelectedIndex() == 1) {
1304
                    if (this.currentPostProcess == null) {
1305
                            return null;
1306
                    }
1307
                    try {
1308
                            FeatureSelection selection = this.store.createFeatureSelection();
1309
                            List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblSearchPostProcessResults.getModel()).getFeatures();
1310
                            for (int i = 0; i < selectedRows.length ; i++) {
1311
                                Feature feature = features.get(selectedRows[i]);
1312
                                selection.select(feature);
1313
                            }
1314
                            return selection==null? null:selection;
1315
                    } catch (Exception ex) {
1316
                            LOGGER.warn("Can't build search for the selected feature.", ex);
1317
                            return null;
1318
                    }
1319
                } else {
1320
                    try {
1321
                            FeatureSelection selection = this.store.createFeatureSelection();
1322
                            List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblResults.getModel()).getFeatures();
1323
                            for (int i = 0; i < selectedRows.length ; i++) {
1324
                                Feature feature = features.get(selectedRows[i]);
1325
                                selection.select(feature);
1326
                            }
1327
                            return selection==null? null:selection;
1328
                    } catch (Exception ex) {
1329
                            LOGGER.warn("Can't build search for the selected feature.", ex);
1330
                            return null;
1331
                    }
1332
                }
1333
        }
1334
        
1335
        @Override
1336
        public Expression getFilterForSelectedFeatures() {
1337
                int maxfeatures = 100;
1338
                
1339
                if (!this.initialized) {
1340
                        return null;
1341
                }
1342
                int[] selectedRows = this.tblResults.getSelectedRows();
1343
                if( ArrayUtils.isEmpty(selectedRows) ) {
1344
                    return null;
1345
                }
1346
                if( selectedRows.length > maxfeatures ) {
1347
                    this.taskStatusController.message("Too many items selecteds");
1348
                }
1349
                if (this.tabResults.getSelectedIndex() == 1) {
1350
                        if (this.currentPostProcess == null) {
1351
                                return null;
1352
                        }
1353
                        try {
1354
                                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1355
                                List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblSearchPostProcessResults.getModel()).getFeatures();
1356
                                for (int i = 0; i < selectedRows.length && i<maxfeatures; i++) {
1357
                                    Feature feature = features.get(selectedRows[i]);
1358
                                    FeatureType ftype = this.postProcessStore.getDefaultFeatureType();
1359
                                    for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1360
                                            builder.or(
1361
                                                    builder.eq(
1362
                                                            builder.column(attrdesc.getName()),
1363
                                                            builder.constant(feature.get(attrdesc.getName()))
1364
                                                    )
1365
                                            );
1366
                                    }
1367
                                }
1368
                                Expression filter = ExpressionUtils.createExpression(builder.toString());
1369
                                return filter;
1370
                        } catch (Exception ex) {
1371
                                LOGGER.warn("Can't build search for the selected feature.", ex);
1372
                                return null;
1373
                        }
1374
                } else {
1375
                    try {
1376
                            FeatureType ftype = this.store.getDefaultFeatureType();
1377
                            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1378
                            List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblResults.getModel()).getFeatures();
1379
                            for (int i = 0; i < selectedRows.length && i<maxfeatures ; i++) {
1380
                                Feature feature = features.get(selectedRows[i]);
1381
                                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1382
                                        builder.or(
1383
                                                builder.eq(
1384
                                                        builder.column(attrdesc.getName()),
1385
                                                        builder.constant(feature.get(attrdesc.getName()))
1386
                                                )
1387
                                        );
1388
                                }
1389
                            }
1390
                            Expression filter = ExpressionUtils.createExpression(builder.toString());                            
1391
                            return filter;
1392
                    } catch (Exception ex) {
1393
                            LOGGER.warn("Can't build search for the selected feature.", ex);
1394
                            return null;
1395
                    }
1396
                }
1397
        }
1398
        
1399
        @Override
1400
        public Expression getFilterForSelectedFeature() {
1401
                if (!this.initialized) { //this.conditionPanels == null) {
1402
                        return null;
1403
                }
1404
                if (this.tabResults.getSelectedIndex() == 1) {
1405
                        if (this.currentPostProcess == null) {
1406
                                return null;
1407
                        }
1408
                        int selectedRow = this.tblSearchPostProcessResults.getSelectedRow();
1409
                        if (selectedRow < 0) {
1410
                                return null;
1411
                        }
1412
                        try {
1413
                                List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblSearchPostProcessResults.getModel()).getFeatures();
1414
                                Feature feature = features.get(selectedRow);
1415

    
1416
                                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1417
                                FeatureType ftype = this.postProcessStore.getDefaultFeatureType();
1418
                                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1419
                                        builder.and(
1420
                                                builder.eq(
1421
                                                        builder.column(attrdesc.getName()),
1422
                                                        builder.constant(feature.get(attrdesc.getName()))
1423
                                                )
1424
                                        );
1425
                                }
1426
                                Expression filter = ExpressionUtils.createExpression(builder.toString());
1427
                                return filter;
1428
                        } catch (Exception ex) {
1429
                                LOGGER.warn("Can't build search for the selected feature.", ex);
1430
                                return null;
1431
                        }
1432
                } else {
1433
                        int selectedRow = this.tblResults.getSelectedRow();
1434
                        if (selectedRow < 0) {
1435
                                return null;
1436
                        }
1437
                        try {
1438
                                List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblResults.getModel()).getFeatures();
1439
                                Feature feature = features.get(selectedRow);
1440

    
1441
                                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1442
                                FeatureType ftype = this.store.getDefaultFeatureType();
1443
                                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1444
                                        builder.and(
1445
                                                builder.eq(
1446
                                                        builder.column(attrdesc.getName()),
1447
                                                        builder.constant(feature.get(attrdesc.getName()))
1448
                                                )
1449
                                        );
1450
                                }
1451
                                Expression filter = ExpressionUtils.createExpression(builder.toString());
1452
                                return filter;
1453
                        } catch (Exception ex) {
1454
                                LOGGER.warn("Can't build search for the selected feature.", ex);
1455
                                return null;
1456
                        }
1457
                }
1458

    
1459
        }
1460

    
1461
        @Override
1462
        public FeatureStore getStore() {
1463
                return store;
1464
        }
1465

    
1466
        private void doOrderBy() {
1467
            try {
1468
                LOGGER.info("Do show order by");
1469
                I18nManager i18n = ToolsLocator.getI18nManager();
1470
                WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1471
                FeatureQueryOrderPanel orderPanel = DALSwingLocator.getDataSwingManager().createFeatureStoreOrderPanel();
1472
                orderPanel.setStore(store);
1473
                orderPanel.put(parameters.getQuery());
1474
                Dialog dialog = windowManager.createDialog(
1475
                        orderPanel.asJComponent(),
1476
                        i18n.getTranslation("_Select_order"),
1477
                        null,
1478
                        WindowManager_v2.BUTTONS_OK_CANCEL
1479
                );
1480
                dialog.addActionListener((ActionEvent e) -> {
1481
                        if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
1482
                                orderPanel.fetch(this.parameters.getQuery());
1483
                                search();
1484
                        }
1485
                });
1486
                dialog.show(WindowManager.MODE.DIALOG);
1487
            } catch (Exception ex) {
1488
                LOGGER.warn("Can't show dialog", ex);
1489
            }
1490
        }
1491

    
1492
    private void doExportTSV(JTable table) {
1493
        try {
1494
            LOGGER.info("Do export TSV");
1495
            final SimpleFeaturesTableModel model;
1496
            if (table.getModel() instanceof SimpleFeaturesTableModel) {
1497
                model = (SimpleFeaturesTableModel) table.getModel();
1498
            } else {
1499
                model = null;
1500
            }
1501
            I18nManager i18n = ToolsLocator.getI18nManager();
1502
            if (model == null) {
1503
                ToolsSwingLocator.getThreadSafeDialogsManager().messageDialog(
1504
                        i18n.getTranslation("_Not_able_to_export_table_to_TSV"),
1505
                        i18n.getTranslation(EXPORT_TO_TSV_TITLE),
1506
                        JOptionPane.WARNING_MESSAGE);
1507
                return;
1508
            }
1509

    
1510
            FileFilter fileFilter = new FileFilter() {
1511
                @Override
1512
                public boolean accept(File f) {
1513
                    if (f.isDirectory()) {
1514
                        return true;
1515
                    }
1516
                    String extension = FilenameUtils.getExtension(f.getAbsolutePath());
1517
                    return StringUtils.equalsIgnoreCase(TSV_EXTENSION, extension);
1518
                }
1519

    
1520
                @Override
1521
                public String getDescription() {
1522
                    return "TSV file";
1523
                }
1524
            };
1525
            FoldersManager folderManager = ToolsLocator.getFoldersManager();
1526
            File initialFolder = folderManager.getLastPath(EXPORT_TO_TSV_LASTPATHID);
1527

    
1528
            ThreadSafeDialogsManager safeDialogsManager = ToolsSwingLocator.getThreadSafeDialogsManager();
1529
            ImmutablePair<File[], Charset> pair = safeDialogsManager.showChooserDialog(
1530
                    i18n.getTranslation(EXPORT_TO_TSV_TITLE),
1531
                    SAVE_DIALOG,
1532
                    FILES_ONLY,
1533
                    false,
1534
                    initialFolder,
1535
                    fileFilter,
1536
                    initialized,
1537
                    true
1538
            );
1539

    
1540
            if (pair == null) {
1541
                return;
1542
            }
1543
            File[] files = pair.getLeft();
1544
            Charset charset = pair.getRight();
1545
            if (files.length < 1) {
1546
                return;
1547
            }
1548
            File f = files[0];
1549
            if (f == null) {
1550
                return;
1551
            }
1552
            if (f.isDirectory()) {
1553
                return;
1554
            }
1555
            if (FilenameUtils.getExtension(f.getName()).isEmpty()) {
1556
                f = new File(f.getAbsolutePath() + FilenameUtils.EXTENSION_SEPARATOR + "tsv");
1557
            }
1558
            if (f.exists()) {
1559
                int res = safeDialogsManager.confirmDialog(
1560
                        i18n.getTranslation("fichero_ya_existe_seguro_desea_guardarlo"),
1561
                        i18n.getTranslation(EXPORT_TO_TSV_TITLE),
1562
                        WIDTH,
1563
                        HEIGHT
1564
                );
1565
                if (res != YES_OPTION) {
1566
                    return;
1567
                }
1568
            }
1569

    
1570
            final File file = f;
1571

    
1572
            folderManager.setLastPath(EXPORT_TO_TSV_LASTPATHID, file.getParentFile());
1573
            Cursor savedCursor = this.getCursor();
1574
            SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("");
1575
            status.setAutoremove(true);
1576
            status.add();
1577
            this.taskStatusController.bind(status);
1578
            
1579
            SearchParameters searchParams = this.fetch(this.parameters.getCopy()); 
1580
            final FeatureQuery myQuery;
1581
            if( this.useSelection() ) {
1582
                myQuery = this.addSelection(this.store, searchParams.getQueryToApply());
1583
            } else {
1584
                myQuery = searchParams.getQueryToApply();
1585
            }
1586
            
1587
            Thread task = new Thread(() -> {
1588
                try {
1589
                    this.processing = true;
1590
                    this.updateComponentState();
1591
                    SwingUtilities.invokeLater(() -> {
1592
                        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1593
                    });
1594
                    status.setTitle(i18n.getTranslation(EXPORT_TO_TSV_TITLE));
1595

    
1596
                    Pair<Iterator<Feature>, Long> features = buildExportIterator(table, store, myQuery);
1597

    
1598
                    ExportTSV exportTSV = new ExportTSV();
1599
                    exportTSV.process(features.getLeft(), features.getRight(), model, file, charset, status);
1600

    
1601
                } catch (Exception ex) {
1602
                    LOGGER.warn("Not able to export table to TSV", ex);
1603
                } finally {
1604
                    this.processing = false;
1605
                    SwingUtilities.invokeLater(() -> {
1606
                        this.setCursor(savedCursor);
1607
                    });
1608
                    this.updateComponentState();
1609
                }
1610
            }, "SearchPanelExportTSV");
1611
            task.start();
1612
        } catch (Exception ex) {
1613
            LOGGER.warn("Can't export TSV", ex);
1614
        }
1615
    }
1616

    
1617
        private void doCopyRows(JTable table) {
1618
                LOGGER.info("Do copy rows");
1619
                if (!(table.getModel() instanceof SimpleFeaturesTableModel)) {
1620
                    LOGGER.warn("Can't copy rows, wrong model.");
1621
                    return;
1622
                }
1623

    
1624
                final SimpleFeaturesTableModel model = (SimpleFeaturesTableModel) table.getModel();
1625

    
1626
                Cursor savedCursor = this.getCursor();
1627
                SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("");
1628
                status.setAutoremove(true);
1629
                status.add();
1630
                this.taskStatusController.bind(status);
1631
                Thread task = new Thread(() -> {
1632
                        try {
1633
                                this.processing = true;
1634
                                this.updateComponentState();
1635
                                SwingUtilities.invokeLater(() -> {
1636
                                        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1637
                                });
1638
                                String title = ToolsLocator.getI18nManager().getTranslation("_Copying_rows_to_clipboard");
1639
                                status.setTitle(title);
1640
                                status.message("");
1641
                                SearchParameters searchParams = this.fetch(this.parameters.getCopy()); 
1642
                                final FeatureQuery myQuery;
1643
                                if( this.useSelection() ) {
1644
                                    myQuery = this.addSelection(this.store, searchParams.getQueryToApply());
1645
                                } else {
1646
                                    myQuery = searchParams.getQueryToApply();
1647
                                }
1648
                                
1649
                                Pair<Iterator<Feature>, Long> features = buildExportIterator(table, store, myQuery);
1650
                                
1651
                                ExportTSV exportTSV = new ExportTSV();
1652
                                ByteArrayOutputStream fos = new ByteArrayOutputStream();
1653
                                
1654
                                exportTSV.process(
1655
                                        features.getLeft(), 
1656
                                        features.getRight(), 
1657
                                        model, 
1658
                                        fos, 
1659
                                        Charset.defaultCharset(), 
1660
                                        status
1661
                                );
1662

    
1663
                                String toStr = new String(fos.toByteArray(),Charset.defaultCharset());
1664

    
1665
                                SwingUtilities.invokeLater(() -> {
1666
                                        ToolsSwingLocator.getToolsSwingManager().putInClipboard(toStr);
1667
                                        status.setTitle(ToolsLocator.getI18nManager().getTranslation("_Copy_ended"));
1668
                                        status.terminate();
1669
                                });
1670

    
1671
                        } catch (Exception ex) {
1672
                                LOGGER.warn("Not able to copy rows to the clipboard", ex);
1673
                                status.message("Not able to copy rows to the clipboard");
1674
                                status.abort();
1675
                        } finally {
1676
                                this.processing = false;
1677
                                SwingUtilities.invokeLater(() -> {
1678
                                        this.setCursor(savedCursor);
1679
                                });
1680
                                this.updateComponentState();
1681
                        }
1682
                }, "SearchPanelCopyRows");
1683
                task.start();
1684
        }
1685

    
1686
    private Pair<Iterator<Feature>, Long> buildExportIterator(JTable table, FeatureStore store, FeatureQuery query) {
1687
        
1688
        if (!(table.getModel() instanceof SimpleFeaturesTableModel)) {
1689
            return null;
1690
        }
1691

    
1692
        final SimpleFeaturesTableModel model = (SimpleFeaturesTableModel) table.getModel();
1693
        
1694
        int[] selection = table.getSelectedRows();
1695
        
1696
        if(ArrayUtils.isEmpty(selection) || selection.length == model.size()) {
1697
            FeatureSet features = null;
1698
            try {
1699
                features = store.getFeatureSet(query);
1700
                return new ImmutablePair<>(features.fastIterator(),features.size64());
1701
            } catch(Exception e) {
1702
                throw new RuntimeException("Can't get features.", e);
1703
            } finally {
1704
                DisposeUtils.disposeQuietly(features);
1705
            }
1706
        }
1707
        Iterator<Feature> featIterator = new Iterator<Feature>() {
1708
            int row = 0;
1709

    
1710
            @Override
1711
            public boolean hasNext() {
1712
                return row < selection.length;
1713
            }
1714

    
1715
            @Override
1716
            public Feature next() {
1717
                int n = table.convertRowIndexToModel(selection[row++]);
1718
                return model.getFeatureAt(n);
1719
            }
1720
        };
1721
        return new ImmutablePair<>(featIterator, (long)selection.length);
1722

    
1723
    }
1724

    
1725
        @Override
1726
        public ImageIcon loadImage(String imageName) {
1727
            return ToolsSwingUtils.loadImage(this, imageName);
1728
        }
1729

    
1730
        @Override
1731
        public int getSelectedFeatureCount() {
1732
                if (!this.initialized) { //this.conditionPanels == null) {
1733
                        return 0;
1734
                }
1735
                if (this.currentPostProcess != null && this.tabResults.getSelectedIndex() == 1) {
1736
                        return this.tblSearchPostProcessResults.getSelectedRowCount();
1737
                }
1738
                return this.tblResults.getSelectedRowCount();
1739
        }
1740

    
1741
        @Override
1742
        public JComponent getActionButton(String name) {
1743
                ActionButtons actionButton = this.actions.get(name);
1744
                if (actionButton == null) {
1745
                        return null;
1746
                }
1747
                return actionButton.button;
1748
        }
1749

    
1750
        @Override
1751
        public void setShowActions(boolean showActions) {
1752
                this.showActions = showActions;
1753
        }
1754

    
1755
        @Override
1756
        public boolean isShowActions() {
1757
                return this.showActions;
1758
        }
1759

    
1760
        private void doCalculatedColumns() {
1761
            try {
1762
                LOGGER.info("Do show calculate columns");
1763
                WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1764
                I18nManager i18n = ToolsLocator.getI18nManager();
1765
                final FeatureQueryCalculatedColumnsPanel panel = new DefaultFeatureQueryCalculatedColumnsPanel();
1766
                panel.setStore(this.store);
1767
                panel.put(this.parameters.getQuery());
1768
                final Dialog dialog = winmanager.createDialog(
1769
                        panel.asJComponent(),
1770
                        i18n.getTranslation("_Calculated_columns"),
1771
                        null,
1772
                        WindowManager_v2.BUTTONS_OK_CANCEL
1773
                );
1774
                dialog.addActionListener((ActionEvent e) -> {
1775
                        if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1776
                                panel.fetch(this.parameters.getQuery());
1777
                                search();
1778
                        }
1779
                });
1780
                dialog.show(WindowManager.MODE.DIALOG);
1781
            } catch (Exception ex) {
1782
                LOGGER.warn("Can't show dialog", ex);
1783
            }
1784
        }
1785

    
1786
        private void doGroupBy() {
1787
            try {
1788
                LOGGER.info("Do show group by");
1789
                DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
1790
                int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
1791
                if (allowGroupBy != DataType.YES) {
1792
                        // FIXME: mensaje al usaurio.
1793
                        I18nManager i18n = ToolsLocator.getI18nManager();
1794
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1795
                        dialogs.messageDialog(
1796
                                i18n.getTranslation("_The_group_function_is_not_available_for_this_table"),
1797
                                i18n.getTranslation("_Information"),
1798
                                JOptionPane.INFORMATION_MESSAGE
1799
                        );
1800
                        return;
1801
                }
1802

    
1803
                WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1804
                I18nManager i18n = ToolsLocator.getI18nManager();
1805
                final DefaultSearchGroupByPanel panelGroupBy = new DefaultSearchGroupByPanel();
1806
                panelGroupBy.setStore(this.store);
1807
                panelGroupBy.put(this.parameters);
1808
                final Dialog dialog = winmanager.createDialog(
1809
                        panelGroupBy.asJComponent(),
1810
                        i18n.getTranslation("_Select_group_columns_and_aggregate_functions"),
1811
                        null,
1812
                        WindowManager_v2.BUTTONS_OK_CANCEL
1813
                );
1814
                dialog.addActionListener((ActionEvent e) -> {
1815
                        if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1816
                                panelGroupBy.fetch(this.parameters);
1817
                                search();
1818
                        }
1819
                });
1820
                dialog.show(WindowManager.MODE.DIALOG);
1821
            } catch (Exception ex) {
1822
                LOGGER.warn("Can't show dialog", ex);
1823
            }
1824
        }
1825

    
1826
        private void doSelectResultColumnNames() {
1827
            try {
1828
                LOGGER.info("Do select result column names");
1829
                WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1830
                I18nManager i18n = ToolsLocator.getI18nManager();
1831
                final FeatureAttributesSelectionPanel panelSelectColumns = DALSwingLocator.getManager().createFeatureAttributeSelectionPanel();
1832
                panelSelectColumns.allowCalculatedAttributes(false);
1833
                FeatureType ftype = this.getFeatureType();
1834
                panelSelectColumns.setFeatureType(ftype);
1835
                if(this.parameters.getQuery() != null){
1836
                    panelSelectColumns.setExtraColumns(this.parameters.getQuery().getExtraColumns().getColumns());
1837
                }
1838
                panelSelectColumns.setSelectedNames(this.parameters.getResultColumnNames());
1839
                final Dialog dialog = winmanager.createDialog(
1840
                        panelSelectColumns.asJComponent(),
1841
                        i18n.getTranslation("_Select_the_columns_to_display"),
1842
                        null,
1843
                        WindowManager_v2.BUTTONS_OK_CANCEL
1844
                );
1845
                dialog.addActionListener((ActionEvent e) -> {
1846
                        if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1847
                                this.setResultColumnNames(panelSelectColumns.getSelectedNames());
1848
                                search();
1849
                        }
1850
                });
1851
                dialog.show(WindowManager.MODE.DIALOG);
1852
            } catch (Exception ex) {
1853
                LOGGER.warn("Can't show dialog", ex);
1854
            }
1855
        }
1856

    
1857
        @Override
1858
        public void put(SearchParameters inParams) {
1859
                this.parameters = (DefaultSearchParameters) inParams;
1860
                for (SearchConditionPanel conditionPanel : this.conditionPanels) {
1861
                        try {
1862
                                conditionPanel.put(inParams);
1863
                        } catch (Exception ex) {
1864
                                LOGGER.warn("Can't open panel", ex);
1865
                        }
1866
                }
1867
                this.tabSearchMode.setSelectedIndex(inParams.getSearchMode());
1868

    
1869
        }
1870

    
1871
        private FeatureQuery getQuery() {
1872
                FeatureQuery query;
1873
                try {
1874
                        int searchMode = this.tabSearchMode.getSelectedIndex();
1875
                        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1876
                        Expression filter = panel.get();
1877
                        if (searchMode != PANEL_ADVANCED) {
1878
                                this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1879
                        }
1880
                        query = (FeatureQuery) this.parameters.getQuery().clone();
1881
                        query.retrievesAllAttributes();
1882
                        if (ExpressionUtils.isPhraseEmpty(filter)) {
1883
                                return query;
1884
                        }
1885
                        query.setFilter(Expression.cloneQuietly(filter));
1886
                        query.retrievesAllAttributes();
1887
                        return query;
1888
                } catch (Exception ex) {
1889
                        LOGGER.warn("Can't build query.", ex);
1890
                        return null;
1891
                }
1892
        }
1893

    
1894
        @Override
1895
        public SearchParameters fetch(SearchParameters outParams) {
1896
            if(!initialized){
1897
                this.initComponents1();
1898
            }
1899
                // Actualiza el fquery del parameters con los paneles
1900
                for (SearchConditionPanel conditionPanel : conditionPanels) {
1901
                        try {
1902
                                conditionPanel.fetch(this.parameters);
1903
                        } catch (Exception ex) {
1904
                                LOGGER.warn("Panel not able to fetch values", ex);
1905
                        }
1906
                }
1907

    
1908
                // Actualiza el filtro con el panel activo
1909
                int searchMode = this.tabSearchMode.getSelectedIndex();
1910
                SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1911
                Expression filter = panel.get();
1912
                if (searchMode != PANEL_ADVANCED) {
1913
                        this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1914
                }
1915
                this.parameters.setSearchMode(searchMode);
1916
                FeatureQuery query = (FeatureQuery) this.parameters.getQuery();
1917
                this.lastQuery = query.getCopy();
1918
                query.retrievesAllAttributes();
1919
                query.clearFilter();
1920
                if (!ExpressionUtils.isPhraseEmpty(filter)) {
1921
                        query.setFilter(filter);
1922
                        query.retrievesAllAttributes();
1923
                }
1924

    
1925
                if (outParams == null) {
1926
                        return this.parameters.getCopy();
1927
                }
1928
                outParams.copyFrom(this.parameters.getCopy());
1929
                return outParams;
1930
        }
1931

    
1932
        public static void selfRegister() {
1933
            boolean n = ToolsSwingUtils.registerIcons(
1934
                    DefaultSearchPanel.class, 
1935
                    "",
1936
                    LIBRARY_NAME,
1937
                    new String[]{"storeaction", "storeaction-select"},
1938
                    new String[]{"storeaction", "storeaction-select-add"},
1939
                    new String[]{"storeaction", "storeaction-select-filter"},
1940

    
1941
                    new String[]{"storesearch", "search-simplifiedcondition-edit-accumulate"},
1942
                    new String[]{"storesearch", "search-simplifiedcondition-clear-accumulate"},
1943
                    new String[]{"storesearch", "search-simplifiedcondition-add-accumulate"},
1944
                    
1945
                    new String[]{"storesearch", "search-nullbehavior-null"},
1946
                    new String[]{"storesearch", "search-nullbehavior-true"},
1947
                    new String[]{"storesearch", "search-nullbehavior-false"},
1948
                    
1949
                    new String[]{"storesearch", "search-geometry-select"},
1950
                    
1951
                    new String[]{"storesearch", "search-select-column"}
1952

    
1953
            );            
1954
            ToolsSwingUtils.registerGroupIconScreenshot(
1955
                    DefaultDALSwingLibrary.class, 
1956
                    "storesearch",
1957
                    "/org/gvsig/fmap/dal/screenshots/storesearch1.png"
1958
            );
1959
            ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
1960
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsYesAction());
1961
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsNoAction());
1962
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsBothAction());
1963
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new SelectColumnsAction());
1964
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new CalculatedColumnsAction());
1965
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new GroupByAction());
1966
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new OrderByAction());
1967
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new PropertiesAction());
1968
        }
1969

    
1970
        private void doSelectSearchPostprocess() throws DataException {
1971
                DataSwingManager manager = DALSwingLocator.getDataSwingManager();
1972
                Map<String, SearchPostProcessFactory> searchPostProcessFactoryMap = manager.getSearchPostProcess();
1973

    
1974
                JPopupMenu menu = new JPopupMenu();
1975
                for (String factory : searchPostProcessFactoryMap.keySet()) {
1976
                        JMenuItem item;
1977
                        item = new JMenuItem(factory);
1978
                        SearchParameters searchParams = this.fetch(this.parameters.getCopy());
1979
                        FeatureQuery myQuery = searchParams.getQueryToApply();
1980
                        item.addActionListener((ActionEvent e) -> {
1981
                                doSearchPostProcess(store, myQuery, manager.getSearchPostProcess(factory), searchParams);
1982
                        });
1983
                        menu.add(item);
1984
                }
1985
                menu.show(this.btnSearchPostProcess, 0, this.btnSearchPostProcess.getHeight());
1986
        }
1987

    
1988
        private void doExecuteSearchPostProcess(
1989
                FeatureStore input,
1990
                FeatureQuery query,
1991
                SearchPostProcessFactory factory,
1992
                DynObject parameters
1993
        ) {
1994
                LOGGER.info("Do execute post process");
1995
                Cursor savedCursor = this.getCursor();
1996
                SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("");
1997
                status.setAutoremove(true);
1998
                status.add();
1999
                this.taskStatusController.bind(status);
2000
                Thread task = new Thread(() -> {
2001
                        try {
2002
                                SwingUtilities.invokeLater(() -> {
2003
                                        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
2004
                                });
2005
                                this.processing = true;
2006
                                this.updateComponentState();
2007
                                SearchPostProcess process = factory.createProcess(factory, input, query, parameters);
2008

    
2009
                                if (parameters != null) {
2010
                                        process.setParameters(parameters);
2011
                                }
2012
                                //Ejecutar el execute en thread para no bloquear el software
2013
                                SearchPostProcess.SearchPostProcessResult output = process.execute(input, query, parameters, status);
2014
                                if (output != null) {
2015
                                        this.postProcessStore = output.getStore();
2016
                                        this.postProcessQuery = output.getQuery();
2017

    
2018
                                        doLoadSearchPostProccessResults(this.postProcessStore);
2019

    
2020
                                }
2021
                                this.currentPostProcess = factory.getName();
2022
                                status.terminate();
2023

    
2024
                        } catch (Exception ex) {
2025
                                LOGGER.warn("SearchPostProcess not able to be executed.", ex);
2026
                                resetPostProcessTable();
2027
                                status.setTitle(ToolsLocator.getI18nManager().getTranslation("_Error_in_post_process_operation"));
2028
                                status.message("");
2029
                                status.abort();
2030
                        } finally {
2031
                                SwingUtilities.invokeLater(() -> {
2032
                                        this.setCursor(savedCursor);
2033
                                });
2034
                                this.processing = false;
2035
                                this.updateComponentState();
2036
                        }
2037
                }, "ExecuteSearchPostProcess");
2038

    
2039
                task.start();
2040

    
2041
        }
2042

    
2043
        private void doLoadSearchPostProccessResults(FeatureStore input) {
2044
                if (!SwingUtilities.isEventDispatchThread()) {
2045
                        SwingUtilities.invokeLater(() -> {
2046
                                doLoadSearchPostProccessResults(input);
2047
                        });
2048
                        return;
2049
                }
2050

    
2051
                final List<Feature> featuresSearchPostProccessResults;
2052
                final FeatureQuery finalQuery;
2053
                finalQuery = null;
2054
                try {
2055
                        this.tabResults.setEnabledAt(1, true);
2056
                        this.tabResults.setSelectedIndex(1);
2057
                        featuresSearchPostProccessResults = input.getFeatures(finalQuery, 20);
2058
                        FacadeOfAFeaturePagingHelper facadeSearchPostProccessResults = (FacadeOfAFeaturePagingHelper) featuresSearchPostProccessResults;
2059
                        FeatureType ftypeSearchPostProccessResults = facadeSearchPostProccessResults.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
2060
                        // al modelo le pasamos el ftype de esas features
2061
                        resultPostProcessModel = new SimpleFeaturesTableModelImpl(
2062
                                ftypeSearchPostProccessResults,
2063
                                this.parameters.getResultColumnNames(),
2064
                                featuresSearchPostProccessResults
2065
                        );
2066

    
2067
                        I18nManager i18n = ToolsLocator.getI18nManager();
2068
                        TableModel oldmodel = tblSearchPostProcessResults.getModel();
2069
                        tblSearchPostProcessResults.setModel(resultPostProcessModel);
2070
                        resultPostProcessModel.setCellRenderers(tblSearchPostProcessResults);
2071
                        if (oldmodel instanceof SimpleFeaturesTableModel) {
2072
                                ((SimpleFeaturesTableModel) oldmodel).dispose();
2073
                        }
2074
                        updateNumberElementsMsg(resultPostProcessModel);
2075
//            if (resultPostProcessModel.hasErrors()) {
2076
//                lblMsg.setText("_Errors_occurred_load_search_post_process");
2077
//            } else {
2078
//                lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), resultPostProcessModel.getRowCount()));
2079
//            }
2080
                } catch (Exception ex) {
2081
                        resetPostProcessTable();
2082
                        LOGGER.warn("SearchPostProcess not able to be executed. Can't get features or create table model", ex);
2083
                }
2084
        }
2085

    
2086
        private void updateComponentState() {
2087
                if (!SwingUtilities.isEventDispatchThread()) {
2088
                        SwingUtilities.invokeLater(this::updateComponentState);
2089
                        return;
2090
                }
2091
                this.pgbStatus.setVisible(processing);
2092
                this.setEnabled(!processing);
2093
        }
2094

    
2095
        private void resetPostProcessTable() {
2096
                if (!SwingUtilities.isEventDispatchThread()) {
2097
                        SwingUtilities.invokeLater(this::resetPostProcessTable);
2098
                        return;
2099
                }
2100

    
2101
                this.tblSearchPostProcessResults.setModel(new DefaultTableModel());
2102
        }
2103

    
2104
        private void doSearchPostProcess(FeatureStore store, FeatureQuery query, SearchPostProcessFactory factory, SearchParameters searchParams) {
2105
                LOGGER.info("Do search post process");
2106
                if (factory.hasProcessParameters()) {
2107
                        DynObject parametersPostProcess = factory.createProcessParameters(store, query, searchParams);
2108
                        JDynForm form = DynFormLocator.getDynFormManager().createJDynForm(parametersPostProcess);
2109
                        form.setLayoutMode(JDynForm.USE_SEPARATORS);
2110

    
2111
                        I18nManager i18n = ToolsLocator.getI18nManager();
2112
                        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
2113

    
2114
                        Dialog dialog = windowManager.createDialog(
2115
                                form.asJComponent(),
2116
                                i18n.getTranslation("_Postprocess_parameters"),
2117
                                i18n.getTranslation(
2118
                                        "_Parameters_for_XpostprocessNameX_postprocess_on_XtableNameX",
2119
                                        new String[]{
2120
                                                factory.getName(),
2121
                                                this.store.getName()
2122
                                        }
2123
                                ),
2124
                                WindowManager_v2.BUTTONS_OK_CANCEL);
2125

    
2126
                        ToolsSwingUtils.ensureRowsCols(dialog.asJComponent(), 20, 60, 30, 100);
2127
                        dialog.addActionListener((ActionEvent e2) -> {
2128
                                if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
2129
                                        form.getValues(parametersPostProcess); // actualiza el valor de lo los parametros con los valores introducidos por el usuario
2130
                                        doExecuteSearchPostProcess(store, query, factory, parametersPostProcess);
2131
                                        this.postProcessParams = parametersPostProcess;
2132
                                }
2133
                        });
2134

    
2135
                        dialog.show(WindowManager.MODE.DIALOG);
2136

    
2137
                } else {
2138
                        doExecuteSearchPostProcess(store, query, factory, null);
2139
                }
2140
        }
2141

    
2142
        private void updateNumberElementsMsg(SimpleFeaturesTableModel model) {
2143
                I18nManager i18n = ToolsLocator.getI18nManager();
2144

    
2145
                if (model.hasErrors()) {
2146
                        this.taskStatusController.setTitle(i18n.getTranslation("_Errors_occurred_load_search_post_process"));
2147
                } else {
2148
                        this.taskStatusController.setTitle(String.format("%d " + i18n.getTranslation("_elements"), model.getRowCount()));
2149
                }
2150
        }
2151

    
2152
        @Override
2153
        public boolean isVisible(Object component) {
2154
                if (this.filterOnlyMode || !this.isGroupByEnabled()) {
2155
                        if (component instanceof GroupByAction) {
2156
                                return false;
2157
                        }
2158
//            if( component instanceof OrderByAction ) {
2159
//                return false;
2160
//            }
2161
//            if( component instanceof CalculatedColumnsAction ) {
2162
//                return false;
2163
//            }
2164
                }
2165
                return true;
2166
        }
2167

    
2168
        @Override
2169
        public boolean isEnabled(Object component) {
2170
                if (component instanceof GroupByAction) {
2171
                        DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
2172
                        int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
2173
                        if (allowGroupBy != DataType.YES) {
2174
                                return false;
2175
                        }
2176
                }
2177
                return true;
2178
        }
2179

    
2180
        @Override
2181
        public void setFilterOnlyMode(boolean filterOnlyMode) {
2182
            if (this.initialized) {
2183
                throw new IllegalStateException("Cannot change filter-only-mode after invoking asJComponent.");
2184
            }
2185
            this.filterOnlyMode = filterOnlyMode;
2186
            this.groupByEnabled = false;
2187
            this.postProcessEnabled = false;
2188
            this.showActions = false;
2189
        }
2190

    
2191
        @Override
2192
        public boolean isFilterOnlyMode() {
2193
                return this.filterOnlyMode;
2194
        }
2195

    
2196
        @Override
2197
        public Feature getLastSelectedFeature() {
2198
                return this.lastSelectedFeature;
2199
        }
2200

    
2201
        @Override
2202
        public Object getProperty(String name) {
2203
                return this.propertiesHelper.getProperty(name);
2204
        }
2205

    
2206
        @Override
2207
        public void setProperty(String name, Object value) {
2208
                this.propertiesHelper.setProperty(name, value);
2209
        }
2210

    
2211
        @Override
2212
        public Map<String, Object> getProperties() {
2213
                return this.propertiesHelper.getProperties();
2214
        }
2215

    
2216
        @Override
2217
    public void setAutomaticallySearch(boolean automaticallySearch){
2218
        this.automaticallySearch = automaticallySearch;
2219
    }
2220
    
2221
        @Override
2222
    public boolean isAutomaticallySearch(){
2223
        return automaticallySearch;
2224
    }
2225

    
2226
    @Override
2227
    public String getLastErrorMessage() {
2228
        return this.lastErrorMessage;
2229
    }
2230
    
2231
    private String getLastErrorMessage(Throwable ex) {
2232
        StringBuilder builder = new StringBuilder();
2233
        while (ex != null){
2234
            if(ex instanceof SQLException){
2235
                builder.append(ex.getLocalizedMessage());
2236
                builder.append("\n");
2237
            }
2238
            ex = ex.getCause();
2239
        }
2240
        return builder.toString();
2241
    }
2242
    
2243
    private void doCopyQueryToCLipboard(FeatureQuery query) {
2244
        ToolsSwingLocator.getToolsSwingManager().putInClipboard(query.toJson().toString());
2245
    }
2246
    
2247
    private void doShowProperties() {
2248
        try {
2249
            LOGGER.info("Do show properties");
2250
            ToolsSwingManager toolSwingManager = ToolsSwingLocator.getToolsSwingManager();
2251
            SearchParameters params = this.fetch(null);
2252
            StringBuilder msg = new StringBuilder();
2253
            params.isValid(this.getFeatureType(), msg);
2254
            I18nManager i18n = ToolsLocator.getI18nManager();
2255
            toolSwingManager.showZoomDialog(
2256
                    this, 
2257
                    i18n.getTranslation("_Properties"), 
2258
                    params.toString() + "\n" + msg.toString(), 
2259
                    false,
2260
                    WindowManager.MODE.DIALOG,
2261
                    ListBuilder.create(
2262
                            new AbstractAction(i18n.getTranslation("_Copy_query")) {
2263
                                @Override
2264
                                public void actionPerformed(ActionEvent e) {
2265
                                    doCopyQueryToCLipboard(params.getQuery());
2266
                                }
2267
                            }
2268
                    )
2269
            );
2270
        } catch (Exception ex) {
2271
            LOGGER.warn("Can't show dialog", ex);
2272
        }
2273
    }
2274

    
2275
    @Override
2276
    public void setPostProcessEnabled(boolean enabled) {
2277
        if (this.initialized) {
2278
            throw new IllegalStateException("Cannot change postProcessEnabled after invoking asJComponent.");
2279
        }
2280
        this.postProcessEnabled = enabled;
2281
    }
2282

    
2283
    @Override
2284
    public void setGroupByEnabled(boolean enabled) {
2285
        if (this.initialized) {
2286
            throw new IllegalStateException("Cannot change groupByEnabled after invoking asJComponent.");
2287
        }
2288
        this.groupByEnabled = enabled;
2289
    }
2290

    
2291
    @Override
2292
    public boolean isPostProcessEnabled() {
2293
        return this.postProcessEnabled;
2294
    }
2295

    
2296
    @Override
2297
    public boolean isGroupByEnabled() {
2298
        return this.groupByEnabled;
2299
    }
2300

    
2301
    private boolean useSelection() {
2302
        boolean x = this.chkUseSelection.isSelected();
2303
        return x;
2304
    }
2305

    
2306
    private FeatureQuery addSelection(FeatureStore store, FeatureQuery query) {
2307
        query = query.getCopy();
2308
        
2309
        if( store.isFeatureSelectionEmpty() ) {
2310
            return  query;
2311
        }
2312
        if( store.getMode()!=FeatureStore.MODE_QUERY ) {
2313
            throw new RuntimeException("Use selection not allowed in editing mode");
2314
        }
2315
        
2316
        FeatureAttributeDescriptor[] pks = store.getDefaultFeatureTypeQuietly().getPrimaryKey();
2317
        if( pks==null ) {
2318
            throw new RuntimeException("Use selection not allowed without primarykey");
2319
        }
2320
        if( pks.length!=1 ) {
2321
            throw new RuntimeException("Use selection not allowed with multifield primarykey");
2322
        }
2323
        ExpressionEvaluatorManager expManager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
2324
        ExpressionBuilder expbuilder = expManager.createExpressionBuilder();
2325

    
2326
        Expression filter = query.getExpressionFilter();
2327
        ExpressionBuilder.Value values = expManager.convertToValue(store.getFeatureSelectionQuietly().referenceIterator());
2328
        if( ExpressionBuilder.isFunction(values, ExpressionBuilder.FUNCTION_TUPLE) ) {
2329
            ((ExpressionBuilder.Function) values).name("");
2330
        }
2331
        String selectionfilter = expbuilder.binaryOperator(
2332
                ExpressionBuilder.OPERATOR_IN,
2333
                expbuilder.variable(pks[0].getName()), 
2334
                values
2335
        ).toString();
2336
        StringBuilder builder = new StringBuilder();
2337
        builder.append(selectionfilter);
2338
        if( filter == null ) {                                    
2339
            query.addFilter(builder.toString());
2340
        } else {
2341
            builder.append(" AND (");
2342
            builder.append(filter.getPhrase());
2343
            builder.append(")");
2344
            filter.setPhrase(builder.toString());
2345
        }
2346
        query.retrievesAllAttributes();
2347
        return query;
2348
    }
2349
    
2350
    @Override
2351
    public void addResultPanel(String name, String title, Component component) {
2352
        int index = -1;
2353
        if( this.additionalResultsPanels.containsKey(name) ) {
2354
            index = this.additionalResultsPanels.get(name).getIndex();
2355
        }
2356
        AdditionalResultsPanel panel = new AdditionalResultsPanel(name, title, component, index);
2357
        this.additionalResultsPanels.put(name, panel);
2358
        if( this.initialized ) {
2359
            if( index < 0 ) {
2360
                panel.setIndex(this.tabResults.getTabCount());
2361
                this.tabResults.addTab(panel.getTitle(), panel.asJComponent());
2362
            } else {
2363
                this.tabResults.setComponentAt(index, panel.asJComponent());
2364
                this.tabResults.setTitleAt(index, panel.getTitle());
2365
            }
2366
        }
2367
    }
2368

    
2369
    @Override
2370
    public void removeResultPanel(String name) {
2371
        int index = -1;
2372
        if( this.additionalResultsPanels.containsKey(name) ) {
2373
            index = this.additionalResultsPanels.get(name).getIndex();
2374
        }
2375
        this.additionalResultsPanels.remove(name);
2376
        if( this.initialized ) {
2377
            this.tabResults.removeTabAt(index);
2378
        }
2379
    }
2380

    
2381
    @Override
2382
    public DALActionFactory.DALActionContext getSearchActionContext() {
2383
        return new SearchActionContext(this);
2384
    }
2385

    
2386
    private void fireSearchEvent() {
2387
        ActionEvent e = new ActionEvent(this, 1, "search");
2388
        for (AdditionalResultsPanel additionalResultsPanel : this.additionalResultsPanels.values()) {
2389
            additionalResultsPanel.fireActionEvent(e);
2390
        }
2391
    }
2392
    
2393
    // https://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html
2394
}