package org.eclipse.gmf.tooling.runtime.linklf.policies; import java.util.Collection; import java.util.LinkedList; import java.util.List; import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.ConnectionRouter; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.commands.Command; import org.eclipse.gef.requests.ChangeBoundsRequest; import org.eclipse.gmf.runtime.common.core.command.ICommand; import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart; import org.eclipse.gmf.runtime.draw2d.ui.internal.routers.OrthogonalRouter; import org.eclipse.gmf.runtime.notation.Edge; /** * This editpolicy persists synthetic bendpoints created by rectilinear router * and not yet serialized in the model. It should be registered before other * adjusting edit policies for the same node. * <p/> * * @since 3.3 */ public class AdjustSyntheticBendpointsEditPolicy extends AdjustAbsoluteBendpointsEditPolicyBase { /** * Default role for registering this edit policy. * <p/> * The value is prefixed by class FQN in order to avoid conflicts, but the * literal should NOT be used anywhere. */ public static final String ROLE = AdjustSyntheticBendpointsEditPolicy.class .getName() + ":Role"; @Override protected Command getAdjustLinksCommand(ChangeBoundsRequest req) { final Point moveDelta = req.getMoveDelta(); if (moveDelta.x == 0 && moveDelta.y == 0) { return null; } CachedEditPartsSet allMoved = getMovedEditPartsSet(req); ICommand result = null; LinkedList<GraphicalEditPart> queue = new LinkedList<GraphicalEditPart>(); queue.add(getHost()); while (!queue.isEmpty()) { GraphicalEditPart cur = queue.removeFirst(); // we will adjust target (incoming) links only from the ends which // are not moved // and all outgoing (source) links // this way all links are processed only once for (Object nextLink : cur.getSourceConnections()) { if (nextLink instanceof ConnectionEditPart) { ConnectionEditPart nextLinkEP = (ConnectionEditPart) nextLink; ICommand nextAdjustment = getAdjustOneLinkCommand( nextLinkEP, req); result = compose(result, nextAdjustment); } } for (Object nextLink : cur.getTargetConnections()) { if (nextLink instanceof ConnectionEditPart) { ConnectionEditPart nextLinkEP = (ConnectionEditPart) nextLink; EditPart target = nextLinkEP.getSource(); MovedNodeKind move = allMoved.isMoved(target); if (move == MovedNodeKind.NO) { ICommand nextAdjustment = getAdjustOneLinkCommand( nextLinkEP, req); result = compose(result, nextAdjustment); } } } @SuppressWarnings("unchecked") Collection<GraphicalEditPart> children = cur.getChildren(); queue.addAll(children); } return result == null ? null : new ICommandProxy(result.reduce()); } private ICommand getAdjustOneLinkCommand(ConnectionEditPart linkEP, ChangeBoundsRequest req) { Connection conn = linkEP.getConnectionFigure(); ConnectionRouter router = conn.getConnectionRouter(); if (false == router instanceof OrthogonalRouter) { // only ortho-routers may produce synthetic bend points return null; } if (false == linkEP.getNotationView() instanceof Edge) { return null; } PointList points = conn.getPoints(); if (points.size() <= 2) { // source + target return null; } if (false == conn.getRoutingConstraint() instanceof List<?>) { return null; } List<?> d2dBendpoints = (List<?>) conn.getRoutingConstraint(); if (d2dBendpoints.size() >= points.size()) { return null; } SetAbsoluteBendpointsCommand result = new SetAbsoluteBendpointsCommand( linkEP.getEditingDomain()); result.setEdge(linkEP); result.setNewPointList(points); return result; } }