Revision 44231 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
85 85
import org.gvsig.utils.save.SaveEvent;
86 86
import org.gvsig.utils.swing.threads.IMonitorableTask;
87 87

  
88

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

  
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";
96
    private static final Logger LOG = LoggerFactory
97
            .getLogger(ProjectExtension.class);
115 98

  
116
	private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
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";
117 115

  
118
	private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
116
    private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
119 117

  
120
        @Override
121
        public void initialize() {
122
            initializeDocumentActionsExtensionPoint();
123
            registerDocuments();
124
            registerIcons();
118
    private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
125 119

  
126
            PropertiesPageManager propertiesManager = ToolsUtilLocator.getPropertiesPageManager();
127
            propertiesManager.registerFactory(new ProjectDocumentsPanelPageFactory());
120
    @Override
121
    public void initialize() {
122
        initializeDocumentActionsExtensionPoint();
123
        registerDocuments();
124
        registerIcons();
128 125

  
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(
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 135
                    "Open project",
136 136
                    new OpenInitialProjectTask(projectFile), true, 1000);
137
            }
138 137
        }
138
    }
139 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);
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 148

  
149
		IconThemeHelper.registerIcon("project", "project-icon", this);
150
	}
149
        IconThemeHelper.registerIcon("project", "project-icon", this);
150
    }
151 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;
152
    /**
153
     * Returns the file to be opened or null if no parameter or file does not
154
     * 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;
183 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 184

  
185
        private class OpenInitialProjectTask implements Runnable {
186
            private File projectFile;
187
            public OpenInitialProjectTask(File projectFile) {
188
                this.projectFile = projectFile;
185
    private class OpenInitialProjectTask implements Runnable {
186

  
187
        private File projectFile;
188

  
189
        public OpenInitialProjectTask(File projectFile) {
190
            this.projectFile = projectFile;
191
        }
192

  
193
        @Override
194
        public void run() {
195
            if (this.projectFile == null) {
196
                return;
189 197
            }
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
            }
198
            ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
199
            ActionInfo action = actionManager.getAction("application-project-open");
200
            action.execute(this.projectFile);
199 201
        }
202
    }
200 203

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

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

  
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
	}
231
    /**
232
     * Muestra la ventana con el gestor de proyectos, con las propiedades de
233
     * ventana especificadas.
234
     */
235
    public void showProjectWindow(WindowInfo wi) {
236
        seedProjectWindow = wi;
237
        showProjectWindow();
238
    }
236 239

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

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

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

  
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));
267
        if (file == null) {
268
            Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
269
            JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID,
270
                    prefs.get("ProjectsFolder", null));
268 271

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

  
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);
274
            GenericFileFilter projExtensionFilter = new GenericFileFilter(
275
                    Project.FILE_EXTENSION, MessageFormat.format(PluginServices
276
                            .getText(this, "tipo_fichero_proyecto"),
277
                            Project.FILE_EXTENSION));
278
            jfc.addChoosableFileFilter(projExtensionFilter);
279
            jfc.setFileFilter(projExtensionFilter);
277 280

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

  
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));
287
        if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
288
                .toLowerCase()))) {
289
            file = new File(file.getPath() + Project.FILE_EXTENSION);
290
        }
291
        saved = writeProject(file, p);
292
        String filePath = file.getAbsolutePath();
293
        lastSavePath = filePath.substring(0,
294
                filePath.lastIndexOf(File.separatorChar));
292 295

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

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

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

  
335
        @Override
338
    @Override
