Revision 41076 trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.app/org.gvsig.app.mainplugin/src/main/java/org/gvsig/app/extension/ProjectExtension.java

View differences:

ProjectExtension.java
32 32
import java.util.prefs.Preferences;
33 33

  
34 34
import javax.swing.JOptionPane;
35
import javax.swing.SwingUtilities;
35 36

  
36 37
import org.slf4j.Logger;
37 38
import org.slf4j.LoggerFactory;
38

  
39
import org.apache.commons.io.FilenameUtils;
39 40
import org.gvsig.andami.IconThemeHelper;
40 41
import org.gvsig.andami.Launcher;
41 42
import org.gvsig.andami.Launcher.TerminationProcess;
......
49 50
import org.gvsig.andami.ui.mdiManager.IWindow;
50 51
import org.gvsig.andami.ui.mdiManager.WindowInfo;
51 52
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
53
import org.gvsig.app.ApplicationLocator;
54
import org.gvsig.app.ApplicationManager;
52 55
import org.gvsig.app.project.Project;
53 56
import org.gvsig.app.project.ProjectManager;
54 57
import org.gvsig.app.project.documents.gui.ProjectWindow;
......
65 68

  
66 69
/**
67 70
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
68
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos
69
 * en esta clase.
71
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos en
72
 * esta clase.
70 73
 * 
71 74
 * @author Fernando Gonz?lez Cort?s
72 75
 */
73 76
public class ProjectExtension extends Extension implements IExtensionStatus {
74
    private static final Logger LOG =
75
        LoggerFactory.getLogger(ProjectExtension.class);
76
    
77
    private static String projectPath = null;
78
    private ProjectWindow projectFrame;
79
    private Project p;
80
    private String lastSavePath;
81
    private WindowInfo seedProjectWindow;
82
    public static final String PROJECT_FILE_CHOOSER_ID =
83
        "PROJECT_FILECHOOSER_ID";
84
    /**
85
     * Use UTF-8 for encoding, as it can represent characters from
86
     * any language.
87
     * 
88
     * Another sensible option would be
89
     * encoding = System.getProperty("file.encoding");
90
     * but this would need some extra testing.
91
     * 
92
     * @deprecated see PersistentManager
93
     */
94
    public static String PROJECTENCODING = "UTF-8";
77
	private static final Logger LOG = LoggerFactory
78
			.getLogger(ProjectExtension.class);
95 79

  
96
    private List<BeforeSavingListener> beforeSavingListeners =
97
        new ArrayList<BeforeSavingListener>();
80
	private static String projectPath = null;
81
	private ProjectWindow projectFrame;
82
	private Project p;
83
	private String lastSavePath;
84
	private WindowInfo seedProjectWindow;
85
	public static final String PROJECT_FILE_CHOOSER_ID = "PROJECT_FILECHOOSER_ID";
86
	/**
87
	 * Use UTF-8 for encoding, as it can represent characters from any language.
88
	 * 
89
	 * Another sensible option would be encoding =
90
	 * System.getProperty("file.encoding"); but this would need some extra
91
	 * testing.
92
	 * 
93
	 * @deprecated see PersistentManager
94
	 */
95
	public static String PROJECTENCODING = "UTF-8";
98 96

  
99
    private List<AfterSavingListener> afterSavingListeners =
100
        new ArrayList<AfterSavingListener>();
97
	private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
101 98

  
102
    /**
103
     * @see com.iver.mdiApp.plugins.IExtension#initialize()
104
     */
105
    public void initialize() {
106
//        try {
107
//            Class.forName("javax.media.jai.EnumeratedParameter");
108
//        } catch (ClassNotFoundException e) {
109
//            NotificationManager
110
//                .addError(
111
//                    "La m?quina virtual con la que se ejecuta gvSIG no tiene JAI instalado",
112
//                    e);
113
//        }
99
	private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
114 100

  
115
        initializeDocumentActionsExtensionPoint();
116
        registerIcons();
117
    }
101
	/**
102
	 * @see com.iver.mdiApp.plugins.IExtension#initialize()
103
	 */
104
	public void initialize() {
105
		// try {
106
		// Class.forName("javax.media.jai.EnumeratedParameter");
107
		// } catch (ClassNotFoundException e) {
108
		// NotificationManager
109
		// .addError(
110
		// "La m?quina virtual con la que se ejecuta gvSIG no tiene JAI instalado",
111
		// e);
112
		// }
118 113

  
119
    private void registerIcons() {
120
    	IconThemeHelper.registerIcon("action", "application-project-new", this);
121
    	IconThemeHelper.registerIcon("action", "application-project-open", this);
122
    	IconThemeHelper.registerIcon("action", "application-project-save", this);
123
    	IconThemeHelper.registerIcon("action", "application-project-save-as", this);
124
    	
125
        IconThemeHelper.registerIcon("project", "project-icon", this);
126
    }
114
		initializeDocumentActionsExtensionPoint();
115
		registerIcons();
116
	}
127 117

  
128
    private void loadInitialProject() {
129
        String[] theArgs = PluginServices.getArguments();
130
        String lastArg = theArgs[theArgs.length - 1];
131
        if ((lastArg.toLowerCase().endsWith(Project.FILE_EXTENSION
132
            .toLowerCase()))) {
133
            PluginServices.getLogger().debug(
134
                "Intentando cargar el proyecto " + lastArg);
135
            // File projectFile = new File(lastArg);
136
            setProject(readProject(lastArg));
137
            
138
            int last_bar = lastArg.lastIndexOf(File.separator);
139
            String tit = lastArg.substring(last_bar);
140
            
141
            PluginServices.getMainFrame().setTitle(tit);
142
            projectPath = lastArg;
143
        } else {
144
            setProject(ProjectManager.getInstance().createProject());
145
            p.setName(PluginServices.getText(this, "untitled"));
146
            p.setModified(false);
147
            PluginServices.getMainFrame().setTitle(
148
                PluginServices.getText(this, "sin_titulo"));
149
        }
118
	private void registerIcons() {
119
		IconThemeHelper.registerIcon("action", "application-project-new", this);
120
		IconThemeHelper
121
				.registerIcon("action", "application-project-open", this);
122
		IconThemeHelper
123
				.registerIcon("action", "application-project-save", this);
124
		IconThemeHelper.registerIcon("action", "application-project-save-as",
125
				this);
150 126

  
151
    }
127
		IconThemeHelper.registerIcon("project", "project-icon", this);
128
	}
152 129

  
153
    /**
154
     * @see com.iver.mdiApp.plugins.IExtension#postInitialize()
155
     */
156
    public void postInitialize() {
157
        registerDocuments();
158
        loadInitialProject();
159
        getProjectFrame().setProject(p);
160
        showProjectWindow();
161
    }
130
	private void loadInitialProject() {
131
		String[] theArgs = PluginServices.getArguments();
132
		String lastArg = theArgs[theArgs.length - 1];
133
		if (lastArg != null) {
134
			if (lastArg.toLowerCase().endsWith(
135
					Project.FILE_EXTENSION.toLowerCase())) {
136
				LOG.info("Loading project '" + lastArg + "'.");
137
				try {
138
					File projectFile = new File(lastArg);
139
					setProject(readProject(projectFile));
140
					PluginServices.getMainFrame().setTitle(
141
							projectFile.getName());
142
					projectPath = projectFile.getAbsolutePath();
143
					return;
144
				} catch (Exception ex) {
145
					LOG.warn("Can't load project from file '" + lastArg + "'.",
146
							ex);
147
					ApplicationManager application = ApplicationLocator
148
							.getManager();
149
					application.messageDialog("_Can_not_open_the_project",
150
							"_Open_project", JOptionPane.WARNING_MESSAGE);
151
				}
152
			}
153
		}
154
		setProject(ProjectManager.getInstance().createProject());
155
		p.setName(PluginServices.getText(this, "untitled"));
156
		p.setModified(false);
157
		PluginServices.getMainFrame().setTitle(
158
				PluginServices.getText(this, "sin_titulo"));
159
		setProject(p);
160
		showProjectWindow();
161
	}
162 162

  
163
    public ProjectWindow getProjectFrame() {
164
        if (projectFrame == null) {
165
            projectFrame = new ProjectWindow();
166
        }
167
        return projectFrame;
168
    }
163
	/**
164
	 * @see com.iver.mdiApp.plugins.IExtension#postInitialize()
165
	 */
166
	public void postInitialize() {
167
		registerDocuments();
168
		SwingUtilities.invokeLater(new Runnable() {
169
			public void run() {
170
				loadInitialProject();
171
			}
172
		});
173
	}
169 174

  
170
    /**
171
     * Muestra la ventana con el gestor de proyectos.
172
     */
173
    public void showProjectWindow() {
174
        if (seedProjectWindow != null) {
175
            if (seedProjectWindow.isClosed()) {
176
                // if it was closed, we just don't open the window now
177
                seedProjectWindow.setClosed(false);
178
                return;
179
            }
180
            WindowInfo winProps = seedProjectWindow;
181
            seedProjectWindow = null;
182
            PluginServices.getMDIManager().addWindow(getProjectFrame());
183
            PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
184
                winProps);
185
        } else {
186
            PluginServices.getMDIManager().addWindow(getProjectFrame());
187
        }
188
    }
