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

History | View | Annotate | Download (51.4 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.exception.FeatureIndexException;
75
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
76
import org.gvsig.fmap.dal.swing.AbstractDALActionFactory.AbstractDALActionContext;
77
import org.gvsig.fmap.dal.swing.DALActionFactory;
78
import org.gvsig.fmap.dal.swing.DALSwingLocator;
79
import org.gvsig.fmap.dal.swing.DataSwingManager;
80
import org.gvsig.fmap.dal.swing.impl.DefaultDataSwingManager;
81
import org.gvsig.fmap.dal.swing.impl.actions.ShowFormAction.ShowFormActionFactory;
82
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
83
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
84
import org.gvsig.tools.ToolsLocator;
85
import org.gvsig.tools.dispose.Disposable;
86
import org.gvsig.tools.dispose.DisposeUtils;
87
import org.gvsig.tools.dynform.AbortActionException;
88
import org.gvsig.tools.dynform.DynFormDefinition;
89
import org.gvsig.tools.dynform.DynFormLocator;
90
import org.gvsig.tools.dynform.DynFormManager;
91
import org.gvsig.tools.dynform.JDynForm;
92
import org.gvsig.tools.dynform.JDynFormField;
93
import org.gvsig.tools.dynform.JDynFormSet;
94
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_CANCEL_NEW;
95
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_DELETE;
96
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NAVIGATION;
97
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NEW;
98
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SAVE;
99
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SEARCH;
100
import org.gvsig.tools.dynform.JDynFormSet.JDynFormSetListener;
101
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
102
import org.gvsig.tools.dynobject.DynClass;
103
import org.gvsig.tools.dynobject.DynObject;
104
import org.gvsig.tools.evaluator.Evaluator;
105
import org.gvsig.tools.exception.BaseException;
106
import org.gvsig.tools.i18n.I18nManager;
107
import org.gvsig.tools.observer.Observable;
108
import org.gvsig.tools.observer.Observer;
109
import org.gvsig.tools.swing.api.ActionListenerSupport;
110
import org.gvsig.tools.swing.api.ToolsSwingLocator;
111
import org.gvsig.tools.swing.api.ToolsSwingUtils;
112
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
113
import org.gvsig.tools.swing.api.windowmanager.Dialog;
114
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
115
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
116
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
117
import org.gvsig.tools.swing.icontheme.IconTheme;
118
import org.gvsig.tools.util.PropertiesSupport;
119
import org.gvsig.tools.util.PropertiesSupportHelper;
120
import org.slf4j.Logger;
121
import org.slf4j.LoggerFactory;
122

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

    
130
    private class JFeaturesFormPanel extends JPanel implements PropertiesSupport {
131

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

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

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

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

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

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

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

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

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

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

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

    
201
    }
202

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

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

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

    
235
    public static void selfRegister() {
236

    
237
    }
238

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

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

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

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

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

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

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

    
343
    public static class MyFeaturesFormContext extends DefaultFeaturesFormContext {
344

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

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

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

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

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

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

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

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

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

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

    
475
    private class RefreshAction extends AbstractAction {
476

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

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

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

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

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

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

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

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

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

    
600
        @Override
601
        public void dispose() {
602
            store.deleteObserver(this);
603
        }
604

    
605
    }
606

    
607
    private class StartEditingAction extends AbstractAction implements Observer, Disposable {
608

    
609
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
610
        public StartEditingAction() {
611
            I18nManager i18nManager = ToolsLocator.getI18nManager();
612
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
613

    
614
            this.putValue(NAME, null);
615
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Start_editing"));
616
            this.putValue(SMALL_ICON, iconTheme.get("table-start-editing"));
617
            this.putValue(ACTION_COMMAND_KEY, STARTEDITING_ACTION);
618

    
619
            this.setEnabled(!store.isEditing());
620
            store.addObserver(this);
621
        }
622

    
623
        @Override
624
        public void actionPerformed(ActionEvent ae) {
625
            if (store == null || formset == null) {
626
                return;
627
            }
628
            if (!store.isEditing()) {
629
                try {
630
                    EditingNotificationManager editingManager = DALSwingLocator.getEditingNotificationManager();
631
                    EditingNotification notification = editingManager.notifyObservers(this, BEFORE_ENTER_EDITING_STORE, null, store);
632
                    if( notification.isCanceled() || notification.isAborted() ) {
633
                        I18nManager i18n = ToolsLocator.getI18nManager();
634
                        formset.message(i18n.getTranslation("Enter editing has been cancelled."));
635
                        return;
636
                    }                
637
                    store.edit();
638
                    editingManager.notifyObservers(this, AFTER_ENTER_EDITING_STORE, null, store);
639
                } catch (DataException ex) {
640
                    LOGGER.warn("Can't finish editing in FeatureForm (" + store.getName() + ").", ex);
641
                }
642
            }
643
            updateButtonEnabledStatus();
644
        }
645

    
646
        @Override
647
        public void update(Observable observable, Object notification) {
648
            if (store == null || formset == null) {
649
                return;
650
            }
651
            if (notification instanceof FeatureStoreNotification) {
652
                FeatureStoreNotification n = (FeatureStoreNotification) notification;
653
                switch (n.getType()) {
654
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
655
                        needrefresh = true;
656
                    case FeatureStoreNotification.AFTER_STARTEDITING:
657
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
658
                        updateButtonEnabledStatus();
659
                        break;
660
                }
661
            }
662
        }
663

    
664
        @Override
665
        public void dispose() {
666
            store.deleteObserver(this);
667
        }
668

    
669
    }
670

    
671
    @Override
672
    public void setQuery(FeatureQuery query) {
673
        if (this.features != null) {
674
            if (this.formset != null && !formset.isReadOnly() && this.formset.isAutosave() && this.formset.countValues() > 0) {
675
                if(this.formset.getForm().isModified()){
676
                    if (!store.isEditing()) {
677
                        try {
678
                            store.edit();
679
                        } catch (DataException e1) {
680
                            throw new RuntimeException("Can't set query", e1);
681
                        }
682
                    }
683
                    saveChanges(this.formset);
684
                }
685
            }
686
        }
687
        this.currentQuery = query;
688
        updateForm();
689
    }
690

    
691
    private FeatureQuery getCurrentQuery() {
692
        return this.currentQuery;
693
    }
694

    
695
    @Override
696
    public void showForm(MODE mode) {
697
        I18nManager i18n = ToolsLocator.getI18nManager();
698
        String title = i18n.getTranslation("_Form") + ": "+ this.definition.getLabel();
699
        showForm(title, mode);
700
    }
701

    
702
    @Override
703
    public void showForm(String title, MODE mode) {
704
        WindowManager winmgr = ToolsSwingLocator.getWindowManager();
705
        if( StringUtils.isBlank(title) ) {
706
            title = this.definition.getLabel();
707
        }
708
        winmgr.showWindow(this.asJComponent(), title, mode);
709
    }
710
    
711
    @Override
712
    public void hideForm() {
713
        DisposeUtils.dispose(this);
714
    }
715

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

    
769
                EditableFeature feature = ((FacadeOfAFeature) currentElement).getEditableFeature();
770
                EditingNotification notification = editingManager.notifyObservers(this, BEFORE_UPDATE_FEATURE, null, this.store, feature);
771
                if( notification.isAborted()) {
772
                    theFormSet.message(i18n.getTranslation("Problems occurred while saving the data."));
773
                    return;
774
                }                
775
                if( notification.isCanceled() ) {
776
                    theFormSet.message(i18n.getTranslation("Data saving has been cancelled."));
777
                    return;
778
                }                
779
                if (!editingManager.canWriteFeature(feature)) {
780
                    theFormSet.message(i18n.getTranslation("The data cannot be saved. Check that all the required fields are filled out.."));
781
                    return;
782
                }
783
                features.update(feature);
784
                editingManager.notifyObservers(this, AFTER_UPDATE_FEATURE, null, this.store, feature);
785

    
786
                this.formset.message(i18n.getTranslation("_Record_saved"));
787
                try {
788
                    this.formset.setCurrentIndex(index);
789
                } catch (Exception ex) {
790
                    LOGGER.warn("Can't reload form data after insert.", ex);
791
                }
792
            }
793
        } catch (Exception ex) {
794
            theFormSet.message(i18n.getTranslation("error_saving_data_will_not_save"));
795
            throw new RuntimeException("Can't save values", ex);
796

    
797
        } finally {
798
            updateButtonEnabledStatus();
799
        }
