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

History | View | Annotate | Download (40 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 javax.swing.AbstractAction;
36
import javax.swing.Action;
37
import static javax.swing.Action.ACTION_COMMAND_KEY;
38
import static javax.swing.Action.NAME;
39
import static javax.swing.Action.SHORT_DESCRIPTION;
40
import static javax.swing.Action.SMALL_ICON;
41

    
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.ExpressionEvaluatorLocator;
48
import org.gvsig.expressionevaluator.ExpressionUtils;
49

    
50
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52

    
53
import org.gvsig.featureform.swing.JFeaturesForm;
54
import org.gvsig.fmap.dal.DALLocator;
55
import org.gvsig.fmap.dal.DataStore;
56
import org.gvsig.fmap.dal.StoresRepository;
57
import org.gvsig.fmap.dal.exception.DataException;
58
import org.gvsig.expressionevaluator.ExpressionEvaluator;
59
import org.gvsig.fmap.dal.feature.EditableFeature;
60
import org.gvsig.fmap.dal.feature.Feature;
61
import org.gvsig.fmap.dal.feature.FacadeOfAFeature;
62
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
63
import org.gvsig.fmap.dal.feature.FeatureQuery;
64
import org.gvsig.fmap.dal.feature.FeatureStore;
65
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
66
import org.gvsig.fmap.dal.feature.FeatureType;
67
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
68
import org.gvsig.fmap.dal.swing.AbstractDALActionFactory.AbstractDALActionContext;
69
import org.gvsig.fmap.dal.swing.DALActionFactory;
70
import org.gvsig.fmap.dal.swing.DALSwingLocator;
71
import org.gvsig.fmap.dal.swing.DataSwingManager;
72
import org.gvsig.fmap.dal.swing.impl.DefaultDataSwingManager;
73
import org.gvsig.fmap.dal.swing.impl.actions.ShowFormAction.ShowFormActionFactory;
74
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
75
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
76
import org.gvsig.tools.ToolsLocator;
77
import org.gvsig.tools.dispose.Disposable;
78
import org.gvsig.tools.dispose.DisposeUtils;
79
import org.gvsig.tools.dynform.AbortActionException;
80
import org.gvsig.tools.dynform.DynFormDefinition;
81
import org.gvsig.tools.dynform.DynFormLocator;
82
import org.gvsig.tools.dynform.DynFormManager;
83
import org.gvsig.tools.dynform.JDynForm;
84
import org.gvsig.tools.dynform.JDynFormField;
85
import org.gvsig.tools.dynform.JDynFormSet;
86
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_CANCEL_NEW;
87
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_DELETE;
88
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NEW;
89
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SAVE;
90
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SEARCH;
91
import org.gvsig.tools.dynform.JDynFormSet.JDynFormSetListener;
92
import org.gvsig.tools.dynobject.DynClass;
93
import org.gvsig.tools.dynobject.DynObject;
94
import org.gvsig.tools.evaluator.Evaluator;
95
import org.gvsig.tools.exception.BaseException;
96
import org.gvsig.tools.i18n.I18nManager;
97
import org.gvsig.tools.observer.Observable;
98
import org.gvsig.tools.observer.Observer;
99
import org.gvsig.tools.service.ServiceException;
100
import org.gvsig.tools.swing.api.ToolsSwingLocator;
101
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
102
import org.gvsig.tools.swing.api.windowmanager.Dialog;
103
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
104
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
105
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
106
import org.gvsig.tools.swing.icontheme.IconTheme;
107
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
108
import org.gvsig.tools.script.ScriptManager;
109
import org.gvsig.tools.swing.api.ActionListenerSupport;
110

    
111
/**
112
 * @author fdiaz
113
 *
114
 */
115
@SuppressWarnings("UseSpecificCatch")
116
public class DefaultJFeaturesForm implements JFeaturesForm, Disposable {
117

    
118
    private final String STARTEDITING_ACTION = "startEditing";
119
    private final String FINISHEDITING_ACTION = "finishEditing";
120
    private final String REFRESHFORM_ACTION = "refreshForm";
121

    
122
    public class DefaultFeaturesFormContext implements FeaturesFormContext {
123

    
124
        private DefaultFeaturesFormContext() {
125

    
126
        }
127

    
128
        @Override
129
        public FeatureStore getFeatureStore() {
130
            return store;
131
        }
132

    
133
        @Override
134
        public FeatureType getFeatureType() {
135
            try {
136
                return store.getDefaultFeatureType();
137
            } catch (DataException ex) {
138
                return null;
139
            }
140
        }
141

    
142
        @Override
143
        public ResourcesStorage getResourcesStorage() {
144
            if (store == null) {
145
                return null;
146
            }
147
            return store.getResourcesStorage();
148
        }
149

    
150
        @Override
151
        public StoresRepository getStoresRepository() {
152
            if (store == null) {
153
                return null;
154
            }
155
            return store.getStoresRepository();
156
        }
157

    
158
        @Override
159
        public ScriptManager getScriptManager() {
160
            return ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
161
        }
162

    
163
    }
164

    
165
    private class FormActionContext extends AbstractDALActionContext {
166

    
167
        public FormActionContext() {
168
            super(ACTION_CONTEXT_NAME);
169
        }
170

    
171
        @Override
172
        public DataStore getStore() {
173
            return store;
174
        }
175

    
176
        @Override
177
        public FeatureQuery getQuery() {
178
            return currentQuery;
179
        }
180

    
181
        @Override
182
        public int getSelectedsCount() {
183
            return 0;
184
        }
185

    
186
        @Override
187
        public Expression getFilterForSelecteds() {
188
            return null;
189
        }
190

    
191
        @Override
192
        public JComponent getActionButton(String actionName) {
193
            if (formset == null) {
194
                return null;
195
            }
196
            return formset.getActionButton(actionName);
197
        }
198

    
199
    }
200

    
201
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJFeaturesForm.class);
202

    
203
    private static final int PAGE_SIZE = 10;
204
    private JPanel panel;
205
    private JDynFormSet formset;
206
    private FeatureStore store;
207
    private FeaturePagingHelper features;
208
    private DynFormDefinition definition = null;
209
    private FeatureQuery currentQuery;
210
    private List<Action> otherActions;
211
    private ActionListenerSupport actionListeners;
212

    
213
    public DefaultJFeaturesForm() {
214
        this.otherActions = new ArrayList<>();
215
        this.panel = new JPanel(new BorderLayout());
216
        this.panel.addComponentListener(new ComponentAdapter() {
217
            @Override
218
            public void componentHidden(ComponentEvent e) {
219
                dispose();
220
            }
221
        });
222
        this.actionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
223
    }
224

    
225
    public static void selfRegister() {
226
        String[][] iconNames = new String[][]{
227
            new String[]{"dalswing", "form-refresh-data"}
228
        };
229
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
230
        for (String[] icon : iconNames) {
231
            URL url = DefaultJFeaturesForm.class.getResource(icon[1] + ".png");
232
            theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
233
        }
234

    
235
    }
236

    
237
    @Override
238
    public void setPreferredSize(Dimension dimension) {
239
        panel.setPreferredSize(dimension);
240
    }
241

    
242
    private void updateForm() {
243
        if (this.formset == null) {
244
            this.getFormset();
245
        }
246
        try {
247
            if (this.currentQuery != null) {
248
                this.currentQuery.retrievesAllAttributes();
249
            }
250
            this.features = DALLocator.getDataManager().createFeaturePagingHelper(store, this.currentQuery, PAGE_SIZE);
251
            this.formset.setValues(features.asListOfDynObjects());
252
        } catch (Exception ex) {
253
            throw new RuntimeException("Can't update form", ex);
254
        }
255
        updateButtonEnabledStatus();
256
    }
257

    
258
    @Override
259
    public JComponent asJComponent() {
260
        if (this.features == null) {
261
            try {
262
                updateForm();
263
            } catch (Exception ex) {
264
                throw new RuntimeException(ex);
265
            }
266
        }
267
        return this.panel;
268
    }
269

    
270
    @Override
271
    public void bind(FeatureStore store) {
272
        this.bind(store, null, null);
273
    }
274

    
275
    public void bind(FeatureStore store, DynClass definition) {
276
        this.bind(store, definition, null);
277
    }
278

    
279
    public void bind(FeatureStore store, DynClass definition, FeatureQuery query) {
280
        if (store == null) {
281
            throw new IllegalArgumentException("bind need a store as parameter, not a null.");
282
        }
283
        if (this.store == store) {
284
            return;
285
        }
286
        try {
287
            if (definition == null) {
288
                DefaultDataSwingManager manager = (DefaultDataSwingManager) DALSwingLocator.getSwingManager();
289
                definition = manager.featureType2DynClass(store, store.getDefaultFeatureType());
290
            }
291
            DynFormManager formManager = DynFormLocator.getDynFormManager();
292
            this.definition = formManager.getDefinition(definition);
293
            if (formset != null) {
294
                this.panel.remove(formset.asJComponent());
295
                this.panel.revalidate();
296
                this.formset = null;
297
            }
298
            this.store = store;
299
            DisposeUtils.bind(store);
300
            this.currentQuery = query;
301
            if (features != null) {
302
                this.features = null;
303
                updateForm();
304
            }
305
        } catch (Exception ex) {
306
            throw new RuntimeException("Can't bind store '" + store.getName() + "' to form", ex);
307
        }
308
    }
309

    
310
    @Override
311
    public void dispose() {
312
        DisposeUtils.disposeQuietly(store);
313
        this.store = null;
314
        this.panel = null;
315
        this.formset = null;
316
        this.features = null;
317
        this.definition = null;
318
        this.currentQuery = null;
319
        this.otherActions = null;
320
    }
321

    
322
    @Override
323
    public JDynFormSet getFormset() {
324
        if (this.formset == null) {
325
            DynFormManager formManager = DynFormLocator.getDynFormManager();
326
            this.formset = formManager.createJDynFormSet(
327
                    new DefaultFeaturesFormContext(),
328
                    this.definition,
329
                    null
330
            );
331
            List<String> groups = this.definition.getGroups();
332
            if (groups.size() == 1 && groups.get(0) == null) {
333
                this.formset.setLayoutMode(JDynForm.USE_PLAIN);
334
            } else {
335
                this.formset.setLayoutMode(JDynForm.USE_TABS);
336
            }
337
            this.formset.setAllowNew(true);
338
            this.formset.setAllowDelete(true);
339
            this.formset.setAllowUpdate(true);
340
            this.formset.setAllowClose(true);
341
            this.formset.setAllowSearch(true);
342
            this.formset.setAutosave(true);
343

    
344
            this.formset.addAction(new StartEditingAction());
345
            this.formset.addAction(new FinishEditingAction());
346
            this.formset.addAction(new RefreshAction());
347

    
348
            FormActionContext actionContext = new FormActionContext();
349
            Collection<DALActionFactory> factories = DALSwingLocator.getSwingManager().getStoreActions();
350
            for (DALActionFactory factory : factories) {
351
                if (StringUtils.equalsIgnoreCase(factory.getName(), ShowFormActionFactory.ACTION_NAME)) {
352
                    continue;
353
                }
354
                Action action = factory.createAction(actionContext);
355
                this.formset.addAction(action);
356
            }
357
            for (Action action : this.otherActions) {
358
                this.formset.addAction(action);
359
            }
360

    
361
            this.formset.addListener(new FormSetListener());
362
            this.formset.getForm().addListener(new JDynForm.JDynFormListener() {
363
                @Override
364
                public void message(String string) {
365
                }
366

    
367
                @Override
368
                public void fieldChanged(JDynFormField jdff) {
369
                    updateButtonEnabledStatus();
370
                }
371
            });
372

    
373
            ToolsSwingLocator.getToolsSwingManager().removeBorder(this.formset.asJComponent());
374
            this.panel.add(this.formset.asJComponent(), BorderLayout.CENTER);
375
            this.panel.revalidate();
376
        }
377
        updateButtonEnabledStatus();
378
        return this.formset;
379
    }
380

    
381
    @Override
382
    public void addAction(Action action) {
383
        this.otherActions.add(action);
384
        if (this.formset != null) {
385
            this.formset.addAction(action);
386
        }
387
    }
388

    
389
    @Override
390
    public long getCurrentIndex() {
391
        if (this.formset == null) {
392
            return -1;
393
        }
394
        return this.formset.getCurrentIndex();
395
    }
396

    
397
    @Override
398
    public Feature get(long index) {
399
        if (this.formset == null || this.features == null) {
400
            return null;
401
        }
402
        try {
403
            return this.features.getFeatureAt(index);
404
        } catch (BaseException ex) {
405
            return null;
406
        }
407
    }
408

    
409
    private class RefreshAction extends AbstractAction {
410

    
411
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
412
        public RefreshAction() {
413
            I18nManager i18nManager = ToolsLocator.getI18nManager();
414
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
415

    
416
            this.putValue(NAME, null);
417
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Reload_data"));
418
            this.putValue(SMALL_ICON, iconTheme.get("form-refresh-data"));
419
            this.putValue(ACTION_COMMAND_KEY, REFRESHFORM_ACTION);
420
            this.setEnabled(!formset.isInNewState());
421
        }
422

    
423
        @Override
424
        public void actionPerformed(ActionEvent ae) {
425
            try {
426
                I18nManager i18n = ToolsLocator.getI18nManager();
427
                formset.message(i18n.getTranslation("_Form_reloaded"));
428
                updateForm();
429
            } catch (Exception ex) {
430
                LOGGER.warn("Can't reload form", ex);
431
            }
432
        }
433
    }
434

    
435
    private class FinishEditingAction extends AbstractAction implements Observer {
436

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

    
442
            this.putValue(NAME, null);
443
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Stop_editing"));
444
            this.putValue(SMALL_ICON, iconTheme.get("table-stop-editing"));
445
            this.putValue(ACTION_COMMAND_KEY, FINISHEDITING_ACTION);
446

    
447
            this.setEnabled(store.isEditing());
448
            store.addObserver(this);
449
        }
450

    
451
        @Override
452
        public void actionPerformed(ActionEvent ae) {
453
            if (store.isEditing()) {
454
                try {
455
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
456
                    ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
457
                    int x = dialogManager.confirmDialog(
458
                            i18nManager.getTranslation("_Do_you_want_to_finish_editing_and_save_the_changes") + "\n\n"
459
                            + i18nManager.getTranslation("_Press_cancel_to_cancel_editing_and_changes"),
460
                            i18nManager.getTranslation("_Stop_editing"),
461
                            JOptionPane.YES_NO_CANCEL_OPTION,
462
                            JOptionPane.QUESTION_MESSAGE
463
                    );
464
                    switch (x) {
465
                        case JOptionPane.YES_OPTION:
466
                            store.finishEditing();
467
                            break;
468
                        case JOptionPane.NO_OPTION:
469
                            break;
470
                        case JOptionPane.CANCEL_OPTION:
471
                            store.cancelEditing();
472
                            int index = formset.getCurrentIndex();
473
                            try {
474
                                formset.setCurrentIndex(index);
475
                            } catch (Exception ex) {
476
                                LOGGER.warn("Can't reload form data after edit.", ex);
477
                            }
478
                            break;
479
                    }
480
                } catch (DataException ex) {
481
                    LOGGER.warn("Can't finish editing in FeatureForm (" + store.getName() + ").", ex);
482
                }
483
            }
484
            updateButtonEnabledStatus();
485
        }
486

    
487
        @Override
488
        public void update(Observable observable, Object notification) {
489
            if (store == null || formset == null) {
490
                return;
491
            }
492
            if (notification instanceof FeatureStoreNotification) {
493
                FeatureStoreNotification n = (FeatureStoreNotification) notification;
494
                switch (n.getType()) {
495
                    case FeatureStoreNotification.AFTER_STARTEDITING:
496
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
497
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
498
                        updateButtonEnabledStatus();
499
                        break;
500
                }
501
            }
502
        }
503

    
504
    }
