]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Sync git svn branch with SVN repository r33324.
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Wed, 12 Oct 2016 08:15:59 +0000 (11:15 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Wed, 12 Oct 2016 08:15:59 +0000 (11:15 +0300)
refs #6751 [PRIVATE-12404]
refs #6752 [PRIVATE-12401]

15 files changed:
bundles/org.simantics.diagram/src/org/simantics/diagram/connection/ModelledConnectionAdvisor.java
bundles/org.simantics.diagram/src/org/simantics/diagram/flag/AbstractFlagType.java
bundles/org.simantics.diagram/src/org/simantics/diagram/flag/FlagUtil.java
bundles/org.simantics.diagram/src/org/simantics/diagram/participant/ConnectTool2.java
bundles/org.simantics.diagram/src/org/simantics/diagram/participant/ConnectionBuilder.java
bundles/org.simantics.diagram/src/org/simantics/diagram/participant/RouteGraphConnectTool.java
bundles/org.simantics.event/src/org/simantics/event/util/EventUtils.java
bundles/org.simantics.event/src/org/simantics/event/view/contribution/ProjectEventsRule.java
bundles/org.simantics.event/src/org/simantics/event/view/handler/Hide.java [deleted file]
bundles/org.simantics.event/src/org/simantics/event/view/handler/MenuActions.java
bundles/org.simantics.event/src/org/simantics/event/view/handler/TagAction.java
bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/pointertool/TerminalUtil.java
bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/BranchPointTerminal.java
bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/connection/RouteGraphNode.java
bundles/org.simantics.structural2/src/org/simantics/structural2/modelingRules/StandardModelingRules.java

index 8ecf158745efb601864335cd19411e36196d03dd..16495f4cc36af5f9c153d9956b197c746f26866b 100644 (file)
@@ -127,7 +127,13 @@ public class ModelledConnectionAdvisor implements IConnectionAdvisor {
             cps.add(getConnectionPoint(graph, element2, term2, true));\r
 \r
         ConnectionJudgement judgement = modelingRules.judgeConnection(graph, cps);\r
-        if (judgement.type == ConnectionJudgementType.LEGAL)\r
+        if (judgement.type == ConnectionJudgementType.LEGAL\r
+                // #6751, Apros #12404: a connection should not be automatically\r
+                // denied just because it is not perfectly legal. Further legality\r
+                // should be decided on the client side even though the IConnectionAdvisor\r
+                // interface is not documented to return ConnectionJudgement instances,\r
+                // because the interface knows nothing about this class.\r
+                || judgement.type == ConnectionJudgementType.CANBEMADELEGAL) \r
             return judgement;\r
         return null;\r
     }\r
index 0f1a96563348b196f46bbab138d7d65c34cfe3a7..a11c10319bcc1cb269511f819547d6893cd84a91 100644 (file)
@@ -49,16 +49,17 @@ public abstract class AbstractFlagType implements IFlagType {
     }\r
 \r
     public static Mode getMode(ReadGraph graph, Resource flag) throws DatabaseException {\r
-        int joinCount = graph.getObjects(flag, DiagramResource.getInstance(graph).FlagIsJoinedBy).size();\r
+        DiagramResource DIA = DiagramResource.getInstance(graph);\r
+        int joinCount = graph.getObjects(flag, DIA.FlagIsJoinedBy).size();\r
         if(joinCount == 0)\r
             return FlagClass.Mode.Internal;\r
         else if(joinCount == 1) {\r
-            Resource otherFlag = FlagUtil.getPossibleCounterpart(graph, flag);\r
-            if(otherFlag == null /* FIXME just to get around npe */ || \r
-                    DiagramGraphUtil.onSameDiagram(graph, flag, otherFlag))\r
-                return FlagClass.Mode.Internal;\r
-            else\r
-                return FlagClass.Mode.External;\r
+            for (Resource connectionJoin : graph.getObjects(flag, DIA.FlagIsJoinedBy))\r
+                for (Resource otherFlag : graph.getObjects(connectionJoin, DIA.JoinsFlag))\r
+                    if (!flag.equals(otherFlag)\r
+                            && !DiagramGraphUtil.onSameDiagram(graph, flag, otherFlag))\r
+                        return FlagClass.Mode.External;\r
+            return FlagClass.Mode.Internal;\r
         }\r
         else\r
             return new FlagClass.External(joinCount);\r
index 27dc9e307e69038ac40daa53f5c24dc8057b412e..2a0e14b933aa7fad2c5c2364fd07b3c6f898796e 100644 (file)
@@ -28,6 +28,7 @@ import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.common.utils.OrderedSetUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.function.DbBiFunction;\r
 import org.simantics.db.function.DbConsumer;\r
 import org.simantics.db.layer0.util.RemoverUtil;\r
 import org.simantics.db.layer0.variable.Variable;\r
@@ -130,6 +131,21 @@ public final class FlagUtil {
         return count;\r
     }\r
 \r
+    public static int forCounterparts(ReadGraph graph, Resource flag, DbBiFunction<Resource, Resource, Boolean> procedure) throws DatabaseException {\r
+        DiagramResource DIA = DiagramResource.getInstance(graph);\r
+        int count = 0;\r
+        for (Resource connectionJoin : graph.getObjects(flag, DIA.FlagIsJoinedBy)) {\r
+            for (Resource otherFlag : graph.getObjects(connectionJoin, DIA.JoinsFlag)) {\r
+                if (!flag.equals(otherFlag)) {\r
+                    if (!procedure.apply(connectionJoin, otherFlag))\r
+                        return ++count;\r
+                    ++count;\r
+                }\r
+            }\r
+        }\r
+        return count;\r
+    }\r
+\r
     /**\r
      * Returns all flags that are joined with the given flag including the flag given as parameter.\r
      */\r
index 4aaa717d843109cb5d92e97e925fc3dd6dfab020..71a8d28290f9b7e020ef3bbb368ccc994287f8bc 100644 (file)
@@ -25,7 +25,6 @@ import java.util.Arrays;
 import java.util.Collection;\r
 import java.util.Collections;\r
 import java.util.Deque;\r
-import java.util.HashSet;\r
 import java.util.Iterator;\r
 import java.util.List;\r
 \r
@@ -39,12 +38,15 @@ import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.diagram.connection.RouteGraph;\r
 import org.simantics.diagram.connection.RouteGraphConnectionClass;\r
+import org.simantics.diagram.connection.RouteLine;\r
 import org.simantics.diagram.connection.RouteTerminal;\r
+import org.simantics.diagram.connection.delta.RouteGraphDelta;\r
 import org.simantics.diagram.connection.rendering.arrows.PlainLineEndStyle;\r
 import org.simantics.diagram.content.ResourceTerminal;\r
 import org.simantics.diagram.stubs.DiagramResource;\r
 import org.simantics.diagram.synchronization.ISynchronizationContext;\r
 import org.simantics.diagram.synchronization.SynchronizationHints;\r
+import org.simantics.diagram.synchronization.graph.RouteGraphConnection;\r
 import org.simantics.g2d.canvas.ICanvasContext;\r
 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
 import org.simantics.g2d.canvas.impl.DependencyReflection.Reference;\r
@@ -54,6 +56,7 @@ import org.simantics.g2d.connection.IConnectionAdvisor;
 import org.simantics.g2d.diagram.DiagramHints;\r
 import org.simantics.g2d.diagram.DiagramUtils;\r
 import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.handler.PickContext;\r
 import org.simantics.g2d.diagram.handler.Topology.Terminal;\r
 import org.simantics.g2d.diagram.participant.ElementPainter;\r
 import org.simantics.g2d.diagram.participant.TerminalPainter;\r
@@ -70,6 +73,7 @@ import org.simantics.g2d.element.IElementClassProvider;
 import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\r
 import org.simantics.g2d.element.handler.SceneGraph;\r
 import org.simantics.g2d.element.handler.TerminalTopology;\r
+import org.simantics.g2d.element.handler.impl.BranchPointTerminal;\r
 import org.simantics.g2d.element.impl.Element;\r
 import org.simantics.g2d.elementclass.BranchPoint;\r
 import org.simantics.g2d.elementclass.BranchPoint.Direction;\r
@@ -77,8 +81,8 @@ import org.simantics.g2d.elementclass.FlagClass;
 import org.simantics.g2d.elementclass.FlagHandler;\r
 import org.simantics.g2d.participant.RenderingQualityInteractor;\r
 import org.simantics.g2d.participant.TransformUtil;\r
+import org.simantics.g2d.utils.geom.DirectionSet;\r
 import org.simantics.modeling.ModelingResources;\r
-import org.simantics.scenegraph.INode;\r
 import org.simantics.scenegraph.g2d.G2DParentNode;\r
 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
 import org.simantics.scenegraph.g2d.events.KeyEvent;\r
@@ -101,6 +105,8 @@ import org.simantics.utils.logging.TimeLogger;
 import org.simantics.utils.ui.ErrorLogger;\r
 import org.simantics.utils.ui.ExceptionUtils;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 /**\r
  * A basic tool for making connection on diagrams.\r
  * \r
@@ -141,6 +147,9 @@ public class ConnectTool2 extends AbstractMode {
     @Dependency\r
     protected PointerInteractor      pi;\r
 \r
+    @Dependency\r
+    protected PickContext            pickContext;\r
+\r
     /**\r
      * Start element terminal of the connection. <code>null</code> if connection\r
      * was started from a flag or a branch point.\r
@@ -269,6 +278,8 @@ public class ConnectTool2 extends AbstractMode {
 \r
     protected G2DParentNode          endFlagNode;\r
 \r
+    private RouteGraphTarget         lastRouteGraphTarget;\r
+\r
     /**\r
      * @param startTerminal\r
      * @param mouseId\r
@@ -387,9 +398,9 @@ public class ConnectTool2 extends AbstractMode {
 \r
         ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class);\r
         pathNode.setColor(new Color(160, 0, 0));\r
-        pathNode.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,\r
-                new float[] { 5f, 2f }, 0));\r
-        pathNode.setScaleStroke(true);\r
+        pathNode.setStroke(new BasicStroke(0.1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,\r
+                new float[] { 0.5f, 0.2f }, 0));\r
+        pathNode.setScaleStroke(false);\r
         pathNode.setZIndex(0);\r
 \r
         G2DParentNode points = ghostNode.getOrCreateNode("points", G2DParentNode.class);\r
@@ -443,105 +454,18 @@ public class ConnectTool2 extends AbstractMode {
 \r
         ControlPoint begin = controlPoints.getFirst();\r
         ControlPoint end = controlPoints.getLast();\r
-        \r
+\r
         RouteGraph routeGraph = new RouteGraph();\r
         RouteTerminal a = addControlPoint(routeGraph, begin);\r
         RouteTerminal b = addControlPoint(routeGraph, end);\r
         routeGraph.link(a, b);\r
-        \r
-        // Route connection segments separately\r
-        /*Router2 router = ElementUtils.getHintOrDefault(diagram, DiagramHints.ROUTE_ALGORITHM, TrivialRouter2.INSTANCE);\r
-        final List<Segment> segments = toSegments(controlPoints);\r
-        //System.out.println("controlpoints: " + controlPoints);\r
-        //System.out.println("segments: " + segments);\r
-        router.route(new IConnection() {\r
-            @Override\r
-            public Collection<? extends Object> getSegments() {\r
-                return segments;\r
-            }\r
-\r
-            @Override\r
-            public Connector getBegin(Object seg) {\r
-                return getConnector(((Segment) seg).begin);\r
-            }\r
-\r
-            @Override\r
-            public Connector getEnd(Object seg) {\r
-                return getConnector(((Segment) seg).end);\r
-            }\r
-\r
-            private Connector getConnector(ControlPoint cp) {\r
-                Connector c = new Connector();\r
-                c.x = cp.getPosition().getX();\r
-                c.y = cp.getPosition().getY();\r
-\r
-                TerminalInfo ti = cp.getAttachedTerminal();\r
-                if (ti != null && (ti == startFlag || ti != endFlag)) {\r
-                    //System.out.println("CP1: " + cp);\r
-                    c.parentObstacle = DiagramUtils.getObstacleShape(ti.e);\r
-                    ConnectionDirectionUtil.determineAllowedDirections(c);\r
-                } else {\r
-                    //System.out.println("CP2: " + cp);\r
-                    c.parentObstacle = GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y),\r
-                            BranchPointClass.DEFAULT_IMAGE2.getBounds());\r
-                    c.allowedDirections = toAllowedDirections(cp.getDirection());\r
-                }\r
-\r
-                return c;\r
-            }\r
 \r
-            @Override\r
-            public void setPath(Object seg, Path2D path) {\r
-                ((Segment) seg).path = (Path2D) path.clone();\r
-            }\r
-\r
-            private int toAllowedDirections(BranchPoint.Direction direction) {\r
-                switch (direction) {\r
-                    case Any:\r
-                        return 0xf;\r
-                    case Horizontal:\r
-                        return Constants.EAST_FLAG | Constants.WEST_FLAG;\r
-                    case Vertical:\r
-                        return Constants.NORTH_FLAG | Constants.SOUTH_FLAG;\r
-                    default:\r
-                        throw new IllegalArgumentException("unrecognized direction: " + direction);\r
-                }\r
-            }\r
-        });\r
-\r
-        // Combine the routed paths\r
-        Path2D path = new Path2D.Double();\r
-        for (Segment seg : segments) {\r
-            //System.out.println("SEG: " + seg);\r
-            if (seg.path != null)\r
-                path.append(seg.path.getPathIterator(null), true);\r
-        }*/\r
-        \r
         Path2D path = routeGraph.getPath2D();\r
 \r
         // Create scene graph to visualize the connection.\r
         ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class);\r
         pathNode.setShape(path);\r
 \r
-        G2DParentNode points = ghostNode.getOrCreateNode("points", G2DParentNode.class);\r
-        HashSet<INode> unusedChildren = new HashSet<INode>(points.getNodes());\r
-        int i = 0;\r
-        for (ControlPoint cp : controlPoints) {\r
-            if (cp.isAttachedToTerminal())\r
-                continue;\r
-\r
-            String id = String.valueOf(i);\r
-            BranchPointNode bpn = points.getOrCreateNode(id, BranchPointNode.class);\r
-            bpn.setDegree(2);\r
-            bpn.setDirection((byte) cp.getDirection().ordinal());\r
-            bpn.setTransform(AffineTransform.getTranslateInstance(cp.getPosition().getX(), cp.getPosition().getY()));\r
-\r
-            ++i;\r
-            unusedChildren.remove(bpn);\r
-        }\r
-        for (INode unusedChild : unusedChildren)\r
-            points.removeNode(unusedChild);\r
-\r
         setDirty();\r
     }\r
 \r