800

    
801
    }
802

    
803
    private void deleteCurrentElement(JDynFormSet theFormSet) {
804
        I18nManager i18n = ToolsLocator.getI18nManager();
805
        try {
806
            EditingNotificationManager editingManager = DALSwingLocator.getEditingNotificationManager();
807
            int index = theFormSet.getCurrentIndex();
808
            DynObject currentElement = theFormSet.get(index);
809
            theFormSet.getFormValues(currentElement);
810
            Feature feature = ((FacadeOfAFeature) currentElement).getFeature();
811
            if (feature instanceof EditableFeature) {
812
                feature = ((EditableFeature) feature).getNotEditableCopy();
813
            }
814
            if( editingManager.notifyObservers(this, BEFORE_REMOVE_FEATURE, null, this.store, feature).isCanceled() ) {
815
                theFormSet.message(i18n.getTranslation("The delete operation has been cancelled."));
816
                return;
817
            }                
818
            features.delete(feature);
819
            editingManager.notifyObservers(this, AFTER_REMOVE_FEATURE, null, this.store, feature);
820

    
821
            this.formset.message(i18n.getTranslation("_Record_removed"));
822

    
823
            this.formset.setValues(features.asListOfDynObjects());
824
            if (features.getTotalSize() - 1 < index) {
825
                index = index - 1;
826
            }
827
            this.formset.setCurrentIndex(index);
828

    
829
        } catch (Exception ex) {
830
            theFormSet.message(i18n.getTranslation("error_removing_data_will_not_remove"));
831
            throw new RuntimeException("Can't remove values", ex);
832

    
833
        } finally {
834
            updateButtonEnabledStatus();
835
        }
836

    
837
    }
