package org.eclipse.papyrus.uml.diagram.sequence.apex.util; import java.util.Collection; import java.util.List; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PrecisionPoint; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.emf.ecore.EStructuralFeature.Setting; import org.eclipse.gef.EditPart; import org.eclipse.gef.commands.Command; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gmf.runtime.common.core.util.StringStatics; import org.eclipse.gmf.runtime.diagram.core.commands.SetConnectionAnchorsCommand; import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionNodeEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.INodeEditPart; import org.eclipse.gmf.runtime.draw2d.ui.figures.BaseSlidableAnchor; import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter; import org.eclipse.gmf.runtime.notation.NotationPackage; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.uml.diagram.common.util.DiagramEditPartsUtil; import org.eclipse.papyrus.uml.diagram.sequence.apex.draw2d.anchors.ApexHorizontalAnchor; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.LifelineEditPart; import org.eclipse.papyrus.uml.diagram.sequence.util.OccurrenceSpecificationMoveHelper; import org.eclipse.papyrus.uml.diagram.sequence.util.SequenceUtil; import org.eclipse.uml2.common.util.CacheAdapter; import org.eclipse.uml2.uml.InteractionFragment; import org.eclipse.uml2.uml.Message; import org.eclipse.uml2.uml.MessageOccurrenceSpecification; import org.eclipse.uml2.uml.OccurrenceSpecification; /** * @author Jiho * */ public class ApexOccurrenceSpecificationMoveHelper { public static Command getMoveInteractionFragmentCommand(InteractionFragment movedInteractionFragment, int yLocation) { CompoundCommand command = new CompoundCommand(); return command; } /** * Get the complete command to move message occurrence specification. * * @param movedOccurrenceSpecification * moved occurrence specification * @param yLocation * y location where occurrence specification is moved * @param newBounds * source or target edit part's bounds * @param lifelinePart * lifeline edit part containing the moved element * @param notToMoveEditParts * list of edit parts which must not be moved in the created command * @return command to move all edit parts linked to the occurrence specifications or null */ public static Command getMoveMessageOccurrenceSpecificationsCommand(OccurrenceSpecification movedOccurrenceSpecification, int yLocation, Rectangle newBounds, EditPart childToReconnectTo, LifelineEditPart lifelinePart, List<EditPart> notToMoveEditParts) { // the global command which shall be completed and returned CompoundCommand command = new CompoundCommand(); if (newBounds == null) { return OccurrenceSpecificationMoveHelper.getMoveOccurrenceSpecificationsCommand(movedOccurrenceSpecification, null, yLocation, -1, lifelinePart, notToMoveEditParts); } if(movedOccurrenceSpecification instanceof MessageOccurrenceSpecification) { Point referencePoint = getReferencePoint(lifelinePart, movedOccurrenceSpecification, yLocation); if (childToReconnectTo instanceof IGraphicalEditPart) { // reconnect message from the event Message message = ((MessageOccurrenceSpecification)movedOccurrenceSpecification).getMessage(); if(message != null && movedOccurrenceSpecification.equals(message.getSendEvent())) { Collection<Setting> settings = CacheAdapter.getInstance().getNonNavigableInverseReferences(message); for(Setting ref : settings) { if(NotationPackage.eINSTANCE.getView_Element().equals(ref.getEStructuralFeature())) { View view = (View)ref.getEObject(); EditPart part = DiagramEditPartsUtil.getEditPartFromView(view, lifelinePart); // the message part must start or finish on the lifeline (with the event) if(part instanceof ConnectionNodeEditPart && !notToMoveEditParts.contains(part)) { SetConnectionAnchorsCommand scaCmd = new SetConnectionAnchorsCommand(((IGraphicalEditPart)childToReconnectTo).getEditingDomain(), StringStatics.BLANK); PrecisionPoint pt = BaseSlidableAnchor.getAnchorRelativeLocation(referencePoint, newBounds); IFigure figure = ((IGraphicalEditPart)childToReconnectTo).getFigure(); if (childToReconnectTo instanceof LifelineEditPart) { figure = ((LifelineEditPart)childToReconnectTo).getNodeFigure(); } ConnectionAnchor sourceAnchor = new ApexHorizontalAnchor(figure, pt); scaCmd.setEdgeAdaptor(new EObjectAdapter(view)); scaCmd.setNewSourceTerminal(((INodeEditPart)part).mapConnectionAnchorToTerminal(sourceAnchor)); command.add(new ICommandProxy(scaCmd)); // update enclosing interaction fragment Command updateIFrag = SequenceUtil.createUpdateEnclosingInteractionCommand((MessageOccurrenceSpecification)movedOccurrenceSpecification, referencePoint, lifelinePart); if(updateIFrag != null && updateIFrag.canExecute()) { // command.add(updateIFrag); } } } } } // reconnect message to the event if(message != null && movedOccurrenceSpecification.equals(message.getReceiveEvent())) { Collection<Setting> settings = CacheAdapter.getInstance().getNonNavigableInverseReferences(message); for(Setting ref : settings) { if(NotationPackage.eINSTANCE.getView_Element().equals(ref.getEStructuralFeature())) { View view = (View)ref.getEObject(); EditPart part = DiagramEditPartsUtil.getEditPartFromView(view, lifelinePart); // the message part must start or finish on the lifeline (with the event) if(part instanceof ConnectionNodeEditPart && !notToMoveEditParts.contains(part)) { SetConnectionAnchorsCommand scaCmd = new SetConnectionAnchorsCommand(((IGraphicalEditPart)childToReconnectTo).getEditingDomain(), StringStatics.BLANK); PrecisionPoint pt = BaseSlidableAnchor.getAnchorRelativeLocation(referencePoint, newBounds); IFigure figure = ((IGraphicalEditPart)childToReconnectTo).getFigure(); if (childToReconnectTo instanceof LifelineEditPart) { figure = ((LifelineEditPart)childToReconnectTo).getNodeFigure(); } ConnectionAnchor targetAnchor = new ApexHorizontalAnchor(figure, pt); scaCmd.setEdgeAdaptor(new EObjectAdapter(view)); scaCmd.setNewSourceTerminal(((INodeEditPart)part).mapConnectionAnchorToTerminal(targetAnchor)); command.add(new ICommandProxy(scaCmd)); // update enclosing interaction fragment Command updateIFrag = SequenceUtil.createUpdateEnclosingInteractionCommand((MessageOccurrenceSpecification)movedOccurrenceSpecification, referencePoint, lifelinePart); if(updateIFrag != null && updateIFrag.canExecute()) { // command.add(updateIFrag); } } } } } } } // return null rather than an empty non executable command if(command.isEmpty()) { return null; } return command; } /** * Get the reference point to reconnect or resize edit parts at the given y location * * @param lifelinePart * lifeline edit part containing the moved element * @param movedOccurrenceSpecification * the moving occurrence specification which a reference point is searched for * @param yLocation * y location * @return reference point on the lifeline */ private static Point getReferencePoint(LifelineEditPart lifelinePart, OccurrenceSpecification movedOccurrenceSpecification, int yLocation) { Point referencePoint = SequenceUtil.findLocationOfEvent(lifelinePart, movedOccurrenceSpecification); if(referencePoint == null) { referencePoint = lifelinePart.getFigure().getBounds().getCenter().getCopy(); } referencePoint.y = yLocation; return referencePoint; } }