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

History | View | Annotate | Download (30.6 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
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * 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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.app.extension;
25

    
26
import java.awt.Component;
27
import java.awt.geom.AffineTransform;
28
import java.awt.image.AffineTransformOp;
29
import java.awt.image.BufferedImage;
30
import java.io.File;
31
import java.io.IOException;
32
import java.text.MessageFormat;
33
import java.util.ArrayList;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Set;
37
import java.util.prefs.Preferences;
38
import java.util.zip.ZipFile;
39

    
40
import javax.swing.JOptionPane;
41
import org.apache.commons.collections.CollectionUtils;
42
import org.apache.commons.io.FilenameUtils;
43

    
44
import org.slf4j.Logger;
45
import org.slf4j.LoggerFactory;
46

    
47
import org.gvsig.tools.util.ArrayUtils;
48

    
49
import org.apache.commons.lang.StringUtils;
50

    
51
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
import org.gvsig.andami.PluginsLocator;
56
import org.gvsig.andami.PluginsManager;
57
import org.gvsig.andami.actioninfo.ActionInfo;
58
import org.gvsig.andami.actioninfo.ActionInfoManager;
59
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
import org.gvsig.app.ApplicationLocator;
68
import org.gvsig.app.ApplicationManager;
69
import org.gvsig.app.gui.ProjectPreviewPanel;
70
import org.gvsig.app.project.Project;
71
import org.gvsig.app.project.ProjectManager;
72
import org.gvsig.app.project.documents.gui.ProjectWindow;
73
import org.gvsig.app.project.documents.gui.projectpanel.ProjectDocumentsPanelPageFactory;
74
import org.gvsig.app.project.documents.view.ViewManager;
75
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
import org.gvsig.gui.beans.swing.JFileChooser;
79
import org.gvsig.propertypage.PropertiesPageManager;
80
import org.gvsig.tools.ToolsLocator;
81
import org.gvsig.tools.dataTypes.DataTypes;
82
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
83
import org.gvsig.tools.i18n.I18nManager;
84
import org.gvsig.tools.util.ToolsUtilLocator;
85
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
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos en
94
 * esta clase.
95
 *
96
 */
97
public class ProjectExtension extends Extension implements IExtensionStatus {
98

    
99
    private static final Logger LOG = LoggerFactory
100
            .getLogger(ProjectExtension.class);
101

    
102
    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

    
119
    private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
120

    
121
    private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
122

    
123
    @Override
124
    public void initialize() {
125
        initializeDocumentActionsExtensionPoint();
126
        registerDocuments();
127
        registerIcons();
128

    
129
        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
                    "Open project",
139
                    new OpenInitialProjectTask(projectFile), true, 1000);
140
        }
141
    }
142

    
143
    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

    
152
        IconThemeHelper.registerIcon("project", "project-icon", this);
153
    }