838

    
839
    @Override
840
    public void saveChanges() {
841
        if (this.formset != null && this.formset.countValues() > 0) {
842
            if (store != null && !store.isEditing()) {
843
                try {
844
                    store.edit();
845
                } catch (DataException e1) {
846
                    LOGGER.warn("Can't edit the store " + store.getName());
847
                    throw new RuntimeException("Can't save changes.", e1);
848
                }
849
            }
850
            this.saveChanges(this.formset);
851
        }
852
    }
853

    
854
    private void updateButtonEnabledStatus() {
855
        if (this.formset == null) {
856
            return;
857
        }
858
        if (this.store == null || store.isBroken() || store.isAppending() || this.features == null) {
859
            this.formset.setReadOnly(true);
860
            formset.setActionVisible(STARTEDITING_ACTION, true);
861
            formset.setActionEnabled(STARTEDITING_ACTION, true);
862
            formset.setActionVisible(FINISHEDITING_ACTION, false);
863
            formset.setActionEnabled(FINISHEDITING_ACTION, false);
864
            formset.setActionEnabled(ACTION_DELETE, false);
865
            formset.setActionEnabled(ACTION_NEW, false);
866
            formset.setActionEnabled(ACTION_CANCEL_NEW, false);
867
            formset.setActionEnabled(ACTION_SAVE, false);
868
            formset.setActionEnabled(ACTION_SEARCH, false);
869
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
870
            formset.setActionEnabled(ACTION_NAVIGATION, false);
871
            return;
872
        }
873
        if (this.needrefresh ) {
874
            this.formset.setReadOnly(true);
875
//            formset.setActionEnabled(STARTEDITING_ACTION, false);
876
//            formset.setActionEnabled(FINISHEDITING_ACTION, false);
877
            formset.setActionEnabled(ACTION_DELETE, false);
878
            formset.setActionEnabled(ACTION_NEW, false);
879
            formset.setActionEnabled(ACTION_CANCEL_NEW, false);
880
            formset.setActionEnabled(ACTION_SAVE, false);
881
            formset.setActionEnabled(ACTION_SEARCH, false);
882
            formset.setActionEnabled(ACTION_NAVIGATION, false);
883
            for (Action action : formset.getActions()) {
884
                formset.setActionEnabled((String) action.getValue(ACTION_COMMAND_KEY), false);
885
            }
886
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
887
            return;
888
        }
889
        if (store.isEditing()) {
890
            this.formset.setReadOnly(false);
891
            formset.setActionVisible(STARTEDITING_ACTION, false);
892
            formset.setActionEnabled(STARTEDITING_ACTION, false);
893
            formset.setActionVisible(FINISHEDITING_ACTION, true);
894
            formset.setActionEnabled(FINISHEDITING_ACTION, true);
895
            if (formset.isInNewState()) {
896
                formset.setActionEnabled(ACTION_DELETE, false);
897
                formset.setActionEnabled(ACTION_SEARCH, false);
898
                formset.setActionEnabled(ACTION_NEW, false);
899
                formset.setActionEnabled(ACTION_CANCEL_NEW, true);
900
                formset.setActionEnabled(ACTION_SAVE, true);
901
                formset.setActionEnabled(FINISHEDITING_ACTION, false);
902
                formset.setActionEnabled(REFRESHFORM_ACTION, false);
903
//                setEnabledUniqueFields(true);
904

    
905
            } else if (this.features != null && this.features.isEmpty()) {
906
                formset.getForm().setReadOnly(true);
907
                formset.setActionEnabled(ACTION_DELETE, false);
908
                formset.setActionEnabled(ACTION_SEARCH, false);
909
                formset.setActionEnabled(ACTION_NEW, true);
910
                formset.setActionEnabled(ACTION_CANCEL_NEW, true);
911
                formset.setActionEnabled(ACTION_SAVE, false);
912
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
913
                formset.setActionEnabled(FINISHEDITING_ACTION, true);         
914
                formset.setActionEnabled(ACTION_NAVIGATION, false);
915

    
916
            } else if (formset.getForm().isModified()) {
917
                formset.setActionEnabled(ACTION_DELETE, false);
918
                formset.setActionEnabled(ACTION_SEARCH, false);
919
                formset.setActionEnabled(ACTION_NEW, false);
920
                formset.setActionEnabled(ACTION_CANCEL_NEW, false);
921
                formset.setActionEnabled(ACTION_SAVE, true);
922
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
923
                formset.setActionEnabled(FINISHEDITING_ACTION, false);
924
                formset.setActionEnabled(ACTION_NAVIGATION, false);
925

    
926
            } else {
927
                formset.setActionEnabled(ACTION_DELETE, true);
928
                formset.setActionEnabled(ACTION_SEARCH, true);
929
                formset.setActionEnabled(ACTION_NEW, true);
930
                formset.setActionEnabled(ACTION_CANCEL_NEW, false);
931
                formset.setActionEnabled(ACTION_SAVE, false);
932
                formset.setActionEnabled(REFRESHFORM_ACTION, true);
933
                formset.setActionEnabled(FINISHEDITING_ACTION, true);
934
                formset.setActionEnabled(ACTION_NAVIGATION, true);
935
            }
936

    
937
            return;
938
        }
939
        this.formset.setReadOnly(true);
940
        formset.setActionVisible(STARTEDITING_ACTION, true);
941
        formset.setActionEnabled(STARTEDITING_ACTION, true);
942
        formset.setActionVisible(FINISHEDITING_ACTION, false);
943
        formset.setActionEnabled(FINISHEDITING_ACTION, false);
944
        formset.setActionEnabled(ACTION_DELETE, false);
945
        formset.setActionEnabled(ACTION_NEW, false);
946
        formset.setActionEnabled(ACTION_CANCEL_NEW, false);
947
        formset.setActionEnabled(ACTION_SAVE, false);
948
        formset.setActionEnabled(ACTION_SEARCH, true);
949
        formset.setActionEnabled(REFRESHFORM_ACTION, true);
950
        for (Action action : formset.getActions()) {
951
            formset.setActionEnabled((String) action.getValue(ACTION_COMMAND_KEY), true);
952
        }
953
        
954
    }