175
	public ProjectWindow getProjectFrame() {
176
		if (projectFrame == null) {
177
			projectFrame = new ProjectWindow();
178
		}
179
		return projectFrame;
180
	}
189 181

  
190
    /**
191
     * Muestra la ventana con el gestor de proyectos, con las propiedades
192
     * de ventana especificadas.
193
     */
194
    public void showProjectWindow(WindowInfo wi) {
195
        seedProjectWindow = wi;
196
        showProjectWindow();
197
    }
182
	/**
183
	 * Muestra la ventana con el gestor de proyectos.
184
	 */
185
	public void showProjectWindow() {
186
		if (seedProjectWindow != null) {
187
			if (seedProjectWindow.isClosed()) {
188
				// if it was closed, we just don't open the window now
189
				seedProjectWindow.setClosed(false);
190
				return;
191
			}
192
			WindowInfo winProps = seedProjectWindow;
193
			seedProjectWindow = null;
194
			PluginServices.getMDIManager().addWindow(getProjectFrame());
195
			PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
196
					winProps);
197
		} else {
198
			PluginServices.getMDIManager().addWindow(getProjectFrame());
199
		}
200
	}
198 201

  
199
    /**
200
     * Guarda el proyecto actual en disco.
201
     */
202
    private boolean guardar() {
203
        boolean saved = false;
204
        // if (p.getPath() == null) {
205
        if (projectPath == null) {
206
            saved = guardarDialogo();
207
        } else {
208
            long t1, t2;
209
            t1 = System.currentTimeMillis();
210
            saved = writeProject(new File(projectPath), p, false);
211
            t2 = System.currentTimeMillis();
212
            PluginServices.getLogger().info(
213
                "Project saved. " + (t2 - t1) + " miliseconds");
214
            getProjectFrame().refreshControls();
215
        }
216
        return saved;
217
    }
202
	/**
203
	 * Muestra la ventana con el gestor de proyectos, con las propiedades de
204
	 * ventana especificadas.
205
	 */
206
	public void showProjectWindow(WindowInfo wi) {
207
		seedProjectWindow = wi;
208
		showProjectWindow();
209
	}