154

    
155
    /**
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
        }
167
        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

    
188
    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
            }
201
            ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
202
            ActionInfo action = actionManager.getAction("application-project-open");
203
            action.execute(this.projectFile);
204
        }
205
    }
206

    
207
    public ProjectWindow getProjectFrame() {
208
        if (projectFrame == null) {
209
            projectFrame = new ProjectWindow();
210
        }
211
        return projectFrame;
212
    }
213

    
214
    /**
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

    
234
    /**
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

    
243
    /**
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

    
263
    private boolean saveAsProject(File file) {
264
        boolean saved = false;
265

    
266
        if (lastSavePath == null) {
267
            lastSavePath = projectPath;
268
        }
269

    
270
        if (file == null) {
271
            FileDialogChooserManager fileDialogChooserManager = ToolsUtilLocator.getFileDialogChooserManager();
272
            FileDialogChooser jfc = fileDialogChooserManager.create(PROJECT_FILE_CHOOSER_ID);
273
            jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
274

    
275
            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

    
282
            if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
283
                return saved;
284
            }
285
            file = jfc.getSelectedFile();
286
        }
287

    
288
        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

    
297
        getProjectFrame().setProject(p);
298
        return saved;
299
    }
300

    
301
    /**
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

    
334
    @Override
335
    public void execute(String command) {
336
        this.execute(command, null);
337
    }
338

    
339
    @Override
340
    public void execute(String actionCommand, Object[] args) {
341
        if (actionCommand.equals("application-project-new")) {
342
            if (!askSave()) {
343
                return;
344
            }
345

    
346
            projectPath = null;
347
            PluginServices.getMDIManager().closeAllWindows();
348
            setProject(ProjectManager.getInstance().createProject());
349

    
350
            showProjectWindow();
351
            PluginServices.getMainFrame().setTitle(PluginServices.getText(this, "sin_titulo"));
352

    
353
        } else if (actionCommand.equals("application-project-open")) {
354
            if (!askSave()) {
355
                return;
356
            }
357

    
358
            setProject(ProjectManager.getInstance().createProject());
359

    
360
            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

    
366
            if (projectFile == null) {
367
                FileDialogChooserManager fileDialogChooserManager = ToolsUtilLocator.getFileDialogChooserManager();
368
                FileDialogChooser jfc = fileDialogChooserManager.create(PROJECT_FILE_CHOOSER_ID);
369
                ProjectPreviewPanel preview = new ProjectPreviewPanel();
370
                jfc.setAccessory(preview);
371
                jfc.addPropertyChangeListener(preview);
372

    
373
                GenericFileFilter projExtensionFilter
374
                        = new GenericFileFilter(Project.FILE_EXTENSION, PluginServices.getText(this, "tipo_fichero_proyecto"));
375
                jfc.addChoosableFileFilter(projExtensionFilter);
376
                GenericFileFilter bakExtensionFilter
377
                        = new GenericFileFilter(Project.FILE_BAK, PluginServices.getText(this, "tipo_fichero_proyecto_bak"));
378
                jfc.addChoosableFileFilter(bakExtensionFilter);
379
                jfc.setFileFilter(projExtensionFilter);
380

    
381
                if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
382
                    return;
383
                }
384
                // ProjectDocument.initializeNUMS();
385

    
386
                projectFile = jfc.getSelectedFile();
387
            }
388

    
389
            PluginServices.getMDIManager().closeAllWindows();
390

    
391
            Project o = readProject(projectFile);
392
            if ("bak".equals(FilenameUtils.getExtension(projectFile.getAbsolutePath()))) {
393
                setPath(null);
394
            } else {
395
                setPath(projectFile.getAbsolutePath());
396
            }
397
            // lastPath = getPath();
398
            if (o != null) {
399
                setProject(o);
400
            }
401

    
402
            getProjectFrame().setProject(p);
403
            PluginServices.getMainFrame().setTitle(projectFile.getName());
404
//            getProjectFrame().refreshControls();
405

    
406
            // p.restoreWindowProperties();
407
        } else if (actionCommand.equals("application-project-save")) {
408
            // saveProject();
409
            try {
410
                Launcher.manageUnsavedData("there_are_unsaved_resources");
411
            } catch (Exception e) {
412
                LOG.warn("Can't manage unsaved data", e);
413
            }
414
        } else if (actionCommand.equals("application-project-save-as")) {
415
            File file = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
416
            saveAsProject(file);
417
        }
418

    
419
    }
420

    
421
    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
    @Override
432
    public void postInitialize() {
433
        PluginsManager pluginsManager = PluginsLocator.getManager();
434
        pluginsManager.addStartupTask(
435
                "createEmptyProject",
436
                new Runnable() {
437
            @Override
438
            public void run() {
439
                createEmptyProject();
440
            }
441
        },
442
                true,
443
                1000
444
        );
445
    }
446

    
447
    /**
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

    
457
    /**
458
     * Escribe el proyecto en disco. Pero permite decidir si se pide
459
     * confirmaci?n para sobreescribir
460
     *
461
     * @param file Fichero.
462
     * @param p Proyecto.
463
     * @param askConfirmation boolean
464
     * @return
465
     */
466
    public boolean writeProject(File file, Project p, boolean askConfirmation) {
467
        I18nManager i18n = ToolsLocator.getI18nManager();
468
        ApplicationManager application = ApplicationLocator.getManager();
469
        if (askConfirmation && file.exists()) {
470
            int resp = application.confirmDialog(
471
                    i18n.getTranslation("fichero_ya_existe_seguro_desea_guardarlo"),
472
                    i18n.getTranslation("guardar"),
473
                    JOptionPane.YES_NO_OPTION,
474
                    JOptionPane.QUESTION_MESSAGE,
475
                    "Overwrite_project_file"
476
            );
477
            if (resp != JOptionPane.YES_OPTION) {
478
                return false;
479
            }
480
        }
481
        LOG.info("Writing project '" + file.getAbsolutePath() + "'.");
482
        try {
483
            fireBeforeSavingFileEvent(new SaveEvent(this, SaveEvent.BEFORE_SAVING, file));
484
            BufferedImage img = ApplicationLocator.getManager().getUIManager().getImagePreview();
485
            img = scale(img, 0.40);
486
            p.saveState(file, img);
487

    
488
            PluginServices.getMainFrame().setTitle(file.getName());
489
            setPath(file.toString());
490

    
491
        } catch (Exception e) {
492
            application.messageDialog(
493
                    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
                    "Problems_saving_the_project"
498
            );
499
            LOG.warn("Error writing project '" + file.getAbsolutePath() + "'.", e);
500
            return false;
501
        }
502
        LOG.warn("Wrote project '" + file.getAbsolutePath() + "'.");
503
        return true;
504
    }
