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 / featureform / swing / impl / DefaultJFeaturesForm.java @ 46010

History | View | Annotate | Download (43.3 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2014 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.featureform.swing.impl;
24

    
25
import java.awt.BorderLayout;
26
import java.awt.Dimension;
27
import java.awt.event.ActionEvent;
28
import java.awt.event.ActionListener;
29
import java.awt.event.ComponentAdapter;
30
import java.awt.event.ComponentEvent;
31
import java.net.URL;
32
import java.util.ArrayList;
33
import java.util.Collection;
34
import java.util.List;
35
import java.util.Map;
36
import javax.swing.AbstractAction;
37
import javax.swing.Action;
38
import static javax.swing.Action.ACTION_COMMAND_KEY;
39
import static javax.swing.Action.NAME;
40
import static javax.swing.Action.SHORT_DESCRIPTION;
41
import static javax.swing.Action.SMALL_ICON;
42
import javax.swing.JComponent;
43
import javax.swing.JOptionPane;
44
import javax.swing.JPanel;
45
import org.apache.commons.lang3.StringUtils;
46
import org.gvsig.expressionevaluator.Expression;
47
import org.gvsig.expressionevaluator.ExpressionEvaluator;
48
import org.gvsig.expressionevaluator.ExpressionUtils;
49
import org.gvsig.featureform.swing.JFeaturesForm;
50
import org.gvsig.fmap.dal.DALLocator;
51
import org.gvsig.fmap.dal.DataStore;
52
import org.gvsig.fmap.dal.exception.DataException;
53
import org.gvsig.fmap.dal.feature.EditableFeature;
54
import org.gvsig.fmap.dal.feature.FacadeOfAFeature;
55
import org.gvsig.fmap.dal.feature.Feature;
56
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
57
import org.gvsig.fmap.dal.feature.FeatureQuery;
58
import org.gvsig.fmap.dal.feature.FeatureStore;
59
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
60
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
61
import org.gvsig.fmap.dal.swing.AbstractDALActionFactory.AbstractDALActionContext;
62
import org.gvsig.fmap.dal.swing.DALActionFactory;
63
import org.gvsig.fmap.dal.swing.DALSwingLocator;
64
import org.gvsig.fmap.dal.swing.DataSwingManager;
65
import org.gvsig.fmap.dal.swing.impl.DefaultDataSwingManager;
66
import org.gvsig.fmap.dal.swing.impl.actions.ShowFormAction.ShowFormActionFactory;
67
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
68
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
69
import org.gvsig.tools.ToolsLocator;
70
import org.gvsig.tools.dispose.Disposable;
71
import org.gvsig.tools.dispose.DisposeUtils;
72
import org.gvsig.tools.dynform.AbortActionException;
73
import org.gvsig.tools.dynform.DynFormDefinition;
74
import org.gvsig.tools.dynform.DynFormLocator;
75
import org.gvsig.tools.dynform.DynFormManager;
76
import org.gvsig.tools.dynform.JDynForm;
77
import org.gvsig.tools.dynform.JDynFormField;
78
import org.gvsig.tools.dynform.JDynFormSet;
79
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_CANCEL_NEW;
80
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_DELETE;
81
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NAVIGATION;
82
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NEW;
83
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SAVE;
84
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SEARCH;
85
import org.gvsig.tools.dynform.JDynFormSet.JDynFormSetListener;
86
import org.gvsig.tools.dynobject.DynClass;
87
import org.gvsig.tools.dynobject.DynObject;
88
import org.gvsig.tools.evaluator.Evaluator;
89
import org.gvsig.tools.exception.BaseException;
90
import org.gvsig.tools.i18n.I18nManager;
91
import org.gvsig.tools.observer.Observable;
92
import org.gvsig.tools.observer.Observer;
93
import org.gvsig.tools.swing.api.ActionListenerSupport;
94
import org.gvsig.tools.swing.api.ToolsSwingLocator;
95
import org.gvsig.tools.swing.api.ToolsSwingUtils;
96
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
97
import org.gvsig.tools.swing.api.windowmanager.Dialog;
98
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
99
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
100
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
101
import org.gvsig.tools.swing.icontheme.IconTheme;
102
import org.gvsig.tools.util.PropertiesSupport;
103
import org.gvsig.tools.util.PropertiesSupportHelper;
104
import org.slf4j.Logger;
105
import org.slf4j.LoggerFactory;
106

    
107
/**
108
 * @author fdiaz
109
 *
110
 */
111
@SuppressWarnings("UseSpecificCatch")
112
public class DefaultJFeaturesForm implements JFeaturesForm, Disposable {
113

    
114
    private final String STARTEDITING_ACTION = "startEditing";
115
    private final String FINISHEDITING_ACTION = "finishEditing";
116
    private final String REFRESHFORM_ACTION = "refreshForm";
117

    
118
    private class JFeaturesFormPanel extends JPanel implements PropertiesSupport {
119

    
120
        private final PropertiesSupport properties;
121
        
122
        private JFeaturesFormPanel(PropertiesSupport properties, BorderLayout layout) {
123
            super(layout);
124
            this.properties = properties;
125
        }
126

    
127
        @Override
128
        public Object getProperty(String name) {
129
            return this.properties.getProperty(name);
130
        }
131

    
132
        @Override
133
        public void setProperty(String name, Object value) {
134
            this.properties.setProperty(name, value);
135
        }
136

    
137
        @Override
138
        public Map<String, Object> getProperties() {
139
            return this.properties.getProperties();
140
        }
141
        
142
    }
143
    
144
    private class FormActionContext extends AbstractDALActionContext {
145

    
146
        public FormActionContext() {
147
            super(ACTION_CONTEXT_NAME);
148
        }
149

    
150
        @Override
151
        public DataStore getStore() {
152
            return store;
153
        }
154

    
155
        @Override
156
        public FeatureQuery getQuery() {
157
            return currentQuery;
158
        }
159

    
160
        @Override
161
        public int getSelectedsCount() {
162
            return 0;
163
        }
164

    
165
        @Override
166
        public Expression getFilterForSelecteds() {
167
            return null;
168
        }
169

    
170
        @Override
171
        public JComponent getActionButton(String actionName) {
172
            if (formset == null) {
173
                return null;
174
            }
175
            return formset.getActionButton(actionName);
176
        }
177

    
178
    }
179

    
180
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJFeaturesForm.class);
181

    
182
    private static final int PAGE_SIZE = 10;
183
    private JFeaturesFormPanel panel;
184
    private JDynFormSet formset;
185
    private FeatureStore store;
186
    private boolean needrefresh;
187
    private FeaturePagingHelper features;
188
    private DynFormDefinition definition = null;
189
    private FeatureQuery currentQuery;
190
    private List<Action> otherActions;
191
    private final ActionListenerSupport actionListeners;
192
    private final PropertiesSupportHelper propertiesHelper;
193

    
194
    @SuppressWarnings("LeakingThisInConstructor")
195
    public DefaultJFeaturesForm() {
196
        this.otherActions = new ArrayList<>();
197
        this.propertiesHelper = new PropertiesSupportHelper();
198
        this.propertiesHelper.setProperty("FeaturesForm", this);
199
        this.panel = new JFeaturesFormPanel(this.propertiesHelper, new BorderLayout());
200
        this.panel.addComponentListener(new ComponentAdapter() {
201
            @Override
202
            public void componentHidden(ComponentEvent e) {
203
                dispose();
204
            }
205
        });
206
        this.actionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
207
    }
208

    
209
    public static void selfRegister() {
210
        String[][] iconNames = new String[][]{
211
            new String[]{"dalswing", "form-refresh-data"}
212
        };
213
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
214
        for (String[] icon : iconNames) {
215
            URL url = DefaultJFeaturesForm.class.getResource(icon[1] + ".png");
216
            theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
217
        }
218

    
219
    }
220

    
221
    @Override
222
    public void setPreferredSize(Dimension dimension) {
223
        panel.setPreferredSize(dimension);
224
    }
225

    
226
    private void updateForm() {
227
        if (this.formset == null) {
228
            this.getFormset();
229
        }
230
        try {
231
            if (this.currentQuery != null) {
232
                this.currentQuery.retrievesAllAttributes();
233
            }
234
            this.features = DALLocator.getDataManager().createFeaturePagingHelper(store, this.currentQuery, PAGE_SIZE);
235
            this.formset.setValues(features.asListOfDynObjects());
236
        } catch (Exception ex) {
237
            throw new RuntimeException("Can't update form", ex);
238
        }
239
        this.needrefresh = false;
240
        updateButtonEnabledStatus();
241
    }
242

    
243
    @Override
244
    public JComponent asJComponent() {
245
        if (this.features == null) {
246
            try {
247
                updateForm();
248
            } catch (Exception ex) {
249
                throw new RuntimeException(ex);
250
            }
251
        }
252
        return this.panel;
253
    }
254

    
255
    @Override
256
    public void bind(FeatureStore store) {
257
        this.bind(store, null, null);
258
    }
259

    
260
    public void bind(FeatureStore store, DynClass definition) {
261
        this.bind(store, definition, null);
262
    }
263

    
264
    public void bind(FeatureStore store, DynClass definition, FeatureQuery query) {
265
        if (store == null) {
266
            throw new IllegalArgumentException("bind need a store as parameter, not a null.");
267
        }
268
        if (this.store == store) {
269
            return;
270
        }
271
        try {
272
            if (definition == null) {
273
                DefaultDataSwingManager manager = (DefaultDataSwingManager) DALSwingLocator.getSwingManager();
274
                definition = manager.featureType2DynClass(store, store.getDefaultFeatureType());
275
            }
276
            DynFormManager formManager = DynFormLocator.getDynFormManager();
277
            this.definition = formManager.getDefinition(definition);
278
            if (formset != null) {
279
                this.panel.remove(formset.asJComponent());
280
                this.panel.revalidate();
281
                this.formset = null;
282
            }
283
            this.store = store;
284
            DisposeUtils.bind(store);
285
            this.currentQuery = query;
286
            if (features != null) {
287
                this.features = null;
288
                updateForm();
289
            }
290
        } catch (Exception ex) {
291
            throw new RuntimeException("Can't bind store '" + store.getName() + "' to form", ex);
292
        }
293
    }
294

    
295
    @Override
296
    public void dispose() {
297
        if( this.formset!=null ) {
298
            Action action = this.formset.getAction(FINISHEDITING_ACTION);
299
            if( action!=null ) {
300
                DisposeUtils.disposeQuietly(action);
301
            }
302
            action = this.formset.getAction(STARTEDITING_ACTION);
303
            if( action!=null ) {
304
                DisposeUtils.disposeQuietly(action);
305
            }
306
        }
307
        DisposeUtils.disposeQuietly(store);
308
        this.store = null;
309
        this.panel = null;
310
        this.formset = null;
311
        this.features = null;
312
        this.definition = null;
313
        this.currentQuery = null;
314
        this.otherActions = null;
315
    }
316

    
317
    public static class MyFeaturesFormContext extends DefaultFeaturesFormContext {
318

    
319
        private final DefaultJFeaturesForm featuresForm;
320
        
321
        public MyFeaturesFormContext(DefaultJFeaturesForm featuresForm) {
322
            super(featuresForm.store);
323
            this.featuresForm = featuresForm;
324
        }
325
        
326
        @Override
327
        public JFeaturesForm getFeaturesForm() {
328
            return this.featuresForm;
329
        }
330
        @Override
331
        public Feature getCurrentFeature() {    
332
            return this.featuresForm.getCurrentFeature();
333
        }
334
    }
335
    
336
    @Override
337
    public JDynFormSet getFormset() {
338
        if (this.formset == null) {
339
            DynFormManager formManager = DynFormLocator.getDynFormManager();
340
            this.formset = formManager.createJDynFormSet(
341
                    new MyFeaturesFormContext(this),
342
                    this.definition,
343
                    null
344
            );
345
            List<String> groups = this.definition.getGroups();
346
            if (groups.size() == 1 && groups.get(0) == null) {
347
                this.formset.setLayoutMode(JDynForm.USE_PLAIN);
348
            } else {
349
                this.formset.setLayoutMode(JDynForm.USE_TABS);
350
            }
351
            this.formset.setAllowNew(true);
352
            this.formset.setAllowDelete(true);
353
            this.formset.setAllowUpdate(true);
354
            this.formset.setAllowClose(true);
355
            this.formset.setAllowSearch(true);
356
            this.formset.setAutosave(true);
357

    
358
            this.formset.addAction(new StartEditingAction());
359
            this.formset.addAction(new FinishEditingAction());
360
            this.formset.addAction(new RefreshAction());
361

    
362
            FormActionContext actionContext = new FormActionContext();
363
            try {
364
                Collection<DALActionFactory> factories = DALSwingLocator.getSwingManager().getStoreActions();
365
                for (DALActionFactory factory : factories) {
366
                    if (factory == null || StringUtils.equalsIgnoreCase(factory.getName(), ShowFormActionFactory.ACTION_NAME)) {
367
                        continue;
368
                    }
369
                    try {
370
                        Action action = factory.createAction(actionContext);
371
                        this.formset.addAction(action);
372
                    } catch (Exception ex) {
373
                        LOGGER.warn("Can't add action " + factory.getName(), ex);
374
                    }
375
                }
376
            } catch (Exception ex) {
377
                LOGGER.warn("Can't add actions", ex);
378
            }
379
            for (Action action : this.otherActions) {
380
                this.formset.addAction(action);
381
            }
382

    
383
            this.formset.addListener(new FormSetListener());
384
            this.formset.getForm().addListener(new JDynForm.JDynFormListener() {
385
                @Override
386
                public void message(String string) {
387
                }
388

    
389
                @Override
390
                public void fieldChanged(JDynFormField jdff) {
391
                    updateButtonEnabledStatus();
392
                }
393
            });
394

    
395
            ToolsSwingLocator.getToolsSwingManager().removeBorder(this.formset.asJComponent());
396
            this.panel.add(this.formset.asJComponent(), BorderLayout.CENTER);
397
            this.panel.revalidate();
398
            ToolsSwingUtils.ensureRowsCols(this.panel, 8, 70, 25, 100);
399

    
400
        }
401
        updateButtonEnabledStatus();
402
        return this.formset;
403
    }
404

    
405
    @Override
406
    public void addAction(Action action) {
407
        this.otherActions.add(action);
408
        if (this.formset != null) {
409
            this.formset.addAction(action);
410
        }
411
    }
412

    
413
    @Override
414
    public long getCurrentIndex() {
415
        if (this.formset == null) {
416
            return -1;
417
        }
418
        return this.formset.getCurrentIndex();
419
    }
420

    
421
    @Override
422
    public Feature get(long index) {
423
        if (this.formset == null || this.features == null) {
424
            return null;
425
        }
426
        try {
427
            return this.features.getFeatureAt(index);
428
        } catch (BaseException ex) {
429
            return null;
430
        }
431
    }
432

    
433
    private class RefreshAction extends AbstractAction {
434

    
435
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
436
        public RefreshAction() {
437
            I18nManager i18nManager = ToolsLocator.getI18nManager();
438
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
439

    
440
            this.putValue(NAME, null);
441
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Reload_data"));
442
            this.putValue(SMALL_ICON, iconTheme.get("form-refresh-data"));
443
            this.putValue(ACTION_COMMAND_KEY, REFRESHFORM_ACTION);
444
            this.setEnabled(!formset.isInNewState());
445
        }
446

    
447
        @Override
448
        public void actionPerformed(ActionEvent ae) {
449
            try {
450
                I18nManager i18n = ToolsLocator.getI18nManager();
451
                formset.message(i18n.getTranslation("_Form_reloaded"));
452
                int x=formset.getCurrentIndex();
453
                updateForm();
454
                formset.setCurrentIndex(x);
455
            } catch (Exception ex) {
456
                LOGGER.warn("Can't reload form", ex);
457
            }
458
        }
459
    }
460

    
461
    private class FinishEditingAction extends AbstractAction implements Observer, Disposable {
462

    
463
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
464
        public FinishEditingAction() {
465
            I18nManager i18nManager = ToolsLocator.getI18nManager();
466
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
467

    
468
            this.putValue(NAME, null);
469
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Stop_editing"));
470
            this.putValue(SMALL_ICON, iconTheme.get("table-stop-editing"));
471
            this.putValue(ACTION_COMMAND_KEY, FINISHEDITING_ACTION);
472

    
473
            this.setEnabled(store.isEditing());
474
            store.addObserver(this);
475
        }
476

    
477
        @Override
478
        public void actionPerformed(ActionEvent ae) {
479
            if (store == null || formset == null) {
480
                return;
481
            }
482
            if (store.isEditing()) {
483
                ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
484
                I18nManager i18nManager = ToolsLocator.getI18nManager();
485
                try {
486
                    int x = dialogManager.confirmDialog(
487
                            i18nManager.getTranslation("_Do_you_want_to_finish_editing_and_save_the_changes") + "\n\n"
488
                            + i18nManager.getTranslation("_Press_cancel_to_cancel_editing_and_changes"),
489
                            i18nManager.getTranslation("_Stop_editing"),
490
                            JOptionPane.YES_NO_CANCEL_OPTION,
491
                            JOptionPane.QUESTION_MESSAGE
492
                    );
493
                    switch (x) {
494
                        case JOptionPane.YES_OPTION:
495
                            store.finishEditing();
496
                            break;
497
                        case JOptionPane.NO_OPTION:
498
                            break;
499
                        case JOptionPane.CANCEL_OPTION:
500
                            store.cancelEditing();
501
                            int index = formset.getCurrentIndex();
502
                            try {
503
                                formset.setCurrentIndex(index);
504
                            } catch (Exception ex) {
505
                                LOGGER.warn("Can't reload form data after edit.", ex);
506
                            }
507
                            break;
508
                    }
509
                } catch (Exception ex) {
510
                    LOGGER.warn("Can't finish editing in FeatureForm (" + store.getName() + ").", ex);
511
                    dialogManager.messageDialog(
512
                            i18nManager.getTranslation("_Problems_finish_table_editing") + "\n\n"
513
                            + i18nManager.getTranslation("_see_error_log_for_more_information"),
514
                            i18nManager.getTranslation("_Stop_editing"),
515
                            JOptionPane.ERROR_MESSAGE
516
                    );
517
                }
518
            }
519
            updateButtonEnabledStatus();
520
        }
521

    
522
        @Override
523
        public void update(Observable observable, Object notification) {
524
            if (store == null || formset == null) {
525
                return;
526
            }
527
            if (notification instanceof FeatureStoreNotification) {
528
                FeatureStoreNotification n = (FeatureStoreNotification) notification;
529
                switch (n.getType()) {
530
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
531
                        needrefresh = true;
532
                    case FeatureStoreNotification.AFTER_STARTEDITING:
533
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
534
                        updateButtonEnabledStatus();
535
                        break;
536
                }
537
            }
538
        }
539

    
540
        @Override
541
        public void dispose() {
542
            store.deleteObserver(this);
543
        }
544

    
545
    }
546

    
547
    private class StartEditingAction extends AbstractAction implements Observer, Disposable {
548

    
549
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
550
        public StartEditingAction() {
551
            I18nManager i18nManager = ToolsLocator.getI18nManager();
552
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
553

    
554
            this.putValue(NAME, null);
555
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Start_editing"));
556
            this.putValue(SMALL_ICON, iconTheme.get("table-start-editing"));
557
            this.putValue(ACTION_COMMAND_KEY, STARTEDITING_ACTION);
558

    
559
            this.setEnabled(!store.isEditing());
560
            store.addObserver(this);
561
        }
562

    
563
        @Override
564
        public void actionPerformed(ActionEvent ae) {
565
            if (store == null || formset == null) {
566
                return;
567
            }
568
            if (!store.isEditing()) {
569
                try {
570
                    store.edit();
571
                } catch (DataException ex) {
572
                    LOGGER.warn("Can't finish editing in FeatureForm (" + store.getName() + ").", ex);
573
                }
574
            }
575
            updateButtonEnabledStatus();
576
        }
577

    
578
        @Override
579
        public void update(Observable observable, Object notification) {
580
            if (store == null || formset == null) {
581
                return;
582
            }
583
            if (notification instanceof FeatureStoreNotification) {
584
                FeatureStoreNotification n = (FeatureStoreNotification) notification;
585
                switch (n.getType()) {
586
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
587
                        needrefresh = true;
588
                    case FeatureStoreNotification.AFTER_STARTEDITING:
589
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
590
                        updateButtonEnabledStatus();
591
                        break;
592
                }
593
            }
594
        }
595

    
596
        @Override
597
        public void dispose() {
598
            store.deleteObserver(this);
599
        }
600

    
601
    }
602

    
603
    @Override
604
    public void setQuery(FeatureQuery query) {
605
        if (this.features != null) {
606
            if (this.formset != null && !formset.isReadOnly() && this.formset.isAutosave() && this.formset.countValues() > 0) {
607
                if(this.formset.getForm().isModified()){
608
                    if (!store.isEditing()) {
609
                        try {
610
                            store.edit();
611
                        } catch (DataException e1) {
612
                            throw new RuntimeException("Can't set query", e1);
613
                        }
614
                    }
615
                    saveChanges(this.formset);
616
                }
617
            }
618
        }
619
        this.currentQuery = query;
620
        updateForm();
621
    }
622

    
623
    private FeatureQuery getCurrentQuery() {
624
        return this.currentQuery;
625
    }
626

    
627
    @Override
628
    public void showForm(MODE mode) {
629
        WindowManager winmgr = ToolsSwingLocator.getWindowManager();
630
        String title = this.definition.getLabel();
631
        winmgr.showWindow(this.asJComponent(), title, mode);
632
    }
633

    
634
    private void saveChanges(JDynFormSet theFormSet) {
635
        I18nManager i18n = ToolsLocator.getI18nManager();
636
        try {
637
            if (theFormSet.isInNewState()) {
638
                EditableFeature newFeature = store.createNewFeature(false);
639
                
640
                // Fill fields not in form with default values
641
                for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
642
                    JDynFormField field = formset.getForm().getField(attr.getName());
643
                    if( field==null ) {
644
                        newFeature.set(attr.getName(), attr.getDefaultValueCoerced());
645
                    }
646
                }
647
                DynObject newElement = newFeature.getAsDynObject();
648
                theFormSet.getFormValues(newElement);
649
                features.insert(((FacadeOfAFeature) newElement).getEditableFeature());
650
                this.formset.message(i18n.getTranslation("_Record_saved"));
651
                try {
652
                    this.formset.setValues(features.asListOfDynObjects());
653
                    this.formset.setCurrentIndex((int) (features.getTotalSize()) - 1);
654
                } catch (Exception ex) {
655
                    LOGGER.warn("Can't reload form data after insert.", ex);
656
                }
657
            } else {
658
                int index = theFormSet.getCurrentIndex();
659
                DynObject currentElement = theFormSet.get(index);
660
                theFormSet.getFormValues(currentElement);
661
                features.update(((FacadeOfAFeature) currentElement).getEditableFeature());
662
                this.formset.message(i18n.getTranslation("_Record_saved"));
663
                try {
664
                    this.formset.setCurrentIndex(index);
665
                } catch (Exception ex) {
666
                    LOGGER.warn("Can't reload form data after insert.", ex);
667
                }
668
            }
669
        } catch (Exception ex) {
670
            theFormSet.message(i18n.getTranslation("error_saving_data_will_not_save"));
671
            throw new RuntimeException("Can't save values", ex);
672

    
673
        } finally {
674
            updateButtonEnabledStatus();
675
        }
676

    
677
    }