218 210

  
219
    private boolean guardarDialogo() {
220
        boolean saved = false;
211
	/**
212
	 * Guarda el proyecto actual en disco.
213
	 */
214
	private boolean saveProject() {
215
		boolean saved = false;
216
		// if (p.getPath() == null) {
217
		if (projectPath == null) {
218
			saved = saveAsProject(null);
219
		} else {
220
			long t1, t2;
221
			t1 = System.currentTimeMillis();
222
			saved = writeProject(new File(projectPath), p, false);
223
			t2 = System.currentTimeMillis();
224
			PluginServices.getLogger().info(
225
					"Project saved. " + (t2 - t1) + " miliseconds");
226
			getProjectFrame().refreshControls();
227
		}
228
		return saved;
229
	}
221 230

  
222
        if (lastSavePath == null) {
223
            lastSavePath = projectPath;
224
        }
231
	private boolean saveAsProject(File file) {
232
		boolean saved = false;
225 233

  
226
        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
227
        JFileChooser jfc =
228
            new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get(
229
                "ProjectsFolder", null));
234
		if (lastSavePath == null) {
235
			lastSavePath = projectPath;
236
		}
230 237

  
231
        jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
232
        jfc.addChoosableFileFilter(new GenericFileFilter(
233
            Project.FILE_EXTENSION, MessageFormat.format(
234
                PluginServices.getText(this, "tipo_fichero_proyecto"),
235
                Project.FILE_EXTENSION)));
238
		if (file == null) {
239
			Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
240
			JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID,
241
					prefs.get("ProjectsFolder", null));
236 242

  
237
        if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
238
            File file = jfc.getSelectedFile();
239
            if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
240
                .toLowerCase()))) {
241
                file = new File(file.getPath() + Project.FILE_EXTENSION);
242
            }
243
            saved = writeProject(file, p);
244
            String filePath = file.getAbsolutePath();
245
            lastSavePath =
246
                filePath.substring(0, filePath.lastIndexOf(File.separatorChar));
243
			jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
244
			jfc.addChoosableFileFilter(new GenericFileFilter(
245
					Project.FILE_EXTENSION, MessageFormat.format(PluginServices
246
							.getText(this, "tipo_fichero_proyecto"),
247
							Project.FILE_EXTENSION)));
247 248

  
248
            getProjectFrame().refreshControls();
249
        }
250
        return saved;
251
    }
249
			if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
250
				return saved;
251
			}
252
			file = jfc.getSelectedFile();
253
		}
252 254

  
253
    /**
254
     * Checks whether the project and related unsaved data is modified,
255
     * and allows the user to save it.
256
     * 
257
     * @return true if the data has been correctly saved, false otherwise
258
     */
259
    private boolean askSave() {
260
        if (p != null && p.hasChanged()) {
261
            TerminationProcess process = Launcher.getTerminationProcess();
262
            UnsavedDataPanel panel = process.getUnsavedDataPanel();
263
            panel.setHeaderText(PluginServices.getText(this,
264
                "_Select_resources_to_save_before_closing_current_project"));
265
            panel.setAcceptText(PluginServices.getText(this, "save_resources"),
266
                PluginServices.getText(this,
267
                    "Save_the_selected_resources_and_close_current_project"));
268
            panel.setCancelText(PluginServices.getText(this, "Cancel"),
269
                PluginServices.getText(this, "Return_to_current_project"));
270
            int closeCurrProj;
271
            try {
272
                closeCurrProj = process.manageUnsavedData();
273
                if (closeCurrProj == JOptionPane.NO_OPTION) {
274
                    // the user chose to return to current project
275
                    return false;
276
                }
277
            } catch (Exception e) {
278
                LOG.error("Some data can not be saved", e);
279
            }           
280
        }
281
        return true;
282
    }
255
		if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
256
				.toLowerCase()))) {
257
			file = new File(file.getPath() + Project.FILE_EXTENSION);
258
		}
259
		saved = writeProject(file, p);
260
		String filePath = file.getAbsolutePath();
261
		lastSavePath = filePath.substring(0,
262
				filePath.lastIndexOf(File.separatorChar));
283 263

  
284
    /**
285
     * @see com.iver.mdiApp.plugins.IExtension#updateUI(java.lang.String)
286
     */
287
    public void execute(String actionCommand) {
288
        if (actionCommand.equals("application-project-new")) {
289
            if (!askSave()) {
290
                return;
291
            }
264
		getProjectFrame().refreshControls();
265
		return saved;
266
	}
292 267

  
293
            projectPath = null;
294
            // ProjectDocument.initializeNUMS();
295
            PluginServices.getMDIManager().closeAllWindows();
296
            setProject(ProjectManager.getInstance().createProject());
297
            getProjectFrame().setProject(p);
298
            showProjectWindow();
299
            PluginServices.getMainFrame().setTitle(
300
                PluginServices.getText(this, "sin_titulo"));
301
        } else if (actionCommand.equals("application-project-open")) {
302
            if (!askSave()) {
303
                return;
304
            }
268
	/**
269
	 * Checks whether the project and related unsaved data is modified, and
270
	 * allows the user to save it.
271
	 * 
272
	 * @return true if the data has been correctly saved, false otherwise
273
	 */
274
	private boolean askSave() {
275
		if (p != null && p.hasChanged()) {
276
			TerminationProcess process = Launcher.getTerminationProcess();
277
			UnsavedDataPanel panel = process.getUnsavedDataPanel();
278
			panel.setHeaderText(PluginServices.getText(this,
279
					"_Select_resources_to_save_before_closing_current_project"));
280
			panel.setAcceptText(
281
					PluginServices.getText(this, "save_resources"),
282
					PluginServices
283
							.getText(this,
284
									"Save_the_selected_resources_and_close_current_project"));
285
			panel.setCancelText(PluginServices.getText(this, "Cancel"),
286
					PluginServices.getText(this, "Return_to_current_project"));
287
			int closeCurrProj;
288
			try {
289
				closeCurrProj = process.manageUnsavedData();
290
				if (closeCurrProj == JOptionPane.NO_OPTION) {
291
					// the user chose to return to current project
292
					return false;
293
				}
294
			} catch (Exception e) {
295
				LOG.error("Some data can not be saved", e);
296
			}
297
		}
298
		return true;
299
	}
305 300

  
306
            Preferences prefs =
307
                Preferences.userRoot().node("gvsig.foldering");
308
            JFileChooser jfc =
309
                new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get(
310
                    "ProjectsFolder", null));
