]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/sg/DiagramSceneGraphProvider.java
Importing TG files creates copies of files without deleting them.
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / sg / DiagramSceneGraphProvider.java
index 3d800d1f1f43d56ff82c929f9e0fcc4aa12ea6fb..ef3197522ff158081466be7f3bfd9daea4418d18 100644 (file)
@@ -19,6 +19,7 @@ import org.simantics.Simantics;
 import org.simantics.databoard.Bindings;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
+import org.simantics.db.VirtualGraph;
 import org.simantics.db.common.ResourceArray;
 import org.simantics.db.common.primitiverequest.PossibleAdapter;
 import org.simantics.db.exception.DatabaseException;
@@ -26,7 +27,9 @@ import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
 import org.simantics.db.exception.NoSingleResultException;
 import org.simantics.db.exception.ServiceException;
 import org.simantics.db.management.ISessionContext;
+import org.simantics.db.procedure.Listener;
 import org.simantics.db.request.Read;
+import org.simantics.db.service.VirtualGraphSupport;
 import org.simantics.diagram.adapter.DefaultConnectionClassFactory;
 import org.simantics.diagram.adapter.FlagClassFactory;
 import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;
@@ -35,6 +38,7 @@ import org.simantics.diagram.handler.CopyPasteStrategy;
 import org.simantics.diagram.handler.DefaultCopyPasteStrategy;
 import org.simantics.diagram.handler.DeleteHandler;
 import org.simantics.diagram.handler.SimpleElementTransformHandler;
+import org.simantics.diagram.participant.ConnectionCrossingsParticipant;
 import org.simantics.diagram.query.DiagramRequests;
 import org.simantics.diagram.runtime.RuntimeDiagramManager;
 import org.simantics.diagram.stubs.DiagramResource;
@@ -54,6 +58,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.IElementClassProvider;
 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
 import org.simantics.g2d.multileveldiagram.TransitionFunction;
 import org.simantics.g2d.multileveldiagram.ZoomTransitionParticipant;
@@ -90,13 +95,13 @@ import org.simantics.scenegraph.g2d.events.adapter.AWTRemoteEventAdapter;
 import org.simantics.scenegraph.g2d.events.command.CommandKeyBinding;
 import org.simantics.structural.stubs.StructuralResource2;
 import org.simantics.structural2.modelingRules.IModelingRules;
-import org.simantics.ui.SimanticsUI;
 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;
+import org.simantics.utils.threads.ThreadUtils;
 import org.simantics.utils.ui.ErrorLogger;
 
 
@@ -171,6 +176,10 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
         }
     }
 
