Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / extension / ProjectExtension.java @ 44535

History | View | Annotate | Download (30.6 KB)

1 40558 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40558 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8 40558 jjdelcerro
 * as published by the Free Software Foundation; either version 3
9 40435 jjdelcerro
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21 40558 jjdelcerro
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24
package org.gvsig.app.extension;
25
26
import java.awt.Component;
27 43506 jjdelcerro
import java.awt.geom.AffineTransform;
28
import java.awt.image.AffineTransformOp;
29
import java.awt.image.BufferedImage;
30 40435 jjdelcerro
import java.io.File;
31 43506 jjdelcerro
import java.io.IOException;
32 40435 jjdelcerro
import java.text.MessageFormat;
33
import java.util.ArrayList;
34
import java.util.Iterator;
35
import java.util.List;
36 42711 fdiaz
import java.util.Set;
37 40435 jjdelcerro
import java.util.prefs.Preferences;
38 43820 jjdelcerro
import java.util.zip.ZipFile;
39 40435 jjdelcerro
40
import javax.swing.JOptionPane;
41 43439 jjdelcerro
import org.apache.commons.collections.CollectionUtils;
42 44088 omartinez
import org.apache.commons.io.FilenameUtils;
43 40435 jjdelcerro
44
import org.slf4j.Logger;
45
import org.slf4j.LoggerFactory;
46 42200 fdiaz
47 41312 jjdelcerro
import org.gvsig.tools.util.ArrayUtils;
48 42200 fdiaz
49 41312 jjdelcerro
import org.apache.commons.lang.StringUtils;
50 42200 fdiaz
51 40435 jjdelcerro
import org.gvsig.andami.IconThemeHelper;
52
import org.gvsig.andami.Launcher;
53
import org.gvsig.andami.Launcher.TerminationProcess;
54
import org.gvsig.andami.PluginServices;
55 41312 jjdelcerro
import org.gvsig.andami.PluginsLocator;
56 43913 jjdelcerro
import org.gvsig.andami.PluginsManager;
57 41312 jjdelcerro
import org.gvsig.andami.actioninfo.ActionInfo;
58
import org.gvsig.andami.actioninfo.ActionInfoManager;
59 40435 jjdelcerro
import org.gvsig.andami.plugins.Extension;
60
import org.gvsig.andami.plugins.IExtension;
61
import org.gvsig.andami.plugins.status.IExtensionStatus;
62
import org.gvsig.andami.plugins.status.IUnsavedData;
63
import org.gvsig.andami.plugins.status.UnsavedData;
64
import org.gvsig.andami.ui.mdiManager.IWindow;
65
import org.gvsig.andami.ui.mdiManager.WindowInfo;
66
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
67 42711 fdiaz
import org.gvsig.app.ApplicationLocator;
68
import org.gvsig.app.ApplicationManager;
69 43506 jjdelcerro
import org.gvsig.app.gui.ProjectPreviewPanel;
70 40435 jjdelcerro
import org.gvsig.app.project.Project;
71
import org.gvsig.app.project.ProjectManager;
72
import org.gvsig.app.project.documents.gui.ProjectWindow;
73 43913 jjdelcerro
import org.gvsig.app.project.documents.gui.projectpanel.ProjectDocumentsPanelPageFactory;
74 40435 jjdelcerro
import org.gvsig.app.project.documents.view.ViewManager;
75 44237 jjdelcerro
import org.gvsig.filedialogchooser.FileDialogChooser;
76
import org.gvsig.filedialogchooser.FileDialogChooserManager;
77
import static org.gvsig.fmap.dal.serverexplorer.filesystem.swing.FilesystemExplorerWizardPanelController.OPEN_LAYER_FILE_CHOOSER_ID;
78 40435 jjdelcerro
import org.gvsig.gui.beans.swing.JFileChooser;
79 43913 jjdelcerro
import org.gvsig.propertypage.PropertiesPageManager;
80 40435 jjdelcerro
import org.gvsig.tools.ToolsLocator;
81 41312 jjdelcerro
import org.gvsig.tools.dataTypes.DataTypes;
82 40435 jjdelcerro
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
83 42711 fdiaz
import org.gvsig.tools.i18n.I18nManager;
84 43913 jjdelcerro
import org.gvsig.tools.util.ToolsUtilLocator;
85 40435 jjdelcerro
import org.gvsig.utils.GenericFileFilter;
86
import org.gvsig.utils.save.AfterSavingListener;
87
import org.gvsig.utils.save.BeforeSavingListener;
88
import org.gvsig.utils.save.SaveEvent;
89
import org.gvsig.utils.swing.threads.IMonitorableTask;
90
91
/**
92
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
93 41076 jjdelcerro
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos en
94
 * esta clase.
95 42200 fdiaz
 *
96 40435 jjdelcerro
 */