311
            jfc.addChoosableFileFilter(new GenericFileFilter(
312
                Project.FILE_EXTENSION, PluginServices.getText(this,
313
                    "tipo_fichero_proyecto")));
301
	public void execute(String command) {
302
		this.execute(command, null);
303
	}
314 304

  
315
            if (jfc.showOpenDialog((Component) PluginServices
316
                .getMainFrame()) == JFileChooser.APPROVE_OPTION) {
317
                // ProjectDocument.initializeNUMS();
318
                PluginServices.getMDIManager().closeAllWindows();
305
	public void execute(String actionCommand, Object[] args) {
306
		if (actionCommand.equals("application-project-new")) {
307
			if (!askSave()) {
308
				return;
309
			}
319 310

  
320
                File projectFile = jfc.getSelectedFile();
321
                Project o = readProject(projectFile);
322
                setPath(projectFile.getAbsolutePath());
323
                // lastPath = getPath();
324
                if (o != null) {
325
                    setProject(o);
326
                }
311
			projectPath = null;
312
			// ProjectDocument.initializeNUMS();
313
			PluginServices.getMDIManager().closeAllWindows();
314
			setProject(ProjectManager.getInstance().createProject());
315
			getProjectFrame().setProject(p);
316
			showProjectWindow();
317
			PluginServices.getMainFrame().setTitle(
318
					PluginServices.getText(this, "sin_titulo"));
319
		} else if (actionCommand.equals("application-project-open")) {
320
			if (!askSave()) {
321
				return;
322
			}
323
			File projectFile = null;
327 324

  
328
                getProjectFrame().setProject(p);
329
                PluginServices.getMainFrame().setTitle(projectFile.getName());
330
                getProjectFrame().refreshControls();
325
			if (args != null && args.length > 0 && args[0] != null) {
326
				if (args[0] instanceof File) {
327
					projectFile = (File) args[0];
328
				} else if (args[0] instanceof String) {
329
					projectFile = new File((String) args[0]);
330
					if (!projectFile.exists()) {
331
						LOG.warn("Can't load project '"
332
								+ projectFile.getAbsolutePath()
333
								+ "', file not exist.");
334
						projectFile = null;
335
					}
336
				}
337
			}
331 338

  
332
                // p.restoreWindowProperties();
333
            }
334
        } else if (actionCommand.equals("application-project-save")) {
335
                guardar();
336
        } else if (actionCommand.equals("application-project-save-as")) {
337
            guardarDialogo();
338
        }
339
			if (projectFile == null) {
340
				Preferences prefs = Preferences.userRoot().node(
341
						"gvsig.foldering");
342
				JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID,
343
						prefs.get("ProjectsFolder", null));
344
				jfc.addChoosableFileFilter(new GenericFileFilter(
345
						Project.FILE_EXTENSION, PluginServices.getText(this,
346
								"tipo_fichero_proyecto")));
339 347

  
340
    }
348
				if (jfc.showOpenDialog((Component) PluginServices
349
						.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
350
					return;
351
				}
352
				// ProjectDocument.initializeNUMS();
353
				PluginServices.getMDIManager().closeAllWindows();
341 354

  
342
    /**
343
     * Escribe el proyecto en XML.
344
     * 
345
     * @param file
346
     *            Fichero.
347
     * @param p
348
     *            Proyecto.
349
     */
350
    public boolean writeProject(File file, Project p) {
351
        return writeProject(file, p, true);
352
    }
355
				projectFile = jfc.getSelectedFile();
356
			}
353 357

  
354
    /**
355
     * Escribe el proyecto en XML. Pero permite decidir si se
356
     * pide confirmaci?n para sobreescribir
357
     * 
358
     * @param file
359
     *            Fichero.
360
     * @param p
361
     *            Proyecto.
362
     * @param askConfirmation
363
     *            boolean
364
     */
365
    public boolean writeProject(File file, Project p, boolean askConfirmation) {
366
        if (askConfirmation && file.exists()) {
367
            int resp =
368
                JOptionPane.showConfirmDialog((Component) PluginServices
369
                    .getMainFrame(), PluginServices.getText(this,
370
                    "fichero_ya_existe_seguro_desea_guardarlo"), PluginServices
371
                    .getText(this, "guardar"), JOptionPane.YES_NO_OPTION);
372
            if (resp != JOptionPane.YES_OPTION) {
373
                return false;
374
            }
375
        }
376
        NotificationManager.addInfo(PluginServices.getText(this,
377
            "writinng_project") + ": " + file.getName());
358
			Project o = readProject(projectFile);
359
			setPath(projectFile.getAbsolutePath());
360
			// lastPath = getPath();
361
			if (o != null) {
362
				setProject(o);
363
			}
378 364

  
379
        // write it out as XML
380
        try {
381
            fireBeforeSavingFileEvent(new SaveEvent(this,
382
                SaveEvent.BEFORE_SAVING, file));
383
            p.saveState(file);
384
            fireAfterSavingFileEvent(new SaveEvent(this,
385
                SaveEvent.AFTER_SAVING, file));
386
            
387
            PluginServices.getMainFrame().setTitle(file.getName());
388
            setPath(file.toString());
365
			getProjectFrame().setProject(p);
366
			PluginServices.getMainFrame().setTitle(projectFile.getName());
367
			getProjectFrame().refreshControls();
389 368

  
390
        } catch (PersistenceException e) {
391
            String messagestack = e.getLocalizedMessageStack();
392
            NotificationManager.addError(
393
                PluginServices.getText(this, "error_writing_project") + ": "
394
                    + file.getName() + "\n" + messagestack, e);
395
            return false;
396
        } catch (Exception e) {
397
            NotificationManager.addError(
398
                PluginServices.getText(this, "error_writing_project") + ": "
399
                    + file.getName(), e);
400
            return false;
401
        }
402
        NotificationManager.addInfo(PluginServices.getText(this,
403
            "wrote_project") + ": " + file.getName());
404
        return true;
405
    }
