/** * Copyright (c) 2006 Borland Software Corp. * * 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * bblajer - initial API and implementation */ package org.eclipse.gmf.runtime.lite.edit.policies; import java.util.ArrayList; import java.util.List; import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.emf.common.command.AbstractCommand; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.transaction.util.TransactionUtil; import org.eclipse.gef.Request; import org.eclipse.gef.commands.Command; import org.eclipse.gef.requests.BendpointRequest; import org.eclipse.gmf.runtime.lite.commands.WrappingCommand; import org.eclipse.gmf.runtime.lite.requests.RequestConstants; import org.eclipse.gmf.runtime.lite.requests.SetAllBendpointsRequest; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.NotationFactory; import org.eclipse.gmf.runtime.notation.RelativeBendpoints; import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint; public class BendpointEditPolicy extends org.eclipse.gef.editpolicies.BendpointEditPolicy { protected Edge getDiagramEdge() { return (Edge) getHost().getModel(); } @Override public Command getCommand(Request request) { if (RequestConstants.REQ_SET_ALL_BENDPOINTS.equals(request.getType())) { return getSetAllBendpointsCommand((SetAllBendpointsRequest) request); } return super.getCommand(request); } protected Command getSetAllBendpointsCommand(SetAllBendpointsRequest request) { return getModifyBendpointCommand(new BendpointSetter(request.getPoints())); } protected Command getCreateBendpointCommand(BendpointRequest request) { return getModifyBendpointCommand(new BendpointCreator(request.getIndex(), request.getLocation())); } protected Command getDeleteBendpointCommand(BendpointRequest request) { return getModifyBendpointCommand(new BendpointDeleter(request.getIndex())); } protected Command getMoveBendpointCommand(BendpointRequest request) { return getModifyBendpointCommand(new BendpointMover(request.getIndex(), request.getLocation())); } private Command getModifyBendpointCommand(final BendpointModifier modifier) { TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(getDiagramEdge().getDiagram().getElement()); return new WrappingCommand(editingDomain, new BendpointModificationCommand(modifier)); } private class BendpointModificationCommand extends AbstractCommand { private BendpointModifier bendpointModifier; private List oldPoints; private Point mySourceRef; private Point myTargetRef; public BendpointModificationCommand(BendpointModifier bendpointModifier) { this.bendpointModifier = bendpointModifier; } @Override protected boolean prepare() { TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(getDiagramEdge()); if (domain != null && domain.isReadOnly(getDiagramEdge().eResource())) { return false; } Connection connection = getConnection(); mySourceRef = connection.getSourceAnchor().getReferencePoint().getCopy(); connection.translateToRelative(mySourceRef); myTargetRef = connection.getTargetAnchor().getReferencePoint().getCopy(); connection.translateToRelative(myTargetRef); return true; } public void execute() { RelativeBendpoints bendpoints = (RelativeBendpoints) getDiagramEdge().getBendpoints(); if (bendpoints == null) { bendpoints = NotationFactory.eINSTANCE.createRelativeBendpoints(); getDiagramEdge().setBendpoints(bendpoints); } oldPoints = bendpoints.getPoints(); List newPoints = new ArrayList(oldPoints); bendpointModifier.applyModification(newPoints, new BendpointConverter() { public RelativeBendpoint convert(Point point) { getConnection().translateToRelative(point); Dimension s = point.getDifference(mySourceRef); Dimension t = point.getDifference(myTargetRef); return new RelativeBendpoint(s.width, s.height, t.width, t.height); } }); bendpoints.setPoints(newPoints); } public void undo() { RelativeBendpoints bendpoints = (RelativeBendpoints) getDiagramEdge().getBendpoints(); bendpoints.setPoints(oldPoints); } public void redo() { execute(); } } private static interface BendpointConverter { public RelativeBendpoint convert(Point point); } private static interface BendpointModifier { public void applyModification(List/*<RelativeBendpoint>*/ originalBendpoints, BendpointConverter converter); } private static class BendpointDeleter implements BendpointModifier { private int index; public BendpointDeleter(int index) { this.index = index; } public void applyModification(List originalBendpoints, BendpointConverter converter) { originalBendpoints.remove(index); } } private static class BendpointMover implements BendpointModifier { private int index; private Point point; public BendpointMover(int index, Point point) { this.index = index; this.point = point; } public void applyModification(List originalBendpoints, BendpointConverter converter) { originalBendpoints.set(index, converter.convert(point)); } } private static class BendpointCreator implements BendpointModifier { private int index; private Point point; public BendpointCreator(int index, Point point) { this.index = index; this.point = point; } public void applyModification(List originalBendpoints, BendpointConverter converter) { originalBendpoints.add(index, converter.convert(point)); } } private static class BendpointSetter implements BendpointModifier { private PointList myPoints; public BendpointSetter(PointList points) { myPoints = points; } public void applyModification(List originalBendpoints, BendpointConverter converter) { originalBendpoints.clear(); for(int i = 0, iMax = myPoints.size(); i < iMax; i++) { originalBendpoints.add(converter.convert(myPoints.getPoint(i))); } } } }