955

    
956
    private void clearUniqueFields() {
957
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
958
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
959
                JDynFormField field = formset.getForm().getField(attr.getName());
960
                if (field != null) {
961
                    field.clear();
962
                }
963
            }
964
        }
965
    }
966

    
967
    private void setEnabledUniqueFields(boolean enabled) {
968
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
969
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
970
                JDynFormField field = formset.getForm().getField(attr.getName());
971
                if (field != null) {
972
                    field.setReadOnly(!enabled);
973
                }
974
            }
975
        }
976
    }
977

    
978
    @Override
979
    public long getDataSetSize() {
980
        if (this.features != null) {
981
            return features.getTotalSize();
982
        }
983
        return 0;
984
    }
985

    
986
    @Override
987
    public FeatureStore getFeatureStore() {
988
        return this.store;
989
    }
990
    
991
    public FeatureType getFeatureType() {
992
        if( this.store == null ) {
993
            return null;
994
        }
995
        return this.store.getDefaultFeatureTypeQuietly();
996
    }
997

    
998
    private class FormSetListener implements JDynFormSetListener {
999

    
1000
        @Override
1001
        public void formMessage(String message) {
1002
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMessage"));
1003
        }
1004

    
1005
        @Override
1006
        public void formClose() {
1007
            panel.setVisible(false);
1008
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formClose"));
1009
        }
1010

    
1011
        @Override
1012
        public void formMovedTo(int currentPosition) throws AbortActionException {
1013
            LOGGER.trace("formMovedTo " + currentPosition);
1014
            updateButtonEnabledStatus();
1015
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMovedTo"));
1016
        }
1017

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

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

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

    
1041
        @Override
1042
        public void formAfterSave(JDynFormSet dynformSet) throws AbortActionException {
1043
            LOGGER.trace("formAfterSave");
1044
            updateButtonEnabledStatus();
1045
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSave"));
1046
        }
1047

    
1048
        @Override
1049
        public void formAfterNew(JDynFormSet dynformSet) throws AbortActionException {
1050
            LOGGER.trace("formAfterNew");
1051
            updateButtonEnabledStatus();
1052
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterNew"));
1053
        }
1054

    
1055
        @Override
1056
        public void formAfterDelete(JDynFormSet dynformSet) throws AbortActionException {
1057
            LOGGER.trace("formAfterDelete");
1058
            deleteCurrentElement(dynformSet);
1059
            updateButtonEnabledStatus();
1060
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterDelete"));
1061
        }
1062

    
1063
        @Override
1064
        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
1065
            LOGGER.trace("formBeforeSearch");
1066
            DataSwingManager dataSwingmanager = DALSwingLocator.getSwingManager();
1067
            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1068

    
1069
            final FeatureStoreSearchPanel searchPanel = dataSwingmanager.createFeatureStoreSearchPanel(store);
1070
            searchPanel.setShowActions(false);
1071
            FeatureQuery currentQuery = getCurrentQuery();
1072
            if (currentQuery != null) {
1073
                Evaluator filter = currentQuery.getFilter();
1074
                if (filter instanceof ExpressionEvaluator) {
1075
                    Expression expression = ((ExpressionEvaluator) filter).toExpression();
1076
                    searchPanel.setFilter(expression);
1077
                    searchPanel.search();
1078
                }
1079
            }
1080
            ToolsSwingUtils.ensureHeightWitdh(
1081
                    searchPanel, 
1082
                    ToolsSwingUtils.RELATIVE_TO_SCREEN,
1083
                    0.75f, 0.75f, 0.85f, 0.85f
1084
            );          
1085
                             
1086
            I18nManager i18n = ToolsLocator.getI18nManager();
1087
            Dialog dialog = winmgr.createDialog(
1088
                    searchPanel.asJComponent(),
1089
                    i18n.getTranslation("_Filter"),
1090
                    i18n.getTranslation("_Creating_filter_for") + ": '" + store.getName() + "'",
1091
                    WindowManager_v2.BUTTONS_OK_CANCEL
1092
            );
1093
            dialog.show(WindowManager.MODE.DIALOG);
1094
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
1095
                SearchParameters params = searchPanel.fetch(null);
1096
                if (params.getQuery() != null) {
1097
                    FeatureQuery searchQuery = params.getQuery().getCopy();
1098

    
1099
                    Expression expresion = null;
1100
                    if (searchQuery != null) {
1101
                        expresion = searchQuery.getExpressionFilter();
1102
                    }
1103
                    try {
1104
                        FeatureQuery query = store.createFeatureQuery();
1105
                        if (ExpressionUtils.isPhraseEmpty(expresion)) {
1106
                            query.clearFilter();
1107
                        } else {
1108
                            query.setFilter(expresion);
1109
                        }
1110
                        setQuery(query);
1111
                    } catch (Exception ex) {
1112
                        LOGGER.warn("Can't apply filter '" + expresion + "'.", ex);
1113
                    }
1114
                } else {
1115
                    LOGGER.warn("FeatureQuery from parameters is null. Query is not applied to the JFeaturesFrom");
1116
                }
1117
            }
