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

History | View | Annotate | Download (50.2 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.Toolkit;
28
import java.awt.event.ActionEvent;
29
import java.awt.event.ActionListener;
30
import java.awt.event.ComponentAdapter;
31
import java.awt.event.ComponentEvent;
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.EditingNotification;
53
import static org.gvsig.fmap.dal.EditingNotification.AFTER_REMOVE_FEATURE;
54
import static org.gvsig.fmap.dal.EditingNotification.AFTER_UPDATE_FEATURE;
55
import static org.gvsig.fmap.dal.EditingNotification.AFTER_INSERT_FEATURE;
56
import static org.gvsig.fmap.dal.EditingNotification.AFTER_ENTER_EDITING_STORE;
57
import static org.gvsig.fmap.dal.EditingNotification.AFTER_EXIT_EDITING_STORE;
58
import static org.gvsig.fmap.dal.EditingNotification.BEFORE_REMOVE_FEATURE;
59
import static org.gvsig.fmap.dal.EditingNotification.BEFORE_UPDATE_FEATURE;
60
import static org.gvsig.fmap.dal.EditingNotification.BEFORE_INSERT_FEATURE;
61
import static org.gvsig.fmap.dal.EditingNotification.BEFORE_ENTER_EDITING_STORE;
62
import static org.gvsig.fmap.dal.EditingNotification.BEFORE_EXIT_EDITING_STORE;
63
import org.gvsig.fmap.dal.EditingNotificationManager;
64
import org.gvsig.fmap.dal.exception.DataException;
65
import org.gvsig.fmap.dal.feature.EditableFeature;
66
import org.gvsig.fmap.dal.feature.FacadeOfAFeature;
67
import org.gvsig.fmap.dal.feature.Feature;
68
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
69
import org.gvsig.fmap.dal.feature.FeatureQuery;
70
import org.gvsig.fmap.dal.feature.FeatureSelection;
71
import org.gvsig.fmap.dal.feature.FeatureStore;
72
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
73
import org.gvsig.fmap.dal.feature.FeatureType;
74
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
75
import org.gvsig.fmap.dal.swing.AbstractDALActionFactory.AbstractDALActionContext;
76
import org.gvsig.fmap.dal.swing.DALActionFactory;
77
import org.gvsig.fmap.dal.swing.DALSwingLocator;
78
import org.gvsig.fmap.dal.swing.DataSwingManager;
79
import org.gvsig.fmap.dal.swing.impl.DefaultDataSwingManager;
80
import org.gvsig.fmap.dal.swing.impl.actions.ShowFormAction.ShowFormActionFactory;
81
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
82
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
83
import org.gvsig.tools.ToolsLocator;
84
import org.gvsig.tools.dispose.Disposable;
85
import org.gvsig.tools.dispose.DisposeUtils;
86
import org.gvsig.tools.dynform.AbortActionException;
87
import org.gvsig.tools.dynform.DynFormDefinition;
88
import org.gvsig.tools.dynform.DynFormLocator;
89
import org.gvsig.tools.dynform.DynFormManager;
90
import org.gvsig.tools.dynform.JDynForm;
91
import org.gvsig.tools.dynform.JDynFormField;
92
import org.gvsig.tools.dynform.JDynFormSet;
93
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_CANCEL_NEW;
94
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_DELETE;
95
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NAVIGATION;
96
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NEW;
97
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SAVE;
98
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SEARCH;
99
import org.gvsig.tools.dynform.JDynFormSet.JDynFormSetListener;
100
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
101
import org.gvsig.tools.dynobject.DynClass;
102
import org.gvsig.tools.dynobject.DynObject;
103
import org.gvsig.tools.evaluator.Evaluator;
104
import org.gvsig.tools.exception.BaseException;
105
import org.gvsig.tools.i18n.I18nManager;
106
import org.gvsig.tools.observer.Observable;
107
import org.gvsig.tools.observer.Observer;
108
import org.gvsig.tools.swing.api.ActionListenerSupport;
109
import org.gvsig.tools.swing.api.ToolsSwingLocator;
110
import org.gvsig.tools.swing.api.ToolsSwingUtils;
111
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
112
import org.gvsig.tools.swing.api.windowmanager.Dialog;
113
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
114
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
115
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
116
import org.gvsig.tools.swing.icontheme.IconTheme;
117
import org.gvsig.tools.util.PropertiesSupport;
118
import org.gvsig.tools.util.PropertiesSupportHelper;
119
import org.slf4j.Logger;
120
import org.slf4j.LoggerFactory;
121

    
122
/**
123
 * @author fdiaz
124
 *
125
 */
126
@SuppressWarnings("UseSpecificCatch")
127
public class DefaultJFeaturesForm implements JFeaturesForm, Disposable {
128

    
129
    private class JFeaturesFormPanel extends JPanel implements PropertiesSupport {
130

    
131
        private final PropertiesSupport properties;
132
        
133
        private JFeaturesFormPanel(PropertiesSupport properties, BorderLayout layout) {
134
            super(layout);
135
            this.properties = properties;
136
        }
137

    
138
        @Override
139
        public Object getProperty(String name) {
140
            return this.properties.getProperty(name);
141
        }
142

    
143
        @Override
144
        public void setProperty(String name, Object value) {
145
            this.properties.setProperty(name, value);
146
        }
147

    
148
        @Override
149
        public Map<String, Object> getProperties() {
150
            return this.properties.getProperties();
151
        }
152
        
153
    }
154
    
155
    private class FormActionContext extends AbstractDALActionContext {
156

    
157
        public FormActionContext() {
158
            super(ACTION_CONTEXT_NAME);
159
        }
160

    
161
        @Override
162
        public DataStore getStore() {
163
            return store;
164
        }
165

    
166
        @Override
167
        public FeatureQuery getQuery() {
168
            return currentQuery;
169
        }
170

    
171
        @Override
172
        public int getSelectedsCount() {
173
            return 0;
174
        }
175

    
176
        @Override
177
        public Expression getFilterForSelecteds() {
178
            return null;
179
        }
180

    
181
        @Override
182
        public FeatureSelection getSelecteds() {
183
            try {
184
                FeatureSelection selection = getFeatureStore().createFeatureSelection();
185
                selection.select(getCurrentFeature());
186
                return selection;
187
            } catch (DataException ex) {
188
                return null;
189
            }
190
        }
191

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

    
200
    }
201

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

    
204
    private static final int PAGE_SIZE = 10;
205
    private JFeaturesFormPanel panel;
206
    private JDynFormSet formset;
207
    private FeatureStore store;
208
    private boolean needrefresh;
209
    private FeaturePagingHelper features;
210
    private DynFormDefinition definition = null;
211
    private FeatureQuery currentQuery;
212
    private List<Action> otherActions;
213
    private final ActionListenerSupport actionListeners;
214
    private final PropertiesSupportHelper propertiesHelper;
215
    private boolean terminateEditingOnClose = true;
216
    private boolean ignoreTerminateEditingOnClose = false;
217

    
218
    @SuppressWarnings("LeakingThisInConstructor")
219
    public DefaultJFeaturesForm() {
220
        this.otherActions = new ArrayList<>();
221
        this.propertiesHelper = new PropertiesSupportHelper();
222
        this.propertiesHelper.setProperty("FeaturesForm", this);
223
        this.panel = new JFeaturesFormPanel(this.propertiesHelper, new BorderLayout());
224
        this.panel.addComponentListener(new ComponentAdapter() {
225
            @Override
226
            public void componentHidden(ComponentEvent e) {
227
                onClose();
228
                dispose();
229
            }
230
        });
231
        this.actionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
232
    }
233

    
234
    public static void selfRegister() {
235

    
236
    }
237

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

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

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

    
274
    @Override
275
    public void bind(FeatureStore store) {
276
        this.bind(store, null, null);
277
    }
278

    
279
    public void bind(FeatureStore store, DynClass definition) {
280
        this.bind(store, definition, null);
281
    }
282

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

    
317
    @Override
318
    public void dispose() {
319
        if( this.formset!=null ) {
320
            Action action = this.formset.getAction(FINISHEDITING_ACTION);
321
            if( action!=null ) {
322
                DisposeUtils.disposeQuietly(action);
323
            }
324
            action = this.formset.getAction(STARTEDITING_ACTION);
325
            if( action!=null ) {
326
                DisposeUtils.disposeQuietly(action);
327
            }
328
        }
329
        if( this.panel!=null ) {
330
            this.panel.setVisible(false);
331
        }
332
        DisposeUtils.disposeQuietly(store);
333
        this.store = null;
334
        this.panel = null;
335
        this.formset = null;
336
        this.features = null;
337
        this.definition = null;
338
        this.currentQuery = null;
339
        this.otherActions = null;
340
    }
341

    
342
    public static class MyFeaturesFormContext extends DefaultFeaturesFormContext {
343

    
344
        private final DefaultJFeaturesForm featuresForm;
345
        
346
        public MyFeaturesFormContext(DefaultJFeaturesForm featuresForm) {
347
            super(featuresForm.store);
348
            this.featuresForm = featuresForm;
349
        }
350
        
351
        @Override
352
        public JFeaturesForm getFeaturesForm() {
353
            return this.featuresForm;
354
        }
355
        @Override
356
        public Feature getCurrentFeature() {    
357
            return this.featuresForm.getCurrentFeature();
358
        }
359
    }
360
    
361
    @Override
362
    public JDynFormSet getFormset() {
363
        if (this.formset == null) {
364
            DynFormManager formManager = DynFormLocator.getDynFormManager();
365
            this.formset = formManager.createJDynFormSet(
366
                    new MyFeaturesFormContext(this),
367
                    this.definition,
368
                    null
369
            );
370
            if(!this.definition.getTags().has(DynFormSPIManager.TAG_DYNFORM_LAYOUTMODE)){
371
                this.formset.setLayoutMode(JDynForm.USE_TABS);
372
            }
373
            
374
            List<String> groups = this.definition.getGroups();
375
            if ((this.formset.getLayoutMode() == JDynForm.USE_TABS || this.formset.getLayoutMode() == JDynForm.USE_SEPARATORS) && groups.size() == 1 && groups.get(0) == null) {
376
                this.formset.setLayoutMode(JDynForm.USE_PLAIN);
377
            }
378
            
379
            JComponent component = this.formset.getActionButton(JDynFormSet.ACTION_SET_CURRENT_RECORD);
380
            if( component!=null ) {
381
                I18nManager i18n = ToolsLocator.getI18nManager();
382
                component.setToolTipText(
383
                    "<html>" +
384
                    i18n.getTranslation("_Table") + ": " + this.store.getName() +"<br>\n"+
385
                    "( "+this.store.getFullName() + " )" +
386
                    "</html>"
387
                );
388
            }
389
            
390
            this.formset.setAllowNew(true);
391
            this.formset.setAllowDelete(true);
392
            this.formset.setAllowUpdate(true);
393
            this.formset.setAllowClose(true);
394
            this.formset.setAllowSearch(true);
395
            this.formset.setAutosave(true);
396

    
397
            this.formset.addAction(new StartEditingAction());
398
            this.formset.addAction(new FinishEditingAction());
399
            this.formset.addAction(new RefreshAction());
400

    
401
            FormActionContext actionContext = new FormActionContext();
402
            actionContext.set("featuresform", this);
403
            try {
404
                Collection<DALActionFactory> factories = DALSwingLocator.getSwingManager().getApplicableStoreActions(actionContext);
405
                for (DALActionFactory factory : factories) {
406
                    if (StringUtils.equalsIgnoreCase(factory.getName(), ShowFormActionFactory.ACTION_NAME)) {
407
                        continue;
408
                    }
409
                    try {
410
                        Action action = factory.createAction(actionContext);
411
                        this.formset.addAction(action);
412
                    } catch (Exception ex) {
413
                        LOGGER.warn("Can't add action " + factory.getName(), ex);
414
                    }
415

    
416
                }
417
            } catch (Exception ex) {
418
                LOGGER.warn("Can't add actions", ex);
419
            }
420
            for (Action action : this.otherActions) {
421
                this.formset.addAction(action);
422
            }
423

    
424
            this.formset.addListener(new FormSetListener());
425
            this.formset.getForm().addListener(new JDynForm.JDynFormListener() {
426
                @Override
427
                public void message(String string) {
428
                }
429

    
430
                @Override
431
                public void fieldChanged(JDynFormField jdff) {
432
                    updateButtonEnabledStatus();
433
                }
434
            });
435

    
436
            ToolsSwingLocator.getToolsSwingManager().removeBorder(this.formset.asJComponent());
437
            this.panel.add(this.formset.asJComponent(), BorderLayout.CENTER);
438
            this.panel.revalidate();
439
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
440
            ToolsSwingUtils.ensureHeightWitdh(this.panel, 256, 400, screenSize.height-100, screenSize.width-60);
441
        }
442
        updateButtonEnabledStatus();
443
        return this.formset;
444
    }
445

    
446
    @Override
447
    public void addAction(Action action) {
448
        this.otherActions.add(action);
449
        if (this.formset != null) {
450
            this.formset.addAction(action);
451
        }
452
    }
453

    
454
    @Override
455
    public long getCurrentIndex() {
456
        if (this.formset == null) {
457
            return -1;
458
        }
459
        return this.formset.getCurrentIndex();
460
    }
461

    
462
    @Override
463
    public Feature get(long index) {
464
        if (this.formset == null || this.features == null) {
465
            return null;
466
        }
467
        try {
468
            return this.features.getFeatureAt(index);
469
        } catch (BaseException ex) {
470
            return null;
471
        }
472
    }
473

    
474
    private class RefreshAction extends AbstractAction {
475

    
476
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
477
        public RefreshAction() {
478
            I18nManager i18nManager = ToolsLocator.getI18nManager();
479
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
480

    
481
            this.putValue(NAME, null);
482
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Reload_data"));
483
            this.putValue(SMALL_ICON, iconTheme.get("common-form-refresh"));
484
            this.putValue(ACTION_COMMAND_KEY, REFRESHFORM_ACTION);
485
            this.setEnabled(!formset.isInNewState());
486
        }
487

    
488
        @Override
489
        public void actionPerformed(ActionEvent ae) {
490
            try {
491
                I18nManager i18n = ToolsLocator.getI18nManager();
492
                formset.message(i18n.getTranslation("_Form_reloaded"));
493
                int x=formset.getCurrentIndex();
494
                updateForm();
495
                formset.setCurrentIndex(x);
496
            } catch (Exception ex) {
497
                LOGGER.warn("Can't reload form", ex);
498
            }
499
        }
500
    }
501

    
502
    private class FinishEditingAction extends AbstractAction implements Observer, Disposable {
503

    
504
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
505
        public FinishEditingAction() {
506
            I18nManager i18nManager = ToolsLocator.getI18nManager();
507
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
508

    
509
            this.putValue(NAME, null);
510
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Stop_editing"));
511
            this.putValue(SMALL_ICON, iconTheme.get("table-stop-editing"));
512
            this.putValue(ACTION_COMMAND_KEY, FINISHEDITING_ACTION);
513

    
514
            this.setEnabled(store.isEditing());
515
            store.addObserver(this);
516
        }
517

    
518
        @Override
519
        public void actionPerformed(ActionEvent ae) {
520
            if (store == null || formset == null) {
521
                return;
522
            }
523
            if (store.isEditing()) {
524
                EditingNotificationManager editingManager = DALSwingLocator.getEditingNotificationManager();
525
                DataSwingManager dataSwingManager = DALSwingLocator.getDataSwingManager();
526
                ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
527
                I18nManager i18nManager = ToolsLocator.getI18nManager();
528
                try {
529
                    int x = dataSwingManager.askUserStopEditing(formset.asJComponent(), store, true);
530
                    switch (x) {
531
                        case DataSwingManager.STOP_EDITING_SAVE:
532
                            EditingNotification notification = editingManager.notifyObservers(this, BEFORE_EXIT_EDITING_STORE, null, store);
533
                            if( notification.isCanceled()) {
534
                                I18nManager i18n = ToolsLocator.getI18nManager();
535
                                formset.message(i18n.getTranslation("Finish editing has been cancelled."));
536
                                return;
537
                            }                
538
                            store.finishEditing();
539
                            editingManager.notifyObservers(this, AFTER_EXIT_EDITING_STORE, null, store);
540
                            break;
541
                        case DataSwingManager.STOP_EDITING_CONTINUE:
542
                            break;
543
                        case DataSwingManager.STOP_EDITING_DISCARD:
544
                            store.cancelEditing();
545
                            int index = formset.getCurrentIndex();
546
                            try {
547
                                formset.setCurrentIndex(index);
548
                            } catch (Exception ex) {
549
                                LOGGER.warn("Can't reload form data after edit.", ex);
550
                            }
551
                            break;
552
                        case DataSwingManager.STOP_EDITING_EXPORT:
553
                            if( !((DefaultDataSwingManager)dataSwingManager).exportStore(store, MODE.DIALOG) ) {
554
                                // Mensaje de operacion no soportada
555
                            }
556
                    }
557
                } catch (Exception ex) {
558
                    LOGGER.warn("Can't finish editing in FeatureForm (" + store.getName() + ").", ex);
559
                    dialogManager.messageDialog(
560
                            i18nManager.getTranslation("_Problems_finish_table_editing") + "\n\n"
561
                            + i18nManager.getTranslation("_see_error_log_for_more_information"),
562
                            i18nManager.getTranslation("_Stop_editing"),
563
                            JOptionPane.ERROR_MESSAGE
564
                    );
565
                }
566
            }
567
            updateButtonEnabledStatus();
568
        }
569

    
570
        @Override
571
        public void update(Observable observable, Object notification) {
572
            if (store == null || formset == null) {
573
                return;
574
            }
575
            if (notification instanceof FeatureStoreNotification) {
576
                FeatureStoreNotification n = (FeatureStoreNotification) notification;
577
                switch (n.getType()) {
578
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
579
                        needrefresh = true;
580
                    case FeatureStoreNotification.AFTER_STARTEDITING:
581
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
582
                        updateButtonEnabledStatus();
583
                        break;
584
                }
585
            }
586
        }
587

    
588
        @Override
589
        public void dispose() {
590
            store.deleteObserver(this);
591
        }
592

    
593
    }
594

    
595
    private class StartEditingAction extends AbstractAction implements Observer, Disposable {
596

    
597
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
598
        public StartEditingAction() {
599
            I18nManager i18nManager = ToolsLocator.getI18nManager();
600
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
601

    
602
            this.putValue(NAME, null);
603
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Start_editing"));
604
            this.putValue(SMALL_ICON, iconTheme.get("table-start-editing"));
605
            this.putValue(ACTION_COMMAND_KEY, STARTEDITING_ACTION);
606

    
607
            this.setEnabled(!store.isEditing());
608
            store.addObserver(this);
609
        }
610

    
611
        @Override
612
        public void actionPerformed(ActionEvent ae) {
613
            if (store == null || formset == null) {
614
                return;
615
            }
616
            if (!store.isEditing()) {
617
                try {
618
                    EditingNotificationManager editingManager = DALSwingLocator.getEditingNotificationManager();
619
                    EditingNotification notification = editingManager.notifyObservers(this, BEFORE_ENTER_EDITING_STORE, null, store);
620
                    if( notification.isCanceled() ) {
621
                        I18nManager i18n = ToolsLocator.getI18nManager();
622
                        formset.message(i18n.getTranslation("Enter editing has been cancelled."));
623
                        return;
624
                    }                
625
                    store.edit();
626
                    editingManager.notifyObservers(this, AFTER_ENTER_EDITING_STORE, null, store);
627
                } catch (DataException ex) {
628
                    LOGGER.warn("Can't finish editing in FeatureForm (" + store.getName() + ").", ex);
629
                }
630
            }
631
            updateButtonEnabledStatus();
632
        }
633

    
634
        @Override
635
        public void update(Observable observable, Object notification) {
636
            if (store == null || formset == null) {
637
                return;
638
            }
639
            if (notification instanceof FeatureStoreNotification) {
640
                FeatureStoreNotification n = (FeatureStoreNotification) notification;
641
                switch (n.getType()) {
642
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
643
                        needrefresh = true;
644
                    case FeatureStoreNotification.AFTER_STARTEDITING:
645
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
646
                        updateButtonEnabledStatus();
647
                        break;
648
                }
649
            }
650
        }
651

    
652
        @Override
653
        public void dispose() {
654
            store.deleteObserver(this);
655
        }
656

    
657
    }
658

    
659
    @Override
660
    public void setQuery(FeatureQuery query) {
661
        if (this.features != null) {
662
            if (this.formset != null && !formset.isReadOnly() && this.formset.isAutosave() && this.formset.countValues() > 0) {
663
                if(this.formset.getForm().isModified()){
664
                    if (!store.isEditing()) {
665
                        try {
666
                            store.edit();
667
                        } catch (DataException e1) {
668
                            throw new RuntimeException("Can't set query", e1);
669
                        }
670
                    }
671
                    saveChanges(this.formset);
672
                }
673
            }
674
        }
675
        this.currentQuery = query;
676
        updateForm();
677
    }
678

    
679
    private FeatureQuery getCurrentQuery() {
680
        return this.currentQuery;
681
    }
682

    
683
    @Override
684
    public void showForm(MODE mode) {
685
        I18nManager i18n = ToolsLocator.getI18nManager();
686
        String title = i18n.getTranslation("_Form") + ": "+ this.definition.getLabel();
687
        showForm(title, mode);
688
    }
689

    
690
    @Override
691
    public void showForm(String title, MODE mode) {
692
        WindowManager winmgr = ToolsSwingLocator.getWindowManager();
693
        if( StringUtils.isBlank(title) ) {
694
            title = this.definition.getLabel();
695
        }
696
        winmgr.showWindow(this.asJComponent(), title, mode);
697
    }
698
    
699
    @Override
700
    public void hideForm() {
701
        DisposeUtils.dispose(this);
702
    }
703

    
704
    private void saveChanges(JDynFormSet theFormSet) {
705
        I18nManager i18n = ToolsLocator.getI18nManager();
706
        try {
707
            EditingNotificationManager editingManager = DALSwingLocator.getEditingNotificationManager();
708
            if (theFormSet.isInNewState()) {
709
                EditableFeature newFeature = store.createNewFeature(false);
710
                JDynForm form = formset.getForm();
711
                for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
712
                    String name = attr.getName();
713
                    if( !newFeature.canSetValue(name) ) {
714
                        continue;
715
                    }
716
                    JDynFormField field = form.getField(name);
717
                    if( field==null ) {
718
                        // The attribute is not in form, set default value
719
                        newFeature.set(name, attr.getDefaultValueCoerced());
720
                    } else {
721
                        try {
722
                            Object value = field.getValue();
723
                            newFeature.set(name, value);
724
                        } catch (Exception ex) {
725
                            LOGGER.warn("Can't get value of field '" + name + "'.", ex);
726
                        }
727
                    }
728
                }
729
                EditingNotification notification = editingManager.notifyObservers(this, BEFORE_INSERT_FEATURE, null, this.store, newFeature);
730
                if( notification.isCanceled() ) {
731
                    theFormSet.message(i18n.getTranslation("Data saving has been cancelled."));
732
                    return;
733
                }                
734
                if (!editingManager.canWriteFeature(newFeature)) {
735
                    theFormSet.message(i18n.getTranslation("The data cannot be saved. Check that all the required fields are filled out.."));
736
                    return;
737
                }
738
                features.insert(newFeature);
739
                editingManager.notifyObservers(this, AFTER_INSERT_FEATURE, null, this.store, newFeature);
740
                
741
                this.formset.message(i18n.getTranslation("_Record_saved"));
742
                try {
743
                    this.formset.setValues(features.asListOfDynObjects());
744
                    this.formset.setCurrentIndex((int) (features.getTotalSize()) - 1);
745
                } catch (Exception ex) {
746
                    LOGGER.warn("Can't reload form data after insert.", ex);
747
                }
748
            } else {
749
                int index = theFormSet.getCurrentIndex();
750
                DynObject currentElement = theFormSet.get(index);
751
                theFormSet.getFormValues(currentElement);
752

    
753
                EditableFeature feature = ((FacadeOfAFeature) currentElement).getEditableFeature();
754
                EditingNotification notification = editingManager.notifyObservers(this, BEFORE_UPDATE_FEATURE, null, this.store, feature);
755
                if( notification.isCanceled() ) {
756
                    theFormSet.message(i18n.getTranslation("Data saving has been cancelled."));
757
                    return;
758
                }                
759
                if (!editingManager.canWriteFeature(feature)) {
760
                    theFormSet.message(i18n.getTranslation("The data cannot be saved. Check that all the required fields are filled out.."));
761
                    return;
762
                }
763
                features.update(feature);
764
                editingManager.notifyObservers(this, AFTER_UPDATE_FEATURE, null, this.store, feature);
765

    
766
                this.formset.message(i18n.getTranslation("_Record_saved"));
767
                try {
768
                    this.formset.setCurrentIndex(index);
769
                } catch (Exception ex) {
770
                    LOGGER.warn("Can't reload form data after insert.", ex);
771
                }
772
            }
773
        } catch (Exception ex) {
774
            theFormSet.message(i18n.getTranslation("error_saving_data_will_not_save"));
775
            throw new RuntimeException("Can't save values", ex);
776

    
777
        } finally {
778
            updateButtonEnabledStatus();
779
        }
780

    
781
    }
782

    
783
    private void deleteCurrentElement(JDynFormSet theFormSet) {
784
        I18nManager i18n = ToolsLocator.getI18nManager();
785
        try {
786
            EditingNotificationManager editingManager = DALSwingLocator.getEditingNotificationManager();
787
            int index = theFormSet.getCurrentIndex();
788
            DynObject currentElement = theFormSet.get(index);
789
            theFormSet.getFormValues(currentElement);
790
            Feature feature = ((FacadeOfAFeature) currentElement).getFeature();
791
            if (feature instanceof EditableFeature) {
792
                feature = ((EditableFeature) feature).getNotEditableCopy();
793
            }
794
            if( editingManager.notifyObservers(this, BEFORE_REMOVE_FEATURE, null, this.store, feature).isCanceled() ) {
795
                theFormSet.message(i18n.getTranslation("The delete operation has been cancelled."));
796
                return;
797
            }                
798
            features.delete(feature);
799
            editingManager.notifyObservers(this, AFTER_REMOVE_FEATURE, null, this.store, feature);
800

    
801
            this.formset.message(i18n.getTranslation("_Record_removed"));
802

    
803
            this.formset.setValues(features.asListOfDynObjects());
804
            if (features.getTotalSize() - 1 < index) {
805
                index = index - 1;
806
            }
807
            this.formset.setCurrentIndex(index);
808

    
809
        } catch (Exception ex) {
810
            theFormSet.message(i18n.getTranslation("error_removing_data_will_not_remove"));
811
            throw new RuntimeException("Can't remove values", ex);
812

    
813
        } finally {
814
            updateButtonEnabledStatus();
815
        }
816

    
817
    }
818

    
819
    @Override
820
    public void saveChanges() {
821
        if (this.formset != null && this.formset.countValues() > 0) {
822
            if (store != null && !store.isEditing()) {
823
                try {
824
                    store.edit();
825
                } catch (DataException e1) {
826
                    LOGGER.warn("Can't edit the store " + store.getName());
827
                    throw new RuntimeException("Can't save changes.", e1);
828
                }
829
            }
830
            this.saveChanges(this.formset);
831
        }
832
    }
833

    
834
    private void updateButtonEnabledStatus() {
835
        if (this.formset == null) {
836
            return;
837
        }
838
        if (this.store == null || store.isBroken() || store.isAppending() || this.features == null) {
839
            this.formset.setReadOnly(true);
840
            formset.setActionVisible(STARTEDITING_ACTION, true);
841
            formset.setActionEnabled(STARTEDITING_ACTION, true);
842
            formset.setActionVisible(FINISHEDITING_ACTION, false);
843
            formset.setActionEnabled(FINISHEDITING_ACTION, false);
844
            formset.setActionEnabled(ACTION_DELETE, false);
845
            formset.setActionEnabled(ACTION_NEW, false);
846
            formset.setActionEnabled(ACTION_CANCEL_NEW, false);
847
            formset.setActionEnabled(ACTION_SAVE, false);
848
            formset.setActionEnabled(ACTION_SEARCH, false);
849
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
850
            formset.setActionEnabled(ACTION_NAVIGATION, false);
851
            return;
852
        }
853
        if (this.needrefresh ) {
854
            this.formset.setReadOnly(true);
855
//            formset.setActionEnabled(STARTEDITING_ACTION, false);
856
//            formset.setActionEnabled(FINISHEDITING_ACTION, false);
857
            formset.setActionEnabled(ACTION_DELETE, false);
858
            formset.setActionEnabled(ACTION_NEW, false);
859
            formset.setActionEnabled(ACTION_CANCEL_NEW, false);
860
            formset.setActionEnabled(ACTION_SAVE, false);
861
            formset.setActionEnabled(ACTION_SEARCH, false);
862
            formset.setActionEnabled(ACTION_NAVIGATION, false);
863
            for (Action action : formset.getActions()) {
864
                formset.setActionEnabled((String) action.getValue(ACTION_COMMAND_KEY), false);
865
            }
866
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
867
            return;
868
        }
869
        if (store.isEditing()) {
870
            this.formset.setReadOnly(false);
871
            formset.setActionVisible(STARTEDITING_ACTION, false);
872
            formset.setActionEnabled(STARTEDITING_ACTION, false);
873
            formset.setActionVisible(FINISHEDITING_ACTION, true);
874
            formset.setActionEnabled(FINISHEDITING_ACTION, true);
875
            if (formset.isInNewState()) {
876
                formset.setActionEnabled(ACTION_DELETE, false);
877
                formset.setActionEnabled(ACTION_SEARCH, false);
878
                formset.setActionEnabled(ACTION_NEW, false);
879
                formset.setActionEnabled(ACTION_CANCEL_NEW, true);
880
                formset.setActionEnabled(ACTION_SAVE, true);
881
                formset.setActionEnabled(FINISHEDITING_ACTION, false);
882
                formset.setActionEnabled(REFRESHFORM_ACTION, false);
883
//                setEnabledUniqueFields(true);
884

    
885
            } else if (this.features != null && this.features.isEmpty()) {
886
                formset.getForm().setReadOnly(true);
887
                formset.setActionEnabled(ACTION_DELETE, false);
888
                formset.setActionEnabled(ACTION_SEARCH, false);
889
                formset.setActionEnabled(ACTION_NEW, true);
890
                formset.setActionEnabled(ACTION_CANCEL_NEW, true);
891
                formset.setActionEnabled(ACTION_SAVE, false);
892
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
893
                formset.setActionEnabled(FINISHEDITING_ACTION, true);         
894
                formset.setActionEnabled(ACTION_NAVIGATION, false);
895

    
896
            } else if (formset.getForm().isModified()) {
897
                formset.setActionEnabled(ACTION_DELETE, false);
898
                formset.setActionEnabled(ACTION_SEARCH, false);
899
                formset.setActionEnabled(ACTION_NEW, false);
900
                formset.setActionEnabled(ACTION_CANCEL_NEW, false);
901
                formset.setActionEnabled(ACTION_SAVE, true);
902
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
903
                formset.setActionEnabled(FINISHEDITING_ACTION, false);
904
                formset.setActionEnabled(ACTION_NAVIGATION, false);
905

    
906
            } else {
907
                formset.setActionEnabled(ACTION_DELETE, true);
908
                formset.setActionEnabled(ACTION_SEARCH, true);
909
                formset.setActionEnabled(ACTION_NEW, true);
910
                formset.setActionEnabled(ACTION_CANCEL_NEW, false);
911
                formset.setActionEnabled(ACTION_SAVE, false);
912
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
913
                formset.setActionEnabled(FINISHEDITING_ACTION, true);
914
                formset.setActionEnabled(ACTION_NAVIGATION, true);
915
            }
916

    
917
            return;
918
        }
919
        this.formset.setReadOnly(true);
920
        formset.setActionVisible(STARTEDITING_ACTION, true);
921
        formset.setActionEnabled(STARTEDITING_ACTION, true);
922
        formset.setActionVisible(FINISHEDITING_ACTION, false);
923
        formset.setActionEnabled(FINISHEDITING_ACTION, false);
924
        formset.setActionEnabled(ACTION_DELETE, false);
925
        formset.setActionEnabled(ACTION_NEW, false);
926
        formset.setActionEnabled(ACTION_CANCEL_NEW, false);
927
        formset.setActionEnabled(ACTION_SAVE, false);
928
        formset.setActionEnabled(ACTION_SEARCH, true);
929
        formset.setActionEnabled(REFRESHFORM_ACTION, true);
930
        for (Action action : formset.getActions()) {
931
            formset.setActionEnabled((String) action.getValue(ACTION_COMMAND_KEY), true);
932
        }
933
        
934
    }
935

    
936
    private void clearUniqueFields() {
937
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
938
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
939
                JDynFormField field = formset.getForm().getField(attr.getName());
940
                if (field != null) {
941
                    field.clear();
942
                }
943
            }
944
        }