97
public class ProjectExtension extends Extension implements IExtensionStatus {
98
99 44231 jjdelcerro
    private static final Logger LOG = LoggerFactory
100
            .getLogger(ProjectExtension.class);
101 40435 jjdelcerro
102 44231 jjdelcerro
    private static String projectPath = null;
103
    private ProjectWindow projectFrame;
104
    private Project p;
105
    private String lastSavePath;
106
    private WindowInfo seedProjectWindow;
107
    public static final String PROJECT_FILE_CHOOSER_ID = "PROJECT_FILECHOOSER_ID";
108
    /**
109
     * Use UTF-8 for encoding, as it can represent characters from any language.
110
     *
111
     * Another sensible option would be encoding =
112
     * System.getProperty("file.encoding"); but this would need some extra
113
     * testing.
114
     *
115
     * @deprecated see PersistentManager
116
     */
117
    public static String PROJECTENCODING = "UTF-8";
118 40435 jjdelcerro
119 44231 jjdelcerro
    private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
120 40435 jjdelcerro
121 44231 jjdelcerro
    private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
122 42200 fdiaz
123 44231 jjdelcerro
    @Override
124
    public void initialize() {
125
        initializeDocumentActionsExtensionPoint();
126
        registerDocuments();
127
        registerIcons();
128 43913 jjdelcerro
129 44231 jjdelcerro
        PropertiesPageManager propertiesManager = ToolsUtilLocator.getPropertiesPageManager();
130
        propertiesManager.registerFactory(new ProjectDocumentsPanelPageFactory());
131
132
        File projectFile = getProjectFileFromArguments();
133
        if (projectFile != null) {
134
            // Posponemos la apertura del proyecto ya que en este momento
135
            // puede que no este inicializado algun plugin que precise el
136
            // proyecto para poderse cargar.
137
            PluginsLocator.getManager().addStartupTask(
138 41312 jjdelcerro
                    "Open project",
139 41314 jjdelcerro
                    new OpenInitialProjectTask(projectFile), true, 1000);
140 41312 jjdelcerro
        }
141 44231 jjdelcerro
    }
142 40435 jjdelcerro
143 44231 jjdelcerro
    private void registerIcons() {
144
        IconThemeHelper.registerIcon("action", "application-project-new", this);
145
        IconThemeHelper
146
                .registerIcon("action", "application-project-open", this);
147
        IconThemeHelper
148
                .registerIcon("action", "application-project-save", this);
149
        IconThemeHelper.registerIcon("action", "application-project-save-as",
150
                this);
151 40435 jjdelcerro
152 44231 jjdelcerro
        IconThemeHelper.registerIcon("project", "project-icon", this);
153
    }
154 40435 jjdelcerro
155 44231 jjdelcerro
    /**
156
     * Returns the file to be opened or null if no parameter or file does not
157
     * exist
158
     *
159
     * @return
160
     */
161
    private File getProjectFileFromArguments() {
162
        String[] theArgs = PluginServices.getArguments();
163
        if (theArgs.length < 3) {
164
            // application-name and extensions-folder are fixed arguments
165
            return null;
166 42200 fdiaz
        }
167 44231 jjdelcerro
        String lastArg = theArgs[theArgs.length - 1];
168
        if (StringUtils.isEmpty(lastArg)) {
169
            return null;
170
        }
171
        if (lastArg.startsWith("-")) {
172
            // Args starts with "-" are flags
173
            return null;
174
        }
175
        if (!lastArg.toLowerCase().endsWith(Project.FILE_EXTENSION.toLowerCase())) {
176
            LOG.info("Do not open project file, does not have the expected extension '"
177
                    + Project.FILE_EXTENSION + "' (" + lastArg + ").");
178
            return null;
179
        }
180
        File projectFile = new File(lastArg);
181
        if (!projectFile.exists()) {
182
            LOG.info("Do not open project file, '" + projectFile.getAbsolutePath() + "' do not exist.");
183
            return null;
184
        }
185
        return projectFile;
186
    }
187 41314 jjdelcerro
188 44231 jjdelcerro
    private class OpenInitialProjectTask implements Runnable {
189
190
        private File projectFile;
191
192
        public OpenInitialProjectTask(File projectFile) {
193
            this.projectFile = projectFile;
194
        }
195
196
        @Override
197
        public void run() {
198
            if (this.projectFile == null) {
199
                return;
200 41314 jjdelcerro
            }
201 44231 jjdelcerro
            ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
202
            ActionInfo action = actionManager.getAction("application-project-open");
203
            action.execute(this.projectFile);
204 41312 jjdelcerro
        }
205 44231 jjdelcerro
    }
206 40435 jjdelcerro
207 44231 jjdelcerro
    public ProjectWindow getProjectFrame() {
208
        if (projectFrame == null) {
209
            projectFrame = new ProjectWindow();
210
        }
211
        return projectFrame;
212
    }
213 40435 jjdelcerro
214 44231 jjdelcerro
    /**
215
     * Muestra la ventana con el gestor de proyectos.
216
     */
217
    public void showProjectWindow() {
218
        if (seedProjectWindow != null) {
219
            if (seedProjectWindow.isClosed()) {
220
                // if it was closed, we just don't open the window now
221
                seedProjectWindow.setClosed(false);
222
                return;
223
            }
224
            WindowInfo winProps = seedProjectWindow;
225
            seedProjectWindow = null;
226
            PluginServices.getMDIManager().addWindow(getProjectFrame());
227
            PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
228
                    winProps);
229
        } else {
230
            PluginServices.getMDIManager().addWindow(getProjectFrame());
231
        }
232
    }