505

    
506
    private class StartEditingAction extends AbstractAction implements Observer {
507

    
508
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
509
        public StartEditingAction() {
510
            I18nManager i18nManager = ToolsLocator.getI18nManager();
511
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
512

    
513
            this.putValue(NAME, null);
514
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Start_editing"));
515
            this.putValue(SMALL_ICON, iconTheme.get("table-start-editing"));
516
            this.putValue(ACTION_COMMAND_KEY, STARTEDITING_ACTION);
517

    
518
            this.setEnabled(!store.isEditing());
519
            store.addObserver(this);
520
        }
521

    
522
        @Override
523
        public void actionPerformed(ActionEvent ae) {
524
            if (!store.isEditing()) {
525
                try {
526
                    store.edit();
527
                } catch (DataException ex) {
528
                    LOGGER.warn("Can't finish editing in FeatureForm (" + store.getName() + ").", ex);
529
                }
530
            }
531
            updateButtonEnabledStatus();
532
        }
533

    
534
        @Override
535
        public void update(Observable observable, Object notification) {
536
            if (store == null || formset == null) {
537
                return;
538
            }
539
            if (notification instanceof FeatureStoreNotification) {
540
                FeatureStoreNotification n = (FeatureStoreNotification) notification;
541
                switch (n.getType()) {
542
                    case FeatureStoreNotification.AFTER_STARTEDITING:
543
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
544
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
545
                        updateButtonEnabledStatus();
546
                        break;
547
                }
548
            }
549
        }
550

    
551
    }