336 339
    public void execute(String actionCommand, Object[] args) {
337 340
        if (actionCommand.equals("application-project-new")) {
338 341
            if (!askSave()) {
......
364 367
                JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get("ProjectsFolder", null));
365 368
                ProjectPreviewPanel preview = new ProjectPreviewPanel();
366 369
                jfc.setAccessory(preview);
367
                jfc.addPropertyChangeListener(preview);                
370
                jfc.addPropertyChangeListener(preview);
368 371

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

  
......
400 403
//            getProjectFrame().refreshControls();
401 404

  
402 405
            // p.restoreWindowProperties();
403

  
404 406
        } else if (actionCommand.equals("application-project-save")) {
405 407
            // saveProject();
406 408
            try {
......
415 417

  
416 418
    }
417 419

  
418

  
419 420
    private void createEmptyProject() {
420 421
        setProject(ProjectManager.getInstance().createProject());
421 422
        p.setName(PluginServices.getText(this, "untitled"));
......
430 431
    public void postInitialize() {
431 432
        PluginsManager pluginsManager = PluginsLocator.getManager();
432 433
        pluginsManager.addStartupTask(
433
                "createEmptyProject", 
434
                "createEmptyProject",
434 435
                new Runnable() {
435
                    @Override
436
                    public void run() {
437
                        createEmptyProject();
438
                    }
439
                }, 
440
                true, 
436
            @Override
437
            public void run() {
438
                createEmptyProject();
439
            }
440
        },
441
                true,
441 442
                1000
442 443
        );
443 444
    }
444 445

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

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

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

  
492 490
        } catch (Exception e) {
493 491
            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, 
492
                    i18n.getTranslation("_Problems_saving_the_project_XnlX_It_is_possible_that_this_was_not_saved_properly_and_can_not_be_loaded_again"),
493
                    null,
494
                    i18n.getTranslation("guardar"),
495
                    JOptionPane.ERROR_MESSAGE,
498 496
                    "Problems_saving_the_project"
499 497
            );
500
            LOG.warn("Error writing project '"+file.getAbsolutePath()+"'.", e);
498
            LOG.warn("Error writing project '" + file.getAbsolutePath() + "'.", e);
501 499
            return false;
502
        }        
503
        LOG.warn("Wrote project '"+file.getAbsolutePath()+"'.");
500
        }
501
        LOG.warn("Wrote project '" + file.getAbsolutePath() + "'.");
504 502
        return true;
505 503
    }
506 504

  
......
523 521
    }
524 522

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

  
539
		project.loadState(new File(path));
540
		return (Project) project;
541
	}
534
    public Project readProject(String path) {
535
        Project project = ProjectManager.getInstance().createProject();
542 536

  
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();
537
        project.loadState(new File(path));
538
        return (Project) project;
539
    }
569 540

  
570
		project.loadState(file);
571
		Set<String> unloadedObjects = project.getUnloadedObjects();
541
    /**
542
     * Lee del XML el proyecto.<br>
543
     * <br>
544
     *
545
     * Reads the XML of the project.<br>
546
     * It returns a project object holding all needed info that is not linked to
547
     * the Project Dialog. <br>
548
     * In case you want the project to be linked to the window you must set this
549
     * object to the extension:<br>
550
     *
551
     * <b>Example:</b><br>
552
     *
553
     * ...<br>
554
     * .
555
     * ..<br>
556
     * Project p = ProjectExtension.readProject(projectFile);<br>
557
     * ProjectExtension.setProject(p); ...<br>
558
     * .
559
     * ..<br>
560
     *
561
     * @param file Fichero.
562
     *
563
     * @return Project
564
     *
565
     */
566
    public Project readProject(File file) {
567
        Project project = ProjectManager.getInstance().createProject();
568

  
569
        project.loadState(file);
570
        Set<String> unloadedObjects = project.getUnloadedObjects();
572 571
        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()){
572

  
573
        if (!CollectionUtils.isEmpty(unloadedObjects)) {
574
            StringBuilder builder = new StringBuilder();
575
            builder.append("Unloaded elements loading the project:\n");
576
            Iterator<String> it = unloadedObjects.iterator();
577
            while (it.hasNext()) {
579 578
                builder.append("\t");
580
		        builder.append(it.next());
581
		        builder.append("\n");
582
		    }
579
                builder.append(it.next());
580
                builder.append("\n");
581
            }
583 582

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

  
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);
589
            application.messageDialog(
590
                    i18nManager.getTranslation("_some_project_elements_could_not_be_loaded") + "\n"
591
                    + i18nManager.getTranslation("_maybe_you_need_to_install_any_plugins") + "\n"
592
                    + i18nManager.getTranslation("_Recovered_data_may_be_corrupted") + "\n\n"
593
                    + i18nManager.getTranslation("_see_error_log_for_more_information"),
594
                    i18nManager.getTranslation("warning"),
595
                    JOptionPane.WARNING_MESSAGE);
597 596

  
598
		} else {
599
            
597
        } else {
598

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

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

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

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

  
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
	}
626
    /**
627
     * Sets the project
628
     *
629
     * @param p
630
     */
631
    public void setProject(Project p) {
632
        this.p = p;
633
        getProjectFrame().setProject(p);
634
    }
