--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2013 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ * Semantum Oy - issue #4384\r
+ *******************************************************************************/\r
+package org.simantics.modeling.ui.diagramEditor;\r
+\r
+import java.awt.Color;\r
+import java.awt.dnd.DnDConstants;\r
+import java.util.Collections;\r
+import java.util.Set;\r
+import java.util.concurrent.TimeUnit;\r
+import java.util.function.Supplier;\r
+\r
+import org.eclipse.core.runtime.Assert;\r
+import org.eclipse.core.runtime.IAdaptable;\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.SubMonitor;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.jface.action.IStatusLineManager;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.ui.IEditorInput;\r
+import org.eclipse.ui.IEditorSite;\r
+import org.eclipse.ui.IWorkbenchPartSite;\r
+import org.eclipse.ui.contexts.IContextService;\r
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.model.browsecontexts.BrowseContext;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.primitiverequest.PossibleAdapter;\r
+import org.simantics.db.common.procedure.adapter.ListenerDelegate;\r
+import org.simantics.db.common.procedure.adapter.ListenerSupport;\r
+import org.simantics.db.common.request.ParametrizedRead;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.CommonDBUtils;\r
+import org.simantics.db.common.utils.TagUtil;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.request.combinations.Combinators;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.management.ISessionContextProvider;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.DiagramTypeUtils;\r
+import org.simantics.diagram.adapter.FlagClassFactory;\r
+import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;\r
+import org.simantics.diagram.adapter.IDiagramLoader;\r
+import org.simantics.diagram.connection.ModelledConnectionAdvisor;\r
+import org.simantics.diagram.handler.ConnectionCommandHandler;\r
+import org.simantics.diagram.handler.CopyPasteHandler;\r
+import org.simantics.diagram.handler.CopyPasteStrategy;\r
+import org.simantics.diagram.handler.DefaultCopyPasteStrategy;\r
+import org.simantics.diagram.handler.DeleteHandler;\r
+import org.simantics.diagram.handler.ExpandSelectionHandler;\r
+import org.simantics.diagram.handler.SimpleElementTransformHandler;\r
+import org.simantics.diagram.layer.ILayersViewPage;\r
+import org.simantics.diagram.participant.ContextUtil;\r
+import org.simantics.diagram.participant.PointerInteractor2;\r
+import org.simantics.diagram.participant.SGFocusParticipant;\r
+import org.simantics.diagram.query.DiagramRequests;\r
+import org.simantics.diagram.runtime.RuntimeDiagramManager;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.symbolcontribution.SymbolProviderFactory;\r
+import org.simantics.diagram.synchronization.CopyAdvisor;\r
+import org.simantics.diagram.synchronization.IModifiableSynchronizationContext;\r
+import org.simantics.diagram.synchronization.SynchronizationHints;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
+import org.simantics.diagram.ui.DiagramModelHints;\r
+import org.simantics.diagram.ui.SWTPopupMenuParticipant;\r
+import org.simantics.diagram.ui.SWTPopupMenuParticipantAwt;\r
+import org.simantics.diagram.ui.WorkbenchSelectionProvider;\r
+import org.simantics.g2d.canvas.Hints;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.ICanvasParticipant;\r
+import org.simantics.g2d.canvas.impl.CanvasContext;\r
+import org.simantics.g2d.chassis.AWTChassis;\r
+import org.simantics.g2d.chassis.ICanvasChassis;\r
+import org.simantics.g2d.chassis.IChassisListener;\r
+import org.simantics.g2d.chassis.SWTChassis;\r
+import org.simantics.g2d.connection.IConnectionAdvisor;\r
+import org.simantics.g2d.diagram.DiagramClass;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.handler.PickRequest.PickFilter;\r
+import org.simantics.g2d.diagram.impl.Diagram;\r
+import org.simantics.g2d.diagram.participant.DelayedBatchElementPainter;\r
+import org.simantics.g2d.diagram.participant.DiagramParticipant;\r
+import org.simantics.g2d.diagram.participant.ElementInteractor;\r
+import org.simantics.g2d.diagram.participant.ElementPainter;\r
+import org.simantics.g2d.diagram.participant.Selection;\r
+import org.simantics.g2d.diagram.participant.TerminalPainter;\r
+import org.simantics.g2d.diagram.participant.ZOrderHandler;\r
+import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;\r
+import org.simantics.g2d.element.ElementClassProviders;\r
+import org.simantics.g2d.element.ElementClasses;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.IElementClassProvider;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.elementclass.connection.ConnectionClass;\r
+import org.simantics.g2d.page.DiagramDesc;\r
+import org.simantics.g2d.participant.BackgroundPainter;\r
+import org.simantics.g2d.participant.CanvasBoundsParticipant;\r
+import org.simantics.g2d.participant.CanvasGrab;\r
+import org.simantics.g2d.participant.GridPainter;\r
+import org.simantics.g2d.participant.KeyUtil;\r
+import org.simantics.g2d.participant.MouseUtil;\r
+import org.simantics.g2d.participant.Notifications;\r
+import org.simantics.g2d.participant.PageBorderParticipant;\r
+import org.simantics.g2d.participant.PanZoomRotateHandler;\r
+import org.simantics.g2d.participant.PointerPainter;\r
+import org.simantics.g2d.participant.RenderingQualityInteractor;\r
+import org.simantics.g2d.participant.RulerPainter;\r
+import org.simantics.g2d.participant.SymbolUtil;\r
+import org.simantics.g2d.participant.TimeParticipant;\r
+import org.simantics.g2d.participant.TransformUtil;\r
+import org.simantics.g2d.participant.WorkbenchStatusLine;\r
+import org.simantics.g2d.participant.ZoomToAreaHandler;\r
+import org.simantics.g2d.tooltip.TerminalTooltipParticipant;\r
+import org.simantics.g2d.utils.CanvasUtils;\r
+import org.simantics.layer0.utils.triggers.IActivation;\r
+import org.simantics.layer0.utils.triggers.IActivationManager;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.mapping.ComponentCopyAdvisor;\r
+import org.simantics.modeling.mapping.ElementCopyAdvisor;\r
+import org.simantics.modeling.mapping.MappedElementCopyAdvisor;\r
+import org.simantics.modeling.mapping.ModelingSynchronizationHints;\r
+import org.simantics.modeling.ui.diagramEditor.handlers.LinkBrowsingHandler;\r
+import org.simantics.modeling.ui.diagramEditor.handlers.StructuralBrowsingHandler;\r
+import org.simantics.modeling.ui.preferences.DiagramPreferenceUtil;\r
+import org.simantics.modeling.ui.preferences.DiagramPreferences;\r
+import org.simantics.project.ontology.ProjectResource;\r
+import org.simantics.scenegraph.INode;\r
+import org.simantics.scenegraph.g2d.snap.GridSnapAdvisor;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+import org.simantics.selectionview.StandardPropertyPage;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.structural2.modelingRules.IModelingRules;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.jobs.SessionGarbageCollectorJob;\r
+import org.simantics.ui.workbench.IPropertyPage;\r
+import org.simantics.ui.workbench.IResourceEditorInput;\r
+import org.simantics.ui.workbench.IResourceEditorInput2;\r
+import org.simantics.ui.workbench.TitleRequest;\r
+import org.simantics.ui.workbench.TitleUpdater;\r
+import org.simantics.ui.workbench.ToolTipRequest;\r
+import org.simantics.ui.workbench.editor.input.InputValidationCombinators;\r
+import org.simantics.utils.DataContainer;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.datastructures.hints.HintContext;\r
+import org.simantics.utils.datastructures.hints.HintListenerAdapter;\r
+import org.simantics.utils.datastructures.hints.IHintContext;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+import org.simantics.utils.threads.AWTThread;\r
+import org.simantics.utils.threads.IThreadWorkQueue;\r
+import org.simantics.utils.threads.SWTThread;\r
+import org.simantics.utils.threads.ThreadUtils;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+import com.kitfox.svg.SVGCache;\r
+\r
+/**\r
+ * @author Toni Kalajainen\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class DiagramViewer \r
+ //extends EditorPart implements IResourceEditorPart2, \r
+ implements ListenerSupport, IAdaptable {\r
+\r
+ public interface DiagramViewerHost {\r
+ void doSetPartName(String name);\r
+ void doSetTitleToolTip(String name);\r
+ }\r
+\r
+ public static final String DIAGRAMMING_CONTEXT = "org.simantics.modeling.ui.diagramming";\r
+ private static final String PREFERENCE_VIRTUAL_GRAPH = "preferences";\r
+\r
+ private static final boolean PROFILE = false;\r
+\r
+ ParametrizedRead<IResourceEditorInput, Boolean> INPUT_VALIDATOR =\r
+ Combinators.compose(\r
+ InputValidationCombinators.or(\r
+ // Normal configuration diagrams of a model\r
+ Combinators.compose(\r
+ InputValidationCombinators.hasURI(),\r
+ InputValidationCombinators.partialFunction(ModelingResources.URIs.DiagramToComposite)\r
+ ),\r
+ // Configuration diagrams of a component type\r
+ Combinators.compose(\r
+ InputValidationCombinators.hasURI(),\r
+ Combinators.compose(\r
+ InputValidationCombinators.partialFunction(StructuralResource2.URIs.Defines),\r
+ InputValidationCombinators.partialFunction(ModelingResources.URIs.DiagramToComposite)\r
+ )\r
+ )\r
+ ),\r
+ InputValidationCombinators.extractInputResource()\r
+ );\r
+\r
+ protected EditorState editorState;\r
+\r
+ protected boolean disposed = false;\r
+ protected IThreadWorkQueue swt;\r
+ protected IStatusLineManager statusLineManager;\r
+ protected Display display;\r
+ protected LocalResourceManager resourceManager;\r
+ protected SWTChassis c;\r
+ protected IDiagram sourceDiagram;\r
+ protected DataContainer<IDiagram> sourceDiagramContainer;\r
+ protected CanvasContext canvasContext;\r
+ protected ISessionContextProvider sessionContextProvider;\r
+ protected ISessionContext sessionContext;\r
+ protected Resource diagramResource;\r
+ protected GraphToDiagramSynchronizer synchronizer;\r
+ protected IActivation activation;\r
+ protected ContextUtil contextUtil;\r
+ protected SWTPopupMenuParticipant popupMenuParticipant;\r
+ \r
+ protected DiagramPreferences diagramPreferences;\r
+ protected DiagramDesc diagramDesc;\r
+ protected GridSnapAdvisor snapAdvisor;\r
+\r
+ private RuntimeDiagramManager runtimeDiagramManager;\r
+\r
+ /**\r
+ * Set externally in\r
+ * {@link #init(DiagramViewerHost, IEditorSite, IEditorInput, DataContainer, WorkbenchSelectionProvider)}\r
+ * .\r
+ */\r
+ protected WorkbenchSelectionProvider selectionProvider;\r
+\r
+ public Resource getRuntime() {\r
+ RuntimeDiagramManager rtdm = runtimeDiagramManager;\r
+ return (rtdm == null) ? null : rtdm.getRuntimeDiagram();\r
+ }\r
+\r
+ public ParametrizedRead<IResourceEditorInput, Boolean> getInputValidator() {\r
+ return INPUT_VALIDATOR;\r
+ }\r
+\r
+ protected void addDropParticipants(ICanvasContext ctx) {\r
+ ctx.getDefaultHintContext().setHint(Hints.KEY_ALLOWED_DRAG_ACTIONS, DnDConstants.ACTION_COPY);\r
+\r
+ ctx.add(new PopulateElementDropParticipant(synchronizer, getSite()));\r
+ ctx.add(new PopulateElementMonitorDropParticipant(synchronizer, 0.5, 0.5));\r
+ }\r
+\r
+ protected CopyPasteStrategy getCopyPasteStrategy() {\r
+ try {\r
+ CopyPasteStrategy cpStrategy = Simantics.getSession().syncRequest(new PossibleAdapter<CopyPasteStrategy>(getInputResource(), CopyPasteStrategy.class));\r
+ if(cpStrategy != null) return cpStrategy;\r
+ } catch (DatabaseException e) {\r
+ }\r
+ return getDefaultCopyPasteStrategy();\r
+ }\r
+ \r
+ protected CopyPasteStrategy getDefaultCopyPasteStrategy() {\r
+ return new DefaultCopyPasteStrategy();\r
+ }\r
+\r
+ protected CopyAdvisor getCopyAdvisor() {\r
+ try {\r
+ CopyAdvisor advisor = Simantics.getSession().syncRequest(new PossibleAdapter<CopyAdvisor>(getInputResource(), CopyAdvisor.class));\r
+ if(advisor != null) return advisor;\r
+ } catch (DatabaseException e) {\r
+ }\r
+ return new MappedElementCopyAdvisor(new ElementCopyAdvisor(), new ComponentCopyAdvisor());\r
+ }\r
+ \r
+ /**\r
+ * @param ctx\r
+ * TODO: change argument from CanvasContext to ICanvasContext\r
+ */\r
+ protected void addKeyBindingParticipants(CanvasContext ctx) {\r
+ //ctx.add( new KeyToCommand( CommandKeyBinding.DEFAULT_BINDINGS ) );\r
+ ctx.add(new DeleteHandler(statusLineManager));\r
+ ctx.add(new CopyPasteHandler(getCopyPasteStrategy(), statusLineManager).setWorkbenchSite(getEditorSite()));\r
+ ctx.add(new ConnectionCommandHandler());\r
+ }\r
+\r
+ protected void addPopupmenu(ICanvasContext ctx) {\r
+ ctx.add(popupMenuParticipant);\r
+ }\r
+\r
+ protected void addWorkbenchSelectionProvider(ICanvasContext ctx) {\r
+ if (selectionProvider != null)\r
+ ctx.add(selectionProvider);\r
+ }\r
+\r
+ protected void addViewManipulationParticipants(CanvasContext ctx) {\r
+ ctx.add(new PanZoomRotateHandler());\r
+ //ctx.add(new MousePanZoomInteractor());\r
+ //ctx.add(new MultitouchPanZoomRotateInteractor());\r
+ // ctx.add( new OrientationRestorer() );\r
+ ctx.add(new ZoomToAreaHandler());\r
+ }\r
+\r
+ protected void addDiagramParticipants(ICanvasContext ctx) {\r
+ ctx.add(new ZOrderHandler());\r
+ ctx.add(getPointerInteractor());\r
+ ctx.add(new ElementInteractor());\r
+ ctx.add(new Selection());\r
+ ctx.add(new DiagramParticipant());\r
+ ctx.add(new ElementPainter());\r
+ //ctx.add(new ElementHeartbeater());\r
+ //ctx.add(new ZoomTransitionParticipant(TransitionFunction.SIGMOID));\r
+ //ctx.add(new TooltipParticipant());\r
+ ctx.add(new TerminalTooltipParticipant());\r
+ }\r
+\r
+ protected void addPainterParticipants(ICanvasContext ctx) {\r
+ ctx.add(new RenderingQualityInteractor());\r
+ ctx.add(new TerminalPainter(true, true, false, true));\r
+ ctx.add(new DelayedBatchElementPainter(PickFilter.FILTER_MONITORS, 500, TimeUnit.MILLISECONDS));\r
+ }\r
+\r
+ protected void addStructureParticipants(ICanvasContext ctx) {\r
+ addWorkbenchSelectionProvider(ctx);\r
+ // Add visual browsing capabilities for structural models\r
+ ctx.add(new StructuralBrowsingHandler(getSite(), sessionContext, getResourceInput2()));\r
+ ctx.add(new LinkBrowsingHandler(getSite(), this, sessionContext));\r
+ }\r
+\r
+ /**\r
+ * Override to add any diagram/canvas participants to the canvas context\r
+ * initialized for the editor.\r
+ * \r
+ * @param ctx\r
+ */\r
+ protected void addOtherParticipants(CanvasContext ctx) {\r
+ }\r
+\r
+ public static Set<String> defaultPropertyBrowseContexts = Collections.singleton(ProjectResource.URIs.ProjectBrowseContext);\r
+\r
+ protected Set<String> getPropertyPageContexts() {\r
+ try {\r
+ return BrowseContext.getBrowseContextClosure(SimanticsUI.getSession(), defaultPropertyBrowseContexts);\r
+ } catch (DatabaseException e) {\r
+ ExceptionUtils.logAndShowError("Failed to load modeled browse contexts for property page, see exception for details.", e);\r
+ return defaultPropertyBrowseContexts;\r
+ }\r
+ }\r
+\r
+ protected IPropertyPage createPropertyPage(IWorkbenchPartSite site, Set<String> contexts) {\r
+ return new StandardPropertyPage(site, contexts);\r
+ }\r
+\r
+ protected String getPopupId() {\r
+ return "#ModelingDiagramPopup";\r
+ }\r
+\r
+ protected void getPreferences() {\r
+ this.diagramPreferences = DiagramPreferenceUtil.getPreferences();\r
+ }\r
+\r
+ protected void initSession() {\r
+ sessionContextProvider = SimanticsUI.getSessionContextProvider();\r
+ sessionContext = sessionContextProvider.getSessionContext();\r
+ }\r
+\r
+ protected void readNames() {\r
+ String name = getEditorInput().getName();\r
+ host.doSetPartName(name);\r
+ host.doSetTitleToolTip(name);\r
+ }\r
+\r
+ class ChassisListener implements IChassisListener {\r
+ @Override\r
+ public void chassisClosed(ICanvasChassis sender) {\r
+ // Prevent deadlock while disposing which using syncExec would result in.\r
+ final ICanvasContext ctx = canvasContext;\r
+ ThreadUtils.asyncExec(ctx.getThreadAccess(), new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ if (ctx != null) {\r
+ saveEditorState(ctx);\r
+ ctx.getHintStack().removeKeyHintListener(GridPainter.KEY_GRID_ENABLED, canvasHintListener);\r
+ ctx.getHintStack().removeKeyHintListener(RulerPainter.KEY_RULER_ENABLED, canvasHintListener);\r
+ final AWTChassis awtChassis = c.getAWTComponent();\r
+ if (awtChassis != null)\r
+ awtChassis.setCanvasContext(null);\r
+ ctx.dispose();\r
+ }\r
+\r
+ if (sourceDiagramContainer != null) {\r
+ sourceDiagramContainer.set(null);\r
+ sourceDiagramContainer = null;\r
+ }\r
+\r
+ if (sourceDiagram != null)\r
+ sourceDiagram.dispose();\r
+\r
+ if(synchronizer != null) {\r
+ synchronizer.dispose();\r
+ // Let GC work.\r
+ synchronizer = null;\r
+ }\r
+\r
+ if (runtimeDiagramManager != null) {\r
+ runtimeDiagramManager.dispose();\r
+ runtimeDiagramManager = null;\r
+ }\r
+ }\r
+ });\r
+ c.removeChassisListener(ChassisListener.this);\r
+ }\r
+ }\r
+\r
+ protected void createChassis(Composite parent) {\r
+ resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);\r
+ c = new SWTChassis(parent, 0);\r
+\r
+ Object task = BEGIN("DV.precreateParticipants");\r
+ createCustomParticipants();\r
+ END(task);\r
+\r
+ c.populate(component -> {\r
+ if (!disposed) {\r
+ c.addChassisListener(new ChassisListener());\r
+ initializeCanvas();\r
+ }\r
+ });\r
+ }\r
+\r
+ protected void beforeSetCanvasContext(ICanvasContext canvasContext2) {\r
+ }\r
+\r
+ /**\r
+ * Invoke this only from the AWT thread.\r
+ * @param context\r
+ */\r
+ protected void setCanvasContext(ICanvasContext context) {\r
+ // Cannot directly invoke SWTChassis.setCanvasContext only because it\r
+ // needs to be invoked in the SWT thread and AWTChassis.setCanvasContext in the\r
+ // AWT thread, but directly invoking SWTChassis.setCanvasContext would call both\r
+ // in the SWT thread which would cause synchronous scheduling of AWT\r
+ // runnables which is always a potential source of deadlocks.\r
+ c.getAWTComponent().setCanvasContext(canvasContext);\r
+ swt.asyncExec(new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ if (!c.isDisposed())\r
+ // For AWT, this is a no-operation.\r
+ c.setCanvasContext(canvasContext);\r
+ }\r
+ });\r
+ }\r
+\r
+ public void createPartControl(Composite parent) {\r
+ //ProfileObserver.begin = System.nanoTime();\r
+ display = parent.getDisplay(); \r
+ swt = SWTThread.getThreadAccess(display);\r
+ statusLineManager = getEditorSite().getActionBars().getStatusLineManager();\r
+\r
+ Object task = BEGIN("DV.initSession");\r
+ initSession();\r
+ END(task);\r
+\r
+ diagramResource = getInputResource();\r
+ readNames();\r
+ getPreferences();\r
+\r
+ try {\r
+ this.runtimeDiagramManager = RuntimeDiagramManager.track(sessionContext.getSession(), diagramResource, getEditorInput(), this);\r
+\r
+ // Create the canvas context here before finishing createPartControl\r
+ // to give DiagramViewerActionContributor a chance to work.\r
+ // The context can be created in SWT thread without scheduling\r
+ // to the context thread and having potential deadlocks.\r
+ IThreadWorkQueue thread = AWTThread.getThreadAccess();\r
+ this.canvasContext = new CanvasContext(thread);\r
+ this.canvasContext.setLocked(true);\r
+\r
+ task = BEGIN("DV.createChassis");\r
+ createChassis(parent);\r
+ END(task);\r
+ } catch (DatabaseException e) {\r
+ ErrorLogger.defaultLogError(e);\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * A method invoked before chassis construction for creating such\r
+ * {@link ICanvasParticipant}s that need to be constructed in the SWT\r
+ * thread.\r
+ * \r
+ * Use it for creating any such canvas participants during the viewer \r
+ * construction and add them to the {@link ICanvasContext} later on from\r
+ * the AWT thread.\r
+ */\r
+ protected void createCustomParticipants() {\r
+ if (SimanticsUI.isLinuxGTK()) {\r
+ popupMenuParticipant = new SWTPopupMenuParticipantAwt(getSite(), c, display, getPopupId());\r
+ } else {\r
+ popupMenuParticipant = new SWTPopupMenuParticipant(getSite(), c, display, getPopupId());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Invoke this only from the AWT thread.\r
+ */\r
+ protected void initializeCanvas() {\r
+ Object canvasInit = BEGIN("DV.canvasInitialization");\r
+\r
+ Object task = BEGIN("DV.createViewerCanvas");\r
+ initializeCanvasContext(canvasContext);\r
+ END(task);\r
+\r
+ beforeSetCanvasContext(canvasContext);\r
+ //FullscreenUtils.addFullScreenHandler(canvasContext, s, canvasProvider);\r
+\r
+ // Without this all diagram participants will crash like there's no tomorrow.\r
+ // Just trying to keep the behavior a bit more sane in case of\r
+ // errors instead of flooding the console with exceptions.\r
+ canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, Diagram.spawnNew(DiagramClass.DEFAULT));\r
+\r
+ // Changes in ruler/grid activity shall be written as\r
+ // workspace-persistent diagram-specific preferences.\r
+ canvasContext.getHintStack().addKeyHintListener(GridPainter.KEY_GRID_ENABLED, canvasHintListener);\r
+ canvasContext.getHintStack().addKeyHintListener(RulerPainter.KEY_RULER_ENABLED, canvasHintListener);\r
+\r
+ task = BEGIN("DV.setCanvasContext");\r
+ setCanvasContext(canvasContext);\r
+ END(task);\r
+\r
+ // Finish loading in a worker thread because it may be a time consuming\r
+ // process to load a large diagram and we don't want unnecessary AWT\r
+ // thread contention.\r
+ Job loadJob = new DiagramViewerLoadJob(this);\r
+ loadJob.schedule();\r
+\r
+ END(canvasInit);\r
+ }\r
+\r
+ protected void activateUiContexts(ContextUtil util) {\r
+ util.activate(DIAGRAMMING_CONTEXT);\r
+ }\r
+\r
+ /**\r
+ * @param monitor the progress monitor to use for reporting progress to the\r
+ * user. It is the caller's responsibility to call done() on the\r
+ * given monitor. Accepts <code>null</code>, indicating that no\r
+ * progress should be reported and that the operation cannot be\r
+ * cancelled.\r
+ */\r
+ protected void performActivation(IProgressMonitor monitor) {\r
+ SubMonitor progress = SubMonitor.convert(monitor, "Activate Mapping", 100);\r
+ IActivationManager activationManager = sessionContext.getSession().peekService(IActivationManager.class);\r
+ if (activationManager != null) {\r
+ activation = activationManager.activate(diagramResource);\r
+ }\r
+ progress.worked(100);\r
+ }\r
+\r
+ protected void onCreated() {\r
+ }\r
+\r
+ /**\r
+ * @param diagram\r
+ */\r
+ protected void scheduleZoomToFit(IDiagram diagram) {\r
+ if (diagram == null)\r
+ throw new IllegalStateException("diagram is null");\r
+\r
+ CanvasUtils.scheduleZoomToFit(swt, () -> disposed, canvasContext, diagram);\r
+ }\r
+\r
+ /**\r
+ * Subclasses may override but should always invoke super.\r
+ * \r
+ * @param diagram\r
+ * @param initialHints\r
+ * @throws DatabaseException\r
+ */\r
+ protected void fillInitialDiagramHints(Resource diagram, IHintContext initialHints) throws DatabaseException {\r
+ IModelingRules modelingRules = sessionContext.getSession().syncRequest(\r
+ DiagramRequests.getModelingRules(diagram, null));\r
+ if (modelingRules != null) {\r
+ initialHints.setHint(DiagramModelHints.KEY_MODELING_RULES, modelingRules);\r
+ initialHints.setHint(DiagramHints.CONNECTION_ADVISOR,\r
+ getConnectionAdvisor(modelingRules, sessionContext.getSession()));\r
+ }\r
+\r
+ initialHints.setHint(SynchronizationHints.COPY_ADVISOR, getCopyAdvisor());\r
+ initialHints.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, Boolean.TRUE);\r
+ initialHints.setHint(DiagramHints.KEY_ALLOW_CONNECTION_BRANCHING, Boolean.TRUE);\r
+ initialHints.setHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS, Boolean.TRUE);\r
+ }\r
+\r
+ /**\r
+ * @param monitor the progress monitor to use for reporting progress to the\r
+ * user. It is the caller's responsibility to call done() on the\r
+ * given monitor. Accepts <code>null</code>, indicating that no\r
+ * progress should be reported and that the operation cannot be\r
+ * cancelled.\r
+ * @param r\r
+ * @return\r
+ * @throws DatabaseException\r
+ */\r
+ protected IDiagram loadDiagram(IProgressMonitor monitor, final Resource r) throws DatabaseException {\r
+ // Pre-load modeling rules and possibly other hints too since they are\r
+ // needed already while loading the diagram contents.\r
+ IHintContext initialHints = new HintContext();\r
+ fillInitialDiagramHints(r, initialHints);\r
+ IDiagram d = loadDiagram(monitor, r, initialHints);\r
+ return d;\r
+ }\r
+\r
+ /**\r
+ * @param monitor the progress monitor to use for reporting progress to the\r
+ * user. It is the caller's responsibility to call done() on the\r
+ * given monitor. Accepts <code>null</code>, indicating that no\r
+ * progress should be reported and that the operation cannot be\r
+ * cancelled.\r
+ * @param diagram\r
+ * @param initialHints\r
+ * @return\r
+ * @throws DatabaseException\r
+ */\r
+ protected IDiagram loadDiagram(IProgressMonitor monitor, Resource diagram, IHintContext initialHints) throws DatabaseException {\r
+ RuntimeDiagramManager rtdm = runtimeDiagramManager;\r
+ Resource runtimeDiagram = rtdm != null ? rtdm.getRuntimeDiagram() : null;\r
+ IDiagramLoader loader = synchronizer;\r
+ if (rtdm == null || runtimeDiagram == null || loader == null)\r
+ return null;\r
+ IDiagram d = sessionContext.getSession().syncRequest(\r
+ DiagramRequests.loadDiagram(monitor, getResourceInput2().getModel(null), diagram,\r
+ runtimeDiagram, null, loader, initialHints));\r
+ return d;\r
+ }\r
+\r
+ protected void beforeSetDiagram(IDiagram diagram) {\r
+ }\r
+\r
+ protected PointerInteractor getPointerInteractor() {\r
+ return new PointerInteractor2(true, true, true, false, true, false, synchronizer.getElementClassProvider());\r
+ }\r
+\r
+ protected IConnectionAdvisor getConnectionAdvisor(IModelingRules modelingRules, Session session) {\r
+ return new ModelledConnectionAdvisor(modelingRules, sessionContext.getSession());\r
+ }\r
+\r
+ protected GraphToDiagramSynchronizer createSynchronizer(final ICanvasContext ctx, final ISessionContext sessionContext) {\r
+ try {\r
+ return sessionContext.getSession().syncRequest(new Read<GraphToDiagramSynchronizer>() {\r
+ @Override\r
+ public GraphToDiagramSynchronizer perform(ReadGraph graph) throws DatabaseException {\r
+ GraphToDiagramSynchronizer sync = new GraphToDiagramSynchronizer(graph, ctx, createElementClassProvider(graph));\r
+ initializeSynchronizationContext(graph, sync);\r
+ return sync;\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ throw new UnsupportedOperationException("Failed to initialize data model synchronizer", e);\r
+ }\r
+ }\r
+\r
+ protected void initializeSynchronizationContext(ReadGraph graph, IModifiableSynchronizationContext context) {\r
+ context.set(ModelingSynchronizationHints.MODELING_RESOURCE, ModelingResources.getInstance(graph));\r
+ }\r
+\r
+ protected IElementClassProvider createElementClassProvider(ReadGraph graph) {\r
+ DiagramResource dr = DiagramResource.getInstance(graph);\r
+ return ElementClassProviders.mappedProvider(\r
+ ElementClasses.CONNECTION, ConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(dr.RouteGraphConnection)),\r
+ ElementClasses.FLAG, FlagClassFactory.createFlagClass(dr.Flag, dr.Flag_Terminal)\r
+ );\r
+ }\r
+ \r
+ protected SimpleElementTransformHandler getTransformHandler() {\r
+ return new SimpleElementTransformHandler(true, true, true);\r
+ }\r
+\r
+ public void initializeCanvasContext(CanvasContext ctx) {\r
+ IHintContext h = ctx.getDefaultHintContext();\r
+\r
+ // The canvas context should not be painted until it is ready to avoid\r
+ // unnecessary visual glitches.\r
+ h.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE);\r
+\r
+ Object task = BEGIN("createSynchronizer");\r
+ this.synchronizer = createSynchronizer(ctx, sessionContext);\r
+ END(task);\r
+\r
+ IContextService contextService = (IContextService) getSite().getService(IContextService.class);\r
+ contextUtil = new ContextUtil(contextService, swt);\r
+\r
+ // Support & Util Participants\r
+ ctx.add(new TransformUtil());\r
+ ctx.add(new MouseUtil());\r
+ ctx.add(new KeyUtil());\r
+ ctx.add(contextUtil);\r
+ ctx.add(new WorkbenchStatusLine(statusLineManager));\r
+ ctx.add(new CanvasGrab());\r
+ ctx.add(new SymbolUtil());\r
+ ctx.add(new TimeParticipant());\r
+ ctx.add(new CanvasBoundsParticipant());\r
+ ctx.add(new Notifications());\r
+\r
+ ctx.add(new SGFocusParticipant(c, DIAGRAMMING_CONTEXT));\r
+\r
+ // Debug participant(s)\r
+ // ctx.add( new PointerPainter() );\r
+ // ctx.add( new HandPainter() );\r
+ h.setHint(PointerPainter.KEY_PAINT_POINTER, true);\r
+\r
+ // Pan & Zoom & Rotate\r
+ addViewManipulationParticipants(ctx);\r
+\r
+ ctx.add(getTransformHandler());\r
+ ctx.add(new ExpandSelectionHandler(getEditorSite().getActionBars().getStatusLineManager()));\r
+\r
+ // Key bindings\r
+ addKeyBindingParticipants(ctx);\r
+\r
+ // Grid & Ruler & Background\r
+ ctx.add(new GridPainter());\r
+ ctx.add(new RulerPainter());\r
+ ctx.add(new BackgroundPainter());\r
+\r
+ h.setHint(Hints.KEY_DISPLAY_PAGE, diagramPreferences.get(DiagramPreferences.P_DISPLAY_PAGE_SIZE));\r
+ h.setHint(Hints.KEY_DISPLAY_MARGINS, diagramPreferences.get(DiagramPreferences.P_DISPLAY_MARGINS));\r
+ ctx.add(new PageBorderParticipant());\r
+\r
+ // h.setHint(Hints.KEY_GRID_COLOR, new Color(0.9f, 0.9f, 0.9f));\r
+ // h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.LIGHT_GRAY);\r
+ h.setHint(Hints.KEY_GRID_COLOR, new Color(0.9f, 0.9f, 0.9f));\r
+ h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.WHITE);\r
+ h.setHint(RulerPainter.KEY_RULER_BACKGROUND_COLOR, new Color(0.9f, 0.9f, 0.9f, 0.75f));\r
+ h.setHint(RulerPainter.KEY_RULER_TEXT_COLOR, Color.BLACK);\r
+\r
+ ////// Diagram Participants //////\r
+ addDiagramParticipants(ctx);\r
+ addPainterParticipants(ctx);\r
+\r
+ /////// D'n'D ///////\r
+ addDropParticipants(ctx);\r
+\r
+ h.setHint(ElementPainter.KEY_SELECTION_FRAME_COLOR, Color.MAGENTA);\r
+ h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);\r
+\r
+ h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 100000.0);\r
+ h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 10.0);\r
+\r
+ Double snapResolution = diagramPreferences.get(DiagramPreferences.P_SNAP_GRID_SIZE);\r
+ this.snapAdvisor = new GridSnapAdvisor(snapResolution);\r
+ h.setHint(DiagramHints.SNAP_ADVISOR, this.snapAdvisor);\r
+ h.setHint(GridPainter.KEY_GRID_SIZE, snapResolution);\r
+ h.setHint(GridPainter.KEY_GRID_ENABLED, Boolean.FALSE);\r
+\r
+ // Workbench selection provider\r
+ addStructureParticipants(ctx);\r
+\r
+ // Pop-up menu\r
+ addPopupmenu(ctx);\r
+\r
+ // Load page frame description settings\r
+ loadPageSettings(ctx);\r
+\r
+ addOtherParticipants(ctx);\r
+\r
+ ctx.assertParticipantDependencies();\r
+ ctx.setLocked(false);\r
+ }\r
+\r
+ protected void loadPageSettings(ICanvasContext ctx) {\r
+ DiagramDesc diagramDesc = null;\r
+\r
+ // load diagram page configuration\r
+ if (diagramResource != null) {\r
+ try {\r
+ diagramDesc = sessionContext.getSession().syncRequest(DiagramRequests.getDiagramDesc(diagramResource));\r
+ } catch (DatabaseException e) {\r
+ ErrorLogger.defaultLogError(e);\r
+ }\r
+ }\r
+\r
+ if (diagramDesc == null) {\r
+ // Take page description from the preferences if nothing else is available.\r
+ final DiagramDesc desc = diagramDesc = diagramPreferences.getDiagramDesc();\r
+\r
+ // Write page configuration to graph\r
+ sessionContext.getSession().asyncRequest(new WriteRequest() {\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ CommonDBUtils.selectClusterSet(graph, diagramResource);\r
+ DiagramGraphUtil.setDiagramDesc(graph, diagramResource, desc);\r
+ }\r
+ }, new Callback<DatabaseException>() {\r
+ @Override\r
+ public void run(DatabaseException parameter) {\r
+ if (parameter != null)\r
+ ErrorLogger.defaultLogError("Failed to write default diagram page description to database, see exception for details", parameter);\r
+ }\r
+ });\r
+ }\r
+\r
+ setDiagramDesc(ctx, diagramDesc);\r
+\r
+ // Create a listener to react to page setting changes.\r
+ sessionContext.getSession().asyncRequest(DiagramRequests.getDiagramDesc(diagramResource),\r
+ new ListenerDelegate<DiagramDesc>(this) {\r
+ @Override\r
+ public void execute(final DiagramDesc result) {\r
+ if (result != null && canvasContext != null) {\r
+ ThreadUtils.asyncExec(canvasContext.getThreadAccess(), new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ if (!disposed)\r
+ setDiagramDesc(canvasContext, result);\r
+ }\r
+ });\r
+ }\r
+ }\r
+ });\r
+ }\r
+\r
+ protected void setDiagramDesc(ICanvasContext ctx, DiagramDesc diagramDesc) {\r
+ if (diagramDesc == null)\r
+ throw new NullPointerException("null diagram desc");\r
+\r
+ if (diagramDesc.equals(this.diagramDesc))\r
+ return;\r
+\r
+ this.diagramDesc = diagramDesc;\r
+ IHintContext hints = ctx.getDefaultHintContext();\r
+ hints.setHint(Hints.KEY_PAGE_DESC, diagramDesc.getPageDesc());\r
+ hints.setHint(Hints.KEY_DISPLAY_PAGE, diagramDesc.isPageBordersVisible());\r
+ hints.setHint(Hints.KEY_DISPLAY_MARGINS, diagramDesc.isMarginsVisible());\r
+ hints.setHint(GridPainter.KEY_GRID_ENABLED, diagramDesc.isGridVisible());\r
+ hints.setHint(RulerPainter.KEY_RULER_ENABLED, diagramDesc.isRulerVisible());\r
+ snapAdvisor.setResolution(diagramDesc.getGridSize());\r
+ hints.setHint(GridPainter.KEY_GRID_SIZE, diagramDesc.getGridSize());\r
+ }\r
+\r
+ /**\r
+ * Must be invoked from the AWT thread only.\r
+ * \r
+ * @param state\r
+ * @param ctx\r
+ */\r
+ protected void applyEditorState(final EditorState state, final ICanvasContext ctx) {\r
+ final IDiagram diagram = ctx.getHintStack().getHint(DiagramHints.KEY_DIAGRAM);\r
+\r
+ if (state.viewTransform != null && state.viewTransform.getDeterminant() != 0) {\r
+ for (PanZoomRotateHandler h : ctx.getItemsByClass(PanZoomRotateHandler.class)) {\r
+ h.setTransform(state.viewTransform);\r
+ }\r
+ }\r
+\r
+ if (diagram != null) {\r
+ if (state.viewTransform != null)\r
+ diagram.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT);\r
+\r
+ if (state.toolMode != null)\r
+ ctx.getDefaultHintContext().setHint(Hints.KEY_TOOL, state.toToolMode());\r
+ else\r
+ ctx.getDefaultHintContext().setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);\r
+\r
+ final Set<IElement> selected = DiagramEditorStates.toElements(state.selection, diagram);\r
+ if (!selected.isEmpty()) {\r
+ for (Selection s : ctx.getItemsByClass(Selection.class)) {\r
+ s.setSelection(0, selected);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ protected EditorState getSavedEditorState(ICanvasContext ctx) {\r
+ return DiagramEditorStates.toEditorState(ctx, true, true, true);\r
+ }\r
+\r
+ protected void saveEditorState(ICanvasContext ctx) {\r
+ DiagramEditorStates.saveEditorState(PREFERENCE_VIRTUAL_GRAPH, diagramResource, getSavedEditorState(ctx) , DiagramViewer.this);\r
+ }\r
+\r
+ private boolean firstFocus = true;\r
+\r
+ public void setFocus() {\r
+ \r
+ if(c != null) {\r
+ c.setFocus();\r
+\r
+ if (firstFocus) {\r
+ // This is a workaround for using the symbol viewer in multi-page\r
+ // editors which causes the first zoom-to-fit scheduling to happen\r
+ // already before the controls have been laid out properly.\r
+ firstFocus = false;\r
+ firstTimeSetFocus();\r
+ }\r
+ \r
+ }\r
+ \r
+ }\r
+\r
+ protected void firstTimeSetFocus() {\r
+ // [Tuukka@2010-02-11]\r
+ // Removed since this is actually a workaround for multi-page editors.\r
+ //scheduleZoomToFit();\r
+ }\r
+\r
+ public void dispose() {\r
+ // Deactivate all contexts here because after this the context service\r
+ // in question will not be available.\r
+ if (contextUtil != null) {\r
+ contextUtil.deactivateAll();\r
+ }\r
+\r
+ disposed = true;\r
+ if (activation != null) {\r
+ activation.deactivate();\r
+ activation = null;\r
+ }\r
+\r
+ if (resourceManager != null) {\r
+ resourceManager.dispose();\r
+ resourceManager = null;\r
+ }\r
+ //super.dispose();\r
+ }\r
+\r
+ protected Resource getInputResource() {\r
+ return getResourceInput().getResource();\r
+ }\r
+\r
+ public IResourceEditorInput getResourceInput() {\r
+ return (IResourceEditorInput) getEditorInput();\r
+ }\r
+\r
+ public IResourceEditorInput2 getResourceInput2() {\r
+ return (IResourceEditorInput2) getEditorInput();\r
+ }\r
+\r
+ public void init(DiagramViewerHost _host, IEditorSite site, IEditorInput input, DataContainer<IDiagram> diagramContainer, WorkbenchSelectionProvider selectionProvider) {\r
+ if (!(input instanceof IResourceEditorInput))\r
+ throw new RuntimeException("Invalid input: must be IResourceEditorInput");\r
+\r
+ setHost(_host);\r
+ setSite(site);\r
+ setInput(input);\r
+ this.sourceDiagramContainer = diagramContainer;\r
+ this.selectionProvider = selectionProvider;\r
+\r
+ // Set initial part name according to the name given by IEditorInput\r
+ host.doSetPartName(getEditorInput().getName());\r
+\r
+ Session session = SimanticsUI.peekSession();\r
+ if (session != null) {\r
+ Supplier<Boolean> disposedCallback = () -> disposed;\r
+ session.asyncRequest(\r
+ new TitleRequest(site.getId(), getResourceInput()),\r
+ new TitleUpdater(site.getShell().getDisplay(), host::doSetPartName, disposedCallback));\r
+ session.asyncRequest(\r
+ new ToolTipRequest(site.getId(), getResourceInput()),\r
+ new TitleUpdater(site.getShell().getDisplay(), host::doSetTitleToolTip, disposedCallback));\r
+ }\r
+\r
+ try {\r
+ // Read previous editor state from the database\r
+ editorState = DiagramEditorStates.readEditorState(getInputResource());\r
+ } catch (DatabaseException e) {\r
+ exception(e);\r
+ }\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T> T getAdapter(Class<T> adapter) {\r
+// System.out.println("diagramViewer getAdapter " + adapter);\r
+ // Property view support\r
+ if (adapter == IPropertyPage.class)\r
+ return (T) createPropertyPage(getSite(), getPropertyPageContexts());\r
+ // Provide symbols for the editor\r
+ if (adapter == SymbolProviderFactory.class) {\r
+ try {\r
+ return (T) DiagramTypeUtils.readSymbolProviderFactory(sessionContext.getSession(), diagramResource);\r
+ } catch (DatabaseException e) {\r
+ ErrorLogger.defaultLogError(getClass() + " failed to adapt to SymbolProviderFactory, see exception for details.", e);\r
+ return null;\r
+ }\r
+ }\r
+ // Outline view support\r
+ if (adapter == IContentOutlinePage.class)\r
+ return (T) new DiagramOutlinePage(sessionContextProvider, getResourceInput2());\r
+ // Role view support\r
+ if (adapter == ILayersViewPage.class)\r
+ return (T) new DiagramLayersPage(sourceDiagram, canvasContext);\r
+ // Support external steering of the diagram canvas, zooming etc.\r
+ if (adapter == ICanvasContext.class)\r
+ return (T) canvasContext;\r
+ // Support scene graph debugger view\r
+ if (adapter == INode.class) {\r
+ if (canvasContext != null) {\r
+ INode node = canvasContext.getCanvasNode();\r
+ if (node != null)\r
+ return (T) NodeUtil.getRootNode(node);\r
+ }\r
+ return null;\r
+ }\r
+ // Support retrieval of the current diagram.\r
+ if (adapter == IDiagram.class)\r
+ return (T) sourceDiagram;\r
+ // Why is this here ??\r
+ if (adapter == Session.class)\r
+ return (T) sessionContext.getSession();\r
+ if(adapter == RuntimeDiagramManager.class)\r
+ return (T) runtimeDiagramManager;\r
+ if (adapter == Resource.class)\r
+ return (T) getRuntime();\r
+ if (adapter == ICanvasChassis.class)\r
+ return (T) c;\r
+\r
+ return null;\r
+ }\r
+\r
+ //-------------------------------------------------------------------------\r
+ // Profiling aid\r
+\r
+ protected static Object BEGIN(String name) {\r
+ if (PROFILE) {\r
+ //return ThreadLog.BEGIN(name);\r
+ }\r
+ return null;\r
+ }\r
+\r
+ protected static void END(Object task) {\r
+ if (PROFILE) {\r
+ //((Task) task).end();\r
+ }\r
+ }\r
+\r
+ //-------------------------------------------------------------------------\r
+ // implement ListenerSupport\r
+\r
+ @Override\r
+ public void exception(Throwable t) {\r
+ ErrorLogger.defaultLogError(t);\r
+ }\r
+\r
+ @Override\r
+ public boolean isDisposed() {\r
+ return disposed;\r
+ }\r
+\r
+ protected void collectGarbage() {\r
+ SessionGarbageCollectorJob.getInstance().schedule(0);\r
+ AWTThread.getThreadAccess().asyncExec(new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ //System.out.println("BEFORE CLEAR: " + SVGCache.getSVGUniverse().report());\r
+ SVGCache.getSVGUniverse().clearUnreferenced();\r
+ //System.out.println("AFTER CLEAR: " + SVGCache.getSVGUniverse().report());\r
+ }\r
+ });\r
+ }\r
+\r
+ //-------------------------------------------------------------------------\r
+ // Listener for certain canvas context hint changes\r
+\r
+ IHintListener canvasHintListener = new HintListenerAdapter() {\r
+ @Override\r
+ public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
+ if (key == GridPainter.KEY_GRID_ENABLED) {\r
+ boolean v = Boolean.TRUE.equals(newValue);\r
+ if (diagramDesc.isGridVisible() != v)\r
+ setGlobalPreference(DiagramResource.URIs.DisplayGrid, v);\r
+ } else if (key == RulerPainter.KEY_RULER_ENABLED) {\r
+ boolean v = Boolean.TRUE.equals(newValue);\r
+ if (diagramDesc.isRulerVisible() != v)\r
+ setGlobalPreference(DiagramResource.URIs.DisplayRuler, v);\r
+ }\r
+ }\r
+ };\r
+\r
+ private <T> void setGlobalPreference(final String preferenceURI, boolean value) {\r
+ TagUtil.execute(Simantics.getSession(), PREFERENCE_VIRTUAL_GRAPH, preferenceURI, value, Simantics.getProjectResource());\r
+ }\r
+\r
+ /*\r
+ * --------------------------------------------------------------------\r
+ * Changes related to removal of EditorPart extension from here on down\r
+ * --------------------------------------------------------------------\r
+ */\r
+\r
+ private IWorkbenchPartSite partSite;\r
+ private DiagramViewerHost host;\r
+ private IEditorInput editorInput = null;\r
+\r
+ /* (non-Javadoc)\r
+ * Method declared on IWorkbenchPart.\r
+ */\r
+ public IWorkbenchPartSite getSite() {\r
+ return partSite;\r
+ }\r
+\r
+ public IEditorSite getEditorSite() {\r
+ return (IEditorSite) getSite();\r
+ }\r
+\r
+ public IEditorInput getEditorInput() {\r
+ return editorInput;\r
+ }\r
+\r
+// protected void setPartName(String partName) {\r
+//// if (compatibilityTitleListener != null) {\r
+//// removePropertyListener(compatibilityTitleListener);\r
+//// compatibilityTitleListener = null;\r
+//// }\r
+////\r
+//// super.setPartName(partName);\r
+// }\r
+ \r
+// protected void setTitleToolTip(String toolTip) {\r
+//// toolTip = Util.safeString(toolTip);\r
+//// //Do not send changes if they are the same\r
+//// if (Util.equals(this.toolTip, toolTip)) {\r
+//// return;\r
+//// }\r
+//// this.toolTip = toolTip;\r
+//// firePropertyChange(IWorkbenchPart.PROP_TITLE);\r
+// }\r
+\r
+ protected void setHost(DiagramViewerHost host) {\r
+ this.host = host;\r
+ }\r
+\r
+ protected void setSite(IWorkbenchPartSite site) {\r
+ this.partSite = site;\r
+ }\r
+\r
+ protected void setInput(IEditorInput input) {\r
+ Assert.isLegal(input != null);\r
+ editorInput = input;\r
+ }\r
+\r
+ public Composite getComposite() {\r
+ return c;\r
+ }\r
+\r
+}\r