@@ -668,12 +592,48 @@ public class ConnectTool2 extends AbstractMode {
 \r
                     // Make sure that we are ending with a flag if ALT is pressed\r
                     // and no end terminal is defined.\r
-                    endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me));\r
-\r
-                    updateSG();\r
+                    if (!endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)))\r
+                        updateSG();\r
                     return false;\r
                 }\r
             }\r
+        } else {\r
+            RouteGraphTarget cp = RouteGraphConnectTool.pickRouteGraphConnection(\r
+                    diagram,\r
+                    pi.getCanvasPickShape(me.controlPosition),\r
+                    pi.getPickDistance());\r
+            if (cp != null) {\r
+                // Remove branch point highlight from previously picked route graph.\r
+                if (lastRouteGraphTarget != null && cp.getNode() != lastRouteGraphTarget.getNode())\r
+                    cp.getNode().showBranchPoint(null);\r
+                lastRouteGraphTarget = cp;\r
+\r
+                // Validate connection before visualizing connectability\r
+                Point2D isectPos = cp.getIntersectionPosition();\r
+                TerminalInfo ti = TerminalInfo.create(\r
+                        isectPos,\r
+                        cp.getElement(),\r
+                        BranchPointTerminal.existingTerminal(\r
+                                isectPos,\r
+                                DirectionSet.ANY,\r
+                                BranchPointNode.SHAPE),\r
+                        BranchPointNode.SHAPE);\r
+                Pair<ConnectionJudgement, TerminalInfo> canConnect = canConnect(ti.e, ti.t);\r
+                if (canConnect != null) {\r
+                    connectionJudgment = canConnect.first;\r
+                    controlPoints.getLast().setPosition(ti.posDia).setAttachedToTerminal(ti);\r
+                    endTerminal = ti;\r
+                    cp.getNode().showBranchPoint(isectPos);\r
+                    if (!endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)))\r
+                        updateSG();\r
+                    return false;\r
+                }\r
+            } else {\r
+                if (lastRouteGraphTarget != null) {\r
+                    lastRouteGraphTarget.getNode().showBranchPoint(null);\r
+                    lastRouteGraphTarget = null;\r
+                }\r
+            }\r
         }\r
 \r
         connectionJudgment = null;\r
