]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewer.java
Option to copy diagram selection to clipboard as SVG graphics
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagramEditor / DiagramViewer.java
index 92d46e160e8f91347dee82da58c2698e5a7ba198..88d85cfbf6581dc996205ffdf0204d4e8e444e51 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2013 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 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
@@ -8,7 +8,7 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
- *     Semantum Oy - issue #4384
+ *     Semantum Oy - issue #4384, gitlab #399
  *******************************************************************************/
 package org.simantics.modeling.ui.diagramEditor;
 
@@ -41,9 +41,11 @@ import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.primitiverequest.PossibleAdapter;
+import org.simantics.db.common.primitiverequest.PossibleObject;
 import org.simantics.db.common.procedure.adapter.ListenerDelegate;
 import org.simantics.db.common.procedure.adapter.ListenerSupport;
 import org.simantics.db.common.request.ParametrizedRead;
+import org.simantics.db.common.request.TypeURIs;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.common.utils.CommonDBUtils;
 import org.simantics.db.common.utils.TagUtil;
@@ -65,7 +67,9 @@ 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.ConnectionCrossingsParticipant;
 import org.simantics.diagram.participant.ContextUtil;
+import org.simantics.diagram.participant.CopyAsSVGParticipant;
 import org.simantics.diagram.participant.PointerInteractor2;
 import org.simantics.diagram.participant.SGFocusParticipant;
 import org.simantics.diagram.query.DiagramRequests;
@@ -104,6 +108,7 @@ 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.ElementUtils;
 import org.simantics.g2d.element.IElement;
 import org.simantics.g2d.element.IElementClassProvider;
 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
@@ -184,8 +189,8 @@ public class DiagramViewer
         void doSetTitleToolTip(String name);
     }
 
-    public static final String                     DIAGRAMMING_CONTEXT      = "org.simantics.modeling.ui.diagramming";
-    private static final String                     PREFERENCE_VIRTUAL_GRAPH = "preferences";
+    public static final String                      DIAGRAMMING_CONTEXT      = "org.simantics.modeling.ui.diagramming"; //$NON-NLS-1$
+    private static final String                     PREFERENCE_VIRTUAL_GRAPH = "preferences"; //$NON-NLS-1$
 
     private static final boolean                    PROFILE                  = false;
 
@@ -233,6 +238,8 @@ public class DiagramViewer
     protected GridSnapAdvisor            snapAdvisor;
 
     private RuntimeDiagramManager        runtimeDiagramManager;
+    private Resource                     runtimeDiagramResourceCache;
+    private HasDiagramSourceListener     hasDiagramSourceListener;
 
     /**
      * Set externally in
@@ -241,11 +248,18 @@ public class DiagramViewer
      */
     protected WorkbenchSelectionProvider selectionProvider;
 
-    public Resource getRuntime() {
+    protected Resource getRuntimeFromManager() {
         RuntimeDiagramManager rtdm = runtimeDiagramManager;
         return (rtdm == null) ? null : rtdm.getRuntimeDiagram();
     }
 
+    public Resource getRuntime() {
+        if (runtimeDiagramResourceCache != null)
+            return runtimeDiagramResourceCache;
+        runtimeDiagramResourceCache = getRuntimeFromManager();
+        return runtimeDiagramResourceCache;
+    }
+
     public ParametrizedRead<IResourceEditorInput, Boolean> getInputValidator() {
         return INPUT_VALIDATOR;
     }
@@ -318,6 +332,8 @@ public class DiagramViewer
         //ctx.add(new ZoomTransitionParticipant(TransitionFunction.SIGMOID));
         //ctx.add(new TooltipParticipant());
         ctx.add(new TerminalTooltipParticipant());
+        ctx.add(new ConnectionCrossingsParticipant(getInputResource()));
+        ctx.add(new CopyAsSVGParticipant());
     }
 
     protected void addPainterParticipants(ICanvasContext ctx) {
@@ -348,7 +364,7 @@ public class DiagramViewer
         try {
             return BrowseContext.getBrowseContextClosure(Simantics.getSession(), defaultPropertyBrowseContexts);
         } catch (DatabaseException e) {
-            ExceptionUtils.logAndShowError("Failed to load modeled browse contexts for property page, see exception for details.", e);
+            ExceptionUtils.logAndShowError(Messages.DiagramViewer_FailedtoLoadModeled, e);
             return defaultPropertyBrowseContexts;
         }
     }
