1 /*******************************************************************************
2 * Copyright (c) 2012 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.modeling.ui.diagramEditor.e4;
14 import java.lang.reflect.Constructor;
16 import org.eclipse.core.runtime.IConfigurationElement;
17 import org.eclipse.core.runtime.IExecutableExtension;
18 import org.eclipse.core.runtime.Platform;
19 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
20 import org.eclipse.e4.ui.workbench.modeling.EPartService;
21 import org.eclipse.e4.ui.workbench.modeling.IPartListener;
22 import org.eclipse.osgi.util.NLS;
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.widgets.Composite;
25 import org.eclipse.ui.PartInitException;
26 import org.osgi.framework.Bundle;
27 import org.simantics.db.Resource;
28 import org.simantics.modeling.ui.diagramEditor.DisposingPolicy;
29 import org.simantics.modeling.ui.diagramEditor.e4.DiagramViewer.DiagramViewerHost;
30 import org.simantics.ui.workbench.e4.E4ResourceEditorBase;
31 import org.simantics.utils.ui.ErrorLogger;
34 * A class for diagram editor parts that contains logic for destruction and
35 * (re)initialization of the actual diagram viewer and its controls during the
36 * life cycle of this editor part.
39 * To use this class in an editor part extension, define the following in the
40 * <code>class</code> attribute of the extension:
43 * class="org.simantics.modeling.ui.diagramEditor.DiagramEditor:viewer=%VIEWER%"
46 * where <code>%VIEWER%</code> is the name of the class that either is or
47 * extends {@link org.simantics.modeling.ui.diagramEditor.DiagramViewer}. The
48 * <code>viewer</code> argument tells {@link DiagramEditor} where to find the
49 * initializer for the diagram editor controls. The initializer must have a
50 * default constructor.
53 * This class is not intended to be extended by clients. Customizations should
54 * be performed through the viewer class.
56 * @author Tuukka Lehtonen
57 * @author Antti Villberg
59 public class DiagramEditor extends E4ResourceEditorBase implements DiagramViewerHost, IExecutableExtension, IPartListener {
62 * The {@value #ARG_VIEWER} argument for this editor part class tells the
63 * name of the class to use for initializing the diagram viewer, i.e.
64 * {@link #viewer}. The class is instantiated through reflection using the
65 * class loader of the bundle named {@link #viewerContributor}.
67 * @see #setInitializationData(IConfigurationElement, String, Object)
69 public static final String ARG_VIEWER = "viewer"; //$NON-NLS-1$
71 private Composite parent;
73 private String viewerContributor;
74 private String viewerClassName;
76 // private ResourceEditorSupport support;
77 private DiagramViewer viewer;
80 * Reads the class arguments from the string in the data argument.
82 * @see org.eclipse.ui.part.EditorPart#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
83 * java.lang.String, java.lang.Object)
84 * @see #createViewer()
87 public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data) {
88 // super.setInitializationData(cfig, propertyName, data);
90 if (data instanceof String) {
91 viewerContributor = cfig.getContributor().getName();
93 String[] parameters = ((String) data).split(";"); //$NON-NLS-1$
95 for (String parameter : parameters) {
96 String[] keyValue = parameter.split("="); //$NON-NLS-1$
97 if (keyValue.length > 2) {
98 ErrorLogger.defaultLogWarning(NLS.bind(Messages.DiagramEditor_InvalidParameter, parameter, data),
102 String key = keyValue[0];
103 String value = keyValue.length > 1 ? keyValue[1] : ""; //$NON-NLS-1$
105 if (ARG_VIEWER.equals(key)) {
106 viewerClassName = value;
112 protected DiagramViewer createViewer() throws PartInitException {
113 if (viewerClassName == null)
114 throw new PartInitException(
115 "DiagramViewer contributor class was not specified in editor extension's class attribute viewer-argument. contributor is '" //$NON-NLS-1$
116 + viewerContributor + "'"); //$NON-NLS-1$
119 Bundle b = Platform.getBundle(viewerContributor);
121 throw new PartInitException("DiagramViewer '" + viewerClassName + "' contributor bundle '" //$NON-NLS-1$ //$NON-NLS-2$
122 + viewerContributor + "' was not found in the platform."); //$NON-NLS-1$
124 Class<?> clazz = b.loadClass(viewerClassName);
125 if (!DiagramViewer.class.isAssignableFrom(clazz))
126 throw new PartInitException("DiagramViewer class '" + viewerClassName + "' is not assignable to " //$NON-NLS-1$ //$NON-NLS-2$
127 + DiagramViewer.class + "."); //$NON-NLS-1$
129 Constructor<?> ctor = clazz.getConstructor();
130 return (DiagramViewer) ctor.newInstance();
131 } catch (Exception e) {
132 throw new PartInitException("Failed to instantiate DiagramViewer implementation '" + viewerClassName //$NON-NLS-1$
133 + "' from bundle '" + viewerContributor + "'. See exception for details.", e); //$NON-NLS-1$ //$NON-NLS-2$
137 public DiagramViewer getViewer() {
141 public Resource getRuntimeResource() {
142 DiagramViewer viewer = this.viewer;
143 return viewer != null ? viewer.getRuntime() : null;
146 // public Resource getInputResource() {
147 // DiagramViewer viewer = this.viewer;
148 // return viewer != null ? viewer.getInputResource() : null;
152 public void initImpl(MPart part) {
153 super.initImpl(part);
156 viewer = createViewer();
157 } catch (PartInitException e) {
158 // TODO Auto-generated catch block
161 // #TODO Finish this when we are going to use full E4 workbench
162 // viewer.init(this, getResourceInput());
164 EPartService partService = part.getContext().get(EPartService.class);
165 partService.addPartListener(this);
169 public void createPartControl(Composite parent) {
170 this.parent = parent;
174 private void initializeViewer() {
175 parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
176 viewer.createPartControl(parent);
177 // It is possible that something goes wrong and the parent gets disposed already
178 if(parent.isDisposed()) return;
183 public void setFocus() {
188 @SuppressWarnings("rawtypes")
189 public Object getAdapter(Class adapter) {
190 if (adapter == DiagramViewer.class)
192 if (viewer != null) {
193 Object result = viewer.getAdapter(adapter);
202 public void dispose() {
204 EPartService partService = getPart().getContext().get(EPartService.class);
205 partService.removePartListener(this);
207 DISPOSING_POLICY.removeDisposer(disposer);
213 public void doSetPartName(String name) {
214 getPart().setLabel(name);
218 public void doSetTitleToolTip(String tooltip) {
219 getPart().setTooltip(tooltip);
222 private static final DisposingPolicy DISPOSING_POLICY =
223 new DisposingPolicy();
225 private Runnable disposer = new Runnable() {
232 private void tryDisposeViewer() {
233 if (viewer != null) {
234 Composite viewerComposite = viewer.getComposite();
237 if (viewerComposite != null) {
238 viewerComposite.dispose();
244 public void partVisible(MPart part) {
245 if (getPart().equals(part)) {
246 DISPOSING_POLICY.removeDisposer(disposer);
247 if (viewer == null) {
249 viewer = createViewer();
250 // #TODO Finish this when we are going to use full E4 workbench
251 // viewer.init(DiagramEditor.this, getResourceInput());
253 } catch (PartInitException e) {
254 // This should never happen!
255 ErrorLogger.defaultLogError(e);
262 public void partHidden(MPart part) {
263 if (getPart().equals(part)) {
264 DISPOSING_POLICY.addDisposer(disposer);
269 public void partDeactivated(MPart part) {
273 public void partBroughtToTop(MPart part) {
277 public void partActivated(MPart part) {