678

    
679
    private void deleteCurrentElement(JDynFormSet theFormSet) {
680
        I18nManager i18n = ToolsLocator.getI18nManager();
681
        try {
682
            int index = theFormSet.getCurrentIndex();
683
            DynObject currentElement = theFormSet.get(index);
684
            theFormSet.getFormValues(currentElement);
685
            Feature feature = ((FacadeOfAFeature) currentElement).getFeature();
686
            if (feature instanceof EditableFeature) {
687
                feature = ((EditableFeature) feature).getNotEditableCopy();
688
            }
689
            features.delete(feature);
690

    
691
            this.formset.message(i18n.getTranslation("_Record_removed"));
692

    
693
            this.formset.setValues(features.asListOfDynObjects());
694
            if (features.getTotalSize() - 1 < index) {
695
                index = index - 1;
696
            }
697
            this.formset.setCurrentIndex(index);
698

    
699
        } catch (Exception ex) {
700
            theFormSet.message(i18n.getTranslation("error_removing_data_will_not_remove"));
701
            throw new RuntimeException("Can't remove values", ex);
702

    
703
        } finally {
704
            updateButtonEnabledStatus();
705
        }
706

    
707
    }
708

    
709
    @Override
710
    public void saveChanges() {
711
        if (this.formset != null && this.formset.countValues() > 0) {
712
            if (store != null && !store.isEditing()) {
713
                try {
714
                    store.edit();
715
                } catch (DataException e1) {
716
                    LOGGER.warn("Can't edit the store " + store.getName());
717
                    throw new RuntimeException("Can't save changes.", e1);
718
                }
719
            }
720
            this.saveChanges(this.formset);
721
        }
722
    }
