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

History | View | Annotate | Download (28.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
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.gui.beans.swing.JFileChooser;
76
import org.gvsig.propertypage.PropertiesPageManager;
77
import org.gvsig.tools.ToolsLocator;
78
import org.gvsig.tools.dataTypes.DataTypes;
79
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
80
import org.gvsig.tools.i18n.I18nManager;
81
import org.gvsig.tools.util.ToolsUtilLocator;
82
import org.gvsig.utils.GenericFileFilter;
83
import org.gvsig.utils.save.AfterSavingListener;
84
import org.gvsig.utils.save.BeforeSavingListener;
85
import org.gvsig.utils.save.SaveEvent;
86
import org.gvsig.utils.swing.threads.IMonitorableTask;
87

    
88

    
89
/**
90
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
91
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos en
92
 * esta clase.
93
 *
94
 */
95
public class ProjectExtension extends Extension implements IExtensionStatus {
96
        private static final Logger LOG = LoggerFactory
97
                        .getLogger(ProjectExtension.class);
98

    
99
        private static String projectPath = null;
100
        private ProjectWindow projectFrame;
101
        private Project p;
102
        private String lastSavePath;
103
        private WindowInfo seedProjectWindow;
104
        public static final String PROJECT_FILE_CHOOSER_ID = "PROJECT_FILECHOOSER_ID";
105
        /**
106
         * Use UTF-8 for encoding, as it can represent characters from any language.
107
         *
108
         * Another sensible option would be encoding =
109
         * System.getProperty("file.encoding"); but this would need some extra
110
         * testing.
111
         *
112
         * @deprecated see PersistentManager
113
         */
114
        public static String PROJECTENCODING = "UTF-8";
115

    
116
        private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
117

    
118
        private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
119

    
120
        @Override
121
        public void initialize() {
122
            initializeDocumentActionsExtensionPoint();
123
            registerDocuments();
124
            registerIcons();
125

    
126
            PropertiesPageManager propertiesManager = ToolsUtilLocator.getPropertiesPageManager();
127
            propertiesManager.registerFactory(new ProjectDocumentsPanelPageFactory());
128

    
129
            File projectFile = getProjectFileFromArguments();
130
            if( projectFile!=null ) {
131
                // Posponemos la apertura del proyecto ya que en este momento
132
                // puede que no este inicializado algun plugin que precise el
133
                // proyecto para poderse cargar.
134
                PluginsLocator.getManager().addStartupTask(
135
                    "Open project",
136
                    new OpenInitialProjectTask(projectFile), true, 1000);
137
            }
138
        }
139

    
140
        private void registerIcons() {
141
                IconThemeHelper.registerIcon("action", "application-project-new", this);
142
                IconThemeHelper
143
                                .registerIcon("action", "application-project-open", this);
144
                IconThemeHelper
145
                                .registerIcon("action", "application-project-save", this);
146
                IconThemeHelper.registerIcon("action", "application-project-save-as",
147
                                this);
148

    
149
                IconThemeHelper.registerIcon("project", "project-icon", this);
150
        }
151

    
152
        /**
153
         * Returns the file to be opened or null if no parameter
154
         * or file does not exist
155
         *
156
         * @return
157
         */
158
        private File getProjectFileFromArguments() {
159
            String[] theArgs = PluginServices.getArguments();
160
            if( theArgs.length< 3 ) {
161
                // application-name and extensions-folder are fixed arguments
162
                return null;
163
            }
164
            String lastArg = theArgs[theArgs.length - 1];
165
            if ( StringUtils.isEmpty(lastArg) ) {
166
                return null;
167
            }
168
            if( lastArg.startsWith("-") ) {
169
                // Args starts with "-" are flags
170
                return null;
171
            }
172
            if (!lastArg.toLowerCase().endsWith(Project.FILE_EXTENSION.toLowerCase())) {
173
                LOG.info("Do not open project file, does not have the expected extension '" +
174
                        Project.FILE_EXTENSION +"' ("+lastArg+").");
175
                return null;
176
            }
177
            File projectFile = new File(lastArg);
178
            if ( !projectFile.exists()) {
179
                LOG.info("Do not open project file, '" +projectFile.getAbsolutePath() + "' do not exist.");
180
                return null;
181
            }
182
            return projectFile;
183
        }
184

    
185
        private class OpenInitialProjectTask implements Runnable {
186
            private File projectFile;
187
            public OpenInitialProjectTask(File projectFile) {
188
                this.projectFile = projectFile;
189
            }
190
            @Override
191
            public void run() {
192
                if (this.projectFile == null) {
193
                    return;
194
                }
195
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
196
                ActionInfo action = actionManager.getAction("application-project-open");
197
                action.execute(this.projectFile);
198
            }
199
        }
200

    
201
        public ProjectWindow getProjectFrame() {
202
                if (projectFrame == null) {
203
                        projectFrame = new ProjectWindow();
204
                }
205
                return projectFrame;
206
        }
207

    
208
        /**
209
         * Muestra la ventana con el gestor de proyectos.
210
         */
211
        public void showProjectWindow() {
212
                if (seedProjectWindow != null) {
213
                        if (seedProjectWindow.isClosed()) {
214
                                // if it was closed, we just don't open the window now
215
                                seedProjectWindow.setClosed(false);
216
                                return;
217
                        }
218
                        WindowInfo winProps = seedProjectWindow;
219
                        seedProjectWindow = null;
220
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
221
                        PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
222
                                        winProps);
223
                } else {
224
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
225
                }
226
        }
227

    
228
        /**
229
         * Muestra la ventana con el gestor de proyectos, con las propiedades de
230
         * ventana especificadas.
231
         */
232
        public void showProjectWindow(WindowInfo wi) {
233
                seedProjectWindow = wi;
234
                showProjectWindow();
235
        }
236

    
237
        /**
238
         * Guarda el proyecto actual en disco.
239
         */
240
        private boolean saveProject() {
241
                boolean saved = false;
242
                // if (p.getPath() == null) {
243
                if (projectPath == null) {
244
                        saved = saveAsProject(null);
245
                } else {
246
                        long t1, t2;
247
                        t1 = System.currentTimeMillis();
248
                        saved = writeProject(new File(projectPath), p, false);
249
                        t2 = System.currentTimeMillis();
250
                        PluginServices.getLogger().info(
251
                                        "Project saved. " + (t2 - t1) + " miliseconds");
252
                        getProjectFrame().setProject(p);
253
                }
254
                return saved;
255
        }
256

    
257
        private boolean saveAsProject(File file) {
258
                boolean saved = false;
259

    
260
                if (lastSavePath == null) {
261
                        lastSavePath = projectPath;
262
                }
263

    
264
                if (file == null) {
265
                        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
266
                        JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID,
267
                                        prefs.get("ProjectsFolder", null));
268

    
269
                        jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
270

    
271
                        GenericFileFilter projExtensionFilter = new GenericFileFilter(
272
                                        Project.FILE_EXTENSION, MessageFormat.format(PluginServices
273
                                                        .getText(this, "tipo_fichero_proyecto"),
274
                                                        Project.FILE_EXTENSION));
275
      jfc.addChoosableFileFilter(projExtensionFilter);
276
      jfc.setFileFilter(projExtensionFilter);
277

    
278
                        if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
279
                                return saved;
280
                        }
281
                        file = jfc.getSelectedFile();
282
                }