552

    
553
    @Override
554
    public void setQuery(FeatureQuery query) {
555
        if (this.features != null) {
556
            if (this.formset != null && !formset.isReadOnly() && this.formset.isAutosave() && this.formset.countValues() > 0) {
557
                if (!store.isEditing()) {
558
                    try {
559
                        store.edit();
560
                    } catch (DataException e1) {
561
                        throw new RuntimeException("Can't set query", e1);
562
                    }
563
                }
564
                saveChanges(this.formset);
565
            }
566
        }
567
        this.currentQuery = query;
568
        updateForm();
569
    }
570

    
571
    private FeatureQuery getCurrentQuery() {
572
        return this.currentQuery;
573
    }
574

    
575
    @Override
576
    public void showForm(MODE mode) {
577
        WindowManager winmgr = ToolsSwingLocator.getWindowManager();
578
        String title = this.definition.getLabel();
579
        winmgr.showWindow(this.asJComponent(), title, mode);
580
    }
581

    
582
    private void saveChanges(JDynFormSet theFormSet) {
583
        I18nManager i18n = ToolsLocator.getI18nManager();
584
        try {
585
            if (theFormSet.isInNewState()) {
586
                EditableFeature newFeature = store.createNewFeature(false);
587
                
588
                // Fill fields not in form with default values
589
                for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
590
                    JDynFormField field = formset.getForm().getField(attr.getName());
591
                    if( field==null ) {
592
                        newFeature.set(attr.getName(), attr.getDefaultValueCoerced());
593
                    }
594
                }
595
                DynObject newElement = newFeature.getAsDynObject();
596
                theFormSet.getFormValues(newElement);
597
                features.insert(((FacadeOfAFeature) newElement).getEditableFeature());
598
                this.formset.message(i18n.getTranslation("_Record_saved"));
599
                try {
600
                    this.formset.setValues(features.asListOfDynObjects());
601
                    this.formset.setCurrentIndex((int) (features.getTotalSize()) - 1);
602
                } catch (Exception ex) {
603
                    LOGGER.warn("Can't reload form data after insert.", ex);
604
                }
605
            } else {
606
                int index = theFormSet.getCurrentIndex();
607
                DynObject currentElement = theFormSet.get(index);
608
                theFormSet.getFormValues(currentElement);
609
                features.update(((FacadeOfAFeature) currentElement).getEditableFeature());
610
                this.formset.message(i18n.getTranslation("_Record_saved"));
611
                try {
612
                    this.formset.setCurrentIndex(index);
613
                } catch (Exception ex) {
614
                    LOGGER.warn("Can't reload form data after insert.", ex);
615
                }
616
            }
617
        } catch (Exception ex) {
618
            theFormSet.message(i18n.getTranslation("error_saving_data_will_not_save"));
619
            throw new RuntimeException("Can't save values", ex);
620

    
621
        } finally {
622
            updateButtonEnabledStatus();
623
        }
