1 /*******************************************************************************
\r
2 * Copyright (c) 2012 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.modeling.ui.diagramEditor.e4;
\r
14 import java.lang.reflect.Constructor;
\r
16 import org.eclipse.core.runtime.IConfigurationElement;
\r
17 import org.eclipse.core.runtime.IExecutableExtension;
\r
18 import org.eclipse.core.runtime.Platform;
\r
19 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
\r
20 import org.eclipse.e4.ui.workbench.modeling.EPartService;
\r
21 import org.eclipse.e4.ui.workbench.modeling.IPartListener;
\r
22 import org.eclipse.swt.SWT;
\r
23 import org.eclipse.swt.widgets.Composite;
\r
24 import org.eclipse.ui.PartInitException;
\r
25 import org.osgi.framework.Bundle;
\r
26 import org.simantics.db.Resource;
\r
27 import org.simantics.modeling.ui.diagramEditor.DisposingPolicy;
\r
28 import org.simantics.modeling.ui.diagramEditor.e4.DiagramViewer.DiagramViewerHost;
\r
29 import org.simantics.ui.workbench.e4.E4ResourceEditorBase;
\r
30 import org.simantics.utils.ui.ErrorLogger;
\r
33 * A class for diagram editor parts that contains logic for destruction and
\r
34 * (re)initialization of the actual diagram viewer and its controls during the
\r
35 * life cycle of this editor part.
\r
38 * To use this class in an editor part extension, define the following in the
\r
39 * <code>class</code> attribute of the extension:
\r
42 * class="org.simantics.modeling.ui.diagramEditor.DiagramEditor:viewer=%VIEWER%"
\r
45 * where <code>%VIEWER%</code> is the name of the class that either is or
\r
46 * extends {@link org.simantics.modeling.ui.diagramEditor.DiagramViewer}. The
\r
47 * <code>viewer</code> argument tells {@link DiagramEditor} where to find the
\r
48 * initializer for the diagram editor controls. The initializer must have a
\r
49 * default constructor.
\r
52 * This class is not intended to be extended by clients. Customizations should
\r
53 * be performed through the viewer class.
\r
55 * @author Tuukka Lehtonen
\r
56 * @author Antti Villberg
\r
58 public class DiagramEditor extends E4ResourceEditorBase implements DiagramViewerHost, IExecutableExtension, IPartListener {
\r
61 * The {@value #ARG_VIEWER} argument for this editor part class tells the
\r
62 * name of the class to use for initializing the diagram viewer, i.e.
\r
63 * {@link #viewer}. The class is instantiated through reflection using the
\r
64 * class loader of the bundle named {@link #viewerContributor}.
\r
66 * @see #setInitializationData(IConfigurationElement, String, Object)
\r
68 public static final String ARG_VIEWER = "viewer";
\r
70 private Composite parent;
\r
72 private String viewerContributor;
\r
73 private String viewerClassName;
\r
75 // private ResourceEditorSupport support;
\r
76 private DiagramViewer viewer;
\r
79 * Reads the class arguments from the string in the data argument.
\r
81 * @see org.eclipse.ui.part.EditorPart#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
\r
82 * java.lang.String, java.lang.Object)
\r
83 * @see #createViewer()
\r
86 public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data) {
\r
87 // super.setInitializationData(cfig, propertyName, data);
\r
89 if (data instanceof String) {
\r
90 viewerContributor = cfig.getContributor().getName();
\r
92 String[] parameters = ((String) data).split(";");
\r
94 for (String parameter : parameters) {
\r
95 String[] keyValue = parameter.split("=");
\r
96 if (keyValue.length > 2) {
\r
97 ErrorLogger.defaultLogWarning("Invalid parameter '" + parameter + ". Complete view argument: " + data, null);
\r
100 String key = keyValue[0];
\r
101 String value = keyValue.length > 1 ? keyValue[1] : "";
\r
103 if (ARG_VIEWER.equals(key)) {
\r
104 viewerClassName = value;
\r
110 protected DiagramViewer createViewer() throws PartInitException {
\r
111 if (viewerClassName == null)
\r
112 throw new PartInitException(
\r
113 "DiagramViewer contributor class was not specified in editor extension's class attribute viewer-argument. contributor is '"
\r
114 + viewerContributor + "'");
\r
117 Bundle b = Platform.getBundle(viewerContributor);
\r
119 throw new PartInitException("DiagramViewer '" + viewerClassName + "' contributor bundle '"
\r
120 + viewerContributor + "' was not found in the platform.");
\r
122 Class<?> clazz = b.loadClass(viewerClassName);
\r
123 if (!DiagramViewer.class.isAssignableFrom(clazz))
\r
124 throw new PartInitException("DiagramViewer class '" + viewerClassName + "' is not assignable to "
\r
125 + DiagramViewer.class + ".");
\r
127 Constructor<?> ctor = clazz.getConstructor();
\r
128 return (DiagramViewer) ctor.newInstance();
\r
129 } catch (Exception e) {
\r
130 throw new PartInitException("Failed to instantiate DiagramViewer implementation '" + viewerClassName
\r
131 + "' from bundle '" + viewerContributor + "'. See exception for details.", e);
\r
135 public DiagramViewer getViewer() {
\r
139 public Resource getRuntimeResource() {
\r
140 DiagramViewer viewer = this.viewer;
\r
141 return viewer != null ? viewer.getRuntime() : null;
\r
144 // public Resource getInputResource() {
\r
145 // DiagramViewer viewer = this.viewer;
\r
146 // return viewer != null ? viewer.getInputResource() : null;
\r
150 public void initImpl(MPart part) {
\r
151 super.initImpl(part);
\r
154 viewer = createViewer();
\r
155 } catch (PartInitException e) {
\r
156 // TODO Auto-generated catch block
\r
157 e.printStackTrace();
\r
159 // #TODO Finish this when we are going to use full E4 workbench
\r
160 // viewer.init(this, getResourceInput());
\r
162 EPartService partService = part.getContext().get(EPartService.class);
\r
163 partService.addPartListener(this);
\r
167 public void createPartControl(Composite parent) {
\r
168 this.parent = parent;
\r
169 initializeViewer();
\r
172 private void initializeViewer() {
\r
173 parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
\r
174 viewer.createPartControl(parent);
\r
175 // It is possible that something goes wrong and the parent gets disposed already
\r
176 if(parent.isDisposed()) return;
\r
177 parent.layout(true);
\r
181 public void setFocus() {
\r
182 if (viewer != null)
\r
186 @SuppressWarnings("rawtypes")
\r
187 public Object getAdapter(Class adapter) {
\r
188 if (adapter == DiagramViewer.class)
\r
190 if (viewer != null) {
\r
191 Object result = viewer.getAdapter(adapter);
\r
192 if (result != null)
\r
200 public void dispose() {
\r
202 EPartService partService = getPart().getContext().get(EPartService.class);
\r
203 partService.removePartListener(this);
\r
205 DISPOSING_POLICY.removeDisposer(disposer);
\r
206 tryDisposeViewer();
\r
211 public void doSetPartName(String name) {
\r
212 getPart().setLabel(name);
\r
216 public void doSetTitleToolTip(String tooltip) {
\r
217 getPart().setTooltip(tooltip);
\r
220 private static final DisposingPolicy DISPOSING_POLICY =
\r
221 new DisposingPolicy();
\r
223 private Runnable disposer = new Runnable() {
\r
225 public void run() {
\r
226 tryDisposeViewer();
\r
230 private void tryDisposeViewer() {
\r
231 if (viewer != null) {
\r
232 Composite viewerComposite = viewer.getComposite();
\r
235 if (viewerComposite != null) {
\r
236 viewerComposite.dispose();
\r
242 public void partVisible(MPart part) {
\r
243 if (getPart().equals(part)) {
\r
244 DISPOSING_POLICY.removeDisposer(disposer);
\r
245 if (viewer == null) {
\r
247 viewer = createViewer();
\r
248 // #TODO Finish this when we are going to use full E4 workbench
\r
249 // viewer.init(DiagramEditor.this, getResourceInput());
\r
250 initializeViewer();
\r
251 } catch (PartInitException e) {
\r
252 // This should never happen!
\r
253 ErrorLogger.defaultLogError(e);
\r
260 public void partHidden(MPart part) {
\r
261 if (getPart().equals(part)) {
\r
262 DISPOSING_POLICY.addDisposer(disposer);
\r
267 public void partDeactivated(MPart part) {
\r
271 public void partBroughtToTop(MPart part) {
\r
275 public void partActivated(MPart part) {
\r