boolean external = FlagUtil.isExternal(graph, flag);\r
boolean inSingleDiagram = FlagUtil.isJoinedInSingleDiagram(graph, flag);\r
if (!external && inSingleDiagram) {\r
+ // FIXME: this doesn't take into account local merged flags, which is a corner case but still possible\r
Resource counterpart = FlagUtil.getPossibleCounterpart(graph, flag);\r
if (selectedFlags.containsKey(counterpart)) {\r
flagSelectedCounterpart.put(flag, counterpart);\r
Resource dst = (Resource) resourceMap.get(src);\r
for (Resource connectedToSrc : graph.getObjects(src, DIA.AreConnected)) {\r
Resource connectedToDst = (Resource) resourceMap.get(connectedToSrc);\r
- graph.claim(dst, DIA.AreConnected, DIA.AreConnected, connectedToDst);\r
+ if (connectedToDst != null) {\r
+ graph.claim(dst, DIA.AreConnected, DIA.AreConnected, connectedToDst);\r
+ } else {\r
+ throw new DatabaseException("Connection copying failed due to an invalid DIA.AreConnected link between source resources " + src + " <-> " + connectedToSrc);\r
+ }\r
}\r
}\r
for (Statement hasConnector : sourceHasConnectors) {\r
import org.simantics.scenegraph.utils.GeometryUtils;\r
import org.simantics.scenegraph.utils.Quality;\r
import org.simantics.structural2.modelingRules.ConnectionJudgement;\r
-import org.simantics.utils.datastructures.Callback;\r
import org.simantics.utils.datastructures.Pair;\r
import org.simantics.utils.logging.TimeLogger;\r
import org.simantics.utils.ui.ErrorLogger;\r
*/\r
protected ConnectionJudgement connectionJudgment;\r
\r
+ /**\r
+ * The latest connectability judgment from the active\r
+ * {@link IConnectionAdvisor} should the connection happen between\r
+ * {@link #selectedStartTerminal} and {@link #lastRouteGraphTarget}.\r
+ */\r
+ protected ConnectionJudgement attachToConnectionJudgement;\r
+\r
/**\r
* If non-null during connection drawing this field tells the direction\r
* forced for the current branch point by the user through the UI commands\r
updateSG();\r
}\r
\r
- static class Segment {\r
- public final ControlPoint begin;\r
- public final ControlPoint end;\r
- public Path2D path;\r
-\r
- public Segment(ControlPoint begin, ControlPoint end) {\r
- this.begin = begin;\r
- this.end = end;\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- return "Segment[begin=" + begin + ", end=" + end + ", path=" + path + "]";\r
- }\r
- }\r
-\r
private RouteTerminal addControlPoint(RouteGraph routeGraph, ControlPoint cp) {\r
TerminalInfo ti = cp.getAttachedTerminal();\r
if(ti != null && ti != startFlag && ti != endFlag) {\r
return elementParent;\r
}\r
\r
- private List<Segment> toSegments(Deque<ControlPoint> points) {\r
- if (points.isEmpty())\r
- return Collections.emptyList();\r
-\r
- List<Segment> segments = new ArrayList<Segment>();\r
-\r
- Iterator<ControlPoint> it = points.iterator();\r
- ControlPoint prev = it.next();\r
- while (it.hasNext()) {\r
- ControlPoint next = it.next();\r
- segments.add(new Segment(prev, next));\r
- prev = next;\r
- }\r
-\r
- return segments;\r
- }\r
-\r
@SGCleanup\r
public void cleanupSG() {\r
ghostNode.remove();\r
BranchPointNode.SHAPE);\r
Pair<ConnectionJudgement, TerminalInfo> canConnect = canConnect(ti.e, ti.t);\r
if (canConnect != null) {\r
- connectionJudgment = canConnect.first;\r
+ attachToConnectionJudgement = canConnect.first;\r
controlPoints.getLast().setPosition(ti.posDia).setAttachedToTerminal(ti);\r
endTerminal = ti;\r
cp.getNode().showBranchPoint(isectPos);\r
}\r
\r
connectionJudgment = null;\r
+ attachToConnectionJudgement = null;\r
if (isEndTerminalDefined()) {\r
// CASE: Mouse was previously on top of a valid terminal to end\r
// the connection. Now the mouse has been moved where there is\r
if (snapAdvisor != null)\r
snapAdvisor.snap(mouseCanvasPos);\r
\r
- if (lastRouteGraphTarget != null) {\r
- lastRouteGraphTarget.getNode().showBranchPoint(null);\r
- attachToConnection();\r
- remove();\r
- return true;\r
- } else if (isEndTerminalDefined()) {\r
+ if (isEndTerminalDefined() && connectionJudgment != null) {\r
// Clicked on an allowed end terminal. End connection & end mode.\r
createConnection();\r
remove();\r
return true;\r
+ } else if (lastRouteGraphTarget != null && attachToConnectionJudgement != null) {\r
+ lastRouteGraphTarget.getNode().showBranchPoint(null);\r
+ attachToConnection();\r
+ remove();\r
+ return true;\r
} else {\r
// Finish connection in thin air only if the\r
// connection was started from a valid terminal.\r
}\r
\r
private void attachToConnection() {\r
- ConnectionJudgement judgment = this.connectionJudgment;\r
+ ConnectionJudgement judgment = this.attachToConnectionJudgement;\r
if (judgment == null) {\r
ErrorLogger.defaultLogError("Cannot attach to connection, no judgment available on connection validity", null);\r
return;\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
+ }, parameter -> {\r
+ if (parameter != null)\r
+ ExceptionUtils.logAndShowError(parameter);\r
});\r
}\r
\r
public void perform(WriteGraph graph) throws DatabaseException {\r
builder.create(graph, judgement, controlPoints, startTerminal, endTerminal);\r
}\r
- }, new Callback<DatabaseException>() {\r
- @Override\r
- public void run(DatabaseException parameter) {\r
- if (parameter != null)\r
- ExceptionUtils.logAndShowError(parameter);\r
- }\r
+ }, parameter -> {\r
+ if (parameter != null)\r
+ ExceptionUtils.logAndShowError(parameter);\r
});\r
}\r
\r