505

    
506
    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

    
524
    private BufferedImage scale(BufferedImage before, double factor) {
525
        int w = (int) (before.getWidth() * factor);
526
        int h = (int) (before.getHeight() * factor);
527
        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
        after = scaleOp.filter(before, after);
532
        return after;
533
    }
534

    
535
    public Project readProject(String path) {
536
        Project project = ProjectManager.getInstance().createProject();
537

    
538
        project.loadState(new File(path));
539
        return (Project) project;
540
    }
541

    
542
    /**
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
        List<Exception> errors = project.getLoadErrors();
573

    
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
                builder.append("\t");
580
                builder.append(it.next());
581
                builder.append("\n");
582
            }
583

    
584
            LOG.warn(builder.toString());
585
        }
586
        if (!CollectionUtils.isEmpty(unloadedObjects) || !CollectionUtils.isEmpty(errors)) {
587
            ApplicationManager application = ApplicationLocator.getManager();
588
            I18nManager i18nManager = ToolsLocator.getI18nManager();
589

    
590
            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

    
598
        } else {
599

    
600
        }
601
        return (Project) project;
602
    }
603

    
604
    /**
605
     * Devuelve el proyecto.
606
     *
607
     * @return Proyecto.
608
     */
609
    public Project getProject() {
610
        return p;
611
    }
612

    
613
    /**
614
     * @see org.gvsig.andami.plugins.IExtension#isEnabled()
615
     */
616
    public boolean isEnabled() {
617
        return true;
618
    }
619

    
620
    /**
621
     * @see org.gvsig.andami.plugins.IExtension#isVisible()
622
     */
623
    public boolean isVisible() {
624
        return true;
625
    }
626

    
627
    /**
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

    
637
    private void registerDocuments() {
638
        ViewManager.register();
639
    }
640

    
641
    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

    
651
    public static String getPath() {
652
        return projectPath;
653
    }
654

    
655
    public static void setPath(String path) {
656
        projectPath = path;
657
    }
658

    
659
    public IWindow getProjectWindow() {
660
        return getProjectFrame();
661
    }
662

    
663
    @Override
664
    public IExtensionStatus getStatus() {
665
        return this;
666
    }
667

    
668
    @Override
669
    public boolean hasUnsavedData() {
670
        return p.hasChanged();
671
    }
672

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

    
684
    /**
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

    
692
        public UnsavedProject(IExtension extension) {
693
            super(extension);
694
        }
695

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

    
707
        @Override
708
        public String getResourceName() {
709
            if (getPath() == null) {
710
                return PluginServices.getText(ProjectExtension.this, "Unnamed");
711
            } else {
712
                return getPath();
713
            }
714

    
715
        }
716

    
717
        @Override
718
        public boolean saveData() {
719
            return saveProject();
720
        }
721

    
722
        @Override
723
        public String getIcon() {
724
            return "project-icon";
725
        }
726
    }
727

    
728
    @Override
729
    public IMonitorableTask[] getRunningProcesses() {
730
        // TODO Auto-generated method stub
731
        return null;
732
    }
733

    
734
    @Override
735
    public boolean hasRunningProcesses() {
736
        // TODO Auto-generated method stub
737
        return false;
738
    }
739

    
740
    /**
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

    
762
    /**
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

    
780
        if (!this.afterSavingListeners.contains(l)) {
781
            this.afterSavingListeners.add(l);
782
        }
783

    
784
    }
785

    
786
    /**
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

    
803
    /**
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

    
818
    }
819

    
820
    /**
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

    
841
        this.beforeSavingListeners.remove(l);
842
    }
843

    
844
    /**
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

    
864
        this.afterSavingListeners.remove(l);
865
    }
866

    
867
    /**
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

    
879
        Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
880
                .iterator();
881

    
882
        while (iter.hasNext()) {
883
            iter.next().beforeSaving(evt);
884
        }
885
    }
886

    
887
    /**
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
}