From: Tuukka Lehtonen Date: Wed, 26 Aug 2020 07:09:23 +0000 (+0000) Subject: Merge "Add utility class org.simantics.modeling.help.HelpContexts" X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=ac218cd884b2c9c42e503f4a0212d56323a52291;hp=c0941146a40af9df766b514fd4238aa20ec2ff4f Merge "Add utility class org.simantics.modeling.help.HelpContexts" --- diff --git a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/RouteLine.java b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/RouteLine.java index 2011bfa28..225c4abfe 100644 --- a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/RouteLine.java +++ b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/RouteLine.java @@ -113,10 +113,17 @@ public class RouteLine implements RouteNode, Serializable { out.print(" HOR"); else out.print(" VER"); + if (hidden) + out.print(" HIDDEN"); + out.print(" @ " + position); for(RoutePoint point : points) { out.print(" ("+point.x+","+point.y+")"); } out.print(" (data=" + data + ")"); + if (nextTransient != null) + out.print(" (next transient line=" + nextTransient.getData() + ")"); + if (terminal != null) + out.print(" (terminal=" + terminal.getData() + ")"); out.println(); } diff --git a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/segments/Segment.java b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/segments/Segment.java index b283cb4ed..4e4280c0a 100644 --- a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/segments/Segment.java +++ b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/segments/Segment.java @@ -28,4 +28,9 @@ public class Segment { public boolean isDegenerated() { return p1.getX() == p2.getX() && p1.getY() == p2.getY(); } + + @Override + public String toString() { + return String.format("(%f, %f) (%f, %f)", p1.getX(), p1.getY(), p2.getX(), p2.getY()); + } } diff --git a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/splitting/SplittedRouteGraph.java b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/splitting/SplittedRouteGraph.java index ae79dc019..8f7f71a29 100644 --- a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/splitting/SplittedRouteGraph.java +++ b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/splitting/SplittedRouteGraph.java @@ -1,13 +1,17 @@ package org.simantics.diagram.connection.splitting; -import gnu.trove.set.hash.THashSet; - +import java.awt.geom.Line2D; import java.awt.geom.Point2D; +import java.util.ArrayList; import org.simantics.diagram.connection.RouteGraph; import org.simantics.diagram.connection.RouteLine; import org.simantics.diagram.connection.RouteNode; +import org.simantics.diagram.connection.RoutePoint; import org.simantics.diagram.connection.RouteTerminal; +import org.simantics.diagram.connection.segments.Segment; + +import gnu.trove.set.hash.THashSet; public class SplittedRouteGraph { public final RouteLine splitLine; @@ -91,7 +95,75 @@ public class SplittedRouteGraph { } } - /** + public static final class PickResult { + /** + * The connection route line nearest to {@link #pickPoint}. + */ + public final RouteLine nearestLine; + /** + * Original pick point in canvas coordinates. + */ + public final Point2D pickPoint; + /** + * Intersection point in canvas coordinates of {@link #nearestLine} and + * perpendicular line from {@link #pickPoint} to {@link #nearestLine}. + */ + public final Point2D intersectionPoint; + + public PickResult(RouteLine nearestLine, Point2D pickPoint, Point2D intersectionPoint) { + this.nearestLine = nearestLine; + this.pickPoint = pickPoint; + this.intersectionPoint = intersectionPoint; + } + } + + public static PickResult pickNearestLine(RouteGraph rg, double x, double y) { + Segment nearestSegment = null; + RouteLine nearestLine = null; + + ArrayList segments = new ArrayList<>(); + double minDistanceSq = Double.MAX_VALUE; + for (RouteLine line : rg.getAllLines()) { + segments.clear(); + line.collectSegments(segments); + for (Segment segment : segments) { + RoutePoint p1 = segment.p1; + RoutePoint p2 = segment.p2; + double distanceSq = Line2D.ptSegDistSq(p1.getX(), p1.getY(), p2.getX(), p2.getY(), x, y); + if (distanceSq < minDistanceSq) { + minDistanceSq = distanceSq; + nearestSegment = segment; + nearestLine = line; + } + } + } + + if (nearestSegment == null) + return null; + + RoutePoint p1 = nearestSegment.p1; + RoutePoint p2 = nearestSegment.p2; + Point2D p = pointToLineIntersection(p1.getX(), p1.getY(), p2.getX(), p2.getY(), x, y); + return new PickResult(nearestLine, new Point2D.Double(x, y), p); + } + + private static Point2D pointToLineIntersection(double x1, double y1, double x2, double y2, double px, double py) { + double d = Math.pow(x2 - x1, 2.0) + Math.pow(y2 - y1, 2.0); + if (d == 0) { + return new Point2D.Double(x1, y1); + } else { + double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / d; + if (u > 1.0) { + return new Point2D.Double(x2, y2); + } else if (u <= 0.0) { + return new Point2D.Double(x1, y1); + } else { + return new Point2D.Double(x2 * u + x1 * (1.0-u), (y2 * u + y1 * (1.0- u))); + } + } + } + + /** * @param point * @param line * @return the specified point instance snapped to the specified line diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/FlagUtil.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/FlagUtil.java index d38a301da..e53f4b636 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/FlagUtil.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/FlagUtil.java @@ -176,6 +176,17 @@ public final class FlagUtil { * @throws DatabaseException */ public static Resource join(WriteGraph g, Resource flag, Resource otherFlag) throws DatabaseException { + return join(g, flag, otherFlag, true); + } + + /** + * @param g + * @param flag + * @param otherFlag + * @return the created DIA.ConnectionJoin instance + * @throws DatabaseException + */ + public static Resource join(WriteGraph g, Resource flag, Resource otherFlag, boolean activateDiagramMapping) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(g); StructuralResource2 STR = StructuralResource2.getInstance(g); Resource connectionJoin = g.newResource(); @@ -184,14 +195,24 @@ public final class FlagUtil { g.claim(connectionJoin, DIA.JoinsFlag, flag); g.claim(connectionJoin, DIA.JoinsFlag, otherFlag); - IActivationManager manager = g.getService(IActivationManager.class); - for(Resource diagram : OrderedSetUtils.getSubjects(g, flag)) - manager.activateOnce(g, diagram); - for(Resource diagram : OrderedSetUtils.getSubjects(g, otherFlag)) - manager.activateOnce(g, diagram); + if (activateDiagramMapping) { + activateMappingForParentDiagramsOf(g, flag, otherFlag); + } + return connectionJoin; } + public static void activateMappingForParentDiagramsOf(WriteGraph graph, Resource... elements) throws DatabaseException { + IActivationManager manager = graph.getService(IActivationManager.class); + Set diagrams = new HashSet<>(elements.length); + for (Resource e : elements) { + diagrams.addAll(OrderedSetUtils.getSubjects(graph, e)); + } + for (Resource diagram : diagrams) { + manager.activateOnce(graph, diagram); + } + } + public static void disconnectFlag(WriteGraph graph, Resource flag) throws DatabaseException { // Remove any :ConnectionJoin's this flag is joined by // if there's less than two flags joined by the join. @@ -531,5 +552,4 @@ public final class FlagUtil { return flags; } - -} +} \ No newline at end of file diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/RouteGraphConnectionSplitter.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/RouteGraphConnectionSplitter.java index 3f1076b5d..5c85a9944 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/RouteGraphConnectionSplitter.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/RouteGraphConnectionSplitter.java @@ -1,11 +1,10 @@ package org.simantics.diagram.flag; -import gnu.trove.map.hash.TObjectIntHashMap; - import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Collection; +import java.util.List; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; @@ -24,9 +23,11 @@ import org.simantics.diagram.connection.RouteNode; import org.simantics.diagram.connection.RoutePoint; import org.simantics.diagram.connection.RouteTerminal; import org.simantics.diagram.connection.splitting.SplittedRouteGraph; +import org.simantics.diagram.connection.splitting.SplittedRouteGraph.PickResult; import org.simantics.diagram.content.ConnectionUtil; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.diagram.synchronization.graph.AddElement; +import org.simantics.diagram.synchronization.graph.BasicResources; import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; import org.simantics.diagram.synchronization.graph.RouteGraphModification; import org.simantics.g2d.elementclass.FlagClass; @@ -34,6 +35,8 @@ import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.structural.stubs.StructuralResource2; +import gnu.trove.map.hash.TObjectIntHashMap; + /** * A class that handles splitting a route graph connection in two with diagram * local flags. @@ -87,34 +90,33 @@ public class RouteGraphConnectionSplitter { RouteGraphModification modis = new RouteGraphModification(ss, rg); TObjectIntHashMap idMap = modis.getIdMap(); + if (DEBUG) { + System.out.println("Split canvas position: " + splitCanvasPos); + rg.print(); + } + // Find the edge to disconnect in the graph. // Bisect the nearest route line. - RouteLine line = SplittedRouteGraph.findNearestLine(rg, splitCanvasPos); - if (DEBUG) - rg.print(); - if (line == null) + PickResult picked = SplittedRouteGraph.pickNearestLine(rg, splitCanvasPos.getX(), splitCanvasPos.getY()); + if (picked == null) return; + + RouteLine line = picked.nearestLine; + if (DEBUG) { + System.out.println("picked nearest line:"); line.print(System.out); for (RoutePoint rp : line.getPoints()) System.out.println("RP: " + rp.getX() + ", " + rp.getY()); } // Get exact intersection point on the line - double isectX = splitCanvasPos.getX(); - double isectY = splitCanvasPos.getY(); - SplittedRouteGraph srg; - if (line.isHorizontal()) { - isectY = line.getPosition(); - srg = rg.splitGraph(line, isectX); - } - else { - isectX = line.getPosition(); - srg = rg.splitGraph(line, isectY); - } + double isectX = picked.intersectionPoint.getX(); + double isectY = picked.intersectionPoint.getY(); + SplittedRouteGraph srg = rg.splitGraph(line, line.isHorizontal() ? isectX : isectY); if (DEBUG) System.out.println(srg); - + // Disconnect if(rg.isSimpleConnection()) { RouteNode na = srg.terminals1.iterator().next(); @@ -141,44 +143,106 @@ public class RouteGraphConnectionSplitter { idMap.get(srg.splitLine) )); } - - ArrayList interfaceNodes1Resources = new ArrayList(srg.interfaceNodes1.size()); - for(RouteNode n : srg.interfaceNodes1) - interfaceNodes1Resources.add(ss.getResource((Long)n.getData())); - ArrayList interfaceNodes2Resources = new ArrayList(srg.interfaceNodes2.size()); - for(RouteNode n : srg.interfaceNodes2) - interfaceNodes2Resources.add(ss.getResource((Long)n.getData())); - - ArrayList lines2Resources = new ArrayList(srg.lines2.size()); - for(RouteLine n : srg.lines2) - lines2Resources.add(ss.getResource((Long)n.getData())); - - ArrayList terminals1Resources = new ArrayList(srg.terminals1.size()); - for(RouteTerminal n : srg.terminals1) - terminals1Resources.add(ss.getResource((Long)n.getData())); - ArrayList terminals2Resources = new ArrayList(srg.terminals2.size()); - for(RouteTerminal n : srg.terminals2) - terminals2Resources.add(ss.getResource((Long)n.getData())); + ArrayList terminals1Resources = toResources(srg.terminals1); + ArrayList terminals2Resources = toResources(srg.terminals2); + + boolean mustFlip = analyzePartInputs(graph, terminals1Resources, terminals2Resources); + + ArrayList interfaceNodes1 = toResources(mustFlip ? srg.interfaceNodes2 : srg.interfaceNodes1); + ArrayList interfaceNodes2 = toResources(mustFlip ? srg.interfaceNodes1 : srg.interfaceNodes2); + + ArrayList lines2 = toResources(mustFlip ? srg.lines1 : srg.lines2); + ArrayList terminals1 = mustFlip ? terminals2Resources : terminals1Resources; + ArrayList terminals2 = mustFlip ? terminals1Resources : terminals2Resources; + doSplit(graph, connection, - interfaceNodes1Resources, - interfaceNodes2Resources, - lines2Resources, - terminals1Resources, - terminals2Resources, + interfaceNodes1, + interfaceNodes2, + lines2, + terminals1, + terminals2, line.isHorizontal(), + mustFlip, isectX, isectY); modis.addModi(new RouteGraphModification.Split( - modis.toIds(interfaceNodes1Resources), - modis.toIds(interfaceNodes2Resources), - modis.toIds(lines2Resources), - modis.toIds(terminals1Resources), - modis.toIds(terminals2Resources), + modis.toIds(interfaceNodes1), + modis.toIds(interfaceNodes2), + modis.toIds(lines2), + modis.toIds(terminals1), + modis.toIds(terminals2), line.isHorizontal(), + mustFlip, isectX, isectY )); - } - + + private ArrayList toResources(Collection nodes) throws DatabaseException { + ArrayList result = new ArrayList<>(nodes.size()); + for (RouteNode n : nodes) + result.add(ss.getResource((Long)n.getData())); + return result; + } + + /** + * @param graph + * @param terminals1 + * @param terminals2 + * @return true if inputs need to be flipped, i.e. if terminals2 + * contains the output terminals and terminals1 doesn't. + * @throws DatabaseException + */ + private boolean analyzePartInputs(ReadGraph graph, List terminals1, List terminals2) throws DatabaseException { + @SuppressWarnings("unused") + int inputs1 = 0, outputs1 = 0; + for(Resource connector : terminals1) { + if(graph.hasStatement(connector, DIA.IsHeadConnectorOf)) + ++inputs1; + else + ++outputs1; + } + @SuppressWarnings("unused") + int inputs2 = 0, outputs2 = 0; + for(Resource connector : terminals2) { + if(graph.hasStatement(connector, DIA.IsHeadConnectorOf)) + ++inputs2; + else + ++outputs2; + } + + boolean mustFlip = outputs1 == 0; + + if (DEBUG) { + System.out.println("inputs1: " + inputs1); + System.out.println("outputs1: " + outputs1); + System.out.println("inputs2: " + inputs2); + System.out.println("outputs2: " + outputs2); + System.out.println("=> type1: " + (mustFlip ? FlagClass.Type.In : FlagClass.Type.Out)); + System.out.println("=> type2: " + (mustFlip ? FlagClass.Type.Out : FlagClass.Type.In)); + System.out.println("=> must flip route graph parts to split: " + mustFlip); + } + + return mustFlip; + } + + private static String routeNodeDebugInfo(ReadGraph graph, Resource c) throws DatabaseException { + BasicResources BR = BasicResources.getInstance(graph); + String ctr = NameUtils.getSafeName(graph, c, true); + for (Resource e : graph.getObjects(c, BR.STR.Connects)) { + ctr += " --> " + NameUtils.getSafeName(graph, e); + } + for (Resource e : graph.getObjects(c, BR.DIA.AreConnected)) { + ctr += " <-> " + NameUtils.getSafeName(graph, e); + } + return ctr; + } + + /** + * Internal routine that is only public because + * {@link RouteGraphModification#runUpdates(WriteGraph)} needs to invoke it. + * + * Assumes that #1 parameters will stay with the existing connection and #2 + * parameters will go to the newly created connection. + */ public void doSplit(WriteGraph graph, Resource connection, ArrayList interfaceNodes1Resources, @@ -186,22 +250,28 @@ public class RouteGraphConnectionSplitter { ArrayList lines2Resources, ArrayList terminals1Resources, ArrayList terminals2Resources, - boolean isHorizontal, + boolean isHorizontal, + boolean invertFlagRotation, double isectX, double isectY) throws DatabaseException { + // 1 = output, 2 = input + FlagClass.Type + type1 = FlagClass.Type.Out, + type2 = FlagClass.Type.In; + if (DEBUG) { System.out.println("doSplit:"); System.out.println(NameUtils.getSafeName(graph, connection, true)); for (Resource i : interfaceNodes1Resources) - System.out.println("i1: " + NameUtils.getSafeName(graph, i, true)); + System.out.println("i1: " + routeNodeDebugInfo(graph, i)); for (Resource i : interfaceNodes2Resources) - System.out.println("i2: " + NameUtils.getSafeName(graph, i, true)); + System.out.println("i2: " + routeNodeDebugInfo(graph, i)); for (Resource l : lines2Resources) - System.out.println("l2r: " + NameUtils.getSafeName(graph, l, true)); + System.out.println("l2r: " + routeNodeDebugInfo(graph, l)); for (Resource t : terminals1Resources) - System.out.println("t1: " + NameUtils.getSafeName(graph, t, true)); + System.out.println("t1: " + routeNodeDebugInfo(graph, t)); for (Resource t : terminals2Resources) - System.out.println("t2: " + NameUtils.getSafeName(graph, t, true)); + System.out.println("t2: " + routeNodeDebugInfo(graph, t)); System.out.println("is horizontal: " + isHorizontal); System.out.println("@(x,y): " + isectX + ", " + isectY); } @@ -209,15 +279,39 @@ public class RouteGraphConnectionSplitter { ConnectionUtil cu = new ConnectionUtil(graph); Resource diagram = OrderedSetUtils.getSingleOwnerList(graph, connection, DIA.Diagram); - Resource connectionType = graph.getSingleType(connection, DIA.Connection); + Resource diagramConnectionType = graph.getSingleType(connection, DIA.Connection); Resource hasConnectionType = graph.getPossibleObject(connection, STR.HasConnectionType); - Resource newConnection = cu.newConnection(diagram, connectionType); + Resource newConnection = cu.newConnection(diagram, diagramConnectionType); if (hasConnectionType != null) graph.claim(newConnection, STR.HasConnectionType, null, hasConnectionType); // Give running name to connection increment the counter attached to the diagram. AddElement.claimFreshElementName(graph, diagram, newConnection); + String commonLabel = DiagramFlagPreferences + .getActiveFlagLabelingScheme(graph) + .generateLabel(graph, diagram); + + Point2D pos1, pos2; + double theta; + double flagDist = 3.0; + if(isHorizontal) { + theta = 0.0; + pos1 = new Point2D.Double(isectX-flagDist, isectY); + pos2 = new Point2D.Double(isectX+flagDist, isectY); + } else { + theta = Math.PI*0.5; + pos1 = new Point2D.Double(isectX, isectY-flagDist); + pos2 = new Point2D.Double(isectX, isectY+flagDist); + } + + if (invertFlagRotation) { + theta += Math.PI; + Point2D p = pos1; + pos1 = pos2; + pos2 = p; + } + // WORKAROUND for mapping problems: // If any terminal of the split connection contains a flag, make sure their STR.Joins relations are all removed // to give mapping a chance to fix them properly. @@ -237,97 +331,31 @@ public class RouteGraphConnectionSplitter { graph.claim(rn, predicate, newConnection); } - // 1 = output, 2 = input - FlagClass.Type type1, type2; - - FlagLabelingScheme scheme = DiagramFlagPreferences.getActiveFlagLabelingScheme(graph); - String commonLabel = scheme.generateLabel(graph, diagram); - // Create flags and connect both disconnected ends to them. - Point2D pos1, pos2; - double theta; - double flagDist = 3.0; - if(isHorizontal) { - theta = 0.0; - pos1 = new Point2D.Double(isectX-flagDist, isectY); - pos2 = new Point2D.Double(isectX+flagDist, isectY); - } - else { - theta = Math.PI*0.5; - pos1 = new Point2D.Double(isectX, isectY-flagDist); - pos2 = new Point2D.Double(isectX, isectY+flagDist); - } - - // Chooses flag directions - { - @SuppressWarnings("unused") - int inputs1 = 0, outputs1 = 0; - for(Resource connector : terminals1Resources) { - if(graph.hasStatement(connector, DIA.IsHeadConnectorOf)) - ++inputs1; - else - ++outputs1; - } - @SuppressWarnings("unused") - int inputs2 = 0, outputs2 = 0; - for(Resource connector : terminals2Resources) { - if(graph.hasStatement(connector, DIA.IsHeadConnectorOf)) - ++inputs2; - else - ++outputs2; - } - - if(outputs1 == 0) { - type1 = FlagClass.Type.In; - type2 = FlagClass.Type.Out; - theta += Math.PI; - } - else { - type1 = FlagClass.Type.Out; - type2 = FlagClass.Type.In; - } - if (DEBUG) { - System.out.println("inputs1: " + inputs1); - System.out.println("outputs1: " + outputs1); - System.out.println("=> type1: " + type1); - System.out.println("inputs2: " + inputs2); - System.out.println("outputs2: " + outputs2); - System.out.println("=> type2: " + type2); - } - } Resource flag1 = createFlag(graph, diagram, getFlagTransform(pos1, theta), type1, commonLabel); Resource flag2 = createFlag(graph, diagram, getFlagTransform(pos2, theta), type2, commonLabel); + if (DEBUG) { + System.out.println("LABEL FOR NEW FLAGS: " + commonLabel); System.out.println("FLAG1: " + NameUtils.getSafeName(graph, flag1, true)); System.out.println("FLAG2: " + NameUtils.getSafeName(graph, flag2, true)); } -// System.out.println("conn1: " + NameUtils.getSafeLabel(graph, type1 == FlagClass.Type.In ? DIA.HasPlainConnector : DIA.HasArrowConnector)); -// System.out.println("conn2: " + NameUtils.getSafeLabel(graph, type2 == FlagClass.Type.In ? DIA.HasPlainConnector : DIA.HasArrowConnector)); - Resource flagConnector1 = cu.newConnector(connection, - type1 == FlagClass.Type.In ? DIA.HasPlainConnector : DIA.HasArrowConnector); - Resource flagConnector2 = cu.newConnector(newConnection, - type2 == FlagClass.Type.In ? DIA.HasPlainConnector : DIA.HasArrowConnector); + Resource flagConnector1 = cu.newConnector(connection, DIA.HasArrowConnector); + Resource flagConnector2 = cu.newConnector(newConnection, DIA.HasPlainConnector); graph.claim(flag1, DIA.Flag_ConnectionPoint, flagConnector1); graph.claim(flag2, DIA.Flag_ConnectionPoint, flagConnector2); double position = isHorizontal ? isectY : isectX; - connectFlag(graph, isHorizontal, position, connection, flagConnector1, - interfaceNodes1Resources); - connectFlag(graph, isHorizontal, position, newConnection, flagConnector2, - interfaceNodes2Resources); - - FlagUtil.join(graph, flag1, flag2); - - // Move mapping relations to new connection if necessary - if(type1 == FlagClass.Type.In) { - moveStatements(graph, connection, newConnection, MOD.ElementToComponent); - moveStatements(graph, connection, newConnection, MOD.DiagramConnectionToConnection); - moveStatements(graph, connection, newConnection, MOD.DiagramConnectionToConnectionSpecial); - FlagUtil.fixBindsStatements(graph, graph.getPossibleObject(newConnection, MOD.DiagramConnectionToConnection)); - } - else - FlagUtil.fixBindsStatements(graph, graph.getPossibleObject(connection, MOD.DiagramConnectionToConnection)); + connectFlag(graph, isHorizontal, position, connection, flagConnector1, interfaceNodes1Resources); + connectFlag(graph, isHorizontal, position, newConnection, flagConnector2, interfaceNodes2Resources); + + // Join the flags without activatingn diagram mapping at this point + FlagUtil.join(graph, flag1, flag2, false); + FlagUtil.fixBindsStatements(graph, graph.getPossibleObject(connection, MOD.DiagramConnectionToConnection)); + + // Finally ensure that all the diagrams related to the operation are mapped properly in one go + FlagUtil.activateMappingForParentDiagramsOf(graph, flag1, flag2); } /** @@ -370,15 +398,6 @@ public class RouteGraphConnectionSplitter { } } - private static void moveStatements(WriteGraph graph, Resource from, Resource to, Resource relation) throws DatabaseException { - if(from.equals(to)) - return; - for(Statement stat : graph.getStatements(from, relation)) - if(stat.getSubject().equals(from)) - graph.claim(to, stat.getPredicate(), stat.getObject()); - graph.deny(from, relation); - } - private void connectFlag(WriteGraph graph, boolean isHorizontal, double position, Resource connection, Resource flagConnector, Collection interfaceNodes) throws DatabaseException { if(interfaceNodes.size() > 1) { @@ -421,6 +440,7 @@ public class RouteGraphConnectionSplitter { } public static void splitConnection(WriteGraph graph, Resource connection, double x, double y) throws DatabaseException { + // TODO: provide a proper runtimeDiagram parameter to load to support also connections attached to flags attached to diagram template flag tables RouteGraph rg = RouteGraphUtils.load(graph, null, connection); new RouteGraphConnectionSplitter(graph).split(graph, connection, rg, new Point2D.Double(x, y)); } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/function/All.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/function/All.java index 6cd4c542f..5bb793f7d 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/function/All.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/function/All.java @@ -95,6 +95,8 @@ public class All { Resource flag = context.element; Resource runtimeDiagram = context.runtime; + if (runtimeDiagram == null) + return flagTransformImpl(graph, converter, context); Resource diagram = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasConfiguration); if (diagram == null) diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/RouteGraphModification.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/RouteGraphModification.java index a15b99bc4..41f4c00e6 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/RouteGraphModification.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/RouteGraphModification.java @@ -162,12 +162,14 @@ public class RouteGraphModification { int[] lines2; int[] terminals1; int[] terminals2; - boolean isHorizontal; + boolean isHorizontal; + boolean invertFlagRotation; double isectX; double isectY; public Split(int[] interface1, int[] interface2, int[] lines2, int[] terminals1, int[] terminals2, boolean isHorizontal, + boolean invertFlagRotation, double isectX, double isectY) { this.interface1 = interface1; this.interface2 = interface2; @@ -175,6 +177,7 @@ public class RouteGraphModification { this.terminals1 = terminals1; this.terminals2 = terminals2; this.isHorizontal = isHorizontal; + this.invertFlagRotation = invertFlagRotation; this.isectX = isectX; this.isectY = isectY; } @@ -188,6 +191,7 @@ public class RouteGraphModification { this.terminals1 = readInts(it); this.terminals2 = readInts(it); this.isHorizontal = Boolean.parseBoolean(it.next()); + this.invertFlagRotation = Boolean.parseBoolean(it.next()); this.isectX = Double.parseDouble(it.next()); this.isectY = Double.parseDouble(it.next()); } @@ -208,6 +212,8 @@ public class RouteGraphModification { b.append("$"); b.append(isHorizontal); b.append("$"); + b.append(invertFlagRotation); + b.append("$"); b.append(isectX); b.append("$"); b.append(isectY); @@ -531,6 +537,7 @@ public class RouteGraphModification { toResources(modi.terminals1), toResources(modi.terminals2), modi.isHorizontal, + modi.invertFlagRotation, modi.isectX, modi.isectY );