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