@@ -358,7 +374,7 @@ public class DiagramViewer
     }
 
     protected String getPopupId() {
-        return "#ModelingDiagramPopup";
+        return "#ModelingDiagramPopup"; //$NON-NLS-1$
     }
 
     protected void getPreferences() {
@@ -422,7 +438,7 @@ public class DiagramViewer
         resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);
         c = new SWTChassis(parent, 0);
 
-        Object task = BEGIN("DV.precreateParticipants");
+        Object task = BEGIN("DV.precreateParticipants"); //$NON-NLS-1$
         createCustomParticipants();
         END(task);
 
@@ -464,7 +480,7 @@ public class DiagramViewer
         swt = SWTThread.getThreadAccess(display);
         statusLineManager = getEditorSite().getActionBars().getStatusLineManager();
 
-        Object task = BEGIN("DV.initSession");
+        Object task = BEGIN("DV.initSession"); //$NON-NLS-1$
         initSession();
         END(task);
 
@@ -483,7 +499,7 @@ public class DiagramViewer
             this.canvasContext = new CanvasContext(thread);
             this.canvasContext.setLocked(true);
 
-            task = BEGIN("DV.createChassis");
+            task = BEGIN("DV.createChassis"); //$NON-NLS-1$
             createChassis(parent);
             END(task);
         } catch (DatabaseException e) {
@@ -513,9 +529,9 @@ public class DiagramViewer
      * Invoke this only from the AWT thread.
      */
     protected void initializeCanvas() {
-        Object canvasInit = BEGIN("DV.canvasInitialization");
+        Object canvasInit = BEGIN("DV.canvasInitialization"); //$NON-NLS-1$
 
-        Object task = BEGIN("DV.createViewerCanvas");
+        Object task = BEGIN("DV.createViewerCanvas"); //$NON-NLS-1$
         initializeCanvasContext(canvasContext);
         END(task);
 
@@ -532,7 +548,7 @@ public class DiagramViewer
         canvasContext.getHintStack().addKeyHintListener(GridPainter.KEY_GRID_ENABLED, canvasHintListener);
         canvasContext.getHintStack().addKeyHintListener(RulerPainter.KEY_RULER_ENABLED, canvasHintListener);
 
-        task = BEGIN("DV.setCanvasContext");
+        task = BEGIN("DV.setCanvasContext"); //$NON-NLS-1$
         setCanvasContext(canvasContext);
         END(task);
 
@@ -557,7 +573,7 @@ public class DiagramViewer
      *        cancelled.
      */
     protected void performActivation(IProgressMonitor monitor) {
-        SubMonitor progress = SubMonitor.convert(monitor, "Activate Mapping", 100);
+        SubMonitor progress = SubMonitor.convert(monitor, Messages.DiagramViewer_MonitorActivateMapping, 100);
         IActivationManager activationManager = sessionContext.getSession().peekService(IActivationManager.class);
         if (activationManager != null) {
             activation = activationManager.activate(diagramResource);
@@ -573,7 +589,7 @@ public class DiagramViewer
      */
     protected void scheduleZoomToFit(IDiagram diagram) {
         if (diagram == null)
-            throw new IllegalStateException("diagram is null");
+            throw new IllegalStateException("diagram is null"); //$NON-NLS-1$
 
         CanvasUtils.scheduleZoomToFit(swt, () -> disposed, canvasContext, diagram);
     }
@@ -631,14 +647,35 @@ public class DiagramViewer
      * @throws DatabaseException
      */
     protected IDiagram loadDiagram(IProgressMonitor monitor, Resource diagram, IHintContext initialHints) throws DatabaseException {
-       RuntimeDiagramManager rtdm = runtimeDiagramManager;
-       Resource runtimeDiagram = rtdm != null ? rtdm.getRuntimeDiagram() : null;
-       IDiagramLoader loader = synchronizer;
-       if (rtdm == null || runtimeDiagram == null || loader == null)
-               return null;
-        IDiagram d = sessionContext.getSession().syncRequest(
-                DiagramRequests.loadDiagram(monitor, getResourceInput2().getModel(null), diagram,
-                        runtimeDiagram, null, loader, initialHints));
+        RuntimeDiagramManager rtdm = runtimeDiagramManager;
+        Resource runtimeDiagram = rtdm != null ? rtdm.getRuntimeDiagram() : null;
+        IDiagramLoader loader = synchronizer;
+        if (rtdm == null || runtimeDiagram == null || loader == null)
+            return null;
+        IDiagram d = sessionContext.getSession().syncRequest((Read<IDiagram>) graph -> {
+            IDiagram result = DiagramRequests.loadDiagram(monitor, getResourceInput2().getModel(null), diagram,
+                    runtimeDiagram, null, loader, initialHints).perform(graph);
+
+            // #399: Enable certain PropertyTester implementation without database transactions
+            ModelingResources MOD = ModelingResources.getInstance(graph);
+            Resource composite = graph.getPossibleObject(diagram, MOD.DiagramToComposite);
+            result.setHint(
+                    DiagramModelHints.KEY_DIAGRAM_RESOURCE_TYPE_URIS,
+                    graph.syncRequest(new TypeURIs(diagram)));
+            result.setHint(
+                    DiagramModelHints.KEY_MAPPED_COMPOSITE_RESOURCE_TYPE_URIS,
+                    composite != null ? graph.syncRequest(new TypeURIs(composite)) : Collections.emptySet());
+
+            Resource diagramSource = graph.syncRequest(
+                    new PossibleObject(diagram, MOD.HasDiagramSource),
+                    hasDiagramSourceListener = new HasDiagramSourceListener(sourceDiagramContainer));
+            ElementUtils.setOrRemoveHint(
+                    result, 
+                    DiagramModelHints.KEY_HAS_DIAGRAM_SOURCE,
+                    diagramSource);
+
+            return result;
+        });
         return d;
     }
 
@@ -664,7 +701,7 @@ public class DiagramViewer
                 }
             });
         } catch (DatabaseException e) {
-            throw new UnsupportedOperationException("Failed to initialize data model synchronizer", e);
+            throw new UnsupportedOperationException("Failed to initialize data model synchronizer", e); //$NON-NLS-1$
         }
     }
 