945
    }
946

    
947
    private void setEnabledUniqueFields(boolean enabled) {
948
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
949
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
950
                JDynFormField field = formset.getForm().getField(attr.getName());
951
                if (field != null) {
952
                    field.setReadOnly(!enabled);
953
                }
954
            }
955
        }
956
    }
957

    
958
    @Override
959
    public long getDataSetSize() {
960
        if (this.features != null) {
961
            return features.getTotalSize();
962
        }
963
        return 0;
964
    }
965

    
966
    @Override
967
    public FeatureStore getFeatureStore() {
968
        return this.store;
969
    }
970
    
971
    public FeatureType getFeatureType() {
972
        if( this.store == null ) {
973
            return null;
974
        }
975
        return this.store.getDefaultFeatureTypeQuietly();
976
    }
977

    
978
    private class FormSetListener implements JDynFormSetListener {
979

    
980
        @Override
981
        public void formMessage(String message) {
982
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMessage"));
983
        }
984

    
985
        @Override
986
        public void formClose() {
987
            panel.setVisible(false);
988
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formClose"));
989
        }
990

    
991
        @Override
992
        public void formMovedTo(int currentPosition) throws AbortActionException {
993
            LOGGER.trace("formMovedTo " + currentPosition);
994
            updateButtonEnabledStatus();
995
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMovedTo"));
996
        }
997

    
998
        @Override
999
        public void formBeforeSave(JDynFormSet dynformSet) throws AbortActionException {
1000
            LOGGER.trace("formBeforeSave");
1001
            saveChanges(dynformSet);
1002
            updateButtonEnabledStatus();
1003
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSave"));
1004
        }
1005

    
1006
        @Override
1007
        public void formBeforeNew(JDynFormSet dynformSet) throws AbortActionException {
1008
            LOGGER.trace("formBeforeNew");
1009
            clearUniqueFields();
1010
            updateButtonEnabledStatus();
1011
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeNew"));
1012
        }
1013

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

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

    
1028
        @Override
1029
        public void formAfterNew(JDynFormSet dynformSet) throws AbortActionException {
1030
            LOGGER.trace("formAfterNew");
1031
            updateButtonEnabledStatus();
1032
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterNew"));
1033
        }
1034

    
1035
        @Override
1036
        public void formAfterDelete(JDynFormSet dynformSet) throws AbortActionException {
1037
            LOGGER.trace("formAfterDelete");
1038
            deleteCurrentElement(dynformSet);
1039
            updateButtonEnabledStatus();
1040
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterDelete"));
1041
        }
1042

    
1043
        @Override
1044
        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
1045
            LOGGER.trace("formBeforeSearch");
1046
            DataSwingManager dataSwingmanager = DALSwingLocator.getSwingManager();
1047
            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1048

    
1049
            final FeatureStoreSearchPanel searchPanel = dataSwingmanager.createFeatureStoreSearchPanel(store);
1050
            searchPanel.setShowActions(false);
1051
            FeatureQuery currentQuery = getCurrentQuery();
1052
            if (currentQuery != null) {
1053
                Evaluator filter = currentQuery.getFilter();
1054
                if (filter instanceof ExpressionEvaluator) {
1055
                    Expression expression = ((ExpressionEvaluator) filter).toExpression();
1056
                    searchPanel.setFilter(expression);
1057
                    searchPanel.search();
1058
                }
1059
            }
1060
            ToolsSwingUtils.ensureHeightWitdh(
1061
                    searchPanel, 
1062
                    ToolsSwingUtils.RELATIVE_TO_SCREEN,
1063
                    0.75f, 0.75f, 0.85f, 0.85f
1064
            );          
1065
                             
1066
            I18nManager i18n = ToolsLocator.getI18nManager();
1067
            Dialog dialog = winmgr.createDialog(
1068
                    searchPanel.asJComponent(),
1069
                    i18n.getTranslation("_Filter"),
1070
                    i18n.getTranslation("_Creating_filter_for") + ": '" + store.getName() + "'",
1071
                    WindowManager_v2.BUTTONS_OK_CANCEL
1072
            );
1073
            dialog.show(WindowManager.MODE.DIALOG);
1074
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
1075
                SearchParameters params = searchPanel.fetch(null);
1076
                if (params.getQuery() != null) {
1077
                    FeatureQuery searchQuery = params.getQuery().getCopy();
1078

    
1079
                    Expression expresion = null;
1080
                    if (searchQuery != null) {
1081
                        expresion = searchQuery.getExpressionFilter();
1082
                    }
1083
                    try {
1084
                        FeatureQuery query = store.createFeatureQuery();
1085
                        if (ExpressionUtils.isPhraseEmpty(expresion)) {
1086
                            query.clearFilter();
1087
                        } else {
1088
                            query.setFilter(expresion);
1089
                        }
1090
                        setQuery(query);
1091
                    } catch (Exception ex) {
1092
                        LOGGER.warn("Can't apply filter '" + expresion + "'.", ex);
1093
                    }
1094
                } else {
1095
                    LOGGER.warn("FeatureQuery from parameters is null. Query is not applied to the JFeaturesFrom");
1096
                }
1097
            }
