]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/e4/DiagramEditor.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagramEditor / e4 / DiagramEditor.java
1 /*******************************************************************************
2  * Copyright (c) 2012 Association for Decentralized Information Management in
3  * Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.modeling.ui.diagramEditor.e4;
13
14 import java.lang.reflect.Constructor;
15
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.swt.SWT;
23 import org.eclipse.swt.widgets.Composite;
24 import org.eclipse.ui.PartInitException;
25 import org.osgi.framework.Bundle;
26 import org.simantics.db.Resource;
27 import org.simantics.modeling.ui.diagramEditor.DisposingPolicy;
28 import org.simantics.modeling.ui.diagramEditor.e4.DiagramViewer.DiagramViewerHost;
29 import org.simantics.ui.workbench.e4.E4ResourceEditorBase;
30 import org.simantics.utils.ui.ErrorLogger;
31
32 /**
33  * A class for diagram editor parts that contains logic for destruction and
34  * (re)initialization of the actual diagram viewer and its controls during the
35  * life cycle of this editor part.
36  * 
37  * <p>
38  * To use this class in an editor part extension, define the following in the
39  * <code>class</code> attribute of the extension:
40  * 
41  * <pre>
42  * class="org.simantics.modeling.ui.diagramEditor.DiagramEditor:viewer=%VIEWER%"
43  * </pre>
44  * 
45  * where <code>%VIEWER%</code> is the name of the class that either is or
46  * extends {@link org.simantics.modeling.ui.diagramEditor.DiagramViewer}. The
47  * <code>viewer</code> argument tells {@link DiagramEditor} where to find the
48  * initializer for the diagram editor controls. The initializer must have a
49  * default constructor.
50  * 
51  * <p>
52  * This class is not intended to be extended by clients. Customizations should
53  * be performed through the viewer class.
54  * 
55  * @author Tuukka Lehtonen
56  * @author Antti Villberg
57  */
58 public class DiagramEditor extends E4ResourceEditorBase implements DiagramViewerHost, IExecutableExtension, IPartListener {
59
60     /**
61      * The {@value #ARG_VIEWER} argument for this editor part class tells the
62      * name of the class to use for initializing the diagram viewer, i.e.
63      * {@link #viewer}. The class is instantiated through reflection using the
64      * class loader of the bundle named {@link #viewerContributor}.
65      * 
66      * @see #setInitializationData(IConfigurationElement, String, Object)
67      */
68     public static final String    ARG_VIEWER = "viewer";
69
70     private Composite             parent;
71
72     private String                viewerContributor;
73     private String                viewerClassName;
74
75 //    private ResourceEditorSupport support;
76     private DiagramViewer         viewer;
77
78     /**
79      * Reads the class arguments from the string in the data argument.
80      * 
81      * @see org.eclipse.ui.part.EditorPart#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
82      *      java.lang.String, java.lang.Object)
83      * @see #createViewer()
84      */
85     @Override
86     public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data) {
87 //        super.setInitializationData(cfig, propertyName, data);
88
89         if (data instanceof String) {
90             viewerContributor = cfig.getContributor().getName();
91
92             String[] parameters = ((String) data).split(";");
93
94             for (String parameter : parameters) {
95                 String[] keyValue = parameter.split("=");
96                 if (keyValue.length > 2) {
97                     ErrorLogger.defaultLogWarning("Invalid parameter '" + parameter + ". Complete view argument: " + data, null);
98                     continue;
99                 }
100                 String key = keyValue[0];
101                 String value = keyValue.length > 1 ? keyValue[1] : "";
102
103                 if (ARG_VIEWER.equals(key)) {
104                     viewerClassName = value;
105                 } 
106             }
107         }
108     }
109
110     protected DiagramViewer createViewer() throws PartInitException {
111         if (viewerClassName == null)
112             throw new PartInitException(
113                     "DiagramViewer contributor class was not specified in editor extension's class attribute viewer-argument. contributor is '"
114                             + viewerContributor + "'");
115
116         try {
117             Bundle b = Platform.getBundle(viewerContributor);
118             if (b == null)
119                 throw new PartInitException("DiagramViewer '" + viewerClassName + "' contributor bundle '"
120                         + viewerContributor + "' was not found in the platform.");
121
122             Class<?> clazz = b.loadClass(viewerClassName);
123             if (!DiagramViewer.class.isAssignableFrom(clazz))
124                 throw new PartInitException("DiagramViewer class '" + viewerClassName + "' is not assignable to "
125                         + DiagramViewer.class + ".");
126
127             Constructor<?> ctor = clazz.getConstructor();
128             return (DiagramViewer) ctor.newInstance();
129         } catch (Exception e) {
130             throw new PartInitException("Failed to instantiate DiagramViewer implementation '" + viewerClassName
131                     + "' from bundle '" + viewerContributor + "'. See exception for details.", e);
132         }
133     }
134
135     public DiagramViewer getViewer() {
136         return viewer;
137     }
138
139     public Resource getRuntimeResource() {
140         DiagramViewer viewer = this.viewer;
141         return viewer != null ? viewer.getRuntime() : null;
142     }
143     
144 //    public Resource getInputResource() {
145 //        DiagramViewer viewer = this.viewer;
146 //        return viewer != null ? viewer.getInputResource() : null;
147 //    }
148
149     @Override
150     public void initImpl(MPart part) {
151         super.initImpl(part);
152  
153         try {
154             viewer = createViewer();
155         } catch (PartInitException e) {
156             // TODO Auto-generated catch block
157             e.printStackTrace();
158         }
159         // #TODO Finish this when we are going to use full E4 workbench
160 //        viewer.init(this, getResourceInput());
161         
162         EPartService partService = part.getContext().get(EPartService.class);
163         partService.addPartListener(this);
164     }
165
166     @Override
167     public void createPartControl(Composite parent) {
168         this.parent = parent;
169         initializeViewer();
170     }
171
172     private void initializeViewer() {
173         parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
174         viewer.createPartControl(parent);
175         // It is possible that something goes wrong and the parent gets disposed already
176         if(parent.isDisposed()) return;
177         parent.layout(true);
178     }
179
180     @Override
181     public void setFocus() {
182         if (viewer != null)
183             viewer.setFocus();
184     }
185
186     @SuppressWarnings("rawtypes")
187     public Object getAdapter(Class adapter) {
188         if (adapter == DiagramViewer.class)
189             return viewer;
190         if (viewer != null) {
191             Object result = viewer.getAdapter(adapter);
192             if (result != null)
193                 return result;
194         }
195         return null;
196     }
197
198
199     @Override
200     public void dispose() {
201         
202         EPartService partService = getPart().getContext().get(EPartService.class);
203         partService.removePartListener(this);
204
205         DISPOSING_POLICY.removeDisposer(disposer);
206         tryDisposeViewer();
207
208     }
209
210     
211     public void doSetPartName(String name) {
212         getPart().setLabel(name);
213     }
214
215     
216     public void doSetTitleToolTip(String tooltip) {
217         getPart().setTooltip(tooltip);
218     }
219     
220     private static final DisposingPolicy DISPOSING_POLICY = 
221             new DisposingPolicy();
222     
223     private Runnable disposer = new Runnable() {
224         @Override
225         public void run() {
226             tryDisposeViewer();
227         }
228     };
229
230     private void tryDisposeViewer() {
231         if (viewer != null) {
232             Composite viewerComposite = viewer.getComposite();
233             viewer.dispose();
234             viewer = null;
235             if (viewerComposite != null) {
236                 viewerComposite.dispose();
237             }
238         }
239     }
240     
241     @Override
242     public void partVisible(MPart part) {
243         if (getPart().equals(part)) {
244             DISPOSING_POLICY.removeDisposer(disposer);
245             if (viewer == null) {
246                 try {
247                     viewer = createViewer();
248                     // #TODO Finish this when we are going to use full E4 workbench
249 //                    viewer.init(DiagramEditor.this, getResourceInput());
250                     initializeViewer();
251                 } catch (PartInitException e) {
252                     // This should never happen!
253                     ErrorLogger.defaultLogError(e);
254                 }
255             }
256         }
257     }
258     
259     @Override
260     public void partHidden(MPart part) {
261         if (getPart().equals(part)) {
262             DISPOSING_POLICY.addDisposer(disposer);
263         }
264     }
265     
266     @Override
267     public void partDeactivated(MPart part) {
268     }
269     
270     @Override
271     public void partBroughtToTop(MPart part) {
272     }
273     
274     @Override
275     public void partActivated(MPart part) {
276     }
277
278 }