Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app.document.table.app / org.gvsig.app.document.table.app.mainplugin / src / main / java / org / gvsig / app / extension / TableEditStopExtension.java @ 42967

History | View | Annotate | Download (12.3 KB)

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

    
25
import java.awt.BorderLayout;
26
import java.awt.Component;
27
import java.awt.Font;
28
import java.awt.GridBagConstraints;
29
import java.awt.GridBagLayout;
30
import java.awt.Insets;
31
import java.util.ArrayList;
32
import java.util.List;
33

    
34
import javax.swing.JLabel;
35
import javax.swing.JOptionPane;
36
import javax.swing.JPanel;
37

    
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

    
41
import org.gvsig.andami.IconThemeHelper;
42
import org.gvsig.andami.PluginServices;
43
import org.gvsig.andami.messages.NotificationManager;
44
import org.gvsig.andami.plugins.IExtension;
45
import org.gvsig.andami.plugins.status.IExtensionStatus;
46
import org.gvsig.andami.plugins.status.IUnsavedData;
47
import org.gvsig.andami.plugins.status.UnsavedData;
48
import org.gvsig.andami.ui.mdiManager.IWindow;
49
import org.gvsig.app.ApplicationLocator;
50
import org.gvsig.app.project.Project;
51
import org.gvsig.app.project.ProjectManager;
52
import org.gvsig.app.project.documents.Document;
53
import org.gvsig.app.project.documents.table.TableDocument;
54
import org.gvsig.app.project.documents.table.TableManager;
55
import org.gvsig.app.project.documents.table.gui.FeatureTableDocumentPanel;
56
import org.gvsig.fmap.dal.EditingNotification;
57
import org.gvsig.fmap.dal.EditingNotificationManager;
58
import org.gvsig.fmap.dal.exception.DataException;
59
import org.gvsig.fmap.dal.exception.ReadException;
60
import org.gvsig.fmap.dal.exception.WriteException;
61
import org.gvsig.fmap.dal.feature.FeatureStore;
62
import org.gvsig.fmap.dal.swing.DALSwingLocator;
63
import org.gvsig.gui.beans.Messages;
64
import org.gvsig.tools.util.ArrayUtils;
65
import org.gvsig.utils.swing.threads.IMonitorableTask;
66

    
67
public class TableEditStopExtension extends AbstractTableEditExtension {
68

    
69
    private static Logger logger
70
            = LoggerFactory.getLogger(TableEditStopExtension.class);
71

    
72
    @Override
73
    public void initialize() {
74
        super.initialize();
75
        IconThemeHelper.registerIcon("action", "table-stop-editing", this);
76
    }
77

    
78
    public void execute(String actionCommand) {
79
        this.execute(actionCommand,null);
80
    }
81

    
82
    @Override
83
    public void execute(String actionCommand, Object[] args) {
84
        if ("table-stop-editing".equals(actionCommand)) {
85
            TableDocument doc = (TableDocument)ArrayUtils.get(args,0);
86
            if( doc == null ) {
87
                doc = (TableDocument) table.getDocument();
88
            }    
89
            EditingNotificationManager editingNotification = DALSwingLocator.getEditingNotificationManager();
90
            EditingNotification notification = editingNotification.notifyObservers(
91
                    this,
92
                    EditingNotification.BEFORE_ENTER_EDITING_STORE,
93
                    doc,
94
                    doc.getStore());
95
            if (notification.isCanceled()) {
96
                return;
97
            }
98
            stopEditing(table);
99
            ApplicationLocator.getManager().refreshMenusAndToolBars();
100
            editingNotification.notifyObservers(
101
                    this,
102
                    EditingNotification.AFTER_ENTER_EDITING_STORE,
103
                    doc,
104
                    doc.getStore());
105
        }
106
    }
107

    
108
    private void stopEditing(FeatureTableDocumentPanel table) {
109

    
110
        Object[] options = {
111
            PluginServices.getText(this, "_Guardar"),
112
            "       " + PluginServices.getText(this, "_Descartar") + "       ",
113
            PluginServices.getText(this, "_Continuar")};
114

    
115
        JPanel explanation_panel = getExplanationPanel(table.getModel().getName());
116

    
117
        int resp = JOptionPane
118
                .showOptionDialog(
119
                        (Component) PluginServices.getMainFrame(),
120
                        explanation_panel,
121
                        PluginServices.getText(this, "stop_edition"),
122
                        JOptionPane.YES_NO_CANCEL_OPTION,
123
                        JOptionPane.QUESTION_MESSAGE, null, options,
124
                        options[2]);
125

    
126
        try {
127
            if (resp == JOptionPane.NO_OPTION) {
128
                // CANCEL EDITING
129
                table.getModel().getStore().cancelEditing();
130
            } else {
131

    
132
                if (resp == JOptionPane.YES_OPTION) {
133
                    // Save table
134
                    table.getModel().getStore().finishEditing();
135
                } else {
136
                    // This happens when user clicks on [x]
137
                    // to abruptly close previous JOptionPane dialog
138
                    // We do nothing (equivalent to 'Continue editing')
139
                }
140
            }
141
        } catch (DataException e) {
142
            logger.error("While finishing or canceling table editing: "
143
                    + e.getMessage(), e);
144
        }
145
    }
146

    
147
    public boolean isEnabled() {
148
        return true;
149
    }
150

    
151
    @Override
152
    public boolean isVisible() {
153
        IWindow v = PluginServices.getMDIManager().getActiveWindow();
154

    
155
        if (v == null) {
156
            return false;
157
        } else if (v instanceof FeatureTableDocumentPanel
158
                && ((FeatureTableDocumentPanel) v).getModel().getStore()
159
                .isEditing()) {
160
            table = (FeatureTableDocumentPanel) v;
161
            return true;
162
        } else {
163
            return false;
164
        }
165
    }
166

    
167
    /**
168
     * <p>
169
     * This class provides the status of extensions. If this extension has some
170
     * unsaved editing table (and save them), and methods to check if the
171
     * extension has some associated background tasks.
172
     *
173
     */
174
    private class StopEditingStatus implements IExtensionStatus {
175

    
176
        /**
177
         * This method is used to check if this extension has some unsaved
178
         * editing tables.
179
         *
180
         * @return true if the extension has some unsaved editing tables, false
181
         * otherwise.
182
         */
183
        public boolean hasUnsavedData() {
184
            Project project = ProjectManager.getInstance().getCurrentProject();
185
            List<Document> tables = project.getDocuments(TableManager.TYPENAME);
186
            for (int i = 0; i < tables.size(); i++) {
187
                FeatureStore store = ((TableDocument) tables.get(i)).getStore();
188
                if (store == null) {
189
                    continue;
190
                }
191
                if (store.isEditing()) {
192
                    return true;
193
                }
194
            }
195
            return false;
196
        }
197

    
198
        /**
199
         * This method is used to check if the extension has some associated
200
         * background process which is currently running.
201
         *
202
         * @return true if the extension has some associated background process,
203
         * false otherwise.
204
         */
205
        public boolean hasRunningProcesses() {
206
            return false;
207
        }
208

    
209
        /**
210
         * <p>
211
         * Gets an array of the traceable background tasks associated with this
212
         * extension. These tasks may be tracked, canceled, etc.
213
         * </p>
214
         *
215
         * @return An array of the associated background tasks, or null in case
216
         * there is no associated background tasks.
217
         */
218
        public IMonitorableTask[] getRunningProcesses() {
219
            return null;
220
        }
221

    
222
        /**
223
         * <p>
224
         * Gets an array of the UnsavedData objects, which contain information
225
         * about the unsaved editing tables and allows to save it.
226
         * </p>
227
         *
228
         * @return An array of the associated unsaved editing layers, or null in
229
         * case the extension has not unsaved editing tables.
230
         */
231
        public IUnsavedData[] getUnsavedData() {
232
            Project project = ProjectManager.getInstance().getCurrentProject();
233
            List<Document> tables = project.getDocuments(TableManager.TYPENAME);
234
            List<UnsavedTable> unsavedTables = new ArrayList<UnsavedTable>();
235
            for (int i = 0; i < tables.size(); i++) {
236
                TableDocument table = (TableDocument) tables.get(i);
237
                FeatureStore store = table.getStore();
238
                if (store == null) {
239
                    continue;
240
                }
241
                if (store.isEditing()) {
242
                    UnsavedTable ul
243
                            = new UnsavedTable(TableEditStopExtension.this);
244
                    ul.setTable(table);
245
                    unsavedTables.add(ul);
246
                }
247
            }
248
            return unsavedTables
249
                    .toArray(new IUnsavedData[unsavedTables.size()]);
250
        }
251
    }
252

    
253
    private class UnsavedTable extends UnsavedData {
254

    
255
        private TableDocument table;
256

    
257
        public UnsavedTable(IExtension extension) {
258
            super(extension);
259
        }
260

    
261
        public String getDescription() {
262
            return PluginServices.getText(this, "editing_table_unsaved");
263
        }
264

    
265
        public String getResourceName() {
266
            return table.getName();
267
        }
268

    
269
        public boolean saveData() {
270
            return executeSaveTable(table);
271
        }
272

    
273
        public void setTable(TableDocument table) {
274
            this.table = table;
275
        }
276

    
277
        @Override
278
        public String getIcon() {
279
            return "document-table-icon-small";
280
        }
281
    }
282

    
283
    // TODO Este codigo esta duplicado, tambien esta en la clase Table en el
284
    // metodo "public void stopEditing()"
285
    private boolean executeSaveTable(TableDocument table2) {
286
        FeatureStore fs = table2.getStore();
287
        if (fs.isEditing()) {
288
            try {
289
                fs.finishEditing();
290
            } catch (WriteException e) {
291
                NotificationManager.addError(PluginServices.getText(this, "error_saving_table"), e);
292
                return false;
293
            } catch (ReadException e) {
294
                NotificationManager.addError(PluginServices.getText(this, "error_saving_table"), e);
295
                return false;
296
            } catch (DataException e) {
297
                NotificationManager.addError(PluginServices.getText(this, "error_saving_table"), e);
298
                return false;
299
            }
300
        }
301
        return true;
302
    }
303

    
304
    @Override
305
    public IExtensionStatus getStatus() {
306
        return new StopEditingStatus();
307
    }
308

    
309
    private JPanel getExplanationPanel(String name) {
310

    
311
        BorderLayout bl = new BorderLayout(10, 10);
312
        JPanel resp = new JPanel(bl);
313

    
314
        String msg = Messages.getText("realmente_desea_guardar");
315
        JLabel topLabel = new JLabel(msg);
316

    
317
        JPanel mainPanel = new JPanel(new GridBagLayout());
318
        GridBagConstraints cc = new GridBagConstraints();
319

    
320
        cc.gridx = 0;
321
        cc.gridy = 0;
322
        cc.anchor = GridBagConstraints.WEST;
323

    
324
        cc.insets = new Insets(3, 6, 3, 6);
325

    
326
        Font boldf = mainPanel.getFont().deriveFont(Font.BOLD);
327

    
328
        JLabel lbl = new JLabel(Messages.getText("_Guardar"));
329
        lbl.setFont(boldf);
330
        mainPanel.add(lbl, cc);
331
        cc.gridx = 1;
332
        mainPanel.add(new JLabel(Messages.getText("_Save_changes_performed")), cc);
333

    
334
        cc.gridx = 0;
335
        cc.gridy = 1;
336
        lbl = new JLabel(Messages.getText("_Descartar"));
337
        lbl.setFont(boldf);
338
        mainPanel.add(lbl, cc);
339
        cc.gridx = 1;
340
        mainPanel.add(new JLabel(Messages.getText("_Discard_and_lose_changes")), cc);
341

    
342
        cc.gridx = 0;
343
        cc.gridy = 2;
344
        lbl = new JLabel(Messages.getText("_Continuar"));
345
        lbl.setFont(boldf);
346
        mainPanel.add(lbl, cc);
347
        cc.gridx = 1;
348
        mainPanel.add(new JLabel(Messages.getText("_Do_not_save_yet_Stay_in_editing_mode")), cc);
349

    
350
        resp.add(mainPanel, BorderLayout.CENTER);
351
        resp.add(topLabel, BorderLayout.NORTH);
352
        return resp;
353
    }
354
}