1098
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSearch"));
1099
        }
1100

    
1101
        @Override
1102
        public void formAfterSearch(JDynFormSet dynformSet) throws AbortActionException {
1103
            LOGGER.trace("formAfterSearch");
1104
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSearch"));
1105
        }
1106

    
1107
        @Override
1108
        public void formBeforeCancelNew(JDynFormSet dynformSet) throws AbortActionException {
1109
            LOGGER.trace("formBeforeCancelNew");
1110
            updateButtonEnabledStatus();
1111
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeCancelNew"));
1112
        }
1113

    
1114
        @Override
1115
        public void formAfterCancelNew(JDynFormSet dynformSet) throws AbortActionException {
1116
            LOGGER.trace("formAfterCancelNew");
1117
            try {
1118
                int index = formset.getCurrentIndex();
1119
                if( index<0 ) {
1120
                    formset.getForm().clear();
1121
                } else {
1122
                    formset.setCurrentIndex(index);
1123
                }
1124
            } catch (Exception ex) {
1125
                LOGGER.warn("Can't reload form data after cancel new.", ex);
1126
            }            
1127
            updateButtonEnabledStatus();
1128
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterCancelNew"));
1129
        }
1130

    
1131
    }
1132

    
1133
    @Override
1134
    public void addActionListener(ActionListener listener) {
1135
        this.actionListeners.addActionListener(listener);
1136
    }