369
			// p.restoreWindowProperties();
406 370

  
407
    public Project readProject(String path) {
408
        Project project = ProjectManager.getInstance().createProject();
371
		} else if (actionCommand.equals("application-project-save")) {
372
			saveProject();
373
		} else if (actionCommand.equals("application-project-save-as")) {
374
			File file = null;
375
			if (args != null && args.length > 0 && args[0] != null) {
376
				if (args[0] instanceof File) {
377
					file = (File) args[0];
378
				} else if (args[0] instanceof String) {
379
					file = new File((String) args[0]);
380
				}
381
			}
382
			saveAsProject(file);
383
		}
409 384

  
410
        project.loadState(new File(path));
411
        return (Project) project;
412
    }
385
	}
413 386

  
414
    /**
415
     * Lee del XML el proyecto.<br>
416
     * <br>
417
     * 
418
     * Reads the XML of the project.<br>
419
     * It returns a project object holding all needed info that is not linked to
420
     * the Project Dialog. <br>
421
     * In case you want the project to be
422
     * linked to the window you must set this object to the extension:<br>
423
     * 
424
     * <b>Example:</b><br>
425
     * 
426
     * ...<br>
427
     * ...<br>
428
     * Project p = ProjectExtension.readProject(projectFile);<br>
429
     * ProjectExtension.setProject(p);
430
     * ...<br>
431
     * ...<br>
432
     * 
433
     * @param file
434
     *            Fichero.
435
     * 
436
     * @return Project
437
     * 
438
     */
439
    public Project readProject(File file) {
440
        Project project = ProjectManager.getInstance().createProject();
387
	/**
388
	 * Escribe el proyecto en XML.
389
	 * 
390
	 * @param file
391
	 *            Fichero.
392
	 * @param p
393
	 *            Proyecto.
394
	 */
395
	public boolean writeProject(File file, Project p) {
396
		return writeProject(file, p, true);
397
	}
441 398

  
442
        project.loadState(file);
443
        return (Project) project;
444
    }
399
	/**
400
	 * Escribe el proyecto en XML. Pero permite decidir si se pide confirmaci?n
401
	 * para sobreescribir
402
	 * 
403
	 * @param file
404
	 *            Fichero.
405
	 * @param p
406
	 *            Proyecto.
407
	 * @param askConfirmation
408
	 *            boolean
409
	 */
410
	public boolean writeProject(File file, Project p, boolean askConfirmation) {
411
		if (askConfirmation && file.exists()) {
412
			int resp = JOptionPane.showConfirmDialog((Component) PluginServices
413
					.getMainFrame(), PluginServices.getText(this,
414
					"fichero_ya_existe_seguro_desea_guardarlo"), PluginServices
415
					.getText(this, "guardar"), JOptionPane.YES_NO_OPTION);
416
			if (resp != JOptionPane.YES_OPTION) {
417
				return false;
418
			}
419
		}
420
		NotificationManager.addInfo(PluginServices.getText(this,
421
				"writinng_project") + ": " + file.getName());
445 422

  
446
    /**
447
     * Devuelve el proyecto.
448
     * 
449
     * @return Proyecto.
450
     */
451
    public Project getProject() {
452
        return p;
453
    }
423
		// write it out as XML
424
		try {
425
			fireBeforeSavingFileEvent(new SaveEvent(this,
426
					SaveEvent.BEFORE_SAVING, file));
427
			p.saveState(file);
428
			fireAfterSavingFileEvent(new SaveEvent(this,
429
					SaveEvent.AFTER_SAVING, file));
454 430

  
455
    /**
456
     * @see org.gvsig.andami.plugins.IExtension#isEnabled()
457
     */
458
    public boolean isEnabled() {
459
        return true;
460
    }
431
			PluginServices.getMainFrame().setTitle(file.getName());
432
			setPath(file.toString());
461 433

  
462
    /**
463
     * @see org.gvsig.andami.plugins.IExtension#isVisible()
464
     */
465
    public boolean isVisible() {
466
        return true;
467
    }
434
		} catch (PersistenceException e) {
435
			String messagestack = e.getLocalizedMessageStack();
436
			NotificationManager.addError(
437
					PluginServices.getText(this, "error_writing_project")
438
							+ ": " + file.getName() + "\n" + messagestack, e);
439
			return false;
440
		} catch (Exception e) {
441
			NotificationManager.addError(
442
					PluginServices.getText(this, "error_writing_project")
443
							+ ": " + file.getName(), e);
444
			return false;
445
		}
446
		NotificationManager.addInfo(PluginServices.getText(this,
447
				"wrote_project") + ": " + file.getName());
448
		return true;
449
	}
468 450

  
469
    /**
470
     * Sets the project
471
     * 
472
     * @param p
473
     */
474
    public void setProject(Project p) {
475
        getProjectFrame().setProject(p);
476
        this.p = p;
477
    }