1118
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSearch"));
1119
        }
1120

    
1121
        @Override
1122
        public void formAfterSearch(JDynFormSet dynformSet) throws AbortActionException {
1123
            LOGGER.trace("formAfterSearch");
1124
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSearch"));
1125
        }
1126

    
1127
        @Override
1128
        public void formBeforeCancelNew(JDynFormSet dynformSet) throws AbortActionException {
1129
            LOGGER.trace("formBeforeCancelNew");
1130
            updateButtonEnabledStatus();
1131
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeCancelNew"));
1132
        }
1133

    
1134
        @Override
1135
        public void formAfterCancelNew(JDynFormSet dynformSet) throws AbortActionException {
1136
            LOGGER.trace("formAfterCancelNew");
1137
            try {
1138
                int index = formset.getCurrentIndex();
1139
                if( index<0 ) {
1140
                    formset.getForm().clear();
1141
                } else {
1142
                    formset.setCurrentIndex(index);
1143
                }
1144
            } catch (Exception ex) {
1145
                LOGGER.warn("Can't reload form data after cancel new.", ex);
1146
            }            
1147
            updateButtonEnabledStatus();
1148
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterCancelNew"));
1149
        }
1150

    
1151
    }
1152

    
1153
    @Override
1154
    public void addActionListener(ActionListener listener) {
1155
        this.actionListeners.addActionListener(listener);
1156
    }
