diff options
| author | jmallet | 2017-06-22 16:17:47 +0000 |
|---|---|---|
| committer | Laurent Fasani | 2017-07-13 12:54:41 +0000 |
| commit | b6d7191463b338113b59495b568161bb0120baf3 (patch) | |
| tree | fbc472a5b8123fece0fb5cc75070a2c730b8a023 | |
| parent | c3d6e8c5e6b0e5834a7ed9a0faf9cdff28d60d4e (diff) | |
| download | org.eclipse.sirius-b6d7191463b338113b59495b568161bb0120baf3.tar.gz org.eclipse.sirius-b6d7191463b338113b59495b568161bb0120baf3.tar.xz org.eclipse.sirius-b6d7191463b338113b59495b568161bb0120baf3.zip | |
[518651] Rectilinear Edge creation with bendpoints computed according to
anchor.
- When user wanted to create new rectilinear edge including creation of
border node as source and target (or something else), bendpoints were
not correct.
Now, bendpoints are computed according to center anchor position.
- SlidableAnchor constructor has been fixed to create new
SlidableAnchor with relative bendpoints (as defined in method signature)
and not with absolute bendpoints.
Bug: 518651
Change-Id: Idac7dc89ed37bdb657b1cd1bbd68f4bc55361114
Signed-off-by: jmallet <jessy.mallet@obeo.fr>
5 files changed, 182 insertions, 11 deletions
diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/diagram/ConnectionsFactory.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/diagram/ConnectionsFactory.java index b5b25e0b74..639628c99c 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/diagram/ConnectionsFactory.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/diagram/ConnectionsFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2015 THALES GLOBAL SERVICES and others. + * Copyright (c) 2011, 2017 THALES GLOBAL SERVICES and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -42,6 +42,7 @@ import org.eclipse.sirius.diagram.CenterLabelStyle; import org.eclipse.sirius.diagram.DEdge; import org.eclipse.sirius.diagram.DiagramPlugin; import org.eclipse.sirius.diagram.EdgeTarget; +import org.eclipse.sirius.diagram.description.CenteringStyle; import org.eclipse.sirius.diagram.ui.business.api.query.EdgeQuery; import org.eclipse.sirius.diagram.ui.business.api.view.SiriusLayoutDataManager; import org.eclipse.sirius.diagram.ui.business.internal.view.EdgeLayoutData; @@ -51,8 +52,10 @@ import org.eclipse.sirius.diagram.ui.internal.refresh.edge.SlidableAnchor; import org.eclipse.sirius.diagram.ui.part.SiriusLinkDescriptor; import org.eclipse.sirius.diagram.ui.provider.DiagramUIPlugin; import org.eclipse.sirius.diagram.ui.provider.Messages; +import org.eclipse.sirius.diagram.ui.tools.internal.routers.RectilinearEdgeUtil; import org.eclipse.sirius.diagram.ui.tools.internal.util.GMFNotationUtilities; import org.eclipse.sirius.ext.base.Option; +import org.eclipse.sirius.ext.gmf.runtime.editparts.GraphicalHelper; /** * Specific factory for {@link Edge} used by the @@ -251,14 +254,32 @@ public class ConnectionsFactory { // Computes pointList PrecisionPoint sourceRelativeReference = SlidableAnchor.parseTerminalString(sourceTerminal); SlidableAnchor sourceAnchor = new SlidableAnchor(source, sourceRelativeReference); - pointList.addPoint(sourceAnchor.getLocation(sourceAnchor.getReferencePoint())); + sourceRefPoint = sourceAnchor.getLocation(sourceAnchor.getReferencePoint()); PrecisionPoint targetRelativeReference = SlidableAnchor.parseTerminalString(targetTerminal); SlidableAnchor targetAnchor = new SlidableAnchor(target, targetRelativeReference); - pointList.addPoint(targetAnchor.getLocation(targetAnchor.getReferencePoint())); + targetRefPoint = targetAnchor.getLocation(targetAnchor.getReferencePoint()); + + + Option<Point> srcConnectionBendpoint = GraphicalHelper.getIntersection(sourceRefPoint, targetRefPoint, optionalSourceBounds.get(), true); + Option<Point> tgtConnectionBendpoint = GraphicalHelper.getIntersection(sourceRefPoint, targetRefPoint, optionaltargetBounds.get(), false); + + if (srcConnectionBendpoint.some() && tgtConnectionBendpoint.some()) { + pointList.addPoint(srcConnectionBendpoint.get()); + pointList.addPoint(tgtConnectionBendpoint.get()); + EdgeQuery edgeQuery = new EdgeQuery(edge); + if (edgeQuery.isEdgeWithRectilinearRoutingStyle()) { + RectilinearEdgeUtil.centerEdgeEnds(pointList, sourceRefPoint, targetRefPoint, CenteringStyle.BOTH); + } + } else { + // no intersection found, case when source and target are overlapped + pointList.addPoint(sourceRefPoint); + pointList.addPoint(targetRefPoint); + } } } } + pointList = RectilinearEdgeUtil.normalizeToStraightLineTolerance(pointList, 2); } /** diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/edge/SlidableAnchor.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/edge/SlidableAnchor.java index c04d85f2ed..0d3c555a11 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/edge/SlidableAnchor.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/edge/SlidableAnchor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2016 THALES GLOBAL SERVICES. + * Copyright (c) 2011, 2017 THALES GLOBAL SERVICES. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -17,7 +17,6 @@ import org.eclipse.draw2d.geometry.PrecisionPoint; import org.eclipse.draw2d.geometry.PrecisionRectangle; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gmf.runtime.common.core.util.StringStatics; -import org.eclipse.gmf.runtime.draw2d.ui.figures.BaseSlidableAnchor; import org.eclipse.gmf.runtime.draw2d.ui.geometry.LineSeg; import org.eclipse.gmf.runtime.draw2d.ui.geometry.PointListUtilities; import org.eclipse.gmf.runtime.notation.Bounds; @@ -84,7 +83,7 @@ public class SlidableAnchor { */ public SlidableAnchor(View owner, PrecisionPoint relativeReference) { this.owner = owner; - this.relativeReference = BaseSlidableAnchor.getAnchorRelativeLocation(relativeReference, getBox()); + this.relativeReference = relativeReference; } /** diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/routers/RectilinearEdgeUtil.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/routers/RectilinearEdgeUtil.java index 5ce9d4ba43..9edeea21dd 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/routers/RectilinearEdgeUtil.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/routers/RectilinearEdgeUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014 THALES GLOBAL SERVICES and others. + * Copyright (c) 2014, 2017 THALES GLOBAL SERVICES and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -371,4 +371,45 @@ public final class RectilinearEdgeUtil { return null; } } + + /** + * Goes through line segments of a polyline and makes strict straight segments from nearly straight segments. + * Then remove also unnecessary points. + * + * @param line + * polyline to straight + * @param tolerance + * tolerance value specifying nearly straight lines. + * @return the line made straight with only necessary points + */ + public static PointList normalizeToStraightLineTolerance(PointList line, int tolerance) { + // straight edge + for (int i = 0; i < line.size() - 1; i++) { + Point pt1 = line.getPoint(i); + Point pt2 = line.getPoint(i + 1); + if (Math.abs(pt1.y - pt2.y) < tolerance) { + line.setPoint(new Point(pt2.x, pt1.y), i + 1); + } else if (Math.abs(pt1.x - pt2.x) < tolerance) { + line.setPoint(new Point(pt1.x, pt2.y), i + 1); + } + } + // delete unnecessary points + PointList newLine = new PointList(); + newLine.addPoint(line.getPoint(0)); + if (line.size() > 2) { + for (int i = 1; i < line.size() - 1; i++) { + Point pt1 = line.getPoint(i - 1); + Point pt2 = line.getPoint(i); + Point pt3 = line.getPoint(i + 1); + if ((pt1.x == pt2.x && pt3.x == pt2.x) || (pt1.y == pt2.y && pt3.y == pt2.y)) { + // three point are aligned horizontally or vertically + // point is not necessary + } else { + newLine.addPoint(pt2); + } + } + } + newLine.addPoint(line.getPoint(line.size() - 1)); + return newLine; + } } diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/AbstractSiriusSwtBotGefTestCase.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/AbstractSiriusSwtBotGefTestCase.java index 39412d8476..d97360eae7 100644 --- a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/AbstractSiriusSwtBotGefTestCase.java +++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/AbstractSiriusSwtBotGefTestCase.java @@ -624,6 +624,30 @@ public abstract class AbstractSiriusSwtBotGefTestCase extends SWTBotGefTestCase protected void launchCancelCustomStyle() { bot.buttonWithTooltip("Cancel custom style").click(); } + + /** + * Change a preference and store the old value. It will be automatically + * reset during tear down. + * + * TO CALL ONLY ONCE PER TEST (set up + test) + * + * @param preferenceKey + * The key of the preference. + * @param newValue + * The new value. + */ + protected void changeDiagramPreference(String preferenceKey, Integer newValue) { + assertNoDiagramUIPreferenceChangedinDiagramCoreStore(preferenceKey); + + int oldValue = Platform.getPreferencesService().getInt(DiagramPlugin.ID, preferenceKey, 0, null); + oldValueDiagramPreferences.put(preferenceKey, oldValue); + + IEclipsePreferences diagramCorePreferences = InstanceScope.INSTANCE.getNode(DiagramPlugin.ID); + diagramCorePreferences.putInt(preferenceKey, newValue); + + int valueToCheck = Platform.getPreferencesService().getInt(DiagramPlugin.ID, preferenceKey, 0, null); + TestCase.assertEquals(getErrorMessage(preferenceKey, DiagramPlugin.ID), newValue.intValue(), valueToCheck); + } /** * Change a boolean preference and store the old value. It will be diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/EdgeCreationPositionTest.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/EdgeCreationPositionTest.java index 94e2560bf0..91df4969e9 100644 --- a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/EdgeCreationPositionTest.java +++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/EdgeCreationPositionTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES. + * Copyright (c) 2010, 2017 THALES GLOBAL SERVICES. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,9 @@ *******************************************************************************/ package org.eclipse.sirius.tests.swtbot; +import java.util.List; + +import org.eclipse.draw2d.Bendpoint; import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.geometry.Dimension; @@ -24,6 +27,8 @@ import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.gef.ui.figures.SlidableAnchor; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.sirius.diagram.DDiagram; +import org.eclipse.sirius.diagram.EdgeRouting; +import org.eclipse.sirius.diagram.tools.api.preferences.SiriusDiagramCorePreferences; import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramBorderNodeEditPart; import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramContainerEditPart; import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramListEditPart; @@ -37,6 +42,8 @@ import org.eclipse.sirius.tests.swtbot.support.api.business.UIResource; import org.eclipse.sirius.tests.swtbot.support.api.condition.OperationDoneCondition; import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotSiriusDiagramEditor; import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils; +import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefConnectionEditPart; +import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart; import org.eclipse.swtbot.swt.finder.SWTBot; import org.eclipse.swtbot.swt.finder.waits.ICondition; @@ -55,6 +62,8 @@ public class EdgeCreationPositionTest extends AbstractSiriusSwtBotGefTestCase { private static final PrecisionPoint TOP_LEFT_CORNER = new PrecisionPoint(0.1, 0.1); private static final PrecisionPoint BOTTOM_RIGHT_CORNER = new PrecisionPoint(0.9, 0.9); + + private static final PrecisionPoint BOTTOM_LEFT_CORNER = new PrecisionPoint(0.1, 0.9); private static final String MODEL = "tc-2185.ecore"; @@ -116,6 +125,16 @@ public class EdgeCreationPositionTest extends AbstractSiriusSwtBotGefTestCase { public void test_Container() { createEdgeAndValidateAnchors("Container", "A", AbstractDiagramContainerEditPart.class, "B", AbstractDiagramContainerEditPart.class); } + + /** + * Test Bendpoints of an edge created with border Node as source and target. + */ + public void test_BorderedEdgeAndContainer() { + changeDiagramPreference(SiriusDiagramCorePreferences.PREF_ENABLE_OVERRIDE, true); + changeDiagramPreference(SiriusDiagramCorePreferences.PREF_LINE_STYLE, EdgeRouting.MANHATTAN); + createBorderedEdgeAndValidateAnchors("Container", "A", AbstractDiagramContainerEditPart.class, "B", + AbstractDiagramContainerEditPart.class); + } /** * Same as test_Container() but with specific location that reveals a bug @@ -249,7 +268,7 @@ public class EdgeCreationPositionTest extends AbstractSiriusSwtBotGefTestCase { openDiagram(diagramName, zoomLevel); IGraphicalEditPart sourcePart = (IGraphicalEditPart) editor.getEditPart(sourceName, expectedSourceType).part(); IGraphicalEditPart targetPart = (IGraphicalEditPart) editor.getEditPart(targetName, expectedTargetType).part(); - createEdge(sourcePart, sourcePosition, targetPart, targetPosition); + createEdge(sourcePart, sourcePosition, targetPart, targetPosition, getCreateEdgeToolName()); DEdgeEditPart edge = getSingleDEdgeFrom((NodeEditPart) sourcePart); assertAreValidAnchors(sourcePart, targetPart, edge); if (!ZoomLevel.ZOOM_100.equals(zoomLevel)) { @@ -258,6 +277,43 @@ public class EdgeCreationPositionTest extends AbstractSiriusSwtBotGefTestCase { } } + /** + * Open the diagram <code>diagramName</code>, create an edge between + * <code>sourceName</code> and <code>targetName</code> including border + * Node creation and validate the source and target anchors. + * + * @param diagramName + * The name of the diagram to open + * @param sourceName + * The name of the source + * @param expectedSourceType + * The type of the expected source edit part + * @param targetName + * The name of the target + * @param expectedTargetType + * The type of the expected target edit part + */ + private void createBorderedEdgeAndValidateAnchors(String diagramName, String sourceName, + Class<? extends EditPart> expectedSourceType, String targetName, + Class<? extends EditPart> expectedTargetType) { + openDiagram(diagramName); + IGraphicalEditPart sourcePart = (IGraphicalEditPart) editor.getEditPart(sourceName, expectedSourceType).part(); + IGraphicalEditPart targetPart = (IGraphicalEditPart) editor.getEditPart(targetName, expectedTargetType).part(); + createEdge(sourcePart, BOTTOM_RIGHT_CORNER, targetPart, BOTTOM_LEFT_CORNER, getCreateBorderEdgeToolName()); + + List<SWTBotGefConnectionEditPart> connectionsEditPart = editor.getConnectionsEditPart(); + assertEquals(1, connectionsEditPart.size()); + SWTBotGefConnectionEditPart conection = connectionsEditPart.get(0); + assertTrue(conection.part() instanceof DEdgeEditPart); + DEdgeEditPart edge = (DEdgeEditPart) conection.part(); + + SWTBotGefEditPart borderSource = conection.source(); + SWTBotGefEditPart borderTarget = conection.target(); + + assertAreValidAnchorsAndBendpoints((IGraphicalEditPart) borderSource.part(), + (IGraphicalEditPart) borderTarget.part(), edge); + } + /** */ public void test_Node_then_Container() { test_Node(); @@ -274,6 +330,20 @@ public class EdgeCreationPositionTest extends AbstractSiriusSwtBotGefTestCase { * Edge to consider */ protected void assertAreValidAnchors(IGraphicalEditPart source, IGraphicalEditPart target, DEdgeEditPart edge) { + assertAreValidAnchorsAndBendpoints(source, target, edge); + } + + /** + * Check that anchor of edge are valid and bend-points of edge are consistent with draw2D points. + * + * @param source + * The source of the edge + * @param target + * The target of the edge + * @param edge + * Edge to consider + */ + protected void assertAreValidAnchorsAndBendpoints(IGraphicalEditPart source, IGraphicalEditPart target, DEdgeEditPart edge) { assertIsValidAnchor((NodeEditPart) source, edge, true); assertIsValidAnchor((NodeEditPart) target, edge, false); @@ -310,7 +380,14 @@ public class EdgeCreationPositionTest extends AbstractSiriusSwtBotGefTestCase { assertTrue("Intersection should exist between target and edge : " + GraphicalHelper.getAbsoluteBoundsIn100Percent(target) + " and " + sourcePoint + "-->" + targetPoint, targetIntersection.some()); + // GMF bendpoints + @SuppressWarnings("unchecked") + List<Bendpoint> routingConstraint = (List<Bendpoint>) connectionFigure.getRoutingConstraint(); + // Draw 2D bendpoints PointList figurePoints = connectionFigure.getPoints(); + + assertEquals("Bad number of bendpoints after edge creation", routingConstraint.size(), figurePoints.size()); + assertEquals("Wrong x coordinate for source.", sourceIntersection.get().x, figurePoints.getFirstPoint().x, 1); assertEquals("Wrong y coordinate for source.", sourceIntersection.get().y, figurePoints.getFirstPoint().y, 1); assertEquals("Wrong x coordinate for target.", targetIntersection.get().x, figurePoints.getLastPoint().x, 1); @@ -352,12 +429,12 @@ public class EdgeCreationPositionTest extends AbstractSiriusSwtBotGefTestCase { return (DEdgeEditPart) edge; } - private void createEdge(IGraphicalEditPart source, PrecisionPoint sourcePosition, IGraphicalEditPart target, PrecisionPoint targetPosition) { + private void createEdge(IGraphicalEditPart source, PrecisionPoint sourcePosition, IGraphicalEditPart target, PrecisionPoint targetPosition, String toolName) { Point sourcePoint = getProportionalPoint(GraphicalHelper.getAbsoluteBounds(source), sourcePosition); Point targetPoint = getProportionalPoint(GraphicalHelper.getAbsoluteBounds(target), targetPosition); ICondition done = new OperationDoneCondition(); - editor.activateTool(getCreateEdgeToolName()); + editor.activateTool(toolName); editor.click(sourcePoint, true); editor.click(targetPoint, true); SWTBotUtils.waitAllUiEvents(); @@ -372,6 +449,15 @@ public class EdgeCreationPositionTest extends AbstractSiriusSwtBotGefTestCase { protected String getCreateEdgeToolName() { return "Super"; } + + /** + * Return the name of the create border edge tool to use. + * + * @return the name of the create edge tool to use. + */ + protected String getCreateBorderEdgeToolName() { + return "SuperWithBorderNode"; + } private Point getProportionalPoint(Rectangle bounds, PrecisionPoint proportions) { Point result = bounds.getTopLeft().getCopy(); |