451
	public Project readProject(String path) {
452
		Project project = ProjectManager.getInstance().createProject();
478 453

  
479
    private void registerDocuments() {
480
        ViewManager.register();
481
    }
454
		project.loadState(new File(path));
455
		return (Project) project;
456
	}
482 457

  
483
    private void initializeDocumentActionsExtensionPoint() {
484
        ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
485
        epMan.add("DocumentActions_View",
486
            "Context menu options of the view document list"
487
                + " in the project window " + "(register instances of "
488
                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
489
    }
458
	/**
459
	 * Lee del XML el proyecto.<br>
460
	 * <br>
461
	 * 
462
	 * Reads the XML of the project.<br>
463
	 * It returns a project object holding all needed info that is not linked to
464
	 * the Project Dialog. <br>
465
	 * In case you want the project to be linked to the window you must set this
466
	 * object to the extension:<br>
467
	 * 
468
	 * <b>Example:</b><br>
469
	 * 
470
	 * ...<br>
471
	 * ...<br>
472
	 * Project p = ProjectExtension.readProject(projectFile);<br>
473
	 * ProjectExtension.setProject(p); ...<br>
474
	 * ...<br>
475
	 * 
476
	 * @param file
477
	 *            Fichero.
478
	 * 
479
	 * @return Project
480
	 * 
481
	 */
482
	public Project readProject(File file) {
483
		Project project = ProjectManager.getInstance().createProject();
490 484

  
491
    public static String getPath() {
492
        return projectPath;
493
    }
485
		project.loadState(file);
486
		return (Project) project;
487
	}
494 488

  
495
    public static void setPath(String path) {
496
        projectPath = path;
497
    }
489
	/**
490
	 * Devuelve el proyecto.
491
	 * 
492
	 * @return Proyecto.
493
	 */
494
	public Project getProject() {
495
		return p;
496
	}
498 497

  
499
    public IWindow getProjectWindow() {
500
        return getProjectFrame();
501
    }
498
	/**
499
	 * @see org.gvsig.andami.plugins.IExtension#isEnabled()
500
	 */
501
	public boolean isEnabled() {
502
		return true;
503
	}
502 504

  
503
    public IExtensionStatus getStatus() {
504
        return this;
505
    }
505
	/**
506
	 * @see org.gvsig.andami.plugins.IExtension#isVisible()
507
	 */
508
	public boolean isVisible() {
509
		return true;
510
	}
506 511

  
507
    public boolean hasUnsavedData() {
508
        return p.hasChanged();
509
    }
512
	/**
513
	 * Sets the project
514
	 * 
515
	 * @param p
516
	 */
517
	public void setProject(Project p) {
518
		getProjectFrame().setProject(p);
519
		this.p = p;
520
	}
510 521

  
511
    public IUnsavedData[] getUnsavedData() {
512
        if (hasUnsavedData()) {
513
            UnsavedProject data = new UnsavedProject(this);
514
            IUnsavedData[] dataArray = { data };
515
            return dataArray;
516
        } else {
517
            return null;
518
        }
519
    }
522
	private void registerDocuments() {
523
		ViewManager.register();
524
	}
520 525

  
521
    /**
522
     * Implements the IUnsavedData interface to show unsaved projects
523
     * in the Unsavad Data dialog.
524
     * 
525
     * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
526
     */
527
    public class UnsavedProject extends UnsavedData {
526
	private void initializeDocumentActionsExtensionPoint() {
527
		ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
528
		epMan.add(
529
				"DocumentActions_View",
530
				"Context menu options of the view document list"
531
						+ " in the project window "
532
						+ "(register instances of "
533
						+ "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
534
	}
528 535

  
529
        public UnsavedProject(IExtension extension) {
530
            super(extension);
531
        }
536
	public static String getPath() {
537
		return projectPath;
538
	}
532 539

  
533
        public String getDescription() {
534
            if (getPath() == null) {
535
                return PluginServices.getText(ProjectExtension.this,
536
                    "Unnamed_new_gvsig_project_");
537
            } else {
538
                return PluginServices.getText(ProjectExtension.this,
539
                    "Modified_project_");
540
            }
541
        }
540
	public static void setPath(String path) {
541
		projectPath = path;
542
	}
542 543

  
543
        public String getResourceName() {
544
            if (getPath() == null) {
545
                return PluginServices.getText(ProjectExtension.this, "Unnamed");
546
            } else {
547
                return getPath();
548
            }
544
	public IWindow getProjectWindow() {
545
		return getProjectFrame();
546
	}
549 547

  
550
        }
548
	public IExtensionStatus getStatus() {
549
		return this;
550
	}
551 551

  
552
        public boolean saveData() {
553
            return guardar();
554
        }
552
	public boolean hasUnsavedData() {
553
		return p.hasChanged();
554
	}
555 555

  
556
        public String getIcon() {
557
            return "project-icon";
558
        }
559
    }
556
	public IUnsavedData[] getUnsavedData() {
557
		if (hasUnsavedData()) {
558
			UnsavedProject data = new UnsavedProject(this);
559
			IUnsavedData[] dataArray = { data };
560
			return dataArray;
561
		} else {
562
			return null;
563
		}
564
	}
560 565

  
561
    public IMonitorableTask[] getRunningProcesses() {
562
        // TODO Auto-generated method stub
563
        return null;
564
    }
566
	/**
567
	 * Implements the IUnsavedData interface to show unsaved projects in the
568
	 * Unsavad Data dialog.
569
	 * 
570
	 * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
571
	 */
572
	public class UnsavedProject extends UnsavedData {
565 573

  
566
    public boolean hasRunningProcesses() {
567
        // TODO Auto-generated method stub
568
        return false;
569
    }
574
		public UnsavedProject(IExtension extension) {
575
			super(extension);
576
		}
570 577

  
571
    /**
572
     * Adds the specified before saving listener to receive
573
     * "before saving file events" from
574
     * this component.
575
     * If l is null, no exception is thrown and no action is performed.
576
     * 
577
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
578
     * 
579
     * @param l
580
     *            the before saving listener.
581
     * @see SaveEvent
582
     * @see BeforeSavingListener
583
     * @see #removeListener(BeforeSavingListener)
584
     * @see #getBeforeSavingListeners
585
     */
586
    public synchronized void addListener(BeforeSavingListener l) {
587
        if (l == null) {
588
            return;
589
        }
590
        if (!this.beforeSavingListeners.contains(l)) {
591
            this.beforeSavingListeners.add(l);
592
        }
593
    }
578
		public String getDescription() {
579
			if (getPath() == null) {
580
				return PluginServices.getText(ProjectExtension.this,
581
						"Unnamed_new_gvsig_project_");
582
			} else {
583
				return PluginServices.getText(ProjectExtension.this,
584
						"Modified_project_");
585
			}
586
		}
594 587

  
595
    /**
596
     * Adds the specified after saving listener to receive
597
     * "after saving file events" from
598
     * this component.
599
     * If l is null, no exception is thrown and no action is performed.
600
     * 
601
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
602
     * 
603
     * @param l
604
     *            the after saving listener.
605
     * @see SaveEvent
606
     * @see AfterSavingListener
607
     * @see #removeListener(AfterSavingListener)
608
     * @see #getAfterSavingListeners()
609
     */
610
    public synchronized void addListener(AfterSavingListener l) {
611
        if (l == null) {
612
            return;
613
        }
588
		public String getResourceName() {
589
			if (getPath() == null) {
590
				return PluginServices.getText(ProjectExtension.this, "Unnamed");
591
			} else {
592
				return getPath();
593
			}
614 594

  
615
        if (!this.afterSavingListeners.contains(l)) {
616
            this.afterSavingListeners.add(l);
617
        }
595
		}
618 596

  
619
    }
597
		public boolean saveData() {
598
			return saveProject();
599
		}
620 600

  
621
    /**
622
     * Returns an array of all the before saving listeners
623
     * registered on this component.
624
     * 
625
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
626
     * 
627
     * @return all of this component's <code>BeforeSavingListener</code>s
628
     *         or an empty array if no key
629
     *         listeners are currently registered
630
     * 
631
     * @see #addBeforeSavingListener(BeforeSavingListener)
632
     * @see #removeBeforeSavingListener(BeforeSavingListener)
633
     */
634
    public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
635
        return this.beforeSavingListeners
636
            .toArray(new BeforeSavingListener[] {});
637
    }
601
		public String getIcon() {
602
			return "project-icon";
603
		}
604
	}
638 605

  
639
    /**
640
     * Returns an array of all the after saving listeners
641
     * registered on this component.
642
     * 
643
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
644
     * 
645
     * @return all of this component's <code>AfterSavingListener</code>s
646
     *         or an empty array if no key
647
     *         listeners are currently registered
648
     * 
649
     * @see #addAfterSavingListener(AfterSavingListener)
650
     * @see #removeAfterSavingListener
651
     */
652
    public synchronized AfterSavingListener[] getAfterSavingListeners() {
653
        return this.afterSavingListeners.toArray(new AfterSavingListener[] {});
606
	public IMonitorableTask[] getRunningProcesses() {
607
		// TODO Auto-generated method stub
608
		return null;
609
	}
654 610

  
655
    }
611
	public boolean hasRunningProcesses() {
612
		// TODO Auto-generated method stub
613
		return false;
614
	}
656 615

  
657
    /**
658
     * Removes the specified before saving listener so that it no longer
659
     * receives save file events from this component. This method performs
660
     * no function, nor does it throw an exception, if the listener
661
     * specified by the argument was not previously added to this component.
662
     * If listener <code>l</code> is <code>null</code>,
663
     * no exception is thrown and no action is performed.
664
     * 
665
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
666
     * 
667
     * @param l
668
     *            the before saving listener
669
     * @see SaveEvent
670
     * @see BeforeSavingListener
671
     * @see #addListener(BeforeSavingListener)
672
     * @see #getBeforeSavingListeners()
673
     */
674
    public synchronized void removeListener(BeforeSavingListener l) {
675
        if (l == null) {
676
            return;
677
        }
616
	/**
617
	 * Adds the specified before saving listener to receive
618
	 * "before saving file events" from this component. If l is null, no
619
	 * exception is thrown and no action is performed.
620
	 * 
621
	 * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
622
	 * 
623
	 * @param l
624
	 *            the before saving listener.
625
	 * @see SaveEvent
626
	 * @see BeforeSavingListener
627
	 * @see #removeListener(BeforeSavingListener)
628
	 * @see #getBeforeSavingListeners
629
	 */
630
	public synchronized void addListener(BeforeSavingListener l) {
631
		if (l == null) {
632
			return;
633
		}
634
		if (!this.beforeSavingListeners.contains(l)) {
635
			this.beforeSavingListeners.add(l);
636
		}
637
	}
678 638

  
679
        this.beforeSavingListeners.remove(l);
680
    }
639
	/**
640
	 * Adds the specified after saving listener to receive
641
	 * "after saving file events" from this component. If l is null, no
642
	 * exception is thrown and no action is performed.
643
	 * 
644
	 * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
645
	 * 
646
	 * @param l
647
	 *            the after saving listener.
648
	 * @see SaveEvent
649
	 * @see AfterSavingListener
650
	 * @see #removeListener(AfterSavingListener)
651
	 * @see #getAfterSavingListeners()
652
	 */
653
	public synchronized void addListener(AfterSavingListener l) {
654
		if (l == null) {
655
			return;
656
		}
681 657

  
682
    /**
683
     * Removes the specified after saving listener so that it no longer
684
     * receives save file events from this component. This method performs
685
     * no function, nor does it throw an exception, if the listener
686
     * specified by the argument was not previously added to this component.
687
     * If listener <code>l</code> is <code>null</code>,
688
     * no exception is thrown and no action is performed.
689
     * 
690
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
691
     * 
692
     * @param l
693
     *            the after saving listener
694
     * @see SaveEvent
695
     * @see AfterSavingListener
696
     * @see #addListener(AfterSavingListener)
697
     * @see #getAfterSavingListeners()
698
     */
699
    public synchronized void removeListener(AfterSavingListener l) {
700
        if (l == null) {
701
            return;
702
        }
658
		if (!this.afterSavingListeners.contains(l)) {
659
			this.afterSavingListeners.add(l);
660
		}
703 661

  
704
        this.afterSavingListeners.remove(l);
705
    }
662
	}
706 663

  
707
    /**
708
     * Reports a before saving file event.
709
     * 
710
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
711
     * 
712
     * @param evt
713
     *            the before saving file event
714
     */
715
    protected void fireBeforeSavingFileEvent(SaveEvent evt) {
716
        if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
717
            return;
718
        }
664
	/**
665
	 * Returns an array of all the before saving listeners registered on this
666
	 * component.
667
	 * 
668
	 * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
669
	 * 
670
	 * @return all of this component's <code>BeforeSavingListener</code>s or an
671
	 *         empty array if no key listeners are currently registered
672
	 * 
673
	 * @see #addBeforeSavingListener(BeforeSavingListener)
674
	 * @see #removeBeforeSavingListener(BeforeSavingListener)
675
	 */
676
	public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
677
		return this.beforeSavingListeners
678
				.toArray(new BeforeSavingListener[] {});
679
	}