723

    
724
    private void updateButtonEnabledStatus() {
725
        if (this.formset == null) {
726
            return;
727
        }
728
        if (this.store == null || store.isBroken() || store.isAppending() || this.features == null) {
729
            this.formset.setReadOnly(true);
730
            formset.setActionVisible(STARTEDITING_ACTION, true);
731
            formset.setActionEnabled(STARTEDITING_ACTION, true);
732
            formset.setActionVisible(FINISHEDITING_ACTION, false);
733
            formset.setActionEnabled(FINISHEDITING_ACTION, false);
734
            formset.setActionEnabled(ACTION_DELETE, false);
735
            formset.setActionEnabled(ACTION_NEW, false);
736
            formset.setActionEnabled(ACTION_CANCEL_NEW, false);
737
            formset.setActionEnabled(ACTION_SAVE, false);
738
            formset.setActionEnabled(ACTION_SEARCH, false);
739
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
740
            formset.setActionEnabled(ACTION_NAVIGATION, false);
741
            return;
742
        }
743
        if (this.needrefresh ) {
744
            this.formset.setReadOnly(true);
745
//            formset.setActionEnabled(STARTEDITING_ACTION, false);
746
//            formset.setActionEnabled(FINISHEDITING_ACTION, false);
747
            formset.setActionEnabled(ACTION_DELETE, false);
748
            formset.setActionEnabled(ACTION_NEW, false);
749
            formset.setActionEnabled(ACTION_CANCEL_NEW, false);
750
            formset.setActionEnabled(ACTION_SAVE, false);
751
            formset.setActionEnabled(ACTION_SEARCH, false);
752
            formset.setActionEnabled(ACTION_NAVIGATION, false);
753
            for (Action action : formset.getActions()) {
754
                formset.setActionEnabled((String) action.getValue(ACTION_COMMAND_KEY), false);
755
            }
756
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
757
            return;
758
        }
759
        if (store.isEditing()) {
760
            this.formset.setReadOnly(false);
761
            formset.setActionVisible(STARTEDITING_ACTION, false);
762
            formset.setActionEnabled(STARTEDITING_ACTION, false);
763
            formset.setActionVisible(FINISHEDITING_ACTION, true);
764
            formset.setActionEnabled(FINISHEDITING_ACTION, true);
765
            if (formset.isInNewState()) {
766
                formset.setActionEnabled(ACTION_DELETE, false);
767
                formset.setActionEnabled(ACTION_SEARCH, false);
768
                formset.setActionEnabled(ACTION_NEW, false);
769
                formset.setActionEnabled(ACTION_CANCEL_NEW, true);
770
                formset.setActionEnabled(ACTION_SAVE, true);
771
                formset.setActionEnabled(FINISHEDITING_ACTION, false);
772
                formset.setActionEnabled(REFRESHFORM_ACTION, false);
773
//                setEnabledUniqueFields(true);
774

    
775
            } else if (this.features != null && this.features.isEmpty()) {
776
                formset.getForm().setReadOnly(true);
777
                formset.setActionEnabled(ACTION_DELETE, false);
778
                formset.setActionEnabled(ACTION_SEARCH, false);
779
                formset.setActionEnabled(ACTION_NEW, true);
780
                formset.setActionEnabled(ACTION_CANCEL_NEW, true);
781
                formset.setActionEnabled(ACTION_SAVE, false);
782
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
783
                formset.setActionEnabled(FINISHEDITING_ACTION, true);         
784
                formset.setActionEnabled(ACTION_NAVIGATION, false);
785

    
786
            } else if (formset.getForm().isModified()) {
787
                formset.setActionEnabled(ACTION_DELETE, false);
788
                formset.setActionEnabled(ACTION_SEARCH, false);
789
                formset.setActionEnabled(ACTION_NEW, false);
790
                formset.setActionEnabled(ACTION_CANCEL_NEW, false);
791
                formset.setActionEnabled(ACTION_SAVE, true);
792
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
793
                formset.setActionEnabled(FINISHEDITING_ACTION, false);
794
                formset.setActionEnabled(ACTION_NAVIGATION, false);
795

    
796
            } else {
797
                formset.setActionEnabled(ACTION_DELETE, true);
798
                formset.setActionEnabled(ACTION_SEARCH, true);
799
                formset.setActionEnabled(ACTION_NEW, true);
800
                formset.setActionEnabled(ACTION_CANCEL_NEW, false);
801
                formset.setActionEnabled(ACTION_SAVE, false);
802
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
803
                formset.setActionEnabled(FINISHEDITING_ACTION, true);
804
                formset.setActionEnabled(ACTION_NAVIGATION, true);
805
            }
806

    
807
            return;
808
        }
809
        this.formset.setReadOnly(true);
810
        formset.setActionVisible(STARTEDITING_ACTION, true);
811
        formset.setActionEnabled(STARTEDITING_ACTION, true);
812
        formset.setActionVisible(FINISHEDITING_ACTION, false);
813
        formset.setActionEnabled(FINISHEDITING_ACTION, false);
814
        formset.setActionEnabled(ACTION_DELETE, false);
815
        formset.setActionEnabled(ACTION_NEW, false);
816
        formset.setActionEnabled(ACTION_CANCEL_NEW, false);
817
        formset.setActionEnabled(ACTION_SAVE, false);
818
        formset.setActionEnabled(ACTION_SEARCH, true);
819
        formset.setActionEnabled(REFRESHFORM_ACTION, true);
820
    }