233 40435 jjdelcerro
234 44231 jjdelcerro
    /**
235
     * Muestra la ventana con el gestor de proyectos, con las propiedades de
236
     * ventana especificadas.
237
     */
238
    public void showProjectWindow(WindowInfo wi) {
239
        seedProjectWindow = wi;
240
        showProjectWindow();
241
    }
242 40435 jjdelcerro
243 44231 jjdelcerro
    /**
244
     * Guarda el proyecto actual en disco.
245
     */
246
    private boolean saveProject() {
247
        boolean saved = false;
248
        // if (p.getPath() == null) {
249
        if (projectPath == null) {
250
            saved = saveAsProject(null);
251
        } else {
252
            long t1, t2;
253
            t1 = System.currentTimeMillis();
254
            saved = writeProject(new File(projectPath), p, false);
255
            t2 = System.currentTimeMillis();
256
            PluginServices.getLogger().info(
257
                    "Project saved. " + (t2 - t1) + " miliseconds");
258
            getProjectFrame().setProject(p);
259
        }
260
        return saved;
261
    }
262 40435 jjdelcerro
263 44231 jjdelcerro
    private boolean saveAsProject(File file) {
264
        boolean saved = false;
265 40435 jjdelcerro
266 44231 jjdelcerro
        if (lastSavePath == null) {
267
            lastSavePath = projectPath;
268
        }
269 40435 jjdelcerro
270 44231 jjdelcerro
        if (file == null) {
271 44237 jjdelcerro
            FileDialogChooserManager fileDialogChooserManager = ToolsUtilLocator.getFileDialogChooserManager();
272
            FileDialogChooser jfc = fileDialogChooserManager.create(PROJECT_FILE_CHOOSER_ID);
273 44231 jjdelcerro
            jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
274 42200 fdiaz
275 44231 jjdelcerro
            GenericFileFilter projExtensionFilter = new GenericFileFilter(
276
                    Project.FILE_EXTENSION, MessageFormat.format(PluginServices
277
                            .getText(this, "tipo_fichero_proyecto"),
278
                            Project.FILE_EXTENSION));
279
            jfc.addChoosableFileFilter(projExtensionFilter);
280
            jfc.setFileFilter(projExtensionFilter);
281 40435 jjdelcerro
282 44231 jjdelcerro
            if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
283
                return saved;
284
            }
285
            file = jfc.getSelectedFile();
286
        }
287 40435 jjdelcerro
288 44231 jjdelcerro
        if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
289
                .toLowerCase()))) {
290
            file = new File(file.getPath() + Project.FILE_EXTENSION);
291
        }
292
        saved = writeProject(file, p);
293
        String filePath = file.getAbsolutePath();
294
        lastSavePath = filePath.substring(0,
295
                filePath.lastIndexOf(File.separatorChar));
296 40435 jjdelcerro
297 44231 jjdelcerro
        getProjectFrame().setProject(p);
298
        return saved;
299
    }
300 40435 jjdelcerro
301 44231 jjdelcerro
    /**
302
     * Checks whether the project and related unsaved data is modified, and
303
     * allows the user to save it.
304
     *
305
     * @return true if the data has been correctly saved, false otherwise
306
     */