719 680

  
720
        Iterator<BeforeSavingListener> iter =
721
            this.beforeSavingListeners.iterator();
681
	/**
682
	 * Returns an array of all the after saving listeners registered on this
683
	 * component.
684
	 * 
685
	 * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
686
	 * 
687
	 * @return all of this component's <code>AfterSavingListener</code>s or an
688
	 *         empty array if no key listeners are currently registered
689
	 * 
690
	 * @see #addAfterSavingListener(AfterSavingListener)
691
	 * @see #removeAfterSavingListener
692
	 */
693
	public synchronized AfterSavingListener[] getAfterSavingListeners() {
694
		return this.afterSavingListeners.toArray(new AfterSavingListener[] {});
722 695

  
723
        while (iter.hasNext()) {
724
            iter.next().beforeSaving(evt);
725
        }
726
    }
696
	}
727 697

  
728
    /**
729
     * Reports a after saving file event.
730
     * 
731
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
732
     * 
733
     * @param evt
734
     *            the after saving file event
735
     */
736
    protected void fireAfterSavingFileEvent(SaveEvent evt) {
737
        if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
738
            return;
739
        }
740
        Iterator<AfterSavingListener> iter =
741
            this.afterSavingListeners.iterator();
698
	/**
699
	 * Removes the specified before saving listener so that it no longer
700
	 * receives save file events from this component. This method performs no
701
	 * function, nor does it throw an exception, if the listener specified by
702
	 * the argument was not previously added to this component. If listener
703
	 * <code>l</code> is <code>null</code>, no exception is thrown and no action
704
	 * is performed.
705
	 * 
706
	 * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
707
	 * 
708
	 * @param l
709
	 *            the before saving listener
710
	 * @see SaveEvent
711
	 * @see BeforeSavingListener
712
	 * @see #addListener(BeforeSavingListener)
713
	 * @see #getBeforeSavingListeners()
714
	 */
