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

History | View | Annotate | Download (38.7 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
import javax.swing.JComponent;
42
import javax.swing.JOptionPane;
43
import javax.swing.JPanel;
44
import org.apache.commons.lang3.StringUtils;
45
import org.gvsig.expressionevaluator.Expression;
46
import org.gvsig.expressionevaluator.ExpressionEvaluator;
47
import org.gvsig.expressionevaluator.ExpressionUtils;
48
import org.gvsig.featureform.swing.JFeaturesForm;
49
import org.gvsig.fmap.dal.DALLocator;
50
import org.gvsig.fmap.dal.DataStore;
51
import org.gvsig.fmap.dal.exception.DataException;
52
import org.gvsig.fmap.dal.feature.EditableFeature;
53
import org.gvsig.fmap.dal.feature.FacadeOfAFeature;
54
import org.gvsig.fmap.dal.feature.Feature;
55
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
56
import org.gvsig.fmap.dal.feature.FeatureQuery;
57
import org.gvsig.fmap.dal.feature.FeatureStore;
58
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
59
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
60
import org.gvsig.fmap.dal.swing.AbstractDALActionFactory.AbstractDALActionContext;
61
import org.gvsig.fmap.dal.swing.DALActionFactory;
62
import org.gvsig.fmap.dal.swing.DALSwingLocator;
63
import org.gvsig.fmap.dal.swing.DataSwingManager;
64
import org.gvsig.fmap.dal.swing.impl.DefaultDataSwingManager;
65
import org.gvsig.fmap.dal.swing.impl.actions.ShowFormAction.ShowFormActionFactory;
66
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
67
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
68
import org.gvsig.tools.ToolsLocator;
69
import org.gvsig.tools.dispose.Disposable;
70
import org.gvsig.tools.dispose.DisposeUtils;
71
import org.gvsig.tools.dynform.AbortActionException;
72
import org.gvsig.tools.dynform.DynFormDefinition;
73
import org.gvsig.tools.dynform.DynFormLocator;
74
import org.gvsig.tools.dynform.DynFormManager;
75
import org.gvsig.tools.dynform.JDynForm;
76
import org.gvsig.tools.dynform.JDynFormField;
77
import org.gvsig.tools.dynform.JDynFormSet;
78
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_CANCEL_NEW;
79
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_DELETE;
80
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NAVIGATION;
81
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NEW;
82
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SAVE;
83
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SEARCH;
84
import org.gvsig.tools.dynform.JDynFormSet.JDynFormSetListener;
85
import org.gvsig.tools.dynobject.DynClass;
86
import org.gvsig.tools.dynobject.DynObject;
87
import org.gvsig.tools.evaluator.Evaluator;
88
import org.gvsig.tools.exception.BaseException;
89
import org.gvsig.tools.i18n.I18nManager;
90
import org.gvsig.tools.observer.Observable;
91
import org.gvsig.tools.observer.Observer;
92
import org.gvsig.tools.swing.api.ActionListenerSupport;
93
import org.gvsig.tools.swing.api.ToolsSwingLocator;
94
import org.gvsig.tools.swing.api.ToolsSwingUtils;
95
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
96
import org.gvsig.tools.swing.api.windowmanager.Dialog;
97
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
98
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
99
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
100
import org.gvsig.tools.swing.icontheme.IconTheme;
101
import org.slf4j.Logger;
102
import org.slf4j.LoggerFactory;
103

    
104
/**
105
 * @author fdiaz
106
 *
107
 */
108
@SuppressWarnings("UseSpecificCatch")
109
public class DefaultJFeaturesForm implements JFeaturesForm, Disposable {
110

    
111
    private final String STARTEDITING_ACTION = "startEditing";
112
    private final String FINISHEDITING_ACTION = "finishEditing";
113
    private final String REFRESHFORM_ACTION = "refreshForm";
114

    
115
    private class FormActionContext extends AbstractDALActionContext {
116

    
117
        public FormActionContext() {
118
            super(ACTION_CONTEXT_NAME);
119
        }
120

    
121
        @Override
122
        public DataStore getStore() {
123
            return store;
124
        }
125

    
126
        @Override
127
        public FeatureQuery getQuery() {
128
            return currentQuery;
129
        }
130

    
131
        @Override
132
        public int getSelectedsCount() {
133
            return 0;
134
        }
135

    
136
        @Override
137
        public Expression getFilterForSelecteds() {
138
            return null;
139
        }
140

    
141
        @Override
142
        public JComponent getActionButton(String actionName) {
143
            if (formset == null) {
144
                return null;
145
            }
146
            return formset.getActionButton(actionName);
147
        }
148

    
149
    }
150

    
151
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJFeaturesForm.class);
152

    
153
    private static final int PAGE_SIZE = 10;
154
    private JPanel panel;
155
    private JDynFormSet formset;
156
    private FeatureStore store;
157
    private FeaturePagingHelper features;
158
    private DynFormDefinition definition = null;
159
    private FeatureQuery currentQuery;
160
    private List<Action> otherActions;
161
    private ActionListenerSupport actionListeners;
162

    
163
    public DefaultJFeaturesForm() {
164
        this.otherActions = new ArrayList<>();
165
        this.panel = new JPanel(new BorderLayout());
166
        this.panel.addComponentListener(new ComponentAdapter() {
167
            @Override
168
            public void componentHidden(ComponentEvent e) {
169
                dispose();
170
            }
171
        });
172
        this.actionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
173
    }
174

    
175
    public static void selfRegister() {
176
        String[][] iconNames = new String[][]{
177
            new String[]{"dalswing", "form-refresh-data"}
178
        };
179
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
180
        for (String[] icon : iconNames) {
181
            URL url = DefaultJFeaturesForm.class.getResource(icon[1] + ".png");
182
            theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
183
        }
184

    
185
    }
186

    
187
    @Override
188
    public void setPreferredSize(Dimension dimension) {
189
        panel.setPreferredSize(dimension);
190
    }
191

    
192
    private void updateForm() {
193
        if (this.formset == null) {
194
            this.getFormset();
195
        }
196
        try {
197
            if (this.currentQuery != null) {
198
                this.currentQuery.retrievesAllAttributes();
199
            }
200
            this.features = DALLocator.getDataManager().createFeaturePagingHelper(store, this.currentQuery, PAGE_SIZE);
201
            this.formset.setValues(features.asListOfDynObjects());
202
        } catch (Exception ex) {
203
            throw new RuntimeException("Can't update form", ex);
204
        }
205
        updateButtonEnabledStatus();
206
    }
207

    
208
    @Override
209
    public JComponent asJComponent() {
210
        if (this.features == null) {
211
            try {
212
                updateForm();
213
            } catch (Exception ex) {
214
                throw new RuntimeException(ex);
215
            }
216
        }
217
        return this.panel;
218
    }
219

    
220
    @Override
221
    public void bind(FeatureStore store) {
222
        this.bind(store, null, null);
223
    }
224

    
225
    public void bind(FeatureStore store, DynClass definition) {
226
        this.bind(store, definition, null);
227
    }
228

    
229
    public void bind(FeatureStore store, DynClass definition, FeatureQuery query) {
230
        if (store == null) {
231
            throw new IllegalArgumentException("bind need a store as parameter, not a null.");
232
        }
233
        if (this.store == store) {
234
            return;
235
        }
236
        try {
237
            if (definition == null) {
238
                DefaultDataSwingManager manager = (DefaultDataSwingManager) DALSwingLocator.getSwingManager();
239
                definition = manager.featureType2DynClass(store, store.getDefaultFeatureType());
240
            }
241
            DynFormManager formManager = DynFormLocator.getDynFormManager();
242
            this.definition = formManager.getDefinition(definition);
243
            if (formset != null) {
244
                this.panel.remove(formset.asJComponent());
245
                this.panel.revalidate();
246
                this.formset = null;
247
            }
248
            this.store = store;
249
            DisposeUtils.bind(store);
250
            this.currentQuery = query;
251
            if (features != null) {
252
                this.features = null;
253
                updateForm();
254
            }
255
        } catch (Exception ex) {
256
            throw new RuntimeException("Can't bind store '" + store.getName() + "' to form", ex);
257
        }
258
    }
259

    
260
    @Override
261
    public void dispose() {
262
        DisposeUtils.disposeQuietly(store);
263
        this.store = null;
264
        this.panel = null;
265
        this.formset = null;
266
        this.features = null;
267
        this.definition = null;
268
        this.currentQuery = null;
269
        this.otherActions = null;
270
    }
271

    
272
    @Override
273
    public JDynFormSet getFormset() {
274
        if (this.formset == null) {
275
            DynFormManager formManager = DynFormLocator.getDynFormManager();
276
            this.formset = formManager.createJDynFormSet(
277
                    new DefaultFeaturesFormContext(this.store),
278
                    this.definition,
279
                    null
280
            );
281
            List<String> groups = this.definition.getGroups();
282
            if (groups.size() == 1 && groups.get(0) == null) {
283
                this.formset.setLayoutMode(JDynForm.USE_PLAIN);
284
            } else {
285
                this.formset.setLayoutMode(JDynForm.USE_TABS);
286
            }
287
            this.formset.setAllowNew(true);
288
            this.formset.setAllowDelete(true);
289
            this.formset.setAllowUpdate(true);
290
            this.formset.setAllowClose(true);
291
            this.formset.setAllowSearch(true);
292
            this.formset.setAutosave(true);
293

    
294
            this.formset.addAction(new StartEditingAction());
295
            this.formset.addAction(new FinishEditingAction());
296
            this.formset.addAction(new RefreshAction());
297

    
298
            FormActionContext actionContext = new FormActionContext();
299
            try {
300
                Collection<DALActionFactory> factories = DALSwingLocator.getSwingManager().getStoreActions();
301
                for (DALActionFactory factory : factories) {
302
                    if (factory == null || StringUtils.equalsIgnoreCase(factory.getName(), ShowFormActionFactory.ACTION_NAME)) {
303
                        continue;
304
                    }
305
                    try {
306
                        Action action = factory.createAction(actionContext);
307
                        this.formset.addAction(action);
308
                    } catch (Exception ex) {
309
                        LOGGER.warn("Can't add action " + factory.getName(), ex);
310
                    }
311
                }
312
            } catch (Exception ex) {
313
                LOGGER.warn("Can't add actions", ex);
314
            }
315
            for (Action action : this.otherActions) {
316
                this.formset.addAction(action);
317
            }
318

    
319
            this.formset.addListener(new FormSetListener());
320
            this.formset.getForm().addListener(new JDynForm.JDynFormListener() {
321
                @Override
322
                public void message(String string) {
323
                }
324

    
325
                @Override
326
                public void fieldChanged(JDynFormField jdff) {
327
                    updateButtonEnabledStatus();
328
                }
329
            });
330

    
331
            ToolsSwingLocator.getToolsSwingManager().removeBorder(this.formset.asJComponent());
332
            this.panel.add(this.formset.asJComponent(), BorderLayout.CENTER);
333
            this.panel.revalidate();
334
            ToolsSwingUtils.ensureRowsCols(this.panel, 8, 70, 25, 100);
335

    
336
        }
337
        updateButtonEnabledStatus();
338
        return this.formset;
339
    }
340

    
341
    @Override
342
    public void addAction(Action action) {
343
        this.otherActions.add(action);
344
        if (this.formset != null) {
345
            this.formset.addAction(action);
346
        }
347
    }
348

    
349
    @Override
350
    public long getCurrentIndex() {
351
        if (this.formset == null) {
352
            return -1;
353
        }
354
        return this.formset.getCurrentIndex();
355
    }
356

    
357
    @Override
358
    public Feature get(long index) {
359
        if (this.formset == null || this.features == null) {
360
            return null;
361
        }
362
        try {
363
            return this.features.getFeatureAt(index);
364
        } catch (BaseException ex) {
365
            return null;
366
        }
367
    }
368

    
369
    private class RefreshAction extends AbstractAction {
370

    
371
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
372
        public RefreshAction() {
373
            I18nManager i18nManager = ToolsLocator.getI18nManager();
374
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
375

    
376
            this.putValue(NAME, null);
377
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Reload_data"));
378
            this.putValue(SMALL_ICON, iconTheme.get("form-refresh-data"));
379
            this.putValue(ACTION_COMMAND_KEY, REFRESHFORM_ACTION);
380
            this.setEnabled(!formset.isInNewState());
381
        }
382

    
383
        @Override
384
        public void actionPerformed(ActionEvent ae) {
385
            try {
386
                I18nManager i18n = ToolsLocator.getI18nManager();
387
                formset.message(i18n.getTranslation("_Form_reloaded"));
388
                int x=formset.getCurrentIndex();
389
                updateForm();
390
                formset.setCurrentIndex(x);
391
            } catch (Exception ex) {
392
                LOGGER.warn("Can't reload form", ex);
393
            }
394
        }
395
    }
396

    
397
    private class FinishEditingAction extends AbstractAction implements Observer {
398

    
399
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
400
        public FinishEditingAction() {
401
            I18nManager i18nManager = ToolsLocator.getI18nManager();
402
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
403

    
404
            this.putValue(NAME, null);
405
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Stop_editing"));
406
            this.putValue(SMALL_ICON, iconTheme.get("table-stop-editing"));
407
            this.putValue(ACTION_COMMAND_KEY, FINISHEDITING_ACTION);
408

    
409
            this.setEnabled(store.isEditing());
410
            store.addObserver(this);
411
        }
412

    
413
        @Override
414
        public void actionPerformed(ActionEvent ae) {
415
            if (store.isEditing()) {
416
                try {
417
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
418
                    ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
419
                    int x = dialogManager.confirmDialog(
420
                            i18nManager.getTranslation("_Do_you_want_to_finish_editing_and_save_the_changes") + "\n\n"
421
                            + i18nManager.getTranslation("_Press_cancel_to_cancel_editing_and_changes"),
422
                            i18nManager.getTranslation("_Stop_editing"),
423
                            JOptionPane.YES_NO_CANCEL_OPTION,
424
                            JOptionPane.QUESTION_MESSAGE
425
                    );
426
                    switch (x) {
427
                        case JOptionPane.YES_OPTION:
428
                            store.finishEditing();
429
                            break;
430
                        case JOptionPane.NO_OPTION:
431
                            break;
432
                        case JOptionPane.CANCEL_OPTION:
433
                            store.cancelEditing();
434
                            int index = formset.getCurrentIndex();
435
                            try {
436
                                formset.setCurrentIndex(index);
437
                            } catch (Exception ex) {
438
                                LOGGER.warn("Can't reload form data after edit.", ex);
439
                            }
440
                            break;
441
                    }
442
                } catch (DataException ex) {
443
                    LOGGER.warn("Can't finish editing in FeatureForm (" + store.getName() + ").", ex);
444
                }
445
            }
446
            updateButtonEnabledStatus();
447
        }
448

    
449
        @Override
450
        public void update(Observable observable, Object notification) {
451
            if (store == null || formset == null) {
452
                return;
453
            }
454
            if (notification instanceof FeatureStoreNotification) {
455
                FeatureStoreNotification n = (FeatureStoreNotification) notification;
456
                switch (n.getType()) {
457
                    case FeatureStoreNotification.AFTER_STARTEDITING:
458
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
459
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
460
                        updateButtonEnabledStatus();
461
                        break;
462
                }
463
            }
464
        }
465

    
466
    }
467

    
468
    private class StartEditingAction extends AbstractAction implements Observer {
469

    
470
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
471
        public StartEditingAction() {
472
            I18nManager i18nManager = ToolsLocator.getI18nManager();
473
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
474

    
475
            this.putValue(NAME, null);
476
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Start_editing"));
477
            this.putValue(SMALL_ICON, iconTheme.get("table-start-editing"));
478
            this.putValue(ACTION_COMMAND_KEY, STARTEDITING_ACTION);
479

    
480
            this.setEnabled(!store.isEditing());
481
            store.addObserver(this);
482
        }
483

    
484
        @Override
485
        public void actionPerformed(ActionEvent ae) {
486
            if (!store.isEditing()) {
487
                try {
488
                    store.edit();
489
                } catch (DataException ex) {
490
                    LOGGER.warn("Can't finish editing in FeatureForm (" + store.getName() + ").", ex);
491
                }
492
            }
493
            updateButtonEnabledStatus();
494
        }
495

    
496
        @Override
497
        public void update(Observable observable, Object notification) {
498
            if (store == null || formset == null) {
499
                return;
500
            }
501
            if (notification instanceof FeatureStoreNotification) {
502
                FeatureStoreNotification n = (FeatureStoreNotification) notification;
503
                switch (n.getType()) {
504
                    case FeatureStoreNotification.AFTER_STARTEDITING:
505
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
506
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
507
                        updateButtonEnabledStatus();
508
                        break;
509
                }
510
            }
511
        }
512

    
513
    }
514

    
515
    @Override
516
    public void setQuery(FeatureQuery query) {
517
        if (this.features != null) {
518
            if (this.formset != null && !formset.isReadOnly() && this.formset.isAutosave() && this.formset.countValues() > 0) {
519
                if(this.formset.getForm().isModified()){
520
                    if (!store.isEditing()) {
521
                        try {
522
                            store.edit();
523
                        } catch (DataException e1) {
524
                            throw new RuntimeException("Can't set query", e1);
525
                        }
526
                    }
527
                    saveChanges(this.formset);
528
                }
529
            }
530
        }
531
        this.currentQuery = query;
532
        updateForm();
533
    }
534

    
535
    private FeatureQuery getCurrentQuery() {
536
        return this.currentQuery;
537
    }
538

    
539
    @Override
540
    public void showForm(MODE mode) {
541
        WindowManager winmgr = ToolsSwingLocator.getWindowManager();
542
        String title = this.definition.getLabel();
543
        winmgr.showWindow(this.asJComponent(), title, mode);
544
    }
545

    
546
    private void saveChanges(JDynFormSet theFormSet) {
547
        I18nManager i18n = ToolsLocator.getI18nManager();
548
        try {
549
            if (theFormSet.isInNewState()) {
550
                EditableFeature newFeature = store.createNewFeature(false);
551
                
552
                // Fill fields not in form with default values
553
                for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
554
                    JDynFormField field = formset.getForm().getField(attr.getName());
555
                    if( field==null ) {
556
                        newFeature.set(attr.getName(), attr.getDefaultValueCoerced());
557
                    }
558
                }
559
                DynObject newElement = newFeature.getAsDynObject();
560
                theFormSet.getFormValues(newElement);
561
                features.insert(((FacadeOfAFeature) newElement).getEditableFeature());
562
                this.formset.message(i18n.getTranslation("_Record_saved"));
563
                try {
564
                    this.formset.setValues(features.asListOfDynObjects());
565
                    this.formset.setCurrentIndex((int) (features.getTotalSize()) - 1);
566
                } catch (Exception ex) {
567
                    LOGGER.warn("Can't reload form data after insert.", ex);
568
                }
569
            } else {
570
                int index = theFormSet.getCurrentIndex();
571
                DynObject currentElement = theFormSet.get(index);
572
                theFormSet.getFormValues(currentElement);
573
                features.update(((FacadeOfAFeature) currentElement).getEditableFeature());
574
                this.formset.message(i18n.getTranslation("_Record_saved"));
575
                try {
576
                    this.formset.setCurrentIndex(index);
577
                } catch (Exception ex) {
578
                    LOGGER.warn("Can't reload form data after insert.", ex);
579
                }
580
            }
581
        } catch (Exception ex) {
582
            theFormSet.message(i18n.getTranslation("error_saving_data_will_not_save"));
583
            throw new RuntimeException("Can't save values", ex);
584

    
585
        } finally {
586
            updateButtonEnabledStatus();
587
        }
588

    
589
    }
