View Javadoc

1   /*
2    * This file is a part of CAST project.
3    * (c) Copyright 2007, AGH University of Science & Technology
4    * https://caribou.iisg.agh.edu.pl/trac/cast
5    *
6    * Licensed under the Eclipse Public License, Version 1.0 (the "License").
7    * You may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    * http://www.eclipse.org/legal/epl-v10.html
10   */
11  /*
12   * File: AbstractEditor.java
13   * Created: 2008-03-09
14   * Author: awos
15   * $Id: AbstractEditor.java 2774 2009-04-22 13:56:23Z tmilos $
16   */
17  
18  package pl.edu.agh.cast.editor;
19  
20  import java.beans.PropertyChangeEvent;
21  import java.beans.PropertyChangeListener;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.LinkedList;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.UUID;
28  
29  import org.apache.log4j.Logger;
30  import org.eclipse.core.runtime.IProgressMonitor;
31  import org.eclipse.draw2d.IFigure;
32  import org.eclipse.draw2d.Viewport;
33  import org.eclipse.gef.ContextMenuProvider;
34  import org.eclipse.gef.EditPart;
35  import org.eclipse.gef.EditPartFactory;
36  import org.eclipse.gef.GraphicalViewer;
37  import org.eclipse.gef.KeyHandler;
38  import org.eclipse.gef.KeyStroke;
39  import org.eclipse.gef.LayerConstants;
40  import org.eclipse.gef.MouseWheelHandler;
41  import org.eclipse.gef.commands.Command;
42  import org.eclipse.gef.commands.CommandStackEvent;
43  import org.eclipse.gef.commands.CommandStackEventListener;
44  import org.eclipse.gef.dnd.TemplateTransferDragSourceListener;
45  import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
46  import org.eclipse.gef.editparts.ZoomManager;
47  import org.eclipse.gef.palette.PaletteGroup;
48  import org.eclipse.gef.palette.PaletteRoot;
49  import org.eclipse.gef.palette.SelectionToolEntry;
50  import org.eclipse.gef.ui.actions.ActionRegistry;
51  import org.eclipse.gef.ui.actions.ZoomInAction;
52  import org.eclipse.gef.ui.actions.ZoomOutAction;
53  import org.eclipse.gef.ui.palette.PaletteViewer;
54  import org.eclipse.gef.ui.palette.PaletteViewerProvider;
55  import org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences;
56  import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
57  import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
58  import org.eclipse.jface.action.IAction;
59  import org.eclipse.jface.commands.ActionHandler;
60  import org.eclipse.jface.viewers.StructuredSelection;
61  import org.eclipse.osgi.util.NLS;
62  import org.eclipse.swt.SWT;
63  import org.eclipse.ui.IEditorInput;
64  import org.eclipse.ui.IEditorPart;
65  import org.eclipse.ui.IEditorSite;
66  import org.eclipse.ui.IPartListener;
67  import org.eclipse.ui.ISaveablePart2;
68  import org.eclipse.ui.IWorkbenchPart;
69  import org.eclipse.ui.PartInitException;
70  import org.eclipse.ui.PlatformUI;
71  import org.eclipse.ui.actions.ActionFactory;
72  import org.eclipse.ui.handlers.IHandlerService;
73  
74  import pl.edu.agh.cast.Activator;
75  import pl.edu.agh.cast.CoreServiceLocator;
76  import pl.edu.agh.cast.data.model.IDataSet;
77  import pl.edu.agh.cast.data.model.IElement;
78  import pl.edu.agh.cast.data.model.presentation.IPresentationDataSet;
79  import pl.edu.agh.cast.data.model.presentation.IPresentationElement;
80  import pl.edu.agh.cast.data.model.visual.IVisualDataSet;
81  import pl.edu.agh.cast.data.model.visual.IVisualElement;
82  import pl.edu.agh.cast.editor.action.FitZoomAction;
83  import pl.edu.agh.cast.editor.action.SaveAllAction;
84  import pl.edu.agh.cast.editor.input.DiagramEditorInput;
85  import pl.edu.agh.cast.editor.input.IDiagramEditorInput;
86  import pl.edu.agh.cast.editor.input.ModelEditorInput;
87  import pl.edu.agh.cast.editpart.ZoomableScalableFreeformRootEditPart;
88  import pl.edu.agh.cast.model.visual.IDiagram;
89  import pl.edu.agh.cast.ui.util.MsgBoxHelper;
90  import pl.edu.agh.cast.util.Messages;
91  
92  /**
93   * Abstract graphical editor for showing CAST data.
94   * 
95   * @param <M>
96   *            presentation data set which is base of diagram
97   * @param <V>
98   *            visual data set which is base of diagram
99   * @param <T>
100  *            input diagram for editor
101  * @author AGH CAST Team
102  */
103 public abstract class AbstractEditor<M extends IPresentationDataSet<? extends IPresentationElement<? extends IElement>>, V extends IVisualDataSet<? extends IVisualElement<? extends IPresentationElement<? extends IElement>>, M>, T extends IDiagram<M, V>>
104         extends GraphicalEditorWithFlyoutPalette implements PropertyChangeListener, CommandStackEventListener,
105         ISaveablePart2 {
106 
107 	/**
108 	 * Logger for editor.
109 	 */
110 	protected static Logger log = Activator.getLogger();
111 
112 	// private RectangleZoomToolEntry rectangleZoomToolEntry;
113 
114 	// private ArrayList<NodeFactory> nodeFactories = new ArrayList<NodeFactory>();
115 
116 	private static IPartListener partActivationListener = new IPartListener() {
117 
118 		public void partActivated(IWorkbenchPart part) {
119 			// do nothing
120 		}
121 
122 		public void partBroughtToTop(IWorkbenchPart part) {
123 			// do nothing
124 		}
125 
126 		public void partClosed(IWorkbenchPart part) {
127 			// do nothing
128 		}
129 
130 		public void partDeactivated(IWorkbenchPart part) {
131 			// do nothing
132 		}
133 
134 		@SuppressWarnings("unchecked")
135 		public void partOpened(IWorkbenchPart part) {
136 			if (part instanceof AbstractEditor) {
137 				AbstractEditor editor = (AbstractEditor)part;
138 				// set default zoom as 'fit to page'
139 				ScalableFreeformRootEditPart rootEditPart = (ScalableFreeformRootEditPart)editor.getGraphicalViewer()
140 				        .getRootEditPart();
141 				// activate part so that zoom can get proper dimensions
142 				PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(part);
143 				// and calculate zoom
144 				rootEditPart.getZoomManager().setZoomAsText(ZoomManager.FIT_ALL);
145 				double zoom = rootEditPart.getZoomManager().getZoom();
146 				/*
147 				 * Warning. Do not optimize this code. rootEditPart.getZoomManager().setZoom() does not work for any
148 				 * zoom - it can only set zoom to one of the registered levels (50/100/150/200 etc). Therefore, zoom has
149 				 * to be changed only if it's not within the constraints of a specific editor.
150 				 */
151 				if (zoom > editor.getMaximumAllowedInitialZoom()) {
152 					rootEditPart.getZoomManager().setZoom(editor.getMaximumAllowedInitialZoom());
153 				}
154 				if (zoom < editor.getMinimumAllowedInitialZoom()) {
155 					rootEditPart.getZoomManager().setZoom(editor.getMinimumAllowedInitialZoom());
156 				}
157 				((ExtendedZoomManager)rootEditPart.getZoomManager()).scaleZoomLevels(zoom);
158 			}
159 		}
160 
161 	};
162 
163 	/**
164 	 * @return minimum allowed initial zoom for this editor, expressed as a double where 1.0 is 100% zoom
165 	 */
166 	protected abstract double getMinimumAllowedInitialZoom();
167 
168 	/**
169 	 * @return maximum allowed initial zoom for this editor, expressed as a double where 1.0 is 100% zoom
170 	 */
171 	protected abstract double getMaximumAllowedInitialZoom();
172 
173 	/**
174 	 * {@inheritDoc}
175 	 * 
176 	 * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#initializeGraphicalViewer()
177 	 */
178 	@Override
179 	protected void initializeGraphicalViewer() {
180 		super.initializeGraphicalViewer();
181 		getGraphicalViewer().setContents(getEditorInput());
182 		getCommandStack().addCommandStackEventListener(this);
183 
184 	}
185 
186 	/**
187 	 * {@inheritDoc}
188 	 * 
189 	 * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
190 	 */
191 	@SuppressWarnings("unchecked")
192 	@Override
193 	protected void setInput(IEditorInput input) {
194 		DiagramEditorInput<M, V, T> diagramEditorInput = null;
195 		if (input instanceof DiagramEditorInput) {
196 			diagramEditorInput = (DiagramEditorInput<M, V, T>)input;
197 		} else {
198 			ModelEditorInput<M> modelInput = (ModelEditorInput<M>)input;
199 			try {
200 				diagramEditorInput = modelToDiagram(modelInput);
201 			} catch (EditorException e) {
202 				log.error("Cannot set editor input. Fatal EditorException occured!", e); //$NON-NLS-1$
203 				return;
204 			}
205 		}
206 		super.setInput(diagramEditorInput);
207 		// diagramEditorInput.getDiagram().getView().addPropertyChangeListener(this);
208 	}
209 
210 	/**
211 	 * 
212 	 * {@inheritDoc}
213 	 * 
214 	 * @see org.eclipse.gef.ui.parts.GraphicalEditor#createActions()
215 	 */
216 	@SuppressWarnings("unchecked")
217 	protected void createActions() {
218 		super.createActions();
219 
220 		ActionRegistry registry = getActionRegistry();
221 		IAction action;
222 
223 		action = new SaveAllAction();
224 		registry.registerAction(action);
225 		getPropertyActions().add(action.getId());
226 	}
227 
228 	/**
229 	 * {@inheritDoc}
230 	 * 
231 	 * @see org.eclipse.ui.part.EditorPart#getEditorInput()
232 	 */
233 	@SuppressWarnings("unchecked")
234 	public IDiagramEditorInput<M, V, T> getEditorInput() {
235 		return (IDiagramEditorInput<M, V, T>)super.getEditorInput();
236 	}
237 
238 	/**
239 	 * {@inheritDoc}
240 	 * 
241 	 * @see org.eclipse.gef.ui.parts.GraphicalEditor#dispose()
242 	 */
243 	@Override
244 	public void dispose() {
245 		// T diagram = ((DiagramEditorInput<M, V, T>)getEditorInput()).getDiagram();
246 		// if (diagram != null) {
247 		// diagram.getView().removePropertyChangeListener(this);
248 		// }
249 
250 		getCommandStack().removeCommandStackEventListener(this);
251 	}
252 
253 	/**
254 	 * Convert the model editor input into diagram.
255 	 * 
256 	 * @param input
257 	 *            The editor input containing the presentation and visual data set.
258 	 * @return Diagram containing the presentation and visual data sets.
259 	 */
260 	// protected abstract DiagramEditorInput<M, V, T> modelToDiagram(ModelEditorInput<M> input);
261 	protected abstract DiagramEditorInput<M, V, T> modelToDiagram(
262 	        ModelEditorInput<? extends IDataSet<? extends IElement>> input) throws EditorException;
263 
264 	/**
265 	 * {@inheritDoc}
266 	 * 
267 	 * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#getPalettePreferences()
268 	 */
269 	@Override
270 	protected FlyoutPreferences getPalettePreferences() {
271 		return new DefaultFlayoutPreferences();
272 	}
273 
274 	/**
275 	 * {@inheritDoc}
276 	 * 
277 	 * @see org.eclipse.gef.ui.parts.GraphicalEditor#configureGraphicalViewer()
278 	 */
279 	@Override
280 	protected void configureGraphicalViewer() {
281 		super.configureGraphicalViewer();
282 		GraphicalViewer viewer = getGraphicalViewer();
283 
284 		// viewer.setRootEditPart(new ExtendedScalableFreeformRootEditPart());
285 		// TODO: ZOOM
286 		viewer.setRootEditPart(new ZoomableScalableFreeformRootEditPart());
287 		viewer.setEditPartFactory(getEditPartsFactory());
288 
289 		KeyHandler keyHandler = new GraphicalViewerKeyHandler(viewer);
290 		keyHandler.setParent(getCommonKeyHandler());
291 		viewer.setKeyHandler(keyHandler);
292 
293 		setupZoom();
294 
295 		viewer.setProperty(MouseWheelHandler.KeyGenerator.getKey(SWT.MOD2), ExtendedMouseWheelScrollHandler
296 		        .getInstance());
297 
298 		registerContextMenu();
299 		// XXX to investigate/reimplement later
300 		// viewer.addDropTargetListener(new EntityDropTargetListener(viewer));
301 	}
302 
303 	protected KeyHandler getCommonKeyHandler() {
304 		KeyHandler sharedKeyHandler = new KeyHandler();
305 
306 		sharedKeyHandler.put(KeyStroke.getPressed((char)26, 'z', SWT.CTRL), getActionRegistry().getAction(
307 		        ActionFactory.UNDO.getId()));
308 		sharedKeyHandler.put(KeyStroke.getPressed((char)25, 'y', SWT.CTRL), getActionRegistry().getAction(
309 		        ActionFactory.REDO.getId()));
310 		sharedKeyHandler.put(KeyStroke.getPressed(SWT.DEL, 127, 0), getActionRegistry().getAction(
311 		        ActionFactory.DELETE.getId()));
312 
313 		return sharedKeyHandler;
314 	}
315 
316 	/**
317 	 * Sets up various actions and handlers needed for zoom support.
318 	 */
319 	private void setupZoom() {
320 		GraphicalViewer viewer = getGraphicalViewer();
321 		ScalableFreeformRootEditPart rootEditPart = (ScalableFreeformRootEditPart)viewer.getRootEditPart();
322 		// TODO: ZOOM
323 		// rectangleZoomToolEntry.setZoomManager(rootEditPart.getZoomManager());
324 		List<String> zoomLevels = new ArrayList<String>(3);
325 		zoomLevels.add(ZoomManager.FIT_ALL);
326 		zoomLevels.add(ZoomManager.FIT_WIDTH);
327 		zoomLevels.add(ZoomManager.FIT_HEIGHT);
328 		rootEditPart.getZoomManager().setZoomLevelContributions(zoomLevels);
329 
330 		// create actions for zooming in, out and fit
331 		IAction zoomIn = new ZoomInAction(rootEditPart.getZoomManager());
332 		IAction zoomOut = new ZoomOutAction(rootEditPart.getZoomManager());
333 		IAction fitZoom = new FitZoomAction(Messages.FitZoomAction_0, null, rootEditPart.getZoomManager());
334 		getActionRegistry().registerAction(zoomIn);
335 		getActionRegistry().registerAction(zoomOut);
336 		getActionRegistry().registerAction(fitZoom);
337 
338 		// register the key shortcuts for zooming in/out (Ctrl -, Ctrl =)
339 		IHandlerService service = (IHandlerService)getEditorSite().getService(IHandlerService.class);
340 		service.activateHandler(zoomIn.getActionDefinitionId(), new ActionHandler(zoomIn));
341 		service.activateHandler(zoomOut.getActionDefinitionId(), new ActionHandler(zoomOut));
342 		// register the mouse wheel zoom handler
343 		viewer
344 		        .setProperty(MouseWheelHandler.KeyGenerator.getKey(SWT.MOD1), ExtendedMouseWheelZoomHandler
345 		                .getInstance());
346 	}
347 
348 	/**
349 	 * Returns editor's viewport.
350 	 * 
351 	 * @return editor's viewport
352 	 */
353 	public Viewport getEditorViewport() {
354 		return (Viewport)((ScalableFreeformRootEditPart)getGraphicalViewer().getRootEditPart()).getFigure();
355 	}
356 
357 	/**
358 	 * Returns editor's printable layer.
359 	 * 
360 	 * @return editor's printable layer
361 	 */
362 	public IFigure getPrintableLayer() {
363 		return ((ScalableFreeformRootEditPart)getGraphicalViewer().getRootEditPart())
364 		        .getLayer(LayerConstants.PRINTABLE_LAYERS);
365 	}
366 
367 	/**
368 	 * Registers context menu Can be called by subclasses to reregister the menu if the action registry is modified
369 	 */
370 	protected final void registerContextMenu() {
371 		GraphicalViewer viewer = getGraphicalViewer();
372 		ContextMenuProvider cmProvider = getContextMenuProvider();
373 		viewer.setContextMenu(cmProvider);
374 		getSite().registerContextMenu(cmProvider, viewer);
375 	}
376 
377 	/**
378 	 * Return the context menu provider. See {@link ContextMenuProvider}.
379 	 * 
380 	 * @return The context menu provider.
381 	 */
382 	protected abstract ContextMenuProvider getContextMenuProvider();
383 
384 	/**
385 	 * {@inheritDoc}
386 	 * 
387 	 * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#getPaletteRoot()
388 	 */
389 	@Override
390 	protected PaletteRoot getPaletteRoot() {
391 
392 		PaletteRoot root = new PaletteRoot();
393 
394 		PaletteGroup basic = new PaletteGroup(Messages.AbstractEditor_0);
395 
396 		SelectionToolEntry selectionToolEntry = new SelectionToolEntry();
397 		basic.add(selectionToolEntry);
398 
399 		// TODO ZOOM
400 		// IVisualResource resource = CoreServiceLocator.getResourceRegistry().getResource(
401 		// CoreVisualResourcesProvider.CHECKBOX_CLEARED);
402 		// ImageDescriptor desc = ImageDescriptor.createFromImage(resource.getImage());
403 
404 		// rectangleZoomToolEntry = new RectangleZoomToolEntry("Rectangle zoom", "rectangle zoom", desc, desc);
405 
406 		// [fibinger] temporarily removed, I remember about it :)
407 		// basic.add(rectangleZoomToolEntry);
408 
409 		root.add(basic);
410 
411 		root.setDefaultEntry(selectionToolEntry);
412 		return root;
413 
414 	}
415 
416 	/**
417 	 * Delegates save process to {@link #doSaveWithoutMessageBox(IProgressMonitor)} and shows info in message box.
418 	 * 
419 	 * {@inheritDoc}
420 	 * 
421 	 * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
422 	 */
423 	@Override
424 	public void doSave(IProgressMonitor monitor) {
425 		doSaveWithoutMessageBox(monitor);
426 
427 		MsgBoxHelper.showInfoBox(PlatformUI.getWorkbench().getDisplay().getActiveShell(), Messages.AbstractEditor_1,
428 		        NLS.bind(Messages.AbstractEditor_2, getDiagram().getName()));
429 
430 	}
431 
432 	/**
433 	 * Saves current diagram without any information to user. It is introduced because save all action has its own
434 	 * message after saving all diagrams.
435 	 * 
436 	 * Save steps:
437 	 * <ol>
438 	 * <li>save view and presentation data set in persistence provider
439 	 * <li>get a new id of visual data set and load the data set
440 	 * <li>set a new model input for editor from the data set
441 	 * <li>refresh the editor and mark as saved
442 	 * </ol>
443 	 * 
444 	 * TODO: use progress monitor
445 	 * 
446 	 * @param monitor
447 	 *            progress monitor
448 	 */
449 	@SuppressWarnings("unchecked")
450 	public void doSaveWithoutMessageBox(IProgressMonitor monitor) {
451 
452 		// save diagram in persistence layer
453 		Map<UUID, UUID> dataSetsIds = CoreServiceLocator.getPersistenceProvider().saveDataSets(
454 		        getDiagram().getDataSets());
455 		if (dataSetsIds == null || dataSetsIds.size() != 2) {
456 			throw new RuntimeException("An error occured during saving diagram"); //$NON-NLS-1$
457 		}
458 		log.info("Diagram saved in persistance manager"); //$NON-NLS-1$
459 
460 		// read saved data set
461 		M model = (M)CoreServiceLocator.getPersistenceProvider().getDataSet(
462 		        dataSetsIds.get(getDiagram().getModel().getId()));
463 
464 		if (model == null) {
465 			throw new RuntimeException("An error occured during saving diagram"); //$NON-NLS-1$
466 		}
467 
468 		// refresh editor with new data set
469 		setInput(new ModelEditorInput<M>(model));
470 		firePropertyChange(IEditorPart.PROP_INPUT);
471 		log.info("New editor input set"); //$NON-NLS-1$
472 
473 		getCommandStack().markSaveLocation();
474 		firePropertyChange(IEditorPart.PROP_DIRTY);
475 
476 		log.info(String.format("Diagram %1$s successfully saved.", getDiagram().getName())); //$NON-NLS-1$
477 	}
478 
479 	/**
480 	 * Gets diagram in current editor input.
481 	 * 
482 	 * @return returns diagram
483 	 */
484 	public T getDiagram() {
485 		DiagramEditorInput<M, V, T> input = (DiagramEditorInput<M, V, T>)getEditorInput();
486 		return input.getDiagram();
487 
488 	}
489 
490 	/**
491 	 * {@inheritDoc}
492 	 * 
493 	 * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#getAdapter(java.lang.Class)
494 	 */
495 	@SuppressWarnings("unchecked")
496 	@Override
497 	public Object getAdapter(Class type) {
498 		if (type == ZoomManager.class) {
499 			return getGraphicalViewer().getProperty(ZoomManager.class.toString());
500 		}
501 
502 		return super.getAdapter(type);
503 	}
504 
505 	/**
506 	 * {@inheritDoc}
507 	 * 
508 	 * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#createPaletteViewerProvider()
509 	 */
510 	@Override
511 	protected PaletteViewerProvider createPaletteViewerProvider() {
512 		return new PaletteViewerProvider(getEditDomain()) {
513 			@Override
514 			protected void configurePaletteViewer(PaletteViewer viewer) {
515 				super.configurePaletteViewer(viewer);
516 				viewer.addDragSourceListener(new TemplateTransferDragSourceListener(viewer));
517 			}
518 		};
519 	}
520 
521 	/**
522 	 * {@inheritDoc}
523 	 * 
524 	 * @see org.eclipse.gef.ui.parts.GraphicalEditor#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
525 	 */
526 	@Override
527 	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
528 		super.init(site, input);
529 		site.getPage().addPartListener(partActivationListener);
530 	}
531 
532 	/**
533 	 * {@inheritDoc}
534 	 * 
535 	 * @see org.eclipse.ui.part.WorkbenchPart#getPartName()
536 	 */
537 	@Override
538 	public String getPartName() {
539 		IDiagramEditorInput<M, V, T> input = getEditorInput();
540 		if (input != null) {
541 			return input.getDiagram().getName();
542 		} else {
543 			return ""; //$NON-NLS-1$
544 		}
545 	}
546 
547 	/**
548 	 * {@inheritDoc}
549 	 * 
550 	 * @see org.eclipse.ui.part.WorkbenchPart#getTitle()
551 	 */
552 	@Override
553 	public String getTitle() {
554 		return getPartName();
555 	}
556 
557 	/**
558 	 * {@inheritDoc}
559 	 * 
560 	 * @see org.eclipse.ui.part.EditorPart#getTitleToolTip()
561 	 */
562 	@Override
563 	public String getTitleToolTip() {
564 		IDiagramEditorInput<M, V, T> input = getEditorInput();
565 		// IDiagram diagram = input.getDiagram();
566 		// if (diagram.getFile() != null) {
567 		// return NLS.bind(Messages.AbstractEditor_9, new Object[] { diagram.getName(),
568 		// diagram.getFile().getFullPath() });
569 		// } else {
570 		// TODO adjust the message properly
571 		return NLS.bind(Messages.AbstractEditor_9, new Object[] { input.getDiagram().getName(), "---" }); //$NON-NLS-1$
572 		// }
573 	}
574 
575 	/**
576 	 * {@inheritDoc}
577 	 * 
578 	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
579 	 */
580 	public void propertyChange(PropertyChangeEvent evt) {
581 		// XXX to investigate/reimplement later
582 		/*
583 		 * if (Diagram.NAME.equals(evt.getPropertyName()) || Diagram.FILE.equals(evt.getPropertyName())) { // refresh
584 		 * part names setPartName(getPartName()); setTitleToolTip(getTitleToolTip()); // save after diagram change to
585 		 * refresh navigator on the left doSave(null); } else if
586 		 * (DiagramSettings.LEGEND_SHOWN.equals(evt.getPropertyName())) { this.refresh(); }
587 		 */
588 	}
589 
590 	/**
591 	 * Executes command.
592 	 * 
593 	 * @param command
594 	 *            command to execute
595 	 */
596 	public void executeCommand(Command command) {
597 		getCommandStack().execute(command);
598 	}
599 
600 	/**
601 	 * Refresh the viewer.
602 	 */
603 	public void refresh() {
604 		getGraphicalViewer().setContents(getEditorInput());
605 	}
606 
607 	/**
608 	 * {@inheritDoc}
609 	 * 
610 	 * @see org.eclipse.gef.commands.CommandStackEventListener#stackChanged(org.eclipse.gef.commands.CommandStackEvent)
611 	 */
612 	public void stackChanged(CommandStackEvent event) {
613 		firePropertyChange(IEditorPart.PROP_DIRTY);
614 	}
615 
616 	/**
617 	 * Selects given visual elements.
618 	 * 
619 	 * @param elements
620 	 *            list of elements to select
621 	 */
622 	public void selectElements(Collection<? extends IPresentationElement<? extends IElement>> elements) {
623 		getGraphicalViewer().deselectAll();
624 		List<EditPart> selection = new LinkedList<EditPart>();
625 
626 		for (IPresentationElement<? extends IElement> e : elements) {
627 			EditPart editPart = (EditPart)getGraphicalViewer().getEditPartRegistry().get(e);
628 			if (editPart != null) {
629 				selection.add(editPart);
630 			}
631 		}
632 		getGraphicalViewer().setSelection(new StructuredSelection(selection));
633 	}
634 
635 	/**
636 	 * {@inheritDoc}
637 	 * 
638 	 * @see org.eclipse.ui.ISaveablePart2#promptToSaveOnClose()
639 	 */
640 	public int promptToSaveOnClose() {
641 		return EditorSaverSupport.getInstance().promptToSaveOnClose(this);
642 	}
643 
644 	/**
645 	 * Gets {@link EditPartFactory} for this editor.
646 	 * 
647 	 * @return {@link EditPartFactory}
648 	 */
649 	public abstract EditPartFactory getEditPartsFactory();
650 
651 }