821

    
822
    private void clearUniqueFields() {
823
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
824
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
825
                JDynFormField field = formset.getForm().getField(attr.getName());
826
                if (field != null) {
827
                    field.clear();
828
                }
829
            }
830
        }
831
    }
832

    
833
    private void setEnabledUniqueFields(boolean enabled) {
834
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
835
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
836
                JDynFormField field = formset.getForm().getField(attr.getName());
837
                if (field != null) {
838
                    field.setReadOnly(!enabled);
839
                }
840
            }
841
        }
842
    }
843

    
844
    @Override
845
    public long getDataSetSize() {
846
        if (this.features != null) {
847
            return features.getTotalSize();
848
        }
849
        return 0;
850
    }
851

    
852
    @Override
853
    public FeatureStore getFeatureStore() {
854
        return this.store;
855
    }
856

    
857
    private class FormSetListener implements JDynFormSetListener {
858

    
859
        @Override
860
        public void formMessage(String message) {
861
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMessage"));
862
        }
863

    
864
        @Override
865
        public void formClose() {
866
            panel.setVisible(false);
867
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formClose"));
868
        }
869

    
870
        @Override
871
        public void formMovedTo(int currentPosition) throws AbortActionException {
872
            LOGGER.trace("formMovedTo " + currentPosition);
873
            updateButtonEnabledStatus();
874
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMovedTo"));
875
        }
876

    
877
        @Override
878
        public void formBeforeSave(JDynFormSet dynformSet) throws AbortActionException {
879
            LOGGER.trace("formBeforeSave");
880
            saveChanges(dynformSet);
881
            updateButtonEnabledStatus();
882
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSave"));
883
        }
884

    
885
        @Override
886
        public void formBeforeNew(JDynFormSet dynformSet) throws AbortActionException {
887
            LOGGER.trace("formBeforeNew");
888
            clearUniqueFields();
889
            updateButtonEnabledStatus();
890
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeNew"));
891
        }
892

    
893
        @Override
894
        public void formBeforeDelete(JDynFormSet dynformSet) throws AbortActionException {
895
            LOGGER.trace("formBeforeDelete");
896
            updateButtonEnabledStatus();
897
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeDelete"));
898
        }
899

    
900
        @Override
901
        public void formAfterSave(JDynFormSet dynformSet) throws AbortActionException {
902
            LOGGER.trace("formAfterSave");
903
            updateButtonEnabledStatus();
904
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSave"));
905
        }
906

    
907
        @Override
908
        public void formAfterNew(JDynFormSet dynformSet) throws AbortActionException {
909
            LOGGER.trace("formAfterNew");
910
            updateButtonEnabledStatus();
911
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterNew"));
912
        }
913

    
914
        @Override
915
        public void formAfterDelete(JDynFormSet dynformSet) throws AbortActionException {
916
            LOGGER.trace("formAfterDelete");
917
            deleteCurrentElement(dynformSet);
918
            updateButtonEnabledStatus();
919
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterDelete"));
920
        }
921

    
922
//        @Override
923
//        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
924
//            LOGGER.trace("formBeforeSearch");
925
//            DataSwingManager dataSwingmanager = DALSwingLocator.getSwingManager();
926
//            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
927
//
928
//            JExpressionBuilder builder = dataSwingmanager.createQueryFilterExpresion(store);
929
//            FeatureQuery currentQuery = getCurrentQuery();
930
//            if( currentQuery!=null ) {
931
//                Evaluator filter = currentQuery.getFilter();
932
//                if( filter instanceof ExpressionEvaluator ) {
933
//                    Expression expression = ((ExpressionEvaluator)filter).getExpression();
934
//                    builder.setExpression(expression);
935
//                }
936
//            }
937
//            Dialog dialog = winmgr.createDialog(
938
//                    builder.asJComponent(),
939
//                    "Filtro",
940
//                    "Creacion de filtro sobre '"+store.getName()+"'",
941
//                    WindowManager_v2.BUTTONS_OK_CANCEL
942
//            );
943
//            dialog.show(WindowManager.MODE.DIALOG);
944
//            if( dialog.getAction() == WindowManager_v2.BUTTON_OK ) {
945
//                Expression expresion = builder.getExpression();
946
//                try {
947
//                    FeatureQuery query = store.createFeatureQuery();
948
//                    if( ExpressionUtils.isPhraseEmpty(expresion) ) {
949
//                        query.clearFilter();
950
//                    } else {
951
//                        query.setFilter(expresion);
952
//                    }
953
//                    setQuery(query);
954
//                } catch (Exception ex) {
955
//                    LOGGER.warn("Can't apply filter '" + expresion + "'.", ex);
956
//                }
957
//            }
958
//        }
959
        @Override
960
        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
961
            LOGGER.trace("formBeforeSearch");
962
            DataSwingManager dataSwingmanager = DALSwingLocator.getSwingManager();
963
            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
964

    
965
            final FeatureStoreSearchPanel searchPanel = dataSwingmanager.createFeatureStoreSearchPanel(store);
966
            searchPanel.setShowActions(false);
967
            FeatureQuery currentQuery = getCurrentQuery();
968
            if (currentQuery != null) {
969
                Evaluator filter = currentQuery.getFilter();
970
                if (filter instanceof ExpressionEvaluator) {
971
                    Expression expression = ((ExpressionEvaluator) filter).toExpression();
972
                    searchPanel.setFilter(expression);
973
                    searchPanel.search();
974
                }
975
            }
976
            searchPanel.asJComponent().setPreferredSize(
977
                    new Dimension(FeatureStoreSearchPanel.DEFAULT_WIDTH, 320)
978
            );
979
            I18nManager i18n = ToolsLocator.getI18nManager();
980
            Dialog dialog = winmgr.createDialog(
981
                    searchPanel.asJComponent(),
982
                    i18n.getTranslation("_Filter"),
983
                    i18n.getTranslation("_Creating_filter_for") + ": '" + store.getName() + "'",
984
                    WindowManager_v2.BUTTONS_OK_CANCEL
985
            );
986
            dialog.show(WindowManager.MODE.DIALOG);
987
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
988
                SearchParameters params = searchPanel.fetch(null);
989
                if (params.getQuery() != null) {
990
                    FeatureQuery searchQuery = params.getQuery().getCopy();
991

    
992
                    Expression expresion = null;
993
                    if (searchQuery != null) {
994
                        expresion = searchQuery.getExpressionFilter();
995
                    }
996
                    try {
997
                        FeatureQuery query = store.createFeatureQuery();
998
                        if (ExpressionUtils.isPhraseEmpty(expresion)) {
999
                            query.clearFilter();
1000
                        } else {
1001
                            query.setFilter(expresion);
1002
                        }
1003
                        setQuery(query);
1004
                    } catch (Exception ex) {
1005
                        LOGGER.warn("Can't apply filter '" + expresion + "'.", ex);
1006
                    }
1007
                } else {
1008
                    LOGGER.warn("FeatureQuery from parameters is null. Query is not applied to the JFeaturesFrom");
1009
                }
1010
            }