590

    
591
    private void deleteCurrentElement(JDynFormSet theFormSet) {
592
        I18nManager i18n = ToolsLocator.getI18nManager();
593
        try {
594
            int index = theFormSet.getCurrentIndex();
595
            DynObject currentElement = theFormSet.get(index);
596
            theFormSet.getFormValues(currentElement);
597
            Feature feature = ((FacadeOfAFeature) currentElement).getFeature();
598
            if (feature instanceof EditableFeature) {
599
                feature = ((EditableFeature) feature).getNotEditableCopy();
600
            }
601
            features.delete(feature);
602

    
603
            this.formset.message(i18n.getTranslation("_Record_removed"));
604

    
605
            this.formset.setValues(features.asListOfDynObjects());
606
            if (features.getTotalSize() - 1 < index) {
607
                index = index - 1;
608
            }
609
            this.formset.setCurrentIndex(index);
610

    
611
        } catch (Exception ex) {
612
            theFormSet.message(i18n.getTranslation("error_removing_data_will_not_remove"));
613
            throw new RuntimeException("Can't remove values", ex);
614

    
615
        } finally {
616
            updateButtonEnabledStatus();
617
        }
618

    
619
    }
620

    
621
    @Override
622
    public void saveChanges() {
623
        if (this.formset != null && this.formset.countValues() > 0) {
624
            if (store != null && !store.isEditing()) {
625
                try {
626
                    store.edit();
627
                } catch (DataException e1) {
628
                    LOGGER.warn("Can't edit the store " + store.getName());
629
                    throw new RuntimeException("Can't save changes.", e1);
630
                }
631
            }
632
            this.saveChanges(this.formset);
633
        }
634
    }
