]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/e4/DiagramEditor.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagramEditor / e4 / DiagramEditor.java
1 /*******************************************************************************\r
2  * Copyright (c) 2012 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.modeling.ui.diagramEditor.e4;\r
13 \r
14 import java.lang.reflect.Constructor;\r
15 \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
31 \r
32 /**\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
36  * \r
37  * <p>\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
40  * \r
41  * <pre>\r
42  * class="org.simantics.modeling.ui.diagramEditor.DiagramEditor:viewer=%VIEWER%"\r
43  * </pre>\r
44  * \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
50  * \r
51  * <p>\r
52  * This class is not intended to be extended by clients. Customizations should\r
53  * be performed through the viewer class.\r
54  * \r
55  * @author Tuukka Lehtonen\r
56  * @author Antti Villberg\r
57  */\r
58 public class DiagramEditor extends E4ResourceEditorBase implements DiagramViewerHost, IExecutableExtension, IPartListener {\r
59 \r
60     /**\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
65      * \r
66      * @see #setInitializationData(IConfigurationElement, String, Object)\r
67      */\r
68     public static final String    ARG_VIEWER = "viewer";\r
69 \r
70     private Composite             parent;\r
71 \r
72     private String                viewerContributor;\r
73     private String                viewerClassName;\r
74 \r
75 //    private ResourceEditorSupport support;\r
76     private DiagramViewer         viewer;\r
77 \r
78     /**\r
79      * Reads the class arguments from the string in the data argument.\r
80      * \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
84      */\r
85     @Override\r
86     public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data) {\r
87 //        super.setInitializationData(cfig, propertyName, data);\r
88 \r
89         if (data instanceof String) {\r
90             viewerContributor = cfig.getContributor().getName();\r
91 \r
92             String[] parameters = ((String) data).split(";");\r
93 \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
98                     continue;\r
99                 }\r
100                 String key = keyValue[0];\r
101                 String value = keyValue.length > 1 ? keyValue[1] : "";\r
102 \r
103                 if (ARG_VIEWER.equals(key)) {\r
104                     viewerClassName = value;\r
105                 } \r
106             }\r
107         }\r
108     }\r
109 \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
115 \r
116         try {\r
117             Bundle b = Platform.getBundle(viewerContributor);\r
118             if (b == null)\r
119                 throw new PartInitException("DiagramViewer '" + viewerClassName + "' contributor bundle '"\r
120                         + viewerContributor + "' was not found in the platform.");\r
121 \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
126 \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
132         }\r
133     }\r
134 \r
135     public DiagramViewer getViewer() {\r
136         return viewer;\r
137     }\r
138 \r
139     public Resource getRuntimeResource() {\r
140         DiagramViewer viewer = this.viewer;\r
141         return viewer != null ? viewer.getRuntime() : null;\r
142     }\r
143     \r
144 //    public Resource getInputResource() {\r
145 //        DiagramViewer viewer = this.viewer;\r
146 //        return viewer != null ? viewer.getInputResource() : null;\r
147 //    }\r
148 \r
149     @Override\r
150     public void initImpl(MPart part) {\r
151         super.initImpl(part);\r
152  \r
153         try {\r
154             viewer = createViewer();\r
155         } catch (PartInitException e) {\r
156             // TODO Auto-generated catch block\r
157             e.printStackTrace();\r
158         }\r
159         // #TODO Finish this when we are going to use full E4 workbench\r
160 //        viewer.init(this, getResourceInput());\r
161         \r
162         EPartService partService = part.getContext().get(EPartService.class);\r
163         partService.addPartListener(this);\r
164     }\r
165 \r
166     @Override\r
167     public void createPartControl(Composite parent) {\r
168         this.parent = parent;\r
169         initializeViewer();\r
170     }\r
171 \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
178     }\r
179 \r
180     @Override\r
181     public void setFocus() {\r
182         if (viewer != null)\r
183             viewer.setFocus();\r
184     }\r
185 \r
186     @SuppressWarnings("rawtypes")\r
187     public Object getAdapter(Class adapter) {\r
188         if (adapter == DiagramViewer.class)\r
189             return viewer;\r
190         if (viewer != null) {\r
191             Object result = viewer.getAdapter(adapter);\r
192             if (result != null)\r
193                 return result;\r
194         }\r
195         return null;\r
196     }\r
197 \r
198 \r
199     @Override\r
200     public void dispose() {\r
201         \r
202         EPartService partService = getPart().getContext().get(EPartService.class);\r
203         partService.removePartListener(this);\r
204 \r
205         DISPOSING_POLICY.removeDisposer(disposer);\r
206         tryDisposeViewer();\r
207 \r
208     }\r
209 \r
210     \r
211     public void doSetPartName(String name) {\r
212         getPart().setLabel(name);\r
213     }\r
214 \r
215     \r
216     public void doSetTitleToolTip(String tooltip) {\r
217         getPart().setTooltip(tooltip);\r
218     }\r
219     \r
220     private static final DisposingPolicy DISPOSING_POLICY = \r
221             new DisposingPolicy();\r
222     \r
223     private Runnable disposer = new Runnable() {\r
224         @Override\r
225         public void run() {\r
226             tryDisposeViewer();\r
227         }\r
228     };\r
229 \r
230     private void tryDisposeViewer() {\r
231         if (viewer != null) {\r
232             Composite viewerComposite = viewer.getComposite();\r
233             viewer.dispose();\r
234             viewer = null;\r
235             if (viewerComposite != null) {\r
236                 viewerComposite.dispose();\r
237             }\r
238         }\r
239     }\r
240     \r
241     @Override\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
246                 try {\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
254                 }\r
255             }\r
256         }\r
257     }\r
258     \r
259     @Override\r
260     public void partHidden(MPart part) {\r
261         if (getPart().equals(part)) {\r
262             DISPOSING_POLICY.addDisposer(disposer);\r
263         }\r
264     }\r
265     \r
266     @Override\r
267     public void partDeactivated(MPart part) {\r
268     }\r
269     \r
270     @Override\r
271     public void partBroughtToTop(MPart part) {\r
272     }\r
273     \r
274     @Override\r
275     public void partActivated(MPart part) {\r
276     }\r
277 \r
278 }\r