1011
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSearch"));
1012
        }
1013

    
1014
        @Override
1015
        public void formAfterSearch(JDynFormSet dynformSet) throws AbortActionException {
1016
            LOGGER.trace("formAfterSearch");
1017
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSearch"));
1018
        }
1019

    
1020
        @Override
1021
        public void formBeforeCancelNew(JDynFormSet dynformSet) throws AbortActionException {
1022
            LOGGER.trace("formBeforeCancelNew");
1023
            updateButtonEnabledStatus();
1024
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeCancelNew"));
1025
        }
1026

    
1027
        @Override
1028
        public void formAfterCancelNew(JDynFormSet dynformSet) throws AbortActionException {
1029
            LOGGER.trace("formAfterCancelNew");
1030
            try {
1031
                int index = formset.getCurrentIndex();
1032
                if( index<0 ) {
1033
                    formset.getForm().clear();
1034
                } else {
1035
                    formset.setCurrentIndex(index);
1036
                }
1037
            } catch (Exception ex) {
1038
                LOGGER.warn("Can't reload form data after cancel new.", ex);
1039
            }            
1040
            updateButtonEnabledStatus();
1041
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterCancelNew"));
1042
        }
1043
    }
1044

    
1045
//    private static class StoreEditException extends AbortActionException {
1046
//
1047
//        /**
1048
//         *
1049
//         */
1050
//        private static final long serialVersionUID = -7682017811778577130L;
1051
//
1052
//        public StoreEditException(Throwable cause, String storename) {
1053
//            super("Can't edit the store '%(storename)'", cause, "cant_edit_the store_XstorenameX", serialVersionUID);
1054
//            setValue("storename", storename);
1055
//        }
1056
//    }
1057
    @Override