@@ -705,9 +665,8 @@ public class ConnectTool2 extends AbstractMode {
 \r
         // Make sure that we are ending with a flag if ALT is pressed and no end\r
         // terminal is defined.\r
-        endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me));\r
-\r
-        updateSG();\r
+        if (!endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)))\r
+            updateSG();\r
 \r
         return false;\r
     }\r
@@ -729,8 +688,13 @@ public class ConnectTool2 extends AbstractMode {
             if (snapAdvisor != null)\r
                 snapAdvisor.snap(mouseCanvasPos);\r
 \r
-            // Clicked on an allowed end terminal. End connection & end mode.\r
-            if (isEndTerminalDefined()) {\r
+            if (lastRouteGraphTarget != null) {\r
+                lastRouteGraphTarget.getNode().showBranchPoint(null);\r
+                attachToConnection();\r
+                remove();\r
+                return true;\r
+            } else if (isEndTerminalDefined()) {\r
+                // Clicked on an allowed end terminal. End connection & end mode.\r
                 createConnection();\r
                 remove();\r
                 return true;\r
@@ -772,6 +736,53 @@ public class ConnectTool2 extends AbstractMode {
         return false;\r
     }\r
 \r
+    private void attachToConnection() {\r
+        ConnectionJudgement judgment = this.connectionJudgment;\r
+        if (judgment == null) {\r
+            ErrorLogger.defaultLogError("Cannot attach to connection, no judgment available on connection validity", null);\r
+            return;\r
+        }\r
+\r
+        ConnectionBuilder builder = new ConnectionBuilder(this.diagram);\r
+        RouteGraph before = lastRouteGraphTarget.getNode().getRouteGraph();\r
+        THashMap<Object, Object> copyMap = new THashMap<>();\r
+        RouteGraph after = before.copy(copyMap);\r
+\r
+        RouteLine attachTo = (RouteLine) copyMap.get(lastRouteGraphTarget.getLine());\r
+        after.makePersistent(attachTo);\r
+        for (RouteLine line : after.getAllLines()) {\r
+            if (!line.isTransient() && line.isHorizontal() == attachTo.isHorizontal()\r
+                    && line.getPosition() == attachTo.getPosition()) {\r
+                attachTo = line;\r
+                break;\r
+            }\r
+        }\r
+        RouteLine attachToLine = attachTo;\r
+        RouteGraphDelta delta = new RouteGraphDelta(before, after);\r
+\r
+        Simantics.getSession().asyncRequest(new WriteRequest() {\r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                graph.markUndoPoint();\r
+                Resource connection = ElementUtils.getObject(endTerminal.e);\r
+                if (!delta.isEmpty()) {\r
+                    new RouteGraphConnection(graph, connection).synchronize(graph, before, after, delta);\r
+                }\r
+                Resource line = RouteGraphConnection.deserialize(graph, attachToLine.getData());\r
+                Deque<ControlPoint> cps = new ArrayDeque<>();\r
+                for (Iterator<ControlPoint> iterator = controlPoints.descendingIterator(); iterator.hasNext();)\r
+                    cps.add(iterator.next());\r
+                builder.attachToRouteGraph(graph, judgment, connection, line, cps, startTerminal, FlagClass.Type.In);\r
+            }\r
+        }, new Callback<DatabaseException>() {\r
+            @Override\r
+            public void run(DatabaseException parameter) {\r
+                if (parameter != null)\r
+                    ExceptionUtils.logAndShowError(parameter);\r
+            }\r
+        });\r
+    }\r
+\r
     protected boolean cancelPreviousBend() {\r
         if (!routePointsAllowed())\r
             return false;\r
@@ -912,10 +923,16 @@ public class ConnectTool2 extends AbstractMode {
         return endFlag != null;\r
     }\r
 \r
-    protected void endWithoutTerminal(Point2D mousePos, boolean altDown) {\r
+    /**\r
+     * @param mousePos\r
+     * @param altDown\r
+     * @return <code>true</code> if updateSG was executed, <code>false</code>\r
+     *         otherwise\r
+     */\r
+    protected boolean endWithoutTerminal(Point2D mousePos, boolean altDown) {\r
         // Just go with branch points if flags are not allowed.\r
         if (!createFlags)\r
-            return;\r
+            return false;\r
 \r
         boolean endTerminalDefined = isEndTerminalDefined();\r
 \r
@@ -931,6 +948,7 @@ public class ConnectTool2 extends AbstractMode {
                 setHint(TerminalPainter.TERMINAL_HOVER_STRATEGY, terminalHoverStrategy);\r
 \r
                 updateSG();\r
+                return true;\r
             }\r
         } else {\r
             if (isEndingInFlag()) {\r
@@ -954,8 +972,10 @@ public class ConnectTool2 extends AbstractMode {
                 setHint(TerminalPainter.TERMINAL_HOVER_STRATEGY, terminalHoverStrategy);\r
 \r
                 updateSG();\r
+                return true;\r
             }\r
         }\r
+        return false;\r
     }\r
 \r
     protected void createConnection() {\r
index 1fcf074cdf8c2863517aea5b22f225f265097764..b36961f87a589595d939d3045c0482bd3e71939c 100644 (file)
@@ -475,7 +475,8 @@ public class ConnectionBuilder {
             Resource attachToConnection,\r
             Resource attachToLine,\r
             Deque<ControlPoint> controlPoints,\r
-            TerminalInfo endTerminal)\r
+            TerminalInfo endTerminal,\r
+            FlagClass.Type flagType)\r
                     throws DatabaseException\r
     {\r
         initializeResources(graph);\r
@@ -502,9 +503,10 @@ public class ConnectionBuilder {
             if (endTerminal != null) {\r
                 endConnector = createConnectorForNode(graph, attachToConnection, endTerminal, EdgeEnd.End, judgment);\r
             } else if (createFlags) {\r
-                IElement endFlag = createFlag(graph, attachToConnection, EdgeEnd.End, controlPoints.getLast(), FlagClass.Type.Out, null);\r
+                EdgeEnd end = flagType == FlagClass.Type.In ? EdgeEnd.Begin : EdgeEnd.End;\r
+                IElement endFlag = createFlag(graph, attachToConnection, end, controlPoints.getLast(), flagType, null);\r
                 endConnector = createConnectorForNode(graph, attachToConnection, (Resource) ElementUtils.getObject(endFlag),\r
-                        ElementUtils.getSingleTerminal(endFlag), EdgeEnd.End, judgment);\r
+                        ElementUtils.getSingleTerminal(endFlag), end, judgment);\r
             }\r
 \r
             cu.connect(attachToLine, endConnector.getConnector());\r
index af1f48f5d89d42dc253257995bd09cc8cddacc25..57f5cd4900310263031a81d3227c99f355a25917 100644 (file)
@@ -763,7 +763,7 @@ public class RouteGraphConnectTool extends AbstractMode {
                     new RouteGraphConnection(graph, connection).synchronize(graph, rgs.first, rgs.second, rgs.third);\r
                 }\r
                 Resource attachToLine = RouteGraphConnection.deserialize(graph, attachedToRouteLine.getData());\r
-                builder.attachToRouteGraph(graph, judgment, connection, attachToLine, controlPoints, endTerminal);\r
+                builder.attachToRouteGraph(graph, judgment, connection, attachToLine, controlPoints, endTerminal, FlagClass.Type.Out);\r
             }\r
         }, new Callback<DatabaseException>() {\r
             @Override\r
index bb85be21fe878143cb864547df0576043625efc3..c4b83aa994c3c3c9585b39f3a503fd28b9b95416 100644 (file)
@@ -1,10 +1,12 @@
 package org.simantics.event.util;\r
 \r
+import java.util.List;\r
 import java.util.UUID;\r
 \r
 import org.simantics.databoard.Bindings;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.PossibleTypedParent;\r
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.event.ontology.EventResource;\r
 import org.simantics.layer0.Layer0;\r
@@ -25,5 +27,46 @@ public class EventUtils {
         graph.claimLiteral(log, EVENT.HasModificationCounter, 0, Bindings.INTEGER);\r
         return log;\r
        }\r
-       \r
+\r
+    /**\r
+     * Bumps the modification counter value of the event log of the specified\r
+     * events using {@link #bumpModificationCounter(WriteGraph, Resource)}.\r
+     * <p>\r
+     * The code assumes that all events are from the same log.\r
+     * \r
+     * @param graph\r
+     * @param forLogOfEvents\r
+     * @throws DatabaseException\r
+     */\r
+    public static void bumpModificationCounter(WriteGraph graph, List<Resource> forLogOfEvents) throws DatabaseException {\r
+        EventResource EVENT = EventResource.getInstance(graph);\r
+        for (Resource event : forLogOfEvents) {\r
+            Resource log = graph.syncRequest(new PossibleTypedParent(event, EVENT.EventLog));\r
+            if (log != null) {\r
+                bumpModificationCounter(graph, log);\r
+                return;\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Bumps the modification counter of the specified event log by 1.\r
+     * \r
+     * @param graph\r
+     * @param eventLog\r
+     * @return new modification counter value\r
+     * @throws DatabaseException\r
+     */\r
+    public static int bumpModificationCounter(WriteGraph graph, Resource eventLog) throws DatabaseException {\r
+        EventResource EVENT = EventResource.getInstance(graph);\r
+        Resource counter = graph.getPossibleObject(eventLog, EVENT.HasModificationCounter);\r
+        if (counter != null) {\r
+            Integer c = graph.getValue(counter, Bindings.INTEGER);\r
+            c = c == null ? 1 : c+1;\r
+            graph.claimValue(counter, c, Bindings.INTEGER);\r
+            return c;\r
+        }\r
+        return 0;\r
+    }\r
+\r
 }\r
index e6e59966c37f7d0a15696d6d7d53e369f048ff6e..9b9ea8bfe07437702a1403ce715e567d33637595 100644 (file)
@@ -116,20 +116,25 @@ public enum ProjectEventsRule implements ChildRule {
             if (!showHiddenEvents && graph.hasStatement(event, EVENT.Hidden))\r
                 continue;\r
 \r
+            boolean isReturnEvent = hideReturnEvents || showOnlyActiveEvents\r
+                    ? graph.hasStatement(event, EVENT.ReturnEvent) : false;\r
+\r
+            // Skip all return events if thus preferred.\r
+            if (hideReturnEvents && isReturnEvent) {\r
+                continue;\r
+            }\r
+\r
+            // Skip all return events and starting events that have been returned,\r
+            // if thus preferred. Also skip events that are defined non-returnable.\r
             if (showOnlyActiveEvents\r
-                    && (graph.hasStatement(event, EVENT.Returns)\r
+                    && (isReturnEvent\r
+                            || graph.hasStatement(event, EVENT.Returns)\r
                             || graph.hasStatement(event, EVENT.ReturnedBy)\r
                             || graph.hasStatement(event, EVENT.NoReturn)))\r
             {\r
                 continue;\r
             }\r
 \r
-            // Skip return events if thus preferred.\r
-            if (hideReturnEvents && graph.hasStatement(event, EVENT.ReturnEvent)) {\r
-                if (graph.getPossibleObject(event, EVENT.Returns) != null)\r
-                    continue;\r
-            }\r
-\r
             // Filter by event type severity\r
             Resource eventType = graph.getPossibleObject(event, EVENT.Event_type);\r
             if (eventType != null) {\r
diff --git a/bundles/org.simantics.event/src/org/simantics/event/view/handler/Hide.java b/bundles/org.simantics.event/src/org/simantics/event/view/handler/Hide.java
deleted file mode 100644 (file)
index 778c5fb..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*******************************************************************************\r
- * Copyright (c) 2007, 2011 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.event.view.handler;\r
-\r
-import org.simantics.event.ontology.EventResource;\r
-\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class Hide extends PreferenceHandler {\r
-\r
-    public Hide() {\r
-        super("experiments", EventResource.URIs.Hidden, true);\r
-    }\r
-\r
-}\r
index ddd70fb7fa6d46add38bf7a0b99c6268e20a15d1..9b125ed446342deb269dd77ec5b2c02517ba9074 100644 (file)
@@ -24,6 +24,7 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.SelectionHints;\r
 import org.simantics.event.Activator;\r
 import org.simantics.event.ontology.EventResource;\r
+import org.simantics.event.util.EventUtils;\r
 import org.simantics.ui.contribution.DynamicMenuContribution;\r
 import org.simantics.ui.workbench.action.PerformDefaultAction;\r
 import org.simantics.utils.ui.ISelectionUtils;\r
@@ -147,13 +148,17 @@ public class MenuActions extends DynamicMenuContribution {
     }\r
 \r
     private IAction hideAction(List<Resource> input) {\r
-        return tagAction("Hide", Activator.HIDE_ICON, EventResource.URIs.Hidden, true, input);\r
+        return contentChangingTagAction("Hide", Activator.HIDE_ICON, EventResource.URIs.Hidden, true, input);\r
     }\r
 \r
     private IAction tagAction(String label, ImageDescriptor image, String tagURI, boolean tag, List<Resource> input) {\r
         return new TagAction(label, image, VG_EXPERIMENTS, tagURI, tag, input);\r
     }\r
 \r
+    private IAction contentChangingTagAction(String label, ImageDescriptor image, String tagURI, boolean tag, List<Resource> input) {\r
+        return new ContentChangingTagAction(label, image, VG_EXPERIMENTS, tagURI, tag, input);\r
+    }\r
+\r
     private IAction setBaseline(Resource eventLog, Resource event) {\r
         return new SetBaseline(VG_EXPERIMENTS, eventLog, event);\r
     }\r
@@ -169,6 +174,17 @@ public class MenuActions extends DynamicMenuContribution {
         return new PerformDefaultAction(title, null, input);\r
     }\r
 \r
+    private static class ContentChangingTagAction extends TagAction {\r
+        public ContentChangingTagAction(String label, ImageDescriptor image, String virtualGraphId, String tagURI, boolean tag, List<Resource> input) {\r
+            super(label, image, virtualGraphId, tagURI, tag, input);\r
+        }\r
+\r
+        @Override\r
+        public void postTagWrite(WriteGraph graph) throws DatabaseException {\r
+            EventUtils.bumpModificationCounter(graph, resources);\r
+        }\r
+    }\r
+\r
     private static class ToClipboardAction extends Action {\r
         private String text;\r
 \r
index 0de441539f55d7a2293eab8ff09b48e13f4902af..3491e29f05ee9870c94ef45550d467a53282846f 100644 (file)
@@ -22,7 +22,7 @@ public class TagAction extends Action {
     private final String virtualGraphId;\r
     private final String tagURI;\r
     private final boolean tag;\r
-    private final List<Resource> resources;\r
+    protected final List<Resource> resources;\r
 \r
     /**\r
      * @param label\r
index a28cfa56360230f754c5c3b7359b5d1c3250153c..409af79d69e4e0febb7fd69375ccb8f76d867fe1 100644 (file)
@@ -78,6 +78,17 @@ public class TerminalUtil {
             .append(']');\r
             return sb.toString();\r
         }\r
+\r
+        public static TerminalInfo create(Point2D p, IElement e, Terminal t, Shape terminalShape) {\r
+            AffineTransform at = AffineTransform.getTranslateInstance(p.getX(), p.getY());\r
+            TerminalInfo ti = new TerminalInfo();\r
+            ti.e = e;\r
+            ti.t = t;\r
+            ti.posElem = at;\r
+            ti.posDia = at;\r
+            ti.shape = terminalShape;\r
+            return ti;\r
+        }\r
     }\r
     private static final Rectangle2D POINT_PICK_SHAPE = new Rectangle2D.Double(0, 0, 0.001, 0.001);\r
 \r
index bce157dd5d035d3768e1359ddb14c32b0dd1ca8c..3ad4a9f7502a61b73a4a3ff4db097b9aa4c91e68 100644 (file)
@@ -13,6 +13,7 @@ package org.simantics.g2d.element.handler.impl;
 \r
 import java.awt.Shape;\r
 import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Point2D;\r
 \r
 import org.simantics.g2d.utils.geom.DirectionSet;\r
 \r
@@ -39,4 +40,8 @@ public class BranchPointTerminal extends ObjectTerminal {
         return new BranchPointTerminal(EXISTING_BRANCH_POINT_DATA, transform, ds, shape);\r
     }\r
 \r
+    public static BranchPointTerminal existingTerminal(Point2D p, DirectionSet ds, Shape shape) {\r
+        return existingTerminal(AffineTransform.getTranslateInstance(p.getX(), p.getY()), ds, shape);\r
+    }\r
+\r
 }
\ No newline at end of file
index 34b1a635d766070867e0a3d2b3170305d0387e5f..e231476acfb00ead8f00699ca7f967e8f372ab25 100644 (file)
@@ -11,8 +11,6 @@
  *******************************************************************************/\r
 package org.simantics.scenegraph.g2d.nodes.connection;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import java.awt.BasicStroke;\r
 import java.awt.Color;\r
 import java.awt.Graphics2D;\r
@@ -31,7 +29,6 @@ import java.util.Map;
 import org.simantics.diagram.connection.RouteGraph;\r
 import org.simantics.diagram.connection.RouteLine;\r
 import org.simantics.diagram.connection.RouteLink;\r
-import org.simantics.diagram.connection.RoutePoint;\r
 import org.simantics.diagram.connection.RouteTerminal;\r
 import org.simantics.diagram.connection.actions.IAction;\r
 import org.simantics.diagram.connection.actions.IReconnectAction;\r
@@ -69,6 +66,8 @@ import org.simantics.scenegraph.utils.GeometryUtils;
 import org.simantics.scenegraph.utils.InitValueSupport;\r
 import org.simantics.scenegraph.utils.NodeUtil;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 /**\r
  * @author Tuukka Lehtonen\r
  */\r
@@ -312,6 +311,10 @@ public class RouteGraphNode extends G2DNode implements ISelectionPainterNode, In
         }\r
     }\r
 \r
+    public void showBranchPoint(Point2D p) {\r
+        newBranchPointPosition = p;\r
+    }\r
+\r
     @Override\r
     public void init() {\r
         super.init();\r
index a45edf0eef1c1e2f2fa2a28ec1a5449f76c71530..c79602c1bde88010b6a9f5706bab6e1425aac46c 100644 (file)
@@ -199,6 +199,8 @@ public class StandardModelingRules extends AbstractModelingRules {
                boolean legal = true;\r
                for (Resource constraint : g.getObjects(connectionType, STR.HasConnectionConstraint)) {\r
                        IConnectionConstraint cc = g.adapt(constraint, IConnectionConstraint.class);\r
+                       if(Policy.DEBUG_STANDARD_MODELING_RULES)\r
+                               System.out.println("Checking " + cc.getClass().getSimpleName());\r
                        switch(cc.isLegal(g, terminals)) {\r
                        case ILLEGAL:\r
                                if(Policy.DEBUG_STANDARD_MODELING_RULES)\r