636 635

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

  
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
	}
640
    private void initializeDocumentActionsExtensionPoint() {
641
        ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
642
        epMan.add(
643
                "DocumentActions_View",
644
                "Context menu options of the view document list"
645
                + " in the project window "
646
                + "(register instances of "
647
                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
648
    }
650 649

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

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

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

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

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

  
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
	}
672
    @Override
673
    public IUnsavedData[] getUnsavedData() {
674
        if (hasUnsavedData()) {
675
            UnsavedProject data = new UnsavedProject(this);
676
            IUnsavedData[] dataArray = {data};
677
            return dataArray;
678
        } else {
679
            return null;
680
        }
681
    }
683 682

  
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 {
683
    /**
684
     * Implements the IUnsavedData interface to show unsaved projects in the
685
     * Unsavad Data dialog.
686
     *
687
     * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
688
     */
689
    public class UnsavedProject extends UnsavedData {
691 690

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

  
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
		}
695
        @Override
696
        public String getDescription() {
697
            if (getPath() == null) {
698
                return PluginServices.getText(ProjectExtension.this,
699
                        "Unnamed_new_gvsig_project_");
700
            } else {
701
                return PluginServices.getText(ProjectExtension.this,
702
                        "Modified_project_");
703
            }
704
        }
706 705

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

  
715
		}
714
        }
716 715

  
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 716
        @Override
729
	public IMonitorableTask[] getRunningProcesses() {
730
		// TODO Auto-generated method stub
731
		return null;
732
	}
717
        public boolean saveData() {
718
            return saveProject();
719
        }
733 720

  
734 721
        @Override
735
	public boolean hasRunningProcesses() {
736
		// TODO Auto-generated method stub
737
		return false;
738
	}
722
        public String getIcon() {
723
            return "project-icon";
724
        }
725
    }
739 726

  
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
	}
727
    @Override
728
    public IMonitorableTask[] getRunningProcesses() {
729
        // TODO Auto-generated method stub
730
        return null;
731
    }
762 732

  
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
		}
733
    @Override
734
    public boolean hasRunningProcesses() {
735
        // TODO Auto-generated method stub
736
        return false;
737
    }
781 738

  
782
		if (!this.afterSavingListeners.contains(l)) {
783
			this.afterSavingListeners.add(l);
784
		}
739
    /**
740
     * Adds the specified before saving listener to receive "before saving file
741
     * events" from this component. If l is null, no exception is thrown and no
742
     * action is performed.
743
     *
744
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
745
     *
746
     * @param l the before saving listener.
747
     * @see SaveEvent
748
     * @see BeforeSavingListener
749
     * @see #removeListener(BeforeSavingListener)
750
     * @see #getBeforeSavingListeners
751
     */
752
    public synchronized void addListener(BeforeSavingListener l) {
753
        if (l == null) {
754
            return;
755
        }
756
        if (!this.beforeSavingListeners.contains(l)) {
757
            this.beforeSavingListeners.add(l);
758
        }
759
    }
785 760

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

  
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
	}
779
        if (!this.afterSavingListeners.contains(l)) {
780
            this.afterSavingListeners.add(l);
781
        }
804 782

  
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[] {});
783
    }
819 784

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

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

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

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

  
868
		this.afterSavingListeners.remove(l);
869
	}
840
        this.beforeSavingListeners.remove(l);
841
    }
870 842

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

  
884
		Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
885
				.iterator();
863
        this.afterSavingListeners.remove(l);
864
    }
886 865

  
887
		while (iter.hasNext()) {
888
			iter.next().beforeSaving(evt);
889
		}
890
	}
866
    /**
867
     * Reports a before saving file event.
868
     *
869
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
870
     *
871
     * @param evt the before saving file event
872
     */
873
    protected void fireBeforeSavingFileEvent(SaveEvent evt) {
874
        if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
875
            return;
876
        }
891 877

  
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();
878
        Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
879
                .iterator();
906 880

  
907
		while (iter.hasNext()) {
908
			iter.next().afterSaving(evt);
909
		}
881
        while (iter.hasNext()) {
882
            iter.next().beforeSaving(evt);
883
        }
884
    }
910 885

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

  
900
        while (iter.hasNext()) {
901
            iter.next().afterSaving(evt);
902
        }
903

  
904
    }
912 905
}

Also available in: Unified diff