624

    
625
    }
626

    
627
    private void deleteCurrentElement(JDynFormSet theFormSet) {
628
        I18nManager i18n = ToolsLocator.getI18nManager();
629
        try {
630
            int index = theFormSet.getCurrentIndex();
631
            DynObject currentElement = theFormSet.get(index);
632
            theFormSet.getFormValues(currentElement);
633
            Feature feature = ((FacadeOfAFeature) currentElement).getFeature();
634
            if (feature instanceof EditableFeature) {
635
                feature = ((EditableFeature) feature).getNotEditableCopy();
636
            }
637
            features.delete(feature);
638

    
639
            this.formset.message(i18n.getTranslation("_Record_removed"));
640

    
641
            this.formset.setValues(features.asListOfDynObjects());
642
            if (features.getTotalSize() - 1 < index) {
643
                index = index - 1;
644
            }
645
            this.formset.setCurrentIndex(index);
646

    
647
        } catch (Exception ex) {
648
            theFormSet.message(i18n.getTranslation("error_removing_data_will_not_remove"));
649
            throw new RuntimeException("Can't remove values", ex);
650

    
651
        } finally {
652
            updateButtonEnabledStatus();
653
        }
654

    
655
    }
656

    
657
    @Override
658
    public void saveChanges() {
659
        if (this.formset != null && this.formset.countValues() > 0) {
660
            if (store != null && !store.isEditing()) {
661
                try {
662
                    store.edit();
663
                } catch (DataException e1) {
664
                    LOGGER.warn("Can't edit the store " + store.getName());
665
                    throw new RuntimeException("Can't save changes.", e1);
666
                }
667
            }
668
            this.saveChanges(this.formset);
669
        }
670
    }