283

    
284
                if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
285
                                .toLowerCase()))) {
286
                        file = new File(file.getPath() + Project.FILE_EXTENSION);
287
                }
288
                saved = writeProject(file, p);
289
                String filePath = file.getAbsolutePath();
290
                lastSavePath = filePath.substring(0,
291
                                filePath.lastIndexOf(File.separatorChar));
292

    
293
                getProjectFrame().setProject(p);
294
                return saved;
295
        }
296

    
297
        /**
298
         * Checks whether the project and related unsaved data is modified, and
299
         * allows the user to save it.
300
         *
301
         * @return true if the data has been correctly saved, false otherwise
302
         */
303
        private boolean askSave() {
304
                if (p != null && p.hasChanged()) {
305
                        TerminationProcess process = Launcher.getTerminationProcess();
306
                        UnsavedDataPanel panel = process.getUnsavedDataPanel();
307
                        panel.setHeaderText(PluginServices.getText(this,
308
                                        "_Select_resources_to_save_before_closing_current_project"));
309
                        panel.setAcceptText(
310
                                        PluginServices.getText(this, "save_resources"),
311
                                        PluginServices
312
                                                        .getText(this,
313
                                                                        "Save_the_selected_resources_and_close_current_project"));
314
                        panel.setCancelText(PluginServices.getText(this, "Cancel"),
315
                                        PluginServices.getText(this, "Return_to_current_project"));
316
                        int closeCurrProj;
317
                        try {
318
                                closeCurrProj = process.manageUnsavedData();
319
                                if (closeCurrProj == JOptionPane.NO_OPTION) {
320
                                        // the user chose to return to current project
321
                                        return false;
322
                                }
323
                        } catch (Exception e) {
324
                                LOG.error("Some data can not be saved", e);
325
                        }
326
                }
327
                return true;
328
        }
