package org.eclipse.papyrus.uml.diagram.sequence.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.common.core.command.ICompositeCommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.commands.SetBoundsCommand;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
import org.eclipse.gmf.runtime.notation.Bounds;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.Shape;
import org.eclipse.papyrus.uml.diagram.sequence.apex.util.ApexSequenceRequestConstants;
import org.eclipse.papyrus.uml.diagram.sequence.apex.util.ApexSequenceUtil;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CombinedFragmentCombinedFragmentCompartmentEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CombinedFragmentEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.InteractionInteractionCompartmentEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.InteractionOperandEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.InteractionCompartmentXYLayoutEditPolicy;
import org.eclipse.papyrus.uml.diagram.sequence.part.UMLVisualIDRegistry;
import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes;
import org.eclipse.swt.SWT;
import org.eclipse.uml2.uml.CombinedFragment;
import org.eclipse.uml2.uml.InteractionOperand;
public class OperandBoundsComputeHelper {
/**
* Default height of Interaction Operand
*/
public static final int DEFAULT_INTERACTION_OPERAND_HEIGHT = 61;
/**
* Default width of Interaction Operand
*/
public static final int DEFAULT_INTERACTION_OPERAND_WIDTH = 210;
/**
* Border width of CombinedFragmentFigure
*/
public static final int COMBINED_FRAGMENT_FIGURE_BORDER = 1;
/**
* Find first Interaction Operand EditpPart of CombinedFragmentCombinedFragmentCompartmentEditPart
* @param compartEP
* @return InteractionOperandEditPart
*/
public static InteractionOperandEditPart findFirstIOEP(
CombinedFragmentCombinedFragmentCompartmentEditPart compartEP) {
InteractionOperandEditPart firstIOEP = null;
List children = compartEP.getChildren();
for (int i = 0; i < children.size(); i++) {
if (children.get(i) instanceof InteractionOperandEditPart) {
firstIOEP = (InteractionOperandEditPart) children.get(i);
break;
}
}
return firstIOEP;
}
/**
* Find Last Interaction Operand EditpPart of CombinedFragmentCombinedFragmentCompartmentEditPart
* @param compartEP
* @return InteractionOperandEditPart
*/
public static InteractionOperandEditPart findLastIOEP(
CombinedFragmentCombinedFragmentCompartmentEditPart compartEP) {
InteractionOperandEditPart lastIOEP = null;
List children = compartEP.getChildren();
for (int i = children.size() - 1; i >= 0; i--) {
if (children.get(i) instanceof InteractionOperandEditPart) {
lastIOEP = (InteractionOperandEditPart) children.get(i);
break;
}
}
return lastIOEP;
}
/**
* Find Previous Interaction Operand EditpPart of current given InteractionOperandEditPart
* @param compartEP
* @param currentIOEP
* @return InteractionOperandEditPart
*/
public static InteractionOperandEditPart findPreviousIOEP(
CombinedFragmentCombinedFragmentCompartmentEditPart compartEP,
InteractionOperandEditPart currentIOEP) {
InteractionOperandEditPart previousIOEP = null;
List children = compartEP.getChildren();
for (int i = 0; i < children.size() - 1; i++) {
if (children.get(i) instanceof InteractionOperandEditPart) {
if (children.get(i) == currentIOEP) {
break;
} else {
previousIOEP = (InteractionOperandEditPart) children.get(i);
}
}
}
return previousIOEP;
}
/**
* Find Latter Interaction Operand EditpPart of current given InteractionOperandEditPart
* @param compartEP
* @param currentIOEP
* @return InteractionOperandEditPart
*/
public static InteractionOperandEditPart findLatterIOEP(
CombinedFragmentCombinedFragmentCompartmentEditPart compartEP,
InteractionOperandEditPart currentIOEP) {
InteractionOperandEditPart latterIOEP = null;
List children = compartEP.getChildren();
for (int i = children.size() - 1; i > 0; i--) {
if (children.get(i) instanceof InteractionOperandEditPart) {
if (children.get(i) == currentIOEP) {
break;
} else {
latterIOEP = (InteractionOperandEditPart) children.get(i);
}
}
}
return latterIOEP;
}
/**
* currentIOEP 아래의 sibling IOEP List를 위치순으로 정렬하여 반환
*
* @param compartEP
* @param currentIOEP
* @return List<InteractionOperandEditPart>
*/
public static List<InteractionOperandEditPart> apexFindBelowIOEPs(
CombinedFragmentCombinedFragmentCompartmentEditPart compartEP,
InteractionOperandEditPart currentIOEP) {
List<InteractionOperandEditPart> belowIOEPs = new ArrayList<InteractionOperandEditPart>();
int currentAbsBottom = ApexSequenceUtil.apexGetAbsolutePosition(currentIOEP, SWT.BOTTOM);
List ioeps = compartEP.getChildren();
for ( int i = 0 ; i < ioeps.size() ; i++ ) {
InteractionOperandEditPart ioep = (InteractionOperandEditPart)ioeps.get(i);
int ioepAbsTop = ApexSequenceUtil.apexGetAbsolutePosition(ioep, SWT.TOP);
if ( ioepAbsTop >= currentAbsBottom ) {
belowIOEPs.add(ioep);
}
}
Collections.sort(belowIOEPs, new Comparator<IGraphicalEditPart>() {
public int compare(IGraphicalEditPart o1, IGraphicalEditPart o2) {
Rectangle r1 = ApexSequenceUtil.apexGetAbsoluteRectangle(o1);
Rectangle r2 = ApexSequenceUtil.apexGetAbsoluteRectangle(o2);
if (r1.y - r2.y == 0)
return r1.x - r2.x;
return r1.y - r2.y;
}
});
return belowIOEPs;
}
/**
* Update EditPart bounds using new rect
* @param parent
* @param rect
*/
public static void updateEditPartBounds(GraphicalEditPart editpart,
final Rectangle rect) {
if (editpart.getModel() instanceof Node) {
Node node = (Node) editpart.getModel();
if (node.getLayoutConstraint() instanceof Bounds) {
Bounds bounds = (Bounds) node.getLayoutConstraint();
updateBounds(bounds, rect, editpart.getEditingDomain());
}
}
}
/**
* Update EditPart bounds using new rect
* @param parent
* @param rect
*/
public static ICommand createUpdateEditPartBoundsCommand(
final GraphicalEditPart editpart, final Rectangle rect) {
ICommand cmd = new AbstractTransactionalCommand(
editpart.getEditingDomain(),
"Update Operand Bounds", null) {
@Override
protected CommandResult doExecuteWithResult(
IProgressMonitor monitor, IAdaptable info)
throws ExecutionException {
if (editpart.getModel() instanceof Node) {
Node node = (Node) editpart.getModel();
if (node.getLayoutConstraint() instanceof Bounds) {
Bounds bounds = (Bounds) node.getLayoutConstraint();
fillBounds(bounds, rect);
}
}
return CommandResult.newOKCommandResult();
}
};
return cmd;
}
/**
* Create command for updating Interaction Operand EditpPart bounds after the CombinedFragment to be created.
* @param editPart
* @param request
* @return ICommand
*/
public static ICommand createUpdateCFAndIOBoundsForCFCreationCommand(final EditPart editPart, final CreateViewRequest request) {
if (!(editPart instanceof GraphicalEditPart)) {
return null;
}
GraphicalEditPart graphicalEditPart= (GraphicalEditPart)editPart;
ICommand cmd = new AbstractTransactionalCommand(graphicalEditPart.getEditingDomain(),"Create update operand bounds command",null) {
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
IAdaptable info) throws ExecutionException {
OperandBoundsComputeHelper.updateCFAndIOBoundsForCFCreation(
(GraphicalEditPart) editPart, request);
return CommandResult.newOKCommandResult();
}
};
return cmd;
}
/**
* Update Interaction Operand EditpPart bounds after the CombinedFragment to be created.
* @param parent
* @param request
* @param selectionRect
*/
private static void updateCFAndIOBoundsForCFCreation(GraphicalEditPart parent, CreateViewRequest request) {
Object subEditPart = null;
if (parent instanceof InteractionInteractionCompartmentEditPart) {
InteractionInteractionCompartmentEditPart interactionInteractionCompartmentEditPart = (InteractionInteractionCompartmentEditPart) parent;
subEditPart = interactionInteractionCompartmentEditPart
.getChildren().get(
interactionInteractionCompartmentEditPart
.getChildren().size() - 1);
}else if (parent instanceof InteractionOperandEditPart) {
InteractionOperandEditPart interactionOperandEditPart = (InteractionOperandEditPart) parent;
subEditPart = interactionOperandEditPart
.getChildren().get(
interactionOperandEditPart
.getChildren().size() - 1);
}
if (subEditPart != null
&& subEditPart instanceof CombinedFragmentEditPart) {
CombinedFragmentEditPart combinedFragmentEditPart = (CombinedFragmentEditPart) subEditPart;
// set bounds for CombinedFragmentEditPart
Rectangle cfEPAbsoluteRect = null;
int labelContainerHeight = computeCombinedFragementHeaderHeight(combinedFragmentEditPart);
Shape cfEPShape = (Shape) combinedFragmentEditPart.getModel();
if (cfEPShape.getLayoutConstraint() instanceof Bounds) {
if(request.getSize() == null){
Dimension cfEPDefaultSize = new Dimension();
cfEPDefaultSize.setWidth(DEFAULT_INTERACTION_OPERAND_WIDTH+COMBINED_FRAGMENT_FIGURE_BORDER*2);
cfEPDefaultSize.setHeight(DEFAULT_INTERACTION_OPERAND_HEIGHT+labelContainerHeight+COMBINED_FRAGMENT_FIGURE_BORDER*2);
cfEPAbsoluteRect = new Rectangle(request.getLocation(),cfEPDefaultSize);
}else{
cfEPAbsoluteRect = new Rectangle(request.getLocation(),request.getSize());
}
Rectangle cfEPRelativeRect = cfEPAbsoluteRect.getCopy();
combinedFragmentEditPart.getFigure().translateToRelative(cfEPRelativeRect);
Bounds cfEPBounds = (Bounds) cfEPShape.getLayoutConstraint();
fillBounds(cfEPBounds,cfEPRelativeRect);
}
// set bounds for new added Operand
InteractionOperandEditPart lastOperand = OperandBoundsComputeHelper
.findLastIOEP((CombinedFragmentCombinedFragmentCompartmentEditPart) combinedFragmentEditPart.getChildBySemanticHint(UMLVisualIDRegistry
.getType(CombinedFragmentCombinedFragmentCompartmentEditPart.VISUAL_ID)));
Shape shape = (Shape) lastOperand.getModel();
if (shape.getLayoutConstraint() instanceof Bounds) {
Bounds bounds = (Bounds) shape.getLayoutConstraint();
Rectangle rect = new Rectangle(bounds.getX(), bounds.getY(),
cfEPAbsoluteRect.width()-COMBINED_FRAGMENT_FIGURE_BORDER*2, cfEPAbsoluteRect.height()
- labelContainerHeight-COMBINED_FRAGMENT_FIGURE_BORDER*2);
fillBounds(bounds,rect);
}
}
}
/**
* apex updated - 사용 안 함 - createIOEPResizeCommand()에서 모두 처리
*
* Create command for updating Interaction Operand EditpPart bounds after CombinedFragment to be resized.
* @param compoundCmd
* @param request
* @param combinedFragmentEditPart
* @return Command
*/
/* apex replaced
public static Command createUpdateIOBoundsForCFResizeCommand(
CompoundCommand compoundCmd, final ChangeBoundsRequest request,
CombinedFragmentEditPart combinedFragmentEditPart) {
if (combinedFragmentEditPart.getChildren().size() > 0
&& combinedFragmentEditPart.getChildren().get(0) instanceof CombinedFragmentCombinedFragmentCompartmentEditPart) {
CombinedFragmentCombinedFragmentCompartmentEditPart compartment = (CombinedFragmentCombinedFragmentCompartmentEditPart) combinedFragmentEditPart
.getChildren().get(0);
CombinedFragment cf = (CombinedFragment) ((CombinedFragmentEditPart) combinedFragmentEditPart)
.resolveSemanticElement();
InteractionOperandEditPart targetIOEP = null;
if ((request.getResizeDirection() & PositionConstants.NORTH) != 0) {
targetIOEP = findFirstIOEP(compartment);
} else if ((request.getResizeDirection() & PositionConstants.SOUTH) != 0) {
targetIOEP = findLastIOEP(compartment);
}
updateIOBoundsForCFResize(
request,
compoundCmd,
compartment.getChildren(),
cf,
targetIOEP != null ? (InteractionOperand) targetIOEP
.resolveSemanticElement() : null,
request.getSizeDelta(), request.getResizeDirection());
}
return compoundCmd;
}
*/
/**
* apex updated - 사용안함 - createIOEPResizeCommand()에서 모두 처리
*
* Update Interaction Operand EditpPart bounds after CombinedFragment to be resized.
* @param request
* @param compoundCmd
* @param combinedFragmentChildrenEditParts
* @param cf
* @param targetOperand
* @param sizeDelta
* @param direction
*/
/* apex replaced
private static void updateIOBoundsForCFResize(final ChangeBoundsRequest request,
CompoundCommand compoundCmd,
List<EditPart> combinedFragmentChildrenEditParts,
CombinedFragment cf, InteractionOperand targetOperand,
final Dimension sizeDelta, int direction) {
InteractionOperandEditPart targetOperandEditPart = findTargetOperandEditPart(
cf, targetOperand, combinedFragmentChildrenEditParts);
for (EditPart ep : combinedFragmentChildrenEditParts) {
if (ep instanceof InteractionOperandEditPart) {
InteractionOperandEditPart ioEP = (InteractionOperandEditPart) ep;
Object ioEPModel = ioEP.getModel();
if (ioEPModel instanceof Shape) {
Shape ioEPShape = (Shape) ioEPModel;
if (ioEPShape.getLayoutConstraint() instanceof Bounds) {
final Bounds ioEPOriginalBounds = (Bounds) ioEPShape
.getLayoutConstraint();
ICommand cmd = new UpdateIOBoundsForCFResizeCommand(
ioEP.getEditingDomain(),
"Update operand bounds interaction command",
ioEPOriginalBounds, request, sizeDelta,
ioEP == targetOperandEditPart, direction);
compoundCmd.add(new ICommandProxy(cmd));
}
}
}
}
}
*/
/**
* Update bounds using new rect
* @param bounds
* @param rect
* @param transactionalEditingDomain
*/
public static void updateBounds(final Bounds bounds, final Rectangle rect,
TransactionalEditingDomain transactionalEditingDomain) {
if (bounds != null) {
final Rectangle originalBounds = new Rectangle();
originalBounds.setX(bounds.getX());
originalBounds.setY(bounds.getY());
originalBounds.setWidth(bounds.getWidth());
originalBounds.setHeight(bounds.getHeight());
AbstractCommand cmd = new AbstractCommand() {
public boolean canExecute() {
return true;
}
public void execute() {
exec(rect);
}
public void redo() {
execute();
}
public void undo(){
exec(originalBounds);
}
public void exec(Rectangle rect){
fillBounds(bounds,rect);
}
public boolean canUndo() {
return true;
}
};
CommandHelper.executeCommandWithoutHistory(
transactionalEditingDomain, cmd,true);
}
}
/**
* Get InteractionOperandEditPart from its model object InteractionOperand.
* @param cf
* @param targetOperand
* @param combinedFragmentChildrenEditParts
* @return InteractionOperandEditPart
*/
public static InteractionOperandEditPart findTargetOperandEditPart(CombinedFragment cf,
InteractionOperand targetOperand,
List<EditPart> combinedFragmentChildrenEditParts) {
if(targetOperand == null)
return null;
for(EditPart ep : combinedFragmentChildrenEditParts) {
if(ep instanceof InteractionOperandEditPart) {
InteractionOperandEditPart ioEP = (InteractionOperandEditPart)ep;
InteractionOperand io = (InteractionOperand)ioEP.resolveSemanticElement();
if(cf.getOperands().contains(io)) {
if(targetOperand.equals(io)) {
return ioEP;
}
}
}
}
return null;
}
/**
* Get graphical edit part bounds
* @param editPart
* @return
*/
public static Bounds getEditPartBounds(GraphicalEditPart editPart){
if (editPart.getModel() instanceof Node) {
Node node = (Node) editPart.getModel();
if (node.getLayoutConstraint() instanceof Bounds) {
Bounds bounds = (Bounds) node.getLayoutConstraint();
return bounds;
}
}
return null;
}
/**
* Fill data from Bounds to Rectangle
* @param source
* @return Rectangle
*/
public static Rectangle fillRectangle(Bounds source) {
if (source == null) {
return null;
}
Rectangle target = new Rectangle();
target.setX(source.getX());
target.setY(source.getY());
target.setWidth(source.getWidth());
target.setHeight(source.getHeight());
return target;
}
/**
* Fill data from Rectangle to Bounds
* @param bounds
* @param source
* @return Bounds
*/
public static Bounds fillBounds(Bounds bounds,Rectangle source) {
if (bounds == null || source == null) {
return null;
}
bounds.setX(source.x());
bounds.setY(source.y());
bounds.setWidth(source.width());
bounds.setHeight(source.height());
return bounds;
}
/**
* Get interaction operand bounds
* @param operandEP
* @return Bounds
*/
public static Bounds getInteractionOperandEPBounds(GraphicalEditPart operandEP){
Object lastChildModel = operandEP.getModel();
if (lastChildModel instanceof Shape) {
Shape lastOperandShape = (Shape) lastChildModel;
if (lastOperandShape.getLayoutConstraint() instanceof Bounds) {
return (Bounds)lastOperandShape.getLayoutConstraint();
}
}
return null;
}
/**
* apex updated
* IO의 경계를 직접 변경하거나, IO내의 element의 move/resize에 의해 경계가 변경되는 경우 처리
*
* @param request
* @param currentIOEP
* @return
*/
public static Command createIOEPResizeCommand(ChangeBoundsRequest request, InteractionOperandEditPart currentIOEP) {
return createIOEPResizeCommand(request, currentIOEP, false);
}
/**
* apex updated
* IO의 경계를 직접 변경하거나, IO내의 element의 move/resize에 의해 경계가 변경되는 경우 처리
* Create interaction operand resize command
*
* @param currentIOEP
* @param heightDelta
* @param compartEP
* @param direction
* @return
*/
public static Command createIOEPResizeCommand(ChangeBoundsRequest request, InteractionOperandEditPart currentIOEP, boolean isCalledByParentCFResize) {
int widthDelta = request.getSizeDelta().width;
int heightDelta = request.getSizeDelta().height;
CombinedFragmentCombinedFragmentCompartmentEditPart compartEP = (CombinedFragmentCombinedFragmentCompartmentEditPart)currentIOEP.getParent();
int direction = request.getResizeDirection();
Bounds currentIOEPBounds = OperandBoundsComputeHelper.getEditPartBounds(currentIOEP);
CombinedFragmentEditPart cfep = (CombinedFragmentEditPart)compartEP.getParent();
if (currentIOEPBounds == null) {
return null;
}
if (heightDelta < 0) {
if (currentIOEPBounds.getHeight() - Math.abs(heightDelta) < OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT) {
return null;
}
}
InteractionOperandEditPart targetIOEP = null;
List<InteractionOperandEditPart> belowIOEPs = null;
List<InteractionOperandEditPart> siblingIOEPsExceptTargetIOEP = null;
if ((direction & PositionConstants.NORTH) != 0) {
targetIOEP = OperandBoundsComputeHelper.findPreviousIOEP(compartEP, currentIOEP);
} else if ((direction & PositionConstants.SOUTH) != 0) {
targetIOEP = OperandBoundsComputeHelper.findLatterIOEP(compartEP, currentIOEP);
belowIOEPs = apexFindBelowIOEPs(compartEP, currentIOEP);
}
if ((direction & PositionConstants.EAST_WEST) != 0) {
List cfChildren = currentIOEP.getParent().getChildren();
List<InteractionOperandEditPart> childrenIOEPs = new ArrayList<InteractionOperandEditPart>();
for ( Object obj : cfChildren ) {
if ( obj instanceof InteractionOperandEditPart
&& !obj.equals(currentIOEP)
&& !obj.equals(targetIOEP) ) {
childrenIOEPs.add((InteractionOperandEditPart)obj);
}
}
siblingIOEPsExceptTargetIOEP = childrenIOEPs;
}
CompositeCommand compositeCommand = new CompositeCommand("Resize Operand");
ChangeBoundsRequest cbCFRequest = new ChangeBoundsRequest(ApexSequenceRequestConstants.APEX_REQUEST_MOVE_AND_RESIZE_COMBINEDFRAGMENT);
Rectangle currentIOEPRect = OperandBoundsComputeHelper.fillRectangle(currentIOEPBounds);
IFigure cfFigure = cfep.getFigure();
Rectangle cfRect = cfFigure.getBounds().getCopy();
int cfX = cfRect.x;
int cfY = cfRect.y;
int cfWidth = cfRect.width;
int cfHeight = cfRect.height;
if ( (direction & PositionConstants.NORTH) != 0 ) { // 상단에서 확대/축소하는 경우
// 최상단 Op의 경우
if(currentIOEP == OperandBoundsComputeHelper.findFirstIOEP(compartEP)) {
// 최상단 Op에서 위로 확장하는 경우
// CF를 위로 이동 시키고 최상단 Op를 확장
currentIOEPRect.setHeight(currentIOEPBounds.getHeight() + heightDelta);
currentIOEPRect.setWidth(currentIOEPBounds.getWidth() + widthDelta);
currentIOEPRect.setY(0); // 최상단 Op 는 (0, 0)으로 고정
// belowIOEPs의 width처리 및 Op의 상변 resize로 CF가 이동되어도 belowIOEP는 이동되지 않도록 처리
belowIOEPs = apexFindBelowIOEPs(compartEP, currentIOEP);
if ( belowIOEPs != null ) {
for ( InteractionOperandEditPart aBelowIOEP : belowIOEPs ) {
Bounds anIOEPBounds = OperandBoundsComputeHelper.getEditPartBounds(aBelowIOEP);
Rectangle anIOEPRect = OperandBoundsComputeHelper.fillRectangle(anIOEPBounds);
anIOEPRect.setWidth(anIOEPBounds.getWidth() + widthDelta);
anIOEPRect.setY(anIOEPBounds.getY() + heightDelta);
ICommand anIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(aBelowIOEP, anIOEPRect);
compositeCommand.add(anIOEPCommand);
}
}
ICommand currentIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(currentIOEP, currentIOEPRect);
compositeCommand.add(currentIOEPCommand);
// CF 경계 처리
if ( (direction & PositionConstants.WEST) != 0 ) { // 좌측에서 확대/축소하는 경우
cfX -= widthDelta;
cfY -= heightDelta;
cfWidth += widthDelta;
cfHeight += heightDelta;
cbCFRequest.setMoveDelta(new Point(-widthDelta, -heightDelta));
cbCFRequest.setSizeDelta(new Dimension(widthDelta, heightDelta));
} else if ( (direction & PositionConstants.EAST) != 0 ) {
cfY -= heightDelta;
cfWidth += widthDelta;
cfHeight += heightDelta;
cbCFRequest.setMoveDelta(new Point(0, -heightDelta));
cbCFRequest.setSizeDelta(new Dimension(widthDelta, heightDelta));
} else {
cfY -= heightDelta;
cfHeight += heightDelta;
cbCFRequest.setMoveDelta(new Point(0, -heightDelta));
cbCFRequest.setSizeDelta(new Dimension(0, heightDelta));
}
} else { // 최상단 Op가 아닌 경우
// Operand Resize에 의한 새 경계가 targetIOEP의 Lowest child 를 침범 시 X 표시 되도록 처리
if ( apexIsInvadingTargetChildren(currentIOEP, compartEP, direction, heightDelta) ) {
return null;
}
Bounds targetIOEPBounds = OperandBoundsComputeHelper.getEditPartBounds(targetIOEP);
if (targetIOEPBounds == null) {
return null;
}
Rectangle targetIOEPRect = null;
targetIOEPRect = OperandBoundsComputeHelper.fillRectangle(targetIOEPBounds);
// 축소되는 targetIOEP가 최소 높이 이하로 축소되지 않도록
if (targetIOEPBounds.getHeight() - heightDelta < OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT) {
return null;
}
// target을 축소하고, current를 확대, CF경계 불변
targetIOEPRect.setHeight(targetIOEPBounds.getHeight() - heightDelta);
currentIOEPRect.setHeight(currentIOEPBounds.getHeight() + heightDelta);
targetIOEPRect.setWidth(targetIOEPBounds.getWidth() + widthDelta);
currentIOEPRect.setWidth(currentIOEPBounds.getWidth() + widthDelta);
currentIOEPRect.setY(currentIOEPRect.y() - heightDelta);
// target를 제외한 sibling width 변경
List<InteractionOperandEditPart> siblingsExceptBelow = siblingIOEPsExceptTargetIOEP;
if ( siblingsExceptBelow != null) {
for (InteractionOperandEditPart anIoep : siblingsExceptBelow) {
Bounds anIOEPBounds = OperandBoundsComputeHelper.getEditPartBounds(anIoep);
Rectangle anIOEPRect = OperandBoundsComputeHelper.fillRectangle(anIOEPBounds);
anIOEPRect.setWidth(anIOEPBounds.getWidth() + widthDelta);
ICommand anIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(anIoep, anIOEPRect);
compositeCommand.add(anIOEPCommand);
}
}
ICommand currentIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(currentIOEP, currentIOEPRect);
ICommand targetIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(targetIOEP, targetIOEPRect);
compositeCommand.add(currentIOEPCommand);
compositeCommand.add(targetIOEPCommand);
// CF 경계 처리를 위한 ChangeBoundsRequeset 처리
if ( (direction & PositionConstants.WEST) != 0 ) { // 좌측에서 확대/축소하는 경우
cfX -= widthDelta;
cfWidth += widthDelta;
cbCFRequest.setMoveDelta(new Point(-widthDelta, 0));
cbCFRequest.setSizeDelta(new Dimension(widthDelta, 0));
} else if ( (direction & PositionConstants.EAST) != 0 ) { // 우측에서 확대/축소하는 경우
cfWidth += widthDelta;
cbCFRequest.setSizeDelta(new Dimension(widthDelta, 0));
}
}
} else if ( (direction & PositionConstants.SOUTH) != 0 ) { // 하단에서 아래로 드래그하여 확대하는 경우
// 최하단 Op의 경우
if(currentIOEP == OperandBoundsComputeHelper.findLastIOEP(compartEP)) {
// 최하단 Op에서 Resize시 CF Resize
currentIOEPRect.setHeight(currentIOEPBounds.getHeight() + heightDelta);
currentIOEPRect.setWidth(currentIOEPBounds.getWidth() + widthDelta);
// target를 제외한 sibling width 변경
List<InteractionOperandEditPart> siblingsExceptBelow = siblingIOEPsExceptTargetIOEP;
if ( siblingsExceptBelow != null) {
for (InteractionOperandEditPart anIoep : siblingsExceptBelow) {
Bounds anIOEPBounds = OperandBoundsComputeHelper.getEditPartBounds(anIoep);
Rectangle anIOEPRect = OperandBoundsComputeHelper.fillRectangle(anIOEPBounds);
anIOEPRect.setWidth(anIOEPBounds.getWidth() + widthDelta);
ICommand anIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(anIoep, anIOEPRect);
compositeCommand.add(anIOEPCommand);
}
}
ICommand currentIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(currentIOEP, currentIOEPRect);
compositeCommand.add(currentIOEPCommand);
// CF 경계 처리
if ( (direction & PositionConstants.WEST) != 0 ) { // 좌측에서 확대/축소하는 경우
cfX -= widthDelta;
cfWidth += widthDelta;
cfHeight += heightDelta;
cbCFRequest.setMoveDelta(new Point(-widthDelta, 0));
cbCFRequest.setSizeDelta(new Dimension(widthDelta, heightDelta));
} else if ( (direction & PositionConstants.EAST) != 0 ) {
cfWidth += widthDelta;
cfHeight += heightDelta;
cbCFRequest.setSizeDelta(new Dimension(widthDelta, heightDelta));
} else {
cfHeight += heightDelta;
cbCFRequest.setSizeDelta(new Dimension(0, heightDelta));
}
} else { // 최하단 Op 가 아닌 경우
// current 경계 확대
currentIOEPRect.setHeight(currentIOEPBounds.getHeight() + heightDelta);
currentIOEPRect.setWidth(currentIOEPBounds.getWidth() + widthDelta);
ICommand currentIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(currentIOEP, currentIOEPRect);
compositeCommand.add(currentIOEPCommand);
// belowIOEPs 위/아래로 이동 및 width 처리
if ( belowIOEPs != null ) {
for ( InteractionOperandEditPart belowIOEP : belowIOEPs ) {
Bounds belowIOEPBounds = OperandBoundsComputeHelper.getEditPartBounds(belowIOEP);
Rectangle belowIOEPRect = OperandBoundsComputeHelper.fillRectangle(belowIOEPBounds);
belowIOEPRect.setY(belowIOEPRect.y() + heightDelta);
belowIOEPRect.setWidth(belowIOEPBounds.getWidth() + widthDelta);
ICommand belowIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(belowIOEP, belowIOEPRect);
compositeCommand.add(belowIOEPCommand);
}
}
// below를 제외한 sibling width 변경
List<InteractionOperandEditPart> siblingsExceptBelow = siblingIOEPsExceptTargetIOEP;
if ( siblingsExceptBelow != null) {
if ( belowIOEPs != null ) {
siblingsExceptBelow.removeAll(belowIOEPs);
}
for (InteractionOperandEditPart anIoep : siblingsExceptBelow) {
Bounds anIOEPBounds = OperandBoundsComputeHelper.getEditPartBounds(anIoep);
Rectangle anIOEPRect = OperandBoundsComputeHelper.fillRectangle(anIOEPBounds);
anIOEPRect.setWidth(anIOEPBounds.getWidth() + widthDelta);
ICommand anIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(anIoep, anIOEPRect);
compositeCommand.add(anIOEPCommand);
}
}
// CF 경계 처리를 위한 ChangeBoundsRequeset 처리
if ( (direction & PositionConstants.WEST) != 0 ) { // 좌측에서 확대/축소하는 경우
cfX -= widthDelta;
cfWidth += widthDelta;
cfHeight += heightDelta;
cbCFRequest.setMoveDelta(new Point(-widthDelta, 0));
cbCFRequest.setSizeDelta(new Dimension(widthDelta, heightDelta));
} else if ( (direction & PositionConstants.EAST) != 0 ) { // 우측에서 확대/축소하는 경우
cfWidth += widthDelta;
cfHeight += heightDelta;
cbCFRequest.setSizeDelta(new Dimension(widthDelta, heightDelta));
} else { // 하단에서
cfWidth += widthDelta;
cfHeight += heightDelta;
cbCFRequest.setSizeDelta(new Dimension(widthDelta, heightDelta));
}
}
} else if ( (direction & PositionConstants.NORTH_SOUTH) == 0 ) { // 좌우로만 이동하는 경우
// current 경계 확대
currentIOEPRect.setWidth(currentIOEPBounds.getWidth() + widthDelta);
ICommand currentIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(currentIOEP, currentIOEPRect);
compositeCommand.add(currentIOEPCommand);
// belowIOEPs 위/아래로 이동 및 width 처리
if ( belowIOEPs != null ) {
for ( InteractionOperandEditPart belowIOEP : belowIOEPs ) {
Bounds belowIOEPBounds = OperandBoundsComputeHelper.getEditPartBounds(belowIOEP);
Rectangle belowIOEPRect = OperandBoundsComputeHelper.fillRectangle(belowIOEPBounds);
belowIOEPRect.setY(belowIOEPRect.y() + heightDelta);
belowIOEPRect.setWidth(belowIOEPBounds.getWidth() + widthDelta);
ICommand belowIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(belowIOEP, belowIOEPRect);
compositeCommand.add(belowIOEPCommand);
}
}
// below를 제외한 sibling width 변경
List<InteractionOperandEditPart> siblingsExceptBelow = siblingIOEPsExceptTargetIOEP;
if ( siblingsExceptBelow != null) {
if ( belowIOEPs != null ) {
siblingsExceptBelow.removeAll(belowIOEPs);
}
for (InteractionOperandEditPart anIoep : siblingsExceptBelow) {
Bounds anIOEPBounds = OperandBoundsComputeHelper.getEditPartBounds(anIoep);
Rectangle anIOEPRect = OperandBoundsComputeHelper.fillRectangle(anIOEPBounds);
anIOEPRect.setWidth(anIOEPBounds.getWidth() + widthDelta);
ICommand anIOEPCommand = OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(anIoep, anIOEPRect);
compositeCommand.add(anIOEPCommand);
}
}
// CF 경계 처리
if ( (direction & PositionConstants.WEST) != 0 ) { // 좌측에서 확대/축소하는 경우
cfX -= widthDelta;
cbCFRequest.setMoveDelta(new Point(-widthDelta, 0));
}
cfWidth += widthDelta;
cbCFRequest.setSizeDelta(new Dimension(widthDelta, 0));
}
if ( !isCalledByParentCFResize ) {
Point moveDelta = cbCFRequest.getMoveDelta();
Dimension sizeDelta = cbCFRequest.getSizeDelta();
if ( !(moveDelta.equals(0, 0) && sizeDelta.equals(0, 0)) ) {
if(compartEP.getParent() instanceof CombinedFragmentEditPart){
CombinedFragmentEditPart parentCfep = (CombinedFragmentEditPart) compartEP.getParent();
Map apexResizeInfo = new HashMap();
apexResizeInfo.put(ApexSequenceRequestConstants.APEX_KEY_RESIZING_COMBINEDFRAGMENTEDITPART_BY_INTERACTIONOPERAND_RESIZE, currentIOEP);
cbCFRequest.setExtendedData(apexResizeInfo);
cbCFRequest.setResizeDirection(direction);
Command compoundCmd = InteractionCompartmentXYLayoutEditPolicy.getCombinedFragmentResizeChildrenCommand(cbCFRequest, parentCfep);
ApexSequenceUtil.apexCompoundCommandToCompositeCommand(compoundCmd, compositeCommand);
}
}
}
return new ICommandProxy(compositeCommand);
}
/**
* apex updated - 사용 안 함
* createIOEPResizeCommand(ChangeBoundsRequest request, InteractionOperandEditPart currentIOEP)로 대체
*
* Create interaction operand resize command
* @param currentIOEP
* @param heightDelta
* @param compartEP
* @param direction
* @return
*/
/* apex replaced
public static Command createIOEPResizeCommand(
InteractionOperandEditPart currentIOEP, int heightDelta,
CombinedFragmentCombinedFragmentCompartmentEditPart compartEP,
int direction) {
Bounds currentIOEPBounds = OperandBoundsComputeHelper
.getEditPartBounds(currentIOEP);
if (currentIOEPBounds == null) {
return null;
}
InteractionOperandEditPart targetIOEP = null;
if ((direction & PositionConstants.NORTH) != 0) {
targetIOEP = OperandBoundsComputeHelper.findPreviousIOEP(compartEP,
currentIOEP);
} else if ((direction & PositionConstants.SOUTH) != 0) {
targetIOEP = OperandBoundsComputeHelper.findLatterIOEP(compartEP,
currentIOEP);
}
CompositeCommand compositeCommand = new CompositeCommand(
"Resize Operand");
// if last operand
if(targetIOEP == null){
if (heightDelta < 0) {
if (currentIOEPBounds.getHeight() - Math.abs(heightDelta) < OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT) {
return null;
}
}
Rectangle currentIOEPRect = OperandBoundsComputeHelper
.fillRectangle(currentIOEPBounds);
currentIOEPRect.setHeight(currentIOEPBounds.getHeight() + heightDelta);
ICommand currentIOEPCommand = OperandBoundsComputeHelper
.createUpdateEditPartBoundsCommand(currentIOEP, currentIOEPRect);
compositeCommand.add(currentIOEPCommand);
// auto update CombinedFragmentEditPart bounds after resize the last operand
if(compartEP.getParent() instanceof CombinedFragmentEditPart){
CombinedFragmentEditPart parent = (CombinedFragmentEditPart) compartEP.getParent();
if (parent.getModel() instanceof Node) {
Node node = (Node) parent.getModel();
if (node.getLayoutConstraint() instanceof Bounds) {
Bounds containerBounds = (Bounds) node
.getLayoutConstraint();
Dimension preferredSize = parent.getFigure().getPreferredSize();
int width = containerBounds.getWidth()!=-1? containerBounds.getWidth() : preferredSize.width();
int height = containerBounds.getHeight()!=-1? containerBounds.getHeight() : preferredSize.height();
height = height + heightDelta;
Rectangle containerRect = new Rectangle(containerBounds.getX(),containerBounds.getY(),width,height);
compositeCommand.add(OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(parent, containerRect));
}
}
}
}else{
Bounds targetIOEPBounds = OperandBoundsComputeHelper
.getEditPartBounds(targetIOEP);
if (targetIOEPBounds == null) {
return null;
}
if (heightDelta > 0) {
if (targetIOEPBounds.getHeight() - heightDelta < OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT) {
return null;
}
} else {
if (currentIOEPBounds.getHeight() - Math.abs(heightDelta) < OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT) {
return null;
}
}
Rectangle targetIOEPRect = OperandBoundsComputeHelper
.fillRectangle(targetIOEPBounds);
Rectangle currentIOEPRect = OperandBoundsComputeHelper
.fillRectangle(currentIOEPBounds);
targetIOEPRect.setHeight(targetIOEPBounds.getHeight() - heightDelta);
currentIOEPRect.setHeight(currentIOEPBounds.getHeight() + heightDelta);
if ((direction & PositionConstants.NORTH) != 0) {
currentIOEPRect.setY(currentIOEPRect.y() - heightDelta);
}else if ((direction & PositionConstants.SOUTH) != 0) {
targetIOEPRect.setY(targetIOEPRect.y() + heightDelta);
}
ICommand previousIOEPCommand = OperandBoundsComputeHelper
.createUpdateEditPartBoundsCommand(targetIOEP, targetIOEPRect);
ICommand currentIOEPCommand = OperandBoundsComputeHelper
.createUpdateEditPartBoundsCommand(currentIOEP, currentIOEPRect);
compositeCommand.add(previousIOEPCommand);
compositeCommand.add(currentIOEPCommand);
}
return new ICommandProxy(compositeCommand);
}
*/
/**
* Compute CombinedFragement's header height
* @param combinedFragmentEditPart
* @return int
*/
public static int computeCombinedFragementHeaderHeight(
CombinedFragmentEditPart combinedFragmentEditPart) {
int headerHeight = 0;
IFigure labelContainer = combinedFragmentEditPart.getPrimaryShape().getHeaderLabel().getParent();
if(labelContainer!=null){
headerHeight = labelContainer.getPreferredSize().height();
}
return headerHeight;
}
/**
* Check if operation resizing on CombinedFragment is allowed
* @param request
* @param child
* @return boolean
*/
public static boolean checkRedistrictOnCFResize(ChangeBoundsRequest request,
EditPart child) {
if(child instanceof CombinedFragmentEditPart){
if ((request.getResizeDirection() & PositionConstants.NORTH_SOUTH) != 0) {
CombinedFragmentEditPart combinedFragmentEditPart = (CombinedFragmentEditPart)child;
if (combinedFragmentEditPart.getChildren().size() > 0
&& combinedFragmentEditPart.getChildren()
.get(0) instanceof CombinedFragmentCombinedFragmentCompartmentEditPart) {
CombinedFragmentCombinedFragmentCompartmentEditPart compartment = (CombinedFragmentCombinedFragmentCompartmentEditPart) combinedFragmentEditPart
.getChildren().get(0);
List<EditPart> combinedFragmentChildrenEditParts = compartment
.getChildren();
CombinedFragment cf = (CombinedFragment) ((CombinedFragmentEditPart) combinedFragmentEditPart)
.resolveSemanticElement();
InteractionOperand targetOperand = null;
if ((request.getResizeDirection() & PositionConstants.NORTH) != 0) {
targetOperand = cf.getOperands().get(0);
} else if ((request.getResizeDirection() & PositionConstants.SOUTH) != 0) {
targetOperand = cf.getOperands().get(
cf.getOperands().size() - 1);
}
InteractionOperandEditPart targetOperandEditPart = OperandBoundsComputeHelper.findTargetOperandEditPart(
cf, targetOperand, combinedFragmentChildrenEditParts);
if(targetOperandEditPart!=null){
int height = targetOperandEditPart.getFigure().getBounds().height();
int heightDelta = request.getSizeDelta().height();
if(heightDelta<0){
if(height-Math.abs(heightDelta) < OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT){
return false;
}
}
}
}
}
}
return true;
}
/**
* Add command for updating adjacent interaction operand bounds after deleting a interaction operand
* @param editPart
* @param cmd
*/
public static void addUpdateBoundsCommandForOperandDelelete(EditPart editPart,ICompositeCommand cmd) {
if(editPart instanceof InteractionOperandEditPart){
if(editPart.getParent() instanceof CombinedFragmentCombinedFragmentCompartmentEditPart){
CombinedFragmentCombinedFragmentCompartmentEditPart compartment = (CombinedFragmentCombinedFragmentCompartmentEditPart)editPart.getParent();
if(compartment.getParent() instanceof CombinedFragmentEditPart){
List<EditPart> combinedFragmentChildrenEditParts = compartment
.getChildren();
InteractionOperandEditPart previousIOEP = null;
InteractionOperandEditPart latterIOEP = null;
boolean isFirstOperand = false;
InteractionOperandEditPart currentioEP = (InteractionOperandEditPart)editPart;
final Rectangle currentioEPBounds = currentioEP.getFigure().getBounds();
for(int i = 0;i<combinedFragmentChildrenEditParts.size();i++) {
EditPart ep = combinedFragmentChildrenEditParts.get(i);
if(ep instanceof InteractionOperandEditPart) {
InteractionOperandEditPart ioEP = (InteractionOperandEditPart)ep;
if(currentioEP == ioEP){
if(previousIOEP!=null){
Object previousIOEPModel = previousIOEP.getModel();
if (previousIOEPModel instanceof Shape) {
Shape previousIOEPShape = (Shape) previousIOEPModel;
if (previousIOEPShape.getLayoutConstraint() instanceof Bounds) {
final Bounds previousIOEPOriginalBounds = (Bounds) previousIOEPShape.getLayoutConstraint();
ICommand command = new AbstractTransactionalCommand(previousIOEP.getEditingDomain(),"Merge operand bounds command",null){
@Override
protected CommandResult doExecuteWithResult(
IProgressMonitor monitor,
IAdaptable info)
throws ExecutionException {
previousIOEPOriginalBounds.setHeight(previousIOEPOriginalBounds.getHeight() + currentioEPBounds.height());
return CommandResult.newOKCommandResult();
}
};
cmd.add(command);
}
}
break;
}else{
isFirstOperand = true;
continue;
}
}else{
previousIOEP = ioEP;
}
if(isFirstOperand){
latterIOEP = ioEP;
break;
}
}
}
if(isFirstOperand && latterIOEP!=null){
Object latterIOEPModel = latterIOEP.getModel();
if (latterIOEPModel instanceof Shape) {
Shape latterIOEPShape = (Shape) latterIOEPModel;
if (latterIOEPShape.getLayoutConstraint() instanceof Bounds) {
final Bounds latterIOEPOriginalBounds = (Bounds) latterIOEPShape.getLayoutConstraint();
ICommand command = new AbstractTransactionalCommand(previousIOEP.getEditingDomain(),"Merge operand bounds command",null){
@Override
protected CommandResult doExecuteWithResult(
IProgressMonitor monitor,
IAdaptable info)
throws ExecutionException {
latterIOEPOriginalBounds.setY(0);
latterIOEPOriginalBounds.setHeight(latterIOEPOriginalBounds.getHeight() + currentioEPBounds.height());
return CommandResult.newOKCommandResult();
}
};
cmd.add(command);
}
}
}
}
}
}
}
/**
* apex updated
*
* extendedData에 IOEP를 넣어줘야 CF에서 lastOperand를 resize하지 않음
*
* Add update InteractionOperand bounds command after IO is created
* @param compartment
* @param request
* @param command
*/
public static void addUpdateBoundsForIOCreationCommand(
CombinedFragmentCombinedFragmentCompartmentEditPart compartment, ViewDescriptor viewDescriptor,
CompositeCommand command) {
List children = compartment.getChildren();
if (children != null && children.size() > 0) {
InteractionOperandEditPart lastOperandEP = OperandBoundsComputeHelper.findLastIOEP(compartment);
// update bounds
if (lastOperandEP != null) {
Bounds lastOperandBounds = OperandBoundsComputeHelper.getInteractionOperandEPBounds(lastOperandEP);
if (lastOperandBounds!= null) {
Rectangle rect = new Rectangle(
lastOperandBounds.getX(),
lastOperandBounds.getY()+lastOperandBounds.getHeight(), lastOperandBounds.getWidth(), OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT);
// auto update CombinedFragmentEditPart bounds after added new operand
if(compartment.getParent() instanceof CombinedFragmentEditPart){
CombinedFragmentEditPart parent = (CombinedFragmentEditPart) compartment
.getParent();
/* apex improved start */
Map apexResizeInfo = new HashMap();
apexResizeInfo.put(ApexSequenceRequestConstants.APEX_KEY_RESIZING_COMBINEDFRAGMENTEDITPART_BY_INTERACTIONOPERAND_CREATE, lastOperandEP);
ChangeBoundsRequest cbRequest = new ChangeBoundsRequest(RequestConstants.REQ_RESIZE);
cbRequest.setExtendedData(apexResizeInfo);
cbRequest.setSizeDelta(new Dimension(0, OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT));
cbRequest.setResizeDirection(PositionConstants.SOUTH);
ApexSequenceUtil.apexCompoundCommandToCompositeCommand(InteractionCompartmentXYLayoutEditPolicy.getCombinedFragmentResizeChildrenCommand(cbRequest, parent),
command);
/* apex improved end */
/* apex replaced
if (parent.getModel() instanceof Node) {
Node node = (Node) parent.getModel();
if (node.getLayoutConstraint() instanceof Bounds) {
Bounds containerBounds = (Bounds) node.getLayoutConstraint();
Dimension preferredSize = parent.getFigure().getPreferredSize();
int width = containerBounds.getWidth()!=-1? containerBounds.getWidth() : preferredSize.width();
int height = containerBounds.getHeight()!=-1? containerBounds.getHeight() : preferredSize.height();
height = height + OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT;
View shapeView = (View) parent.getModel();
ICommand setParentBoundsCmd = new SetBoundsCommand(compartment.getEditingDomain(),
DiagramUIMessages.SetLocationCommand_Label_Resize,
new EObjectAdapter(shapeView), new Rectangle(containerBounds.getX(),containerBounds.getY(),width,height));
command.add(setParentBoundsCmd);
}
}
*/
}
command.add(new SetBoundsCommand(compartment.getEditingDomain(), DiagramUIMessages.SetLocationCommand_Label_Resize, viewDescriptor, rect));
}
}
}else{ // first add operand
if(compartment.getParent() instanceof CombinedFragmentEditPart){
CombinedFragmentEditPart parent = (CombinedFragmentEditPart) compartment
.getParent();
if (parent.getModel() instanceof Node) {
Node node = (Node) parent.getModel();
if (node.getLayoutConstraint() instanceof Bounds) {
Bounds containerBounds = (Bounds) node.getLayoutConstraint();
Dimension preferredSize = parent.getFigure().getPreferredSize();
int width = containerBounds.getWidth()!=-1? containerBounds.getWidth() : preferredSize.width();
int height = containerBounds.getHeight()!=-1? containerBounds.getHeight() : preferredSize.height();
height = height - computeCombinedFragementHeaderHeight(parent);
command.add(new SetBoundsCommand(compartment.getEditingDomain(), DiagramUIMessages.SetLocationCommand_Label_Resize, viewDescriptor, new Rectangle(0,0,width-COMBINED_FRAGMENT_FIGURE_BORDER*2,height-COMBINED_FRAGMENT_FIGURE_BORDER*2)));
}
}
}
}
}
/**
* Check if it is a combined fragment.
*
* @param hint
* the semantic hint
* @return
*/
public static boolean isDerivedCombinedFragment(String hint) {
if(((IHintedType)UMLElementTypes.CombinedFragment_3004).getSemanticHint().equals(hint)) {
return true;
}
if(((IHintedType)UMLElementTypes.ConsiderIgnoreFragment_3007).getSemanticHint().equals(hint)) {
return true;
}
return false;
}
/**
* apex updated - 사용안함 - createIOEPResizeCommand()에서 모두 처리
*
* Command class for updating Interaction Operand EditpPart bounds after CombinedFragment to be resized.
*
*/
/* apex replaced
private static final class UpdateIOBoundsForCFResizeCommand extends
AbstractTransactionalCommand {
private final Bounds ioEPOriginalBounds;
private final ChangeBoundsRequest request;
private final Dimension sizeDelta;
private boolean updateHeight = false;
private int direction;
private UpdateIOBoundsForCFResizeCommand(TransactionalEditingDomain domain,
String label, Bounds ioEPOriginalBounds,
ChangeBoundsRequest request, Dimension sizeDelta,
boolean updateHeight, int direction) {
super(domain, label, null);
this.ioEPOriginalBounds = ioEPOriginalBounds;
this.request = request;
this.sizeDelta = sizeDelta;
this.updateHeight = updateHeight;
this.direction = direction;
}
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
IAdaptable info) throws ExecutionException {
if (updateHeight) {
ioEPOriginalBounds.setHeight(ioEPOriginalBounds.getHeight()
+ sizeDelta.height());
} else if ((direction & PositionConstants.NORTH) != 0) {
ioEPOriginalBounds.setY(ioEPOriginalBounds.getY()
+ sizeDelta.height());
}
if ((request.getResizeDirection() & PositionConstants.EAST_WEST) != 0) {
ioEPOriginalBounds.setWidth(ioEPOriginalBounds.getWidth()
+ sizeDelta.width());
}
return CommandResult.newOKCommandResult();
}
}
*/
/**
* 상방향으로 확대하는 경우 위에 있는 targetOp의 lowest child를 침범하지 않고
* 하뱡향으로 확대하는 경우 아래에 있는 targetOp의 lowest child가 targetOp의 bottom 아래로 밀려내려가지 않도록 처리
*
* 상방향으로 축소하는 경우 currentOp의 lowest child를 침범하지 않고
* 하방향으로 축소하는 경우 currentOp의 lowest child가 currentOp의 bottom 아래로 밀려내려가지 않도록 처리
*
* @param currentIOEP
* @param compartEP
* @param direction
* @param heightDelta
* @return
*/
public static boolean apexIsInvadingTargetChildren(InteractionOperandEditPart currentIOEP,
CombinedFragmentCombinedFragmentCompartmentEditPart compartEP,
int direction,
int heightDelta) {
boolean isInvadingTargetChildren = false;
InteractionOperandEditPart targetIOEP = null;
if ((direction & PositionConstants.NORTH) != 0) {
targetIOEP = OperandBoundsComputeHelper.findPreviousIOEP(compartEP,
currentIOEP);
} else if ((direction & PositionConstants.SOUTH) != 0) {
targetIOEP = OperandBoundsComputeHelper.findLatterIOEP(compartEP,
currentIOEP);
}
if ( targetIOEP != null ) {
List targetIOEPChildrenEditParts = ApexSequenceUtil.apexGetInteractionOperandChildrenEditParts(targetIOEP);
IGraphicalEditPart lowestTargetChildEP = ApexSequenceUtil.apexGetLowestEditPartFromList(targetIOEPChildrenEditParts);
List currentIOEPChildrenEditParts = ApexSequenceUtil.apexGetInteractionOperandChildrenEditParts(currentIOEP);
IGraphicalEditPart lowestCurrentChildEP = ApexSequenceUtil.apexGetLowestEditPartFromList(currentIOEPChildrenEditParts);
if ((direction & PositionConstants.NORTH) != 0) { // 상단에서
if ( heightDelta > 0 ) { // 확대하는 경우
// currentIOEP의 상단이 targetIOEP의 lowest child보다 위로 가면 X
int topNewCurrentIOEP = ApexSequenceUtil.apexGetAbsolutePosition(currentIOEP, SWT.TOP) - Math.abs(heightDelta);
if ( lowestTargetChildEP != null ) {
int bottomTargetIOEPLowestChild = ApexSequenceUtil.apexGetAbsolutePosition(lowestTargetChildEP, SWT.BOTTOM);
if ( topNewCurrentIOEP < bottomTargetIOEPLowestChild + OperandBoundsComputeHelper.COMBINED_FRAGMENT_FIGURE_BORDER) {
isInvadingTargetChildren = true;
}
}
} else { // 축소하는 경우
// currentIOEP의 new lowest child가 currentIOEP의 하단보다 아래로 내려가면 X
if ( lowestCurrentChildEP != null ) {
int bottomNewLowestCurrentChildEP = ApexSequenceUtil.apexGetAbsolutePosition(lowestCurrentChildEP, SWT.BOTTOM) + Math.abs(heightDelta);
int bottomCurrentIOEP = ApexSequenceUtil.apexGetAbsolutePosition(currentIOEP, SWT.BOTTOM);
if ( (bottomNewLowestCurrentChildEP + OperandBoundsComputeHelper.COMBINED_FRAGMENT_FIGURE_BORDER) >= bottomCurrentIOEP ) {
isInvadingTargetChildren = true;
}
}
}
} else if ((direction & PositionConstants.SOUTH) != 0) { // 하단에서
if ( heightDelta > 0 ) { // 확대하는 경우
// targetIOEP의 new lowest child가 targetIOEP의 하단보다 아래로 내려가면 X
if ( lowestTargetChildEP != null ) {
int bottomNewLowestTargetChildEP = ApexSequenceUtil.apexGetAbsolutePosition(lowestTargetChildEP, SWT.BOTTOM) + Math.abs(heightDelta);
int bottomTargetIOEP = ApexSequenceUtil.apexGetAbsolutePosition(targetIOEP, SWT.BOTTOM);
if ( (bottomNewLowestTargetChildEP + OperandBoundsComputeHelper.COMBINED_FRAGMENT_FIGURE_BORDER) >= bottomTargetIOEP ) {
isInvadingTargetChildren = true;
}
}
} else { // 축소하는 경우
// currentIOEP의 하단이 currentIOEP의 lowest child보다 위로 가면 X
if ( lowestCurrentChildEP != null ) {
int bottomNewCurrentIOEP = ApexSequenceUtil.apexGetAbsolutePosition(currentIOEP, SWT.BOTTOM) - Math.abs(heightDelta);
int bottomCurrentIOEPLowestChild = ApexSequenceUtil.apexGetAbsolutePosition(lowestCurrentChildEP, SWT.BOTTOM);
if ( bottomNewCurrentIOEP < bottomCurrentIOEPLowestChild + OperandBoundsComputeHelper.COMBINED_FRAGMENT_FIGURE_BORDER) {
isInvadingTargetChildren = true;
}
}
}
}
} else { // 하나뿐인 Op의 경우
List currentIOEPChildrenEditParts = ApexSequenceUtil.apexGetInteractionOperandChildrenEditParts(currentIOEP);
IGraphicalEditPart lowestCurrentChildEP = ApexSequenceUtil.apexGetLowestEditPartFromList(currentIOEPChildrenEditParts);
if ( (direction & PositionConstants.NORTH) != 0 && heightDelta < 0 ) { // 상단에서 축소하는 경우
// currentIOEP의 new lowest child가 currentIOEP의 하단보다 아래로 내려가면 X
if ( lowestCurrentChildEP != null ) {
int bottomNewLowestCurrentChildEP = ApexSequenceUtil.apexGetAbsolutePosition(lowestCurrentChildEP, SWT.BOTTOM) + Math.abs(heightDelta);
int bottomCurrentIOEP = ApexSequenceUtil.apexGetAbsolutePosition(currentIOEP, SWT.BOTTOM);
if ( (bottomNewLowestCurrentChildEP + OperandBoundsComputeHelper.COMBINED_FRAGMENT_FIGURE_BORDER) >= bottomCurrentIOEP ) {
isInvadingTargetChildren = true;
}
}
ApexSequenceUtil.apexGetCoveredLifelineEditParts(currentIOEP, true);
}
}
return isInvadingTargetChildren;
}
}