635

    
636
    private void updateButtonEnabledStatus() {
637
        if (this.formset == null) {
638
            return;
639
        }
640
        if (this.store == null || store.isBroken() || store.isAppending() || this.features == null) {
641
            this.formset.setReadOnly(true);
642
            formset.setActionVisible(STARTEDITING_ACTION, true);
643
            formset.setActionEnabled(STARTEDITING_ACTION, true);
644
            formset.setActionVisible(FINISHEDITING_ACTION, false);
645
            formset.setActionEnabled(FINISHEDITING_ACTION, false);
646
            formset.setActionEnabled(ACTION_DELETE, false);
647
            formset.setActionEnabled(ACTION_NEW, false);
648
            formset.setActionEnabled(ACTION_CANCEL_NEW, false);
649
            formset.setActionEnabled(ACTION_SAVE, false);
650
            formset.setActionEnabled(ACTION_SEARCH, false);
651
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
652
            formset.setActionEnabled(ACTION_NAVIGATION, false);
653
            return;
654
        }
655
//        setEnabledUniqueFields(false);
656
        if (store.isEditing()) {
657
            this.formset.setReadOnly(false);
658
            formset.setActionVisible(STARTEDITING_ACTION, false);
659
            formset.setActionEnabled(STARTEDITING_ACTION, false);
660
            formset.setActionVisible(FINISHEDITING_ACTION, true);
661
            formset.setActionEnabled(FINISHEDITING_ACTION, true);
662
            if (formset.isInNewState()) {
663
                formset.setActionEnabled(ACTION_DELETE, false);
664
                formset.setActionEnabled(ACTION_SEARCH, false);
665
                formset.setActionEnabled(ACTION_NEW, false);
666
                formset.setActionEnabled(ACTION_CANCEL_NEW, true);
667
                formset.setActionEnabled(ACTION_SAVE, true);
668
                formset.setActionEnabled(FINISHEDITING_ACTION, false);
669
                formset.setActionEnabled(REFRESHFORM_ACTION, false);
670
//                setEnabledUniqueFields(true);
671

    
672
            } else if (this.features != null && this.features.isEmpty()) {
673
                formset.getForm().setReadOnly(true);
674
                formset.setActionEnabled(ACTION_DELETE, false);
675
                formset.setActionEnabled(ACTION_SEARCH, false);
676
                formset.setActionEnabled(ACTION_NEW, true);
677
                formset.setActionEnabled(ACTION_CANCEL_NEW, true);
678
                formset.setActionEnabled(ACTION_SAVE, false);
679
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
680
                formset.setActionEnabled(FINISHEDITING_ACTION, true);         
681
                formset.setActionEnabled(ACTION_NAVIGATION, false);
682

    
683
            } else if (formset.getForm().isModified()) {
684
                formset.setActionEnabled(ACTION_DELETE, false);
685
                formset.setActionEnabled(ACTION_SEARCH, false);
686
                formset.setActionEnabled(ACTION_NEW, false);
687
                formset.setActionEnabled(ACTION_CANCEL_NEW, false);
688
                formset.setActionEnabled(ACTION_SAVE, true);
689
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
690
                formset.setActionEnabled(FINISHEDITING_ACTION, false);
691
                formset.setActionEnabled(ACTION_NAVIGATION, false);
692

    
693
            } else {
694
                formset.setActionEnabled(ACTION_DELETE, true);
695
                formset.setActionEnabled(ACTION_SEARCH, true);
696
                formset.setActionEnabled(ACTION_NEW, true);
697
                formset.setActionEnabled(ACTION_CANCEL_NEW, false);
698
                formset.setActionEnabled(ACTION_SAVE, false);
699
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
700
                formset.setActionEnabled(FINISHEDITING_ACTION, true);
701
                formset.setActionEnabled(ACTION_NAVIGATION, true);
702
            }
703

    
704
            return;
705
        }
706
        this.formset.setReadOnly(true);
707
        formset.setActionVisible(STARTEDITING_ACTION, true);
708
        formset.setActionEnabled(STARTEDITING_ACTION, true);
709
        formset.setActionVisible(FINISHEDITING_ACTION, false);
710
        formset.setActionEnabled(FINISHEDITING_ACTION, false);
711
        formset.setActionEnabled(ACTION_DELETE, false);
712
        formset.setActionEnabled(ACTION_NEW, false);
713
        formset.setActionEnabled(ACTION_CANCEL_NEW, false);
714
        formset.setActionEnabled(ACTION_SAVE, false);
715
        formset.setActionEnabled(ACTION_SEARCH, true);
716
        formset.setActionEnabled(REFRESHFORM_ACTION, true);
717
    }