307
    private boolean askSave() {
308
        if (p != null && p.hasChanged()) {
309
            TerminationProcess process = Launcher.getTerminationProcess();
310
            UnsavedDataPanel panel = process.getUnsavedDataPanel();
311
            panel.setHeaderText(PluginServices.getText(this,
312
                    "_Select_resources_to_save_before_closing_current_project"));
313
            panel.setAcceptText(
314
                    PluginServices.getText(this, "save_resources"),
315
                    PluginServices
316
                            .getText(this,
317
                                    "Save_the_selected_resources_and_close_current_project"));
318
            panel.setCancelText(PluginServices.getText(this, "Cancel"),
319
                    PluginServices.getText(this, "Return_to_current_project"));
320
            int closeCurrProj;
321
            try {
322
                closeCurrProj = process.manageUnsavedData();
323
                if (closeCurrProj == JOptionPane.NO_OPTION) {
324
                    // the user chose to return to current project
325
                    return false;
326
                }
327
            } catch (Exception e) {
328
                LOG.error("Some data can not be saved", e);
329
            }
330
        }
331
        return true;
332
    }
333 40435 jjdelcerro
334 44231 jjdelcerro
    @Override
335
    public void execute(String command) {
336
        this.execute(command, null);
337
    }
338 42200 fdiaz
339 44231 jjdelcerro
    @Override
340 43293 fdiaz
    public void execute(String actionCommand, Object[] args) {
341
        if (actionCommand.equals("application-project-new")) {
342
            if (!askSave()) {
343
                return;
344
            }
345 40435 jjdelcerro
346 43293 fdiaz
            projectPath = null;
347
            PluginServices.getMDIManager().closeAllWindows();
348
            setProject(ProjectManager.getInstance().createProject());
349 41312 jjdelcerro
350 43293 fdiaz
            showProjectWindow();
351
            PluginServices.getMainFrame().setTitle(PluginServices.getText(this, "sin_titulo"));
352 40435 jjdelcerro
353 43293 fdiaz
        } else if (actionCommand.equals("application-project-open")) {
354
            if (!askSave()) {
355
                return;
356
            }
357 42200 fdiaz
358 43293 fdiaz
            setProject(ProjectManager.getInstance().createProject());
359 40893 jjdelcerro
360 43293 fdiaz
            File projectFile = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
361
            if (projectFile != null && !projectFile.exists()) {
362
                LOG.warn("Can't load project '" + projectFile.getAbsolutePath() + "', file not exist.");
363
                projectFile = null;
364
            }
365 40435 jjdelcerro
366 43293 fdiaz
            if (projectFile == null) {
367 44237 jjdelcerro
                FileDialogChooserManager fileDialogChooserManager = ToolsUtilLocator.getFileDialogChooserManager();
368
                FileDialogChooser jfc = fileDialogChooserManager.create(PROJECT_FILE_CHOOSER_ID);
369 43506 jjdelcerro
                ProjectPreviewPanel preview = new ProjectPreviewPanel();
370
                jfc.setAccessory(preview);
371 44231 jjdelcerro
                jfc.addPropertyChangeListener(preview);
372 42200 fdiaz
373 44231 jjdelcerro
                GenericFileFilter projExtensionFilter
374
                        = new GenericFileFilter(Project.FILE_EXTENSION, PluginServices.getText(this, "tipo_fichero_proyecto"));
375 43293 fdiaz
                jfc.addChoosableFileFilter(projExtensionFilter);
376 44231 jjdelcerro
                GenericFileFilter bakExtensionFilter
377
                        = new GenericFileFilter(Project.FILE_BAK, PluginServices.getText(this, "tipo_fichero_proyecto_bak"));
378 44088 omartinez
                jfc.addChoosableFileFilter(bakExtensionFilter);
379 43293 fdiaz
                jfc.setFileFilter(projExtensionFilter);
380 42200 fdiaz
381 43293 fdiaz
                if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
382
                    return;
383
                }
384
                // ProjectDocument.initializeNUMS();
385 40435 jjdelcerro
386 43293 fdiaz
                projectFile = jfc.getSelectedFile();
387
            }
388 40435 jjdelcerro
389 43293 fdiaz
            PluginServices.getMDIManager().closeAllWindows();
390 40435 jjdelcerro
391 43293 fdiaz
            Project o = readProject(projectFile);
392 44088 omartinez
            if ("bak".equals(FilenameUtils.getExtension(projectFile.getAbsolutePath()))) {
393
                setPath(null);
394
            } else {
395
                setPath(projectFile.getAbsolutePath());
396
            }
397 43293 fdiaz
            // lastPath = getPath();
398
            if (o != null) {
399
                setProject(o);
400
            }
401 40435 jjdelcerro
402 43293 fdiaz
            getProjectFrame().setProject(p);
403
            PluginServices.getMainFrame().setTitle(projectFile.getName());
404 43913 jjdelcerro
//            getProjectFrame().refreshControls();
405 43293 fdiaz
406
            // p.restoreWindowProperties();
407
        } else if (actionCommand.equals("application-project-save")) {
408
            // saveProject();
409
            try {
410 42200 fdiaz
                Launcher.manageUnsavedData("there_are_unsaved_resources");
411
            } catch (Exception e) {
412
                LOG.warn("Can't manage unsaved data", e);
413
            }
414 43293 fdiaz
        } else if (actionCommand.equals("application-project-save-as")) {
415
            File file = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
416
            saveAsProject(file);
417
        }
