diff options
author | Asma Smaoui | 2018-03-09 13:46:57 +0000 |
---|---|---|
committer | Ansgar Radermacher | 2018-03-09 14:51:48 +0000 |
commit | c24fe36ff2ed08b048885e68a698dfa5a8f94878 (patch) | |
tree | 479f9d514dd5905faf52ed2fc462d34063b02ee1 /plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.composite/custom-src | |
parent | 0dac77dfab1dd890604fd0d47a26eed191c79d1f (diff) | |
download | org.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/org.eclipse.papyrus.uml.diagram.composite/custom-src')
3 files changed, 270 insertions, 1 deletions
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; + } +} |