329

    
330
        @Override
331
        public void execute(String command) {
332
                this.execute(command, null);
333
        }
334

    
335
        @Override
336
    public void execute(String actionCommand, Object[] args) {
337
        if (actionCommand.equals("application-project-new")) {
338
            if (!askSave()) {
339
                return;
340
            }
341

    
342
            projectPath = null;
343
            PluginServices.getMDIManager().closeAllWindows();
344
            setProject(ProjectManager.getInstance().createProject());
345

    
346
            showProjectWindow();
347
            PluginServices.getMainFrame().setTitle(PluginServices.getText(this, "sin_titulo"));
348

    
349
        } else if (actionCommand.equals("application-project-open")) {
350
            if (!askSave()) {
351
                return;
352
            }
353

    
354
            setProject(ProjectManager.getInstance().createProject());
355

    
356
            File projectFile = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
357
            if (projectFile != null && !projectFile.exists()) {
358
                LOG.warn("Can't load project '" + projectFile.getAbsolutePath() + "', file not exist.");
359
                projectFile = null;
360
            }
361

    
362
            if (projectFile == null) {
363
                Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
364
                JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get("ProjectsFolder", null));
365
                ProjectPreviewPanel preview = new ProjectPreviewPanel();
366
                jfc.setAccessory(preview);
367
                jfc.addPropertyChangeListener(preview);                
368

    
369
                GenericFileFilter projExtensionFilter =
370
                    new GenericFileFilter(Project.FILE_EXTENSION, PluginServices.getText(this, "tipo_fichero_proyecto"));
371
                jfc.addChoosableFileFilter(projExtensionFilter);
372
                GenericFileFilter bakExtensionFilter =
373
                    new GenericFileFilter(Project.FILE_BAK, PluginServices.getText(this, "tipo_fichero_proyecto_bak"));
374
                jfc.addChoosableFileFilter(bakExtensionFilter);
375
                jfc.setFileFilter(projExtensionFilter);
376

    
377
                if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
378
                    return;
379
                }
380
                // ProjectDocument.initializeNUMS();
381

    
382
                projectFile = jfc.getSelectedFile();
383
            }
384

    
385
            PluginServices.getMDIManager().closeAllWindows();
386

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

    
398
            getProjectFrame().setProject(p);
399
            PluginServices.getMainFrame().setTitle(projectFile.getName());
400
//            getProjectFrame().refreshControls();
401

    
402
            // p.restoreWindowProperties();
403

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

    
416
    }
417

    
418

    
419
    private void createEmptyProject() {
420
        setProject(ProjectManager.getInstance().createProject());
421
        p.setName(PluginServices.getText(this, "untitled"));
422
        p.setModified(false);
423
        PluginServices.getMainFrame().setTitle(
424
                PluginServices.getText(this, "sin_titulo"));
425
        setProject(p);
426
        showProjectWindow();
427
    }
428

    
429
    @Override