671

    
672
    private void updateButtonEnabledStatus() {
673
        if (this.formset == null) {
674
            return;
675
        }
676
        if (this.store == null || store.isBroken() || store.isAppending() || this.features == null) {
677
            this.formset.setReadOnly(true);
678
            formset.setActionVisible(STARTEDITING_ACTION, true);
679
            formset.setActionEnabled(STARTEDITING_ACTION, true);
680
            formset.setActionVisible(FINISHEDITING_ACTION, false);
681
            formset.setActionEnabled(FINISHEDITING_ACTION, false);
682
            formset.setActionEnabled(ACTION_DELETE, false);
683
            formset.setActionEnabled(ACTION_NEW, false);
684
            formset.setActionEnabled(ACTION_CANCEL_NEW, false);
685
            formset.setActionEnabled(ACTION_SAVE, false);
686
            formset.setActionEnabled(ACTION_SEARCH, false);
687
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
688
            formset.setActionEnabled(JDynFormSet.ACTION_NEXT, false);
689
            formset.setActionEnabled(JDynFormSet.ACTION_PREVIOUS, false);
690
            formset.setActionEnabled(JDynFormSet.ACTION_FIRST, false);
691
            formset.setActionEnabled(JDynFormSet.ACTION_LAST, false);
692
            return;
693
        }
694
        setEnabledUniqueFields(false);
695
        if (store.isEditing()) {
696
            this.formset.setReadOnly(false);
697
            formset.setActionVisible(STARTEDITING_ACTION, false);
698
            formset.setActionEnabled(STARTEDITING_ACTION, false);
699
            formset.setActionVisible(FINISHEDITING_ACTION, true);
700
            formset.setActionEnabled(FINISHEDITING_ACTION, true);
701
            if (formset.isInNewState()) {
702
                formset.setActionEnabled(ACTION_DELETE, false);
703
                formset.setActionEnabled(ACTION_SEARCH, false);
704
                formset.setActionEnabled(ACTION_NEW, false);
705
                formset.setActionEnabled(ACTION_CANCEL_NEW, true);
706
                formset.setActionEnabled(ACTION_SAVE, true);
707
                formset.setActionEnabled(FINISHEDITING_ACTION, false);
708
                formset.setActionEnabled(REFRESHFORM_ACTION, false);
709
                setEnabledUniqueFields(true);
710

    
711
            } else if (this.features != null && this.features.isEmpty()) {
712
                formset.getForm().setReadOnly(true);
713
                formset.setActionEnabled(ACTION_DELETE, false);
714
                formset.setActionEnabled(ACTION_SEARCH, false);
715
                formset.setActionEnabled(ACTION_NEW, true);
716
                formset.setActionEnabled(ACTION_CANCEL_NEW, true);
717
                formset.setActionEnabled(ACTION_SAVE, false);
718
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
719
                formset.setActionEnabled(FINISHEDITING_ACTION, true);         
720
                formset.setActionEnabled(JDynFormSet.ACTION_NEXT, false);
721
                formset.setActionEnabled(JDynFormSet.ACTION_PREVIOUS, false);
722
                formset.setActionEnabled(JDynFormSet.ACTION_FIRST, false);
723
                formset.setActionEnabled(JDynFormSet.ACTION_LAST, false);
724

    
725
            } else if (formset.getForm().isModified()) {
726
                formset.setActionEnabled(ACTION_DELETE, false);
727
                formset.setActionEnabled(ACTION_SEARCH, false);
728
                formset.setActionEnabled(ACTION_NEW, false);
729
                formset.setActionEnabled(ACTION_CANCEL_NEW, false);
730
                formset.setActionEnabled(ACTION_SAVE, true);
731
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
732
                formset.setActionEnabled(FINISHEDITING_ACTION, false);
733
                formset.setActionEnabled(JDynFormSet.ACTION_NEXT, false);
734
                formset.setActionEnabled(JDynFormSet.ACTION_PREVIOUS, false);
735
                formset.setActionEnabled(JDynFormSet.ACTION_FIRST, false);
736
                formset.setActionEnabled(JDynFormSet.ACTION_LAST, false);
737

    
738
            } else {
739
                this.formset.setReadOnly(false); //Esto habilita los botones de navegacion
740
                formset.setActionEnabled(ACTION_DELETE, true);
741
                formset.setActionEnabled(ACTION_SEARCH, true);
742
                formset.setActionEnabled(ACTION_NEW, true);
743
                formset.setActionEnabled(ACTION_CANCEL_NEW, false);
744
                formset.setActionEnabled(ACTION_SAVE, false); //false);
745
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
746
                formset.setActionEnabled(FINISHEDITING_ACTION, true);
747
            }
748

    
749
            return;
750
        }
751
        this.formset.setReadOnly(true);
752
        formset.setActionVisible(STARTEDITING_ACTION, true);
753
        formset.setActionEnabled(STARTEDITING_ACTION, true);
754
        formset.setActionVisible(FINISHEDITING_ACTION, false);
755
        formset.setActionEnabled(FINISHEDITING_ACTION, false);
756
        formset.setActionEnabled(ACTION_DELETE, false);
757
        formset.setActionEnabled(ACTION_NEW, false);
758
        formset.setActionEnabled(ACTION_CANCEL_NEW, false);
759
        formset.setActionEnabled(ACTION_SAVE, false);
760
        formset.setActionEnabled(ACTION_SEARCH, true);
761
        formset.setActionEnabled(REFRESHFORM_ACTION, true);
762
    }