1157

    
1158
    @Override
1159
    public ActionListener[] getActionListeners() {
1160
        return this.actionListeners.getActionListeners();
1161
    }
1162

    
1163
    @Override
1164
    public void removeActionListener(ActionListener listener) {
1165
        this.actionListeners.removeActionListener(listener);
1166
    }
1167

    
1168
    @Override
1169
    public void removeAllActionListener() {
1170
        this.actionListeners.removeAllActionListener();
1171
    }
1172

    
1173
    @Override
1174
    public void fireActionEvent(ActionEvent event) {
1175
        this.actionListeners.fireActionEvent(event);
1176
    }
1177

    
1178
    @Override
1179
    public boolean hasActionListeners() {
1180
        return this.actionListeners.hasActionListeners();
1181
    }
1182

    
1183
    @Override
1184
    public Feature getCurrentFeature() {
1185
        // TODO: No tengo claro que esto sea correcto, ya que no tiene 
1186
        // en cuenta si el form se esta modificando o es nuevo para coger
1187
        // los valores del formulario.
1188
        long index = getCurrentIndex();
1189
        if( index<0 ) {
1190
            return null;
1191
        }
1192
        Feature f = get(index);
1193
        try {
1194
            DynObject adapter = f.getAsDynObject();
1195
            this.getFormset().getForm().getValues(adapter);
1196
            f = ((FacadeOfAFeature)adapter).getFeature();
1197
            return f;
1198
        } catch(Exception ex) {
1199
            return f;
1200
        }
1201
    }
