]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/e4/DiagramViewer.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagramEditor / e4 / DiagramViewer.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2013 Association for Decentralized Information Management\r
3  * in 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  *     Semantum Oy - issue #4384\r
12  *******************************************************************************/\r
13 package org.simantics.modeling.ui.diagramEditor.e4;\r
14 \r
15 import java.awt.Color;\r
16 import java.awt.dnd.DnDConstants;\r
17 import java.util.Collections;\r
18 import java.util.Set;\r
19 import java.util.concurrent.TimeUnit;\r
20 import java.util.function.Supplier;\r
21 \r
22 import org.eclipse.core.runtime.Assert;\r
23 import org.eclipse.core.runtime.IAdaptable;\r
24 import org.eclipse.core.runtime.IProgressMonitor;\r
25 import org.eclipse.core.runtime.SubMonitor;\r
26 import org.eclipse.core.runtime.jobs.Job;\r
27 import org.eclipse.e4.ui.model.application.ui.basic.MPart;\r
28 import org.eclipse.e4.ui.services.EContextService;\r
29 import org.eclipse.jface.action.IStatusLineManager;\r
30 import org.eclipse.jface.resource.JFaceResources;\r
31 import org.eclipse.jface.resource.LocalResourceManager;\r
32 import org.eclipse.swt.widgets.Composite;\r
33 import org.eclipse.swt.widgets.Display;\r
34 import org.eclipse.swt.widgets.Shell;\r
35 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;\r
36 import org.simantics.Simantics;\r
37 import org.simantics.browsing.ui.model.browsecontexts.BrowseContext;\r
38 import org.simantics.db.ReadGraph;\r
39 import org.simantics.db.Resource;\r
40 import org.simantics.db.Session;\r
41 import org.simantics.db.WriteGraph;\r
42 import org.simantics.db.common.primitiverequest.PossibleAdapter;\r
43 import org.simantics.db.common.procedure.adapter.ListenerDelegate;\r
44 import org.simantics.db.common.procedure.adapter.ListenerSupport;\r
45 import org.simantics.db.common.request.ParametrizedRead;\r
46 import org.simantics.db.common.request.WriteRequest;\r
47 import org.simantics.db.common.utils.CommonDBUtils;\r
48 import org.simantics.db.common.utils.TagUtil;\r
49 import org.simantics.db.exception.DatabaseException;\r
50 import org.simantics.db.layer0.request.combinations.Combinators;\r
51 import org.simantics.db.management.ISessionContext;\r
52 import org.simantics.db.management.ISessionContextProvider;\r
53 import org.simantics.db.request.Read;\r
54 import org.simantics.diagram.DiagramTypeUtils;\r
55 import org.simantics.diagram.adapter.FlagClassFactory;\r
56 import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;\r
57 import org.simantics.diagram.adapter.IDiagramLoader;\r
58 import org.simantics.diagram.connection.ModelledConnectionAdvisor;\r
59 import org.simantics.diagram.handler.ConnectionCommandHandler;\r
60 import org.simantics.diagram.handler.CopyPasteStrategy;\r
61 import org.simantics.diagram.handler.DefaultCopyPasteStrategy;\r
62 import org.simantics.diagram.handler.DeleteHandler;\r
63 import org.simantics.diagram.handler.ExpandSelectionHandler;\r
64 import org.simantics.diagram.handler.SimpleElementTransformHandler;\r
65 import org.simantics.diagram.handler.e4.CopyPasteHandler;\r
66 import org.simantics.diagram.layer.ILayersViewPage;\r
67 import org.simantics.diagram.participant.PointerInteractor2;\r
68 import org.simantics.diagram.participant.SGFocusParticipant;\r
69 import org.simantics.diagram.participant.e4.ContextUtil;\r
70 import org.simantics.diagram.query.DiagramRequests;\r
71 import org.simantics.diagram.runtime.RuntimeDiagramManager;\r
72 import org.simantics.diagram.stubs.DiagramResource;\r
73 import org.simantics.diagram.symbolcontribution.SymbolProviderFactory;\r
74 import org.simantics.diagram.synchronization.CopyAdvisor;\r
75 import org.simantics.diagram.synchronization.IModifiableSynchronizationContext;\r
76 import org.simantics.diagram.synchronization.SynchronizationHints;\r
77 import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
78 import org.simantics.diagram.ui.DiagramModelHints;\r
79 import org.simantics.diagram.ui.SWTPopupMenuParticipant;\r
80 import org.simantics.diagram.ui.WorkbenchSelectionProvider;\r
81 import org.simantics.g2d.canvas.Hints;\r
82 import org.simantics.g2d.canvas.ICanvasContext;\r
83 import org.simantics.g2d.canvas.ICanvasParticipant;\r
84 import org.simantics.g2d.canvas.impl.CanvasContext;\r
85 import org.simantics.g2d.chassis.AWTChassis;\r
86 import org.simantics.g2d.chassis.ICanvasChassis;\r
87 import org.simantics.g2d.chassis.IChassisListener;\r
88 import org.simantics.g2d.chassis.SWTChassis;\r
89 import org.simantics.g2d.connection.IConnectionAdvisor;\r
90 import org.simantics.g2d.diagram.DiagramClass;\r
91 import org.simantics.g2d.diagram.DiagramHints;\r
92 import org.simantics.g2d.diagram.IDiagram;\r
93 import org.simantics.g2d.diagram.handler.PickRequest.PickFilter;\r
94 import org.simantics.g2d.diagram.impl.Diagram;\r
95 import org.simantics.g2d.diagram.participant.DelayedBatchElementPainter;\r
96 import org.simantics.g2d.diagram.participant.DiagramParticipant;\r
97 import org.simantics.g2d.diagram.participant.ElementInteractor;\r
98 import org.simantics.g2d.diagram.participant.ElementPainter;\r
99 import org.simantics.g2d.diagram.participant.Selection;\r
100 import org.simantics.g2d.diagram.participant.TerminalPainter;\r
101 import org.simantics.g2d.diagram.participant.ZOrderHandler;\r
102 import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;\r
103 import org.simantics.g2d.element.ElementClassProviders;\r
104 import org.simantics.g2d.element.ElementClasses;\r
105 import org.simantics.g2d.element.IElement;\r
106 import org.simantics.g2d.element.IElementClassProvider;\r
107 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
108 import org.simantics.g2d.elementclass.connection.ConnectionClass;\r
109 import org.simantics.g2d.page.DiagramDesc;\r
110 import org.simantics.g2d.participant.BackgroundPainter;\r
111 import org.simantics.g2d.participant.CanvasBoundsParticipant;\r
112 import org.simantics.g2d.participant.CanvasGrab;\r
113 import org.simantics.g2d.participant.GridPainter;\r
114 import org.simantics.g2d.participant.KeyUtil;\r
115 import org.simantics.g2d.participant.MouseUtil;\r
116 import org.simantics.g2d.participant.Notifications;\r
117 import org.simantics.g2d.participant.PageBorderParticipant;\r
118 import org.simantics.g2d.participant.PanZoomRotateHandler;\r
119 import org.simantics.g2d.participant.PointerPainter;\r
120 import org.simantics.g2d.participant.RenderingQualityInteractor;\r
121 import org.simantics.g2d.participant.RulerPainter;\r
122 import org.simantics.g2d.participant.SymbolUtil;\r
123 import org.simantics.g2d.participant.TimeParticipant;\r
124 import org.simantics.g2d.participant.TransformUtil;\r
125 import org.simantics.g2d.participant.WorkbenchStatusLine;\r
126 import org.simantics.g2d.participant.ZoomToAreaHandler;\r
127 import org.simantics.g2d.tooltip.TerminalTooltipParticipant;\r
128 import org.simantics.g2d.utils.CanvasUtils;\r
129 import org.simantics.layer0.utils.triggers.IActivation;\r
130 import org.simantics.layer0.utils.triggers.IActivationManager;\r
131 import org.simantics.modeling.ModelingResources;\r
132 import org.simantics.modeling.mapping.ComponentCopyAdvisor;\r
133 import org.simantics.modeling.mapping.ElementCopyAdvisor;\r
134 import org.simantics.modeling.mapping.MappedElementCopyAdvisor;\r
135 import org.simantics.modeling.mapping.ModelingSynchronizationHints;\r
136 import org.simantics.modeling.ui.diagramEditor.DiagramEditorStates;\r
137 import org.simantics.modeling.ui.diagramEditor.DiagramLayersPage;\r
138 import org.simantics.modeling.ui.diagramEditor.DiagramOutlinePage;\r
139 import org.simantics.modeling.ui.diagramEditor.EditorState;\r
140 import org.simantics.modeling.ui.diagramEditor.PopulateElementMonitorDropParticipant;\r
141 import org.simantics.modeling.ui.diagramEditor.handlers.e4.LinkBrowsingHandler;\r
142 import org.simantics.modeling.ui.diagramEditor.handlers.e4.StructuralBrowsingHandler;\r
143 import org.simantics.modeling.ui.preferences.DiagramPreferenceUtil;\r
144 import org.simantics.modeling.ui.preferences.DiagramPreferences;\r
145 import org.simantics.project.ontology.ProjectResource;\r
146 import org.simantics.scenegraph.INode;\r
147 import org.simantics.scenegraph.g2d.snap.GridSnapAdvisor;\r
148 import org.simantics.scenegraph.utils.NodeUtil;\r
149 import org.simantics.structural.stubs.StructuralResource2;\r
150 import org.simantics.structural2.modelingRules.IModelingRules;\r
151 import org.simantics.ui.SimanticsUI;\r
152 import org.simantics.ui.jobs.SessionGarbageCollectorJob;\r
153 import org.simantics.ui.workbench.IPropertyPage;\r
154 import org.simantics.ui.workbench.IResourceEditorInput;\r
155 import org.simantics.ui.workbench.IResourceEditorInput2;\r
156 import org.simantics.ui.workbench.TitleRequest;\r
157 import org.simantics.ui.workbench.TitleUpdater;\r
158 import org.simantics.ui.workbench.ToolTipRequest;\r
159 import org.simantics.ui.workbench.editor.input.InputValidationCombinators;\r
160 import org.simantics.utils.DataContainer;\r
161 import org.simantics.utils.datastructures.Callback;\r
162 import org.simantics.utils.datastructures.hints.HintContext;\r
163 import org.simantics.utils.datastructures.hints.HintListenerAdapter;\r
164 import org.simantics.utils.datastructures.hints.IHintContext;\r
165 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
166 import org.simantics.utils.datastructures.hints.IHintListener;\r
167 import org.simantics.utils.datastructures.hints.IHintObservable;\r
168 import org.simantics.utils.threads.AWTThread;\r
169 import org.simantics.utils.threads.IThreadWorkQueue;\r
170 import org.simantics.utils.threads.SWTThread;\r
171 import org.simantics.utils.threads.ThreadUtils;\r
172 import org.simantics.utils.ui.ErrorLogger;\r
173 import org.simantics.utils.ui.ExceptionUtils;\r
174 import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
175 \r
176 import com.kitfox.svg.SVGCache;\r
177 \r
178 /**\r
179  * @author Toni Kalajainen\r
180  * @author Tuukka Lehtonen\r
181  */\r
182 public class DiagramViewer \r
183   //extends EditorPart implements IResourceEditorPart2, \r
184     implements ListenerSupport, IAdaptable {\r
185 \r
186     public interface DiagramViewerHost {\r
187         void doSetPartName(String name);\r
188         void doSetTitleToolTip(String name);\r
189     }\r
190 \r
191     public static final String                     DIAGRAMMING_CONTEXT      = "org.simantics.modeling.ui.diagramming";\r
192     private static final String                     PREFERENCE_VIRTUAL_GRAPH = "preferences";\r
193 \r
194     private static final boolean                    PROFILE                  = false;\r
195 \r
196     ParametrizedRead<IResourceEditorInput, Boolean> INPUT_VALIDATOR =\r
197         Combinators.compose(\r
198                 InputValidationCombinators.or(\r
199                         // Normal configuration diagrams of a model\r
200                         Combinators.compose(\r
201                                 InputValidationCombinators.hasURI(),\r
202                                 InputValidationCombinators.partialFunction(ModelingResources.URIs.DiagramToComposite)\r
203                         ),\r
204                         // Configuration diagrams of a component type\r
205                         Combinators.compose(\r
206                                 InputValidationCombinators.hasURI(),\r
207                                 Combinators.compose(\r
208                                         InputValidationCombinators.partialFunction(StructuralResource2.URIs.Defines),\r
209                                         InputValidationCombinators.partialFunction(ModelingResources.URIs.DiagramToComposite)\r
210                                 )\r
211                         )\r
212                 ),\r
213                 InputValidationCombinators.extractInputResource()\r
214         );\r
215 \r
216     protected EditorState                editorState;\r
217 \r
218     protected boolean                    disposed           = false;\r
219     protected IThreadWorkQueue           swt;\r
220     protected IStatusLineManager         statusLineManager;\r
221     protected Display                    display;\r
222     protected LocalResourceManager       resourceManager;\r
223     protected SWTChassis                 c;\r
224     protected IDiagram                   sourceDiagram;\r
225     protected DataContainer<IDiagram>    sourceDiagramContainer = new DataContainer<IDiagram>();\r
226     protected CanvasContext              canvasContext;\r
227     protected ISessionContextProvider    sessionContextProvider;\r
228     protected ISessionContext            sessionContext;\r
229     protected Resource                   diagramResource;\r
230     protected GraphToDiagramSynchronizer synchronizer;\r
231     protected IActivation                activation;\r
232     protected ContextUtil                contextUtil;\r
233     protected SWTPopupMenuParticipant    popupMenuParticipant;\r
234     \r
235     protected DiagramPreferences         diagramPreferences;\r
236     protected DiagramDesc                diagramDesc;\r
237     protected GridSnapAdvisor            snapAdvisor;\r
238 \r
239     private RuntimeDiagramManager        runtimeDiagramManager;\r
240 \r
241     protected WorkbenchSelectionProvider selectionProvider;\r
242 \r
243     public Resource getRuntime() {\r
244         RuntimeDiagramManager rtdm = runtimeDiagramManager;\r
245         return (rtdm == null) ? null : rtdm.getRuntimeDiagram();\r
246     }\r
247 \r
248     public ParametrizedRead<IResourceEditorInput, Boolean> getInputValidator() {\r
249         return INPUT_VALIDATOR;\r
250     }\r
251 \r
252     protected void addDropParticipants(ICanvasContext ctx) {\r
253         ctx.getDefaultHintContext().setHint(Hints.KEY_ALLOWED_DRAG_ACTIONS, DnDConstants.ACTION_COPY);\r
254 \r
255         ctx.add(new PopulateElementDropParticipant(synchronizer, getPart()));\r
256         ctx.add(new PopulateElementMonitorDropParticipant(synchronizer, 0.5, 0.5));\r
257     }\r
258 \r
259     protected CopyPasteStrategy getCopyPasteStrategy() {\r
260                 try {\r
261                         CopyPasteStrategy cpStrategy = Simantics.getSession().syncRequest(new PossibleAdapter<CopyPasteStrategy>(getResourceEditorInput().getResource(), CopyPasteStrategy.class));\r
262                         if(cpStrategy != null) return cpStrategy;\r
263                 } catch (DatabaseException e) {\r
264                 }\r
265                 return new DefaultCopyPasteStrategy();\r
266     }\r
267 \r
268     protected CopyAdvisor getCopyAdvisor() {\r
269                 try {\r
270                         CopyAdvisor advisor = Simantics.getSession().syncRequest(new PossibleAdapter<CopyAdvisor>(getResourceEditorInput().getResource(), CopyAdvisor.class));\r
271                         if(advisor != null) return advisor;\r
272                 } catch (DatabaseException e) {\r
273                 }\r
274                 return new MappedElementCopyAdvisor(new ElementCopyAdvisor(), new ComponentCopyAdvisor());\r
275     }\r
276     \r
277     /**\r
278      * @param ctx\r
279      * TODO: change argument from CanvasContext to ICanvasContext\r
280      */\r
281     protected void addKeyBindingParticipants(CanvasContext ctx) {\r
282         //ctx.add( new KeyToCommand( CommandKeyBinding.DEFAULT_BINDINGS ) );\r
283         ctx.add(new DeleteHandler(statusLineManager));\r
284         ctx.add(new CopyPasteHandler(getCopyPasteStrategy(), statusLineManager).setWorkbenchSite(getPart()));\r
285         ctx.add(new ConnectionCommandHandler());\r
286     }\r
287 \r
288     protected void addPopupmenu(ICanvasContext ctx) {\r
289         ctx.add(popupMenuParticipant);\r
290     }\r
291 \r
292     protected void addWorkbenchSelectionProvider(ICanvasContext ctx) {\r
293         ctx.add(selectionProvider);\r
294     }\r
295 \r
296     protected void addViewManipulationParticipants(CanvasContext ctx) {\r
297         ctx.add(new PanZoomRotateHandler());\r
298         //ctx.add(new MousePanZoomInteractor());\r
299         //ctx.add(new MultitouchPanZoomRotateInteractor());\r
300         // ctx.add( new OrientationRestorer() );\r
301         ctx.add(new ZoomToAreaHandler());\r
302     }\r
303 \r
304     protected void addDiagramParticipants(ICanvasContext ctx) {\r
305         ctx.add(new ZOrderHandler());\r
306         ctx.add(getPointerInteractor());\r
307         ctx.add(new ElementInteractor());\r
308         ctx.add(new Selection());\r
309         ctx.add(new DiagramParticipant());\r
310         ctx.add(new ElementPainter());\r
311         //ctx.add(new ElementHeartbeater());\r
312         //ctx.add(new ZoomTransitionParticipant(TransitionFunction.SIGMOID));\r
313         //ctx.add(new TooltipParticipant());\r
314         ctx.add(new TerminalTooltipParticipant());\r
315     }\r
316 \r
317     protected void addPainterParticipants(ICanvasContext ctx) {\r
318         ctx.add(new RenderingQualityInteractor());\r
319         ctx.add(new TerminalPainter(true, true, false, true));\r
320         ctx.add(new DelayedBatchElementPainter(PickFilter.FILTER_MONITORS, 500, TimeUnit.MILLISECONDS));\r
321     }\r
322 \r
323     protected void addStructureParticipants(ICanvasContext ctx) {\r
324         addWorkbenchSelectionProvider(ctx);\r
325         // Add visual browsing capabilities for structural models\r
326         ctx.add(new StructuralBrowsingHandler(sessionContext, getPart(), getResourceEditorInput()));\r
327         ctx.add(new LinkBrowsingHandler(this, sessionContext));\r
328     }\r
329 \r
330     /**\r
331      * Override to add any diagram/canvas participants to the canvas context\r
332      * initialized for the editor.\r
333      * \r
334      * @param ctx\r
335      */\r
336     protected void addOtherParticipants(CanvasContext ctx) {\r
337     }\r
338 \r
339     public static Set<String> defaultPropertyBrowseContexts = Collections.singleton(ProjectResource.URIs.ProjectBrowseContext);\r
340 \r
341     protected Set<String> getPropertyPageContexts() {\r
342         try {\r
343             return BrowseContext.getBrowseContextClosure(SimanticsUI.getSession(), defaultPropertyBrowseContexts);\r
344         } catch (DatabaseException e) {\r
345             ExceptionUtils.logAndShowError("Failed to load modeled browse contexts for property page, see exception for details.", e);\r
346             return defaultPropertyBrowseContexts;\r
347         }\r
348     }\r
349 \r
350     protected IPropertyPage createPropertyPage(MPart part, Set<String> contexts) {\r
351 //        #TODO Finish this when we are going to use full E4 workbench\r
352 //        return new StandardPropertyPage(part, contexts);\r
353         return null;\r
354     }\r
355 \r
356     protected String getPopupId() {\r
357         return "#ModelingDiagramPopup";\r
358     }\r
359 \r
360     protected void getPreferences() {\r
361         this.diagramPreferences = DiagramPreferenceUtil.getPreferences();\r
362     }\r
363 \r
364     protected void initSession() {\r
365         sessionContextProvider = SimanticsUI.getSessionContextProvider();\r
366         sessionContext = sessionContextProvider.getSessionContext();\r
367     }\r
368 \r
369     protected void readNames() {\r
370         String name = getResourceEditorInput().getName();\r
371         host.doSetPartName(name);\r
372         host.doSetTitleToolTip(name);\r
373     }\r
374 \r
375     class ChassisListener implements IChassisListener {\r
376         @Override\r
377         public void chassisClosed(ICanvasChassis sender) {\r
378             // Prevent deadlock while disposing which using syncExec would result in.\r
379             final ICanvasContext ctx = canvasContext;\r
380             ThreadUtils.asyncExec(ctx.getThreadAccess(), new Runnable() {\r
381                 @Override\r
382                 public void run() {\r
383                     if (ctx != null) {\r
384                         saveEditorState(ctx);\r
385                         ctx.getHintStack().removeKeyHintListener(GridPainter.KEY_GRID_ENABLED, canvasHintListener);\r
386                         ctx.getHintStack().removeKeyHintListener(RulerPainter.KEY_RULER_ENABLED, canvasHintListener);\r
387                         final AWTChassis awtChassis = c.getAWTComponent();\r
388                         if (awtChassis != null)\r
389                             awtChassis.setCanvasContext(null);\r
390                         ctx.dispose();\r
391                     }\r
392 \r
393                     sourceDiagramContainer.set(null);\r
394                     sourceDiagramContainer = null;\r
395 \r
396                     if (sourceDiagram != null)\r
397                         sourceDiagram.dispose();\r
398 \r
399                     if(synchronizer != null) {\r
400                         synchronizer.dispose();\r
401                         // Let GC work.\r
402                         synchronizer = null;\r
403                     }\r
404 \r
405                     if (runtimeDiagramManager != null) {\r
406                         runtimeDiagramManager.dispose();\r
407                         runtimeDiagramManager = null;\r
408                     }\r
409                 }\r
410             });\r
411             c.removeChassisListener(ChassisListener.this);\r
412         }\r
413     }\r
414 \r
415     protected void createChassis(Composite parent) {\r
416         resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);\r
417         c = new SWTChassis(parent, 0);\r
418 \r
419         Object task = BEGIN("DV.precreateParticipants");\r
420         createCustomParticipants();\r
421         END(task);\r
422 \r
423         c.populate(component -> {\r
424             if (!disposed) {\r
425                 c.addChassisListener(new ChassisListener());\r
426                 initializeCanvas();\r
427             }\r
428         });\r
429     }\r
430 \r
431     protected void beforeSetCanvasContext(ICanvasContext canvasContext2) {\r
432     }\r
433 \r
434     /**\r
435      * Invoke this only from the AWT thread.\r
436      * @param context\r
437      */\r
438     protected void setCanvasContext(ICanvasContext context) {\r
439         // Cannot directly invoke SWTChassis.setCanvasContext only because it\r
440         // needs to be invoked in the SWT thread and AWTChassis.setCanvasContext in the\r
441         // AWT thread, but directly invoking SWTChassis.setCanvasContext would call both\r
442         // in the SWT thread which would cause synchronous scheduling of AWT\r
443         // runnables which is always a potential source of deadlocks.\r
444         c.getAWTComponent().setCanvasContext(canvasContext);\r
445         swt.asyncExec(new Runnable() {\r
446             @Override\r
447             public void run() {\r
448                 if (!c.isDisposed())\r
449                     // For AWT, this is a no-operation.\r
450                     c.setCanvasContext(canvasContext);\r
451             }\r
452         });\r
453     }\r
454 \r
455     public void createPartControl(Composite parent) {\r
456         //ProfileObserver.begin = System.nanoTime();\r
457         display = parent.getDisplay(); \r
458         swt = SWTThread.getThreadAccess(display);\r
459         statusLineManager = WorkbenchUtils.getStatusLine(WorkbenchUtils.getActiveWorkbenchPart());\r
460 \r
461         Object task = BEGIN("DV.initSession");\r
462         initSession();\r
463         END(task);\r
464 \r
465         diagramResource = getResourceEditorInput().getResource();\r
466         readNames();\r
467         getPreferences();\r
468 \r
469         // DiagramViewerSelectionProvider MUST be created and attached to the\r
470         // workbench site:\r
471         //   1. in SWT thread!\r
472         //   2. here before returning from createPartControl\r
473         selectionProvider = createSelectionProvider();\r
474 \r
475         try {\r
476             this.runtimeDiagramManager = RuntimeDiagramManager.track(sessionContext.getSession(), diagramResource, getResourceEditorInput(), this);\r
477 \r
478             // Create the canvas context here before finishing createPartControl\r
479             // to give DiagramViewerActionContributor a chance to work.\r
480             // The context can be created in SWT thread without scheduling\r
481             // to the context thread and having potential deadlocks.\r
482             IThreadWorkQueue thread = AWTThread.getThreadAccess();\r
483             this.canvasContext = new CanvasContext(thread);\r
484             this.canvasContext.setLocked(true);\r
485 \r
486             task = BEGIN("DV.createChassis");\r
487             createChassis(parent);\r
488             END(task);\r
489         } catch (DatabaseException e) {\r
490             ErrorLogger.defaultLogError(e);\r
491         }\r
492     }\r
493 \r
494     /**\r
495      * @return\r
496      */\r
497     protected WorkbenchSelectionProvider createSelectionProvider() {\r
498 //        #TODO Finish this when we are going to use full E4 workbench        \r
499 //        return new DiagramViewerSelectionProvider(swt, getPart(), sourceDiagramContainer);\r
500         return null;\r
501     }\r
502 \r
503         /**\r
504      * A method invoked before chassis construction for creating such\r
505      * {@link ICanvasParticipant}s that need to be constructed in the SWT\r
506      * thread.\r
507      * \r
508      * Use it for creating any such canvas participants during the viewer \r
509      * construction and add them to the {@link ICanvasContext} later on from\r
510      * the AWT thread.\r
511      */\r
512     protected void createCustomParticipants() {\r
513 //        #TODO Finish this when we are going to use full E4 workbench\r
514 //        popupMenuParticipant = new SWTPopupMenuParticipant(getPart(), c, display, getPopupId());\r
515     }\r
516 \r
517     /**\r
518      * Invoke this only from the AWT thread.\r
519      */\r
520     protected void initializeCanvas() {\r
521         Object canvasInit = BEGIN("DV.canvasInitialization");\r
522 \r
523         Object task = BEGIN("DV.createViewerCanvas");\r
524         initializeCanvasContext(canvasContext);\r
525         END(task);\r
526 \r
527         beforeSetCanvasContext(canvasContext);\r
528         //FullscreenUtils.addFullScreenHandler(canvasContext, s, canvasProvider);\r
529 \r
530         // Without this all diagram participants will crash like there's no tomorrow.\r
531         // Just trying to keep the behavior a bit more sane in case of\r
532         // errors instead of flooding the console with exceptions.\r
533         canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, Diagram.spawnNew(DiagramClass.DEFAULT));\r
534 \r
535         // Changes in ruler/grid activity shall be written as\r
536         // workspace-persistent diagram-specific preferences.\r
537         canvasContext.getHintStack().addKeyHintListener(GridPainter.KEY_GRID_ENABLED, canvasHintListener);\r
538         canvasContext.getHintStack().addKeyHintListener(RulerPainter.KEY_RULER_ENABLED, canvasHintListener);\r
539 \r
540         task = BEGIN("DV.setCanvasContext");\r
541         setCanvasContext(canvasContext);\r
542         END(task);\r
543 \r
544         // Finish loading in a worker thread because it may be a time consuming\r
545         // process to load a large diagram and we don't want unnecessary AWT\r
546         // thread contention.\r
547         Job loadJob = new DiagramViewerLoadJob(this);\r
548         loadJob.schedule();\r
549 \r
550         END(canvasInit);\r
551     }\r
552 \r
553     protected void activateUiContexts(ContextUtil util) {\r
554         util.activate(DIAGRAMMING_CONTEXT);\r
555     }\r
556 \r
557     /**\r
558      * @param monitor the progress monitor to use for reporting progress to the\r
559      *        user. It is the caller's responsibility to call done() on the\r
560      *        given monitor. Accepts <code>null</code>, indicating that no\r
561      *        progress should be reported and that the operation cannot be\r
562      *        cancelled.\r
563      */\r
564     protected void performActivation(IProgressMonitor monitor) {\r
565         SubMonitor progress = SubMonitor.convert(monitor, "Activate Mapping", 100);\r
566         IActivationManager activationManager = sessionContext.getSession().peekService(IActivationManager.class);\r
567         if (activationManager != null) {\r
568             activation = activationManager.activate(diagramResource);\r
569         }\r
570         progress.worked(100);\r
571     }\r
572 \r
573     protected void onCreated() {\r
574     }\r
575 \r
576     /**\r
577      * @param diagram\r
578      */\r
579     protected void scheduleZoomToFit(IDiagram diagram) {\r
580         if (diagram == null)\r
581             throw new IllegalStateException("diagram is null");\r
582 \r
583         CanvasUtils.scheduleZoomToFit(swt, () -> disposed, canvasContext, diagram);\r
584     }\r
585 \r
586     /**\r
587      * Subclasses may override but should always invoke super.\r
588      * \r
589      * @param diagram\r
590      * @param initialHints\r
591      * @throws DatabaseException\r
592      */\r
593     protected void fillInitialDiagramHints(Resource diagram, IHintContext initialHints) throws DatabaseException {\r
594         IModelingRules modelingRules = sessionContext.getSession().syncRequest(\r
595                 DiagramRequests.getModelingRules(diagram, null));\r
596         if (modelingRules != null) {\r
597             initialHints.setHint(DiagramModelHints.KEY_MODELING_RULES, modelingRules);\r
598             initialHints.setHint(DiagramHints.CONNECTION_ADVISOR,\r
599                     getConnectionAdvisor(modelingRules, sessionContext.getSession()));\r
600         }\r
601 \r
602         initialHints.setHint(SynchronizationHints.COPY_ADVISOR, getCopyAdvisor());\r
603         initialHints.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, Boolean.TRUE);\r
604         initialHints.setHint(DiagramHints.KEY_ALLOW_CONNECTION_BRANCHING, Boolean.TRUE);\r
605         initialHints.setHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS, Boolean.TRUE);\r
606     }\r
607 \r
608     /**\r
609      * @param monitor the progress monitor to use for reporting progress to the\r
610      *        user. It is the caller's responsibility to call done() on the\r
611      *        given monitor. Accepts <code>null</code>, indicating that no\r
612      *        progress should be reported and that the operation cannot be\r
613      *        cancelled.\r
614      * @param r\r
615      * @return\r
616      * @throws DatabaseException\r
617      */\r
618     protected IDiagram loadDiagram(IProgressMonitor monitor, final Resource r) throws DatabaseException {\r
619         // Pre-load modeling rules and possibly other hints too since they are\r
620         // needed already while loading the diagram contents.\r
621         IHintContext initialHints = new HintContext();\r
622         fillInitialDiagramHints(r, initialHints);\r
623         IDiagram d = loadDiagram(monitor, r, initialHints);\r
624         return d;\r
625     }\r
626 \r
627     /**\r
628      * @param monitor the progress monitor to use for reporting progress to the\r
629      *        user. It is the caller's responsibility to call done() on the\r
630      *        given monitor. Accepts <code>null</code>, indicating that no\r
631      *        progress should be reported and that the operation cannot be\r
632      *        cancelled.\r
633      * @param diagram\r
634      * @param initialHints\r
635      * @return\r
636      * @throws DatabaseException\r
637      */\r
638     protected IDiagram loadDiagram(IProgressMonitor monitor, Resource diagram, IHintContext initialHints) throws DatabaseException {\r
639         RuntimeDiagramManager rtdm = runtimeDiagramManager;\r
640         Resource runtimeDiagram = rtdm != null ? rtdm.getRuntimeDiagram() : null;\r
641         IDiagramLoader loader = synchronizer;\r
642         if (rtdm == null || runtimeDiagram == null || loader == null)\r
643                 return null;\r
644         IDiagram d = sessionContext.getSession().syncRequest(\r
645                 DiagramRequests.loadDiagram(monitor, getResourceEditorInput().getModel(null), diagram,\r
646                         runtimeDiagram, null, loader, initialHints));\r
647         return d;\r
648     }\r
649 \r
650     protected void beforeSetDiagram(IDiagram diagram) {\r
651     }\r
652 \r
653     protected PointerInteractor getPointerInteractor() {\r
654         return new PointerInteractor2(true, true, true, false, true, false, synchronizer.getElementClassProvider());\r
655     }\r
656 \r
657     protected IConnectionAdvisor getConnectionAdvisor(IModelingRules modelingRules, Session session) {\r
658         return new ModelledConnectionAdvisor(modelingRules, sessionContext.getSession());\r
659     }\r
660 \r
661     protected GraphToDiagramSynchronizer createSynchronizer(final ICanvasContext ctx, final ISessionContext sessionContext) {\r
662         try {\r
663             return sessionContext.getSession().syncRequest(new Read<GraphToDiagramSynchronizer>() {\r
664                 @Override\r
665                 public GraphToDiagramSynchronizer perform(ReadGraph graph) throws DatabaseException {\r
666                     GraphToDiagramSynchronizer sync = new GraphToDiagramSynchronizer(graph, ctx, createElementClassProvider(graph));\r
667                     initializeSynchronizationContext(graph, sync);\r
668                     return sync;\r
669                 }\r
670             });\r
671         } catch (DatabaseException e) {\r
672             throw new UnsupportedOperationException("Failed to initialize data model synchronizer", e);\r
673         }\r
674     }\r
675 \r
676     protected void initializeSynchronizationContext(ReadGraph graph, IModifiableSynchronizationContext context) {\r
677         context.set(ModelingSynchronizationHints.MODELING_RESOURCE, ModelingResources.getInstance(graph));\r
678     }\r
679 \r
680     protected IElementClassProvider createElementClassProvider(ReadGraph graph) {\r
681         DiagramResource dr = DiagramResource.getInstance(graph);\r
682         return ElementClassProviders.mappedProvider(\r
683                 ElementClasses.CONNECTION, ConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(dr.RouteGraphConnection)),\r
684                 ElementClasses.FLAG, FlagClassFactory.createFlagClass(dr.Flag, dr.Flag_Terminal)\r
685         );\r
686     }\r
687     \r
688     protected SimpleElementTransformHandler getTransformHandler() {\r
689         return new SimpleElementTransformHandler(true, true, true);\r
690     }\r
691 \r
692     public void initializeCanvasContext(CanvasContext ctx) {\r
693         IHintContext h = ctx.getDefaultHintContext();\r
694 \r
695         // The canvas context should not be painted until it is ready to avoid\r
696         // unnecessary visual glitches.\r
697         h.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE);\r
698 \r
699         Object task = BEGIN("createSynchronizer");\r
700         this.synchronizer = createSynchronizer(ctx, sessionContext);\r
701         END(task);\r
702 \r
703         EContextService contextService = getPart().getContext().get(EContextService.class);\r
704         contextUtil = new ContextUtil(contextService, swt);\r
705 \r
706         // Support & Util Participants\r
707         ctx.add(new TransformUtil());\r
708         ctx.add(new MouseUtil());\r
709         ctx.add(new KeyUtil());\r
710         ctx.add(contextUtil);\r
711         ctx.add(new WorkbenchStatusLine(statusLineManager));\r
712         ctx.add(new CanvasGrab());\r
713         ctx.add(new SymbolUtil());\r
714         ctx.add(new TimeParticipant());\r
715         ctx.add(new CanvasBoundsParticipant());\r
716         ctx.add(new Notifications());\r
717 \r
718         ctx.add(new SGFocusParticipant(c, DIAGRAMMING_CONTEXT));\r
719 \r
720         // Debug participant(s)\r
721         // ctx.add( new PointerPainter() );\r
722         // ctx.add( new HandPainter() );\r
723         h.setHint(PointerPainter.KEY_PAINT_POINTER, true);\r
724 \r
725         // Pan & Zoom & Rotate\r
726         addViewManipulationParticipants(ctx);\r
727 \r
728         ctx.add(getTransformHandler());\r
729         ctx.add(new ExpandSelectionHandler(statusLineManager));\r
730 \r
731         // Key bindings\r
732         addKeyBindingParticipants(ctx);\r
733 \r
734         // Grid & Ruler & Background\r
735         ctx.add(new GridPainter());\r
736         ctx.add(new RulerPainter());\r
737         ctx.add(new BackgroundPainter());\r
738 \r
739         h.setHint(Hints.KEY_DISPLAY_PAGE, diagramPreferences.get(DiagramPreferences.P_DISPLAY_PAGE_SIZE));\r
740         h.setHint(Hints.KEY_DISPLAY_MARGINS, diagramPreferences.get(DiagramPreferences.P_DISPLAY_MARGINS));\r
741         ctx.add(new PageBorderParticipant());\r
742 \r
743         // h.setHint(Hints.KEY_GRID_COLOR, new Color(0.9f, 0.9f, 0.9f));\r
744         // h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.LIGHT_GRAY);\r
745         h.setHint(Hints.KEY_GRID_COLOR, new Color(0.9f, 0.9f, 0.9f));\r
746         h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.WHITE);\r
747         h.setHint(RulerPainter.KEY_RULER_BACKGROUND_COLOR, new Color(0.9f, 0.9f, 0.9f, 0.75f));\r
748         h.setHint(RulerPainter.KEY_RULER_TEXT_COLOR, Color.BLACK);\r
749 \r
750         ////// Diagram Participants //////\r
751         addDiagramParticipants(ctx);\r
752         addPainterParticipants(ctx);\r
753 \r
754         /////// D'n'D ///////\r
755         addDropParticipants(ctx);\r
756 \r
757         h.setHint(ElementPainter.KEY_SELECTION_FRAME_COLOR, Color.MAGENTA);\r
758         h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);\r
759 \r
760         h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 100000.0);\r
761         h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 10.0);\r
762 \r
763         Double snapResolution = diagramPreferences.get(DiagramPreferences.P_SNAP_GRID_SIZE);\r
764         this.snapAdvisor = new GridSnapAdvisor(snapResolution);\r
765         h.setHint(DiagramHints.SNAP_ADVISOR, this.snapAdvisor);\r
766         h.setHint(GridPainter.KEY_GRID_SIZE, snapResolution);\r
767         h.setHint(GridPainter.KEY_GRID_ENABLED, Boolean.FALSE);\r
768 \r
769         // Workbench selection provider\r
770         addStructureParticipants(ctx);\r
771 \r
772         // Pop-up menu\r
773         addPopupmenu(ctx);\r
774 \r
775         // Load page frame description settings\r
776         loadPageSettings(ctx);\r
777 \r
778         addOtherParticipants(ctx);\r
779 \r
780         ctx.assertParticipantDependencies();\r
781         ctx.setLocked(false);\r
782     }\r
783 \r
784     protected void loadPageSettings(ICanvasContext ctx) {\r
785         DiagramDesc diagramDesc = null;\r
786 \r
787         // load diagram page configuration\r
788         if (diagramResource != null) {\r
789             try {\r
790                 diagramDesc = sessionContext.getSession().syncRequest(DiagramRequests.getDiagramDesc(diagramResource));\r
791             } catch (DatabaseException e) {\r
792                 ErrorLogger.defaultLogError(e);\r
793             }\r
794         }\r
795 \r
796         if (diagramDesc == null) {\r
797             // Take page description from the preferences if nothing else is available.\r
798             final DiagramDesc desc = diagramDesc = diagramPreferences.getDiagramDesc();\r
799 \r
800             // Write page configuration to graph\r
801             sessionContext.getSession().asyncRequest(new WriteRequest() {\r
802                 @Override\r
803                 public void perform(WriteGraph graph) throws DatabaseException {\r
804                         CommonDBUtils.selectClusterSet(graph, diagramResource);\r
805                     DiagramGraphUtil.setDiagramDesc(graph, diagramResource, desc);\r
806                 }\r
807             }, new Callback<DatabaseException>() {\r
808                 @Override\r
809                 public void run(DatabaseException parameter) {\r
810                     if (parameter != null)\r
811                         ErrorLogger.defaultLogError("Failed to write default diagram page description to database, see exception for details", parameter);\r
812                 }\r
813             });\r
814         }\r
815 \r
816         setDiagramDesc(ctx, diagramDesc);\r
817 \r
818         // Create a listener to react to page setting changes.\r
819         sessionContext.getSession().asyncRequest(DiagramRequests.getDiagramDesc(diagramResource),\r
820                 new ListenerDelegate<DiagramDesc>(this) {\r
821             @Override\r
822             public void execute(final DiagramDesc result) {\r
823                 if (result != null && canvasContext != null) {\r
824                     ThreadUtils.asyncExec(canvasContext.getThreadAccess(), new Runnable() {\r
825                         @Override\r
826                         public void run() {\r
827                             if (!disposed)\r
828                                 setDiagramDesc(canvasContext, result);\r
829                         }\r
830                     });\r
831                 }\r
832             }\r
833         });\r
834     }\r
835 \r
836     protected void setDiagramDesc(ICanvasContext ctx, DiagramDesc diagramDesc) {\r
837         if (diagramDesc == null)\r
838             throw new NullPointerException("null diagram desc");\r
839 \r
840         if (diagramDesc.equals(this.diagramDesc))\r
841             return;\r
842 \r
843         this.diagramDesc = diagramDesc;\r
844         IHintContext hints = ctx.getDefaultHintContext();\r
845         hints.setHint(Hints.KEY_PAGE_DESC, diagramDesc.getPageDesc());\r
846         hints.setHint(Hints.KEY_DISPLAY_PAGE, diagramDesc.isPageBordersVisible());\r
847         hints.setHint(Hints.KEY_DISPLAY_MARGINS, diagramDesc.isMarginsVisible());\r
848         hints.setHint(GridPainter.KEY_GRID_ENABLED, diagramDesc.isGridVisible());\r
849         hints.setHint(RulerPainter.KEY_RULER_ENABLED, diagramDesc.isRulerVisible());\r
850         snapAdvisor.setResolution(diagramDesc.getGridSize());\r
851         hints.setHint(GridPainter.KEY_GRID_SIZE, diagramDesc.getGridSize());\r
852     }\r
853 \r
854     /**\r
855      * Must be invoked from the AWT thread only.\r
856      * \r
857      * @param state\r
858      * @param ctx\r
859      */\r
860     protected void applyEditorState(final EditorState state, final ICanvasContext ctx) {\r
861         final IDiagram diagram = ctx.getHintStack().getHint(DiagramHints.KEY_DIAGRAM);\r
862 \r
863         if (state.viewTransform != null && state.viewTransform.getDeterminant() != 0) {\r
864             for (PanZoomRotateHandler h : ctx.getItemsByClass(PanZoomRotateHandler.class)) {\r
865                 h.setTransform(state.viewTransform);\r
866             }\r
867         }\r
868 \r
869         if (diagram != null) {\r
870             if (state.viewTransform != null)\r
871                 diagram.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT);\r
872 \r
873             if (state.toolMode != null)\r
874                 ctx.getDefaultHintContext().setHint(Hints.KEY_TOOL, state.toToolMode());\r
875             else\r
876                 ctx.getDefaultHintContext().setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);\r
877 \r
878             final Set<IElement> selected = DiagramEditorStates.toElements(state.selection, diagram);\r
879             if (!selected.isEmpty()) {\r
880                 for (Selection s : ctx.getItemsByClass(Selection.class)) {\r
881                     s.setSelection(0, selected);\r
882                 }\r
883             }\r
884         }\r
885     }\r
886 \r
887     protected EditorState getSavedEditorState(ICanvasContext ctx) {\r
888         return DiagramEditorStates.toEditorState(ctx, true, true, true);\r
889     }\r
890 \r
891     protected void saveEditorState(ICanvasContext ctx) {\r
892         DiagramEditorStates.saveEditorState(PREFERENCE_VIRTUAL_GRAPH, diagramResource, getSavedEditorState(ctx) , DiagramViewer.this);\r
893     }\r
894 \r
895     private boolean firstFocus = true;\r
896 \r
897     public void setFocus() {\r
898         \r
899         if(c != null) {\r
900                 c.setFocus();\r
901 \r
902                 if (firstFocus) {\r
903                     // This is a workaround for using the symbol viewer in multi-page\r
904                     // editors which causes the first zoom-to-fit scheduling to happen\r
905                     // already before the controls have been laid out properly.\r
906                     firstFocus = false;\r
907                     firstTimeSetFocus();\r
908                 }\r
909                 \r
910         }\r
911         \r
912     }\r
913 \r
914     protected void firstTimeSetFocus() {\r
915         // [Tuukka@2010-02-11]\r
916         // Removed since this is actually a workaround for multi-page editors.\r
917         //scheduleZoomToFit();\r
918     }\r
919 \r
920     public void dispose() {\r
921         // Deactivate all contexts here because after this the context service\r
922         // in question will not be available.\r
923         if (contextUtil != null) {\r
924             contextUtil.deactivateAll();\r
925         }\r
926 \r
927         disposed = true;\r
928         if (activation != null) {\r
929             activation.deactivate();\r
930             activation = null;\r
931         }\r
932 \r
933         if (resourceManager != null) {\r
934                 resourceManager.dispose();\r
935                 resourceManager = null;\r
936         }\r
937         //super.dispose();\r
938     }\r
939 \r
940 //    protected Resource getInputResource() {\r
941 //        return getResourceInput().getResource();\r
942 //    }\r
943 //\r
944 //    public IResourceEditorInput getResourceInput() {\r
945 //        return (IResourceEditorInput) getEditorInput();\r
946 //    }\r
947 //\r
948 //    public IResourceEditorInput2 getResourceInput2() {\r
949 //        return (IResourceEditorInput2) getEditorInput();\r
950 //    }\r
951 \r
952     public void init(DiagramViewerHost _host, MPart part, IResourceEditorInput2 input) {\r
953 \r
954         if (!(input instanceof IResourceEditorInput))\r
955             throw new RuntimeException("Invalid input: must be IResourceEditorInput");\r
956 \r
957         setHost(_host);\r
958         setPart(part);\r
959         setResourceEditorInput(input);\r
960 \r
961         // Set initial part name according to the name given by IEditorInput\r
962         host.doSetPartName(getResourceEditorInput().getName());\r
963 \r
964         Session session = SimanticsUI.peekSession();\r
965         if (session != null) {\r
966             Supplier<Boolean> disposedCallback = () -> disposed;\r
967             Display display = part.getContext().get(Shell.class).getDisplay();\r
968             session.asyncRequest(\r
969                     new TitleRequest(part.getElementId(), getResourceEditorInput()),\r
970                     new TitleUpdater(display, host::doSetPartName, disposedCallback));\r
971             session.asyncRequest(\r
972                     new ToolTipRequest(part.getElementId(), getResourceEditorInput()),\r
973                     new TitleUpdater(display, host::doSetTitleToolTip, disposedCallback));\r
974         }\r
975 \r
976         try {\r
977             // Read previous editor state from the database\r
978             editorState = DiagramEditorStates.readEditorState(getResourceEditorInput().getResource());\r
979         } catch (DatabaseException e) {\r
980             exception(e);\r
981         }\r
982     }\r
983 \r
984     @SuppressWarnings("rawtypes")\r
985     @Override\r
986     public Object getAdapter(Class adapter) {\r
987 //        System.out.println("diagramViewer getAdapter " + adapter);\r
988         // Property view support\r
989         if (adapter == IPropertyPage.class)\r
990             return createPropertyPage(getPart(), getPropertyPageContexts());\r
991         // Provide symbols for the editor\r
992         if (adapter == SymbolProviderFactory.class) {\r
993             try {\r
994                 return DiagramTypeUtils.readSymbolProviderFactory(sessionContext.getSession(), diagramResource);\r
995             } catch (DatabaseException e) {\r
996                 ErrorLogger.defaultLogError(getClass() + " failed to adapt to SymbolProviderFactory, see exception for details.", e);\r
997                 return null;\r
998             }\r
999         }\r
1000         // Outline view support\r
1001         if (adapter == IContentOutlinePage.class)\r
1002             return new DiagramOutlinePage(sessionContextProvider, getResourceEditorInput());\r
1003         // Role view support\r
1004         if (adapter == ILayersViewPage.class)\r
1005             return new DiagramLayersPage(sourceDiagram, canvasContext);\r
1006         // Support external steering of the diagram canvas, zooming etc.\r
1007         if (adapter == ICanvasContext.class)\r
1008             return canvasContext;\r
1009         // Support scene graph debugger view\r
1010         if (adapter == INode.class) {\r
1011             if (canvasContext != null) {\r
1012                 INode node = canvasContext.getCanvasNode();\r
1013                 if (node != null)\r
1014                     return NodeUtil.getRootNode(node);\r
1015             }\r
1016             return null;\r
1017         }\r
1018         // Support retrieval of the current diagram.\r
1019         if (adapter == IDiagram.class)\r
1020             return sourceDiagram;\r
1021         // Why is this here ??\r
1022         if (adapter == Session.class)\r
1023             return sessionContext.getSession();\r
1024         if(adapter == RuntimeDiagramManager.class)\r
1025             return runtimeDiagramManager;\r
1026         if (adapter == Resource.class)\r
1027             return getRuntime();\r
1028         if (adapter == ICanvasChassis.class)\r
1029                 return c;\r
1030 \r
1031         return null;\r
1032     }\r
1033 \r
1034     //-------------------------------------------------------------------------\r
1035     // Profiling aid\r
1036 \r
1037     protected static Object BEGIN(String name) {\r
1038         if (PROFILE) {\r
1039             //return ThreadLog.BEGIN(name);\r
1040         }\r
1041         return null;\r
1042     }\r
1043 \r
1044     protected static void END(Object task) {\r
1045         if (PROFILE) {\r
1046             //((Task) task).end();\r
1047         }\r
1048     }\r
1049 \r
1050     //-------------------------------------------------------------------------\r
1051     // implement ListenerSupport\r
1052 \r
1053     @Override\r
1054     public void exception(Throwable t) {\r
1055         ErrorLogger.defaultLogError(t);\r
1056     }\r
1057 \r
1058     @Override\r
1059     public boolean isDisposed() {\r
1060         return disposed;\r
1061     }\r
1062 \r
1063     protected void collectGarbage() {\r
1064         SessionGarbageCollectorJob.getInstance().schedule(0);\r
1065         AWTThread.getThreadAccess().asyncExec(new Runnable() {\r
1066             @Override\r
1067             public void run() {\r
1068                 //System.out.println("BEFORE CLEAR: " + SVGCache.getSVGUniverse().report());\r
1069                 SVGCache.getSVGUniverse().clearUnreferenced();\r
1070                 //System.out.println("AFTER CLEAR: " + SVGCache.getSVGUniverse().report());\r
1071             }\r
1072         });\r
1073     }\r
1074 \r
1075     //-------------------------------------------------------------------------\r
1076     // Listener for certain canvas context hint changes\r
1077 \r
1078     IHintListener canvasHintListener = new HintListenerAdapter() {\r
1079         @Override\r
1080         public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
1081             if (key == GridPainter.KEY_GRID_ENABLED) {\r
1082                 boolean v = Boolean.TRUE.equals(newValue);\r
1083                 if (diagramDesc.isGridVisible() != v)\r
1084                     setGlobalPreference(DiagramResource.URIs.DisplayGrid, v);\r
1085             } else if (key == RulerPainter.KEY_RULER_ENABLED) {\r
1086                 boolean v = Boolean.TRUE.equals(newValue);\r
1087                 if (diagramDesc.isRulerVisible() != v)\r
1088                     setGlobalPreference(DiagramResource.URIs.DisplayRuler, v);\r
1089             }\r
1090         }\r
1091     };\r
1092 \r
1093     private <T> void setGlobalPreference(final String preferenceURI, boolean value) {\r
1094         TagUtil.execute(Simantics.getSession(), PREFERENCE_VIRTUAL_GRAPH, preferenceURI, value, Simantics.getProjectResource());\r
1095     }\r
1096 \r
1097     /*\r
1098      * --------------------------------------------------------------------\r
1099      * Changes related to removal of EditorPart extension from here on down\r
1100      * --------------------------------------------------------------------\r
1101      */\r
1102 \r
1103     private MPart part;\r
1104     private DiagramViewerHost host;\r
1105     private IResourceEditorInput2 resourceEditorInput = null;\r
1106 \r
1107     public MPart getPart() {\r
1108         return part;\r
1109     }\r
1110 \r
1111 //    public IEditorSite getEditorSite() {\r
1112 //        return (IEditorSite) getSite();\r
1113 //    }\r
1114 \r
1115 //    public IEditorInput getEditorInput() {\r
1116 //        return editorInput;\r
1117 //    }\r
1118 \r
1119 //    protected void setPartName(String partName) {\r
1120 ////        if (compatibilityTitleListener != null) {\r
1121 ////            removePropertyListener(compatibilityTitleListener);\r
1122 ////            compatibilityTitleListener = null;\r
1123 ////        }\r
1124 ////\r
1125 ////        super.setPartName(partName);\r
1126 //    }\r
1127  \r
1128 //    protected void setTitleToolTip(String toolTip) {\r
1129 ////        toolTip = Util.safeString(toolTip);\r
1130 ////        //Do not send changes if they are the same\r
1131 ////        if (Util.equals(this.toolTip, toolTip)) {\r
1132 ////                    return;\r
1133 ////            }\r
1134 ////        this.toolTip = toolTip;\r
1135 ////        firePropertyChange(IWorkbenchPart.PROP_TITLE);\r
1136 //    }\r
1137 \r
1138     protected void setHost(DiagramViewerHost host) {\r
1139         this.host = host;\r
1140     }\r
1141 \r
1142     protected void setPart(MPart part) {\r
1143         this.part = part;\r
1144     }\r
1145 \r
1146     protected void setResourceEditorInput(IResourceEditorInput2 input) {\r
1147         Assert.isLegal(input != null);\r
1148         resourceEditorInput = input;\r
1149     }\r
1150     \r
1151     public IResourceEditorInput2 getResourceEditorInput() {\r
1152         return resourceEditorInput;\r
1153     }\r
1154 \r
1155     public Composite getComposite() {\r
1156         return c;\r
1157     }\r
1158 \r
1159 }\r