718

    
719
    private void clearUniqueFields() {
720
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
721
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
722
                JDynFormField field = formset.getForm().getField(attr.getName());
723
                if (field != null) {
724
                    field.clear();
725
                }
726
            }
727
        }
728
    }
729

    
730
    private void setEnabledUniqueFields(boolean enabled) {
731
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
732
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
733
                JDynFormField field = formset.getForm().getField(attr.getName());
734
                if (field != null) {
735
                    field.setReadOnly(!enabled);
736
                }
737
            }
738
        }
739
    }
740

    
741
    @Override
742
    public long getDataSetSize() {
743
        if (this.features != null) {
744
            return features.getTotalSize();
745
        }
746
        return 0;
747
    }
748

    
749
    @Override
750
    public FeatureStore getFeatureStore() {
751
        return this.store;
752
    }
753

    
754
    private class FormSetListener implements JDynFormSetListener {
755

    
756
        @Override
757
        public void formMessage(String message) {
758
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMessage"));
759
        }
760

    
761
        @Override
762
        public void formClose() {
763
            panel.setVisible(false);
764
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formClose"));
765
        }
766

    
767
        @Override
768
        public void formMovedTo(int currentPosition) throws AbortActionException {
769
            LOGGER.trace("formMovedTo " + currentPosition);
770
            updateButtonEnabledStatus();
771
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMovedTo"));
772
        }
773

    
774
        @Override
775
        public void formBeforeSave(JDynFormSet dynformSet) throws AbortActionException {
776
            LOGGER.trace("formBeforeSave");
777
            saveChanges(dynformSet);
778
            updateButtonEnabledStatus();
779
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSave"));
780
        }
781

    
782
        @Override
783
        public void formBeforeNew(JDynFormSet dynformSet) throws AbortActionException {
784
            LOGGER.trace("formBeforeNew");
785
            clearUniqueFields();
786
            updateButtonEnabledStatus();
787
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeNew"));
788
        }
789

    
790
        @Override
791
        public void formBeforeDelete(JDynFormSet dynformSet) throws AbortActionException {
792
            LOGGER.trace("formBeforeDelete");
793
            updateButtonEnabledStatus();
794
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeDelete"));
795
        }
796

    
797
        @Override
798
        public void formAfterSave(JDynFormSet dynformSet) throws AbortActionException {
799
            LOGGER.trace("formAfterSave");
800
            updateButtonEnabledStatus();
801
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSave"));
802
        }
803

    
804
        @Override
805
        public void formAfterNew(JDynFormSet dynformSet) throws AbortActionException {
806
            LOGGER.trace("formAfterNew");
807
            updateButtonEnabledStatus();
808
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterNew"));
809
        }
810

    
811
        @Override
812
        public void formAfterDelete(JDynFormSet dynformSet) throws AbortActionException {
813
            LOGGER.trace("formAfterDelete");
814
            deleteCurrentElement(dynformSet);
815
            updateButtonEnabledStatus();
816
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterDelete"));
817
        }
818

    
819
//        @Override
820
//        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
821
//            LOGGER.trace("formBeforeSearch");
822
//            DataSwingManager dataSwingmanager = DALSwingLocator.getSwingManager();
823
//            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
824
//
825
//            JExpressionBuilder builder = dataSwingmanager.createQueryFilterExpresion(store);
826
//            FeatureQuery currentQuery = getCurrentQuery();
827
//            if( currentQuery!=null ) {
828
//                Evaluator filter = currentQuery.getFilter();
829
//                if( filter instanceof ExpressionEvaluator ) {
830
//                    Expression expression = ((ExpressionEvaluator)filter).getExpression();
831
//                    builder.setExpression(expression);
832
//                }
833
//            }
834
//            Dialog dialog = winmgr.createDialog(
835
//                    builder.asJComponent(),
836
//                    "Filtro",
837
//                    "Creacion de filtro sobre '"+store.getName()+"'",
838
//                    WindowManager_v2.BUTTONS_OK_CANCEL
839
//            );
840
//            dialog.show(WindowManager.MODE.DIALOG);
841
//            if( dialog.getAction() == WindowManager_v2.BUTTON_OK ) {
842
//                Expression expresion = builder.getExpression();
843
//                try {
844
//                    FeatureQuery query = store.createFeatureQuery();
845
//                    if( ExpressionUtils.isPhraseEmpty(expresion) ) {
846
//                        query.clearFilter();
847
//                    } else {
848
//                        query.setFilter(expresion);
849
//                    }
850
//                    setQuery(query);
851
//                } catch (Exception ex) {
852
//                    LOGGER.warn("Can't apply filter '" + expresion + "'.", ex);
853
//                }
854
//            }
855
//        }
856
        @Override
857
        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
858
            LOGGER.trace("formBeforeSearch");
859
            DataSwingManager dataSwingmanager = DALSwingLocator.getSwingManager();
860
            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
861

    
862
            final FeatureStoreSearchPanel searchPanel = dataSwingmanager.createFeatureStoreSearchPanel(store);
863
            searchPanel.setShowActions(false);
864
            FeatureQuery currentQuery = getCurrentQuery();
865
            if (currentQuery != null) {
866
                Evaluator filter = currentQuery.getFilter();
867
                if (filter instanceof ExpressionEvaluator) {
868
                    Expression expression = ((ExpressionEvaluator) filter).toExpression();
869
                    searchPanel.setFilter(expression);
870
                    searchPanel.search();
871
                }
872
            }
873
            searchPanel.asJComponent().setPreferredSize(
874
                    new Dimension(FeatureStoreSearchPanel.DEFAULT_WIDTH, 320)
875
            );
876
            I18nManager i18n = ToolsLocator.getI18nManager();
877
            Dialog dialog = winmgr.createDialog(
878
                    searchPanel.asJComponent(),
879
                    i18n.getTranslation("_Filter"),
880
                    i18n.getTranslation("_Creating_filter_for") + ": '" + store.getName() + "'",
881
                    WindowManager_v2.BUTTONS_OK_CANCEL
882
            );
883
            dialog.show(WindowManager.MODE.DIALOG);
884
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
885
                SearchParameters params = searchPanel.fetch(null);
886
                if (params.getQuery() != null) {
887
                    FeatureQuery searchQuery = params.getQuery().getCopy();
888

    
889
                    Expression expresion = null;
890
                    if (searchQuery != null) {
891
                        expresion = searchQuery.getExpressionFilter();
892
                    }
893
                    try {
894
                        FeatureQuery query = store.createFeatureQuery();
895
                        if (ExpressionUtils.isPhraseEmpty(expresion)) {
896
                            query.clearFilter();
897
                        } else {
898
                            query.setFilter(expresion);
899
                        }
900
                        setQuery(query);
901
                    } catch (Exception ex) {
902
                        LOGGER.warn("Can't apply filter '" + expresion + "'.", ex);
903
                    }
904
                } else {
905
                    LOGGER.warn("FeatureQuery from parameters is null. Query is not applied to the JFeaturesFrom");
906
                }
907
            }