763

    
764
    private void clearUniqueFields() {
765
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
766
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
767
                JDynFormField field = formset.getForm().getField(attr.getName());
768
                if (field != null) {
769
                    field.clear();
770
                }
771
            }
772
        }
773
    }
774

    
775
    private void setEnabledUniqueFields(boolean enabled) {
776
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
777
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
778
                JDynFormField field = formset.getForm().getField(attr.getName());
779
                if (field != null) {
780
                    field.setReadOnly(!enabled);
781
                }
782
            }
783
        }
784
    }
785

    
786
    @Override
787
    public long getDataSetSize() {
788
        if (this.features != null) {
789
            return features.getTotalSize();
790
        }
791
        return 0;
792
    }
793

    
794
    @Override
795
    public FeatureStore getFeatureStore() {
796
        return this.store;
797
    }
798

    
799
    private class FormSetListener implements JDynFormSetListener {
800

    
801
        @Override
802
        public void formMessage(String message) {
803
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMessage"));
804
        }
805

    
806
        @Override
807
        public void formClose() {
808
            panel.setVisible(false);
809
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formClose"));
810
        }
811

    
812
        @Override
813
        public void formMovedTo(int currentPosition) throws AbortActionException {
814
            LOGGER.trace("formMovedTo " + currentPosition);
815
            updateButtonEnabledStatus();
816
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMovedTo"));
817
        }
818

    
819
        @Override
820
        public void formBeforeSave(JDynFormSet dynformSet) throws AbortActionException {
821
            LOGGER.trace("formBeforeSave");
822
            saveChanges(dynformSet);
823
            updateButtonEnabledStatus();
824
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSave"));
825
        }
826

    
827
        @Override
828
        public void formBeforeNew(JDynFormSet dynformSet) throws AbortActionException {
829
            LOGGER.trace("formBeforeNew");
830
            clearUniqueFields();
831
            updateButtonEnabledStatus();
832
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeNew"));
833
        }
834

    
835
        @Override
836
        public void formBeforeDelete(JDynFormSet dynformSet) throws AbortActionException {
837
            LOGGER.trace("formBeforeDelete");
838
            updateButtonEnabledStatus();
839
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeDelete"));
840
        }
841

    
842
        @Override
843
        public void formAfterSave(JDynFormSet dynformSet) throws AbortActionException {
844
            LOGGER.trace("formAfterSave");
845
            updateButtonEnabledStatus();
846
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSave"));
847
        }
848

    
849
        @Override
850
        public void formAfterNew(JDynFormSet dynformSet) throws AbortActionException {
851
            LOGGER.trace("formAfterNew");
852
            updateButtonEnabledStatus();
853
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterNew"));
854
        }
855

    
856
        @Override
857
        public void formAfterDelete(JDynFormSet dynformSet) throws AbortActionException {
858
            LOGGER.trace("formAfterDelete");
859
            deleteCurrentElement(dynformSet);
860
            updateButtonEnabledStatus();
861
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterDelete"));
862
        }
863

    
864
//        @Override
865
//        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
866
//            LOGGER.trace("formBeforeSearch");
867
//            DataSwingManager dataSwingmanager = DALSwingLocator.getSwingManager();
868
//            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
869
//
870
//            JExpressionBuilder builder = dataSwingmanager.createQueryFilterExpresion(store);
871
//            FeatureQuery currentQuery = getCurrentQuery();
872
//            if( currentQuery!=null ) {
873
//                Evaluator filter = currentQuery.getFilter();
874
//                if( filter instanceof ExpressionEvaluator ) {
875
//                    Expression expression = ((ExpressionEvaluator)filter).getExpression();
876
//                    builder.setExpression(expression);
877
//                }
878
//            }
879
//            Dialog dialog = winmgr.createDialog(
880
//                    builder.asJComponent(),
881
//                    "Filtro",
882
//                    "Creacion de filtro sobre '"+store.getName()+"'",
883
//                    WindowManager_v2.BUTTONS_OK_CANCEL
884
//            );
885
//            dialog.show(WindowManager.MODE.DIALOG);
886
//            if( dialog.getAction() == WindowManager_v2.BUTTON_OK ) {
887
//                Expression expresion = builder.getExpression();
888
//                try {
889
//                    FeatureQuery query = store.createFeatureQuery();
890
//                    if( ExpressionUtils.isPhraseEmpty(expresion) ) {
891
//                        query.clearFilter();
892
//                    } else {
893
//                        query.setFilter(expresion);
894
//                    }
895
//                    setQuery(query);
896
//                } catch (Exception ex) {
897
//                    LOGGER.warn("Can't apply filter '" + expresion + "'.", ex);
898
//                }
899
//            }
900
//        }
901
        @Override
902
        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
903
            LOGGER.trace("formBeforeSearch");
904
            DataSwingManager dataSwingmanager = DALSwingLocator.getSwingManager();
905
            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
906

    
907
            final FeatureStoreSearchPanel searchPanel = dataSwingmanager.createFeatureStoreSearchPanel(store);
908
            searchPanel.setShowActions(false);
909
            FeatureQuery currentQuery = getCurrentQuery();
910
            if (currentQuery != null) {
911
                Evaluator filter = currentQuery.getFilter();
912
                if (filter instanceof ExpressionEvaluator) {
913
                    Expression expression = ((ExpressionEvaluator) filter).toExpression();
914
                    searchPanel.setFilter(expression);
915
                    searchPanel.search();
916
                }
917
            }
918
            searchPanel.asJComponent().setPreferredSize(
919
                    new Dimension(FeatureStoreSearchPanel.DEFAULT_WIDTH, 320)
920
            );
921
            I18nManager i18n = ToolsLocator.getI18nManager();
922
            Dialog dialog = winmgr.createDialog(
923
                    searchPanel.asJComponent(),
924
                    i18n.getTranslation("_Filter"),
925
                    i18n.getTranslation("_Creating_filter_for") + ": '" + store.getName() + "'",
926
                    WindowManager_v2.BUTTONS_OK_CANCEL
927
            );
928
            dialog.show(WindowManager.MODE.DIALOG);
929
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
930
                SearchParameters params = searchPanel.fetch(null);
931
                if (params.getQuery() != null) {
932
                    FeatureQuery searchQuery = params.getQuery().getCopy();
933

    
934
                    Expression expresion = null;
935
                    if (searchQuery != null) {
936
                        expresion = searchQuery.getExpressionFilter();
937
                    }
938
                    try {
939
                        FeatureQuery query = store.createFeatureQuery();
940
                        if (ExpressionUtils.isPhraseEmpty(expresion)) {
941
                            query.clearFilter();
942
                        } else {
943
                            query.setFilter(expresion);
944
                        }
945
                        setQuery(query);
946
                    } catch (Exception ex) {
947
                        LOGGER.warn("Can't apply filter '" + expresion + "'.", ex);
948
                    }
949
                } else {
950
                    LOGGER.warn("FeatureQuery from parameters is null. Query is not applied to the JFeaturesFrom");
951
                }
952
            }