1137

    
1138
    @Override
1139
    public ActionListener[] getActionListeners() {
1140
        return this.actionListeners.getActionListeners();
1141
    }
1142

    
1143
    @Override
1144
    public void removeActionListener(ActionListener listener) {
1145
        this.actionListeners.removeActionListener(listener);
1146
    }
1147

    
1148
    @Override
1149
    public void removeAllActionListener() {
1150
        this.actionListeners.removeAllActionListener();
1151
    }
1152

    
1153
    @Override
1154
    public void fireActionEvent(ActionEvent event) {
1155
        this.actionListeners.fireActionEvent(event);
1156
    }
1157

    
1158
    @Override
1159
    public boolean hasActionListeners() {
1160
        return this.actionListeners.hasActionListeners();
1161
    }
1162

    
1163
    @Override
1164
    public Feature getCurrentFeature() {
1165
        // TODO: No tengo claro que esto sea correcto, ya que no tiene 
1166
        // en cuenta si el form se esta modificando o es nuevo para coger
1167
        // los valores del formulario.
1168
        long index = getCurrentIndex();
1169
        if( index<0 ) {
1170
            return null;
1171
        }
1172
        Feature f = get(index);
1173
        try {
1174
            DynObject adapter = f.getAsDynObject();
1175
            this.getFormset().getForm().getValues(adapter);
1176
            f = ((FacadeOfAFeature)adapter).getFeature();
1177
            return f;
1178
        } catch(Exception ex) {
1179
            return f;
1180
        }
1181
    }
