Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAsma Smaoui2018-03-09 13:46:57 +0000
committerAnsgar Radermacher2018-03-09 14:51:48 +0000
commitc24fe36ff2ed08b048885e68a698dfa5a8f94878 (patch)
tree479f9d514dd5905faf52ed2fc462d34063b02ee1 /plugins/uml/diagram
parent0dac77dfab1dd890604fd0d47a26eed191c79d1f (diff)
downloadorg.eclipse.papyrus-c24fe36ff2ed08b048885e68a698dfa5a8f94878.tar.gz
org.eclipse.papyrus-c24fe36ff2ed08b048885e68a698dfa5a8f94878.tar.xz
org.eclipse.papyrus-c24fe36ff2ed08b048885e68a698dfa5a8f94878.zip
Bug 527181 - [Composite structure diagram] Initial port location on a
part is top-left corner - Add possibility to override the initial port poisition in ShowHidecontentsAction - Create a custom port position for the composite-structure diagram that locates the diagram for the defining type (if any) and copies port positions from there. Based on similar code in PapyrusRT - Add a new edit policy "CompositeSideAffixedNodesCreation". Change-Id: If3c62f78ea1f2373a610f78260d317174ca4ca12 Signed-off-by: Asma Smaoui <asma.smaoui@cea.fr>
Diffstat (limited to 'plugins/uml/diagram')
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/actions/ShowHideContentsAction.java36
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/RelativePortLocation.java288
-rwxr-xr-xplugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/META-INF/MANIFEST.MF1
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/actions/ShowHideRelatedContentsAction.java19
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/edit/policies/CompositeSideAffixedNodesCreationEditPolicy.java73
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/utils/CompositeStructureDiagramUtils.java179
-rwxr-xr-xplugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/model/compositediagram.gmfgen4
-rwxr-xr-xplugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/src-gen/org/eclipse/papyrus/uml/diagram/composite/edit/parts/PropertyPartEditPartCN.java4
-rwxr-xr-xplugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/src-gen/org/eclipse/papyrus/uml/diagram/composite/edit/parts/StateMachineCompositeEditPart.java4
9 files changed, 594 insertions, 14 deletions
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/actions/ShowHideContentsAction.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/actions/ShowHideContentsAction.java
index a1a3f2b6153..d4109183550 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/actions/ShowHideContentsAction.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/actions/ShowHideContentsAction.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2010 CEA LIST.
+ * Copyright (c) 2010, 2017 CEA LIST.
*
*
* All rights reserved. This program and the accompanying materials
@@ -9,7 +9,9 @@
*
* Contributors:
* Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
- * Benoit maggi (CEA LIST) benoit.maggi@cea.fr -#501701 Showing nested port on Port
+ * Benoit maggi (CEA LIST) benoit.maggi@cea.fr -#501701 Showing nested port on Port
+ * Ansgar Radermacher (CEA LIST) ansgar.radermacher@cea.fr - bug 527181, ports on part layout
+ *
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.actions;
@@ -176,18 +178,27 @@ public class ShowHideContentsAction extends AbstractShowHideAction implements IA
if (!(rep instanceof OptionalEditPartRepresentation)) {
continue;
}
- EditPart ep = ((OptionalEditPartRepresentation) rep).getParentRepresentation().getParentRepresentation().getRepresentedEditPart();
- View compartmentView = ((OptionalEditPartRepresentation) rep).getParentRepresentation().getRepresentedEditPart().getNotationView();
+ OptionalEditPartRepresentation optRep = (OptionalEditPartRepresentation) rep;
+ EditPart ep = optRep.getParentRepresentation().getParentRepresentation().getRepresentedEditPart();
+ View compartmentView = optRep.getParentRepresentation().getRepresentedEditPart().getNotationView();
if (compartmentView != null) {
- req = new ShowHideElementsRequest(compartmentView, ((OptionalEditPartRepresentation) rep).getSemanticElement());
+ req = new ShowHideElementsRequest(compartmentView, optRep.getSemanticElement());
if (isXYLayout(compartmentView, ep)) {
propertyLocation.x += INCREMENT;
propertyLocation.y += INCREMENT;
req.setLocation(new Point(propertyLocation));
- } else if (isAffixedChildNode(ep, ((OptionalEditPartRepresentation) rep).getSemanticElement())) {
+ } else if (isAffixedChildNode(ep, optRep.getSemanticElement())) {
+
portLocation.y += INCREMENT;
- req.setLocation(new Point(portLocation));
+ Point initialPosition = getInitialPortLocation(ep, optRep.getSemanticElement());
+ if (initialPosition != null) {
+ // use initial-position instead of increment-based one
+ req.setLocation(initialPosition);
+ }
+ else {
+ req.setLocation(new Point(portLocation));
+ }
}
Command cmd = ep.getCommand(req);
if (cmd != null && cmd.canExecute()) {
@@ -199,6 +210,17 @@ public class ShowHideContentsAction extends AbstractShowHideAction implements IA
}
/**
+ * Return the initial position of a port on a part. Should be override by subclasses (e.g. composite diagram)
+ *
+ * @param partEditPart edit part of the part within a composite (for which we want to display a port)
+ * @param port the semantic UML2 port which we want to display
+ * @return the initial location of the port or null (if none could be determined)
+ */
+ public Point getInitialPortLocation(EditPart partEditPart, EObject port) {
+ return null;
+ }
+
+ /**
* Test if the child is represented by an affixed child node
* TODO This method will not work if we have an UML element E1 which inherits from
* another element E2 and if E2 is represented by an affixed child node and
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/RelativePortLocation.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/RelativePortLocation.java
new file mode 100644
index 00000000000..5b12424bd2b
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/RelativePortLocation.java
@@ -0,0 +1,288 @@
+/*****************************************************************************
+ * Copyright (c) 2016, 2017 Christian W. Damus and others.
+ *
+ * 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:
+ * Christian W. Damus - Initial API and implementation
+ * Ansgar Radermacher - Moved class from PapyrusRT to base Papyrus
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.diagram.common.helper;
+
+import static java.lang.Math.abs;
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+import static org.eclipse.draw2d.PositionConstants.EAST;
+import static org.eclipse.draw2d.PositionConstants.NORTH;
+import static org.eclipse.draw2d.PositionConstants.SOUTH;
+import static org.eclipse.draw2d.PositionConstants.WEST;
+
+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.gmf.runtime.notation.Bounds;
+
+/**
+ * A representation of the relative location of a port on the border of a shape.
+ * @since 3.1
+ */
+public final class RelativePortLocation {
+
+ private final int side;
+ private final int relativePosition;
+
+ /**
+ * Initializes me.
+ *
+ * @param side
+ * the side of the parent shape on which the port is located.
+ * One of {@link PositionConstants#NORTH}, {@link PositionConstants#WEST},
+ * {@link PositionConstants#SOUTH}, {@link PositionConstants#EAST}
+ *
+ * @param relativePosition
+ * the percentage across or down, as appropriate to the
+ * {@code side}, at which the centre-point of the port is located.
+ * Between 0 and 100, inclusive
+ */
+ private RelativePortLocation(int side, int relativePosition) {
+ super();
+
+ this.side = side;
+ this.relativePosition = relativePosition;
+ }
+
+ /**
+ * Computes the relative position of a port on a shape.
+ *
+ * @param portBounds
+ * the port bounds
+ * @param onShape
+ * the bounds of the shape that it's on
+ *
+ * @return the relative position
+ */
+ public static RelativePortLocation of(Rectangle portBounds, Rectangle onShape) {
+ Point portCenter = portBounds.getCenter();
+
+ int side = getSide(portCenter, onShape);
+ double relativePosition;
+
+ switch (side) {
+ case WEST:
+ case EAST:
+ relativePosition = min(max(0.0, portCenter.preciseY()), onShape.preciseHeight()) * 100
+ / onShape.preciseHeight();
+ break;
+ case NORTH:
+ case SOUTH:
+ relativePosition = min(max(0, portCenter.preciseX()), onShape.preciseWidth()) * 100
+ / onShape.preciseWidth();
+ break;
+ default:
+ throw new IllegalStateException("Could not compute side of relative port location"); //$NON-NLS-1$
+ }
+
+ return new RelativePortLocation(side, (int) Math.round(relativePosition));
+ }
+
+ /**
+ * Computes the relative position of a port on a shape.
+ *
+ * @param portBounds
+ * the port bounds
+ * @param onShape
+ * the bounds of the shape that it's on
+ *
+ * @return the relative position
+ */
+ public static RelativePortLocation of(Bounds portBounds, Bounds onShape) {
+ return of(new Rectangle(portBounds.getX(), portBounds.getY(), portBounds.getWidth(), portBounds.getHeight()),
+ new Rectangle(onShape.getX(), onShape.getY(), onShape.getWidth(), onShape.getHeight()));
+ }
+
+ /**
+ * Computes the side of a rectangle on which a point lies.
+ *
+ * @param portCenter
+ * a point to locate on a rectangle
+ * @param onShape
+ * the rectangle on which to locate it
+ *
+ * @return the side of the rectangle (north, south, west, east) on
+ * which the point lies
+ */
+ static int getSide(Point portCenter, Rectangle onShape) {
+ int result;
+
+ // Where is the centre of the port?
+ int closenessToLeft = abs(portCenter.x());
+ int closenessToTop = abs(portCenter.y());
+ int closenessToRight = abs(onShape.width() - portCenter.x());
+ int closenessToBottom = abs(onShape.height() - portCenter.y());
+
+ if (closenessToLeft < closenessToRight) {
+ // It's left-ish, but maybe top or bottom
+ if (closenessToBottom < closenessToTop) {
+ if (closenessToBottom < closenessToLeft) {
+ result = SOUTH;
+ } else {
+ result = WEST;
+ }
+ } else {
+ if (closenessToTop < closenessToLeft) {
+ result = NORTH;
+ } else {
+ result = WEST;
+ }
+ }
+ } else {
+ // It's right-ish, but maybe top or bottom
+ if (closenessToBottom < closenessToTop) {
+ if (closenessToBottom < closenessToRight) {
+ result = SOUTH;
+ } else {
+ result = EAST;
+ }
+ } else {
+ if (closenessToTop < closenessToRight) {
+ result = NORTH;
+ } else {
+ result = EAST;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Queries the side of the parent shape on which the port is located.
+ *
+ * @return one of {@link PositionConstants#NORTH}, {@link PositionConstants#WEST},
+ * {@link PositionConstants#SOUTH}, {@link PositionConstants#EAST}
+ */
+ public final int side() {
+ return side;
+ }
+
+ /**
+ * Queries the percentage across or down, as appropriate to the
+ * {@linkplain #side() side}, at which the centre-point of the
+ * port is located.
+ *
+ * @return between 0 and 100, inclusive
+ */
+ public final int relativePosition() {
+ return relativePosition;
+ }
+
+ /**
+ * Obtains the point on a shape's {@code bounds} that is the absolute
+ * location that I indicate.
+ *
+ * @param bounds
+ * a shape's bounds
+ * @param portSize
+ * the size of the port to locate (I represent the relative position
+ * of its centre-point)
+ *
+ * @return the point on the {@code bounds} that I represent, in absolute terms of
+ * the port's origin corner
+ */
+ public Point applyTo(Rectangle bounds, Dimension portSize) {
+ Point result = new Point(-portSize.width() / 2, -portSize.height() / 2);
+
+ switch (side()) {
+ case WEST:
+ result.translate(
+ 0,
+ // Relative position up and down the left side
+ bounds.height() * relativePosition() / 100);
+ break;
+ case NORTH:
+ result.translate(
+ // Relative position along the top side
+ bounds.width() * relativePosition() / 100,
+ 0);
+ break;
+ case EAST:
+ result.translate(
+ bounds.width(),
+ // Relative position up and down the right side
+ bounds.height() * relativePosition() / 100);
+ break;
+ case SOUTH:
+ result.translate(
+ // Relative position along the bottom side
+ bounds.width() * relativePosition() / 100,
+ bounds.height());
+ break;
+ default:
+ throw new IllegalStateException("invalid side: " + side());
+ }
+
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + relativePosition;
+ result = prime * result + side;
+ return result;
+ }
+
+ /**
+ * Relative port locations are equal if they are on the same side
+ * at the same relative position.
+ *
+ * @param obj
+ * another object
+ * @return whether they are equivalent relative port locations
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RelativePortLocation other = (RelativePortLocation) obj;
+ if (relativePosition != other.relativePosition)
+ return false;
+ if (side != other.side)
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ String sideString;
+ switch (side) {
+ case NORTH:
+ sideString = "NORTH"; //$NON-NLS-1$
+ break;
+ case WEST:
+ sideString = "WEST"; //$NON-NLS-1$
+ break;
+ case SOUTH:
+ sideString = "SOUTH"; //$NON-NLS-1$
+ break;
+ case EAST:
+ sideString = "EAST"; //$NON-NLS-1$
+ break;
+ default:
+ sideString = "<invalid>"; //$NON-NLS-1$
+ }
+
+ return String.format("Port@(%s, %d%%)", sideString, relativePosition);
+ }
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/META-INF/MANIFEST.MF b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/META-INF/MANIFEST.MF
index 6d4c80c0cc8..71f1f5932fc 100755
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/META-INF/MANIFEST.MF
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/META-INF/MANIFEST.MF
@@ -81,3 +81,4 @@ Bundle-Version: 3.1.0.qualifier
Bundle-Activator: org.eclipse.papyrus.uml.diagram.composite.part.UMLDiagramEditorPlugin
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.papyrus.uml.diagram.composite; singleton:=true
+Import-Package: com.google.common.base;version="21.0.0"
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/actions/ShowHideRelatedContentsAction.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/actions/ShowHideRelatedContentsAction.java
index b39122ed8f3..6acac305bba 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/actions/ShowHideRelatedContentsAction.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/actions/ShowHideRelatedContentsAction.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2009-2011 CEA LIST.
+ * Copyright (c) 2009-2011, 2017 CEA LIST.
*
*
* All rights reserved. This program and the accompanying materials
@@ -9,15 +9,20 @@
*
* Contributors:
* Yann Tanguy (CEA LIST) yann.tanguy@cea.fr - Initial API and implementation
+ * Ansgar Radermacher (CEA LIST) ansgar.radermacher@cea.fr - bug 527181, ports on part layout
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.composite.custom.actions;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.uml.diagram.common.actions.ShowHideContentsAction;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.ShowHideRelatedContentsEditPolicy;
import org.eclipse.papyrus.uml.diagram.composite.custom.messages.Messages;
+import org.eclipse.papyrus.uml.diagram.composite.custom.utils.CompositeStructureDiagramUtils;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Property;
@@ -48,4 +53,16 @@ public class ShowHideRelatedContentsAction extends ShowHideContentsAction {
}
}
}
+
+ /**
+ * Return the initial position of a port on a part.
+ *
+ * @param partEditPart edit part of the part within a composite (for which we want to display a port)
+ * @param port the semantic UML2 port which we want to display
+ * @return the initial location of the port or null (if none could be determined)
+ */
+ @Override
+ public Point getInitialPortLocation(EditPart partEditPart, EObject port) {
+ return CompositeStructureDiagramUtils.getInitialPortLocation(partEditPart, port, null);
+ }
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/edit/policies/CompositeSideAffixedNodesCreationEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/edit/policies/CompositeSideAffixedNodesCreationEditPolicy.java
new file mode 100644
index 00000000000..4e02f9c39e7
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/edit/policies/CompositeSideAffixedNodesCreationEditPolicy.java
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * Copyright (c) 2017 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:
+ * Ansgar Radermacher (CEA) ansgar.radermacher@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.diagram.composite.custom.edit.policies;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.draw2d.FigureListener;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.diagram.ui.commands.SetBoundsCommand;
+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.papyrus.commands.Activator;
+import org.eclipse.papyrus.infra.gmfdiag.common.editpart.NodeEditPart;
+import org.eclipse.papyrus.uml.diagram.common.editpolicies.SideAffixedNodesCreationEditPolicy;
+import org.eclipse.papyrus.uml.diagram.composite.custom.utils.CompositeStructureDiagramUtils;
+import org.eclipse.uml2.uml.Port;
+
+/**
+ * This EditPolicy takes care of the correct placement of ports, see bug 527181
+ */
+public class CompositeSideAffixedNodesCreationEditPolicy extends SideAffixedNodesCreationEditPolicy {
+
+ /**
+ * Extends the inherited method with handling of ports.
+ */
+ @Override
+ protected ICommand getSetBoundsCommand(CreateViewRequest request, ViewDescriptor descriptor) {
+
+ EObject portEObj = descriptor.getElementAdapter().getAdapter(EObject.class);
+ if (portEObj instanceof Port) {
+ final NodeEditPart partEditPart = (NodeEditPart) getHost();
+ if (partEditPart.getFigure().getBounds().width != 0) {
+ Point initialLocation = CompositeStructureDiagramUtils.getInitialPortLocation(getHost(), (Port) portEObj, descriptor);
+ if (initialLocation != null) {
+ return new SetBoundsCommand(partEditPart.getEditingDomain(),
+ DiagramUIMessages.SetLocationCommand_Label_Resize, descriptor, initialLocation);
+ }
+ }
+ else {
+ // host figure does not have proper bounds yet, make deferred calculation
+ partEditPart.getFigure().addFigureListener(new FigureListener() {
+
+ @Override
+ public void figureMoved(IFigure source) {
+ Point initialLocation = CompositeStructureDiagramUtils.getInitialPortLocation(getHost(), (Port) portEObj, descriptor);
+ SetBoundsCommand cmd = new SetBoundsCommand(partEditPart.getEditingDomain(),
+ DiagramUIMessages.SetLocationCommand_Label_Resize, descriptor, initialLocation);
+ try {
+ cmd.execute(null, descriptor);
+ } catch (ExecutionException e) {
+ Activator.log.error(e);
+ }
+ source.removeFigureListener(this);
+ }
+ });
+ }
+ }
+ return super.getSetBoundsCommand(request, descriptor);
+ }
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/utils/CompositeStructureDiagramUtils.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/utils/CompositeStructureDiagramUtils.java
new file mode 100644
index 00000000000..33fcfb85781
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src/org/eclipse/papyrus/uml/diagram/composite/custom/utils/CompositeStructureDiagramUtils.java
@@ -0,0 +1,179 @@
+/*****************************************************************************
+ * Copyright (c) 2014, 2017 CEA LIST, Christian W. Damus, and others.
+ *
+ * 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:
+ * CEA LIST - Initial API and implementation
+ * Christian W. Damus - bugs 493869, 513067
+ * Ansgar Radermacher - move & adapt from PapyrusRT to base Papyrus, bug 527181
+ * Asma Smaoui - bug 527181
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.diagram.composite.custom.utils;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
+import org.eclipse.gmf.runtime.notation.Bounds;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
+import org.eclipse.papyrus.infra.gmfdiag.common.editpart.NodeEditPart;
+import org.eclipse.papyrus.infra.gmfdiag.common.model.NotationModel;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil;
+import org.eclipse.papyrus.infra.tools.util.TypeUtils;
+import org.eclipse.papyrus.uml.diagram.common.Activator;
+import org.eclipse.papyrus.uml.diagram.common.helper.RelativePortLocation;
+import org.eclipse.papyrus.uml.diagram.composite.edit.parts.ClassCompositeEditPart;
+import org.eclipse.papyrus.uml.diagram.composite.edit.parts.CompositeStructureDiagramEditPart;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Type;
+
+/**
+ * Utility method for composite structure diagrams
+ *
+ * @since 3.1
+ */
+public class CompositeStructureDiagramUtils {
+
+ /**
+ * Returns <code>true</code> if the diagram is a composite structure diagram (and has a class as base element)
+ *
+ * @param diagram
+ * the diagram to check
+ * @return <code>true</code> if the diagram is a composite capsule structure diagram
+ */
+ public static boolean isCompositeStructureDiagram(Diagram diagram) {
+ if (diagram == null) {
+ return false;
+ }
+ if (CompositeStructureDiagramEditPart.MODEL_ID.equals(diagram.getType())) {
+ EObject businessElement = diagram.getElement();
+ if (businessElement instanceof org.eclipse.uml2.uml.Class) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Obtains the Composite Structure Diagram for a class
+ *
+ * @param component
+ * b * @return its Composite Structure Diagram, or {@code null} if none is currently known (perhaps
+ * because it is in a resource that is not yet loaded)
+ */
+ public static Diagram getCompositeStructureDiagram(Class component) {
+ return DiagramEditPartsUtil.getDiagram(component, CompositeStructureDiagramUtils::isCompositeStructureDiagram);
+ }
+
+ /**
+ * Obtains the first view of the Type (here the Class) in any diagrams
+ *
+ * @param typingClass: the type of the Part
+ *
+ */
+ public static View getPartTypeFirstView(Class typingClass) {
+ View view = null;
+ try {
+ ServicesRegistry servicesRegistry = ServiceUtilsForEObject.getInstance().getServiceRegistry(typingClass);
+ ModelSet modelSet = servicesRegistry.getService(ModelSet.class);
+ NotationModel notation = (NotationModel) modelSet.getModel(NotationModel.MODEL_ID);
+ List<Diagram> diagrams = notation.getResource().getContents().stream()
+ .map(Diagram.class::cast)
+ .collect(Collectors.toList());
+
+ for (Diagram d : diagrams) {
+ for (Iterator children = d.getChildren().iterator(); children.hasNext();) {
+ View child = (View) children.next();
+ if (ViewUtil.resolveSemanticElement(child).equals(typingClass)) {
+ return child;
+ }
+ }
+ }
+ } catch (Exception e) {
+ Activator.log.error(e);
+ }
+ return view;
+ }
+
+ /**
+ * @param partEditPart
+ * the edit part of an element
+ * @return the type (if it is a UML Class) for a given partEditPart
+ */
+ public static Class getPartType(EditPart partEditPart) {
+ Object modelObj = partEditPart.getModel();
+ if (modelObj instanceof View) {
+ View model = (View) modelObj;
+ EObject elementEObj = model.getElement();
+ if (elementEObj instanceof Property) {
+ Type type = ((Property) elementEObj).getType();
+ if (type instanceof Class) {
+ return (Class) type;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return the initial position of a port on a part.
+ *
+ * @param partEditPart
+ * edit part of the part within a composite (for which we want to display a port)
+ * @param port
+ * the semantic UML2 port which we want to display
+ * @return the initial location of the port or null (if none could be determined)
+ */
+ public static Point getInitialPortLocation(EditPart partEditPart, EObject port, ViewDescriptor descriptor) {
+ Class typingClass = getPartType(partEditPart);
+ View typingClassView = null;
+ Diagram d = null;
+ if (typingClass != null) {
+ d = CompositeStructureDiagramUtils.getCompositeStructureDiagram(typingClass);
+ // look for another diagram if no owning composite diagram
+ if (d != null) {
+ typingClassView = ViewUtil.getChildBySemanticHint(d, ClassCompositeEditPart.VISUAL_ID);
+ } else {
+ typingClassView = getPartTypeFirstView(typingClass);
+ }
+ View portOnTypingClass = null;
+ for (Object child : typingClassView.getChildren()) {
+ if (child instanceof View && ((View) child).getElement() == port) {
+ portOnTypingClass = (View) child;
+ break;
+ }
+ }
+ if (portOnTypingClass != null) {
+ Bounds typingClassBounds = TypeUtils.as(((Node) typingClassView).getLayoutConstraint(), Bounds.class);
+ Bounds portOnTypingClassBounds = TypeUtils.as(((Node) portOnTypingClass).getLayoutConstraint(), Bounds.class);
+ int portWidth = portOnTypingClassBounds.getWidth();
+ int portHeight = portOnTypingClassBounds.getHeight();
+ Rectangle r = new Rectangle(portOnTypingClassBounds.getX(), portOnTypingClassBounds.getY(), portWidth, portHeight);
+ // use 0, 0 as starting point, since the port coordinates are relative to the part.
+ RelativePortLocation relative = RelativePortLocation.of(r, new Rectangle(0, 0, typingClassBounds.getWidth(), typingClassBounds.getHeight()));
+ final Rectangle partBounds = ((NodeEditPart) partEditPart).getFigure().getBounds();
+
+ return relative.applyTo(partBounds, new Dimension(portWidth, portHeight));
+ }
+
+ }
+ return null;
+ }
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/model/compositediagram.gmfgen b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/model/compositediagram.gmfgen
index 40a225f31d9..5da54c43952 100755
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/model/compositediagram.gmfgen
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/model/compositediagram.gmfgen
@@ -440,7 +440,7 @@
<behaviour
xsi:type="gmfgen:CustomBehaviour"
key="org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles.CREATION_ROLE"
- editPolicyQualifiedClassName="org.eclipse.papyrus.uml.diagram.common.editpolicies.SideAffixedNodesCreationEditPolicy"/>
+ editPolicyQualifiedClassName="org.eclipse.papyrus.uml.diagram.composite.custom.edit.policies.CompositeSideAffixedNodesCreationEditPolicy"/>
<modelFacet
modelElementSelector="/0/@expressionProviders/@providers.0/@expressions.2">
<metaClass
@@ -10551,7 +10551,7 @@
iD="org.eclipse.papyrus.uml.diagram.composite"
name="Papyrus Composite Structure Diagram "
provider="Eclipse Modeling Project"
- version="3.0.0.qualifier">
+ version="3.1.0.qualifier">
<requiredPlugins>org.eclipse.draw2d</requiredPlugins>
<requiredPlugins>org.eclipse.gmf.runtime.draw2d.ui</requiredPlugins>
</plugin>
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/src-gen/org/eclipse/papyrus/uml/diagram/composite/edit/parts/PropertyPartEditPartCN.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/src-gen/org/eclipse/papyrus/uml/diagram/composite/edit/parts/PropertyPartEditPartCN.java
index e0e142e6541..e75f2b399d1 100755
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/src-gen/org/eclipse/papyrus/uml/diagram/composite/edit/parts/PropertyPartEditPartCN.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/src-gen/org/eclipse/papyrus/uml/diagram/composite/edit/parts/PropertyPartEditPartCN.java
@@ -55,9 +55,9 @@ import org.eclipse.papyrus.uml.diagram.common.editpolicies.MaskManagedNodeEditPo
import org.eclipse.papyrus.uml.diagram.common.editpolicies.QualifiedNameDisplayEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.ShowHideCompartmentEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.ShowHideRelatedContentsEditPolicy;
-import org.eclipse.papyrus.uml.diagram.common.editpolicies.SideAffixedNodesCreationEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.locator.PortPositionLocator;
import org.eclipse.papyrus.uml.diagram.common.locator.RoundedRectangleLabelPositionLocator;
+import org.eclipse.papyrus.uml.diagram.composite.custom.edit.policies.CompositeSideAffixedNodesCreationEditPolicy;
import org.eclipse.papyrus.uml.diagram.composite.custom.edit.policies.CustomDiagramDragDropEditPolicy;
import org.eclipse.papyrus.uml.diagram.composite.custom.edit.policies.PropertyLayoutEditPolicy;
import org.eclipse.papyrus.uml.diagram.composite.custom.figures.PropertyPartFigure;
@@ -114,7 +114,7 @@ public class PropertyPartEditPartCN extends RoundedCompartmentEditPart {
installEditPolicy(ShowHideRelatedContentsEditPolicy.SHOW_HIDE_RELATED_CONTENTS_POLICY, new ShowHideRelatedContentsEditPolicy());
installEditPolicy(IMaskManagedLabelEditPolicy.MASK_MANAGED_LABEL_EDIT_POLICY, new MaskManagedNodeEditPolicy());
installEditPolicy(EditPolicy.LAYOUT_ROLE, new GetChildLayoutEditPolicy());
- installEditPolicy(EditPolicyRoles.CREATION_ROLE, new SideAffixedNodesCreationEditPolicy());
+ installEditPolicy(EditPolicyRoles.CREATION_ROLE, new CompositeSideAffixedNodesCreationEditPolicy());
// XXX need an SCR to runtime to have another abstract superclass that would let children add reasonable editpolicies
// removeEditPolicy(org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles.CONNECTION_HANDLES_ROLE);
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/src-gen/org/eclipse/papyrus/uml/diagram/composite/edit/parts/StateMachineCompositeEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/src-gen/org/eclipse/papyrus/uml/diagram/composite/edit/parts/StateMachineCompositeEditPart.java
index f12fd539dc9..fbf2ee06e3c 100755
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/src-gen/org/eclipse/papyrus/uml/diagram/composite/edit/parts/StateMachineCompositeEditPart.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/src-gen/org/eclipse/papyrus/uml/diagram/composite/edit/parts/StateMachineCompositeEditPart.java
@@ -53,10 +53,10 @@ import org.eclipse.papyrus.uml.diagram.common.editpolicies.BorderItemResizableEd
import org.eclipse.papyrus.uml.diagram.common.editpolicies.QualifiedNameDisplayEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.ShowHideClassifierContentsEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.ShowHideCompartmentEditPolicy;
-import org.eclipse.papyrus.uml.diagram.common.editpolicies.SideAffixedNodesCreationEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.locator.PortPositionLocator;
import org.eclipse.papyrus.uml.diagram.common.locator.RoundedRectangleLabelPositionLocator;
import org.eclipse.papyrus.uml.diagram.composite.custom.edit.policies.BehaviorLayoutEditPolicy;
+import org.eclipse.papyrus.uml.diagram.composite.custom.edit.policies.CompositeSideAffixedNodesCreationEditPolicy;
import org.eclipse.papyrus.uml.diagram.composite.custom.edit.policies.CustomDiagramDragDropEditPolicy;
import org.eclipse.papyrus.uml.diagram.composite.custom.figures.StateMachineCompositeFigure;
import org.eclipse.papyrus.uml.diagram.composite.part.UMLVisualIDRegistry;
@@ -110,7 +110,7 @@ public class StateMachineCompositeEditPart extends RoundedCompartmentEditPart {
installEditPolicy(ShowHideCompartmentEditPolicy.SHOW_HIDE_COMPARTMENT_POLICY, new ShowHideCompartmentEditPolicy());
installEditPolicy(AffixedNodeAlignmentEditPolicy.AFFIXED_CHILD_ALIGNMENT_ROLE, new AffixedNodeAlignmentEditPolicy());
installEditPolicy(EditPolicy.LAYOUT_ROLE, new GetChildLayoutEditPolicy());
- installEditPolicy(EditPolicyRoles.CREATION_ROLE, new SideAffixedNodesCreationEditPolicy());
+ installEditPolicy(EditPolicyRoles.CREATION_ROLE, new CompositeSideAffixedNodesCreationEditPolicy());
// XXX need an SCR to runtime to have another abstract superclass that would let children add reasonable editpolicies
// removeEditPolicy(org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles.CONNECTION_HANDLES_ROLE);
}

Back to the top