953
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSearch"));
954
        }
955

    
956
        @Override
957
        public void formAfterSearch(JDynFormSet dynformSet) throws AbortActionException {
958
            LOGGER.trace("formAfterSearch");
959
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSearch"));
960
        }
961

    
962
        @Override
963
        public void formBeforeCancelNew(JDynFormSet dynformSet) throws AbortActionException {
964
            LOGGER.trace("formBeforeCancelNew");
965
            updateButtonEnabledStatus();
966
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeCancelNew"));
967
        }
968

    
969
        @Override
970
        public void formAfterCancelNew(JDynFormSet dynformSet) throws AbortActionException {
971
            LOGGER.trace("formAfterCancelNew");
972
            updateButtonEnabledStatus();
973
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterCancelNew"));
974
        }
975
    }
976

    
977
//    private static class StoreEditException extends AbortActionException {
978
//
979
//        /**
980
//         *
981
//         */
982
//        private static final long serialVersionUID = -7682017811778577130L;
983
//
984
//        public StoreEditException(Throwable cause, String storename) {
985
//            super("Can't edit the store '%(storename)'", cause, "cant_edit_the store_XstorenameX", serialVersionUID);
986
//            setValue("storename", storename);
987
//        }
988
//    }
989
    @Override
990
    public void addActionListener(ActionListener listener) {
991
        this.actionListeners.addActionListener(listener);
992
    }
993

    
994
    @Override
995
    public ActionListener[] getActionListeners() {
996
        return this.actionListeners.getActionListeners();
997
    }
998

    
999
    @Override
1000
    public void removeActionListener(ActionListener listener) {
1001
        this.actionListeners.removeActionListener(listener);
1002
    }
1003

    
1004
    @Override
1005
    public void removeAllActionListener() {
1006
        this.actionListeners.removeAllActionListener();
1007
    }
1008

    
1009
    @Override
1010
    public void fireActionEvent(ActionEvent event) {
1011
        this.actionListeners.fireActionEvent(event);
1012
    }
1013

    
1014
    @Override
1015
    public boolean hasActionListeners() {
1016
        return this.actionListeners.hasActionListeners();
1017
    }
1018

    
1019
}