1182

    
1183
    protected void callUserEvent(String name, Object...args) {
1184
//        try {
1185
            JDynForm form = this.formset.getForm();
1186
            form.callUserEvent(name, args);
1187
//        } catch(NoSuchMethodException ex) {
1188
//            LOGGER.debug("Function '"+name+"' not found.", ex);
1189
//            // Do nothing
1190
//        } catch(Exception ex) {
1191
//            LOGGER.warn("Error calling form event '"+name+"'.", ex);
1192
//        }
1193
    }
1194
    
1195
    @Override
1196
    public void setTerminateEditingOnClose(boolean b) {
1197
        terminateEditingOnClose = b;
1198
    }
1199

    
1200
    @Override
1201
    public boolean isTerminateEditingOnClose() {
1202
        return terminateEditingOnClose;
1203
    }
1204

    
1205
    private void onClose() {
1206
        if (this.store == null || this.ignoreTerminateEditingOnClose) {
1207
            return;
1208
        }
1209
        if (this.store.isEditing() && terminateEditingOnClose) {
1210
            DataSwingManager dataSwingManager = DALSwingLocator.getDataSwingManager();
1211
            ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
1212
            I18nManager i18nManager = ToolsLocator.getI18nManager();
1213
            try {
1214
                int x = dataSwingManager.askUserStopEditing(formset.asJComponent(), store, false);
1215
                switch (x) {
1216
                    case DataSwingManager.STOP_EDITING_SAVE:
1217
                        store.finishEditing();
1218
                        break;
1219
                    case DataSwingManager.STOP_EDITING_CONTINUE:
1220
                        break;
1221
                    case DataSwingManager.STOP_EDITING_DISCARD:
1222
                        store.cancelEditing();
1223
                        break;
1224
                    case DataSwingManager.STOP_EDITING_EXPORT:
1225
                        if( !((DefaultDataSwingManager)dataSwingManager).exportStore(store, MODE.DIALOG) ) {
1226
                            // Mensaje de operacion no soportada
1227
                        }
1228
                }
1229
            } catch (Exception ex) {
1230
                LOGGER.warn("Can't finish editing in FeatureForm (" + DataStore.getNameQuietly(store) + ").", ex);
1231
                dialogManager.messageDialog(
1232
                        i18nManager.getTranslation("_Problems_finish_table_editing") + "\n\n"
1233
                        + i18nManager.getTranslation("_see_error_log_for_more_information"),
1234
                        i18nManager.getTranslation("_Stop_editing"),
1235
                        JOptionPane.ERROR_MESSAGE
1236
                );
1237
            }
1238

    
1239
        }
1240
    }
1241

    
1242

    
1243
}