1202

    
1203
    protected void callUserEvent(String name, Object...args) {
1204
//        try {
1205
            JDynForm form = this.formset.getForm();
1206
            form.callUserEvent(name, args);
1207
//        } catch(NoSuchMethodException ex) {
1208
//            LOGGER.debug("Function '"+name+"' not found.", ex);
1209
//            // Do nothing
1210
//        } catch(Exception ex) {
1211
//            LOGGER.warn("Error calling form event '"+name+"'.", ex);
1212
//        }
1213
    }
1214
    
1215
    @Override
1216
    public void setTerminateEditingOnClose(boolean b) {
1217
        terminateEditingOnClose = b;
1218
    }
1219

    
1220
    @Override
1221
    public boolean isTerminateEditingOnClose() {
1222
        return terminateEditingOnClose;
1223
    }
1224

    
1225
    private void onClose() {
1226
        if (this.store == null || this.ignoreTerminateEditingOnClose) {
1227
            return;
1228
        }
1229
        if (this.store.isEditing() && terminateEditingOnClose) {
1230
            DataSwingManager dataSwingManager = DALSwingLocator.getDataSwingManager();
1231
            ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
1232
            I18nManager i18nManager = ToolsLocator.getI18nManager();
1233
            try {
1234
                int x = dataSwingManager.askUserStopEditing(formset.asJComponent(), store, false);
1235
                switch (x) {
1236
                    case DataSwingManager.STOP_EDITING_SAVE:
1237
                        store.finishEditing();
1238
                        break;
1239
                    case DataSwingManager.STOP_EDITING_CONTINUE:
1240
                        break;
1241
                    case DataSwingManager.STOP_EDITING_DISCARD:
1242
                        store.cancelEditing();
1243
                        break;
1244
                    case DataSwingManager.STOP_EDITING_EXPORT:
1245
                        if( !((DefaultDataSwingManager)dataSwingManager).exportStore(store, MODE.DIALOG) ) {
1246
                            // Mensaje de operacion no soportada
1247
                        }
1248
                }
1249
            } catch (Exception ex) {
1250
                LOGGER.warn("Can't finish editing in FeatureForm (" + DataStore.getNameQuietly(store) + ").", ex);
1251
                dialogManager.messageDialog(
1252
                        i18nManager.getTranslation("_Problems_finish_table_editing") + "\n\n"
1253
                        + i18nManager.getTranslation("_see_error_log_for_more_information"),
1254
                        i18nManager.getTranslation("_Stop_editing"),
1255
                        JOptionPane.ERROR_MESSAGE
1256
                );
1257
            }
1258

    
1259
        }
1260
    }
1261

    
1262

    
1263
}