418 40435 jjdelcerro
419 43293 fdiaz
    }
420 40435 jjdelcerro
421 41217 jldominguez
    private void createEmptyProject() {
422
        setProject(ProjectManager.getInstance().createProject());
423
        p.setName(PluginServices.getText(this, "untitled"));
424
        p.setModified(false);
425
        PluginServices.getMainFrame().setTitle(
426
                PluginServices.getText(this, "sin_titulo"));
427
        setProject(p);
428
        showProjectWindow();
429
    }
430
431 43913 jjdelcerro
    @Override
432 41217 jldominguez
    public void postInitialize() {
433 43913 jjdelcerro
        PluginsManager pluginsManager = PluginsLocator.getManager();
434
        pluginsManager.addStartupTask(
435 44231 jjdelcerro
                "createEmptyProject",
436 43913 jjdelcerro
                new Runnable() {
437 44231 jjdelcerro
            @Override
438
            public void run() {
439
                createEmptyProject();
440
            }
441
        },
442
                true,
443 43942 jjdelcerro
                1000
444 43913 jjdelcerro
        );
445 42200 fdiaz
    }
446
447 44231 jjdelcerro
    /**
448
     * Escribe el proyecto en XML.
449
     *
450
     * @param file Fichero.
451
     * @param p Proyecto.
452
     */
453
    public boolean writeProject(File file, Project p) {
454
        return writeProject(file, p, true);
455
    }
456 42200 fdiaz
457 43820 jjdelcerro
    /**
458 44231 jjdelcerro
     * Escribe el proyecto en disco. Pero permite decidir si se pide
459
     * confirmaci?n para sobreescribir
460 43820 jjdelcerro
     *
461
     * @param file Fichero.
462
     * @param p Proyecto.
463
     * @param askConfirmation boolean
464
     * @return
465
     */
466 44231 jjdelcerro
    public boolean writeProject(File file, Project p, boolean askConfirmation) {
467 43820 jjdelcerro
        I18nManager i18n = ToolsLocator.getI18nManager();
468
        ApplicationManager application = ApplicationLocator.getManager();
469
        if (askConfirmation && file.exists()) {
470
            int resp = application.confirmDialog(
471 44231 jjdelcerro
                    i18n.getTranslation("fichero_ya_existe_seguro_desea_guardarlo"),
472
                    i18n.getTranslation("guardar"),
473
                    JOptionPane.YES_NO_OPTION,
474
                    JOptionPane.QUESTION_MESSAGE,
475 43820 jjdelcerro
                    "Overwrite_project_file"
476
            );
477
            if (resp != JOptionPane.YES_OPTION) {
478
                return false;
479
            }
480
        }
481 44231 jjdelcerro
        LOG.info("Writing project '" + file.getAbsolutePath() + "'.");
482 43820 jjdelcerro
        try {
483 44231 jjdelcerro
            fireBeforeSavingFileEvent(new SaveEvent(this, SaveEvent.BEFORE_SAVING, file));
484 43506 jjdelcerro
            BufferedImage img = ApplicationLocator.getManager().getUIManager().getImagePreview();
485
            img = scale(img, 0.40);
486 44231 jjdelcerro
            p.saveState(file, img);
487 43820 jjdelcerro
488
            PluginServices.getMainFrame().setTitle(file.getName());
489
            setPath(file.toString());
490 40435 jjdelcerro
491 43820 jjdelcerro
        } catch (Exception e) {
492
            application.messageDialog(
493 44231 jjdelcerro
                    i18n.getTranslation("_Problems_saving_the_project_XnlX_It_is_possible_that_this_was_not_saved_properly_and_can_not_be_loaded_again"),
494
                    null,
495
                    i18n.getTranslation("guardar"),
496
                    JOptionPane.ERROR_MESSAGE,
497 43820 jjdelcerro
                    "Problems_saving_the_project"
498
            );
499 44231 jjdelcerro
            LOG.warn("Error writing project '" + file.getAbsolutePath() + "'.", e);
500 43820 jjdelcerro
            return false;
501 44231 jjdelcerro
        }
502
        LOG.warn("Wrote project '" + file.getAbsolutePath() + "'.");
503 43820 jjdelcerro
        return true;
504
    }
505 40435 jjdelcerro
506 43820 jjdelcerro
    boolean isValidZIP(final File file) {
507
        ZipFile zipfile = null;
508
        try {
509
            zipfile = new ZipFile(file);
510
            return true;
511
        } catch (IOException e) {
512
            return false;
513
        } finally {
514
            try {
515
                if (zipfile != null) {
516
                    zipfile.close();
517
                    zipfile = null;
518
                }
519
            } catch (IOException e) {
520
            }
521
        }
522
    }
