View Javadoc
1   /**
2    * 
3    * Copyright (c) 2013-2014, Openflexo
4    * Copyright (c) 2011-2012, AgileBirds
5    * 
6    * This file is part of Gina-swing-editor, a component of the software infrastructure 
7    * developed at Openflexo.
8    * 
9    * 
10   * Openflexo is dual-licensed under the European Union Public License (EUPL, either 
11   * version 1.1 of the License, or any later version ), which is available at 
12   * https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
13   * and the GNU General Public License (GPL, either version 3 of the License, or any 
14   * later version), which is available at http://www.gnu.org/licenses/gpl.html .
15   * 
16   * You can redistribute it and/or modify under the terms of either of these licenses
17   * 
18   * If you choose to redistribute it and/or modify under the terms of the GNU GPL, you
19   * must include the following additional permission.
20   *
21   *          Additional permission under GNU GPL version 3 section 7
22   *
23   *          If you modify this Program, or any covered work, by linking or 
24   *          combining it with software containing parts covered by the terms 
25   *          of EPL 1.0, the licensors of this Program grant you additional permission
26   *          to convey the resulting work. * 
27   * 
28   * This software is distributed in the hope that it will be useful, but WITHOUT ANY 
29   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
30   * PARTICULAR PURPOSE. 
31   *
32   * See http://www.openflexo.org/license.html for details.
33   * 
34   * 
35   * Please contact Openflexo (openflexo-contacts@openflexo.org)
36   * or visit www.openflexo.org if you need additional information.
37   * 
38   */
39  
40  package org.openflexo.gina.swing.editor;
41  
42  import java.awt.event.InputEvent;
43  import java.awt.event.KeyEvent;
44  import java.io.File;
45  import java.net.MalformedURLException;
46  import java.util.ArrayList;
47  import java.util.Collection;
48  import java.util.HashMap;
49  import java.util.List;
50  import java.util.Map;
51  import java.util.logging.Logger;
52  
53  import javax.swing.JComponent;
54  import javax.swing.JDialog;
55  import javax.swing.JFileChooser;
56  import javax.swing.JFrame;
57  import javax.swing.JOptionPane;
58  import javax.swing.filechooser.FileFilter;
59  
60  import org.openflexo.gina.ApplicationFIBLibrary;
61  import org.openflexo.gina.ApplicationFIBLibrary.ApplicationFIBLibraryImpl;
62  import org.openflexo.gina.FIBLibrary;
63  import org.openflexo.gina.controller.FIBController;
64  import org.openflexo.gina.model.FIBComponent;
65  import org.openflexo.gina.model.FIBContainer;
66  import org.openflexo.gina.model.FIBModelFactory;
67  import org.openflexo.gina.model.FIBModelObject.FIBModelObjectImpl;
68  import org.openflexo.gina.model.container.FIBPanel;
69  import org.openflexo.gina.model.container.FIBPanel.Layout;
70  import org.openflexo.gina.swing.editor.controller.FIBEditorController;
71  import org.openflexo.gina.swing.editor.inspector.FIBEditorInspectorController;
72  import org.openflexo.gina.swing.editor.palette.FIBEditorPalettes;
73  import org.openflexo.gina.swing.editor.palette.FIBEditorPalettesDialog;
74  import org.openflexo.gina.swing.editor.validation.ComponentValidationWindow;
75  import org.openflexo.gina.swing.utils.FIBEditorLoadingProgress;
76  import org.openflexo.gina.swing.utils.JFIBDialogInspectorController;
77  import org.openflexo.gina.swing.utils.JFIBPreferences;
78  import org.openflexo.gina.swing.utils.localization.LocalizedEditor;
79  import org.openflexo.gina.swing.view.JFIBView;
80  import org.openflexo.gina.swing.view.SwingViewFactory;
81  import org.openflexo.localization.FlexoLocalization;
82  import org.openflexo.localization.Language;
83  import org.openflexo.localization.LocalizedDelegate;
84  import org.openflexo.localization.LocalizedDelegateImpl;
85  import org.openflexo.logging.FlexoLogger;
86  import org.openflexo.pamela.exceptions.ModelDefinitionException;
87  import org.openflexo.pamela.factory.Clipboard;
88  import org.openflexo.rm.BasicResourceImpl.LocatorNotFoundException;
89  import org.openflexo.rm.FileResourceImpl;
90  import org.openflexo.rm.FileSystemResourceLocatorImpl;
91  import org.openflexo.rm.Resource;
92  import org.openflexo.rm.ResourceLocator;
93  import org.openflexo.swing.FlexoFileChooser;
94  import org.openflexo.toolbox.ToolBox;
95  
96  /**
97   * This class provides a generic framework for managing {@link FIBComponent} edition<br>
98   * 
99   * 
100  * @author sylvain
101  *
102  */
103 public class FIBEditor {
104 
105 	static final Logger logger = FlexoLogger.getLogger(FIBEditor.class.getPackage().getName());
106 
107 	public static LocalizedDelegate EDITOR_LOCALIZATION = new LocalizedDelegateImpl(
108 			ResourceLocator.locateResource("GinaLocalization/GinaSwingEditor"), FIBModelObjectImpl.GINA_LOCALIZATION, true, true);
109 
110 	public static Resource COMPONENT_LOCALIZATION_FIB = ResourceLocator.locateResource("Fib/LocalizedPanel.fib");
111 
112 	public static final int META_MASK = ToolBox.isMacOS() ? InputEvent.META_MASK : InputEvent.CTRL_MASK;
113 	public static final int MULTI_SELECTION_MASK = ToolBox.isMacOS() ? InputEvent.META_DOWN_MASK : InputEvent.CTRL_DOWN_MASK;
114 	public static final int DELETE_KEY_CODE = ToolBox.isMacOS() ? KeyEvent.VK_BACK_SPACE : KeyEvent.VK_DELETE;
115 	public static final int BACKSPACE_DELETE_KEY_CODE = ToolBox.isMacOS() ? KeyEvent.VK_DELETE : KeyEvent.VK_BACK_SPACE;
116 
117 	private FIBEditorPalettes palette;
118 	private JFIBDialogInspectorController inspector;
119 	private FIBEditorInspectorController inspectors;
120 
121 	protected LocalizedEditor localizedEditor;
122 	private ComponentValidationWindow componentValidationWindow;
123 	private ComponentLocalizationWindow componentLocalizationWindow;
124 
125 	final FileSystemResourceLocatorImpl resourceLocator;
126 
127 	static ApplicationFIBLibrary APP_FIB_LIBRARY = ApplicationFIBLibraryImpl.instance();
128 	private final FIBLibrary fibLibrary;
129 
130 	private MainPanel mainPanel;
131 	private FIBEditorMenuBar menuBar;
132 
133 	// This map stores all editors (FIBEditorController - editor of an EditedFIBComponent) managed by this FIBEditor
134 	private final Map<EditedFIBComponent, FIBEditorController> controllers = new HashMap<>();
135 
136 	private FIBEditorController activeEditorController = null;
137 
138 	private final FIBEditorLoadingProgress progress;
139 
140 	// Clipboard shared by all components opened in this FIBEditor
141 	private Clipboard clipboard;
142 
143 	public FIBEditor(FIBLibrary fibLibrary) {
144 		this(fibLibrary, null);
145 	}
146 
147 	public FIBEditor(FIBLibrary fibLibrary, FIBEditorLoadingProgress progress) {
148 		super();
149 
150 		this.fibLibrary = fibLibrary;
151 		this.progress = progress;
152 
153 		resourceLocator = new FileSystemResourceLocatorImpl();
154 		if (JFIBPreferences.getLastDirectory() != null) {
155 			resourceLocator.appendToDirectories(JFIBPreferences.getLastDirectory().getAbsolutePath());
156 		}
157 		resourceLocator.appendToDirectories(System.getProperty("user.home"));
158 		ResourceLocator.appendDelegate(resourceLocator);
159 
160 	}
161 
162 	/**
163 	 * Return a collection storing all components beeing edited in this FIBEditor
164 	 * 
165 	 * @return a collection of {@link EditedFIBComponent}
166 	 */
167 	public Collection<EditedFIBComponent> getEditedFIBComponents() {
168 		return controllers.keySet();
169 	}
170 
171 	/**
172 	 * Return {@link FIBEditorController} managing edition of {@link EditedFIBComponent}, asserting that supplied edited component is edited
173 	 * in this {@link FIBEditor}
174 	 * 
175 	 * @param editedComponent
176 	 * @return
177 	 */
178 	public FIBEditorController getControllerForEditedFIBComponent(EditedFIBComponent editedComponent) {
179 		return controllers.get(editedComponent);
180 	}
181 
182 	/**
183 	 * Return active {@link FIBEditorController}
184 	 * 
185 	 * @return
186 	 */
187 	public FIBEditorController getActiveEditorController() {
188 		return activeEditorController;
189 	}
190 
191 	/**
192 	 * Return active {@link EditedFIBComponent}
193 	 * 
194 	 * @return
195 	 */
196 	public EditedFIBComponent getActiveEditedComponent() {
197 		return activeEditorController.getEditedComponent();
198 	}
199 
200 	private static FlexoFileChooser getFileChooser(JFrame frame) {
201 		FlexoFileChooser fileChooser = new FlexoFileChooser(frame);
202 		fileChooser.setFileFilter(new FileFilter() {
203 
204 			@Override
205 			public String getDescription() {
206 				return "*.fib *.inspector";
207 			}
208 
209 			@Override
210 			public boolean accept(File f) {
211 				return f.isDirectory() || f.getName().endsWith(".fib") || f.getName().endsWith(".inspector");
212 			}
213 		});
214 		fileChooser.setCurrentDirectory(JFIBPreferences.getLastDirectory());
215 		return fileChooser;
216 	}
217 
218 	public FIBEditorMenuBar makeMenuBar(JFrame frame) {
219 		if (progress != null) {
220 			progress.progress(EDITOR_LOCALIZATION.localizedForKey("make_menu_bar"));
221 		}
222 		menuBar = new FIBEditorMenuBar(this, frame);
223 		return menuBar;
224 	}
225 
226 	public JFIBDialogInspectorController makeInspector(JFrame frame) {
227 		inspector = new JFIBDialogInspectorController(frame, ResourceLocator.locateResource("EditorInspectors"), APP_FIB_LIBRARY,
228 				EDITOR_LOCALIZATION, progress);
229 		return inspector;
230 	}
231 
232 	public FIBEditorPalettesDialog makePaletteDialog(JFrame frame) {
233 		if (palette == null) {
234 			if (progress != null) {
235 				progress.progress(EDITOR_LOCALIZATION.localizedForKey("make_palette_dialog"));
236 			}
237 			palette = makePalette();
238 		}
239 		return new FIBEditorPalettesDialog(frame, palette);
240 	}
241 
242 	public FIBEditorPalettes makePalette() {
243 		if (progress != null) {
244 			progress.progress(EDITOR_LOCALIZATION.localizedForKey("make_palette"));
245 		}
246 		palette = new FIBEditorPalettes();
247 		return palette;
248 	}
249 
250 	public FIBEditorInspectorController makeInspectors() {
251 		if (progress != null) {
252 			progress.progress(EDITOR_LOCALIZATION.localizedForKey("make_inspectors"));
253 		}
254 		inspectors = new FIBEditorInspectorController();
255 		return inspectors;
256 	}
257 
258 	public MainPanel makeMainPanel() {
259 		if (progress != null) {
260 			progress.progress(EDITOR_LOCALIZATION.localizedForKey("make_main_panel"));
261 		}
262 		mainPanel = new MainPanel(this);
263 		return mainPanel;
264 	}
265 
266 	public FIBLibrary getFIBLibrary() {
267 		return fibLibrary;
268 	}
269 
270 	public JFIBDialogInspectorController getInspector() {
271 		return inspector;
272 	}
273 
274 	public FIBEditorInspectorController getInspectors() {
275 		return inspectors;
276 	}
277 
278 	public FIBEditorPalettes getPalettes() {
279 		return palette;
280 	}
281 
282 	public FIBEditorMenuBar getMenuBar() {
283 		return menuBar;
284 	}
285 
286 	public MainPanel getMainPanel() {
287 		return mainPanel;
288 	}
289 
290 	private static void updateFrameTitle(JFrame frame) {
291 		frame.setTitle("Flexo Interface Builder Editor");
292 	}
293 
294 	public void quit() {
295 
296 		// TODO: Check if a component needs to be saved.
297 		/*
298 		 * for(FIBEditor.EditedFIB c: mainPanel.editedComponents) { }
299 		 */
300 		// frame.dispose();
301 		System.exit(0);
302 	}
303 
304 	// Edited components, stored using their source resource
305 	private final List<EditedFIBComponent> editedComponents = new ArrayList<>();
306 
307 	private EditedFIBComponent retrieveEditedFIBComponent(Resource resource) {
308 		return retrieveEditedFIBComponent(resource, null);
309 	}
310 
311 	private EditedFIBComponent retrieveEditedFIBComponent(Resource resource, FIBComponent fibComponent) {
312 
313 		EditedFIBComponent returned = null;
314 
315 		Resource sourceResource = ResourceLocator.locateSourceCodeResource(resource);
316 
317 		// First, attempt to lookup considering resource as source resource or production resource
318 		for (EditedFIBComponent e : editedComponents) {
319 			if (e.getSourceResource() != null && e.getSourceResource() == resource) {
320 				returned = e;
321 				break;
322 			}
323 			if (e.getProductionResource() != null && e.getProductionResource() == resource) {
324 				returned = e;
325 				break;
326 			}
327 		}
328 
329 		if (returned == null) {
330 			// OK, we have to instanciate it
331 			Resource productionResource = null;
332 			if (sourceResource == null || sourceResource.equals(resource)) {
333 				// no source resource means that resource is already source resource
334 				sourceResource = resource;
335 			}
336 			else {
337 				productionResource = resource;
338 			}
339 			if (fibComponent == null) {
340 				returned = new EditedFIBComponent(sourceResource, productionResource, getFIBLibrary());
341 			}
342 			else {
343 				returned = new EditedFIBComponent(fibComponent, getFIBLibrary());
344 				returned.setSourceResource(sourceResource);
345 				returned.setProductionResource(productionResource);
346 			}
347 			editedComponents.add(returned);
348 		}
349 
350 		return returned;
351 	}
352 
353 	/**
354 	 * Internally used to create and register a new {@link FIBEditorController} managing the edition of a {@link EditedFIBComponent}
355 	 * 
356 	 * @param newEditedFIB
357 	 * @param frame
358 	 * @return
359 	 */
360 	private FIBEditorController openEditedComponent(EditedFIBComponent newEditedFIB, Object dataObject, JFrame frame) {
361 
362 		newEditedFIB.setDataObject(dataObject);
363 
364 		FIBEditorController returned = controllers.get(newEditedFIB);
365 
366 		if (returned == null) {
367 			returned = new FIBEditorController(newEditedFIB, this, frame);
368 			controllers.put(newEditedFIB, returned);
369 			if (getMainPanel() != null) {
370 				mainPanel.newEditedComponent(returned);
371 			}
372 		}
373 
374 		if (dataObject != null) {
375 			returned.setDataObject(dataObject);
376 		}
377 
378 		activate(returned);
379 		return returned;
380 	}
381 
382 	/**
383 	 * Called to launch the edition of a FIBComponent in the editor<br>
384 	 * Editor might be retrieved from cache, using resource attached to component.
385 	 * 
386 	 * @param component
387 	 * @param frame
388 	 * @return
389 	 */
390 	public FIBEditorController openFIBComponent(FIBComponent component, Object dataObject, JFrame frame) {
391 
392 		EditedFIBComponent editedFIB = null;
393 		if (component.getResource() == null) {
394 			editedFIB = new EditedFIBComponent("New" + (newIndex > 0 ? newIndex + 1 : "") + ".fib", component, getFIBLibrary());
395 			editedComponents.add(editedFIB);
396 			newIndex++;
397 		}
398 		else {
399 			if (component.getResource() instanceof FileResourceImpl) {
400 				File fibFile = ((FileResourceImpl) component.getResource()).getFile();
401 				JFIBPreferences.setLastFile(fibFile);
402 			}
403 			editedFIB = retrieveEditedFIBComponent(component.getResource(), component);
404 		}
405 
406 		return openEditedComponent(editedFIB, dataObject, frame);
407 	}
408 
409 	/**
410 	 * Called to launch the edition of a FIBComponent - identified by its resource - in the editor<br>
411 	 * Editor might be retrieved from cache
412 	 * 
413 	 * @param fibResource
414 	 * @param frame
415 	 * @return
416 	 */
417 	public FIBEditorController openFIBComponent(Resource fibResource, FIBComponent fibComponent, Object dataObject, JFrame frame) {
418 
419 		if (fibResource instanceof FileResourceImpl) {
420 			File fibFile = ((FileResourceImpl) fibResource).getFile();
421 			JFIBPreferences.setLastFile(fibFile);
422 		}
423 
424 		EditedFIBComponent editedFIB = retrieveEditedFIBComponent(fibResource, fibComponent);
425 
426 		return openEditedComponent(editedFIB, dataObject, frame);
427 	}
428 
429 	private int newIndex = 0;
430 
431 	public FIBEditorController newFIB(JFrame frame) {
432 
433 		FIBModelFactory factory = null;
434 
435 		try {
436 			factory = new FIBModelFactory(null);
437 		} catch (ModelDefinitionException e) {
438 			e.printStackTrace();
439 			return null;
440 		}
441 
442 		FIBPanel fibComponent = factory.newInstance(FIBPanel.class);
443 		fibComponent.setLayout(Layout.border);
444 		fibComponent.finalizeDeserialization();
445 		EditedFIBComponent newEditedFIB = new EditedFIBComponent("New" + (newIndex > 0 ? newIndex + 1 : "") + ".fib", fibComponent,
446 				getFIBLibrary());
447 		editedComponents.add(newEditedFIB);
448 		newIndex++;
449 
450 		return openEditedComponent(newEditedFIB, null, frame);
451 	}
452 
453 	public FIBEditorController loadFIB(JFrame frame) {
454 
455 		FlexoFileChooser fileChooser = getFileChooser(frame);
456 
457 		if (fileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
458 			File fibFile = fileChooser.getSelectedFile();
459 			return loadFIB(fibFile, frame);
460 		}
461 
462 		return null;
463 	}
464 
465 	public FIBEditorController loadFIB(File fibFile, JFrame frame) {
466 		return loadFIB(fibFile, null, frame);
467 	}
468 
469 	public FIBEditorController loadFIB(Resource fibResource, JFrame frame) {
470 		return loadFIB(fibResource, null, frame);
471 	}
472 
473 	public FIBEditorController loadFIB(File fibFile, Object dataObject, JFrame frame) {
474 
475 		if (fibFile != null && !fibFile.exists()) {
476 			JOptionPane.showMessageDialog(frame, "File " + fibFile.getAbsolutePath() + " does not exist anymore");
477 			return null;
478 		}
479 		JFIBPreferences.setLastFile(fibFile);
480 
481 		FileResourceImpl fibResource = null;
482 		try {
483 			fibResource = new FileResourceImpl(resourceLocator, fibFile);
484 		} catch (Exception e) {
485 			e.printStackTrace();
486 			return null;
487 		}
488 
489 		return loadFIB(fibResource, dataObject, frame);
490 	}
491 
492 	public FIBEditorController loadFIB(Resource fibResource, Object dataObject, JFrame frame) {
493 
494 		EditedFIBComponent editedFIB = retrieveEditedFIBComponent(fibResource);
495 		editedFIB.setDataObject(dataObject);
496 
497 		return openEditedComponent(editedFIB, dataObject, frame);
498 	}
499 
500 	public void saveFIB(EditedFIBComponent editedFIB, JFrame frame) {
501 		if (editedFIB == null) {
502 			return;
503 		}
504 		if (editedFIB.getSourceResource() != null) {
505 			editedFIB.save();
506 		}
507 		else {
508 			saveFIBAs(editedFIB, frame);
509 		}
510 	}
511 
512 	public void saveFIBAs(EditedFIBComponent editedFIB, JFrame frame) {
513 		if (editedFIB == null) {
514 			return;
515 		}
516 
517 		FlexoFileChooser fileChooser = getFileChooser(frame);
518 
519 		if (fileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
520 			File file = fileChooser.getSelectedFile();
521 			System.out.println("file=" + file);
522 			if (!file.getName().endsWith(".fib")) {
523 				file = new File(file.getParentFile(), file.getName() + ".fib");
524 			}
525 			JFIBPreferences.setLastFile(file);
526 			try {
527 				editedFIB.saveAs(new FileResourceImpl(resourceLocator, file));
528 				mainPanel.getTabbedPane().setTitleAt(mainPanel.getTabbedPane().getSelectedIndex(), editedFIB.getName());
529 				updateFrameTitle(frame);
530 			} catch (MalformedURLException e) {
531 				e.printStackTrace();
532 			} catch (LocatorNotFoundException e) {
533 				e.printStackTrace();
534 			}
535 		}
536 	}
537 
538 	public void closeFIB(EditedFIBComponent editedFIB, JFrame frame) {
539 		logger.warning("Not implemented yet");
540 	}
541 
542 	public void testFIB(EditedFIBComponent editedFIB, JFrame frame) {
543 		JFIBView<?, ? extends JComponent> view = (JFIBView<?, ? extends JComponent>) FIBController.makeView(editedFIB.getFIBComponent(),
544 				SwingViewFactory.INSTANCE, EDITOR_LOCALIZATION, null, true);
545 
546 		if (editedFIB.getDataObject() != null) {
547 			view.getController().setDataObject(editedFIB.getDataObject());
548 		}
549 		else {
550 			if (editedFIB.getFIBComponent() instanceof FIBContainer
551 					&& ((FIBContainer) editedFIB.getFIBComponent()).getDataClass() != null) {
552 				try {
553 					// testClass =
554 					// Class.forName(editedFIB.fibComponent.getDataClassName());
555 					FIBContainer container = (FIBContainer) editedFIB.getFIBComponent();
556 					Object testData = container.getDataClass().newInstance();
557 					view.getController().setDataObject(testData);
558 				} catch (InstantiationException e) {
559 					e.printStackTrace();
560 				} catch (IllegalAccessException e) {
561 					e.printStackTrace();
562 				}
563 			}
564 			else {
565 				view.getController().updateWithoutDataObject();
566 			}
567 		}
568 
569 		JDialog testInterface = new JDialog(frame, "Test", false);
570 		testInterface.getContentPane().add(view.getResultingJComponent());
571 		testInterface.pack();
572 		testInterface.setVisible(true);
573 	}
574 
575 	public void localizeFIB(EditedFIBComponent editedFIB, JFrame frame) {
576 
577 		if (editedFIB != null && editedFIB.getFIBComponent() != null) {
578 			editedFIB.getFIBComponent().searchAndRegisterAllLocalized();
579 			getLocalizationWindow(editedFIB, frame).setVisible(true);
580 		}
581 
582 	}
583 
584 	public void validateFIB(EditedFIBComponent editedFIB, JFrame frame) {
585 		if (editedFIB != null && editedFIB.getFIBComponent() != null) {
586 			try {
587 				getValidationWindow(editedFIB, frame).validateAndDisplayReportForComponent(editedFIB.getFIBComponent());
588 			} catch (InterruptedException e) {
589 				e.printStackTrace();
590 			}
591 		}
592 	}
593 
594 	protected ComponentValidationWindow getValidationWindow(EditedFIBComponent editedComponent, JFrame frame) {
595 		if (componentValidationWindow != null && componentValidationWindow.getEditedComponent() != editedComponent) {
596 			componentValidationWindow.dispose();
597 			componentValidationWindow = null;
598 		}
599 		FIBEditorController editorController = getControllerForEditedFIBComponent(editedComponent);
600 		if (componentValidationWindow == null && editorController != null) {
601 			componentValidationWindow = new ComponentValidationWindow(frame, editorController, APP_FIB_LIBRARY);
602 		}
603 		return componentValidationWindow;
604 	}
605 
606 	protected ComponentLocalizationWindow getLocalizationWindow(EditedFIBComponent editedComponent, JFrame frame) {
607 		if (componentLocalizationWindow != null && componentLocalizationWindow.getEditedComponent() != editedComponent) {
608 			componentLocalizationWindow.dispose();
609 			componentLocalizationWindow = null;
610 		}
611 		FIBEditorController editorController = getControllerForEditedFIBComponent(editedComponent);
612 		if (componentLocalizationWindow == null && editorController != null) {
613 			componentLocalizationWindow = new ComponentLocalizationWindow(frame, editorController);
614 		}
615 		return componentLocalizationWindow;
616 	}
617 
618 	public void switchToLanguage(Language lang) {
619 		FlexoLocalization.setCurrentLanguage(lang);
620 		for (EditedFIBComponent editedComponent : getEditedFIBComponents()) {
621 			FIBEditorController editorController = getControllerForEditedFIBComponent(editedComponent);
622 			if (editorController != null) {
623 				editorController.switchToLanguage(lang);
624 			}
625 		}
626 
627 	}
628 
629 	public boolean activate(FIBEditorController editorController) {
630 		if (activeEditorController == editorController) {
631 			return false;
632 		}
633 		if (activeEditorController != null) {
634 			disactivate(activeEditorController);
635 		}
636 		System.out.println("Activate edition of " + editorController.getEditedComponent().getName());
637 		activeEditorController = editorController;
638 		if (getPalettes() != null) {
639 			getPalettes().setEditorController(editorController);
640 		}
641 		if (getMainPanel() != null) {
642 			mainPanel.focusOnEditedComponent(editorController);
643 		}
644 		return true;
645 	}
646 
647 	public boolean disactivate(FIBEditorController editorController) {
648 		if (activeEditorController == editorController) {
649 			System.out.println("Desactivate edition of " + editorController.getEditedComponent().getName());
650 			activeEditorController = null;
651 			if (getPalettes() != null) {
652 				getPalettes().setEditorController(null);
653 			}
654 			return true;
655 		}
656 		return false;
657 	}
658 
659 	public EditedFIBComponent getEditedFIBComponent(FIBComponent component) {
660 		for (EditedFIBComponent editedFIB : editedComponents) {
661 			if (editedFIB.getFIBComponent() == component) {
662 				return editedFIB;
663 			}
664 		}
665 		return null;
666 	}
667 
668 	/**
669 	 * Get clipboard shared by all components opened in this FIBEditor
670 	 * 
671 	 * @return
672 	 */
673 	public Clipboard getClipboard() {
674 		return clipboard;
675 	}
676 
677 	/**
678 	 * Sets clipboard shared by all components opened in this FIBEditor
679 	 * 
680 	 * @param clipboard
681 	 */
682 	public void setClipboard(Clipboard clipboard) {
683 		this.clipboard = clipboard;
684 	}
685 
686 }