715
	public synchronized void removeListener(BeforeSavingListener l) {
716
		if (l == null) {
717
			return;
718
		}
742 719

  
743
        while (iter.hasNext()) {
744
            iter.next().afterSaving(evt);
745
        }
720
		this.beforeSavingListeners.remove(l);
721
	}
746 722

  
747
    }
723
	/**
724
	 * Removes the specified after saving listener so that it no longer receives
725
	 * save file events from this component. This method performs no function,
726
	 * nor does it throw an exception, if the listener specified by the argument
727
	 * was not previously added to this component. If listener <code>l</code> is
728
	 * <code>null</code>, no exception is thrown and no action is performed.
729
	 * 
730
	 * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
731
	 * 
732
	 * @param l
733
	 *            the after saving listener
734
	 * @see SaveEvent
735
	 * @see AfterSavingListener
736
	 * @see #addListener(AfterSavingListener)
737
	 * @see #getAfterSavingListeners()
738
	 */
739
	public synchronized void removeListener(AfterSavingListener l) {
740
		if (l == null) {
741
			return;
742
		}
743

  
744
		this.afterSavingListeners.remove(l);
745
	}
746

  
747
	/**
748
	 * Reports a before saving file event.
749
	 * 
750
	 * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
751
	 * 
752
	 * @param evt
753
	 *            the before saving file event
754
	 */
755
	protected void fireBeforeSavingFileEvent(SaveEvent evt) {
756
		if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
757
			return;
758
		}
759

  
760
		Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
761
				.iterator();
762

  
763
		while (iter.hasNext()) {
764
			iter.next().beforeSaving(evt);
765
		}
766
	}
767

  
768
	/**
769
	 * Reports a after saving file event.
770
	 * 
771
	 * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
772
	 * 
773
	 * @param evt
774
	 *            the after saving file event
775
	 */
776
	protected void fireAfterSavingFileEvent(SaveEvent evt) {
777
		if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
778
			return;
779
		}
780
		Iterator<AfterSavingListener> iter = this.afterSavingListeners
781
				.iterator();
782

  
783
		while (iter.hasNext()) {
784
			iter.next().afterSaving(evt);
785
		}
786

  
787
	}
748 788
}

Also available in: Unified diff