+    public GraphToDiagramSynchronizer getGraphToDiagramSynchronizer() {
+        return synchronizer;
+    }
+
     protected CopyPasteStrategy getCopyPasteStrategy() {
                try {
                        CopyPasteStrategy cpStrategy = Simantics.getSession().syncRequest(new PossibleAdapter<CopyPasteStrategy>(resource, CopyPasteStrategy.class));
@@ -189,7 +198,7 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
                return new MappedElementCopyAdvisor(new ElementCopyAdvisor(), new ComponentCopyAdvisor());
     }
     
-    private void initContext(CanvasContext ctx) {
+    protected void initContext(CanvasContext ctx) {
         boolean unlock = false;
         if (!ctx.isLocked()) {
             ctx.setLocked(true);
@@ -244,7 +253,8 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
         ctx.add( new ElementInteractor() );
         ctx.add( new Selection() );
         ctx.add( new DiagramParticipant() );
-        ctx.add( new ElementPainter(false) );
+        ctx.add( new ElementPainter(true) );
+        ctx.add( new ConnectionCrossingsParticipant(resource));
 
         //ctx.add( new ElementHeartbeater() );
         ctx.add( new ZOrderHandler() );
@@ -278,12 +288,56 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
         if (unlock)
             ctx.setLocked(false);
     }
+    
+    public static class DiagramDescListener implements Listener<DiagramDesc> {
+       ICanvasContext ctx;
+       public DiagramDescListener(ICanvasContext ctx) {
+                       this.ctx = ctx;
+               }
+        @Override
+         public void execute(DiagramDesc result) {
+             if (result != null && ctx != null) {
+                 ThreadUtils.asyncExec(ctx.getThreadAccess(), () -> {
+                     if (ctx != null) {
+                         setDiagramDesc(ctx, result);
+                     }
+                 });
+             }
+         }
+
+         @Override
+         public void exception(Throwable t) {
+             ErrorLogger.defaultLogError(t);
+         }
+
+         @Override
+         public boolean isDisposed() {
+             return ctx == null;
+         }
+         
+         protected void setDiagramDesc(ICanvasContext ctx, DiagramDesc diagramDesc) {
+             IHintContext hints = ctx.getDefaultHintContext();
+             hints.setHint(Hints.KEY_PAGE_DESC, diagramDesc.getPageDesc());
+             hints.setHint(Hints.KEY_DISPLAY_PAGE, diagramDesc.isPageBordersVisible());
+             hints.setHint(Hints.KEY_DISPLAY_MARGINS, diagramDesc.isMarginsVisible());
+         }
+         
+         public void dispose() {
+                ctx = null;
+         }
+    }
 
+    DiagramDescListener diagramDescListener;
+    
     protected void loadPageSettings(ICanvasContext ctx, Resource diagramResource) {
         try {
             DiagramDesc diagramDesc = Simantics.getSession().syncRequest(DiagramRequests.getDiagramDesc(diagramResource));
             if (diagramDesc != null)
                 setDiagramDesc(ctx, diagramDesc);
+
+            diagramDescListener = new DiagramDescListener(ctx);
+            // Create a listener to react to page setting changes.
+            Simantics.getSession().asyncRequest(DiagramRequests.getDiagramDesc(diagramResource), diagramDescListener);
         } catch (DatabaseException e) {
             ErrorLogger.defaultLogError(e);
         }
@@ -292,7 +346,7 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
     protected void setDiagramDesc(ICanvasContext ctx, DiagramDesc diagramDesc) {
         IHintContext hints = ctx.getDefaultHintContext();
         hints.setHint(Hints.KEY_PAGE_DESC, diagramDesc.getPageDesc());
-        //hints.setHint(Hints.KEY_DISPLAY_PAGE, diagramDesc.isPageBordersVisible());
+        hints.setHint(Hints.KEY_DISPLAY_PAGE, diagramDesc.isPageBordersVisible());
         hints.setHint(Hints.KEY_DISPLAY_MARGINS, diagramDesc.isMarginsVisible());
     }
 
@@ -325,7 +379,7 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
      */
     private G2DSceneGraph initializeSceneGraph(G2DSceneGraph sg, String modelURI, String RVI, String view) {
         IThreadWorkQueue thread = AWTThread.getThreadAccess();
-        ctx = new CanvasContext(thread, sg); // By giving the scene graph instance as parameter, we can use external serializer
+        ICanvasContext ctx = new CanvasContext(thread, sg); // By giving the scene graph instance as parameter, we can use external serializer
         return initializeSceneGraph(ctx, sg, modelURI, RVI, view);
     }
 
@@ -336,7 +390,9 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
      * @return
      */
     private G2DSceneGraph initializeSceneGraph(ICanvasContext context, G2DSceneGraph sg, String modelURI, String RVI, String view) {
-        this.ctx = (CanvasContext) context;
+        if (this.ctx != null)
+               throw new RuntimeException("Cannot initialize scenegraph twice");
+       this.ctx = (CanvasContext) context;
         this.view = view;
         if(view != null) {
             //System.out.println("using layer '"+view+"'");
@@ -344,15 +400,10 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
         }
 
         try {
-
-            IModelingRules modelingRules = Simantics.getSession().syncRequest(DiagramRequests.getModelingRules(resource, null));
-            if (modelingRules != null) {
-                initialHints.setHint(DiagramModelHints.KEY_MODELING_RULES, modelingRules);
-            }
-            
-            initialHints.setHint(SynchronizationHints.COPY_ADVISOR, getCopyAdvisor());
+               fillInitialDiagramHints(initialHints);
             
             final RuntimeDiagramManager runtimeDiagramManager = RuntimeDiagramManager.create(Simantics.getSession(), resource, modelURI, RVI);
+            VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);
             
             synchronizer = Simantics.getSession().syncRequest(new Read<GraphToDiagramSynchronizer>() {
                 @Override
@@ -362,12 +413,14 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
                     if(val != null && navigation == null) { // Set only if navigation has not been set manually
                         navigation = val;
                     }
-                    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)
-                            )
-                    );
+                    VirtualGraph virtualGraph = support.getGraph(graph, resource);
+                    GraphToDiagramSynchronizer sync;
+                    if (virtualGraph != null) {
+                       sync = new GraphToDiagramSynchronizer(graph, ctx,createElementClassProvider(graph), virtualGraph);
+                    } else {
+                       sync = new GraphToDiagramSynchronizer(graph, ctx,createElementClassProvider(graph));
+                    }
+                    
                     sync.set(ModelingSynchronizationHints.MODELING_RESOURCE, ModelingResources.getInstance(graph));
                     diagram = sync.loadDiagram(new NullProgressMonitor(), graph, null, resource, runtimeDiagramManager.getRuntimeDiagram(), structuralPath, initialHints); // FIXME
                     return sync;
@@ -384,9 +437,31 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
 
         return ctx.getSceneGraph();
     }
+    
+    protected void fillInitialDiagramHints(IHintContext initialHints) throws DatabaseException {
+         IModelingRules modelingRules = Simantics.getSession().syncRequest(DiagramRequests.getModelingRules(resource, null));
+          if (modelingRules != null) {
+              initialHints.setHint(DiagramModelHints.KEY_MODELING_RULES, modelingRules);
+          }
+          
+          initialHints.setHint(SynchronizationHints.COPY_ADVISOR, getCopyAdvisor());
+    }
+    
+    protected IElementClassProvider createElementClassProvider(ReadGraph graph) throws DatabaseException {
+        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)
+        );
+        
+    }
 
     @Override
     public void dispose() {
+       if (diagramDescListener != null) {
+               diagramDescListener.dispose();
+               diagramDescListener = null;
+       }
         if(ctx != null) {
             if (ownsContext)
                 ctx.dispose();
@@ -431,7 +506,7 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi
 
         try {
             // FIXME: I have no idea if this works or not..
-            diagram = SimanticsUI.getSession().syncRequest(new Read<IDiagram>() {
+            diagram = Simantics.getSession().syncRequest(new Read<IDiagram>() {
                 @Override
                 public IDiagram perform(ReadGraph graph) throws DatabaseException {
                     IDiagram d = synchronizer.loadDiagram(new NullProgressMonitor(), graph, null, structuralPath.resources[0], null, structuralPath.removeFromBeginning(0), hints);