430
    public void postInitialize() {
431
        PluginsManager pluginsManager = PluginsLocator.getManager();
432
        pluginsManager.addStartupTask(
433
                "createEmptyProject", 
434
                new Runnable() {
435
                    @Override
436
                    public void run() {
437
                        createEmptyProject();
438
                    }
439
                }, 
440
                true, 
441
                1000
442
        );
443
    }
444

    
445

    
446
        /**
447
         * Escribe el proyecto en XML.
448
         *
449
         * @param file
450
         *            Fichero.
451
         * @param p
452
         *            Proyecto.
453
         */
454
        public boolean writeProject(File file, Project p) {
455
                return writeProject(file, p, true);
456
        }
457

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

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

    
492
        } catch (Exception e) {
493
            application.messageDialog(
494
                    i18n.getTranslation("_Problems_saving_the_project_XnlX_It_is_possible_that_this_was_not_saved_properly_and_can_not_be_loaded_again"), 
495
                    null, 
496
                    i18n.getTranslation("guardar"), 
497
                    JOptionPane.ERROR_MESSAGE, 
498
                    "Problems_saving_the_project"
499
            );
500
            LOG.warn("Error writing project '"+file.getAbsolutePath()+"'.", e);
501
            return false;
502
        }        
503
        LOG.warn("Wrote project '"+file.getAbsolutePath()+"'.");
504
        return true;
505
    }
506

    
507
    boolean isValidZIP(final File file) {
508
        ZipFile zipfile = null;
509
        try {
510
            zipfile = new ZipFile(file);
511
            return true;
512
        } catch (IOException e) {
513
            return false;
514
        } finally {
515
            try {
516
                if (zipfile != null) {
517
                    zipfile.close();
518
                    zipfile = null;
519
                }
520
            } catch (IOException e) {
521
            }
522
        }
523
    }
524

    
525
    private BufferedImage scale(BufferedImage before, double factor) {
526
        int w = (int) (before.getWidth()*factor);
527
        int h = (int) (before.getHeight()*factor);
528
        BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
529
        AffineTransform at = new AffineTransform();
530
        at.scale(factor, factor);
531
        AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
532
        after = scaleOp.filter(before, after);        
533
        return after;
534
    }
535
    
536
        public Project readProject(String path) {
537
                Project project = ProjectManager.getInstance().createProject();
538

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

    
543
        /**
544
         * Lee del XML el proyecto.<br>
545
         * <br>
546
         *
547
         * Reads the XML of the project.<br>
548
         * It returns a project object holding all needed info that is not linked to
549
         * the Project Dialog. <br>
550
         * In case you want the project to be linked to the window you must set this
551
         * object to the extension:<br>
552
         *
553
         * <b>Example:</b><br>
554
         *
555
         * ...<br>
556
         * ...<br>
557
         * Project p = ProjectExtension.readProject(projectFile);<br>
558
         * ProjectExtension.setProject(p); ...<br>
559
         * ...<br>
560
         *
561
         * @param file
562
         *            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
742
         * "before saving file events" from this component. If l is null, no
743
         * exception is thrown and no action is performed.
744
         *
745
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
746
         *
747
         * @param l
748
         *            the before saving listener.
749
         * @see SaveEvent
750
         * @see BeforeSavingListener
751
         * @see #removeListener(BeforeSavingListener)
752
         * @see #getBeforeSavingListeners
753
         */
754
        public synchronized void addListener(BeforeSavingListener l) {
755
                if (l == null) {
756
                        return;
757
                }
758
                if (!this.beforeSavingListeners.contains(l)) {
759
                        this.beforeSavingListeners.add(l);
760
                }
761
        }
762

    
763
        /**
764
         * Adds the specified after saving listener to receive
765
         * "after saving file events" from this component. If l is null, no
766
         * exception is thrown and no action is performed.
767
         *
768
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
769
         *
770
         * @param l
771
         *            the after saving listener.
772
         * @see SaveEvent
773
         * @see AfterSavingListener
774
         * @see #removeListener(AfterSavingListener)
775
         * @see #getAfterSavingListeners()
776
         */
777
        public synchronized void addListener(AfterSavingListener l) {
778
                if (l == null) {
779
                        return;
780
                }
781

    
782
                if (!this.afterSavingListeners.contains(l)) {
783
                        this.afterSavingListeners.add(l);
784
                }
785

    
786
        }
787

    
788
        /**
789
         * Returns an array of all the before saving listeners registered on this
790
         * component.
791
         *
792
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
793
         *
794
         * @return all of this component's <code>BeforeSavingListener</code>s or an
795
         *         empty array if no key listeners are currently registered
796
         *
797
         * @see #addBeforeSavingListener(BeforeSavingListener)
798
         * @see #removeBeforeSavingListener(BeforeSavingListener)
799
         */
800
        public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
801
                return this.beforeSavingListeners
802
                                .toArray(new BeforeSavingListener[] {});
803
        }