523 40435 jjdelcerro
524 43506 jjdelcerro
    private BufferedImage scale(BufferedImage before, double factor) {
525 44231 jjdelcerro
        int w = (int) (before.getWidth() * factor);
526
        int h = (int) (before.getHeight() * factor);
527 43506 jjdelcerro
        BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
528
        AffineTransform at = new AffineTransform();
529
        at.scale(factor, factor);
530
        AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
531 44231 jjdelcerro
        after = scaleOp.filter(before, after);
532 43506 jjdelcerro
        return after;
533
    }
534 40435 jjdelcerro
535 44231 jjdelcerro
    public Project readProject(String path) {
536
        Project project = ProjectManager.getInstance().createProject();
537 40435 jjdelcerro
538 44231 jjdelcerro
        project.loadState(new File(path));
539
        return (Project) project;
540
    }
541 40435 jjdelcerro
542 44231 jjdelcerro
    /**
543
     * Lee del XML el proyecto.<br>
544
     * <br>
545
     *
546
     * Reads the XML of the project.<br>
547
     * It returns a project object holding all needed info that is not linked to
548
     * the Project Dialog. <br>
549
     * In case you want the project to be linked to the window you must set this
550
     * object to the extension:<br>
551
     *
552
     * <b>Example:</b><br>
553
     *
554
     * ...<br>
555
     * .
556
     * ..<br>
557
     * Project p = ProjectExtension.readProject(projectFile);<br>
558
     * ProjectExtension.setProject(p); ...<br>
559
     * .
560
     * ..<br>
561
     *
562
     * @param file Fichero.
563
     *
564
     * @return Project
565
     *
566
     */
567
    public Project readProject(File file) {
568
        Project project = ProjectManager.getInstance().createProject();
569
570
        project.loadState(file);
571
        Set<String> unloadedObjects = project.getUnloadedObjects();
572 43439 jjdelcerro
        List<Exception> errors = project.getLoadErrors();
573 44231 jjdelcerro
574
        if (!CollectionUtils.isEmpty(unloadedObjects)) {
575
            StringBuilder builder = new StringBuilder();
576
            builder.append("Unloaded elements loading the project:\n");
577
            Iterator<String> it = unloadedObjects.iterator();
578
            while (it.hasNext()) {
579 42711 fdiaz
                builder.append("\t");
580 44231 jjdelcerro
                builder.append(it.next());
581
                builder.append("\n");
582
            }
583 42711 fdiaz
584 44231 jjdelcerro
            LOG.warn(builder.toString());
585 43439 jjdelcerro
        }
586 44231 jjdelcerro
        if (!CollectionUtils.isEmpty(unloadedObjects) || !CollectionUtils.isEmpty(errors)) {
587
            ApplicationManager application = ApplicationLocator.getManager();
588
            I18nManager i18nManager = ToolsLocator.getI18nManager();
589 42711 fdiaz
590 44231 jjdelcerro
            application.messageDialog(
591
                    i18nManager.getTranslation("_some_project_elements_could_not_be_loaded") + "\n"
592
                    + i18nManager.getTranslation("_maybe_you_need_to_install_any_plugins") + "\n"
593
                    + i18nManager.getTranslation("_Recovered_data_may_be_corrupted") + "\n\n"
594
                    + i18nManager.getTranslation("_see_error_log_for_more_information"),
595
                    i18nManager.getTranslation("warning"),
596
                    JOptionPane.WARNING_MESSAGE);
597 42711 fdiaz
598 44231 jjdelcerro
        } else {
599
600 43439 jjdelcerro
        }
601 44231 jjdelcerro
        return (Project) project;
602
    }
603 40435 jjdelcerro
604 44231 jjdelcerro
    /**
605
     * Devuelve el proyecto.
606
     *
607
     * @return Proyecto.
608
     */
609
    public Project getProject() {
610
        return p;
611
    }
612 40435 jjdelcerro
613 44231 jjdelcerro
    /**
614
     * @see org.gvsig.andami.plugins.IExtension#isEnabled()
615
     */
616
    public boolean isEnabled() {
617
        return true;
618
    }
619 40435 jjdelcerro
620 44231 jjdelcerro
    /**
621
     * @see org.gvsig.andami.plugins.IExtension#isVisible()
622
     */
623
    public boolean isVisible() {
624
        return true;
625
    }
626 40435 jjdelcerro
627 44231 jjdelcerro
    /**
628
     * Sets the project
629
     *
630
     * @param p
631
     */