@@ -691,7 +728,7 @@ public class DiagramViewer
         // unnecessary visual glitches.
         h.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE);
 
-        Object task = BEGIN("createSynchronizer");
+        Object task = BEGIN("createSynchronizer"); //$NON-NLS-1$
         this.synchronizer = createSynchronizer(ctx, sessionContext);
         END(task);
 
@@ -807,7 +844,7 @@ public class DiagramViewer
                 }
             }, parameter -> {
                 if (parameter != null)
-                    ErrorLogger.defaultLogError("Failed to write default diagram page description to database, see exception for details", parameter);
+                    ErrorLogger.defaultLogError("Failed to write default diagram page description to database, see exception for details", parameter); //$NON-NLS-1$
             });
         }
 
@@ -833,7 +870,7 @@ public class DiagramViewer
 
     protected void setDiagramDesc(ICanvasContext ctx, DiagramDesc diagramDesc) {
         if (diagramDesc == null)
-            throw new NullPointerException("null diagram desc");
+            throw new NullPointerException("null diagram desc"); //$NON-NLS-1$
 
         if (diagramDesc.equals(this.diagramDesc))
             return;
@@ -923,6 +960,12 @@ public class DiagramViewer
         }
 
         disposed = true;
+
+        if (hasDiagramSourceListener != null) {
+            hasDiagramSourceListener.dispose();
+            hasDiagramSourceListener = null;
+        }
+
         if (activation != null) {
             activation.deactivate();
             activation = null;
@@ -949,7 +992,7 @@ public class DiagramViewer
 
     public void init(DiagramViewerHost _host, IEditorSite site, IEditorInput input, DataContainer<IDiagram> diagramContainer, WorkbenchSelectionProvider selectionProvider) {
         if (!(input instanceof IResourceEditorInput))
-            throw new RuntimeException("Invalid input: must be IResourceEditorInput");
+            throw new RuntimeException("Invalid input: must be IResourceEditorInput"); //$NON-NLS-1$
 
         setHost(_host);
         setSite(site);
@@ -991,7 +1034,7 @@ public class DiagramViewer
             try {
                 return (T) DiagramTypeUtils.readSymbolProviderFactory(sessionContext.getSession(), diagramResource);
             } catch (DatabaseException e) {
-                ErrorLogger.defaultLogError(getClass() + " failed to adapt to SymbolProviderFactory, see exception for details.", e);
+                ErrorLogger.defaultLogError(getClass() + " failed to adapt to SymbolProviderFactory, see exception for details.", e); //$NON-NLS-1$
                 return null;
             }
         }