1058
    public void addActionListener(ActionListener listener) {
1059
        this.actionListeners.addActionListener(listener);
1060
    }
1061

    
1062
    @Override
1063
    public ActionListener[] getActionListeners() {
1064
        return this.actionListeners.getActionListeners();
1065
    }
1066

    
1067
    @Override
1068
    public void removeActionListener(ActionListener listener) {
1069
        this.actionListeners.removeActionListener(listener);
1070
    }
1071

    
1072
    @Override
1073
    public void removeAllActionListener() {
1074
        this.actionListeners.removeAllActionListener();
1075
    }
1076

    
1077
    @Override
1078
    public void fireActionEvent(ActionEvent event) {
1079
        this.actionListeners.fireActionEvent(event);
1080
    }
1081

    
1082
    @Override
1083
    public boolean hasActionListeners() {
1084
        return this.actionListeners.hasActionListeners();
1085
    }
1086

    
1087
    @Override
1088
    public Feature getCurrentFeature() {
1089
        long index = getCurrentIndex();
1090
        if( index<0 ) {
1091
            return null;
1092
        }
1093
        Feature f = get(index);
1094
        try {
1095
            DynObject adapter = f.getAsDynObject();
1096
            this.getFormset().getForm().getValues(adapter);
1097
            f = ((FacadeOfAFeature)adapter).getFeature();
1098
            return f;
1099
        } catch(Exception ex) {
1100
            return f;
1101
        }
1102
    }
1103
}