]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/WikiDiagramViewer.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagramEditor / WikiDiagramViewer.java
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/WikiDiagramViewer.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/WikiDiagramViewer.java
new file mode 100644 (file)
index 0000000..8848eb2
--- /dev/null
@@ -0,0 +1,434 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 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
+ *******************************************************************************/\r
+package org.simantics.modeling.ui.diagramEditor;\r
+\r
+import java.awt.Color;\r
+import java.awt.datatransfer.Transferable;\r
+import java.awt.datatransfer.UnsupportedFlavorException;\r
+import java.io.IOException;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.NullProgressMonitor;\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.contexts.IContextActivation;\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.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.db.service.SerialisationSupport;\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.SimpleElementTransformHandler;\r
+import org.simantics.diagram.layer.ILayersViewPage;\r
+import org.simantics.diagram.query.DiagramRequests;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.ui.DiagramModelHints;\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.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.IDiagram;\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.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.multileveldiagram.TransitionFunction;\r
+import org.simantics.g2d.multileveldiagram.ZoomTransitionParticipant;\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.KeyToCommand;\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.g2d.utils.CanvasUtils;\r
+import org.simantics.layer0.utils.triggers.IActivation;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.mapping.ModelingSynchronizationHints;\r
+import org.simantics.scenegraph.g2d.events.command.CommandKeyBinding;\r
+import org.simantics.scenegraph.g2d.events.command.Commands;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.dnd.ResourceTransferData;\r
+import org.simantics.ui.dnd.ResourceTransferUtils;\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.utils.datastructures.hints.HintContext;\r
+import org.simantics.utils.datastructures.hints.IHintContext;\r
+import org.simantics.utils.page.PageDesc;\r
+import org.simantics.utils.page.PageOrientation;\r
+import org.simantics.utils.threads.AWTThread;\r
+import org.simantics.utils.threads.IThreadWorkQueue;\r
+\r
+/**\r
+ * @author J-P Laine\r
+ */\r
+public class WikiDiagramViewer extends EditorPart implements IResourceEditorPart2 {\r
+\r
+    protected boolean                  disposed = false;\r
+    protected IDiagram                 sourceDiagram;\r
+    protected ICanvasContext           canvasContext;\r
+    protected ResourceEditorSupport    support;\r
+    protected ISessionContextProvider  sessionContextProvider;\r
+    protected ISessionContext          sessionContext;\r
+    protected GraphToDiagramSynchronizer synchronizer;\r
+    protected IActivation              activation;\r
+    protected ResourceArray            structuralPath = new ResourceArray();\r
+    protected IContextActivation       contextActivation;\r
+    protected IExperiment              experiment;\r
+    protected String                              layer = null;\r
+\r
+    public WikiDiagramViewer() {\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
+    }\r
+\r
+    public void setExperiment(IExperiment experiment) {\r
+        sourceDiagram.setHint(DiagramModelHints.KEY_ACTIVE_EXPERIMENT, experiment);\r
+    }\r
+\r
+    public void init(ResourceArray structuralPath, String layer, IExperiment experiment) {\r
+        this.experiment = experiment;\r
+        this.layer = layer;\r
+        this.structuralPath = structuralPath;\r
+\r
+        sessionContextProvider = SimanticsUI.getSessionContextProvider();\r
+        sessionContext = sessionContextProvider.getSessionContext();\r
+\r
+        canvasContext = createViewerCanvas();\r
+\r
+        try {\r
+            sourceDiagram = loadDiagram(structuralPath, experiment);\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        onCreated();\r
+    }\r
+\r
+    public void updateDiagram(ResourceArray structuralPath) {\r
+        canvasContext = createViewerCanvas();\r
+        try {\r
+            IHintContext hints = new HintContext();\r
+            hints.setHint(DiagramModelHints.KEY_ACTIVE_EXPERIMENT, experiment);\r
+            if(layer != null) {\r
+                System.out.println("using layer '"+layer+"'");\r
+                hints.setHint(DiagramHints.KEY_FIXED_LAYERS, new String[] { layer });\r
+            }\r
+\r
+            sourceDiagram = sessionContext.getSession().syncRequest(DiagramRequests.loadDiagram(new NullProgressMonitor(), getResourceInput2().getModel(null), structuralPath.resources[0], null, structuralPath.removeFromBeginning(0), synchronizer, hints));\r
+            canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, sourceDiagram);\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    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
+\r
+        // zoom-to-fit\r
+        sourceDiagram.removeHint(Hints.KEY_DISABLE_PAINTING);\r
+        Boolean zoomToFit = sourceDiagram.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT);\r
+        if (zoomToFit != null && zoomToFit)\r
+            CanvasUtils.sendCommand(canvasContext, Commands.ZOOM_TO_FIT);\r
+        canvasContext.getContentContext().setDirty();\r
+    }\r
+\r
+    protected IDiagram loadDiagram(ResourceArray structuralPath, IExperiment experiment) throws DatabaseException {\r
+        IHintContext hints = new HintContext();\r
+        if(experiment != null)\r
+            hints.setHint(DiagramModelHints.KEY_ACTIVE_EXPERIMENT, experiment);\r
+        if(layer != null) {\r
+            System.out.println("using layer '"+layer+"'");\r
+            hints.setHint(DiagramHints.KEY_FIXED_LAYERS, new String[] { layer });\r
+        }\r
+        IDiagram d = sessionContext.getSession().syncRequest(DiagramRequests.loadDiagram(new NullProgressMonitor(), getResourceInput2().getModel(null), structuralPath.resources[0], null, structuralPath.removeFromBeginning(0), synchronizer, hints));\r
+        canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, d);\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
+                    DiagramResource dr = DiagramResource.getInstance(graph);\r
+                    GraphToDiagramSynchronizer sync = new GraphToDiagramSynchronizer(graph, ctx,\r
+                            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
+                    sync.set(ModelingSynchronizationHints.MODELING_RESOURCE, ModelingResources.getInstance(graph));\r
+                    return sync;\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            throw new UnsupportedOperationException("Failed to initialize data model synchronizer", e);\r
+        }\r
+    }\r
+\r
+    public ICanvasContext createViewerCanvas()\r
+    {\r
+        IThreadWorkQueue thread = AWTThread.getThreadAccess();\r
+        CanvasContext ctx = new CanvasContext(thread);\r
+        IHintContext h = ctx.getDefaultHintContext();\r
+\r
+        this.synchronizer = createSynchronizer(ctx, sessionContext);\r
+\r
+        canvasContext.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( 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) ); // FIXME: Get chassis from somewhere\r
+\r
+        h.setHint(PointerPainter.KEY_PAINT_POINTER, true);\r
+\r
+        ctx.add( new MultitouchPanZoomRotateInteractor() );\r
+        ctx.add( new ZoomToAreaHandler() );\r
+        ctx.add( new SimpleElementTransformHandler() );\r
+\r
+        // Key bindings\r
+        addKeyBindingParticipants(ctx);\r
+\r
+        // Grid & Ruler & Background\r
+\r
+        ctx.add( new GridPainter() );\r
+        ctx.add( new RulerPainter() );\r
+        ctx.add( new BackgroundPainter() );\r
+        ctx.add( new PageBorderParticipant() );\r
+\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 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 ZOrderHandler());\r
+        ctx.add(new ZoomTransitionParticipant(TransitionFunction.SIGMOID));\r
+\r
+        /////// D'n'D ///////\r
+        addDropParticipants(ctx);\r
+\r
+        h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);\r
+\r
+        h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 1000.0);\r
+        h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 10.0);\r
+\r
+        // Add visual browsing capabilities for structural models\r
+//        ctx.add(new HeadlessStructuralBrowsingHandler(this, sessionContext, structuralPath));\r
+\r
+        // Page settings\r
+        PageDesc pageDesc = PageDesc.DEFAULT.withOrientation(PageOrientation.Landscape);\r
+        // TODO: load page desc from graph\r
+        h.setHint(Hints.KEY_PAGE_DESC, pageDesc);\r
+\r
+        ctx.assertParticipantDependencies();\r
+\r
+        return ctx;\r
+    }\r
+\r
+    private boolean firstFocus = true;\r
+\r
+    @Override\r
+    public void setFocus() {\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
+        System.out.println("RemoteDiagramViewer.dispose()");\r
+        if(getSite() != null) {\r
+            IContextService contextService = (IContextService) getSite().getService(IContextService.class);\r
+            contextService.deactivateContext(contextActivation);\r
+        }\r
+\r
+        disposed = true;\r
+        if (activation != null) {\r
+            activation.deactivate();\r
+            activation = null;\r
+        }\r
+\r
+        if(synchronizer != null) {\r
+            synchronizer.dispose();\r
+            synchronizer = null;\r
+        }\r
+\r
+        if(sourceDiagram != null) {\r
+            sourceDiagram.dispose();\r
+            sourceDiagram = null;\r
+        }\r
+\r
+        if(support != null) {\r
+            support.dispose();\r
+            support = null;\r
+        }\r
+        super.dispose();\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)\r
+    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
+\r
+    @Override\r
+    public boolean isDirty() {\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public boolean isSaveAsAllowed() {\r
+        return false;\r
+    }\r
+\r
+    public static ResourceArray[] decodeToResources(Session session, Transferable tr)\r
+    {\r
+        try {\r
+            SerialisationSupport support = session.getService(SerialisationSupport.class);\r
+            ResourceTransferData data = ResourceTransferUtils.readAwtTransferable(support, tr);\r
+            if ("property".equals(data.getPurpose()))\r
+                return data.toResourceArrayArray();\r
+        } catch (UnsupportedFlavorException e) {\r
+            throw new RuntimeException(e);\r
+        } catch (IOException e) {\r
+            throw new RuntimeException(e);\r
+        } catch (IllegalArgumentException e) {\r
+            throw new RuntimeException(e);\r
+        } catch (DatabaseException e) {\r
+            throw new RuntimeException(e);\r
+        }\r
+        return null;\r
+    }\r
+\r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if (adapter == IContentOutlinePage.class)\r
+            return new DiagramOutlinePage(sessionContextProvider, getResourceInput2());\r
+        if (adapter == ILayersViewPage.class)\r
+            return new DiagramLayersPage(sourceDiagram, canvasContext);\r
+        if (adapter == ICanvasContext.class)\r
+            return canvasContext;\r
+        if (adapter == IDiagram.class)\r
+            return sourceDiagram;\r
+        if (adapter == Session.class)\r
+            return sessionContext.getSession();\r
+        return super.getAdapter(adapter);\r
+    }\r
+\r
+    public ICanvasContext getCanvasContext() {\r
+        return canvasContext;\r
+    }\r
+\r
+    protected void onCreated() {\r
+    }\r
+\r
+    @Override\r
+    public void createPartControl(Composite parent) {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+    @Override\r
+    public IResourceEditorInput2 getResourceInput2() {\r
+        // TODO Auto-generated method stub\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public IResourceEditorInput getResourceInput() {\r
+        // TODO Auto-generated method stub\r
+        return null;\r
+    }\r
+\r
+}\r