632
    public void setProject(Project p) {
633
        this.p = p;
634
        getProjectFrame().setProject(p);
635
    }
636 40435 jjdelcerro
637 44231 jjdelcerro
    private void registerDocuments() {
638
        ViewManager.register();
639
    }
640 40435 jjdelcerro
641 44231 jjdelcerro
    private void initializeDocumentActionsExtensionPoint() {
642
        ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
643
        epMan.add(
644
                "DocumentActions_View",
645
                "Context menu options of the view document list"
646
                + " in the project window "
647
                + "(register instances of "
648
                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
649
    }
650 40435 jjdelcerro
651 44231 jjdelcerro
    public static String getPath() {
652
        return projectPath;
653
    }
654 40435 jjdelcerro
655 44231 jjdelcerro
    public static void setPath(String path) {
656
        projectPath = path;
657
    }
658 40435 jjdelcerro
659 44231 jjdelcerro
    public IWindow getProjectWindow() {
660
        return getProjectFrame();
661
    }
662 40435 jjdelcerro
663 44231 jjdelcerro
    @Override
664
    public IExtensionStatus getStatus() {
665
        return this;
666
    }
667 40435 jjdelcerro
668 44231 jjdelcerro
    @Override
669
    public boolean hasUnsavedData() {
670
        return p.hasChanged();
671
    }
672 40435 jjdelcerro
673 44231 jjdelcerro
    @Override
674
    public IUnsavedData[] getUnsavedData() {
675
        if (hasUnsavedData()) {
676
            UnsavedProject data = new UnsavedProject(this);
677
            IUnsavedData[] dataArray = {data};
678
            return dataArray;
679
        } else {
680
            return null;
681
        }
682
    }
683 40435 jjdelcerro
684 44231 jjdelcerro
    /**
685
     * Implements the IUnsavedData interface to show unsaved projects in the
686
     * Unsavad Data dialog.
687
     *
688
     * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
689
     */
690
    public class UnsavedProject extends UnsavedData {
691 40435 jjdelcerro
692 44231 jjdelcerro
        public UnsavedProject(IExtension extension) {
693
            super(extension);
694
        }
695 40435 jjdelcerro
696 44231 jjdelcerro
        @Override
697
        public String getDescription() {
698
            if (getPath() == null) {
699
                return PluginServices.getText(ProjectExtension.this,
700
                        "Unnamed_new_gvsig_project_");
701
            } else {
702
                return PluginServices.getText(ProjectExtension.this,
703
                        "Modified_project_");
704
            }
705
        }
706 40435 jjdelcerro
707 44231 jjdelcerro
        @Override
708
        public String getResourceName() {
709
            if (getPath() == null) {
710
                return PluginServices.getText(ProjectExtension.this, "Unnamed");
711
            } else {
712
                return getPath();
713
            }
714 40435 jjdelcerro
715 44231 jjdelcerro
        }
716 40435 jjdelcerro
717 44088 omartinez
        @Override
718 44231 jjdelcerro
        public boolean saveData() {
719
            return saveProject();
720
        }
721 40435 jjdelcerro
722 44088 omartinez
        @Override
723 44231 jjdelcerro
        public String getIcon() {
724
            return "project-icon";
725
        }
726
    }
727 40435 jjdelcerro
728 44231 jjdelcerro
    @Override
729
    public IMonitorableTask[] getRunningProcesses() {
730
        // TODO Auto-generated method stub
731
        return null;
732
    }
733 40435 jjdelcerro
734 44231 jjdelcerro
    @Override
735
    public boolean hasRunningProcesses() {
736
        // TODO Auto-generated method stub
737
        return false;
738
    }
739 40435 jjdelcerro
740 44231 jjdelcerro
    /**
741
     * Adds the specified before saving listener to receive "before saving file
742
     * events" from this component. If l is null, no exception is thrown and no
743
     * action is performed.
744
     *
745
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
746
     *
747
     * @param l the before saving listener.
748
     * @see SaveEvent
749
     * @see BeforeSavingListener
750
     * @see #removeListener(BeforeSavingListener)
751
     * @see #getBeforeSavingListeners
752
     */
753
    public synchronized void addListener(BeforeSavingListener l) {
754
        if (l == null) {
755
            return;
756
        }
757
        if (!this.beforeSavingListeners.contains(l)) {
758
            this.beforeSavingListeners.add(l);
759
        }
760
    }
761 40435 jjdelcerro
762 44231 jjdelcerro
    /**
763
     * Adds the specified after saving listener to receive "after saving file
764
     * events" from this component. If l is null, no exception is thrown and no
765
     * action is performed.
766
     *
767
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
768
     *
769
     * @param l the after saving listener.
770
     * @see SaveEvent
771
     * @see AfterSavingListener
772
     * @see #removeListener(AfterSavingListener)
773
     * @see #getAfterSavingListeners()
774
     */
775
    public synchronized void addListener(AfterSavingListener l) {
776
        if (l == null) {
777
            return;
778
        }
779 40435 jjdelcerro
780 44231 jjdelcerro
        if (!this.afterSavingListeners.contains(l)) {
781
            this.afterSavingListeners.add(l);
782
        }
783 40435 jjdelcerro
784 44231 jjdelcerro
    }
785 40435 jjdelcerro
786 44231 jjdelcerro
    /**
787
     * Returns an array of all the before saving listeners registered on this
788
     * component.
789
     *
790
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
791
     *
792
     * @return all of this component's <code>BeforeSavingListener</code>s or an
793
     * empty array if no key listeners are currently registered
794
     *
795
     * @see #addBeforeSavingListener(BeforeSavingListener)
796
     * @see #removeBeforeSavingListener(BeforeSavingListener)
797
     */
798
    public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
799
        return this.beforeSavingListeners
800
                .toArray(new BeforeSavingListener[]{});
801
    }