908
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSearch"));
909
        }
910

    
911
        @Override
912
        public void formAfterSearch(JDynFormSet dynformSet) throws AbortActionException {
913
            LOGGER.trace("formAfterSearch");
914
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSearch"));
915
        }
916

    
917
        @Override
918
        public void formBeforeCancelNew(JDynFormSet dynformSet) throws AbortActionException {
919
            LOGGER.trace("formBeforeCancelNew");
920
            updateButtonEnabledStatus();
921
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeCancelNew"));
922
        }
923

    
924
        @Override
925
        public void formAfterCancelNew(JDynFormSet dynformSet) throws AbortActionException {
926
            LOGGER.trace("formAfterCancelNew");
927
            updateButtonEnabledStatus();
928
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterCancelNew"));
929
        }
930
    }
931

    
932
//    private static class StoreEditException extends AbortActionException {
933
//
934
//        /**
935
//         *
936
//         */
937
//        private static final long serialVersionUID = -7682017811778577130L;
938
//
939
//        public StoreEditException(Throwable cause, String storename) {
940
//            super("Can't edit the store '%(storename)'", cause, "cant_edit_the store_XstorenameX", serialVersionUID);
941
//            setValue("storename", storename);
942
//        }
943
//    }
944
    @Override
945
    public void addActionListener(ActionListener listener) {
946
        this.actionListeners.addActionListener(listener);
947
    }
948

    
949
    @Override
950
    public ActionListener[] getActionListeners() {
951
        return this.actionListeners.getActionListeners();
952
    }
953

    
954
    @Override
955
    public void removeActionListener(ActionListener listener) {
956
        this.actionListeners.removeActionListener(listener);
957
    }
958

    
959
    @Override
960
    public void removeAllActionListener() {
961
        this.actionListeners.removeAllActionListener();
962
    }
963

    
964
    @Override
965
    public void fireActionEvent(ActionEvent event) {
966
        this.actionListeners.fireActionEvent(event);
967
    }
968

    
969
    @Override
970
    public boolean hasActionListeners() {
971
        return this.actionListeners.hasActionListeners();
972
    }
973

    
974
}