Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas FAUVERGUE2015-02-09 07:47:08 -0500
committerNicolas FAUVERGUE2015-02-09 07:47:08 -0500
commit3cd8f3cd05787cc8bca95d8e96903adc9751eb44 (patch)
tree9db535b7638e87ee64306f605eafa415bef78b21
parent9b85d70980c9fbc0ff5a53068ae692693b94b30c (diff)
downloadorg.eclipse.papyrus-3cd8f3cd05787cc8bca95d8e96903adc9751eb44.tar.gz
org.eclipse.papyrus-3cd8f3cd05787cc8bca95d8e96903adc9751eb44.tar.xz
org.eclipse.papyrus-3cd8f3cd05787cc8bca95d8e96903adc9751eb44.zip
454693: [Activity Diagram] ClassCastException when attempting to
activate some contextual actions from a Pin https://bugs.eclipse.org/bugs/show_bug.cgi?id=454693 Change-Id: I74573c902f2735c66ef495ff7ca87994e9e43884 Signed-off-by: Nicolas FAUVERGUE <nicolas.fauvergue@all4tec.net>
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/edit/part/AbstractPinEditPart.java350
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/DistributeAffixedChildNodeLinkAction.java1807
2 files changed, 1086 insertions, 1071 deletions
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/edit/part/AbstractPinEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/edit/part/AbstractPinEditPart.java
index 3c6590568c2..7358405208f 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/edit/part/AbstractPinEditPart.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/edit/part/AbstractPinEditPart.java
@@ -1,169 +1,181 @@
-package org.eclipse.papyrus.uml.diagram.activity.edit.part;
-
-import java.util.List;
-
-import org.eclipse.draw2d.AbstractPointListShape;
-import org.eclipse.gef.ConnectionEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.BorderedBorderItemEditPart;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.papyrus.uml.diagram.activity.edit.parts.ControlFlowEditPart;
-import org.eclipse.papyrus.uml.diagram.activity.edit.parts.ObjectFlowEditPart;
-import org.eclipse.papyrus.uml.diagram.activity.figures.PinFigure;
-import org.eclipse.papyrus.uml.diagram.activity.helper.ActivityFigureDrawer;
-
-
-public abstract class AbstractPinEditPart extends BorderedBorderItemEditPart {
-
- public AbstractPinEditPart(View view) {
- super(view);
- }
-
- /**
- * Notifies listeners that a target connection has been added.
- *
- * @param connection
- * <code>ConnectionEditPart</code> being added as child.
- * @param index
- * Position child is being added into.
- */
- @Override
- protected void fireTargetConnectionAdded(ConnectionEditPart connection, int index) {
- super.fireTargetConnectionAdded(connection, index);
- undrawPinArrow(connection);
- }
-
- /**
- * Notifies listeners that a source connection has been added.
- *
- * @param connection
- * <code>ConnectionEditPart</code> being added as child.
- * @param index
- * Position child is being added into.
- */
- @Override
- protected void fireSourceConnectionAdded(ConnectionEditPart connection, int index) {
- super.fireSourceConnectionAdded(connection, index);
- undrawPinArrow(connection);
- }
-
- /**
- * Undraw the pin arrow
- *
- * @param connection
- * <code>ConnectionEditPart</code> being added as child.
- */
- private void undrawPinArrow(ConnectionEditPart connection) {
- if (isConnectionSupported(connection)) {
- PinFigure pinFigure = getPrimaryShape();
- AbstractPointListShape arrow = pinFigure.getOptionalArrowFigure();
- ActivityFigureDrawer.undrawFigure(arrow);
- }
- }
-
- /**
- * Draw the pin arrow
- *
- */
- private void drawPinArrow() {
- PinFigure pinFigure = getPrimaryShape();
- AbstractPointListShape arrow = pinFigure.getOptionalArrowFigure();
- int side = getBorderItemLocator().getCurrentSideOfParent();
- int direction = ActivityFigureDrawer.getOppositeDirection(side);
- ActivityFigureDrawer.redrawPinArrow(arrow, getMapMode(), getSize(), direction);
- }
-
- /**
- * redraw the pin arrow if current connection doesnt set
- *
- * @param connection
- * <code>ConnectionEditPart</code> being added as child.
- */
- private void redrawPinArrow(List<?> connections) {
- this.redrawPinArrow(null, connections);
- }
-
- /**
- * redraw the pin arrow if no other target connection left
- *
- * @param connection
- * <code>ConnectionEditPart</code> being added as child.
- */
- private void redrawPinArrow(ConnectionEditPart connection, List<?> connections) {
- if (isHasActiveEdge(connection, connections)) {
- undrawPinArrow(connection);
- return;
- }
- drawPinArrow();
- }
-
- private boolean isHasActiveEdge(ConnectionEditPart connection, List<?> connections) {
- if (connection == null && (connections == null || connections.isEmpty())) {
- return false;
- }
- if (connection == null) {
- for (Object next : connections) {
- if (isConnectionSupported((ConnectionEditPart) next)) {
- return true;
- }
- }
- return false;
- }
- for (Object next : connections) {
- if (!connection.equals(next) && isConnectionSupported((ConnectionEditPart) next)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * is connection supported for the pin arrow redraw
- *
- * @param connection
- * <code>ConnectionEditPart</code> being added as child.
- */
- private boolean isConnectionSupported(ConnectionEditPart connection) {
- return (connection instanceof ObjectFlowEditPart || connection instanceof ControlFlowEditPart);
- }
-
- /**
- * Notifies listeners that a target connection has been removed.
- *
- * @param connection
- * <code>ConnectionEditPart</code> being added as child.
- * @param index
- * Position child is being added into.
- */
- @Override
- protected void fireRemovingTargetConnection(ConnectionEditPart connection, int index) {
- super.fireRemovingTargetConnection(connection, index);
- redrawPinArrow(connection, getTargetConnections());
- }
-
- /**
- * Notifies listeners that a source connection has been removed.
- *
- * @param connection
- * <code>ConnectionEditPart</code> being added as child.
- * @param index
- * Position child is being added into.
- */
- @Override
- protected void fireRemovingSourceConnection(ConnectionEditPart connection, int index) {
- super.fireRemovingTargetConnection(connection, index);
- redrawPinArrow(connection, getSourceConnections());
- }
-
- public abstract PinFigure getPrimaryShape();
-
- /**
- * Registers this editpart to recieve notation and semantic events.
- *
- */
- @Override
- public void activate() {
- super.activate();
- // redraw the pin arrow if no connection
- redrawPinArrow(getTargetConnections().isEmpty() ? getSourceConnections() : getTargetConnections());
- }
-}
+package org.eclipse.papyrus.uml.diagram.activity.edit.part;
+
+import java.util.List;
+
+import org.eclipse.draw2d.AbstractPointListShape;
+import org.eclipse.gef.ConnectionEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.BorderedBorderItemEditPart;
+import org.eclipse.gmf.runtime.draw2d.ui.figures.IBorderItemLocator;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.uml.diagram.activity.edit.parts.ControlFlowEditPart;
+import org.eclipse.papyrus.uml.diagram.activity.edit.parts.ObjectFlowEditPart;
+import org.eclipse.papyrus.uml.diagram.activity.figures.PinFigure;
+import org.eclipse.papyrus.uml.diagram.activity.helper.ActivityFigureDrawer;
+
+
+public abstract class AbstractPinEditPart extends BorderedBorderItemEditPart {
+
+ public AbstractPinEditPart(View view) {
+ super(view);
+ }
+
+ /**
+ * Notifies listeners that a target connection has been added.
+ *
+ * @param connection
+ * <code>ConnectionEditPart</code> being added as child.
+ * @param index
+ * Position child is being added into.
+ */
+ @Override
+ protected void fireTargetConnectionAdded(ConnectionEditPart connection, int index) {
+ super.fireTargetConnectionAdded(connection, index);
+ undrawPinArrow(connection);
+ }
+
+ /**
+ * Notifies listeners that a source connection has been added.
+ *
+ * @param connection
+ * <code>ConnectionEditPart</code> being added as child.
+ * @param index
+ * Position child is being added into.
+ */
+ @Override
+ protected void fireSourceConnectionAdded(ConnectionEditPart connection, int index) {
+ super.fireSourceConnectionAdded(connection, index);
+ undrawPinArrow(connection);
+ }
+
+ /**
+ * Undraw the pin arrow
+ *
+ * @param connection
+ * <code>ConnectionEditPart</code> being added as child.
+ */
+ private void undrawPinArrow(ConnectionEditPart connection) {
+ if (isConnectionSupported(connection)) {
+ PinFigure pinFigure = getPrimaryShape();
+ AbstractPointListShape arrow = pinFigure.getOptionalArrowFigure();
+ ActivityFigureDrawer.undrawFigure(arrow);
+ }
+ }
+
+ /**
+ * Draw the pin arrow
+ *
+ */
+ private void drawPinArrow() {
+ PinFigure pinFigure = getPrimaryShape();
+ AbstractPointListShape arrow = pinFigure.getOptionalArrowFigure();
+ int side = getBorderItemLocator().getCurrentSideOfParent();
+ int direction = ActivityFigureDrawer.getOppositeDirection(side);
+ ActivityFigureDrawer.redrawPinArrow(arrow, getMapMode(), getSize(), direction);
+ }
+
+ /**
+ * redraw the pin arrow if current connection doesnt set
+ *
+ * @param connection
+ * <code>ConnectionEditPart</code> being added as child.
+ */
+ private void redrawPinArrow(List<?> connections) {
+ this.redrawPinArrow(null, connections);
+ }
+
+ /**
+ * redraw the pin arrow if no other target connection left
+ *
+ * @param connection
+ * <code>ConnectionEditPart</code> being added as child.
+ */
+ private void redrawPinArrow(ConnectionEditPart connection, List<?> connections) {
+ if (isHasActiveEdge(connection, connections)) {
+ undrawPinArrow(connection);
+ return;
+ }
+ drawPinArrow();
+ }
+
+ private boolean isHasActiveEdge(ConnectionEditPart connection, List<?> connections) {
+ if (connection == null && (connections == null || connections.isEmpty())) {
+ return false;
+ }
+ if (connection == null) {
+ for (Object next : connections) {
+ if (isConnectionSupported((ConnectionEditPart) next)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ for (Object next : connections) {
+ if (!connection.equals(next) && isConnectionSupported((ConnectionEditPart) next)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * is connection supported for the pin arrow redraw
+ *
+ * @param connection
+ * <code>ConnectionEditPart</code> being added as child.
+ */
+ private boolean isConnectionSupported(ConnectionEditPart connection) {
+ return (connection instanceof ObjectFlowEditPart || connection instanceof ControlFlowEditPart);
+ }
+
+ /**
+ * Notifies listeners that a target connection has been removed.
+ *
+ * @param connection
+ * <code>ConnectionEditPart</code> being added as child.
+ * @param index
+ * Position child is being added into.
+ */
+ @Override
+ protected void fireRemovingTargetConnection(ConnectionEditPart connection, int index) {
+ super.fireRemovingTargetConnection(connection, index);
+ redrawPinArrow(connection, getTargetConnections());
+ }
+
+ /**
+ * Notifies listeners that a source connection has been removed.
+ *
+ * @param connection
+ * <code>ConnectionEditPart</code> being added as child.
+ * @param index
+ * Position child is being added into.
+ */
+ @Override
+ protected void fireRemovingSourceConnection(ConnectionEditPart connection, int index) {
+ super.fireRemovingTargetConnection(connection, index);
+ redrawPinArrow(connection, getSourceConnections());
+ }
+
+ public abstract PinFigure getPrimaryShape();
+
+ /**
+ * Registers this editpart to recieve notation and semantic events.
+ *
+ */
+ @Override
+ public void activate() {
+ super.activate();
+ // redraw the pin arrow if no connection
+ redrawPinArrow(getTargetConnections().isEmpty() ? getSourceConnections() : getTargetConnections());
+ }
+
+ @Override
+ public void refreshBounds() {
+ super.refreshBounds();
+ // Update location manually.
+ // Bug 454693 : This allow to refresh the pin location
+ IBorderItemLocator locator = getBorderItemLocator();
+ if (locator != null) {
+ locator.relocate(getFigure());
+ }
+ }
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/DistributeAffixedChildNodeLinkAction.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/DistributeAffixedChildNodeLinkAction.java
index fa401591526..cd4c62ee783 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/DistributeAffixedChildNodeLinkAction.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/DistributeAffixedChildNodeLinkAction.java
@@ -1,902 +1,905 @@
-/*****************************************************************************
- * Copyright (c) 2009-2010 CEA LIST.
- *
- *
- * 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:
- * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.uml.diagram.menu.actions;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import org.eclipse.draw2d.PositionConstants;
-import org.eclipse.draw2d.geometry.Dimension;
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.draw2d.geometry.PointList;
-import org.eclipse.draw2d.geometry.PrecisionPoint;
-import org.eclipse.draw2d.geometry.PrecisionRectangle;
-import org.eclipse.gef.ConnectionEditPart;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.Request;
-import org.eclipse.gef.commands.Command;
-import org.eclipse.gef.commands.CompoundCommand;
-import org.eclipse.gef.commands.UnexecutableCommand;
-import org.eclipse.gef.requests.ChangeBoundsRequest;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
-import org.eclipse.gmf.runtime.diagram.ui.requests.SetAllBendpointRequest;
-import org.eclipse.gmf.runtime.draw2d.ui.figures.IBorderItemLocator;
-import org.eclipse.papyrus.uml.diagram.common.editparts.BorderNamedElementEditPart;
-import org.eclipse.papyrus.uml.diagram.common.layout.DistributionConstants;
-import org.eclipse.papyrus.uml.diagram.common.layout.LayoutUtils;
-import org.eclipse.papyrus.uml.diagram.common.layout.LinkRepresentationForLayoutAction;
-import org.eclipse.papyrus.uml.diagram.common.util.Util;
-import org.eclipse.papyrus.uml.diagram.menu.Activator;
-
-/**
- * This class provides the action to distribute links and ports on a side of a node
- * Two modes are available for this action :
- * <ul>
- * <li>DISTRIBUTE_ON_ONE_END : the user selects links(and affixed child nodes) and nodes to do the distribution the distribution is done only on this node</li>
- * <li>DISTRIBUTE_ON_TWO_END: the user selects only links (and affixed child nodes) ,the distribution is done on the source node and one the target node</li>
- * </ul>
- * The behavior for Affixed child nodes is the same in the 2 modes, they are distributed in the same time that links.
- */
-public class DistributeAffixedChildNodeLinkAction extends AbstractDistributeAction {
-
- /** This list is used to regroup the selected elements by their common parent. */
- private List<NodeRepresentation> commonParentRepresentations;
-
- /** mode used for this action. */
- private int mode;
-
- /** constant for the link selection mode. */
- public final static int DISTRIBUTE_ON_ONE_END = 1;
-
- /** constant for the link/node selection. */
- public final static int DISTRIBUTE_ON_TWO_END = DISTRIBUTE_ON_ONE_END + 1;
-
- /**
- *
- * Constructor.
- *
- * @param distribution
- * the distribution
- * @param selectedElements
- * the selected elements to do the distribution
- */
- public DistributeAffixedChildNodeLinkAction(int distribution, List<IGraphicalEditPart> selectedElements) {
- super(distribution, selectedElements);
-
- }
-
- /**
- * Builds the action.
- *
- * @param list
- * the list
- * @see org.eclipse.papyrus.uml.diagram.common.actions.AbstractDistributeAction#buildAction(java.util.List)
- */
- @Override
- protected void buildAction(List<?> list) {
- this.commonParentRepresentations = new ArrayList<DistributeAffixedChildNodeLinkAction.NodeRepresentation>();
- // we sort the list to get this order:
- // 1: possible parents EditPart
- // 2: Affixed Child Node
- // 3: ConnectionEditPart
- Collections.sort(list, new TypeComparator());
-
- this.mode = getMode(list);
-
- for (Object current : list) {
- if ((current instanceof ConnectionEditPart)) {
- switch (this.mode) {
- case DISTRIBUTE_ON_ONE_END: // the link representation is owned by only one NodeRepresentation
- NodeRepresentation representation = getCorrespondingRepresentation((EditPart) current);
- if (representation != null) {
- LinkRepresentationForLayoutAction link = new LinkRepresentationForLayoutAction((ConnectionEditPart) current);
- representation.addElements(link);
- } else {// no source and no target are in the selection, this link will no be managed
- }
- break;
- case DISTRIBUTE_ON_TWO_END:// the link representation is owned by two NodeRepresentation
- NodeRepresentation representationSource = getCorrespondingRepresentation(((ConnectionEditPart) current).getSource());
- NodeRepresentation representationTarget = getCorrespondingRepresentation(((ConnectionEditPart) current).getTarget());
- LinkRepresentationForLayoutAction linkRep = new LinkRepresentationForLayoutAction((ConnectionEditPart) current);
-
- // we add the source and the target of the link in the commonParentRepresentations
- if (representationSource == null) {
- representationSource = new NodeRepresentation(((ConnectionEditPart) current).getSource());
- this.commonParentRepresentations.add(representationSource);
- }
- if (representationTarget == null) {
- representationTarget = new NodeRepresentation(((ConnectionEditPart) current).getTarget());
- this.commonParentRepresentations.add(representationTarget);
- }
- representationSource.addElements(linkRep);
- representationTarget.addElements(linkRep);
- break;
- default:
- break;
- }
- } else if (Util.isAffixedChildNode((EditPart) current)) {
- NodeRepresentation representation = getCorrespondingRepresentation((EditPart) current);
- if (representation != null) {
- representation.addElements(new AffixedChildNodeRepresentation((EditPart) current));
- } else {
- representation = new NodeRepresentation(((EditPart) current).getParent());
- this.commonParentRepresentations.add(representation);
- representation.addElements(new AffixedChildNodeRepresentation((EditPart) current));
- ;
- }
- } else {
- this.commonParentRepresentations.add(new NodeRepresentation((EditPart) current));
- }
- }
- }
-
- /**
- * Return the mode for this selection.
- *
- * @param list
- * the list of the elements to distribute
- * @return the mode
- * the mode for this selection
- */
- protected int getMode(List<?> list) {
- for (Object current : list) {
- if (current instanceof ConnectionEditPart) {
- EditPart source = ((ConnectionEditPart) current).getSource();
- EditPart target = ((ConnectionEditPart) current).getTarget();
- if (list.contains(source) || list.contains(target)) {
- return DISTRIBUTE_ON_ONE_END;
- }
- }
- }
- return DISTRIBUTE_ON_TWO_END;
- }
-
- /**
- * Gets the command.
- *
- * @return the command
- * @see org.eclipse.papyrus.uml.diagram.common.actions.AbstractDistributeAction#getCommand()
- */
- @Override
- public Command getCommand() {
- CompoundCommand command = new CompoundCommand("Distribute Affixed Child Nodes and Links"); //$NON-NLS-1$
- if (canExistCommand(this.selectedElements) && onOppositeSide()) {
- for (NodeRepresentation current : this.commonParentRepresentations) {
- Command cmd = current.getCommand();
- if (cmd != null && cmd.canExecute()) {
- command.add(cmd);
- }
- }
- }
- return command.isEmpty() ? UnexecutableCommand.INSTANCE : (Command) command;
- }
-
-
- /**
- * On opposite side.
- *
- * @return true, if successful
- */
- protected boolean onOppositeSide() {
- for (NodeRepresentation current : this.commonParentRepresentations) {
- if (!current.onCorrectSide()) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Return The {@link NodeRepresentation} owning the editpart or <code>null</code> if not found.
- *
- * @param ep
- * an editpart
- * @return the corresponding representation
- * The {@link NodeRepresentation} owning the editpart or <code>null</code> if not found
- */
- protected NodeRepresentation getCorrespondingRepresentation(EditPart ep) {
- if (ep instanceof ConnectionEditPart) {
- EditPart source = ((ConnectionEditPart) ep).getSource();
- EditPart target = ((ConnectionEditPart) ep).getTarget();
- for (NodeRepresentation current : commonParentRepresentations) {
- EditPart node = current.getRepresentedNode();
- if (node == source || node == target) {
- return current;
- }
- }
- } else if (Util.isAffixedChildNode(ep)) {
- EditPart parent = ep.getParent();
- for (NodeRepresentation current : commonParentRepresentations) {
- if (current.getRepresentedNode() == parent) {
- return current;
- }
- }
- } else {// we look for a represented node
- for (NodeRepresentation current : commonParentRepresentations) {
- EditPart node = current.getRepresentedNode();
- if (node == ep) {
- return current;
- }
- }
- }
- return null;
- }
-
- // Replaced by a new method in util.Util
- // /**
- // * Test if the EditPart is an Affixed Child Node.
- // *
- // * @param ep
- // * an EditPart
- // * @return true, if is affixed child node <code>true</code> if the {@link EditPart} is an affixed child node and <code>false</code> if not
- // */
- // protected boolean isAffixedChildNode(EditPart ep) {
- // if(ep.getParent() instanceof CompartmentEditPart) {
- // return false;
- // } else if(ep.getParent() instanceof DiagramEditPart) {
- // return false;
- // }
- // return true;
- // }
-
- /**
- * This class provides facilities to represent a parent with its children that we want to distribute.
- * The element to distribute should be {@link LinkRepresentationForLayoutAction} of {@link AffixedChildNodeRepresentation}
- *
- */
- protected class NodeRepresentation {
-
- /** the node represented by this class. */
- private EditPart representedNode;
-
- /** the elements to distribute. */
- private List<Object> elementsToDistribute;
-
- /**
- *
- * Constructor.
- *
- * @param representedNode
- * the represented EditPart
- */
- public NodeRepresentation(EditPart representedNode) {
- this.representedNode = representedNode;
- elementsToDistribute = new ArrayList<Object>();
- }
-
- /**
- * Test if the elements to distribute are on a correct side.
- *
- * @return <code>true</code>, if successful, <code>false</code> if not
- */
- public boolean onCorrectSide() {
- for (Object current : elementsToDistribute) {
- if (current instanceof AffixedChildNodeRepresentation) {
- int side = ((AffixedChildNodeRepresentation) current).getSideOnParent();
- if (distribution == DistributionConstants.DISTRIBUTE_H_CONTAINER_INT || distribution == DistributionConstants.DISTRIBUTE_H_NODES_INT) {
- if (!DistributionConstants.horizontalValuesList.contains(side)) {
- return false;
- }
- } else {// vertical distribution
- if (!DistributionConstants.verticalValuesList.contains(side)) {
- return false;
- }
- }
- } else if (current instanceof LinkRepresentationForLayoutAction) {
- int sourceSide = ((LinkRepresentationForLayoutAction) current).getSideOnSource();
- int targetSide = ((LinkRepresentationForLayoutAction) current).getSideOnTarget();
- if (distribution == DistributionConstants.DISTRIBUTE_H_CONTAINER_INT || distribution == DistributionConstants.DISTRIBUTE_H_NODES_INT) {
- if (!DistributionConstants.horizontalValuesList.contains(sourceSide) && !DistributionConstants.horizontalValuesList.contains(targetSide)) {
- return false;
- }
- } else {// vertical distribution
- if (!DistributionConstants.verticalValuesList.contains(sourceSide) && !DistributionConstants.verticalValuesList.contains(targetSide)) {
- return false;
- }
- }
- }
- }
- return true;
- }
-
- /**
- * This method calculates the new position for the elements
- */
- public void calculateNewLocations() {
- // we sort the element by coordinates
- Collections.sort(this.elementsToDistribute, new CoordinatesComparator(representedNode));
-
- PrecisionRectangle boundsArea = calcultateArea(this.representedNode);
- double[] hSpaceAndvSpace = calculatesSpaceBetweenNodes(boundsArea, this.elementsToDistribute, representedNode);
-
-
- // variable containing the new position for the editpart (x or y following the distribution)
- double newPosition = 0;
- // we determine the location for the first editpart
- switch (distribution) {
- case DistributionConstants.DISTRIBUTE_H_CONTAINER_INT:
- newPosition = (horizontalDegradedMode == false) ? (boundsArea.preciseX + hSpaceAndvSpace[0]) : boundsArea.preciseX();
- break;
- case DistributionConstants.DISTRIBUTE_H_NODES_INT:
- newPosition = boundsArea.preciseX;
- break;
- case DistributionConstants.DISTRIBUTE_V_CONTAINER_INT:
- newPosition = (verticalDegradedMode == false) ? (boundsArea.preciseY + hSpaceAndvSpace[1]) : boundsArea.preciseY();
- break;
- case DistributionConstants.DISTRIBUTE_V_NODES_INT:
- newPosition = boundsArea.preciseY;
- break;
- default:
- break;
- }
- // these 4 booleans indicates if we have already consider a port located on a bad side for the chosen action
- boolean eastPort = false;
- boolean westPort = false;
- boolean northPort = false;
- boolean southPort = false;
-
- for (Object current : elementsToDistribute) {
- int side = PositionConstants.NONE;
- PrecisionRectangle absolutePosition = null;
- // the new location for the editpart
- PrecisionPoint ptLocation = null;
- if (current instanceof LinkRepresentationForLayoutAction) {
- side = ((LinkRepresentationForLayoutAction) current).getCurrentSideOn(representedNode);
- absolutePosition = ((LinkRepresentationForLayoutAction) current).getAbsolutePositionOn(representedNode);
- } else if (current instanceof AffixedChildNodeRepresentation) {
- side = ((AffixedChildNodeRepresentation) current).getSideOnParent();
- absolutePosition = ((AffixedChildNodeRepresentation) current).getAbsolutePosition();
- }
-
- switch (distribution) {
- case DistributionConstants.DISTRIBUTE_H_CONTAINER_INT:
- if (DistributionConstants.horizontalValuesList.contains(side)) {
- ptLocation = new PrecisionPoint(newPosition, absolutePosition.preciseY);
- newPosition += absolutePosition.preciseWidth() + hSpaceAndvSpace[0];
- }
- break;
- case DistributionConstants.DISTRIBUTE_H_NODES_INT:
- if (DistributionConstants.horizontalValuesList.contains(side)) {
- ptLocation = new PrecisionPoint(newPosition, absolutePosition.preciseY);
- newPosition += absolutePosition.preciseWidth() + hSpaceAndvSpace[0];
- } else if (eastPort == false && side == PositionConstants.EAST) {
- eastPort = true;
- ptLocation = new PrecisionPoint(absolutePosition.preciseX, absolutePosition.preciseY);
- newPosition += absolutePosition.preciseWidth() + hSpaceAndvSpace[0];
- } else if (westPort == false && side == PositionConstants.WEST) {
- westPort = true;
- ptLocation = new PrecisionPoint(absolutePosition.preciseX, absolutePosition.preciseY);
- newPosition += absolutePosition.preciseWidth() + hSpaceAndvSpace[0];
- }
- break;
- case DistributionConstants.DISTRIBUTE_V_CONTAINER_INT:
- if (DistributionConstants.verticalValuesList.contains(side)) {
- ptLocation = new PrecisionPoint(absolutePosition.preciseX, newPosition);
- newPosition += absolutePosition.preciseHeight() + hSpaceAndvSpace[1];
- }
- break;
- case DistributionConstants.DISTRIBUTE_V_NODES_INT:
- if (DistributionConstants.verticalValuesList.contains(side)) {
- ptLocation = new PrecisionPoint(absolutePosition.preciseX, newPosition);
- newPosition += absolutePosition.preciseHeight() + hSpaceAndvSpace[1];
- } else if (northPort == false && side == PositionConstants.NORTH) {
- northPort = true;
- ptLocation = new PrecisionPoint(absolutePosition.preciseX, absolutePosition.preciseY);
- newPosition += absolutePosition.preciseHeight() + hSpaceAndvSpace[1];
- } else if (southPort == false && side == PositionConstants.SOUTH) {
- southPort = true;
- ptLocation = new PrecisionPoint(absolutePosition.preciseX, absolutePosition.preciseY);
- newPosition += absolutePosition.preciseHeight() + hSpaceAndvSpace[1];
- }
-
- break;
- default:
- break;
- }
-
- if (current instanceof LinkRepresentationForLayoutAction) {
- ((LinkRepresentationForLayoutAction) current).setNewLocationFor(representedNode, ptLocation);
- } else if (current instanceof AffixedChildNodeRepresentation) {
- ((AffixedChildNodeRepresentation) current).setNewLocation(ptLocation);
- }
- }
- }
-
- /**
- * Return the command for this aciton
- *
- * @return
- * the command for this action
- */
- public Command getCommand() {
- calculateNewLocations();
- CompoundCommand command = new CompoundCommand("Distribute Command"); //$NON-NLS-1$
- for (Object obj : elementsToDistribute) {
- Command cmd = null;
- if (obj instanceof AffixedChildNodeRepresentation) {
- cmd = ((AffixedChildNodeRepresentation) obj).getCommand();
- } else if (obj instanceof LinkRepresentationForLayoutAction) {
- cmd = new CompoundCommand("Move Link and remove bendpoints"); //$NON-NLS-1$
- ((CompoundCommand) cmd).add(((LinkRepresentationForLayoutAction) obj).getCommand());
- // we remove the bendpoints
- Request noBendpoints = new SetAllBendpointRequest(RequestConstants.REQ_SET_ALL_BENDPOINT, new PointList(), null, null);
- ((CompoundCommand) cmd).add(((LinkRepresentationForLayoutAction) obj).getRepresentedLink().getCommand(noBendpoints));
- }
- if (cmd != null && cmd.canExecute()) {
- command.add(cmd);
- }
- }
-
- return command;
- }
-
- /**
- * Calculate the area to do the distribution.
- *
- * @param node
- * the EditPart owning the elements to distribute
- * @return the precision rectangle
- * the area used to do the distribution
- */
- protected PrecisionRectangle calcultateArea(EditPart node) {
- PrecisionRectangle bounds = new PrecisionRectangle();
- Object first = elementsToDistribute.get(0);
- Object last = elementsToDistribute.get(elementsToDistribute.size() - 1);
- Point locStart = new Point();
- PrecisionRectangle locEnd = new PrecisionRectangle();
- switch (distribution) {
- case DistributionConstants.DISTRIBUTE_H_CONTAINER_INT:
- case DistributionConstants.DISTRIBUTE_V_CONTAINER_INT:
- bounds = LayoutUtils.getAbsolutePosition(node);
- break;
- case DistributionConstants.DISTRIBUTE_H_NODES_INT:
- if (first instanceof LinkRepresentationForLayoutAction) {
- locStart = ((LinkRepresentationForLayoutAction) first).getAbsoluteLocationOn(representedNode);
- } else if (first instanceof AffixedChildNodeRepresentation) {
- locStart = ((AffixedChildNodeRepresentation) first).getAbsoluteLocation();
- }
-
- if (last instanceof LinkRepresentationForLayoutAction) {
- locEnd = ((LinkRepresentationForLayoutAction) last).getAbsolutePositionOn(representedNode);
- } else if (last instanceof AffixedChildNodeRepresentation) {
- locEnd = ((AffixedChildNodeRepresentation) last).getAbsolutePosition();
- }
- bounds.setLocation(locStart);
- bounds.setHeight(0);
- bounds.setWidth(locEnd.getRight().preciseX() - locStart.preciseX());
- break;
- case DistributionConstants.DISTRIBUTE_V_NODES_INT:
- if (first instanceof LinkRepresentationForLayoutAction) {
- locStart = ((LinkRepresentationForLayoutAction) first).getAbsoluteLocationOn(representedNode);
- } else if (first instanceof AffixedChildNodeRepresentation) {
- locStart = ((AffixedChildNodeRepresentation) first).getAbsoluteLocation();
- }
-
- if (last instanceof LinkRepresentationForLayoutAction) {
- locEnd = ((LinkRepresentationForLayoutAction) last).getAbsolutePositionOn(representedNode);
- } else if (last instanceof AffixedChildNodeRepresentation) {
- locEnd = ((AffixedChildNodeRepresentation) last).getAbsolutePosition();
- }
- bounds.setLocation(locStart);
- bounds.setHeight(locEnd.getBottom().preciseY() - locStart.preciseY());
- bounds.setWidth(0);
- break;
- default:
- break;
- }
-
-
- return bounds;
- }
-
- /**
- * Add an element to {@link #elementsToDistribute}.
- *
- * @param obj
- * the obj
- */
- public void addElements(Object obj) {
- if (!(obj instanceof AffixedChildNodeRepresentation)) {
- if (!(obj instanceof LinkRepresentationForLayoutAction)) {
- Activator.log.debug("The added element has not a correct type"); //$NON-NLS-1$
- }
- }
- this.elementsToDistribute.add(obj);
- }
-
- /**
- * Gets the represented node.
- *
- * @return the represented node
- */
- public EditPart getRepresentedNode() {
- return representedNode;
- }
-
- /**
- * Calculates the horizontal space and the vertical space to distribute the nodes
- * Set the fields {@link #horizontalDegradedMode} and {@link #verticalDegradedMode} to {@code true} or {@code false}.
- *
- * @param boundsArea
- * the Rectangle used to do the distribution
- * @param nodeChild
- * the node to distribute in the Rectangle
- * @param node
- * the node
- * @return {@code double[2]} with :
- *
- */
- protected double[] calculatesSpaceBetweenNodes(PrecisionRectangle boundsArea, List<Object> nodeChild, EditPart node) {
-
- // reset these 2 fields
- setHorizontalDegradedMode(false);
- setVerticalDegradedMode(false);
-
- // variables used to calculate the spacing
- double vertical = 0;
- double horizontal = 0;
- double vSpace = 0;
- double hSpace = 0;
- double[] hSpaceAndvSpace = new double[] { 0, 0 };
-
- // -------variables used when it's a port selection
- double nbPort = 0;// used to know the number of necessary spaces
-
- // if a port is on a bad side for the current alignment, we need to count it only one time!
- boolean eastPort = false;
- boolean westPort = false;
- boolean northPort = false;
- boolean southPort = false;
-
- // we calculate the length take by the element
- for (Object current : nodeChild) {
- PrecisionRectangle rect = new PrecisionRectangle();
- int side = 0;
- if (current instanceof LinkRepresentationForLayoutAction) {
- rect = ((LinkRepresentationForLayoutAction) current).getAbsolutePositionOn(node);
- side = ((LinkRepresentationForLayoutAction) current).getCurrentSideOn(node);
-
- } else if (current instanceof AffixedChildNodeRepresentation) {
- rect = ((AffixedChildNodeRepresentation) current).getAbsolutePosition();
- side = ((AffixedChildNodeRepresentation) current).getSideOnParent();
-
- }
-
- switch (distribution) {
- case DistributionConstants.DISTRIBUTE_H_CONTAINER_INT:
- if (DistributionConstants.horizontalValuesList.contains(side)) {
- vertical += rect.preciseHeight();
- horizontal += rect.preciseWidth();
- nbPort++;
- }
- break;
- case DistributionConstants.DISTRIBUTE_H_NODES_INT:
- if (DistributionConstants.horizontalValuesList.contains(side)) {
- vertical += rect.preciseHeight();
- horizontal += rect.preciseWidth();
- nbPort++;
- } else if (side == PositionConstants.EAST && eastPort == false) {
- /*
- * the port located on this side are a limit for the action,
- * so we consider only one port located on the east side
- */
- eastPort = true;
- vertical += rect.preciseHeight();
- horizontal += rect.preciseWidth();
- nbPort++;
-
- } else if (side == PositionConstants.WEST && westPort == false) {
- /*
- * the port located on this side are a limit for the action,
- * so we consider only one port located on the west side
- */
- westPort = true;
- vertical += rect.preciseHeight();
- horizontal += rect.preciseWidth();
- nbPort++;
- }
- break;
- case DistributionConstants.DISTRIBUTE_V_CONTAINER_INT:
- if (DistributionConstants.verticalValuesList.contains(side)) {
- vertical += rect.preciseHeight();
- horizontal += rect.preciseWidth();
- nbPort++;
- }
- break;
- case DistributionConstants.DISTRIBUTE_V_NODES_INT:
- if (DistributionConstants.verticalValuesList.contains(side)) {
- vertical += rect.preciseHeight();
- horizontal += rect.preciseWidth();
- nbPort++;
- } else if (side == PositionConstants.NORTH && northPort == false) {
- /*
- * the port located on this side are a limit for the action,
- * so we consider only one port located on the north side
- */
- northPort = true;
- vertical += rect.preciseHeight();
- horizontal += rect.preciseWidth();
- nbPort++;
- } else if (side == PositionConstants.SOUTH && southPort == false) {
- /*
- * the port located on this side are a limit for the action,
- * so we consider only one port located on the south side
- */
- southPort = true;
- vertical += rect.preciseHeight();
- horizontal += rect.preciseWidth();
- nbPort++;
- }
- break;
- default:
- break;
- }
- }
-
-
- // we determine the divisor
- double divisor;
- if (distribution == DistributionConstants.DISTRIBUTE_H_CONTAINER_INT || distribution == DistributionConstants.DISTRIBUTE_V_CONTAINER_INT) {
- divisor = nbPort + 1;
- } else {
- divisor = nbPort - 1;
- }
-
- hSpace = ((boundsArea.preciseWidth() - horizontal) / divisor);
- vSpace = ((boundsArea.preciseHeight() - vertical) / divisor);
-
-
- if (hSpace < 0/* && parentContainer */) {
- setHorizontalDegradedMode(true);
- double diff = boundsArea.preciseWidth() - horizontal;
- hSpace = diff / (divisor - 2);
-
- }
-
- if (vSpace < 0 /* && parentContainer */) {
- setVerticalDegradedMode(true);
- double diff = boundsArea.preciseHeight() - vertical;
- vSpace = diff / (divisor - 2);
-
- }
-
- hSpaceAndvSpace[0] = hSpace;
- hSpaceAndvSpace[1] = vSpace;
- return hSpaceAndvSpace;
- }
- }
-
-
-
- /**
- * The Class CoordinatesComparator.
- */
- protected class CoordinatesComparator implements Comparator<Object> {
-
- /** The reference. */
- private EditPart reference;
-
- /**
- * Instantiates a new coordinates comparator.
- *
- * @param ep
- * the ep
- */
- public CoordinatesComparator(EditPart ep) {
- this.reference = ep;
- }
-
- /**
- * Compare.
- *
- * @param o1
- * the o1
- * @param o2
- * the o2
- * @return the int
- * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
- */
- public int compare(Object o1, Object o2) {
- Point location1 = new Point();
- Point location2 = new Point();
- if (o1 instanceof LinkRepresentationForLayoutAction) {
- location1 = ((LinkRepresentationForLayoutAction) o1).getAbsoluteLocationOn(reference);
- } else if (o1 instanceof AffixedChildNodeRepresentation) {
- location1 = ((AffixedChildNodeRepresentation) o1).getAbsoluteLocation();
- }
- if (o2 instanceof LinkRepresentationForLayoutAction) {
- location2 = ((LinkRepresentationForLayoutAction) o2).getAbsoluteLocationOn(reference);
- } else if (o2 instanceof AffixedChildNodeRepresentation) {
- location2 = ((AffixedChildNodeRepresentation) o2).getAbsoluteLocation();
- }
-
- if (distribution == DistributionConstants.DISTRIBUTE_H_CONTAINER_INT || distribution == DistributionConstants.DISTRIBUTE_H_NODES_INT) {
- if (location1.x < location2.x) {
- return -1;
- } else if (location1.x == location2.x) {
- return 0;
- } else {
- return 1;
- }
- } else { // vertical distribution
- if (location1.y < location2.y) {
- return -1;
- } else if (location1.y == location2.y) {
- return 0;
- } else {
- return 1;
- }
- }
- }
-
- }
-
-
- /**
- * This comparator sorts an EditPart list, the sorted elements are in this order :
- * <ul>
- * <li>1/ The EditPart which are not included in the following criterias</li>
- * <li>2/ The Affixed Child Node</li>
- * <li>3/ The ConnectionEditPart</li>
- * </ul>
- * .
- */
- protected class TypeComparator implements Comparator<Object> {
-
- /**
- * Compare.
- *
- * @param o1
- * the o1
- * @param o2
- * the o2
- * @return the int
- * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
- */
- public int compare(Object o1, Object o2) {
- int index1 = getIndex((EditPart) o1);
- int index2 = getIndex((EditPart) o2);
-
- if (index1 == index2) {
- return 0;
- } else if (index1 < index2) {
- return -1;
- } else {
- return 1;
- }
-
- }
-
- /**
- * Return a int representing the type of EditPart.
- *
- * @param ep
- * an EditPart
- * @return the index
- * <ul>
- * <li>3 : if the EditPart is an Affixed ChildNode EditPart</li>
- * <li>2 : if the EditPart is a {@link ConnectionEditPart}</li>
- * <li>1 : in other cases</li>
- * </ul>
- */
- protected int getIndex(EditPart ep) {
- if (ep instanceof ConnectionEditPart) {
- return 2;
- } else if (Util.isAffixedChildNode(ep)) {
- return 3;
- } else {
- return 1;
- }
- }
- }
-
- /**
- * The Class AffixedChildNodeRepresentation.
- */
- protected class AffixedChildNodeRepresentation {
-
- /** the represented affixed child node. */
- private EditPart affixedChildNode;
-
- /** the new location for the affixed child node. */
- private Point newLocation;
-
- /**
- * Instantiates a new affixed child node representation.
- *
- * @param affixedChildNode
- * the affixed child node
- */
- public AffixedChildNodeRepresentation(EditPart affixedChildNode) {
- this.affixedChildNode = affixedChildNode;
- }
-
- /**
- * Gets the absolute location.
- *
- * @return the absolute location
- */
- public Point getAbsoluteLocation() {
- return getAbsolutePosition().getTopLeft();
- }
-
- /**
- * Gets the side on parent.
- *
- * @return the side on parent
- */
- public int getSideOnParent() {
- IBorderItemLocator loc = ((BorderNamedElementEditPart) this.affixedChildNode).getBorderItemLocator();
- return loc.getCurrentSideOfParent();
-
- }
-
- /**
- * Gets the absolute position.
- *
- * @return the absolute position
- */
- public PrecisionRectangle getAbsolutePosition() {
- return LayoutUtils.getAbsolutePosition(this.affixedChildNode);
- }
-
- /**
- * Gets the command.
- *
- * @return the command
- */
- public Command getCommand() {
- Request req = getRequest();
- if (req == null) {
- return UnexecutableCommand.INSTANCE;
- } else {
- return this.affixedChildNode.getCommand(req);
- }
- }
-
- /**
- * Gets the request.
- *
- * @return the request
- */
- public Request getRequest() {
- if (newLocation != null) {
- ChangeBoundsRequest req = new ChangeBoundsRequest(org.eclipse.gef.RequestConstants.REQ_MOVE);
- req.setEditParts(this.affixedChildNode);
- PrecisionRectangle absolutePosition = LayoutUtils.getAbsolutePosition(this.affixedChildNode);
- PrecisionPoint oldLocation = new PrecisionPoint(absolutePosition.preciseX, absolutePosition.preciseY);
-
- Dimension delta = newLocation.getDifference(oldLocation);
- req.setMoveDelta(new Point(delta.width, delta.height));
- req.setSizeDelta(absolutePosition.getSize().getDifference(absolutePosition.getSize()));
- return req;
- }
- return null;
- }
-
- /**
- * Sets the new location.
- *
- * @param pt
- * the new new location
- */
- public void setNewLocation(Point pt) {
- this.newLocation = pt;
- }
-
- }
-}
+/*****************************************************************************
+ * Copyright (c) 2009-2010 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Bug 454693
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.diagram.menu.actions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.draw2d.geometry.PrecisionPoint;
+import org.eclipse.draw2d.geometry.PrecisionRectangle;
+import org.eclipse.gef.ConnectionEditPart;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.commands.CompoundCommand;
+import org.eclipse.gef.commands.UnexecutableCommand;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.BorderedBorderItemEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.gmf.runtime.diagram.ui.requests.SetAllBendpointRequest;
+import org.eclipse.gmf.runtime.draw2d.ui.figures.IBorderItemLocator;
+import org.eclipse.papyrus.uml.diagram.common.editparts.BorderNamedElementEditPart;
+import org.eclipse.papyrus.uml.diagram.common.layout.DistributionConstants;
+import org.eclipse.papyrus.uml.diagram.common.layout.LayoutUtils;
+import org.eclipse.papyrus.uml.diagram.common.layout.LinkRepresentationForLayoutAction;
+import org.eclipse.papyrus.uml.diagram.common.util.Util;
+import org.eclipse.papyrus.uml.diagram.menu.Activator;
+
+/**
+ * This class provides the action to distribute links and ports on a side of a node
+ * Two modes are available for this action :
+ * <ul>
+ * <li>DISTRIBUTE_ON_ONE_END : the user selects links(and affixed child nodes) and nodes to do the distribution the distribution is done only on this node</li>
+ * <li>DISTRIBUTE_ON_TWO_END: the user selects only links (and affixed child nodes) ,the distribution is done on the source node and one the target node</li>
+ * </ul>
+ * The behavior for Affixed child nodes is the same in the 2 modes, they are distributed in the same time that links.
+ */
+public class DistributeAffixedChildNodeLinkAction extends AbstractDistributeAction {
+
+ /** This list is used to regroup the selected elements by their common parent. */
+ private List<NodeRepresentation> commonParentRepresentations;
+
+ /** mode used for this action. */
+ private int mode;
+
+ /** constant for the link selection mode. */
+ public final static int DISTRIBUTE_ON_ONE_END = 1;
+
+ /** constant for the link/node selection. */
+ public final static int DISTRIBUTE_ON_TWO_END = DISTRIBUTE_ON_ONE_END + 1;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param distribution
+ * the distribution
+ * @param selectedElements
+ * the selected elements to do the distribution
+ */
+ public DistributeAffixedChildNodeLinkAction(int distribution, List<IGraphicalEditPart> selectedElements) {
+ super(distribution, selectedElements);
+
+ }
+
+ /**
+ * Builds the action.
+ *
+ * @param list
+ * the list
+ * @see org.eclipse.papyrus.uml.diagram.common.actions.AbstractDistributeAction#buildAction(java.util.List)
+ */
+ @Override
+ protected void buildAction(List<?> list) {
+ this.commonParentRepresentations = new ArrayList<DistributeAffixedChildNodeLinkAction.NodeRepresentation>();
+ // we sort the list to get this order:
+ // 1: possible parents EditPart
+ // 2: Affixed Child Node
+ // 3: ConnectionEditPart
+ Collections.sort(list, new TypeComparator());
+
+ this.mode = getMode(list);
+
+ for (Object current : list) {
+ if ((current instanceof ConnectionEditPart)) {
+ switch (this.mode) {
+ case DISTRIBUTE_ON_ONE_END: // the link representation is owned by only one NodeRepresentation
+ NodeRepresentation representation = getCorrespondingRepresentation((EditPart) current);
+ if (representation != null) {
+ LinkRepresentationForLayoutAction link = new LinkRepresentationForLayoutAction((ConnectionEditPart) current);
+ representation.addElements(link);
+ } else {// no source and no target are in the selection, this link will no be managed
+ }
+ break;
+ case DISTRIBUTE_ON_TWO_END:// the link representation is owned by two NodeRepresentation
+ NodeRepresentation representationSource = getCorrespondingRepresentation(((ConnectionEditPart) current).getSource());
+ NodeRepresentation representationTarget = getCorrespondingRepresentation(((ConnectionEditPart) current).getTarget());
+ LinkRepresentationForLayoutAction linkRep = new LinkRepresentationForLayoutAction((ConnectionEditPart) current);
+
+ // we add the source and the target of the link in the commonParentRepresentations
+ if (representationSource == null) {
+ representationSource = new NodeRepresentation(((ConnectionEditPart) current).getSource());
+ this.commonParentRepresentations.add(representationSource);
+ }
+ if (representationTarget == null) {
+ representationTarget = new NodeRepresentation(((ConnectionEditPart) current).getTarget());
+ this.commonParentRepresentations.add(representationTarget);
+ }
+ representationSource.addElements(linkRep);
+ representationTarget.addElements(linkRep);
+ break;
+ default:
+ break;
+ }
+ } else if (Util.isAffixedChildNode((EditPart) current)) {
+ NodeRepresentation representation = getCorrespondingRepresentation((EditPart) current);
+ if (representation != null) {
+ representation.addElements(new AffixedChildNodeRepresentation((EditPart) current));
+ } else {
+ representation = new NodeRepresentation(((EditPart) current).getParent());
+ this.commonParentRepresentations.add(representation);
+ representation.addElements(new AffixedChildNodeRepresentation((EditPart) current));
+ ;
+ }
+ } else {
+ this.commonParentRepresentations.add(new NodeRepresentation((EditPart) current));
+ }
+ }
+ }
+
+ /**
+ * Return the mode for this selection.
+ *
+ * @param list
+ * the list of the elements to distribute
+ * @return the mode
+ * the mode for this selection
+ */
+ protected int getMode(List<?> list) {
+ for (Object current : list) {
+ if (current instanceof ConnectionEditPart) {
+ EditPart source = ((ConnectionEditPart) current).getSource();
+ EditPart target = ((ConnectionEditPart) current).getTarget();
+ if (list.contains(source) || list.contains(target)) {
+ return DISTRIBUTE_ON_ONE_END;
+ }
+ }
+ }
+ return DISTRIBUTE_ON_TWO_END;
+ }
+
+ /**
+ * Gets the command.
+ *
+ * @return the command
+ * @see org.eclipse.papyrus.uml.diagram.common.actions.AbstractDistributeAction#getCommand()
+ */
+ @Override
+ public Command getCommand() {
+ CompoundCommand command = new CompoundCommand("Distribute Affixed Child Nodes and Links"); //$NON-NLS-1$
+ if (canExistCommand(this.selectedElements) && onOppositeSide()) {
+ for (NodeRepresentation current : this.commonParentRepresentations) {
+ Command cmd = current.getCommand();
+ if (cmd != null && cmd.canExecute()) {
+ command.add(cmd);
+ }
+ }
+ }
+ return command.isEmpty() ? UnexecutableCommand.INSTANCE : (Command) command;
+ }
+
+
+ /**
+ * On opposite side.
+ *
+ * @return true, if successful
+ */
+ protected boolean onOppositeSide() {
+ for (NodeRepresentation current : this.commonParentRepresentations) {
+ if (!current.onCorrectSide()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return The {@link NodeRepresentation} owning the editpart or <code>null</code> if not found.
+ *
+ * @param ep
+ * an editpart
+ * @return the corresponding representation
+ * The {@link NodeRepresentation} owning the editpart or <code>null</code> if not found
+ */
+ protected NodeRepresentation getCorrespondingRepresentation(EditPart ep) {
+ if (ep instanceof ConnectionEditPart) {
+ EditPart source = ((ConnectionEditPart) ep).getSource();
+ EditPart target = ((ConnectionEditPart) ep).getTarget();
+ for (NodeRepresentation current : commonParentRepresentations) {
+ EditPart node = current.getRepresentedNode();
+ if (node == source || node == target) {
+ return current;
+ }
+ }
+ } else if (Util.isAffixedChildNode(ep)) {
+ EditPart parent = ep.getParent();
+ for (NodeRepresentation current : commonParentRepresentations) {
+ if (current.getRepresentedNode() == parent) {
+ return current;
+ }
+ }
+ } else {// we look for a represented node
+ for (NodeRepresentation current : commonParentRepresentations) {
+ EditPart node = current.getRepresentedNode();
+ if (node == ep) {
+ return current;
+ }
+ }
+ }
+ return null;
+ }
+
+ // Replaced by a new method in util.Util
+ // /**
+ // * Test if the EditPart is an Affixed Child Node.
+ // *
+ // * @param ep
+ // * an EditPart
+ // * @return true, if is affixed child node <code>true</code> if the {@link EditPart} is an affixed child node and <code>false</code> if not
+ // */
+ // protected boolean isAffixedChildNode(EditPart ep) {
+ // if(ep.getParent() instanceof CompartmentEditPart) {
+ // return false;
+ // } else if(ep.getParent() instanceof DiagramEditPart) {
+ // return false;
+ // }
+ // return true;
+ // }
+
+ /**
+ * This class provides facilities to represent a parent with its children that we want to distribute.
+ * The element to distribute should be {@link LinkRepresentationForLayoutAction} of {@link AffixedChildNodeRepresentation}
+ *
+ */
+ protected class NodeRepresentation {
+
+ /** the node represented by this class. */
+ private EditPart representedNode;
+
+ /** the elements to distribute. */
+ private List<Object> elementsToDistribute;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param representedNode
+ * the represented EditPart
+ */
+ public NodeRepresentation(EditPart representedNode) {
+ this.representedNode = representedNode;
+ elementsToDistribute = new ArrayList<Object>();
+ }
+
+ /**
+ * Test if the elements to distribute are on a correct side.
+ *
+ * @return <code>true</code>, if successful, <code>false</code> if not
+ */
+ public boolean onCorrectSide() {
+ for (Object current : elementsToDistribute) {
+ if (current instanceof AffixedChildNodeRepresentation) {
+ int side = ((AffixedChildNodeRepresentation) current).getSideOnParent();
+ if (distribution == DistributionConstants.DISTRIBUTE_H_CONTAINER_INT || distribution == DistributionConstants.DISTRIBUTE_H_NODES_INT) {
+ if (!DistributionConstants.horizontalValuesList.contains(side)) {
+ return false;
+ }
+ } else {// vertical distribution
+ if (!DistributionConstants.verticalValuesList.contains(side)) {
+ return false;
+ }
+ }
+ } else if (current instanceof LinkRepresentationForLayoutAction) {
+ int sourceSide = ((LinkRepresentationForLayoutAction) current).getSideOnSource();
+ int targetSide = ((LinkRepresentationForLayoutAction) current).getSideOnTarget();
+ if (distribution == DistributionConstants.DISTRIBUTE_H_CONTAINER_INT || distribution == DistributionConstants.DISTRIBUTE_H_NODES_INT) {
+ if (!DistributionConstants.horizontalValuesList.contains(sourceSide) && !DistributionConstants.horizontalValuesList.contains(targetSide)) {
+ return false;
+ }
+ } else {// vertical distribution
+ if (!DistributionConstants.verticalValuesList.contains(sourceSide) && !DistributionConstants.verticalValuesList.contains(targetSide)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * This method calculates the new position for the elements
+ */
+ public void calculateNewLocations() {
+ // we sort the element by coordinates
+ Collections.sort(this.elementsToDistribute, new CoordinatesComparator(representedNode));
+
+ PrecisionRectangle boundsArea = calcultateArea(this.representedNode);
+ double[] hSpaceAndvSpace = calculatesSpaceBetweenNodes(boundsArea, this.elementsToDistribute, representedNode);
+
+
+ // variable containing the new position for the editpart (x or y following the distribution)
+ double newPosition = 0;
+ // we determine the location for the first editpart
+ switch (distribution) {
+ case DistributionConstants.DISTRIBUTE_H_CONTAINER_INT:
+ newPosition = (horizontalDegradedMode == false) ? (boundsArea.preciseX + hSpaceAndvSpace[0]) : boundsArea.preciseX();
+ break;
+ case DistributionConstants.DISTRIBUTE_H_NODES_INT:
+ newPosition = boundsArea.preciseX;
+ break;
+ case DistributionConstants.DISTRIBUTE_V_CONTAINER_INT:
+ newPosition = (verticalDegradedMode == false) ? (boundsArea.preciseY + hSpaceAndvSpace[1]) : boundsArea.preciseY();
+ break;
+ case DistributionConstants.DISTRIBUTE_V_NODES_INT:
+ newPosition = boundsArea.preciseY;
+ break;
+ default:
+ break;
+ }
+ // these 4 booleans indicates if we have already consider a port located on a bad side for the chosen action
+ boolean eastPort = false;
+ boolean westPort = false;
+ boolean northPort = false;
+ boolean southPort = false;
+
+ for (Object current : elementsToDistribute) {
+ int side = PositionConstants.NONE;
+ PrecisionRectangle absolutePosition = null;
+ // the new location for the editpart
+ PrecisionPoint ptLocation = null;
+ if (current instanceof LinkRepresentationForLayoutAction) {
+ side = ((LinkRepresentationForLayoutAction) current).getCurrentSideOn(representedNode);
+ absolutePosition = ((LinkRepresentationForLayoutAction) current).getAbsolutePositionOn(representedNode);
+ } else if (current instanceof AffixedChildNodeRepresentation) {
+ side = ((AffixedChildNodeRepresentation) current).getSideOnParent();
+ absolutePosition = ((AffixedChildNodeRepresentation) current).getAbsolutePosition();
+ }
+
+ switch (distribution) {
+ case DistributionConstants.DISTRIBUTE_H_CONTAINER_INT:
+ if (DistributionConstants.horizontalValuesList.contains(side)) {
+ ptLocation = new PrecisionPoint(newPosition, absolutePosition.preciseY);
+ newPosition += absolutePosition.preciseWidth() + hSpaceAndvSpace[0];
+ }
+ break;
+ case DistributionConstants.DISTRIBUTE_H_NODES_INT:
+ if (DistributionConstants.horizontalValuesList.contains(side)) {
+ ptLocation = new PrecisionPoint(newPosition, absolutePosition.preciseY);
+ newPosition += absolutePosition.preciseWidth() + hSpaceAndvSpace[0];
+ } else if (eastPort == false && side == PositionConstants.EAST) {
+ eastPort = true;
+ ptLocation = new PrecisionPoint(absolutePosition.preciseX, absolutePosition.preciseY);
+ newPosition += absolutePosition.preciseWidth() + hSpaceAndvSpace[0];
+ } else if (westPort == false && side == PositionConstants.WEST) {
+ westPort = true;
+ ptLocation = new PrecisionPoint(absolutePosition.preciseX, absolutePosition.preciseY);
+ newPosition += absolutePosition.preciseWidth() + hSpaceAndvSpace[0];
+ }
+ break;
+ case DistributionConstants.DISTRIBUTE_V_CONTAINER_INT:
+ if (DistributionConstants.verticalValuesList.contains(side)) {
+ ptLocation = new PrecisionPoint(absolutePosition.preciseX, newPosition);
+ newPosition += absolutePosition.preciseHeight() + hSpaceAndvSpace[1];
+ }
+ break;
+ case DistributionConstants.DISTRIBUTE_V_NODES_INT:
+ if (DistributionConstants.verticalValuesList.contains(side)) {
+ ptLocation = new PrecisionPoint(absolutePosition.preciseX, newPosition);
+ newPosition += absolutePosition.preciseHeight() + hSpaceAndvSpace[1];
+ } else if (northPort == false && side == PositionConstants.NORTH) {
+ northPort = true;
+ ptLocation = new PrecisionPoint(absolutePosition.preciseX, absolutePosition.preciseY);
+ newPosition += absolutePosition.preciseHeight() + hSpaceAndvSpace[1];
+ } else if (southPort == false && side == PositionConstants.SOUTH) {
+ southPort = true;
+ ptLocation = new PrecisionPoint(absolutePosition.preciseX, absolutePosition.preciseY);
+ newPosition += absolutePosition.preciseHeight() + hSpaceAndvSpace[1];
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ if (current instanceof LinkRepresentationForLayoutAction) {
+ ((LinkRepresentationForLayoutAction) current).setNewLocationFor(representedNode, ptLocation);
+ } else if (current instanceof AffixedChildNodeRepresentation) {
+ ((AffixedChildNodeRepresentation) current).setNewLocation(ptLocation);
+ }
+ }
+ }
+
+ /**
+ * Return the command for this aciton
+ *
+ * @return
+ * the command for this action
+ */
+ public Command getCommand() {
+ calculateNewLocations();
+ CompoundCommand command = new CompoundCommand("Distribute Command"); //$NON-NLS-1$
+ for (Object obj : elementsToDistribute) {
+ Command cmd = null;
+ if (obj instanceof AffixedChildNodeRepresentation) {
+ cmd = ((AffixedChildNodeRepresentation) obj).getCommand();
+ } else if (obj instanceof LinkRepresentationForLayoutAction) {
+ cmd = new CompoundCommand("Move Link and remove bendpoints"); //$NON-NLS-1$
+ ((CompoundCommand) cmd).add(((LinkRepresentationForLayoutAction) obj).getCommand());
+ // we remove the bendpoints
+ Request noBendpoints = new SetAllBendpointRequest(RequestConstants.REQ_SET_ALL_BENDPOINT, new PointList(), null, null);
+ ((CompoundCommand) cmd).add(((LinkRepresentationForLayoutAction) obj).getRepresentedLink().getCommand(noBendpoints));
+ }
+ if (cmd != null && cmd.canExecute()) {
+ command.add(cmd);
+ }
+ }
+
+ return command;
+ }
+
+ /**
+ * Calculate the area to do the distribution.
+ *
+ * @param node
+ * the EditPart owning the elements to distribute
+ * @return the precision rectangle
+ * the area used to do the distribution
+ */
+ protected PrecisionRectangle calcultateArea(EditPart node) {
+ PrecisionRectangle bounds = new PrecisionRectangle();
+ Object first = elementsToDistribute.get(0);
+ Object last = elementsToDistribute.get(elementsToDistribute.size() - 1);
+ Point locStart = new Point();
+ PrecisionRectangle locEnd = new PrecisionRectangle();
+ switch (distribution) {
+ case DistributionConstants.DISTRIBUTE_H_CONTAINER_INT:
+ case DistributionConstants.DISTRIBUTE_V_CONTAINER_INT:
+ bounds = LayoutUtils.getAbsolutePosition(node);
+ break;
+ case DistributionConstants.DISTRIBUTE_H_NODES_INT:
+ if (first instanceof LinkRepresentationForLayoutAction) {
+ locStart = ((LinkRepresentationForLayoutAction) first).getAbsoluteLocationOn(representedNode);
+ } else if (first instanceof AffixedChildNodeRepresentation) {
+ locStart = ((AffixedChildNodeRepresentation) first).getAbsoluteLocation();
+ }
+
+ if (last instanceof LinkRepresentationForLayoutAction) {
+ locEnd = ((LinkRepresentationForLayoutAction) last).getAbsolutePositionOn(representedNode);
+ } else if (last instanceof AffixedChildNodeRepresentation) {
+ locEnd = ((AffixedChildNodeRepresentation) last).getAbsolutePosition();
+ }
+ bounds.setLocation(locStart);
+ bounds.setHeight(0);
+ bounds.setWidth(locEnd.getRight().preciseX() - locStart.preciseX());
+ break;
+ case DistributionConstants.DISTRIBUTE_V_NODES_INT:
+ if (first instanceof LinkRepresentationForLayoutAction) {
+ locStart = ((LinkRepresentationForLayoutAction) first).getAbsoluteLocationOn(representedNode);
+ } else if (first instanceof AffixedChildNodeRepresentation) {
+ locStart = ((AffixedChildNodeRepresentation) first).getAbsoluteLocation();
+ }
+
+ if (last instanceof LinkRepresentationForLayoutAction) {
+ locEnd = ((LinkRepresentationForLayoutAction) last).getAbsolutePositionOn(representedNode);
+ } else if (last instanceof AffixedChildNodeRepresentation) {
+ locEnd = ((AffixedChildNodeRepresentation) last).getAbsolutePosition();
+ }
+ bounds.setLocation(locStart);
+ bounds.setHeight(locEnd.getBottom().preciseY() - locStart.preciseY());
+ bounds.setWidth(0);
+ break;
+ default:
+ break;
+ }
+
+
+ return bounds;
+ }
+
+ /**
+ * Add an element to {@link #elementsToDistribute}.
+ *
+ * @param obj
+ * the obj
+ */
+ public void addElements(Object obj) {
+ if (!(obj instanceof AffixedChildNodeRepresentation)) {
+ if (!(obj instanceof LinkRepresentationForLayoutAction)) {
+ Activator.log.debug("The added element has not a correct type"); //$NON-NLS-1$
+ }
+ }
+ this.elementsToDistribute.add(obj);
+ }
+
+ /**
+ * Gets the represented node.
+ *
+ * @return the represented node
+ */
+ public EditPart getRepresentedNode() {
+ return representedNode;
+ }
+
+ /**
+ * Calculates the horizontal space and the vertical space to distribute the nodes
+ * Set the fields {@link #horizontalDegradedMode} and {@link #verticalDegradedMode} to {@code true} or {@code false}.
+ *
+ * @param boundsArea
+ * the Rectangle used to do the distribution
+ * @param nodeChild
+ * the node to distribute in the Rectangle
+ * @param node
+ * the node
+ * @return {@code double[2]} with :
+ *
+ */
+ protected double[] calculatesSpaceBetweenNodes(PrecisionRectangle boundsArea, List<Object> nodeChild, EditPart node) {
+
+ // reset these 2 fields
+ setHorizontalDegradedMode(false);
+ setVerticalDegradedMode(false);
+
+ // variables used to calculate the spacing
+ double vertical = 0;
+ double horizontal = 0;
+ double vSpace = 0;
+ double hSpace = 0;
+ double[] hSpaceAndvSpace = new double[] { 0, 0 };
+
+ // -------variables used when it's a port selection
+ double nbPort = 0;// used to know the number of necessary spaces
+
+ // if a port is on a bad side for the current alignment, we need to count it only one time!
+ boolean eastPort = false;
+ boolean westPort = false;
+ boolean northPort = false;
+ boolean southPort = false;
+
+ // we calculate the length take by the element
+ for (Object current : nodeChild) {
+ PrecisionRectangle rect = new PrecisionRectangle();
+ int side = 0;
+ if (current instanceof LinkRepresentationForLayoutAction) {
+ rect = ((LinkRepresentationForLayoutAction) current).getAbsolutePositionOn(node);
+ side = ((LinkRepresentationForLayoutAction) current).getCurrentSideOn(node);
+
+ } else if (current instanceof AffixedChildNodeRepresentation) {
+ rect = ((AffixedChildNodeRepresentation) current).getAbsolutePosition();
+ side = ((AffixedChildNodeRepresentation) current).getSideOnParent();
+
+ }
+
+ switch (distribution) {
+ case DistributionConstants.DISTRIBUTE_H_CONTAINER_INT:
+ if (DistributionConstants.horizontalValuesList.contains(side)) {
+ vertical += rect.preciseHeight();
+ horizontal += rect.preciseWidth();
+ nbPort++;
+ }
+ break;
+ case DistributionConstants.DISTRIBUTE_H_NODES_INT:
+ if (DistributionConstants.horizontalValuesList.contains(side)) {
+ vertical += rect.preciseHeight();
+ horizontal += rect.preciseWidth();
+ nbPort++;
+ } else if (side == PositionConstants.EAST && eastPort == false) {
+ /*
+ * the port located on this side are a limit for the action,
+ * so we consider only one port located on the east side
+ */
+ eastPort = true;
+ vertical += rect.preciseHeight();
+ horizontal += rect.preciseWidth();
+ nbPort++;
+
+ } else if (side == PositionConstants.WEST && westPort == false) {
+ /*
+ * the port located on this side are a limit for the action,
+ * so we consider only one port located on the west side
+ */
+ westPort = true;
+ vertical += rect.preciseHeight();
+ horizontal += rect.preciseWidth();
+ nbPort++;
+ }
+ break;
+ case DistributionConstants.DISTRIBUTE_V_CONTAINER_INT:
+ if (DistributionConstants.verticalValuesList.contains(side)) {
+ vertical += rect.preciseHeight();
+ horizontal += rect.preciseWidth();
+ nbPort++;
+ }
+ break;
+ case DistributionConstants.DISTRIBUTE_V_NODES_INT:
+ if (DistributionConstants.verticalValuesList.contains(side)) {
+ vertical += rect.preciseHeight();
+ horizontal += rect.preciseWidth();
+ nbPort++;
+ } else if (side == PositionConstants.NORTH && northPort == false) {
+ /*
+ * the port located on this side are a limit for the action,
+ * so we consider only one port located on the north side
+ */
+ northPort = true;
+ vertical += rect.preciseHeight();
+ horizontal += rect.preciseWidth();
+ nbPort++;
+ } else if (side == PositionConstants.SOUTH && southPort == false) {
+ /*
+ * the port located on this side are a limit for the action,
+ * so we consider only one port located on the south side
+ */
+ southPort = true;
+ vertical += rect.preciseHeight();
+ horizontal += rect.preciseWidth();
+ nbPort++;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ // we determine the divisor
+ double divisor;
+ if (distribution == DistributionConstants.DISTRIBUTE_H_CONTAINER_INT || distribution == DistributionConstants.DISTRIBUTE_V_CONTAINER_INT) {
+ divisor = nbPort + 1;
+ } else {
+ divisor = nbPort - 1;
+ }
+
+ hSpace = ((boundsArea.preciseWidth() - horizontal) / divisor);
+ vSpace = ((boundsArea.preciseHeight() - vertical) / divisor);
+
+
+ if (hSpace < 0/* && parentContainer */) {
+ setHorizontalDegradedMode(true);
+ double diff = boundsArea.preciseWidth() - horizontal;
+ hSpace = diff / (divisor - 2);
+
+ }
+
+ if (vSpace < 0 /* && parentContainer */) {
+ setVerticalDegradedMode(true);
+ double diff = boundsArea.preciseHeight() - vertical;
+ vSpace = diff / (divisor - 2);
+
+ }
+
+ hSpaceAndvSpace[0] = hSpace;
+ hSpaceAndvSpace[1] = vSpace;
+ return hSpaceAndvSpace;
+ }
+ }
+
+
+
+ /**
+ * The Class CoordinatesComparator.
+ */
+ protected class CoordinatesComparator implements Comparator<Object> {
+
+ /** The reference. */
+ private EditPart reference;
+
+ /**
+ * Instantiates a new coordinates comparator.
+ *
+ * @param ep
+ * the ep
+ */
+ public CoordinatesComparator(EditPart ep) {
+ this.reference = ep;
+ }
+
+ /**
+ * Compare.
+ *
+ * @param o1
+ * the o1
+ * @param o2
+ * the o2
+ * @return the int
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(Object o1, Object o2) {
+ Point location1 = new Point();
+ Point location2 = new Point();
+ if (o1 instanceof LinkRepresentationForLayoutAction) {
+ location1 = ((LinkRepresentationForLayoutAction) o1).getAbsoluteLocationOn(reference);
+ } else if (o1 instanceof AffixedChildNodeRepresentation) {
+ location1 = ((AffixedChildNodeRepresentation) o1).getAbsoluteLocation();
+ }
+ if (o2 instanceof LinkRepresentationForLayoutAction) {
+ location2 = ((LinkRepresentationForLayoutAction) o2).getAbsoluteLocationOn(reference);
+ } else if (o2 instanceof AffixedChildNodeRepresentation) {
+ location2 = ((AffixedChildNodeRepresentation) o2).getAbsoluteLocation();
+ }
+
+ if (distribution == DistributionConstants.DISTRIBUTE_H_CONTAINER_INT || distribution == DistributionConstants.DISTRIBUTE_H_NODES_INT) {
+ if (location1.x < location2.x) {
+ return -1;
+ } else if (location1.x == location2.x) {
+ return 0;
+ } else {
+ return 1;
+ }
+ } else { // vertical distribution
+ if (location1.y < location2.y) {
+ return -1;
+ } else if (location1.y == location2.y) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+ }
+
+ }
+
+
+ /**
+ * This comparator sorts an EditPart list, the sorted elements are in this order :
+ * <ul>
+ * <li>1/ The EditPart which are not included in the following criterias</li>
+ * <li>2/ The Affixed Child Node</li>
+ * <li>3/ The ConnectionEditPart</li>
+ * </ul>
+ * .
+ */
+ protected class TypeComparator implements Comparator<Object> {
+
+ /**
+ * Compare.
+ *
+ * @param o1
+ * the o1
+ * @param o2
+ * the o2
+ * @return the int
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(Object o1, Object o2) {
+ int index1 = getIndex((EditPart) o1);
+ int index2 = getIndex((EditPart) o2);
+
+ if (index1 == index2) {
+ return 0;
+ } else if (index1 < index2) {
+ return -1;
+ } else {
+ return 1;
+ }
+
+ }
+
+ /**
+ * Return a int representing the type of EditPart.
+ *
+ * @param ep
+ * an EditPart
+ * @return the index
+ * <ul>
+ * <li>3 : if the EditPart is an Affixed ChildNode EditPart</li>
+ * <li>2 : if the EditPart is a {@link ConnectionEditPart}</li>
+ * <li>1 : in other cases</li>
+ * </ul>
+ */
+ protected int getIndex(EditPart ep) {
+ if (ep instanceof ConnectionEditPart) {
+ return 2;
+ } else if (Util.isAffixedChildNode(ep)) {
+ return 3;
+ } else {
+ return 1;
+ }
+ }
+ }
+
+ /**
+ * The Class AffixedChildNodeRepresentation.
+ */
+ protected class AffixedChildNodeRepresentation {
+
+ /** the represented affixed child node. */
+ private EditPart affixedChildNode;
+
+ /** the new location for the affixed child node. */
+ private Point newLocation;
+
+ /**
+ * Instantiates a new affixed child node representation.
+ *
+ * @param affixedChildNode
+ * the affixed child node
+ */
+ public AffixedChildNodeRepresentation(EditPart affixedChildNode) {
+ this.affixedChildNode = affixedChildNode;
+ }
+
+ /**
+ * Gets the absolute location.
+ *
+ * @return the absolute location
+ */
+ public Point getAbsoluteLocation() {
+ return getAbsolutePosition().getTopLeft();
+ }
+
+ /**
+ * Gets the side on parent.
+ *
+ * @return the side on parent
+ */
+ public int getSideOnParent() {
+ // Bug 454693 : The cast of the border item locator will be BorderedBorderItemEditPart to include pin objects
+ IBorderItemLocator loc = ((BorderedBorderItemEditPart) this.affixedChildNode).getBorderItemLocator();
+ return loc.getCurrentSideOfParent();
+
+ }
+
+ /**
+ * Gets the absolute position.
+ *
+ * @return the absolute position
+ */
+ public PrecisionRectangle getAbsolutePosition() {
+ return LayoutUtils.getAbsolutePosition(this.affixedChildNode);
+ }
+
+ /**
+ * Gets the command.
+ *
+ * @return the command
+ */
+ public Command getCommand() {
+ Request req = getRequest();
+ if (req == null) {
+ return UnexecutableCommand.INSTANCE;
+ } else {
+ return this.affixedChildNode.getCommand(req);
+ }
+ }
+
+ /**
+ * Gets the request.
+ *
+ * @return the request
+ */
+ public Request getRequest() {
+ if (newLocation != null) {
+ ChangeBoundsRequest req = new ChangeBoundsRequest(org.eclipse.gef.RequestConstants.REQ_MOVE);
+ req.setEditParts(this.affixedChildNode);
+ PrecisionRectangle absolutePosition = LayoutUtils.getAbsolutePosition(this.affixedChildNode);
+ PrecisionPoint oldLocation = new PrecisionPoint(absolutePosition.preciseX, absolutePosition.preciseY);
+
+ Dimension delta = newLocation.getDifference(oldLocation);
+ req.setMoveDelta(new Point(delta.width, delta.height));
+ req.setSizeDelta(absolutePosition.getSize().getDifference(absolutePosition.getSize()));
+ return req;
+ }
+ return null;
+ }
+
+ /**
+ * Sets the new location.
+ *
+ * @param pt
+ * the new new location
+ */
+ public void setNewLocation(Point pt) {
+ this.newLocation = pt;
+ }
+
+ }
+}

Back to the top