802 40435 jjdelcerro
803 44231 jjdelcerro
    /**
804
     * Returns an array of all the after saving listeners registered on this
805
     * component.
806
     *
807
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
808
     *
809
     * @return all of this component's <code>AfterSavingListener</code>s or an
810
     * empty array if no key listeners are currently registered
811
     *
812
     * @see #addAfterSavingListener(AfterSavingListener)
813
     * @see #removeAfterSavingListener
814
     */
815
    public synchronized AfterSavingListener[] getAfterSavingListeners() {
816
        return this.afterSavingListeners.toArray(new AfterSavingListener[]{});
817 40435 jjdelcerro
818 44231 jjdelcerro
    }
819 40435 jjdelcerro
820 44231 jjdelcerro
    /**
821
     * Removes the specified before saving listener so that it no longer
822
     * receives save file events from this component. This method performs no
823
     * function, nor does it throw an exception, if the listener specified by
824
     * the argument was not previously added to this component. If listener
825
     * <code>l</code> is <code>null</code>, no exception is thrown and no action
826
     * is performed.
827
     *
828
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
829
     *
830
     * @param l the before saving listener
831
     * @see SaveEvent
832
     * @see BeforeSavingListener
833
     * @see #addListener(BeforeSavingListener)
834
     * @see #getBeforeSavingListeners()
835
     */
836
    public synchronized void removeListener(BeforeSavingListener l) {
837
        if (l == null) {
838
            return;
839
        }
840 41076 jjdelcerro
841 44231 jjdelcerro
        this.beforeSavingListeners.remove(l);
842
    }
843 41076 jjdelcerro
844 44231 jjdelcerro
    /**
845
     * Removes the specified after saving listener so that it no longer receives
846
     * save file events from this component. This method performs no function,
847
     * nor does it throw an exception, if the listener specified by the argument
848
     * was not previously added to this component. If listener <code>l</code> is
849
     * <code>null</code>, no exception is thrown and no action is performed.
850
     *
851
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
852
     *
853
     * @param l the after saving listener
854
     * @see SaveEvent
855
     * @see AfterSavingListener
856
     * @see #addListener(AfterSavingListener)
857
     * @see #getAfterSavingListeners()
858
     */
859
    public synchronized void removeListener(AfterSavingListener l) {
860
        if (l == null) {
861
            return;
862
        }
863 41076 jjdelcerro
864 44231 jjdelcerro
        this.afterSavingListeners.remove(l);
865
    }
866 41076 jjdelcerro
867 44231 jjdelcerro
    /**
868
     * Reports a before saving file event.
869
     *
870
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
871
     *
872
     * @param evt the before saving file event
873
     */
874
    protected void fireBeforeSavingFileEvent(SaveEvent evt) {
875
        if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
876
            return;
877
        }
878 41076 jjdelcerro
879 44231 jjdelcerro
        Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
880
                .iterator();
881 41076 jjdelcerro
882 44231 jjdelcerro
        while (iter.hasNext()) {
883
            iter.next().beforeSaving(evt);
884
        }
885
    }
886 41076 jjdelcerro
887 44231 jjdelcerro
    /**
888
     * Reports a after saving file event.
889
     *
890
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
891
     *
892
     * @param evt the after saving file event
893
     */
894
    protected void fireAfterSavingFileEvent(SaveEvent evt) {
895
        if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
896
            return;
897
        }
898
        Iterator<AfterSavingListener> iter = this.afterSavingListeners
899
                .iterator();
900
901
        while (iter.hasNext()) {
902
            iter.next().afterSaving(evt);
903
        }
904
905
    }
906 40435 jjdelcerro
}