-/*******************************************************************************\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.lang.reflect.InvocationTargetException;\r
-import java.util.function.Supplier;\r
-\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.eclipse.core.runtime.SubMonitor;\r
-import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;\r
-import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;\r
-import org.eclipse.jface.action.IStatusLineManager;\r
-import org.eclipse.jface.operation.IRunnableWithProgress;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.ui.IEditorInput;\r
-import org.eclipse.ui.IEditorSite;\r
-import org.eclipse.ui.PartInitException;\r
-import org.eclipse.ui.PlatformUI;\r
-import org.eclipse.ui.contexts.IContextService;\r
-import org.eclipse.ui.part.EditorPart;\r
-import org.eclipse.ui.views.contentoutline.IContentOutlinePage;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.common.ResourceArray;\r
-import org.simantics.db.exception.DatabaseException;\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.adapter.DefaultConnectionClassFactory;\r
-import org.simantics.diagram.adapter.FlagClassFactory;\r
-import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;\r
-import org.simantics.diagram.handler.ConnectionCommandHandler;\r
-import org.simantics.diagram.handler.CopyPasteHandler;\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.SGFocusParticipant;\r
-import org.simantics.diagram.query.DiagramRequests;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.diagram.synchronization.IModifiableSynchronizationContext;\r
-import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
-import org.simantics.diagram.ui.SWTPopupMenuParticipant;\r
-import org.simantics.g2d.canvas.Hints;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.canvas.impl.CanvasContext;\r
-import org.simantics.g2d.chassis.SWTChassis;\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.impl.Diagram;\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.IElementClassProvider;\r
-import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
-import org.simantics.g2d.participant.CanvasBoundsParticipant;\r
-import org.simantics.g2d.participant.CanvasGrab;\r
-import org.simantics.g2d.participant.KeyUtil;\r
-import org.simantics.g2d.participant.MouseUtil;\r
-import org.simantics.g2d.participant.MultitouchPanZoomRotateInteractor;\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.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.ZoomToAreaHandler;\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.ModelingSynchronizationHints;\r
-import org.simantics.modeling.ui.diagramEditor.handlers.WorkbenchStructuralSelectionProvider;\r
-import org.simantics.modeling.ui.preferences.DiagramPreferenceUtil;\r
-import org.simantics.modeling.ui.preferences.DiagramPreferences;\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.ui.SimanticsUI;\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.IResourceEditorPart2;\r
-import org.simantics.ui.workbench.ResourceEditorSupport;\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.utils.DataContainer;\r
-import org.simantics.utils.datastructures.hints.IHintContext;\r
-import org.simantics.utils.page.PageDesc;\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
-\r
-/**\r
- * @author Toni Kalajainen\r
- * @author Tuukka Lehtonen\r
- */\r
-public class SheetViewer extends EditorPart implements IResourceEditorPart2 {\r
-\r
- private static final boolean PROFILE = false;\r
-\r
- protected boolean disposed = false;\r
- protected IThreadWorkQueue swt;\r
- protected IStatusLineManager statusLineManager;\r
- protected SWTChassis c;\r
- protected IDiagram sourceDiagram;\r
- protected ICanvasContext canvasContext;\r
- protected ResourceEditorSupport support;\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
-\r
- protected DiagramPreferences diagramPreferences;\r
- protected GridSnapAdvisor snapAdvisor;\r
-\r
- public ResourceArray structuralPath;\r
-\r
- IPreferenceChangeListener preferenceListener = new IPreferenceChangeListener() {\r
- @Override\r
- public void preferenceChange(PreferenceChangeEvent event) {\r
- String value = (String) event.getNewValue();\r
- if (DiagramPreferences.P_SNAP_GRID_SIZE.equals(event.getKey())) {\r
- double grid = DiagramPreferences.DEFAULT_SNAP_GRID_SIZE;\r
- if (value != null)\r
- grid = Double.parseDouble(value);\r
- snapAdvisor.setResolution(grid);\r
- } else if (DiagramPreferences.P_DEFAULT_PAGE_SIZE.equals(event.getKey())) {\r
- PageDesc pageDesc = PageDesc.deserialize(value, DiagramPreferences.DEFAULT_PAGE_SIZE);\r
- //System.out.println("new page desc: " + pageDesc);\r
- canvasContext.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc);\r
- } else if (DiagramPreferences.P_DISPLAY_PAGE_SIZE.equals(event.getKey())) {\r
- Boolean display = value != null ? Boolean.parseBoolean(value) : DiagramPreferences.DEFAULT_DISPLAY_PAGE_SIZE;\r
- canvasContext.getDefaultHintContext().setHint(Hints.KEY_DISPLAY_PAGE, display);\r
- } else if (DiagramPreferences.P_DISPLAY_MARGINS.equals(event.getKey())) {\r
- Boolean display = value != null ? Boolean.parseBoolean(value) : DiagramPreferences.DEFAULT_DISPLAY_MARGINS;\r
- canvasContext.getDefaultHintContext().setHint(Hints.KEY_DISPLAY_MARGINS, display);\r
- }\r
- }\r
- };\r
-\r
- protected void addDropParticipants(ICanvasContext ctx) {\r
- // FIXME This is a workaround so that this participant can be disabled\r
- // for SymbolViewer\r
- ctx.add(new PopulateElementDropParticipant(synchronizer));\r
- ctx.add(new PopulateElementMonitorDropParticipant(synchronizer, 0.5, 0.5));\r
- }\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(statusLineManager));\r
- ctx.add(new ConnectionCommandHandler());\r
- }\r
-\r
- protected void addPopupmenu(ICanvasContext ctx) {\r
- ctx.add(new SWTPopupMenuParticipant(getSite(), c, getPopupId()));\r
- }\r
-\r
- protected void addStructureParticipants(ICanvasContext ctx) {\r
- structuralPath = getResourceInput().getResourceArray().removeFromBeginning(1);\r
-\r
- ctx.add(new WorkbenchStructuralSelectionProvider(swt, getSite(), structuralPath));\r
- // Add visual browsing capabilities for structural models\r
-// ctx.add(new StructuralBrowsingHandler(getSite(), sessionContext, structuralPath));\r
-// ctx.add(new LinkBrowsingHandler(getSite(), this, sessionContext));\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
- setPartName(name);\r
- setTitleToolTip(name);\r
- }\r
-\r
- protected void createChassis(Composite parent) {\r
- c = new SWTChassis(parent, 0);\r
- c.syncPopulate();\r
- }\r
-\r
- protected void setCanvasContext(ICanvasContext context) {\r
- c.setCanvasContext(canvasContext);\r
- }\r
-\r
- @Override\r
- public void createPartControl(Composite parent) {\r
- swt = SWTThread.getThreadAccess(parent.getDisplay());\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
- task = BEGIN("DV.createChassis");\r
- createChassis(parent);\r
- END(task);\r
-\r
- initializeCanvas();\r
-\r
- // Start tracking changes in diagram preferences.\r
- diagramPreferences.preferences.addPreferenceChangeListener(preferenceListener);\r
- }\r
-\r
- protected void initializeCanvas() {\r
- Object canvasInit = BEGIN("DV.canvasInitialization");\r
-\r
- Object task = BEGIN("DV.createViewerCanvas");\r
-// ThreadUtils.syncExec(AWTThread.getThreadAccess(), new Runnable() {\r
-// @Override\r
-// public void run() {\r
- canvasContext = createViewerCanvas();\r
-// }\r
-// });\r
- END(task);\r
-\r
- //FullscreenUtils.addFullScreenHandler(canvasContext, s, canvasProvider);\r
-\r
- task = BEGIN("DV.setCanvasContext");\r
- setCanvasContext(canvasContext);\r
- END(task);\r
-\r
- try {\r
- task = BEGIN("DV.loadDiagram");\r
- sourceDiagram = loadDiagram(diagramResource);\r
- END(task);\r
-\r
- // Zoom to fit\r
- task = BEGIN("DV.scheduleZoomToFit");\r
-\r
-// canvasContext.getDefaultHintContext().setHint(Hints.KEY_CANVAS_TRANSFORM, new AffineTransform());\r
-// canvasContext.getContentContext().setDirty();\r
- scheduleZoomToFit();\r
-\r
- END(task);\r
-\r
- // Start an activation for the input resource.\r
- // This will activate mapping if necessary.\r
- task = BEGIN("DV.performActivation");\r
- performActivation();\r
- END(task);\r
-\r
- task = BEGIN("DV.activate context");\r
- contextUtil.activate(DiagramViewer.DIAGRAMMING_CONTEXT);\r
- END(task);\r
-\r
- task = BEGIN("DV.onCreated");\r
- onCreated();\r
- END(task);\r
-\r
- } catch (DatabaseException e) {\r
- ErrorLogger.defaultLogError(e);\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
- END(canvasInit);\r
- }\r
-\r
- protected void performActivation() {\r
-\r
- IActivationManager activationManager = sessionContext.getSession().peekService(IActivationManager.class);\r
- if (activationManager != null) {\r
- activation = activationManager.activate(diagramResource);\r
- }\r
-\r
- }\r
-\r
- protected void scheduleZoomToFit() {\r
- if (sourceDiagram == null)\r
- throw new IllegalStateException("source diagram is null");\r
-\r
- sourceDiagram.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE);\r
- sourceDiagram.setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.TRUE);\r
- ThreadUtils.asyncExec(swt, new Runnable() {\r
- @Override\r
- public void run() {\r
- if (disposed)\r
- return;\r
-\r
- // System.out.println("size: " + c.getSize());\r
- ThreadUtils.asyncExec(canvasContext.getThreadAccess(), new Runnable() {\r
- @Override\r
- public void run() {\r
- if (disposed)\r
- return;\r
- // System.out.println("fit diagram to view");\r
- sourceDiagram.removeHint(Hints.KEY_DISABLE_PAINTING);\r
- /*Boolean zoomToFit =*/ sourceDiagram.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT);\r
- canvasContext.getDefaultHintContext().removeHint(Hints.KEY_DISABLE_PAINTING);\r
-\r
-// if (Boolean.TRUE.equals(zoomToFit))\r
-// CanvasUtils.sendCommand(canvasContext, Commands.ZOOM_TO_FIT);\r
-\r
- canvasContext.getContentContext().setDirty();\r
- }\r
- });\r
- }\r
- });\r
- }\r
-\r
-\r
-\r
- protected IDiagram loadDiagram(final Resource r) throws DatabaseException {\r
- final DataContainer<IDiagram> dc = new DataContainer<IDiagram>();\r
- //dc.set( loadDiagram(new NullProgressMonitor(), r) );\r
- try {\r
- PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {\r
- @Override\r
- public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {\r
- SubMonitor mon = SubMonitor.convert(monitor, "Loading Diagram", 100);\r
- try {\r
- dc.set( loadDiagram(mon.newChild(100), r) );\r
- } catch (DatabaseException e) {\r
- throw new InvocationTargetException(e);\r
- } finally {\r
- monitor.done();\r
- }\r
- }\r
- });\r
- } catch (InvocationTargetException e) {\r
- Throwable t = e.getTargetException();\r
- if (t instanceof DatabaseException)\r
- throw (DatabaseException) t;\r
- throw new DatabaseException(t);\r
- } catch (InterruptedException e) {\r
- throw new DatabaseException(e);\r
- }\r
- return dc.get();\r
- }\r
-\r
- protected IDiagram loadDiagram(IProgressMonitor monitor, Resource r) throws DatabaseException {\r
- SubMonitor mon = SubMonitor.convert(monitor, "Loading Diagram", 100);\r
-\r
- Object task = BEGIN("DV.DiagramLoadQuery");\r
- IDiagram d = sessionContext.getSession().syncRequest(DiagramRequests.loadDiagram(mon.newChild(100), getResourceInput2().getModel(null), r, null, structuralPath, synchronizer, null));\r
- END(task);\r
-\r
- task = BEGIN("DV.setDiagramHint");\r
- canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, d);\r
- END(task);\r
-\r
- task = BEGIN("DV.set other hints");\r
- // Setup a copy advisor for the synchronizer\r
- //d.setHint(SynchronizationHints.COPY_ADVISOR, new MappedElementCopyAdvisor(new ComponentCopyAdvisor()));\r
- d.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, Boolean.FALSE);\r
- d.setHint(DiagramHints.KEY_ALLOW_CONNECTION_BRANCHING, Boolean.FALSE);\r
- d.setHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS, Boolean.FALSE);\r
- END(task);\r
-\r
- return d;\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, DefaultConnectionClassFactory.CLASS.newClassWith(new StaticObjectAdapter(dr.Connection)),\r
- ElementClasses.FLAG, FlagClassFactory.createFlagClass(dr.Flag, dr.Flag_Terminal)\r
- );\r
- }\r
-\r
- public ICanvasContext createViewerCanvas() {\r
- IThreadWorkQueue thread = AWTThread.getThreadAccess();\r
- CanvasContext ctx = new CanvasContext(thread);\r
- IHintContext h = ctx.getDefaultHintContext();\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
- ctx.add(new PanZoomRotateHandler()); // Must be before TransformUtil\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 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, DiagramViewer.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
- ctx.add(new MultitouchPanZoomRotateInteractor());\r
- // ctx.add( new OrientationRestorer() );\r
- ctx.add(new ZoomToAreaHandler());\r
- ctx.add(new SimpleElementTransformHandler(true, true, true));\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
-\r
- h.setHint(PanZoomRotateHandler.KEY_ADAPT_VIEWPORT_TO_RESIZED_CONTROL, Boolean.FALSE);\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.95f, 0.95f, 0.95f));\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
- ctx.add(new ZOrderHandler());\r
- ctx.add(new PointerInteractor(true, true, true, false, true, false, synchronizer.getElementClassProvider(), null));\r
- ctx.add(new ElementInteractor());\r
- ctx.add(new Selection());\r
- ctx.add(new DiagramParticipant());\r
- ctx.add(new ElementPainter());\r
- ctx.add(new TerminalPainter(true, true, false, true));\r
- //ctx.add(new ElementHeartbeater());\r
-// ctx.add(new ZoomTransitionParticipant(TransitionFunction.SIGMOID));\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
-\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
- // 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
- ctx.assertParticipantDependencies();\r
-\r
- return ctx;\r
- }\r
-\r
- protected void loadPageSettings(ICanvasContext ctx) {\r
- PageDesc pageDesc = null;\r
-\r
- if (diagramResource != null) {\r
- try {\r
- pageDesc = sessionContext.getSession().syncRequest(new Read<PageDesc>() {\r
- @Override\r
- public PageDesc perform(ReadGraph graph) throws DatabaseException {\r
- return DiagramGraphUtil.getPageDesc(graph, diagramResource, null);\r
- }\r
- });\r
- } catch (DatabaseException e) {\r
- ErrorLogger.defaultLogError(e);\r
- }\r
- }\r
-\r
- if (pageDesc == null) {\r
- // Take page description from the preferences if nothing else is available.\r
- PageDesc pd = diagramPreferences.getCompletePageDesc();\r
- pageDesc = pd;\r
- }\r
- ctx.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc);\r
- }\r
-\r
- private boolean firstFocus = true;\r
-\r
- @Override\r
- public void setFocus() {\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
- protected void firstTimeSetFocus() {\r
- //scheduleZoomToFit();\r
- }\r
-\r
- @Override\r
- public void dispose() {\r
- // Remember to remove the added preference change listener\r
- diagramPreferences.preferences.removePreferenceChangeListener(preferenceListener);\r
-\r
- // Deactivate all contexts here because after this the context service\r
- // in question will not be available.\r
- contextUtil.deactivateAll();\r
-\r
- disposed = true;\r
- if (activation != null) {\r
- activation.deactivate();\r
- activation = null;\r
- }\r
- synchronizer.dispose();\r
- ThreadUtils.asyncExec(c.getCanvasContext().getThreadAccess(), new Runnable() {\r
- @Override\r
- public void run() {\r
- c.getCanvasContext().dispose();\r
- }\r
- });\r
- sourceDiagram.dispose();\r
- support.dispose();\r
- super.dispose();\r
- }\r
-\r
- protected Resource getInputResource() {\r
- return getResourceInput().getResource();\r
- }\r
-\r
- @Override\r
- public IResourceEditorInput2 getResourceInput2() {\r
- return (IResourceEditorInput2) getEditorInput();\r
- }\r
-\r
- @Override\r
- public IResourceEditorInput getResourceInput() {\r
- return (IResourceEditorInput) getEditorInput();\r
- }\r
-\r
- @Override\r
- public void doSave(IProgressMonitor monitor) {\r
- }\r
-\r
- @Override\r
- public void doSaveAs() {\r
- }\r
-\r
- @Override\r
- public void init(IEditorSite site, IEditorInput input) throws PartInitException {\r
- if (!(input instanceof IResourceEditorInput))\r
- throw new PartInitException("Invalid input: must be IResourceEditorInput");\r
- setSite(site);\r
- setInput(input);\r
- support = new ResourceEditorSupport(this);\r
-\r
- // Set initial part name according to the name given by IEditorInput\r
- setPartName(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(), getResourceInput2()),\r
- new TitleUpdater(site.getShell().getDisplay(), this::setPartName, disposedCallback));\r
- session.asyncRequest(\r
- new ToolTipRequest(site.getId(), getResourceInput2()),\r
- new TitleUpdater(site.getShell().getDisplay(), this::setTitleToolTip, disposedCallback));\r
- }\r
-\r
- }\r
-\r
- @Override\r
- public boolean isDirty() {\r
- return false;\r
- }\r
-\r
- @Override\r
- public boolean isSaveAsAllowed() {\r
- return false;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public <T> T getAdapter(Class<T> adapter) {\r
- if (adapter == IPropertyPage.class)\r
- return (T) new StandardPropertyPage(getSite());\r
- if (adapter == IContentOutlinePage.class)\r
- return (T) new DiagramOutlinePage(sessionContextProvider, getResourceInput2());\r
- if (adapter == ILayersViewPage.class)\r
- return (T) new DiagramLayersPage(sourceDiagram, canvasContext);\r
- if (adapter == ICanvasContext.class)\r
- return (T) canvasContext;\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
- if (adapter == IDiagram.class)\r
- return (T) sourceDiagram;\r
- if (adapter == Session.class)\r
- return (T) sessionContext.getSession();\r
- return super.getAdapter(adapter);\r
- }\r
-\r
- protected void onCreated() {\r
- }\r
-\r
-\r
- private static Object BEGIN(String name) {\r
- if (PROFILE) {\r
- //return ThreadLog.BEGIN(name);\r
- }\r
- return null;\r
- }\r
-\r
- private static void END(Object task) {\r
- if (PROFILE) {\r
- //((Task) task).end();\r
- }\r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - issue #4384
+ *******************************************************************************/
+package org.simantics.modeling.ui.diagramEditor;
+
+import java.awt.Color;
+import java.lang.reflect.InvocationTargetException;
+import java.util.function.Supplier;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.common.ResourceArray;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.management.ISessionContext;
+import org.simantics.db.management.ISessionContextProvider;
+import org.simantics.db.request.Read;
+import org.simantics.diagram.adapter.DefaultConnectionClassFactory;
+import org.simantics.diagram.adapter.FlagClassFactory;
+import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;
+import org.simantics.diagram.handler.ConnectionCommandHandler;
+import org.simantics.diagram.handler.CopyPasteHandler;
+import org.simantics.diagram.handler.DeleteHandler;
+import org.simantics.diagram.handler.ExpandSelectionHandler;
+import org.simantics.diagram.handler.SimpleElementTransformHandler;
+import org.simantics.diagram.layer.ILayersViewPage;
+import org.simantics.diagram.participant.ContextUtil;
+import org.simantics.diagram.participant.SGFocusParticipant;
+import org.simantics.diagram.query.DiagramRequests;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.synchronization.IModifiableSynchronizationContext;
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;
+import org.simantics.diagram.ui.SWTPopupMenuParticipant;
+import org.simantics.g2d.canvas.Hints;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.canvas.impl.CanvasContext;
+import org.simantics.g2d.chassis.SWTChassis;
+import org.simantics.g2d.diagram.DiagramClass;
+import org.simantics.g2d.diagram.DiagramHints;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.impl.Diagram;
+import org.simantics.g2d.diagram.participant.DiagramParticipant;
+import org.simantics.g2d.diagram.participant.ElementInteractor;
+import org.simantics.g2d.diagram.participant.ElementPainter;
+import org.simantics.g2d.diagram.participant.Selection;
+import org.simantics.g2d.diagram.participant.TerminalPainter;
+import org.simantics.g2d.diagram.participant.ZOrderHandler;
+import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;
+import org.simantics.g2d.element.ElementClassProviders;
+import org.simantics.g2d.element.ElementClasses;
+import org.simantics.g2d.element.IElementClassProvider;
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
+import org.simantics.g2d.participant.CanvasBoundsParticipant;
+import org.simantics.g2d.participant.CanvasGrab;
+import org.simantics.g2d.participant.KeyUtil;
+import org.simantics.g2d.participant.MouseUtil;
+import org.simantics.g2d.participant.MultitouchPanZoomRotateInteractor;
+import org.simantics.g2d.participant.Notifications;
+import org.simantics.g2d.participant.PageBorderParticipant;
+import org.simantics.g2d.participant.PanZoomRotateHandler;
+import org.simantics.g2d.participant.PointerPainter;
+import org.simantics.g2d.participant.RulerPainter;
+import org.simantics.g2d.participant.SymbolUtil;
+import org.simantics.g2d.participant.TimeParticipant;
+import org.simantics.g2d.participant.TransformUtil;
+import org.simantics.g2d.participant.ZoomToAreaHandler;
+import org.simantics.layer0.utils.triggers.IActivation;
+import org.simantics.layer0.utils.triggers.IActivationManager;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.modeling.mapping.ModelingSynchronizationHints;
+import org.simantics.modeling.ui.diagramEditor.handlers.WorkbenchStructuralSelectionProvider;
+import org.simantics.modeling.ui.preferences.DiagramPreferenceUtil;
+import org.simantics.modeling.ui.preferences.DiagramPreferences;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.g2d.snap.GridSnapAdvisor;
+import org.simantics.scenegraph.utils.NodeUtil;
+import org.simantics.selectionview.StandardPropertyPage;
+import org.simantics.ui.SimanticsUI;
+import org.simantics.ui.workbench.IPropertyPage;
+import org.simantics.ui.workbench.IResourceEditorInput;
+import org.simantics.ui.workbench.IResourceEditorInput2;
+import org.simantics.ui.workbench.IResourceEditorPart2;
+import org.simantics.ui.workbench.ResourceEditorSupport;
+import org.simantics.ui.workbench.TitleRequest;
+import org.simantics.ui.workbench.TitleUpdater;
+import org.simantics.ui.workbench.ToolTipRequest;
+import org.simantics.utils.DataContainer;
+import org.simantics.utils.datastructures.hints.IHintContext;
+import org.simantics.utils.page.PageDesc;
+import org.simantics.utils.threads.AWTThread;
+import org.simantics.utils.threads.IThreadWorkQueue;
+import org.simantics.utils.threads.SWTThread;
+import org.simantics.utils.threads.ThreadUtils;
+import org.simantics.utils.ui.ErrorLogger;
+
+/**
+ * @author Toni Kalajainen
+ * @author Tuukka Lehtonen
+ */
+public class SheetViewer extends EditorPart implements IResourceEditorPart2 {
+
+ private static final boolean PROFILE = false;
+
+ protected boolean disposed = false;
+ protected IThreadWorkQueue swt;
+ protected IStatusLineManager statusLineManager;
+ protected SWTChassis c;
+ protected IDiagram sourceDiagram;
+ protected ICanvasContext canvasContext;
+ protected ResourceEditorSupport support;
+ protected ISessionContextProvider sessionContextProvider;
+ protected ISessionContext sessionContext;
+ protected Resource diagramResource;
+ protected GraphToDiagramSynchronizer synchronizer;
+ protected IActivation activation;
+ protected ContextUtil contextUtil;
+
+ protected DiagramPreferences diagramPreferences;
+ protected GridSnapAdvisor snapAdvisor;
+
+ public ResourceArray structuralPath;
+
+ IPreferenceChangeListener preferenceListener = new IPreferenceChangeListener() {
+ @Override
+ public void preferenceChange(PreferenceChangeEvent event) {
+ String value = (String) event.getNewValue();
+ if (DiagramPreferences.P_SNAP_GRID_SIZE.equals(event.getKey())) {
+ double grid = DiagramPreferences.DEFAULT_SNAP_GRID_SIZE;
+ if (value != null)
+ grid = Double.parseDouble(value);
+ snapAdvisor.setResolution(grid);
+ } else if (DiagramPreferences.P_DEFAULT_PAGE_SIZE.equals(event.getKey())) {
+ PageDesc pageDesc = PageDesc.deserialize(value, DiagramPreferences.DEFAULT_PAGE_SIZE);
+ //System.out.println("new page desc: " + pageDesc);
+ canvasContext.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc);
+ } else if (DiagramPreferences.P_DISPLAY_PAGE_SIZE.equals(event.getKey())) {
+ Boolean display = value != null ? Boolean.parseBoolean(value) : DiagramPreferences.DEFAULT_DISPLAY_PAGE_SIZE;
+ canvasContext.getDefaultHintContext().setHint(Hints.KEY_DISPLAY_PAGE, display);
+ } else if (DiagramPreferences.P_DISPLAY_MARGINS.equals(event.getKey())) {
+ Boolean display = value != null ? Boolean.parseBoolean(value) : DiagramPreferences.DEFAULT_DISPLAY_MARGINS;
+ canvasContext.getDefaultHintContext().setHint(Hints.KEY_DISPLAY_MARGINS, display);
+ }
+ }
+ };
+
+ protected void addDropParticipants(ICanvasContext ctx) {
+ // FIXME This is a workaround so that this participant can be disabled
+ // for SymbolViewer
+ ctx.add(new PopulateElementDropParticipant(synchronizer));
+ ctx.add(new PopulateElementMonitorDropParticipant(synchronizer, 0.5, 0.5));
+ }
+
+ protected void addKeyBindingParticipants(CanvasContext ctx) {
+ //ctx.add( new KeyToCommand( CommandKeyBinding.DEFAULT_BINDINGS ) );
+ ctx.add(new DeleteHandler(statusLineManager));
+ ctx.add(new CopyPasteHandler(statusLineManager));
+ ctx.add(new ConnectionCommandHandler());
+ }
+
+ protected void addPopupmenu(ICanvasContext ctx) {
+ ctx.add(new SWTPopupMenuParticipant(getSite(), c, getPopupId()));
+ }
+
+ protected void addStructureParticipants(ICanvasContext ctx) {
+ structuralPath = getResourceInput().getResourceArray().removeFromBeginning(1);
+
+ ctx.add(new WorkbenchStructuralSelectionProvider(swt, getSite(), structuralPath));
+ // Add visual browsing capabilities for structural models
+// ctx.add(new StructuralBrowsingHandler(getSite(), sessionContext, structuralPath));
+// ctx.add(new LinkBrowsingHandler(getSite(), this, sessionContext));
+ }
+
+ protected String getPopupId() {
+ return "#ModelingDiagramPopup";
+ }
+
+ protected void getPreferences() {
+ this.diagramPreferences = DiagramPreferenceUtil.getPreferences();
+ }
+
+ protected void initSession() {
+ sessionContextProvider = SimanticsUI.getSessionContextProvider();
+ sessionContext = sessionContextProvider.getSessionContext();
+ }
+
+ protected void readNames() {
+ String name = getEditorInput().getName();
+ setPartName(name);
+ setTitleToolTip(name);
+ }
+
+ protected void createChassis(Composite parent) {
+ c = new SWTChassis(parent, 0);
+ c.syncPopulate();
+ }
+
+ protected void setCanvasContext(ICanvasContext context) {
+ c.setCanvasContext(canvasContext);
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ swt = SWTThread.getThreadAccess(parent.getDisplay());
+ statusLineManager = getEditorSite().getActionBars().getStatusLineManager();
+
+ Object task = BEGIN("DV.initSession");
+ initSession();
+ END(task);
+
+ diagramResource = getInputResource();
+ readNames();
+ getPreferences();
+
+ task = BEGIN("DV.createChassis");
+ createChassis(parent);
+ END(task);
+
+ initializeCanvas();
+
+ // Start tracking changes in diagram preferences.
+ diagramPreferences.preferences.addPreferenceChangeListener(preferenceListener);
+ }
+
+ protected void initializeCanvas() {
+ Object canvasInit = BEGIN("DV.canvasInitialization");
+
+ Object task = BEGIN("DV.createViewerCanvas");
+// ThreadUtils.syncExec(AWTThread.getThreadAccess(), new Runnable() {
+// @Override
+// public void run() {
+ canvasContext = createViewerCanvas();
+// }
+// });
+ END(task);
+
+ //FullscreenUtils.addFullScreenHandler(canvasContext, s, canvasProvider);
+
+ task = BEGIN("DV.setCanvasContext");
+ setCanvasContext(canvasContext);
+ END(task);
+
+ try {
+ task = BEGIN("DV.loadDiagram");
+ sourceDiagram = loadDiagram(diagramResource);
+ END(task);
+
+ // Zoom to fit
+ task = BEGIN("DV.scheduleZoomToFit");
+
+// canvasContext.getDefaultHintContext().setHint(Hints.KEY_CANVAS_TRANSFORM, new AffineTransform());
+// canvasContext.getContentContext().setDirty();
+ scheduleZoomToFit();
+
+ END(task);
+
+ // Start an activation for the input resource.
+ // This will activate mapping if necessary.
+ task = BEGIN("DV.performActivation");
+ performActivation();
+ END(task);
+
+ task = BEGIN("DV.activate context");
+ contextUtil.activate(DiagramViewer.DIAGRAMMING_CONTEXT);
+ END(task);
+
+ task = BEGIN("DV.onCreated");
+ onCreated();
+ END(task);
+
+ } catch (DatabaseException e) {
+ ErrorLogger.defaultLogError(e);
+
+ // Without this all diagram participants will crash like there's no tomorrow.
+ // Just trying to keep the behavior a bit more sane in case of
+ // errors instead of flooding the console with exceptions.
+ canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, Diagram.spawnNew(DiagramClass.DEFAULT));
+ }
+ END(canvasInit);
+ }
+
+ protected void performActivation() {
+
+ IActivationManager activationManager = sessionContext.getSession().peekService(IActivationManager.class);
+ if (activationManager != null) {
+ activation = activationManager.activate(diagramResource);
+ }
+
+ }
+
+ protected void scheduleZoomToFit() {
+ if (sourceDiagram == null)
+ throw new IllegalStateException("source diagram is null");
+
+ sourceDiagram.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE);
+ sourceDiagram.setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.TRUE);
+ ThreadUtils.asyncExec(swt, new Runnable() {
+ @Override
+ public void run() {
+ if (disposed)
+ return;
+
+ // System.out.println("size: " + c.getSize());
+ ThreadUtils.asyncExec(canvasContext.getThreadAccess(), new Runnable() {
+ @Override
+ public void run() {
+ if (disposed)
+ return;
+ // System.out.println("fit diagram to view");
+ sourceDiagram.removeHint(Hints.KEY_DISABLE_PAINTING);
+ /*Boolean zoomToFit =*/ sourceDiagram.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT);
+ canvasContext.getDefaultHintContext().removeHint(Hints.KEY_DISABLE_PAINTING);
+
+// if (Boolean.TRUE.equals(zoomToFit))
+// CanvasUtils.sendCommand(canvasContext, Commands.ZOOM_TO_FIT);
+
+ canvasContext.getContentContext().setDirty();
+ }
+ });
+ }
+ });
+ }
+
+
+
+ protected IDiagram loadDiagram(final Resource r) throws DatabaseException {
+ final DataContainer<IDiagram> dc = new DataContainer<IDiagram>();
+ //dc.set( loadDiagram(new NullProgressMonitor(), r) );
+ try {
+ PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ SubMonitor mon = SubMonitor.convert(monitor, "Loading Diagram", 100);
+ try {
+ dc.set( loadDiagram(mon.newChild(100), r) );
+ } catch (DatabaseException e) {
+ throw new InvocationTargetException(e);
+ } finally {
+ monitor.done();
+ }
+ }
+ });
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getTargetException();
+ if (t instanceof DatabaseException)
+ throw (DatabaseException) t;
+ throw new DatabaseException(t);
+ } catch (InterruptedException e) {
+ throw new DatabaseException(e);
+ }
+ return dc.get();
+ }
+
+ protected IDiagram loadDiagram(IProgressMonitor monitor, Resource r) throws DatabaseException {
+ SubMonitor mon = SubMonitor.convert(monitor, "Loading Diagram", 100);
+
+ Object task = BEGIN("DV.DiagramLoadQuery");
+ IDiagram d = sessionContext.getSession().syncRequest(DiagramRequests.loadDiagram(mon.newChild(100), getResourceInput2().getModel(null), r, null, structuralPath, synchronizer, null));
+ END(task);
+
+ task = BEGIN("DV.setDiagramHint");
+ canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, d);
+ END(task);
+
+ task = BEGIN("DV.set other hints");
+ // Setup a copy advisor for the synchronizer
+ //d.setHint(SynchronizationHints.COPY_ADVISOR, new MappedElementCopyAdvisor(new ComponentCopyAdvisor()));
+ d.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, Boolean.FALSE);
+ d.setHint(DiagramHints.KEY_ALLOW_CONNECTION_BRANCHING, Boolean.FALSE);
+ d.setHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS, Boolean.FALSE);
+ END(task);
+
+ return d;
+ }
+
+ protected GraphToDiagramSynchronizer createSynchronizer(final ICanvasContext ctx, final ISessionContext sessionContext) {
+ try {
+ return sessionContext.getSession().syncRequest(new Read<GraphToDiagramSynchronizer>() {
+ @Override
+ public GraphToDiagramSynchronizer perform(ReadGraph graph) throws DatabaseException {
+ GraphToDiagramSynchronizer sync = new GraphToDiagramSynchronizer(graph, ctx, createElementClassProvider(graph));
+ initializeSynchronizationContext(graph, sync);
+ return sync;
+ }
+ });
+ } catch (DatabaseException e) {
+ throw new UnsupportedOperationException("Failed to initialize data model synchronizer", e);
+ }
+ }
+
+ protected void initializeSynchronizationContext(ReadGraph graph, IModifiableSynchronizationContext context) {
+ context.set(ModelingSynchronizationHints.MODELING_RESOURCE, ModelingResources.getInstance(graph));
+ }
+
+ protected IElementClassProvider createElementClassProvider(ReadGraph graph) {
+ DiagramResource dr = DiagramResource.getInstance(graph);
+ return ElementClassProviders.mappedProvider(
+ ElementClasses.CONNECTION, DefaultConnectionClassFactory.CLASS.newClassWith(new StaticObjectAdapter(dr.Connection)),
+ ElementClasses.FLAG, FlagClassFactory.createFlagClass(dr.Flag, dr.Flag_Terminal)
+ );
+ }
+
+ public ICanvasContext createViewerCanvas() {
+ IThreadWorkQueue thread = AWTThread.getThreadAccess();
+ CanvasContext ctx = new CanvasContext(thread);
+ IHintContext h = ctx.getDefaultHintContext();
+
+ Object task = BEGIN("createSynchronizer");
+ this.synchronizer = createSynchronizer(ctx, sessionContext);
+ END(task);
+
+ IContextService contextService = (IContextService) getSite().getService(IContextService.class);
+ contextUtil = new ContextUtil(contextService, swt);
+
+ ctx.add(new PanZoomRotateHandler()); // Must be before TransformUtil
+
+ // Support & Util Participants
+ ctx.add(new TransformUtil());
+ ctx.add(new MouseUtil());
+ ctx.add(new KeyUtil());
+ ctx.add(contextUtil);
+ ctx.add(new CanvasGrab());
+ ctx.add(new SymbolUtil());
+ ctx.add(new TimeParticipant());
+ ctx.add(new CanvasBoundsParticipant());
+ ctx.add(new Notifications());
+
+ ctx.add( new SGFocusParticipant(c, DiagramViewer.DIAGRAMMING_CONTEXT) );
+
+ // Debug participant(s)
+ // ctx.add( new PointerPainter() );
+ // ctx.add( new HandPainter() );
+ h.setHint(PointerPainter.KEY_PAINT_POINTER, true);
+
+ // Pan & Zoom & Rotate
+ ctx.add(new MultitouchPanZoomRotateInteractor());
+ // ctx.add( new OrientationRestorer() );
+ ctx.add(new ZoomToAreaHandler());
+ ctx.add(new SimpleElementTransformHandler(true, true, true));
+ ctx.add(new ExpandSelectionHandler(getEditorSite().getActionBars().getStatusLineManager()));
+
+ // Key bindings
+ addKeyBindingParticipants(ctx);
+
+ // Grid & Ruler & Background
+// ctx.add(new GridPainter());
+// ctx.add(new RulerPainter());
+// ctx.add(new BackgroundPainter());
+
+
+ h.setHint(PanZoomRotateHandler.KEY_ADAPT_VIEWPORT_TO_RESIZED_CONTROL, Boolean.FALSE);
+ h.setHint(Hints.KEY_DISPLAY_PAGE, diagramPreferences.get(DiagramPreferences.P_DISPLAY_PAGE_SIZE));
+ h.setHint(Hints.KEY_DISPLAY_MARGINS, diagramPreferences.get(DiagramPreferences.P_DISPLAY_MARGINS));
+ ctx.add(new PageBorderParticipant());
+
+ // h.setHint(Hints.KEY_GRID_COLOR, new Color(0.9f, 0.9f, 0.9f));
+ // h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.LIGHT_GRAY);
+ h.setHint(Hints.KEY_GRID_COLOR, new Color(0.95f, 0.95f, 0.95f));
+ h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.WHITE);
+ h.setHint(RulerPainter.KEY_RULER_BACKGROUND_COLOR, new Color(0.9f, 0.9f, 0.9f, 0.75f));
+ h.setHint(RulerPainter.KEY_RULER_TEXT_COLOR, Color.BLACK);
+
+ ////// Diagram Participants //////
+ ctx.add(new ZOrderHandler());
+ ctx.add(new PointerInteractor(true, true, true, false, true, false, synchronizer.getElementClassProvider(), null));
+ ctx.add(new ElementInteractor());
+ ctx.add(new Selection());
+ ctx.add(new DiagramParticipant());
+ ctx.add(new ElementPainter());
+ ctx.add(new TerminalPainter(true, true, false, true));
+ //ctx.add(new ElementHeartbeater());
+// ctx.add(new ZoomTransitionParticipant(TransitionFunction.SIGMOID));
+
+ /////// D'n'D ///////
+ addDropParticipants(ctx);
+
+ h.setHint(ElementPainter.KEY_SELECTION_FRAME_COLOR, Color.MAGENTA);
+ h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);
+
+ h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 100000.0);
+ h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 10.0);
+
+ Double snapResolution = diagramPreferences.get(DiagramPreferences.P_SNAP_GRID_SIZE);
+ this.snapAdvisor = new GridSnapAdvisor(snapResolution);
+ h.setHint(DiagramHints.SNAP_ADVISOR, this.snapAdvisor);
+
+ // Workbench selection provider
+ addStructureParticipants(ctx);
+
+ // Pop-up menu
+ addPopupmenu(ctx);
+
+ // Load page frame description settings
+ loadPageSettings(ctx);
+
+ // The canvas context should not be painted until it is ready to avoid
+ // unnecessary visual glitches.
+ h.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE);
+
+ ctx.assertParticipantDependencies();
+
+ return ctx;
+ }
+
+ protected void loadPageSettings(ICanvasContext ctx) {
+ PageDesc pageDesc = null;
+
+ if (diagramResource != null) {
+ try {
+ pageDesc = sessionContext.getSession().syncRequest(new Read<PageDesc>() {
+ @Override
+ public PageDesc perform(ReadGraph graph) throws DatabaseException {
+ return DiagramGraphUtil.getPageDesc(graph, diagramResource, null);
+ }
+ });
+ } catch (DatabaseException e) {
+ ErrorLogger.defaultLogError(e);
+ }
+ }
+
+ if (pageDesc == null) {
+ // Take page description from the preferences if nothing else is available.
+ PageDesc pd = diagramPreferences.getCompletePageDesc();
+ pageDesc = pd;
+ }
+ ctx.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc);
+ }
+
+ private boolean firstFocus = true;
+
+ @Override
+ public void setFocus() {
+ c.setFocus();
+
+ if (firstFocus) {
+ // This is a workaround for using the symbol viewer in multi-page
+ // editors which causes the first zoom-to-fit scheduling to happen
+ // already before the controls have been laid out properly.
+ firstFocus = false;
+ firstTimeSetFocus();
+ }
+ }
+
+ protected void firstTimeSetFocus() {
+ //scheduleZoomToFit();
+ }
+
+ @Override
+ public void dispose() {
+ // Remember to remove the added preference change listener
+ diagramPreferences.preferences.removePreferenceChangeListener(preferenceListener);
+
+ // Deactivate all contexts here because after this the context service
+ // in question will not be available.
+ contextUtil.deactivateAll();
+
+ disposed = true;
+ if (activation != null) {
+ activation.deactivate();
+ activation = null;
+ }
+ synchronizer.dispose();
+ ThreadUtils.asyncExec(c.getCanvasContext().getThreadAccess(), new Runnable() {
+ @Override
+ public void run() {
+ c.getCanvasContext().dispose();
+ }
+ });
+ sourceDiagram.dispose();
+ support.dispose();
+ super.dispose();
+ }
+
+ protected Resource getInputResource() {
+ return getResourceInput().getResource();
+ }
+
+ @Override
+ public IResourceEditorInput2 getResourceInput2() {
+ return (IResourceEditorInput2) getEditorInput();
+ }
+
+ @Override
+ public IResourceEditorInput getResourceInput() {
+ return (IResourceEditorInput) getEditorInput();
+ }
+
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ }
+
+ @Override
+ public void doSaveAs() {
+ }
+
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+ if (!(input instanceof IResourceEditorInput))
+ throw new PartInitException("Invalid input: must be IResourceEditorInput");
+ setSite(site);
+ setInput(input);
+ support = new ResourceEditorSupport(this);
+
+ // Set initial part name according to the name given by IEditorInput
+ setPartName(getEditorInput().getName());
+
+ Session session = SimanticsUI.peekSession();
+ if (session != null) {
+ Supplier<Boolean> disposedCallback = () -> disposed;
+ session.asyncRequest(
+ new TitleRequest(site.getId(), getResourceInput2()),
+ new TitleUpdater(site.getShell().getDisplay(), this::setPartName, disposedCallback));
+ session.asyncRequest(
+ new ToolTipRequest(site.getId(), getResourceInput2()),
+ new TitleUpdater(site.getShell().getDisplay(), this::setTitleToolTip, disposedCallback));
+ }
+
+ }
+
+ @Override
+ public boolean isDirty() {
+ return false;
+ }
+
+ @Override
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T getAdapter(Class<T> adapter) {
+ if (adapter == IPropertyPage.class)
+ return (T) new StandardPropertyPage(getSite());
+ if (adapter == IContentOutlinePage.class)
+ return (T) new DiagramOutlinePage(sessionContextProvider, getResourceInput2());
+ if (adapter == ILayersViewPage.class)
+ return (T) new DiagramLayersPage(sourceDiagram, canvasContext);
+ if (adapter == ICanvasContext.class)
+ return (T) canvasContext;
+ if (adapter == INode.class) {
+ if (canvasContext != null) {
+ INode node = canvasContext.getCanvasNode();
+ if (node != null)
+ return (T) NodeUtil.getRootNode(node);
+ }
+ return null;
+ }
+ if (adapter == IDiagram.class)
+ return (T) sourceDiagram;
+ if (adapter == Session.class)
+ return (T) sessionContext.getSession();
+ return super.getAdapter(adapter);
+ }
+
+ protected void onCreated() {
+ }
+
+
+ private static Object BEGIN(String name) {
+ if (PROFILE) {
+ //return ThreadLog.BEGIN(name);
+ }
+ return null;
+ }
+
+ private static void END(Object task) {
+ if (PROFILE) {
+ //((Task) task).end();
+ }
+ }
+
+}