804

    
805
        /**
806
         * Returns an array of all the after saving listeners registered on this
807
         * component.
808
         *
809
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
810
         *
811
         * @return all of this component's <code>AfterSavingListener</code>s or an
812
         *         empty array if no key listeners are currently registered
813
         *
814
         * @see #addAfterSavingListener(AfterSavingListener)
815
         * @see #removeAfterSavingListener
816
         */
817
        public synchronized AfterSavingListener[] getAfterSavingListeners() {
818
                return this.afterSavingListeners.toArray(new AfterSavingListener[] {});
819

    
820
        }
821

    
822
        /**
823
         * Removes the specified before saving listener so that it no longer
824
         * receives save file events from this component. This method performs no
825
         * function, nor does it throw an exception, if the listener specified by
826
         * the argument was not previously added to this component. If listener
827
         * <code>l</code> is <code>null</code>, no exception is thrown and no action
828
         * is performed.
829
         *
830
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
831
         *
832
         * @param l
833
         *            the before saving listener
834
         * @see SaveEvent
835
         * @see BeforeSavingListener
836
         * @see #addListener(BeforeSavingListener)
837
         * @see #getBeforeSavingListeners()
838
         */
839
        public synchronized void removeListener(BeforeSavingListener l) {
840
                if (l == null) {
841
                        return;
842
                }
843

    
844
                this.beforeSavingListeners.remove(l);
845
        }
846

    
847
        /**
848
         * Removes the specified after saving listener so that it no longer receives
849
         * save file events from this component. This method performs no function,
850
         * nor does it throw an exception, if the listener specified by the argument
851
         * was not previously added to this component. If listener <code>l</code> is
852
         * <code>null</code>, no exception is thrown and no action is performed.
853
         *
854
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
855
         *
856
         * @param l
857
         *            the after saving listener
858
         * @see SaveEvent
859
         * @see AfterSavingListener
860
         * @see #addListener(AfterSavingListener)
861
         * @see #getAfterSavingListeners()
862
         */
863
        public synchronized void removeListener(AfterSavingListener l) {
864
                if (l == null) {
865
                        return;
866
                }
867

    
868
                this.afterSavingListeners.remove(l);
869
        }
870

    
871
        /**
872
         * Reports a before saving file event.
873
         *
874
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
875
         *
876
         * @param evt
877
         *            the before saving file event
878
         */
879
        protected void fireBeforeSavingFileEvent(SaveEvent evt) {
880
                if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
881
                        return;
882
                }
883

    
884
                Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
885
                                .iterator();
886

    
887
                while (iter.hasNext()) {
888
                        iter.next().beforeSaving(evt);
889
                }
890
        }
891

    
892
        /**
893
         * Reports a after saving file event.
894
         *
895
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
896
         *
897
         * @param evt
898
         *            the after saving file event
899
         */
900
        protected void fireAfterSavingFileEvent(SaveEvent evt) {
901
                if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
902
                        return;
903
                }
904
                Iterator<AfterSavingListener> iter = this.afterSavingListeners
905
                                .iterator();
906

    
907
                while (iter.hasNext()) {
908
                        iter.next().afterSaving(evt);
909
                }
910

    
911
        }
912
}