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