From 51fca5d418f190c3ed6594f5774055b1c37a989b Mon Sep 17 00:00:00 2001 From: Christian W. Damus Date: Thu, 27 Sep 2018 11:32:34 -0400 Subject: Bug 537571: [Sequence Diagram] Time Constraints and Observations Implement the TimeConstraint for DestructionOccurrenceSpecifications. Implement the TimeObservation for ExecutionSpecifications and DestructionOccurrenceSpecifications. Implement time observations and constraints on message ends, on lifelines and on execution specifications, as well as on the lifeline head for creation message timing. Ensure accurate creation feed-back for time constraints and observations with an oversized shadow figure for clarity. JUnit test coverage for creation of time observations and time constraints in the diagram. Change-Id: I57761c0b4819e7c0b2324bebb9f192a0aa495fef Signed-off-by: Christian W. Damus --- .../.settings/.api_filters | 10 - .../AbstractExecutionSpecificationEditPart.java | 48 +- ...DestructionOccurrenceSpecificationEditPart.java | 18 +- .../sequence/edit/parts/CLifeLineEditPart.java | 84 +- .../CustomTimeConstraintBorderNodeEditPart.java | 61 ++ .../CustomTimeObservationBorderNodeEditPart.java | 60 ++ .../edit/parts/ITimeElementBorderNodeEditPart.java | 37 + .../edit/parts/TimeElementEditPartHelper.java | 117 +++ ...nOccurrenceSpecificationSemanticEditPolicy.java | 51 ++ ...omExecutionSpecificationSemanticEditPolicy.java | 7 +- .../policies/CustomLifelineSemanticEditPolicy.java | 76 ++ .../TimeElementCreationFeedbackEditPolicy.java | 202 +++++ .../diagram/sequence/figures/LifelineFigure.java | 8 +- .../sequence/figures/TimeObservationFigure.java | 23 +- .../diagram/sequence/locator/CenterLocator.java | 11 +- .../sequence/locator/TimeElementLocator.java | 108 ++- ...nOccurrenceSpecificationEditPolicyProvider.java | 58 ++ .../sequence/providers/CustomEditPartProvider.java | 15 +- ...omExecutionSpecificationEditPolicyProvider.java | 17 +- .../CustomLifelineEditPolicyProvider.java | 70 ++ ...nOccurrenceSpecificationCreationEditPolicy.java | 45 ++ ...omExecutionSpecificationCreationEditPolicy.java | 77 +- .../LifelineCreationEditPolicy.java | 8 +- .../model/sequenceDiagram.gmfgen | 120 ++- .../plugin.xml | 18 +- .../ActionExecutionSpecificationEditPart.java | 1 + .../BehaviorExecutionSpecificationEditPart.java | 1 + .../sequence/edit/parts/ContextLinkEditPart.java | 4 +- ...DestructionOccurrenceSpecificationEditPart.java | 33 +- .../parts/DurationObservationLinkEditPart.java | 12 +- .../sequence/edit/parts/LifelineEditPart.java | 33 +- .../TimeObservationAppliedStereotypeEditPart.java | 853 ++++++++++++++++++++ .../parts/TimeObservationBorderNodeEditPart.java | 281 +++++++ .../edit/parts/TimeObservationNameEditPart.java | 857 +++++++++++++++++++++ .../sequence/edit/parts/UMLEditPartFactory.java | 9 + .../uml/diagram/sequence/part/Messages.java | 119 +-- .../diagram/sequence/part/UMLDiagramEditor.java | 5 +- .../sequence/part/UMLDiagramEditorUtil.java | 4 +- .../diagram/sequence/part/UMLDiagramUpdater.java | 88 ++- .../diagram/sequence/part/UMLVisualIDRegistry.java | 56 +- .../sequence/providers/ElementInitializers.java | 25 +- .../sequence/providers/UMLElementTypes.java | 12 + .../sequence/providers/UMLParserProvider.java | 40 +- .../sequence/providers/UMLViewProvider.java | 41 +- .../model/uml.elementtypesconfigurations | 6 +- ...ionOccurrenceSpecificationEditHelperAdvice.java | 201 +++++ .../helper/advice/TimeConstraintHelperAdvice.java | 13 +- .../advice/TimeObservationEditHelperAdvice.java | 76 ++ 48 files changed, 3956 insertions(+), 163 deletions(-) create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CustomTimeConstraintBorderNodeEditPart.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CustomTimeObservationBorderNodeEditPart.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/ITimeElementBorderNodeEditPart.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeElementEditPartHelper.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomDestructionOccurrenceSpecificationSemanticEditPolicy.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomLifelineSemanticEditPolicy.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/TimeElementCreationFeedbackEditPolicy.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomDestructionOccurrenceSpecificationEditPolicyProvider.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomLifelineEditPolicyProvider.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomDestructionOccurrenceSpecificationCreationEditPolicy.java mode change 100755 => 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/ContextLinkEditPart.java mode change 100755 => 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/LifelineEditPart.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeObservationAppliedStereotypeEditPart.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeObservationBorderNodeEditPart.java create mode 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeObservationNameEditPart.java mode change 100755 => 100644 plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/UMLEditPartFactory.java create mode 100644 plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/DestructionOccurrenceSpecificationEditHelperAdvice.java create mode 100644 plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/TimeObservationEditHelperAdvice.java (limited to 'plugins') diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/.settings/.api_filters b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/.settings/.api_filters index 3d7cee1853b..6c30062304d 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/.settings/.api_filters +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/.settings/.api_filters @@ -1,11 +1,6 @@ - - - - - @@ -24,10 +19,5 @@ - - - - - diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/AbstractExecutionSpecificationEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/AbstractExecutionSpecificationEditPart.java index ff12bf6cd9d..0889585edc7 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/AbstractExecutionSpecificationEditPart.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/AbstractExecutionSpecificationEditPart.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2017 CEA LIST and others. + * Copyright (c) 2017, 2018 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 2.0 @@ -11,10 +11,12 @@ * Contributors: * CEA LIST - Initial API and implementation * Mickaël ADAM (ALL4TEC) mickael.adam@all4tec.net - Bug 526079 + * Christian W. Damus - bug 536486 *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.edit.parts; import java.util.List; +import java.util.Optional; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.DelegatingLayout; @@ -38,6 +40,7 @@ import org.eclipse.gmf.runtime.common.core.util.Log; import org.eclipse.gmf.runtime.common.core.util.Trace; import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ResizableShapeEditPolicy; +import org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocator; import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIDebugOptions; import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIPlugin; import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIStatusCodes; @@ -69,6 +72,7 @@ import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.SequenceReferenceE import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.UpdateConnectionReferenceEditPolicy; import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.UpdateWeakReferenceForExecSpecEditPolicy; import org.eclipse.papyrus.uml.diagram.sequence.figures.ExecutionSpecificationNodePlate; +import org.eclipse.papyrus.uml.diagram.sequence.locator.CenterLocator; import org.eclipse.papyrus.uml.diagram.sequence.locator.TimeElementLocator; import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes; import org.eclipse.papyrus.uml.diagram.sequence.referencialgrilling.BoundForEditPart; @@ -80,6 +84,7 @@ import org.eclipse.papyrus.uml.diagram.sequence.util.GeneralOrderingUtil; import org.eclipse.papyrus.uml.diagram.sequence.util.OccurrenceSpecificationUtil; import org.eclipse.papyrus.uml.diagram.stereotype.edition.editpolicies.AppliedStereotypeCommentEditPolicy; import org.eclipse.swt.graphics.Color; +import org.eclipse.uml2.uml.MessageEnd; /** * Add implementing IPapyrusEditPart to displaying Stereotypes. @@ -167,14 +172,49 @@ public abstract class AbstractExecutionSpecificationEditPart extends RoundedComp @Override protected void addBorderItem(IFigure borderItemContainer, IBorderItemEditPart borderItemEditPart) { - if (TimeConstraintBorderNodeEditPart.class.isInstance(borderItemEditPart)) { - borderItemContainer.add(borderItemEditPart.getFigure(), - new TimeElementLocator(getMainFigure())); + if (borderItemEditPart instanceof TimeConstraintBorderNodeEditPart || + borderItemEditPart instanceof TimeObservationBorderNodeEditPart) { + Optional messageEnd = Optional.of(borderItemEditPart) + .filter(ITimeElementBorderNodeEditPart.class::isInstance) + .map(ITimeElementBorderNodeEditPart.class::cast) + .flatMap(ITimeElementBorderNodeEditPart::getMessageEnd); + + IBorderItemLocator locator = messageEnd + // It needs to remain anchored to the message end + .map(__ -> new CenterLocator(getMainFigure(), PositionConstants.NONE)) + .map(IBorderItemLocator.class::cast) + .orElseGet(() -> new TimeElementLocator(getMainFigure(), + constraint -> findNearestSide(getMainFigure(), constraint))); + borderItemContainer.add(borderItemEditPart.getFigure(), locator); } else { super.addBorderItem(borderItemContainer, borderItemEditPart); } } + /** + * Given a {@code constraint} proposed for a border item (usually a time element) + * on an execution figure, compute the side to which it should be attached. + * + * @param execFig + * an execution specification figure + * @param constraint + * a proposed time element border item bounds + * + * @return a {@link PositionConstants} side + */ + public static int findNearestSide(IFigure execFig, Rectangle constraint) { + Rectangle figBounds = execFig.getBounds().getCopy(); + Point where = constraint.getTopLeft(); + where.setX((figBounds.width() - constraint.width()) / 2); + + if (DurationLinkUtil.isStart(execFig, where)) { + // Pin it to the top of the execution + return PositionConstants.NORTH; + } else { + // Pin it to the bottome + return PositionConstants.SOUTH; + } + } @Override public EditPart getTargetEditPart(Request request) { diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CDestructionOccurrenceSpecificationEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CDestructionOccurrenceSpecificationEditPart.java index 05cbf46e2fc..71e368b5ea2 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CDestructionOccurrenceSpecificationEditPart.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CDestructionOccurrenceSpecificationEditPart.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2018 CEA LIST, EclipseSource and others. + * Copyright (c) 2018 CEA LIST, EclipseSource, 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 @@ -8,6 +8,7 @@ * * Contributors: * EclipseSource - Initial API and implementation + * Christian W. Damus - bug 536486 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.edit.parts; @@ -15,9 +16,12 @@ package org.eclipse.papyrus.uml.diagram.sequence.edit.parts; import java.util.List; import org.eclipse.draw2d.ConnectionAnchor; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.Request; import org.eclipse.gef.requests.ReconnectRequest; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart; import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest; import org.eclipse.gmf.runtime.diagram.ui.requests.CreateUnspecifiedTypeConnectionRequest; import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure; @@ -25,6 +29,7 @@ import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.uml.diagram.sequence.anchors.CenterAnchor; import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.DestructionOccurrenceGraphicalNodeEditPolicy; import org.eclipse.papyrus.uml.diagram.sequence.figures.DestructionEventNodePlate; +import org.eclipse.papyrus.uml.diagram.sequence.locator.TimeElementLocator; import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes; import org.eclipse.papyrus.uml.diagram.sequence.util.DurationLinkUtil; import org.eclipse.papyrus.uml.diagram.sequence.util.GeneralOrderingUtil; @@ -91,4 +96,15 @@ public class CDestructionOccurrenceSpecificationEditPart extends DestructionOccu return nodePlate; } + @Override + protected void addBorderItem(IFigure borderItemContainer, IBorderItemEditPart borderItemEditPart) { + if (borderItemEditPart instanceof TimeConstraintBorderNodeEditPart + || borderItemEditPart instanceof TimeObservationBorderNodeEditPart) { + borderItemContainer.add(borderItemEditPart.getFigure(), new TimeElementLocator(getMainFigure(), + __ -> PositionConstants.CENTER)); + } else { + super.addBorderItem(borderItemContainer, borderItemEditPart); + } + } + } diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CLifeLineEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CLifeLineEditPart.java index ac063d5a830..386bb347b38 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CLifeLineEditPart.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CLifeLineEditPart.java @@ -12,21 +12,29 @@ * CEA LIST - Initial API and implementation * Mickaël ADAM (ALL4TEC) mickael.adam@all4tec.net - Bug 519621, 526803 * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Bug 531520 - * Christian W. Damus - bug 533672 + * Christian W. Damus - bugs 533672, 536486 *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.edit.parts; import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.OptionalInt; +import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.emf.ecore.EObject; import org.eclipse.gef.ConnectionEditPart; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.Request; import org.eclipse.gef.requests.CreateRequest; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.requests.CreateUnspecifiedTypeRequest; import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest; import org.eclipse.gmf.runtime.emf.type.core.IElementType; @@ -44,8 +52,13 @@ import org.eclipse.papyrus.uml.diagram.sequence.figures.LifeLineLayoutManager; import org.eclipse.papyrus.uml.diagram.sequence.figures.LifelineFigure; import org.eclipse.papyrus.uml.diagram.sequence.figures.LifelineNodeFigure; import org.eclipse.papyrus.uml.diagram.sequence.locator.MessageCreateLifelineAnchor; +import org.eclipse.papyrus.uml.diagram.sequence.locator.TimeElementLocator; import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes; +import org.eclipse.papyrus.uml.diagram.sequence.referencialgrilling.DisplayEvent; import org.eclipse.papyrus.uml.diagram.sequence.util.SequenceUtil; +import org.eclipse.uml2.uml.Message; +import org.eclipse.uml2.uml.MessageEnd; +import org.eclipse.uml2.uml.MessageSort; /** * @author Patrick Tessier @@ -274,4 +287,73 @@ public class CLifeLineEditPart extends LifelineEditPart { } super.eraseTargetFeedback(request); } + + @Override + protected boolean addFixedChild(EditPart childEditPart) { + Optional createEnd = TimeElementLocator.getTimedElement(childEditPart, MessageEnd.class) + .filter(MessageEnd::isReceive) + .filter(end -> end.getMessage().getMessageSort() == MessageSort.CREATE_MESSAGE_LITERAL); + + return createEnd.map(this::getCreateMessageIncomingSide) + .filter(OptionalInt::isPresent) + .map(side -> { + getBorderedFigure().getBorderItemContainer() + .add(((IGraphicalEditPart) childEditPart).getFigure(), + new TimeElementLocator(getMainFigure(), this::getTimeElementSide)); + + return true; + }).orElseGet(() -> super.addFixedChild(childEditPart)); + } + + public OptionalInt getCreateMessageIncomingSide(Point where) { + // The proposed location is in relative coordinates, but the DisplayEvent API is + // in absolute terms (dealing with the mouse pointer) + Point search = where.getCopy(); + getMainFigure().translateToAbsolute(search); + + DisplayEvent displayEvent = new DisplayEvent(this); + MessageEnd end = displayEvent.getMessageEvent(getMainFigure(), search); + if ((end != null) && end.isReceive() && (end.getMessage().getMessageSort() == MessageSort.CREATE_MESSAGE_LITERAL)) { + return getCreateMessageIncomingSide(end); + } + + return OptionalInt.empty(); + } + + private OptionalInt getCreateMessageIncomingSide(MessageEnd end) { + LifelineFigure lifelineFigure = (LifelineFigure) svgNodePlate.getChildren().get(0); + IFigure headerFigure = lifelineFigure.getHeaderFigure(); + + OptionalInt result = OptionalInt.empty(); + + for (Object next : getTargetConnections()) { + ConnectionEditPart incoming = (ConnectionEditPart) next; + EObject semantic = incoming.getAdapter(EObject.class); + if (semantic instanceof Message) { + Message message = (Message) semantic; + if (message.getMessageSort() == MessageSort.CREATE_MESSAGE_LITERAL) { + Point headCenter = headerFigure.getBounds().getCenter(); + lifelineFigure.translateToAbsolute(headCenter); + Connection conn = (Connection) incoming.getFigure(); + Point target = conn.getPoints().getLastPoint(); + if (target.x() > headCenter.x()) { + // The create message is incoming from the right + result = OptionalInt.of(PositionConstants.EAST); + } else { + result = OptionalInt.of(PositionConstants.WEST); + } + } + } + } + + return result; + } + + int getTimeElementSide(Rectangle proposedBounds) { + int incoming = getCreateMessageIncomingSide(proposedBounds.getTopLeft()) + .orElse(PositionConstants.WEST); + + // Put the time element on the side opposite to the incoming create message + return PositionConstants.EAST_WEST ^ incoming; + } } diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CustomTimeConstraintBorderNodeEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CustomTimeConstraintBorderNodeEditPart.java new file mode 100644 index 00000000000..a352eaad2e2 --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CustomTimeConstraintBorderNodeEditPart.java @@ -0,0 +1,61 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.sequence.edit.parts; + +import java.util.Optional; + +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.uml2.uml.MessageEnd; +import org.eclipse.uml2.uml.TimeConstraint; + +/** + * Custom edit-part for {@code TimeConstraint} as a border node. + */ +public class CustomTimeConstraintBorderNodeEditPart extends TimeConstraintBorderNodeEditPart implements ITimeElementBorderNodeEditPart { + + private final TimeElementEditPartHelper helper; + + /** + * Initializes me with my view model. + * + * @param view + * my view model + */ + public CustomTimeConstraintBorderNodeEditPart(View view) { + super(view); + + helper = new TimeElementEditPartHelper(this, this::getMessageEnd); + } + + @Override + protected void refreshBounds() { + if (!helper.refreshBounds(getBorderItemLocator())) { + super.refreshBounds(); + } + } + + @Override + public Optional getMessageEnd() { + return Optional.of(resolveSemanticElement()) + .filter(TimeConstraint.class::isInstance) + .map(TimeConstraint.class::cast) + .flatMap(tc -> tc.getConstrainedElements().stream() + .filter(MessageEnd.class::isInstance) + .map(MessageEnd.class::cast) + .findFirst()); + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CustomTimeObservationBorderNodeEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CustomTimeObservationBorderNodeEditPart.java new file mode 100644 index 00000000000..ef42cec14d7 --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/CustomTimeObservationBorderNodeEditPart.java @@ -0,0 +1,60 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.sequence.edit.parts; + +import java.util.Optional; + +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.uml2.uml.MessageEnd; +import org.eclipse.uml2.uml.TimeObservation; + +/** + * Custom edit-part for {@code TimeObservation} as a border node. + */ +public class CustomTimeObservationBorderNodeEditPart extends TimeObservationBorderNodeEditPart implements ITimeElementBorderNodeEditPart { + + private final TimeElementEditPartHelper helper; + + /** + * Initializes me with my view model. + * + * @param view + * my view model + */ + public CustomTimeObservationBorderNodeEditPart(View view) { + super(view); + + helper = new TimeElementEditPartHelper(this, this::getMessageEnd); + } + + @Override + protected void refreshBounds() { + if (!helper.refreshBounds(getBorderItemLocator())) { + super.refreshBounds(); + } + } + + @Override + public Optional getMessageEnd() { + return Optional.of(resolveSemanticElement()) + .filter(TimeObservation.class::isInstance) + .map(TimeObservation.class::cast) + .map(TimeObservation::getEvent) + .filter(MessageEnd.class::isInstance) + .map(MessageEnd.class::cast); + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/ITimeElementBorderNodeEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/ITimeElementBorderNodeEditPart.java new file mode 100644 index 00000000000..3d7a2327c0e --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/ITimeElementBorderNodeEditPart.java @@ -0,0 +1,37 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.sequence.edit.parts; + +import java.util.Optional; + +import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart; +import org.eclipse.uml2.uml.MessageEnd; +import org.eclipse.uml2.uml.TimeConstraint; +import org.eclipse.uml2.uml.TimeObservation; + +/** + * Protocol for the border-item edit parts controlling the presentation of + * {@link TimeObservation}s and {@link TimeConstraint}s. + */ +public interface ITimeElementBorderNodeEditPart extends IBorderItemEditPart { + + /** + * Obtain the message end that is my time event, if any. + * + * @return my message end, or {@code null} if I do not observe or constrain a message end + */ + Optional getMessageEnd(); +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeElementEditPartHelper.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeElementEditPartHelper.java new file mode 100644 index 00000000000..f950853d680 --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeElementEditPartHelper.java @@ -0,0 +1,117 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.sequence.edit.parts; + +import java.util.Optional; +import java.util.function.Supplier; + +import org.eclipse.draw2d.Connection; +import org.eclipse.draw2d.ConnectionAnchor; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.ConnectionEditPart; +import org.eclipse.gef.EditPart; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; +import org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocator; +import org.eclipse.gmf.runtime.notation.NotationPackage; +import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil; +import org.eclipse.uml2.uml.MessageEnd; + +/** + * Common behaviour that time-element edit-parts can delegate. + */ +class TimeElementEditPartHelper { + + private final IGraphicalEditPart owner; + private final Supplier> messageEndSupplier; + + /** + * Initializes me with the edit-part that I help. + * + * @param owner + * my owner + * @param messageEndSupplier + * extracts the message-end from my {@code owner}'s semantic element + */ + public TimeElementEditPartHelper(IGraphicalEditPart owner, + Supplier> messageEndSupplier) { + + super(); + + this.owner = owner; + this.messageEndSupplier = messageEndSupplier; + } + + boolean refreshBounds(IBorderItemLocator locator) { + boolean result = false; + + if (locator != null) { + Optional messageEndLoc = getMessageEnd().map(this::getLocation); + + if (messageEndLoc.isPresent()) { + // We are fixed by a message end, then + Dimension size = new Dimension( + ((Integer) owner.getStructuralFeatureValue(NotationPackage.eINSTANCE.getSize_Width())).intValue(), + ((Integer) owner.getStructuralFeatureValue(NotationPackage.eINSTANCE.getSize_Height())).intValue()); + + locator.setConstraint(new Rectangle(messageEndLoc.get(), size)); + result = true; + } + } + + return result; + } + + /** + * Obtain the message end that is my observedor constrained event, if any. + * + * @return my message end, or {@code null} if I do not observe or constrain a message end + */ + Optional getMessageEnd() { + return messageEndSupplier.get(); + } + + /** + * Compute the location of a message end. + * + * @param messageEnd + * a message end + * @return the location of that end relative to my parent, or {@code null} if it cannot + * be determined + */ + Point getLocation(MessageEnd messageEnd) { + Point result = null; + + if (messageEnd != null) { + EditPart messageEP = DiagramEditPartsUtil.getChildByEObject(messageEnd.getMessage(), + (IGraphicalEditPart) owner.getRoot().getContents(), true); + if (messageEP instanceof ConnectionEditPart) { + Connection connection = (Connection) ((ConnectionEditPart) messageEP).getFigure(); + ConnectionAnchor anchor = messageEnd.isSend() + ? connection.getSourceAnchor() + : connection.getTargetAnchor(); + if (anchor != null) { + result = anchor.getReferencePoint().getCopy(); + owner.getFigure().getParent().translateToRelative(result); + } + } + } + + return result; + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomDestructionOccurrenceSpecificationSemanticEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomDestructionOccurrenceSpecificationSemanticEditPolicy.java new file mode 100644 index 00000000000..a053f982e5d --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomDestructionOccurrenceSpecificationSemanticEditPolicy.java @@ -0,0 +1,51 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.uml.diagram.sequence.edit.policies; + +import static java.util.Arrays.asList; +import static org.eclipse.papyrus.uml.service.types.utils.SequenceRequestConstant.NEAREST_OCCURRENCE_SPECIFICATION; + +import org.eclipse.gef.commands.Command; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; +import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest; +import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.DefaultSemanticEditPolicy; +import org.eclipse.papyrus.uml.service.types.element.UMLElementTypes; +import org.eclipse.papyrus.uml.service.types.utils.ElementUtil; +import org.eclipse.uml2.uml.DestructionOccurrenceSpecification; +import org.eclipse.uml2.uml.TimeConstraint; +import org.eclipse.uml2.uml.TimeObservation; + +/** + * Custom semantic edit policy for configuration of the constrained or observed element in a + * {@link TimeConstraint} or {@link TimeObservation}, respectively. + */ +public class CustomDestructionOccurrenceSpecificationSemanticEditPolicy extends DefaultSemanticEditPolicy { + + @Override + protected Command getCreateCommand(CreateElementRequest req) { + if (ElementUtil.isTypeOf(req.getElementType(), UMLElementTypes.TIME_CONSTRAINT) + || ElementUtil.isTypeOf(req.getElementType(), UMLElementTypes.TIME_OBSERVATION)) { + + if (!(getHost() instanceof IGraphicalEditPart) || !(req.getContainer() instanceof DestructionOccurrenceSpecification)) { + return super.getCreateCommand(req); + } + + req.setParameter(NEAREST_OCCURRENCE_SPECIFICATION, asList(req.getContainer())); + } + return super.getCreateCommand(req); + } + + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomExecutionSpecificationSemanticEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomExecutionSpecificationSemanticEditPolicy.java index c25063c0263..95fe15a4a05 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomExecutionSpecificationSemanticEditPolicy.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomExecutionSpecificationSemanticEditPolicy.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2018 CEA LIST and others. + * Copyright (c) 2018 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 @@ -8,6 +8,7 @@ * * Contributors: * EclipseSource France - Initial API and implementation + * Christian W. Damus - bug 536486 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.edit.policies; @@ -32,7 +33,9 @@ public class CustomExecutionSpecificationSemanticEditPolicy extends OccurenceSem @Override protected Command getCreateCommand(CreateElementRequest req) { - if (ElementUtil.isTypeOf(req.getElementType(), UMLElementTypes.TIME_CONSTRAINT)) { + if (ElementUtil.isTypeOf(req.getElementType(), UMLElementTypes.TIME_CONSTRAINT) + || ElementUtil.isTypeOf(req.getElementType(), UMLElementTypes.TIME_OBSERVATION)) { + Object loc = req.getParameter("initialMouseLocationForCreation"); // evaluate parameters if (!Point.class.isInstance(loc) diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomLifelineSemanticEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomLifelineSemanticEditPolicy.java new file mode 100644 index 00000000000..60b6adaf2ea --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/CustomLifelineSemanticEditPolicy.java @@ -0,0 +1,76 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.sequence.edit.policies; + +import java.util.Arrays; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.commands.UnexecutableCommand; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; +import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest; +import org.eclipse.papyrus.uml.diagram.common.editpolicies.CustomDefaultSemanticEditPolicy; +import org.eclipse.papyrus.uml.diagram.sequence.referencialgrilling.DisplayEvent; +import org.eclipse.papyrus.uml.service.types.element.UMLElementTypes; +import org.eclipse.papyrus.uml.service.types.utils.ElementUtil; +import org.eclipse.papyrus.uml.service.types.utils.SequenceRequestConstant; +import org.eclipse.uml2.uml.MessageOccurrenceSpecification; +import org.eclipse.uml2.uml.TimeConstraint; + +/** + * Custom semantic edit-policy for lifelines that manages configuration of + * {@#link TimeObservation} and {@link TimeConstraint} border items. + */ +public class CustomLifelineSemanticEditPolicy extends CustomDefaultSemanticEditPolicy { + + private DisplayEvent displayEvent; + + /** + * Initializes me. + */ + public CustomLifelineSemanticEditPolicy() { + super(); + } + + @Override + public void setHost(EditPart host) { + super.setHost(host); + displayEvent = new DisplayEvent(host); + } + + @Override + protected Command getCreateCommand(CreateElementRequest req) { + if (ElementUtil.isTypeOf(req.getElementType(), UMLElementTypes.TIME_CONSTRAINT) + || ElementUtil.isTypeOf(req.getElementType(), UMLElementTypes.TIME_OBSERVATION)) { + + Object loc = req.getParameter("initialMouseLocationForCreation"); + if ((loc instanceof Point) && (getHost() instanceof IGraphicalEditPart)) { + // Is a message end here? + MessageOccurrenceSpecification messageOcc = displayEvent.getMessageEvent(((IGraphicalEditPart) getHost()).getFigure(), (Point) loc); + if (messageOcc != null) { + req.setParameter(SequenceRequestConstant.NEAREST_OCCURRENCE_SPECIFICATION, Arrays.asList(messageOcc)); + } else { + // Cannot create this on a lifeline without the message end to constrain + // or observe + return UnexecutableCommand.INSTANCE; + } + } + } + return super.getCreateCommand(req); + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/TimeElementCreationFeedbackEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/TimeElementCreationFeedbackEditPolicy.java new file mode 100644 index 00000000000..ab8c9685b5e --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/TimeElementCreationFeedbackEditPolicy.java @@ -0,0 +1,202 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.sequence.edit.policies; + +import java.util.Set; +import java.util.function.Function; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.RectangleFigure; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.gef.Request; +import org.eclipse.gef.editpolicies.GraphicalEditPolicy; +import org.eclipse.gef.requests.DropRequest; +import org.eclipse.gmf.runtime.diagram.ui.figures.BorderedNodeFigure; +import org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocator; +import org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest; +import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry; +import org.eclipse.gmf.runtime.emf.type.core.IElementType; +import org.eclipse.gmf.runtime.emf.type.core.ISpecializationType; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +import org.eclipse.papyrus.infra.gmfdiag.common.service.palette.AspectUnspecifiedTypeCreationTool.CreateAspectUnspecifiedTypeRequest; +import org.eclipse.papyrus.infra.services.edit.utils.ElementTypeUtils; +import org.eclipse.papyrus.uml.diagram.sequence.locator.CenterLocator; +import org.eclipse.papyrus.uml.service.types.element.UMLElementTypes; + +import com.google.common.collect.ImmutableSet; + +/** + * Feed-back edit-policy for creation of time constraints and time observations + * on various elements in the sequence diagram. + */ +public class TimeElementCreationFeedbackEditPolicy extends GraphicalEditPolicy { + + public static final String ROLE = "TimeElementCreationFeedback"; //$NON-NLS-1$ + + private final Function locatorFunction; + private IBorderItemLocator locator; + private IFigure feedback; + + /** + * Initializes me. + */ + public TimeElementCreationFeedbackEditPolicy() { + this(fig -> new CenterLocator(fig, PositionConstants.NONE)); + } + + public TimeElementCreationFeedbackEditPolicy(Function locatorFunction) { + super(); + + this.locatorFunction = locatorFunction; + } + + protected IBorderItemLocator getFeedbackLocator() { + if (locator == null) { + locator = locatorFunction.apply(getFeedbackParent()); + } + return locator; + } + + IFigure getFeedbackParent() { + IFigure result = getHostFigure(); + if (result instanceof BorderedNodeFigure) { + // Unwrap to get the figure on which border items are presented + result = ((BorderedNodeFigure) result).getMainFigure(); + } + return result; + } + + @Override + public void showTargetFeedback(Request request) { + IElementType typeToShow = getCreatedElementType(request); + if (isTimeElementType(typeToShow)) { + IFigure feedback = requireFeedback(); + + // Use our locator to present the feed-back in the place where the edit-part + // would end up putting the resulting element + IBorderItemLocator locator = getFeedbackLocator(); + Point where = getRelativeLocation(request); + Rectangle proposedLocation = new Rectangle(where, feedback.getSize()); + locator.setConstraint(proposedLocation); + + // Resolve the appropriate location in the feedback layer + Rectangle resolved = locator.getValidLocation(proposedLocation, feedback); + resolved.translate(0, -resolved.height() / 2); // Center on the mouse + getFeedbackParent().translateToAbsolute(resolved); + getFeedbackLayer().translateToRelative(resolved); + feedback.setBounds(resolved); + } + } + + /** + * Determine the element type being created that is a time element for which + * we provide feed-back. + * + * @param request + * the create/drop request + * @return the element type to be created/dropped, or {@code null} if indeterminate + */ + protected IElementType getCreatedElementType(Request request) { + IElementType result = null; + + if (request instanceof CreateAspectUnspecifiedTypeRequest) { + CreateAspectUnspecifiedTypeRequest createReq = (CreateAspectUnspecifiedTypeRequest) request; + if (createReq.getElementTypes().size() == 1) { + result = (IElementType) createReq.getElementTypes().get(0); + } + } else if (request instanceof DropObjectsRequest) { + // Not creating the element, but creating the view, so infer the type from the element + DropObjectsRequest dropReq = (DropObjectsRequest) request; + if (dropReq.getObjects().size() == 1) { + EObject element = EMFHelper.getEObject(dropReq.getObjects().get(0)); + if (element != null) { + result = ElementTypeRegistry.getInstance().getElementType(element, ElementTypeUtils.getDefaultClientContext()); + } + } + } + + return result; + } + + protected boolean isTimeElementType(IElementType type) { + boolean result = false; + + if (type != null) { + final Set types = ImmutableSet.of(UMLElementTypes.TIME_CONSTRAINT, + UMLElementTypes.TIME_OBSERVATION); + result = types.contains(type); + if (!result && type instanceof ISpecializationType) { + // Try subtypes + ISpecializationType spec = (ISpecializationType) type; + result = types.stream().anyMatch(spec::isSpecializationOf); + } + } + + return result; + } + + protected Point getRelativeLocation(Request request) { + Point result = null; + + // There are other requests that implement distinct getLocation API but + // we aren't interested in those + if (request instanceof DropRequest) { + result = ((DropRequest) request).getLocation(); + } + if (result != null) { + // Don't destroy the request's data + result = result.getCopy(); + getFeedbackParent().translateToRelative(result); + } else { + // Assume top left for want of anything requested + result = new Point(); + } + + return result; + } + + protected IFigure getFeedback() { + if (feedback == null) { + feedback = new RectangleFigure(); + feedback.setForegroundColor(ColorConstants.gray); + feedback.setBackgroundColor(ColorConstants.gray); + feedback.setSize(60, 5); // Make it thicker so that it's obvious + } + return feedback; + } + + protected IFigure requireFeedback() { + IFigure result = getFeedback(); + if (result.getParent() == null) { + // Add it now because we need to show it + addFeedback(result); + } + return result; + } + + @Override + public void eraseTargetFeedback(Request request) { + if (feedback != null && feedback.getParent() != null) { + // Remove it from the scene + removeFeedback(feedback); + } + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/LifelineFigure.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/LifelineFigure.java index bbb8270c575..3f333e2c391 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/LifelineFigure.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/LifelineFigure.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2010 - 2018 CEA + * Copyright (c) 2010 - 2018 CEA, Christian W. Damus, and others * * * All rights reserved. This program and the accompanying materials @@ -13,7 +13,7 @@ * Soyatec - Initial API and implementation * Mickaël ADAM (ALL4TEC) mickael.adam@all4tec.net - Bug 519408 * Vincent LORENZO (CEA LIST) vincent.lorenzo@cea.fr - Bug 531520 - * Christian W. Damus - bug 539373 + * Christian W. Damus - bugs 539373, 536486 *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.figures; @@ -510,6 +510,10 @@ public class LifelineFigure extends RoundedCompartmentFigure { this.add(lifelineHeaderBoundsFigure); } + public IFigure getHeaderFigure() { + return lifelineHeaderBoundsFigure; + } + protected IMapMode getMapMode() { return MapModeUtil.getMapMode(); } diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/TimeObservationFigure.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/TimeObservationFigure.java index b9b98ebebdd..d639b57b842 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/TimeObservationFigure.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/TimeObservationFigure.java @@ -1,12 +1,25 @@ +/** + * Copyright (c) 2015, 2018 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 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * CEA LIST - Initial API and implementation + * Christian W. Damus - bug 536486 + */ package org.eclipse.papyrus.uml.diagram.sequence.figures; -public class TimeObservationFigure extends TimeMarkElementFigure { +public class TimeObservationFigure extends TimeConstraintFigure { /** - * Constructor. - * + * Initializes me. */ public TimeObservationFigure() { - removeAllPoints(); + super(); } -} \ No newline at end of file +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/locator/CenterLocator.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/locator/CenterLocator.java index b76858aad8f..780a84c2404 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/locator/CenterLocator.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/locator/CenterLocator.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2010 CEA + * Copyright (c) 2010, 2018 CEA, Christian W. Damus, and others * * * All rights reserved. This program and the accompanying materials @@ -11,6 +11,7 @@ * * Contributors: * Atos Origin - Initial API and implementation + * Christian W. Damus - bug 536486 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.locator; @@ -18,6 +19,7 @@ package org.eclipse.papyrus.uml.diagram.sequence.locator; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gmf.runtime.diagram.ui.figures.BorderedNodeFigure; import org.eclipse.gmf.runtime.diagram.ui.internal.figures.BorderItemContainerFigure; import org.eclipse.gmf.runtime.gef.ui.figures.DefaultSizeNodeFigure; import org.eclipse.papyrus.uml.diagram.common.locator.AdvancedBorderItemLocator; @@ -64,6 +66,10 @@ public class CenterLocator extends AdvancedBorderItemLocator { BorderItemContainerFigure borderItemContainerFigure = getBorderItemContainerFigure(); if (borderItemContainerFigure != null) { for (Object child : borderItemContainerFigure.getChildren()) { + if (child instanceof BorderedNodeFigure) { + // Unwrap it (the destruction occurrence, itself, can have border items) + child = ((BorderedNodeFigure) child).getMainFigure(); + } if (child instanceof DefaultSizeNodeFigure) { for (Object figure : ((DefaultSizeNodeFigure) child).getChildren()) { if (figure instanceof DestructionEventFigure) { @@ -106,7 +112,8 @@ public class CenterLocator extends AdvancedBorderItemLocator { public Rectangle getValidLocation(Rectangle proposedLocation, IFigure borderItem) { // The valid position for destruction event is always the bottom if (getDestructionEventFigure() != null) { - if (borderItem.equals(getDestructionEventFigure().getParent())) { + // The destruction event supports border items, itself, so there are two levels of parent + if (borderItem.equals(getDestructionEventFigure().getParent().getParent())) { Rectangle realLocation = new Rectangle(proposedLocation); Point point = new Point(getParentBorder().getCenter().x - realLocation.getSize().width / 2, getParentBorder().y + getParentBorder().height - realLocation.height / 2); realLocation.setLocation(point); diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/locator/TimeElementLocator.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/locator/TimeElementLocator.java index 74bb6d30a4e..574071f4696 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/locator/TimeElementLocator.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/locator/TimeElementLocator.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2018 CEA LIST and others. + * Copyright (c) 2018 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 @@ -8,18 +8,28 @@ * * Contributors: * CEA LIST - Initial API and implementation + * Christian W. Damus - bug 536486 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.locator; +import java.util.Optional; +import java.util.function.ToIntFunction; +import java.util.stream.Stream; + import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.gef.EditPart; import org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocator; import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure; +import org.eclipse.papyrus.uml.diagram.sequence.figures.DestructionEventNodePlate; +import org.eclipse.papyrus.uml.diagram.sequence.figures.LifelineFigure; +import org.eclipse.uml2.uml.NamedElement; import org.eclipse.uml2.uml.TimeConstraint; import org.eclipse.uml2.uml.TimeObservation; @@ -28,11 +38,30 @@ import org.eclipse.uml2.uml.TimeObservation; */ public class TimeElementLocator implements IBorderItemLocator { + private final IBorderItemLocator centeringDelegate; + private IFigure parentFigure; private Rectangle constraint; + private ToIntFunction sideFunction; + + /** + * Initializes me with my parent figure and a function that computes the side on + * which to place the time element based on a proposed locating rectangle. + * + * @param parentFigure + * the parent figure + * @param sideFunction + * the proposed rectangle to side function. Valid outputs of the + * side function are the NSEW and {@link PositionConstants#CENTER CENTER} + * values of the {@link PositionConstants} + */ + public TimeElementLocator(IFigure parentFigure, ToIntFunction sideFunction) { + super(); - public TimeElementLocator(IFigure parentFigure) { this.setParentFigure(parentFigure); + this.sideFunction = sideFunction; + + this.centeringDelegate = new CenterLocator(parentFigure, PositionConstants.NONE); } @Override @@ -71,17 +100,54 @@ public class TimeElementLocator implements IBorderItemLocator { } protected Point locateOnBorder(Rectangle rectSuggested, IFigure borderItem) { - int relativeItemLeft = rectSuggested.x; + Point relativeItem = rectSuggested.getTopLeft(); + Rectangle parentBounds = getParentFigure().getBounds(); + Rectangle itemBounds = borderItem.getBounds(); + + // On which side? + int side = sideFunction.applyAsInt(rectSuggested); + switch (side) { + case PositionConstants.WEST: // Applied on the lifeline head + relativeItem.setLocation(-(itemBounds.width() / 2), + getLifelineHead().height() / 2); + break; + case PositionConstants.EAST: // Applied on the lifeline head + relativeItem.setLocation(parentBounds.width() - (itemBounds.width() / 2), + getLifelineHead().height() / 2); + break; + case PositionConstants.NORTH: // Applied on an execution specification + relativeItem.setLocation((parentBounds.width() - rectSuggested.width()) / 2, 0); + break; + case PositionConstants.SOUTH: // Applied on an execution specification + relativeItem.setLocation((parentBounds.width() - rectSuggested.width()) / 2, + parentBounds.height()); + break; + case PositionConstants.CENTER: // Applied on a destruction occurrence and lifeline + if (isOnDestructionOccurrence()) { + // Center vertically, also + relativeItem.setLocation((parentBounds.width() - itemBounds.width()) / 2, + parentBounds.height() / 2); + } else { + return centeringDelegate.getValidLocation(rectSuggested, borderItem) + .getLocation(); + } + break; + default: + throw new IllegalArgumentException("unsupported side: " + side); + } - int relativeItemTop = 0; + Point result = getAbsoluteToBorder(relativeItem); + return result; + } - if (getConstraint().getTopLeft().y() > 0) { - relativeItemTop = getParentFigure().getBounds().height; - } else { - relativeItemTop = 0; - } - Point pt = getAbsoluteToBorder(new Point(relativeItemLeft, relativeItemTop)); - return pt; + protected boolean isOnDestructionOccurrence() { + return getParentFigure() instanceof DestructionEventNodePlate; + } + + protected Rectangle getLifelineHead() { + // The first (and only) child of the lifeline node plate is the lifeline figure + LifelineFigure lifeline = (LifelineFigure) getParentFigure().getChildren().get(0); + return lifeline.getHeaderFigure().getBounds(); } protected IFigure getParentFigure() { @@ -140,4 +206,24 @@ public class TimeElementLocator implements IBorderItemLocator { return bounds; } + public static Optional getTimedElement(EditPart timeElementEP, Class type) { + return Optional.ofNullable(timeElementEP.getAdapter(EObject.class)) + .filter(NamedElement.class::isInstance).map(NamedElement.class::cast) + .flatMap(named -> getTimedElement(named, type)); + } + + public static Optional getTimedElement(NamedElement timeElement, Class type) { + Stream timed = Stream.empty(); + + if (timeElement instanceof TimeConstraint) { + TimeConstraint constraint = (TimeConstraint) timeElement; + timed = constraint.getConstrainedElements().stream().filter(type::isInstance).map(type::cast); + } else if (timeElement instanceof TimeObservation) { + TimeObservation observation = (TimeObservation) timeElement; + timed = Stream.of(observation.getEvent()).filter(type::isInstance).map(type::cast); + } + + return timed.findFirst(); + } + } diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomDestructionOccurrenceSpecificationEditPolicyProvider.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomDestructionOccurrenceSpecificationEditPolicyProvider.java new file mode 100644 index 00000000000..2fe6cf5f841 --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomDestructionOccurrenceSpecificationEditPolicyProvider.java @@ -0,0 +1,58 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.sequence.providers; + +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.gef.EditPart; +import org.eclipse.gmf.runtime.common.core.service.AbstractProvider; +import org.eclipse.gmf.runtime.common.core.service.IOperation; +import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles; +import org.eclipse.gmf.runtime.diagram.ui.services.editpolicy.CreateEditPoliciesOperation; +import org.eclipse.gmf.runtime.diagram.ui.services.editpolicy.IEditPolicyProvider; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.DestructionOccurrenceSpecificationEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.CustomDestructionOccurrenceSpecificationSemanticEditPolicy; +import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.TimeElementCreationFeedbackEditPolicy; +import org.eclipse.papyrus.uml.diagram.sequence.locator.TimeElementLocator; +import org.eclipse.papyrus.uml.diagram.sequence.referencialgrilling.CustomDestructionOccurrenceSpecificationCreationEditPolicy; + +/** + * Provider of custom edit policies for destruction occurrence specifications. + */ +public class CustomDestructionOccurrenceSpecificationEditPolicyProvider extends AbstractProvider implements IEditPolicyProvider { + + @Override + public boolean provides(final IOperation operation) { + + if (operation instanceof CreateEditPoliciesOperation) { + final EditPart editPart = ((CreateEditPoliciesOperation) operation).getEditPart(); + if (editPart instanceof DestructionOccurrenceSpecificationEditPart) { + return true; + } + } + + return false; + } + + @Override + public void createEditPolicies(final EditPart editPart) { + editPart.installEditPolicy(EditPolicyRoles.CREATION_ROLE, new CustomDestructionOccurrenceSpecificationCreationEditPolicy()); + editPart.installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new CustomDestructionOccurrenceSpecificationSemanticEditPolicy()); + editPart.installEditPolicy(TimeElementCreationFeedbackEditPolicy.ROLE, + new TimeElementCreationFeedbackEditPolicy(parentFigure -> new TimeElementLocator(parentFigure, + __ -> PositionConstants.CENTER))); + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomEditPartProvider.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomEditPartProvider.java index e34a16ea433..8041edb58e4 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomEditPartProvider.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomEditPartProvider.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2010, 2018 CEA List, EclipseSource and others + * Copyright (c) 2010, 2018 CEA List, EclipseSource, 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 2.0 @@ -11,6 +11,7 @@ * Contributors: * Soyatec - Initial API and implementation * EclipseSource - Bug 536641 + * Christian W. Damus - bug 536486 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.providers; @@ -41,6 +42,8 @@ import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CustomMessageName7Edi import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CustomMessageNameEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CustomStateInvariantEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CustomStateInvariantLabelEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CustomTimeConstraintBorderNodeEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CustomTimeObservationBorderNodeEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.DestructionOccurrenceSpecificationEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.DurationConstraintLinkEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.DurationObservationLinkEditPart; @@ -59,6 +62,8 @@ import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.MessageReplyNameEditP import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.MessageSyncNameEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.StateInvariantEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.StateInvariantLabelEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintBorderNodeEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationBorderNodeEditPart; import org.eclipse.papyrus.uml.diagram.sequence.part.UMLVisualIDRegistry; import org.eclipse.papyrus.uml.diagram.sequence.referencialgrilling.GrillingEditpart; @@ -124,14 +129,14 @@ public class CustomEditPartProvider extends UMLEditPartProvider { return new CustomStateInvariantEditPart(view); // case CombinedFragment2EditPart.VISUAL_ID: // return new CustomCombinedFragment2EditPart(view); - // case TimeConstraintEditPart.VISUAL_ID: - // return new CustomTimeConstraintEditPart(view); + case TimeConstraintBorderNodeEditPart.VISUAL_ID: + return new CustomTimeConstraintBorderNodeEditPart(view); // case TimeConstraintAppliedStereotypeEditPart.VISUAL_ID: // return new CustomTimeConstraintAppliedStereotypeEditPart(view); // case TimeConstraintLabelEditPart.VISUAL_ID: // return new CustomTimeConstraintLabelEditPart(view); - // case TimeObservationEditPart.VISUAL_ID: - // return new CustomTimeObservationEditPart(view); + case TimeObservationBorderNodeEditPart.VISUAL_ID: + return new CustomTimeObservationBorderNodeEditPart(view); // case TimeObservationLabelEditPart.VISUAL_ID: // return new CustomTimeObservationLabelEditPart(view); // case TimeObservationAppliedStereotypeEditPart.VISUAL_ID: diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomExecutionSpecificationEditPolicyProvider.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomExecutionSpecificationEditPolicyProvider.java index b6848078f2e..16642d82c0f 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomExecutionSpecificationEditPolicyProvider.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomExecutionSpecificationEditPolicyProvider.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2017 CEA LIST and others. + * Copyright (c) 2017, 2018 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 2.0 @@ -10,11 +10,14 @@ * * Contributors: * Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation + * Christian W. Damus - bug 536486 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.providers; +import static org.eclipse.papyrus.uml.diagram.sequence.edit.parts.AbstractExecutionSpecificationEditPart.findNearestSide; + import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPolicy; import org.eclipse.gmf.runtime.common.core.service.AbstractProvider; @@ -24,6 +27,8 @@ import org.eclipse.gmf.runtime.diagram.ui.services.editpolicy.CreateEditPolicies import org.eclipse.gmf.runtime.diagram.ui.services.editpolicy.IEditPolicyProvider; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.AbstractExecutionSpecificationEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.CustomExecutionSpecificationSemanticEditPolicy; +import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.TimeElementCreationFeedbackEditPolicy; +import org.eclipse.papyrus.uml.diagram.sequence.locator.TimeElementLocator; import org.eclipse.papyrus.uml.diagram.sequence.referencialgrilling.CustomExecutionSpecificationCreationEditPolicy; import org.eclipse.papyrus.uml.diagram.sequence.referencialgrilling.CustomExecutionSpecificationXYLayoutEditPolicy; @@ -50,16 +55,16 @@ public class CustomExecutionSpecificationEditPolicyProvider extends AbstractProv return false; } - /** - * {@inheritDoc} - * - * @see org.eclipse.gmf.runtime.diagram.ui.services.editpolicy.IEditPolicyProvider#createEditPolicies(org.eclipse.gef.EditPart) - */ @Override public void createEditPolicies(final EditPart editPart) { editPart.installEditPolicy(EditPolicyRoles.CREATION_ROLE, new CustomExecutionSpecificationCreationEditPolicy()); editPart.installEditPolicy(EditPolicy.LAYOUT_ROLE, new CustomExecutionSpecificationXYLayoutEditPolicy()); editPart.installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new CustomExecutionSpecificationSemanticEditPolicy()); + + TimeElementCreationFeedbackEditPolicy tecfep = new TimeElementCreationFeedbackEditPolicy( + parentFigure -> new TimeElementLocator(parentFigure, + constraint -> findNearestSide(parentFigure, constraint))); + editPart.installEditPolicy(TimeElementCreationFeedbackEditPolicy.ROLE, tecfep); } } diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomLifelineEditPolicyProvider.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomLifelineEditPolicyProvider.java new file mode 100644 index 00000000000..99cc0665dda --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/providers/CustomLifelineEditPolicyProvider.java @@ -0,0 +1,70 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.sequence.providers; + +import java.util.OptionalInt; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.gef.EditPart; +import org.eclipse.gmf.runtime.common.core.service.AbstractProvider; +import org.eclipse.gmf.runtime.common.core.service.IOperation; +import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles; +import org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocator; +import org.eclipse.gmf.runtime.diagram.ui.services.editpolicy.CreateEditPoliciesOperation; +import org.eclipse.gmf.runtime.diagram.ui.services.editpolicy.IEditPolicyProvider; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CLifeLineEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.CustomLifelineSemanticEditPolicy; +import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.TimeElementCreationFeedbackEditPolicy; +import org.eclipse.papyrus.uml.diagram.sequence.locator.TimeElementLocator; + +/** + * Provider of custom edit policies for lifelines. + */ +public class CustomLifelineEditPolicyProvider extends AbstractProvider implements IEditPolicyProvider { + + @Override + public boolean provides(final IOperation operation) { + + if (operation instanceof CreateEditPoliciesOperation) { + final EditPart editPart = ((CreateEditPoliciesOperation) operation).getEditPart(); + if (editPart instanceof CLifeLineEditPart) { + return true; + } + } + + return false; + } + + @Override + public void createEditPolicies(final EditPart editPart) { + CLifeLineEditPart lifeline = (CLifeLineEditPart) editPart; + + editPart.installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new CustomLifelineSemanticEditPolicy()); + editPart.installEditPolicy(TimeElementCreationFeedbackEditPolicy.ROLE, new TimeElementCreationFeedbackEditPolicy( + parentFigure -> getTimeElementLocator(lifeline, parentFigure))); + } + + private IBorderItemLocator getTimeElementLocator(CLifeLineEditPart lifeline, IFigure parentFigure) { + return new TimeElementLocator(parentFigure, proposedConstraints -> { + OptionalInt side = lifeline.getCreateMessageIncomingSide(proposedConstraints.getTopLeft()); + + return side.isPresent() + ? PositionConstants.EAST_WEST ^ side.getAsInt() + : PositionConstants.CENTER; + }); + } +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomDestructionOccurrenceSpecificationCreationEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomDestructionOccurrenceSpecificationCreationEditPolicy.java new file mode 100644 index 00000000000..c3c88a2e8dc --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomDestructionOccurrenceSpecificationCreationEditPolicy.java @@ -0,0 +1,45 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.sequence.referencialgrilling; + +import org.eclipse.draw2d.geometry.Dimension; +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.editparts.IGraphicalEditPart; +import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages; +import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest; +import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor; +import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.DefaultCreationEditPolicy; +import org.eclipse.papyrus.uml.service.types.element.UMLDIElementTypes; + +/** + * Custom creation edit policy for destruction occurrences, supporting time + * constraints and time observations. + */ +public class CustomDestructionOccurrenceSpecificationCreationEditPolicy extends DefaultCreationEditPolicy { + + @Override + protected ICommand getSetBoundsCommand(CreateViewRequest request, ViewDescriptor descriptor) { + if (UMLDIElementTypes.TIME_CONSTRAINT_SHAPE.getSemanticHint().equals(descriptor.getSemanticHint()) + || UMLDIElementTypes.TIME_OBSERVATION_SHAPE.getSemanticHint().equals(descriptor.getSemanticHint())) { + + // The visualization of the time constraint cannot be moved + Dimension size = new Dimension(40, 1); + return new SetBoundsCommand(((IGraphicalEditPart) getHost()).getEditingDomain(), DiagramUIMessages.Commands_MoveElement, descriptor, size); + } + return super.getSetBoundsCommand(request, descriptor); + } +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomExecutionSpecificationCreationEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomExecutionSpecificationCreationEditPolicy.java index 3bf1c87c5cb..4a34b0021b9 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomExecutionSpecificationCreationEditPolicy.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomExecutionSpecificationCreationEditPolicy.java @@ -10,7 +10,7 @@ * * Contributors: * Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation - * Christian W. Damus - bug 539373 + * Christian W. Damus - bug 539373, 536486 * *****************************************************************************/ @@ -18,11 +18,15 @@ package org.eclipse.papyrus.uml.diagram.sequence.referencialgrilling; import static org.eclipse.papyrus.uml.service.types.utils.ElementUtil.isTypeOf; +import java.util.Optional; +import java.util.function.Predicate; import java.util.stream.Stream; +import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.emf.ecore.EClass; import org.eclipse.gef.EditPart; import org.eclipse.gef.Request; import org.eclipse.gef.requests.CreateRequest; @@ -40,12 +44,31 @@ import org.eclipse.papyrus.uml.diagram.sequence.util.DurationLinkUtil; import org.eclipse.papyrus.uml.diagram.sequence.util.SequenceUtil; import org.eclipse.papyrus.uml.service.types.element.UMLDIElementTypes; import org.eclipse.papyrus.uml.service.types.element.UMLElementTypes; +import org.eclipse.uml2.uml.MessageOccurrenceSpecification; +import org.eclipse.uml2.uml.UMLPackage; /** * This allows to define the creation edit policy for the execution specification. */ public class CustomExecutionSpecificationCreationEditPolicy extends DefaultCreationEditPolicy { + private DisplayEvent displayEvent; + + public CustomExecutionSpecificationCreationEditPolicy() { + super(); + } + + @Override + public void setHost(EditPart host) { + super.setHost(host); + + // Note that messages always actually connect to the lifeline, even if their + // connection figures show as connected to the execution, so we need to use + // the lifeline to find message ends + EditPart lifeline = SequenceUtil.getParentLifelinePart(getHost()); + displayEvent = new DisplayEvent(lifeline != null ? lifeline : host); + } + @Override protected ICommand getSetBoundsCommand(CreateViewRequest request, ViewDescriptor descriptor) { if (UMLDIElementTypes.TIME_CONSTRAINT_SHAPE.getSemanticHint().equals(descriptor.getSemanticHint()) @@ -53,11 +76,12 @@ public class CustomExecutionSpecificationCreationEditPolicy extends DefaultCreat // check the position of the request to give the basic constraint for the created shape (should not be moveable) Point location = request.getLocation().getCopy(); location.setX(-10); - boolean isStart = DurationLinkUtil.isStart(((IGraphicalEditPart) getHost()).getFigure(), location); + IFigure execFigure = ((IGraphicalEditPart) getHost()).getFigure(); + boolean isStart = DurationLinkUtil.isStart(execFigure, location); if (isStart) { location.setY(-1); } else { - location.setY(10); + location.setY(Short.MAX_VALUE); } Dimension size = new Dimension(40, 1); return new SetBoundsCommand(((IGraphicalEditPart) getHost()).getEditingDomain(), DiagramUIMessages.Commands_MoveElement, descriptor, new Rectangle(location, size)); @@ -72,6 +96,7 @@ public class CustomExecutionSpecificationCreationEditPolicy extends DefaultCreat if (!(request instanceof CreateRequest)) { return result; } + CreateRequest create = (CreateRequest) request; Stream elementTypes = null; if (request instanceof CreateViewAndElementRequest) { @@ -80,10 +105,48 @@ public class CustomExecutionSpecificationCreationEditPolicy extends DefaultCreat } else if (request instanceof CreateUnspecifiedTypeRequest) { elementTypes = ((CreateUnspecifiedTypeRequest) request).getElementTypes().stream(); } - if ((elementTypes != null) && elementTypes.anyMatch(type -> isTypeOf(type, UMLElementTypes.EXECUTION_SPECIFICATION))) { - // The lifeline is responsible for creating all execution specifications, as they - // are semantically all children of it (nesting is strictly visual) - return SequenceUtil.getParentLifelinePart(getHost()); + if (elementTypes != null) { + Predicate isInteresting = type -> isTypeOf(type, UMLElementTypes.TIME_CONSTRAINT); + isInteresting = isInteresting.or(type -> isTypeOf(type, UMLElementTypes.TIME_OBSERVATION)); + isInteresting = isInteresting.or(type -> isTypeOf(type, UMLElementTypes.EXECUTION_SPECIFICATION)); + Optional interestingType = elementTypes.map(type -> { + if (isTypeOf(type, UMLElementTypes.TIME_CONSTRAINT)) { + return UMLPackage.Literals.TIME_CONSTRAINT; + } else if (isTypeOf(type, UMLElementTypes.TIME_OBSERVATION)) { + return UMLPackage.Literals.TIME_OBSERVATION; + } else if (isTypeOf(type, UMLElementTypes.EXECUTION_SPECIFICATION)) { + return UMLPackage.Literals.EXECUTION_SPECIFICATION; + } else { + return null; + } + }).findFirst(); + + result = interestingType. map(type -> { + switch (type.getClassifierID()) { + case UMLPackage.TIME_CONSTRAINT: + case UMLPackage.TIME_OBSERVATION: + Point loc = create.getLocation(); + if (loc != null) { + // Is a message end, here? Note that messages always actually connect to the + // lifeline, even if their connection figures show as connected to me, so + // we need to delegate to the lifeline to create the notation. Otherwise, + // re-targeting of the message to some other execution or to the lifeline + // itself will be complicated by the fact of the time element being a border + // node of this execution. Besides that it is more consistent with the + // edge anchoring implementation anyways + MessageOccurrenceSpecification messageOcc = displayEvent.getMessageEvent(((IGraphicalEditPart) getHost()).getFigure(), loc); + if (messageOcc != null) { + return SequenceUtil.getParentLifelinePart(getHost()); + } + } + break; + case UMLPackage.EXECUTION_SPECIFICATION: + // The lifeline is responsible for creating all execution specifications, as they + // are semantically all children of it (nesting is strictly visual) + return SequenceUtil.getParentLifelinePart(getHost()); + } + return null; + }).orElse(result); } return result; diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/LifelineCreationEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/LifelineCreationEditPolicy.java index 984bc044363..512a99f4f5c 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/LifelineCreationEditPolicy.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/LifelineCreationEditPolicy.java @@ -10,7 +10,7 @@ * * Contributors: * CEA LIST - Initial API and implementation - * Christian W. Damus - bug 530201 + * Christian W. Damus - bugs 530201, 536486 * *****************************************************************************/ @@ -121,7 +121,7 @@ public class LifelineCreationEditPolicy extends DefaultCreationEditPolicy implem /** * {@inheritDoc} - * + * * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.DefaultCreationEditPolicy#getReparentCommand(org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart) */ @Override @@ -136,7 +136,7 @@ public class LifelineCreationEditPolicy extends DefaultCreationEditPolicy implem return super.getReparentCommand(gep); } - + /** * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.DefaultCreationEditPolicy#getReparentViewCommand(org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart) * @@ -174,6 +174,8 @@ public class LifelineCreationEditPolicy extends DefaultCreationEditPolicy implem controlledByLifeline = true; } else if (ElementUtil.isTypeOf(elementType, UMLDIElementTypes.TIME_CONSTRAINT_SHAPE)) { controlledByLifeline = true; + } else if (ElementUtil.isTypeOf(elementType, UMLDIElementTypes.TIME_OBSERVATION_SHAPE)) { + controlledByLifeline = true; } else if (ElementUtil.isTypeOf(elementType, UMLDIElementTypes.STATE_INVARIANT_SHAPE)) { controlledByLifeline = true; } else if (ElementUtil.isTypeOf(elementType, UMLDIElementTypes.COMBINED_FRAGMENT_CO_REGION_SHAPE)) { diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/sequenceDiagram.gmfgen b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/sequenceDiagram.gmfgen index db69337c456..daee1a5bcf0 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/sequenceDiagram.gmfgen +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/sequenceDiagram.gmfgen @@ -11,7 +11,7 @@ domainFileExtension="PapyrusUMLSequence" dynamicTemplates="true" templateDirectory="/org.eclipse.papyrus.def/xtend/" - copyrightText="Copyright (c) 2016 CEA LIST. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-2.0 SPDX-License-Identifier: EPL-2.0 Contributors: CEA LIST - Initial API and implementation" + copyrightText="Copyright (c) 2018 CEA LIST. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-2.0 SPDX-License-Identifier: EPL-2.0 Contributors: CEA LIST - Initial API and implementation" pluginDirectory="/org.eclipse.papyrus.uml.diagram.sequence/src-gen"> @@ -484,7 +484,7 @@ itemSemanticEditPolicyClassName="ActionExecutionSpecificationItemSemanticEditPolicy" notationViewFactoryClassName="ActionExecutionSpecificationViewFactory" canonicalEditPolicyClassName="ActionExecutionSpecificationCanonicalEditPolicy" - childNodes="/0/@diagram/@childNodes.13" + childNodes="/0/@diagram/@childNodes.13 /0/@diagram/@childNodes.14" graphicalNodeEditPolicyClassName="ActionExecutionSpecificationGraphicalNodeEditPolicy" createCommandClassName="ActionExecutionSpecificationCreateCommand" containers="/0/@diagram/@childNodes.5"> @@ -529,7 +529,7 @@ itemSemanticEditPolicyClassName="BehaviorExecutionSpecificationItemSemanticEditPolicy" notationViewFactoryClassName="BehaviorExecutionSpecificationViewFactory" canonicalEditPolicyClassName="BehaviorExecutionSpecificationCanonicalEditPolicy" - childNodes="/0/@diagram/@childNodes.13" + childNodes="/0/@diagram/@childNodes.13 /0/@diagram/@childNodes.14" graphicalNodeEditPolicyClassName="BehaviorExecutionSpecificationGraphicalNodeEditPolicy" createCommandClassName="BehaviorExecutionSpecificationCreateCommand" containers="/0/@diagram/@childNodes.5"> @@ -647,6 +647,7 @@ itemSemanticEditPolicyClassName="DestructionOccurrenceSpecificationItemSemanticEditPolicy" notationViewFactoryClassName="DestructionEventViewFactory" canonicalEditPolicyClassName="DestructionOccurrenceSpecificationCanonicalEditPolicy" + childNodes="/0/@diagram/@childNodes.13 /0/@diagram/@childNodes.14" graphicalNodeEditPolicyClassName="DestructionOccurrenceSpecificationGraphicalNodeEditPolicy" createCommandClassName="DestructionOccurrenceSpecificationCreateCommand" containers="/0/@diagram/@childNodes.5" @@ -898,7 +899,7 @@ canonicalEditPolicyClassName="TimeConstraintBorderNodeCanonicalEditPolicy" graphicalNodeEditPolicyClassName="TimeConstraintBorderNodeGraphicalNodeEditPolicy" createCommandClassName="TimeConstraintBorderNodeCreateCommand" - containers="/0/@diagram/@childNodes.6 /0/@diagram/@childNodes.7"> + containers="/0/@diagram/@childNodes.6 /0/@diagram/@childNodes.7 /0/@diagram/@childNodes.9 /0/@diagram/@childNodes.5"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + genChildSideAffixedNode="/0/@diagram/@childNodes.9 /0/@diagram/@childNodes.8 /0/@diagram/@childNodes.13 /0/@diagram/@childNodes.14"/> + + + + + diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/plugin.xml b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/plugin.xml index aab854be387..106d802d64a 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/plugin.xml +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/plugin.xml @@ -135,7 +135,7 @@ - + @@ -148,13 +148,13 @@ - + - + @@ -348,6 +348,12 @@ name="Highest"> + + + + + + + + parserElements; + + /** + * @generated + */ + private String defaultText; + + /** + * direct edition mode (default, undefined, registered editor, etc.) + * + * @generated + */ + protected int directEditionMode = IDirectEdition.UNDEFINED_DIRECT_EDITOR; + + /** + * configuration from a registered edit dialog + * + * @generated + */ + protected IDirectEditorConfiguration configuration; + + /** + * @generated + */ + static { + registerSnapBackPosition(UMLVisualIDRegistry.getType( + org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationAppliedStereotypeEditPart.VISUAL_ID), + new Point(0, 0)); + } + + /** + * @generated + */ + public TimeObservationAppliedStereotypeEditPart(View view) { + super(view); + } + + /** + * @generated + */ + @Override + protected void createDefaultEditPolicies() { + super.createDefaultEditPolicies(); + installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new LabelDirectEditPolicy()); + installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, new UMLTextSelectionEditPolicy()); + installEditPolicy(AppliedStereotypeLabelDisplayEditPolicy.STEREOTYPE_LABEL_POLICY, + new AppliedStereotypeExternalNodeEditPolicy()); + installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, new ExternalLabelPrimaryDragRoleEditPolicy()); + } + + /** + * @generated + */ + @Override + public IBorderItemLocator getBorderItemLocator() { + IFigure parentFigure = getFigure().getParent(); + if (parentFigure != null && parentFigure.getLayoutManager() != null) { + Object constraint = parentFigure.getLayoutManager().getConstraint(getFigure()); + return (IBorderItemLocator) constraint; + } + return null; + } + + /** + * @generated + */ + @Override + public void refreshBounds() { + int x = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE.getLocation_X())).intValue(); + int y = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE.getLocation_Y())).intValue(); + int width = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE.getSize_Width())).intValue(); + int height = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE.getSize_Height())).intValue(); + getBorderItemLocator().setConstraint(new Rectangle(x, y, width, height)); + } + + /** + * @generated + */ + protected String getLabelTextHelper(IFigure figure) { + if (figure instanceof WrappingLabel) { + return ((WrappingLabel) figure).getText(); + } else if (figure instanceof ILabelFigure) { + return ((ILabelFigure) figure).getText(); + } else { + return ((Label) figure).getText(); + } + } + + /** + * @generated + */ + protected void setLabelTextHelper(IFigure figure, String text) { + if (figure instanceof WrappingLabel) { + ((WrappingLabel) figure).setText(text); + } else if (figure instanceof ILabelFigure) { + ((ILabelFigure) figure).setText(text); + } else { + ((Label) figure).setText(text); + } + } + + /** + * @generated + */ + protected Image getLabelIconHelper(IFigure figure) { + if (figure instanceof WrappingLabel) { + return ((WrappingLabel) figure).getIcon(); + } else if (figure instanceof ILabelFigure) { + return ((ILabelFigure) figure).getIcon(); + } else { + return ((Label) figure).getIcon(); + } + } + + /** + * @generated + */ + protected void setLabelIconHelper(IFigure figure, Image icon) { + if (figure instanceof WrappingLabel) { + ((WrappingLabel) figure).setIcon(icon); + } else if (figure instanceof ILabelFigure) { + ((ILabelFigure) figure).setIcon(icon); + } else { + ((Label) figure).setIcon(icon); + } + } + + /** + * @generated + */ + public void setLabel(IFigure figure) { + unregisterVisuals(); + setFigure(figure); + defaultText = getLabelTextHelper(figure); + registerVisuals(); + refreshVisuals(); + } + + /** + * @generated + */ + @Override + protected List getModelChildren() { + return Collections.EMPTY_LIST; + } + + /** + * @generated + */ + @Override + public IGraphicalEditPart getChildBySemanticHint(String semanticHint) { + return null; + } + + /** + * @generated + */ + public void setParser(IParser parser) { + this.parser = parser; + } + + /** + * @generated + */ + protected EObject getParserElement() { + return resolveSemanticElement(); + } + + /** + * @generated + */ + protected Image getLabelIcon() { + return null; + } + + /** + * @generated + */ + protected String getLabelText() { + String text = null; + EObject parserElement = getParserElement(); + if (parserElement != null && getParser() != null) { + text = getParser().getPrintString(ParserUtil.getParserAdapter(getParserElement(), this), + getParserOptions().intValue()); + } + if (text == null || text.length() == 0) { + text = defaultText; + } + return text; + } + + /** + * @generated + */ + @Override + public void setLabelText(String text) { + setLabelTextHelper(getFigure(), text); + Object pdEditPolicy = getEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE); + if (pdEditPolicy instanceof UMLTextSelectionEditPolicy) { + ((UMLTextSelectionEditPolicy) pdEditPolicy).refreshFeedback(); + } + Object sfEditPolicy = getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE); + if (sfEditPolicy instanceof UMLTextSelectionEditPolicy) { + ((UMLTextSelectionEditPolicy) sfEditPolicy).refreshFeedback(); + } + } + + /** + * @generated + */ + @Override + public String getEditText() { + if (getParserElement() == null || getParser() == null) { + return ""; //$NON-NLS-1$ + } + return getParser().getEditString(ParserUtil.getParserAdapter(getParserElement(), this), + getParserOptions().intValue()); + } + + /** + * @generated + */ + protected boolean isEditable() { + return false; + } + + /** + * @generated + */ + @Override + public ICellEditorValidator getEditTextValidator() { + return new ICellEditorValidator() { + + @Override + public String isValid(final Object value) { + if (value instanceof String) { + final EObject element = getParserElement(); + final IParser parser = getParser(); + try { + IParserEditStatus valid = (IParserEditStatus) getEditingDomain() + .runExclusive(new RunnableWithResult.Impl() { + + @Override + public void run() { + setResult(parser.isValidEditString( + ParserUtil.getParserAdapter(getParserElement(), + TimeObservationAppliedStereotypeEditPart.this), + (String) value)); + } + }); + return valid.getCode() == IParserEditStatus.EDITABLE ? null : valid.getMessage(); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + + // shouldn't get here + return null; + } + }; + } + + /** + * @generated + */ + @Override + public IContentAssistProcessor getCompletionProcessor() { + if (getParserElement() == null || getParser() == null) { + return null; + } + return getParser().getCompletionProcessor(ParserUtil.getParserAdapter(getParserElement(), this)); + } + + /** + * @generated + */ + @Override + public ParserOptions getParserOptions() { + return ParserOptions.NONE; + } + + /** + * @generated + */ + @Override + public IParser getParser() { + if (parser == null) { + parser = ParserUtil.getParser(UMLElementTypes.TimeObservation_Shape, getParserElement(), this, VISUAL_ID); + } + return parser; + } + + /** + * @generated + */ + protected DirectEditManager getManager() { + if (manager == null) { + setManager(new MultilineLabelDirectEditManager(this, + MultilineLabelDirectEditManager.getTextCellEditorClass(this), + UMLEditPartFactory.getTextCellEditorLocator(this))); + } + return manager; + } + + /** + * @generated + */ + protected void setManager(DirectEditManager manager) { + this.manager = manager; + } + + /** + * @generated + */ + protected void performDirectEdit() { + BusyIndicator.showWhile(Display.getDefault(), new java.lang.Runnable() { + + @Override + public void run() { + getManager().show(); + } + }); + } + + /** + * @generated + */ + protected void performDirectEdit(Point eventLocation) { + if (getManager() instanceof TextDirectEditManager) { + ((TextDirectEditManager) getManager()).show(eventLocation.getSWTPoint()); + } + } + + /** + * @generated + */ + protected void performDirectEdit(char initialCharacter) { + if (getManager() instanceof TextDirectEditManager) { + ((TextDirectEditManager) getManager()).show(initialCharacter); + } else { + performDirectEdit(); + } + } + + /** + * @generated + */ + @Override + protected void performDirectEditRequest(Request request) { + + final Request theRequest = request; + + if (IDirectEdition.UNDEFINED_DIRECT_EDITOR == directEditionMode) { + directEditionMode = getDirectEditionType(); + } + switch (directEditionMode) { + case IDirectEdition.NO_DIRECT_EDITION: + // no direct edition mode => does nothing + return; + case IDirectEdition.EXTENDED_DIRECT_EDITOR: + updateExtendedEditorConfiguration(); + if (configuration == null || configuration.getLanguage() == null) { + // Create default edit manager + setManager(new MultilineLabelDirectEditManager(this, + MultilineLabelDirectEditManager.getTextCellEditorClass(this), + UMLEditPartFactory.getTextCellEditorLocator(this))); + performDefaultDirectEditorEdit(theRequest); + } else { + configuration.preEditAction(resolveSemanticElement()); + Dialog dialog = null; + if (configuration instanceof ICustomDirectEditorConfiguration) { + setManager(((ICustomDirectEditorConfiguration) configuration).createDirectEditManager(this)); + initializeDirectEditManager(theRequest); + return; + } else if (configuration instanceof IPopupEditorConfiguration) { + IPopupEditorHelper helper = ((IPopupEditorConfiguration) configuration) + .createPopupEditorHelper(this); + helper.showEditor(); + return; + } else if (configuration instanceof IAdvancedEditorConfiguration) { + dialog = ((IAdvancedEditorConfiguration) configuration).createDialog( + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), resolveSemanticElement(), + configuration.getTextToEdit(resolveSemanticElement())); + } else if (configuration instanceof IDirectEditorConfiguration) { + dialog = new ExtendedDirectEditionDialog( + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), resolveSemanticElement(), + configuration.getTextToEdit(resolveSemanticElement()), configuration); + } else { + return; + } + final Dialog finalDialog = dialog; + + if (Window.OK == dialog.open()) { + TransactionalEditingDomain domain = getEditingDomain(); + RecordingCommand command = new RecordingCommand(domain, "Edit Label") { + + @Override + protected void doExecute() { + configuration.postEditAction(resolveSemanticElement(), + ((ILabelEditorDialog) finalDialog).getValue()); + + } + }; + domain.getCommandStack().execute(command); + } + } + break; + case IDirectEdition.DEFAULT_DIRECT_EDITOR: + initializeDirectEditManager(theRequest); + break; + default: + break; + } + } + + /** + * @generated + */ + protected void initializeDirectEditManager(final Request request) { + // initialize the direct edit manager + try { + getEditingDomain().runExclusive(new Runnable() { + @Override + public void run() { + if (isActive() && isEditable()) { + if (request.getExtendedData() + .get(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR) instanceof Character) { + Character initialChar = (Character) request.getExtendedData() + .get(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR); + performDirectEdit(initialChar.charValue()); + } else { + performDirectEdit(); + } + } + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * @generated + */ + @Override + protected void refreshVisuals() { + super.refreshVisuals(); + refreshLabel(); + refreshFont(); + refreshFontColor(); + refreshUnderline(); + refreshStrikeThrough(); + } + + /** + * @generated + */ + protected void refreshLabel() { + EditPolicy maskLabelPolicy = getEditPolicy(IMaskManagedLabelEditPolicy.MASK_MANAGED_LABEL_EDIT_POLICY); + if (maskLabelPolicy == null) { + maskLabelPolicy = getEditPolicy(IndirectMaskLabelEditPolicy.INDRIRECT_MASK_MANAGED_LABEL); + } + if (maskLabelPolicy == null) { + View view = (View) getModel(); + if (view.isVisible()) { + setLabelTextHelper(getFigure(), getLabelText()); + setLabelIconHelper(getFigure(), getLabelIcon()); + } else { + setLabelTextHelper(getFigure(), ""); //$NON-NLS-1$ + setLabelIconHelper(getFigure(), null); + } + } + Object pdEditPolicy = getEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE); + if (pdEditPolicy instanceof UMLTextSelectionEditPolicy) { + ((UMLTextSelectionEditPolicy) pdEditPolicy).refreshFeedback(); + } + Object sfEditPolicy = getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE); + if (sfEditPolicy instanceof UMLTextSelectionEditPolicy) { + ((UMLTextSelectionEditPolicy) sfEditPolicy).refreshFeedback(); + } + } + + /** + * @generated + */ + protected void refreshUnderline() { + FontStyle style = (FontStyle) getFontStyleOwnerView().getStyle(NotationPackage.eINSTANCE.getFontStyle()); + if (style != null && getFigure() instanceof WrappingLabel) { + ((WrappingLabel) getFigure()).setTextUnderline(style.isUnderline()); + } + if (resolveSemanticElement() instanceof Feature) { + if (((Feature) resolveSemanticElement()).isStatic()) { + ((WrappingLabel) getFigure()).setTextUnderline(true); + } else { + ((WrappingLabel) getFigure()).setTextUnderline(false); + } + } + } + + /** + * @generated + */ + protected void refreshStrikeThrough() { + FontStyle style = (FontStyle) getFontStyleOwnerView().getStyle(NotationPackage.eINSTANCE.getFontStyle()); + if (style != null && getFigure() instanceof WrappingLabel) { + ((WrappingLabel) getFigure()).setTextStrikeThrough(style.isStrikeThrough()); + } + } + + /** + * @generated + */ + @Override + protected void refreshFont() { + FontStyle style = (FontStyle) getFontStyleOwnerView().getStyle(NotationPackage.eINSTANCE.getFontStyle()); + if (style != null) { + FontData fontData = new FontData(style.getFontName(), style.getFontHeight(), + (style.isBold() ? SWT.BOLD : SWT.NORMAL) | (style.isItalic() ? SWT.ITALIC : SWT.NORMAL)); + setFont(fontData); + } + } + + /** + * @generated + */ + @Override + protected void setFontColor(Color color) { + getFigure().setForegroundColor(color); + } + + /** + * @generated + */ + @Override + protected void addSemanticListeners() { + if (getParser() instanceof ISemanticParser) { + EObject element = resolveSemanticElement(); + parserElements = ((ISemanticParser) getParser()).getSemanticElementsBeingParsed(element); + for (int i = 0; i < parserElements.size(); i++) { + addListenerFilter("SemanticModel" + i, this, (EObject) parserElements.get(i)); //$NON-NLS-1$ + } + } else { + super.addSemanticListeners(); + } + } + + /** + * @generated + */ + @Override + protected void removeSemanticListeners() { + if (parserElements != null) { + for (int i = 0; i < parserElements.size(); i++) { + removeListenerFilter("SemanticModel" + i); //$NON-NLS-1$ + } + } else { + super.removeSemanticListeners(); + } + } + + /** + * @generated + */ + @Override + protected AccessibleEditPart getAccessibleEditPart() { + if (accessibleEP == null) { + accessibleEP = new AccessibleGraphicalEditPart() { + + @Override + public void getName(AccessibleEvent e) { + e.result = getLabelTextHelper(getFigure()); + } + }; + } + return accessibleEP; + } + + /** + * @generated + */ + private View getFontStyleOwnerView() { + return getPrimaryView(); + } + + /** + * Returns the kind of associated editor for direct edition. + * + * @return an int corresponding to the kind of direct editor, @see org.eclipse.papyrus.uml.diagram.common.editpolicies.IDirectEdition + * @generated + */ + public int getDirectEditionType() { + // The label is read-only (defined in GMFGen model) + return IDirectEdition.NO_DIRECT_EDITION; + } + + /** + * Checks if an extended editor is present. + * + * @return true if an extended editor is present. + * @generated + */ + protected boolean checkExtendedEditor() { + if (resolveSemanticElement() != null) { + return DirectEditorsUtil.hasSpecificEditorConfiguration(resolveSemanticElement(), this); + } + return false; + } + + /** + * Checks if a default direct edition is available + * + * @return true if a default direct edition is available + * @generated + */ + protected boolean checkDefaultEdition() { + return (getParser() != null); + } + + /** + * Initializes the extended editor configuration + * + * @generated + */ + protected void initExtendedEditorConfiguration() { + if (configuration == null) { + final String languagePreferred = Activator.getDefault().getPreferenceStore().getString( + IDirectEditorsIds.EDITOR_FOR_ELEMENT + resolveSemanticElement().eClass().getInstanceClassName()); + if (languagePreferred != null && !languagePreferred.equals("")) { + configuration = DirectEditorsUtil.findEditorConfiguration(languagePreferred, resolveSemanticElement(), + this); + } else { + configuration = DirectEditorsUtil.findEditorConfiguration(IDirectEditorsIds.UML_LANGUAGE, + resolveSemanticElement(), this); + } + } + } + + /** + * Updates the preference configuration + * + * @generated + */ + protected void updateExtendedEditorConfiguration() { + String languagePreferred = Activator.getDefault().getPreferenceStore().getString( + IDirectEditorsIds.EDITOR_FOR_ELEMENT + resolveSemanticElement().eClass().getInstanceClassName()); + if (languagePreferred != null && !languagePreferred.equals("") + && !languagePreferred.equals(configuration.getLanguage())) { + configuration = DirectEditorsUtil.findEditorConfiguration(languagePreferred, resolveSemanticElement(), + this); + } else if (IDirectEditorsIds.SIMPLE_DIRECT_EDITOR.equals(languagePreferred)) { + configuration = null; + } + } + + /** + * Performs the direct edit usually used by GMF editors. + * + * @param theRequest + * the direct edit request that starts the direct edit system + * @generated + */ + protected void performDefaultDirectEditorEdit(final Request theRequest) { + // initialize the direct edit manager + try { + getEditingDomain().runExclusive(new Runnable() { + + @Override + public void run() { + if (isActive() && isEditable()) { + if (theRequest.getExtendedData() + .get(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR) instanceof Character) { + Character initialChar = (Character) theRequest.getExtendedData() + .get(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR); + performDirectEdit(initialChar.charValue()); + } else if ((theRequest instanceof DirectEditRequest) + && (getEditText().equals(getLabelText()))) { + DirectEditRequest editRequest = (DirectEditRequest) theRequest; + performDirectEdit(editRequest.getLocation()); + } else { + performDirectEdit(); + } + } + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * @generated + */ + @Override + protected void handleNotificationEvent(Notification event) { + Object feature = event.getFeature(); + if (NotationPackage.eINSTANCE.getFontStyle_FontColor().equals(feature)) { + Integer c = (Integer) event.getNewValue(); + setFontColor(DiagramColorRegistry.getInstance().getColor(c)); + } else if (NotationPackage.eINSTANCE.getFontStyle_Underline().equals(feature)) { + refreshUnderline(); + } else if (NotationPackage.eINSTANCE.getFontStyle_StrikeThrough().equals(feature)) { + refreshStrikeThrough(); + } else if (NotationPackage.eINSTANCE.getFontStyle_FontHeight().equals(feature) + || NotationPackage.eINSTANCE.getFontStyle_FontName().equals(feature) + || NotationPackage.eINSTANCE.getFontStyle_Bold().equals(feature) + || NotationPackage.eINSTANCE.getFontStyle_Italic().equals(feature)) { + refreshFont(); + } else { + if (getParser() != null && getParser().isAffectingEvent(event, getParserOptions().intValue())) { + refreshLabel(); + } + if (getParser() instanceof ISemanticParser) { + ISemanticParser modelParser = (ISemanticParser) getParser(); + if (modelParser.areSemanticElementsAffected(null, event)) { + removeSemanticListeners(); + if (resolveSemanticElement() != null) { + addSemanticListeners(); + } + refreshLabel(); + } + } + } + super.handleNotificationEvent(event); + } + + /** + * @generated + */ + @Override + protected IFigure createFigure() { + IFigure label = createFigurePrim(); + defaultText = getLabelTextHelper(label); + return label; + } + + /** + * @generated + */ + protected IFigure createFigurePrim() { + return new AppliedStereotypeWrappingLabelFigure(); + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeObservationBorderNodeEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeObservationBorderNodeEditPart.java new file mode 100644 index 00000000000..dc8ed111e72 --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeObservationBorderNodeEditPart.java @@ -0,0 +1,281 @@ +/** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + */ +package org.eclipse.papyrus.uml.diagram.sequence.edit.parts; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.StackLayout; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gef.Request; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.editpolicies.LayoutEditPolicy; +import org.eclipse.gef.editpolicies.NonResizableEditPolicy; +import org.eclipse.gef.handles.MoveHandle; +import org.eclipse.gef.requests.CreateRequest; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart; +import org.eclipse.gmf.runtime.diagram.ui.editpolicies.BorderItemSelectionEditPolicy; +import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles; +import org.eclipse.gmf.runtime.diagram.ui.figures.BorderItemLocator; +import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure; +import org.eclipse.gmf.runtime.notation.BasicCompartment; +import org.eclipse.gmf.runtime.notation.Edge; +import org.eclipse.gmf.runtime.notation.NotationPackage; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.DefaultGraphicalNodeEditPolicy; +import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.DefaultSemanticEditPolicy; +import org.eclipse.papyrus.infra.gmfdiag.common.figure.node.IPapyrusNodeFigure; +import org.eclipse.papyrus.infra.gmfdiag.common.figure.node.RoundedRectangleNodePlateFigure; +import org.eclipse.papyrus.uml.diagram.common.editparts.BorderNodeEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.figures.TimeObservationFigure; +import org.eclipse.papyrus.uml.diagram.sequence.part.UMLVisualIDRegistry; +import org.eclipse.swt.graphics.Color; + +/** + * @generated + */ +public class TimeObservationBorderNodeEditPart extends BorderNodeEditPart { + + /** + * @generated + */ + public static final String VISUAL_ID = "TimeObservation_Shape"; + + /** + * @generated + */ + protected IFigure contentPane; + + /** + * @generated + */ + protected IFigure primaryShape; + + /** + * @generated + */ + public TimeObservationBorderNodeEditPart(View view) { + super(view); + } + + /** + * @generated + */ + @Override + protected void createDefaultEditPolicies() { + super.createDefaultEditPolicies(); + installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, getPrimaryDragEditPolicy()); + installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new DefaultSemanticEditPolicy()); + + installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new DefaultGraphicalNodeEditPolicy()); + + installEditPolicy(EditPolicy.LAYOUT_ROLE, createLayoutEditPolicy()); + // 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); + } + + /** + * @generated + */ + protected LayoutEditPolicy createLayoutEditPolicy() { + org.eclipse.gmf.runtime.diagram.ui.editpolicies.LayoutEditPolicy lep = new org.eclipse.gmf.runtime.diagram.ui.editpolicies.LayoutEditPolicy() { + + @Override + protected EditPolicy createChildEditPolicy(EditPart child) { + View childView = (View) child.getModel(); + String vid = UMLVisualIDRegistry.getVisualID(childView); + if (vid != null) { + switch (vid) { + case TimeObservationNameEditPart.VISUAL_ID: + case TimeObservationAppliedStereotypeEditPart.VISUAL_ID: + return new BorderItemSelectionEditPolicy() { + + @Override + protected List createSelectionHandles() { + MoveHandle mh = new MoveHandle((GraphicalEditPart) getHost()); + mh.setBorder(null); + return Collections.singletonList(mh); + } + }; + } + } + EditPolicy result = child.getEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE); + if (result == null) { + result = new NonResizableEditPolicy(); + } + return result; + } + + @Override + protected Command getMoveChildrenCommand(Request request) { + return null; + } + + @Override + protected Command getCreateCommand(CreateRequest request) { + return null; + } + }; + return lep; + } + + /** + * Papyrus codeGen + * + * @generated + **/ + @Override + protected void handleNotificationEvent(Notification event) { + /* + * when a node have external node labels, the methods refreshChildren() remove the EditPart corresponding to the Label from the EditPart + * Registry. After that, we can't reset the visibility to true (using the Show/Hide Label Action)! + */ + if (NotationPackage.eINSTANCE.getView_Visible().equals(event.getFeature())) { + Object notifier = event.getNotifier(); + List modelChildren = ((View) getModel()).getChildren(); + if (false == notifier instanceof Edge && false == notifier instanceof BasicCompartment) { + if (modelChildren.contains(event.getNotifier())) { + return; + } + } + } + super.handleNotificationEvent(event); + + } + + /** + * @generated + */ + protected IFigure createNodeShape() { + return primaryShape = new TimeObservationFigure(); + } + + /** + * org.eclipse.papyrus.uml.diagram.sequence.figures.TimeObservationFigure + * + * @generated + */ + @Override + public TimeObservationFigure getPrimaryShape() { + return (TimeObservationFigure) primaryShape; + } + + /** + * @generated + */ + @Override + protected void addBorderItem(IFigure borderItemContainer, IBorderItemEditPart borderItemEditPart) { + if (borderItemEditPart instanceof TimeObservationNameEditPart + || borderItemEditPart instanceof TimeObservationAppliedStereotypeEditPart) { + BorderItemLocator locator = new BorderItemLocator(getMainFigure(), PositionConstants.SOUTH); + locator.setBorderItemOffset(new Dimension(-20, -20)); + borderItemContainer.add(borderItemEditPart.getFigure(), locator); + } else { + super.addBorderItem(borderItemContainer, borderItemEditPart); + } + } + + /** + * @generated + */ + protected NodeFigure createNodePlate() { + RoundedRectangleNodePlateFigure result = new RoundedRectangleNodePlateFigure(40, 1); + return result; + } + + /** + * Creates figure for this edit part. + * + * Body of this method does not depend on settings in generation model + * so you may safely remove generated tag and modify it. + * + * @generated + */ + @Override + protected NodeFigure createMainFigure() { + NodeFigure figure = createNodePlate(); + figure.setLayoutManager(new StackLayout()); + IFigure shape = createNodeShape(); + figure.add(shape); + contentPane = setupContentPane(shape); + return figure; + + } + + /** + * Default implementation treats passed figure as content pane. + * Respects layout one may have set for generated figure. + * + * @param nodeShape + * instance of generated figure class + * @generated + */ + protected IFigure setupContentPane(IFigure nodeShape) { + return nodeShape; // use nodeShape itself as contentPane + } + + /** + * @generated + */ + @Override + public IFigure getContentPane() { + if (contentPane != null) { + return contentPane; + } + return super.getContentPane(); + } + + /** + * @generated + */ + @Override + protected void setForegroundColor(Color color) { + if (primaryShape != null) { + primaryShape.setForegroundColor(color); + } + } + + /** + * @generated + */ + @Override + protected void setLineWidth(int width) { + super.setLineWidth(width); + } + + /** + * @generated + */ + @Override + protected void setLineType(int style) { + if (primaryShape instanceof IPapyrusNodeFigure) { + ((IPapyrusNodeFigure) primaryShape).setLineStyle(style); + } + } + + /** + * @generated + */ + @Override + public EditPart getPrimaryChildEditPart() { + return getChildBySemanticHint(UMLVisualIDRegistry.getType(TimeObservationNameEditPart.VISUAL_ID)); + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeObservationNameEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeObservationNameEditPart.java new file mode 100644 index 00000000000..a0be8507a9e --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/TimeObservationNameEditPart.java @@ -0,0 +1,857 @@ +/** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + */ +package org.eclipse.papyrus.uml.diagram.sequence.edit.parts; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.transaction.RecordingCommand; +import org.eclipse.emf.transaction.RunnableWithResult; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.gef.AccessibleEditPart; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.Request; +import org.eclipse.gef.requests.DirectEditRequest; +import org.eclipse.gef.tools.DirectEditManager; +import org.eclipse.gmf.runtime.common.ui.services.parser.IParser; +import org.eclipse.gmf.runtime.common.ui.services.parser.IParserEditStatus; +import org.eclipse.gmf.runtime.common.ui.services.parser.ParserOptions; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; +import org.eclipse.gmf.runtime.diagram.ui.editparts.ITextAwareEditPart; +import org.eclipse.gmf.runtime.diagram.ui.editpolicies.LabelDirectEditPolicy; +import org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocator; +import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramColorRegistry; +import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants; +import org.eclipse.gmf.runtime.diagram.ui.tools.TextDirectEditManager; +import org.eclipse.gmf.runtime.draw2d.ui.figures.WrappingLabel; +import org.eclipse.gmf.runtime.emf.ui.services.parser.ISemanticParser; +import org.eclipse.gmf.runtime.notation.FontStyle; +import org.eclipse.gmf.runtime.notation.NotationPackage; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.viewers.ICellEditorValidator; +import org.eclipse.jface.window.Window; +import org.eclipse.papyrus.extensionpoints.editors.Activator; +import org.eclipse.papyrus.extensionpoints.editors.configuration.IAdvancedEditorConfiguration; +import org.eclipse.papyrus.extensionpoints.editors.configuration.ICustomDirectEditorConfiguration; +import org.eclipse.papyrus.extensionpoints.editors.configuration.IDirectEditorConfiguration; +import org.eclipse.papyrus.extensionpoints.editors.configuration.IPopupEditorConfiguration; +import org.eclipse.papyrus.extensionpoints.editors.ui.ExtendedDirectEditionDialog; +import org.eclipse.papyrus.extensionpoints.editors.ui.ILabelEditorDialog; +import org.eclipse.papyrus.extensionpoints.editors.ui.IPopupEditorHelper; +import org.eclipse.papyrus.extensionpoints.editors.utils.DirectEditorsUtil; +import org.eclipse.papyrus.extensionpoints.editors.utils.IDirectEditorsIds; +import org.eclipse.papyrus.infra.gmfdiag.common.editpart.PapyrusLabelEditPart; +import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.ExternalLabelPrimaryDragRoleEditPolicy; +import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.IMaskManagedLabelEditPolicy; +import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.IndirectMaskLabelEditPolicy; +import org.eclipse.papyrus.infra.gmfdiag.common.figure.node.PapyrusWrappingLabel; +import org.eclipse.papyrus.infra.gmfdiag.common.parsers.ParserUtil; +import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil; +import org.eclipse.papyrus.uml.diagram.common.directedit.MultilineLabelDirectEditManager; +import org.eclipse.papyrus.uml.diagram.common.editpolicies.IDirectEdition; +import org.eclipse.papyrus.uml.diagram.common.figure.node.ILabelFigure; +import org.eclipse.papyrus.uml.diagram.sequence.edit.policies.UMLTextSelectionEditPolicy; +import org.eclipse.papyrus.uml.diagram.sequence.part.UMLVisualIDRegistry; +import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes; +import org.eclipse.swt.SWT; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; +import org.eclipse.uml2.uml.Feature; + +/** + * @generated + */ +public class TimeObservationNameEditPart extends PapyrusLabelEditPart + implements ITextAwareEditPart, IBorderItemEditPart { + + /** + * @generated + */ + public static final String VISUAL_ID = "TimeObservation_NameLabel"; + + /** + * @generated + */ + private DirectEditManager manager; + + /** + * @generated + */ + private IParser parser; + + /** + * @generated + */ + private List parserElements; + + /** + * @generated + */ + private String defaultText; + + /** + * direct edition mode (default, undefined, registered editor, etc.) + * + * @generated + */ + protected int directEditionMode = IDirectEdition.UNDEFINED_DIRECT_EDITOR; + + /** + * configuration from a registered edit dialog + * + * @generated + */ + protected IDirectEditorConfiguration configuration; + + /** + * @generated + */ + static { + registerSnapBackPosition( + UMLVisualIDRegistry.getType( + org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationNameEditPart.VISUAL_ID), + new Point(0, 0)); + } + + /** + * @generated + */ + public TimeObservationNameEditPart(View view) { + super(view); + } + + /** + * @generated + */ + @Override + protected void createDefaultEditPolicies() { + super.createDefaultEditPolicies(); + installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new LabelDirectEditPolicy()); + installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, new UMLTextSelectionEditPolicy()); + installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, new ExternalLabelPrimaryDragRoleEditPolicy()); + } + + /** + * @generated + */ + @Override + public IBorderItemLocator getBorderItemLocator() { + IFigure parentFigure = getFigure().getParent(); + if (parentFigure != null && parentFigure.getLayoutManager() != null) { + Object constraint = parentFigure.getLayoutManager().getConstraint(getFigure()); + return (IBorderItemLocator) constraint; + } + return null; + } + + /** + * @generated + */ + @Override + public void refreshBounds() { + int x = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE.getLocation_X())).intValue(); + int y = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE.getLocation_Y())).intValue(); + int width = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE.getSize_Width())).intValue(); + int height = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE.getSize_Height())).intValue(); + getBorderItemLocator().setConstraint(new Rectangle(x, y, width, height)); + } + + /** + * @generated + */ + protected String getLabelTextHelper(IFigure figure) { + if (figure instanceof WrappingLabel) { + return ((WrappingLabel) figure).getText(); + } else if (figure instanceof ILabelFigure) { + return ((ILabelFigure) figure).getText(); + } else { + return ((Label) figure).getText(); + } + } + + /** + * @generated + */ + protected void setLabelTextHelper(IFigure figure, String text) { + if (figure instanceof WrappingLabel) { + ((WrappingLabel) figure).setText(text); + } else if (figure instanceof ILabelFigure) { + ((ILabelFigure) figure).setText(text); + } else { + ((Label) figure).setText(text); + } + } + + /** + * @generated + */ + protected Image getLabelIconHelper(IFigure figure) { + if (figure instanceof WrappingLabel) { + return ((WrappingLabel) figure).getIcon(); + } else if (figure instanceof ILabelFigure) { + return ((ILabelFigure) figure).getIcon(); + } else { + return ((Label) figure).getIcon(); + } + } + + /** + * @generated + */ + protected void setLabelIconHelper(IFigure figure, Image icon) { + if (figure instanceof WrappingLabel) { + ((WrappingLabel) figure).setIcon(icon); + } else if (figure instanceof ILabelFigure) { + ((ILabelFigure) figure).setIcon(icon); + } else { + ((Label) figure).setIcon(icon); + } + } + + /** + * @generated + */ + public void setLabel(IFigure figure) { + unregisterVisuals(); + setFigure(figure); + defaultText = getLabelTextHelper(figure); + registerVisuals(); + refreshVisuals(); + } + + /** + * @generated + */ + @Override + protected List getModelChildren() { + return Collections.EMPTY_LIST; + } + + /** + * @generated + */ + @Override + public IGraphicalEditPart getChildBySemanticHint(String semanticHint) { + return null; + } + + /** + * @generated + */ + public void setParser(IParser parser) { + this.parser = parser; + } + + /** + * @generated + */ + protected EObject getParserElement() { + return resolveSemanticElement(); + } + + /** + * @generated + */ + protected Image getLabelIcon() { + return DiagramEditPartsUtil.getIcon(getParserElement(), getViewer()); + } + + /** + * @generated + */ + protected String getLabelText() { + String text = null; + EObject parserElement = getParserElement(); + if (parserElement != null && getParser() != null) { + text = getParser().getPrintString(ParserUtil.getParserAdapter(getParserElement(), this), + getParserOptions().intValue()); + } + if (text == null || text.length() == 0) { + text = defaultText; + } + return text; + } + + /** + * @generated + */ + @Override + public void setLabelText(String text) { + setLabelTextHelper(getFigure(), text); + Object pdEditPolicy = getEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE); + if (pdEditPolicy instanceof UMLTextSelectionEditPolicy) { + ((UMLTextSelectionEditPolicy) pdEditPolicy).refreshFeedback(); + } + Object sfEditPolicy = getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE); + if (sfEditPolicy instanceof UMLTextSelectionEditPolicy) { + ((UMLTextSelectionEditPolicy) sfEditPolicy).refreshFeedback(); + } + } + + /** + * @generated + */ + @Override + public String getEditText() { + if (getParserElement() == null || getParser() == null) { + return ""; //$NON-NLS-1$ + } + return getParser().getEditString(ParserUtil.getParserAdapter(getParserElement(), this), + getParserOptions().intValue()); + } + + /** + * @generated + */ + protected boolean isEditable() { + return getParser() != null; + } + + /** + * @generated + */ + @Override + public ICellEditorValidator getEditTextValidator() { + return new ICellEditorValidator() { + + @Override + public String isValid(final Object value) { + if (value instanceof String) { + final EObject element = getParserElement(); + final IParser parser = getParser(); + try { + IParserEditStatus valid = (IParserEditStatus) getEditingDomain() + .runExclusive(new RunnableWithResult.Impl() { + + @Override + public void run() { + setResult(parser.isValidEditString(ParserUtil.getParserAdapter( + getParserElement(), TimeObservationNameEditPart.this), (String) value)); + } + }); + return valid.getCode() == IParserEditStatus.EDITABLE ? null : valid.getMessage(); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + + // shouldn't get here + return null; + } + }; + } + + /** + * @generated + */ + @Override + public IContentAssistProcessor getCompletionProcessor() { + if (getParserElement() == null || getParser() == null) { + return null; + } + return getParser().getCompletionProcessor(ParserUtil.getParserAdapter(getParserElement(), this)); + } + + /** + * @generated + */ + @Override + public ParserOptions getParserOptions() { + return ParserOptions.NONE; + } + + /** + * @generated + */ + @Override + public IParser getParser() { + if (parser == null) { + parser = ParserUtil.getParser(UMLElementTypes.TimeObservation_Shape, getParserElement(), this, VISUAL_ID); + } + return parser; + } + + /** + * @generated + */ + protected DirectEditManager getManager() { + if (manager == null) { + setManager(new MultilineLabelDirectEditManager(this, + MultilineLabelDirectEditManager.getTextCellEditorClass(this), + UMLEditPartFactory.getTextCellEditorLocator(this))); + } + return manager; + } + + /** + * @generated + */ + protected void setManager(DirectEditManager manager) { + this.manager = manager; + } + + /** + * @generated + */ + protected void performDirectEdit() { + BusyIndicator.showWhile(Display.getDefault(), new java.lang.Runnable() { + + @Override + public void run() { + getManager().show(); + } + }); + } + + /** + * @generated + */ + protected void performDirectEdit(Point eventLocation) { + if (getManager() instanceof TextDirectEditManager) { + ((TextDirectEditManager) getManager()).show(eventLocation.getSWTPoint()); + } + } + + /** + * @generated + */ + protected void performDirectEdit(char initialCharacter) { + if (getManager() instanceof TextDirectEditManager) { + ((TextDirectEditManager) getManager()).show(initialCharacter); + } else { + performDirectEdit(); + } + } + + /** + * @generated + */ + @Override + protected void performDirectEditRequest(Request request) { + + final Request theRequest = request; + + if (IDirectEdition.UNDEFINED_DIRECT_EDITOR == directEditionMode) { + directEditionMode = getDirectEditionType(); + } + switch (directEditionMode) { + case IDirectEdition.NO_DIRECT_EDITION: + // no direct edition mode => does nothing + return; + case IDirectEdition.EXTENDED_DIRECT_EDITOR: + updateExtendedEditorConfiguration(); + if (configuration == null || configuration.getLanguage() == null) { + // Create default edit manager + setManager(new MultilineLabelDirectEditManager(this, + MultilineLabelDirectEditManager.getTextCellEditorClass(this), + UMLEditPartFactory.getTextCellEditorLocator(this))); + performDefaultDirectEditorEdit(theRequest); + } else { + configuration.preEditAction(resolveSemanticElement()); + Dialog dialog = null; + if (configuration instanceof ICustomDirectEditorConfiguration) { + setManager(((ICustomDirectEditorConfiguration) configuration).createDirectEditManager(this)); + initializeDirectEditManager(theRequest); + return; + } else if (configuration instanceof IPopupEditorConfiguration) { + IPopupEditorHelper helper = ((IPopupEditorConfiguration) configuration) + .createPopupEditorHelper(this); + helper.showEditor(); + return; + } else if (configuration instanceof IAdvancedEditorConfiguration) { + dialog = ((IAdvancedEditorConfiguration) configuration).createDialog( + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), resolveSemanticElement(), + configuration.getTextToEdit(resolveSemanticElement())); + } else if (configuration instanceof IDirectEditorConfiguration) { + dialog = new ExtendedDirectEditionDialog( + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), resolveSemanticElement(), + configuration.getTextToEdit(resolveSemanticElement()), configuration); + } else { + return; + } + final Dialog finalDialog = dialog; + + if (Window.OK == dialog.open()) { + TransactionalEditingDomain domain = getEditingDomain(); + RecordingCommand command = new RecordingCommand(domain, "Edit Label") { + + @Override + protected void doExecute() { + configuration.postEditAction(resolveSemanticElement(), + ((ILabelEditorDialog) finalDialog).getValue()); + + } + }; + domain.getCommandStack().execute(command); + } + } + break; + case IDirectEdition.DEFAULT_DIRECT_EDITOR: + initializeDirectEditManager(theRequest); + break; + default: + break; + } + } + + /** + * @generated + */ + protected void initializeDirectEditManager(final Request request) { + // initialize the direct edit manager + try { + getEditingDomain().runExclusive(new Runnable() { + @Override + public void run() { + if (isActive() && isEditable()) { + if (request.getExtendedData() + .get(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR) instanceof Character) { + Character initialChar = (Character) request.getExtendedData() + .get(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR); + performDirectEdit(initialChar.charValue()); + } else { + performDirectEdit(); + } + } + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * @generated + */ + @Override + protected void refreshVisuals() { + super.refreshVisuals(); + refreshLabel(); + refreshFont(); + refreshFontColor(); + refreshUnderline(); + refreshStrikeThrough(); + } + + /** + * @generated + */ + protected void refreshLabel() { + EditPolicy maskLabelPolicy = getEditPolicy(IMaskManagedLabelEditPolicy.MASK_MANAGED_LABEL_EDIT_POLICY); + if (maskLabelPolicy == null) { + maskLabelPolicy = getEditPolicy(IndirectMaskLabelEditPolicy.INDRIRECT_MASK_MANAGED_LABEL); + } + if (maskLabelPolicy == null) { + View view = (View) getModel(); + if (view.isVisible()) { + setLabelTextHelper(getFigure(), getLabelText()); + setLabelIconHelper(getFigure(), getLabelIcon()); + } else { + setLabelTextHelper(getFigure(), ""); //$NON-NLS-1$ + setLabelIconHelper(getFigure(), null); + } + } + Object pdEditPolicy = getEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE); + if (pdEditPolicy instanceof UMLTextSelectionEditPolicy) { + ((UMLTextSelectionEditPolicy) pdEditPolicy).refreshFeedback(); + } + Object sfEditPolicy = getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE); + if (sfEditPolicy instanceof UMLTextSelectionEditPolicy) { + ((UMLTextSelectionEditPolicy) sfEditPolicy).refreshFeedback(); + } + } + + /** + * @generated + */ + protected void refreshUnderline() { + FontStyle style = (FontStyle) getFontStyleOwnerView().getStyle(NotationPackage.eINSTANCE.getFontStyle()); + if (style != null && getFigure() instanceof WrappingLabel) { + ((WrappingLabel) getFigure()).setTextUnderline(style.isUnderline()); + } + if (resolveSemanticElement() instanceof Feature) { + if (((Feature) resolveSemanticElement()).isStatic()) { + ((WrappingLabel) getFigure()).setTextUnderline(true); + } else { + ((WrappingLabel) getFigure()).setTextUnderline(false); + } + } + } + + /** + * @generated + */ + protected void refreshStrikeThrough() { + FontStyle style = (FontStyle) getFontStyleOwnerView().getStyle(NotationPackage.eINSTANCE.getFontStyle()); + if (style != null && getFigure() instanceof WrappingLabel) { + ((WrappingLabel) getFigure()).setTextStrikeThrough(style.isStrikeThrough()); + } + } + + /** + * @generated + */ + @Override + protected void refreshFont() { + FontStyle style = (FontStyle) getFontStyleOwnerView().getStyle(NotationPackage.eINSTANCE.getFontStyle()); + if (style != null) { + FontData fontData = new FontData(style.getFontName(), style.getFontHeight(), + (style.isBold() ? SWT.BOLD : SWT.NORMAL) | (style.isItalic() ? SWT.ITALIC : SWT.NORMAL)); + setFont(fontData); + } + } + + /** + * @generated + */ + @Override + protected void setFontColor(Color color) { + getFigure().setForegroundColor(color); + } + + /** + * @generated + */ + @Override + protected void addSemanticListeners() { + if (getParser() instanceof ISemanticParser) { + EObject element = resolveSemanticElement(); + parserElements = ((ISemanticParser) getParser()).getSemanticElementsBeingParsed(element); + for (int i = 0; i < parserElements.size(); i++) { + addListenerFilter("SemanticModel" + i, this, (EObject) parserElements.get(i)); //$NON-NLS-1$ + } + } else { + super.addSemanticListeners(); + } + } + + /** + * @generated + */ + @Override + protected void removeSemanticListeners() { + if (parserElements != null) { + for (int i = 0; i < parserElements.size(); i++) { + removeListenerFilter("SemanticModel" + i); //$NON-NLS-1$ + } + } else { + super.removeSemanticListeners(); + } + } + + /** + * @generated + */ + @Override + protected AccessibleEditPart getAccessibleEditPart() { + if (accessibleEP == null) { + accessibleEP = new AccessibleGraphicalEditPart() { + + @Override + public void getName(AccessibleEvent e) { + e.result = getLabelTextHelper(getFigure()); + } + }; + } + return accessibleEP; + } + + /** + * @generated + */ + private View getFontStyleOwnerView() { + return getPrimaryView(); + } + + /** + * Returns the kind of associated editor for direct edition. + * + * @return an int corresponding to the kind of direct editor, @see org.eclipse.papyrus.uml.diagram.common.editpolicies.IDirectEdition + * @generated + */ + public int getDirectEditionType() { + if (checkExtendedEditor()) { + initExtendedEditorConfiguration(); + return IDirectEdition.EXTENDED_DIRECT_EDITOR; + } + if (checkDefaultEdition()) { + return IDirectEdition.DEFAULT_DIRECT_EDITOR; + } + + // not a named element. no specific editor => do nothing + return IDirectEdition.NO_DIRECT_EDITION; + } + + /** + * Checks if an extended editor is present. + * + * @return true if an extended editor is present. + * @generated + */ + protected boolean checkExtendedEditor() { + if (resolveSemanticElement() != null) { + return DirectEditorsUtil.hasSpecificEditorConfiguration(resolveSemanticElement(), this); + } + return false; + } + + /** + * Checks if a default direct edition is available + * + * @return true if a default direct edition is available + * @generated + */ + protected boolean checkDefaultEdition() { + return (getParser() != null); + } + + /** + * Initializes the extended editor configuration + * + * @generated + */ + protected void initExtendedEditorConfiguration() { + if (configuration == null) { + final String languagePreferred = Activator.getDefault().getPreferenceStore().getString( + IDirectEditorsIds.EDITOR_FOR_ELEMENT + resolveSemanticElement().eClass().getInstanceClassName()); + if (languagePreferred != null && !languagePreferred.equals("")) { + configuration = DirectEditorsUtil.findEditorConfiguration(languagePreferred, resolveSemanticElement(), + this); + } else { + configuration = DirectEditorsUtil.findEditorConfiguration(IDirectEditorsIds.UML_LANGUAGE, + resolveSemanticElement(), this); + } + } + } + + /** + * Updates the preference configuration + * + * @generated + */ + protected void updateExtendedEditorConfiguration() { + String languagePreferred = Activator.getDefault().getPreferenceStore().getString( + IDirectEditorsIds.EDITOR_FOR_ELEMENT + resolveSemanticElement().eClass().getInstanceClassName()); + if (languagePreferred != null && !languagePreferred.equals("") + && !languagePreferred.equals(configuration.getLanguage())) { + configuration = DirectEditorsUtil.findEditorConfiguration(languagePreferred, resolveSemanticElement(), + this); + } else if (IDirectEditorsIds.SIMPLE_DIRECT_EDITOR.equals(languagePreferred)) { + configuration = null; + } + } + + /** + * Performs the direct edit usually used by GMF editors. + * + * @param theRequest + * the direct edit request that starts the direct edit system + * @generated + */ + protected void performDefaultDirectEditorEdit(final Request theRequest) { + // initialize the direct edit manager + try { + getEditingDomain().runExclusive(new Runnable() { + + @Override + public void run() { + if (isActive() && isEditable()) { + if (theRequest.getExtendedData() + .get(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR) instanceof Character) { + Character initialChar = (Character) theRequest.getExtendedData() + .get(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR); + performDirectEdit(initialChar.charValue()); + } else if ((theRequest instanceof DirectEditRequest) + && (getEditText().equals(getLabelText()))) { + DirectEditRequest editRequest = (DirectEditRequest) theRequest; + performDirectEdit(editRequest.getLocation()); + } else { + performDirectEdit(); + } + } + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * @generated + */ + @Override + protected void handleNotificationEvent(Notification event) { + Object feature = event.getFeature(); + if (NotationPackage.eINSTANCE.getFontStyle_FontColor().equals(feature)) { + Integer c = (Integer) event.getNewValue(); + setFontColor(DiagramColorRegistry.getInstance().getColor(c)); + } else if (NotationPackage.eINSTANCE.getFontStyle_Underline().equals(feature)) { + refreshUnderline(); + } else if (NotationPackage.eINSTANCE.getFontStyle_StrikeThrough().equals(feature)) { + refreshStrikeThrough(); + } else if (NotationPackage.eINSTANCE.getFontStyle_FontHeight().equals(feature) + || NotationPackage.eINSTANCE.getFontStyle_FontName().equals(feature) + || NotationPackage.eINSTANCE.getFontStyle_Bold().equals(feature) + || NotationPackage.eINSTANCE.getFontStyle_Italic().equals(feature)) { + refreshFont(); + } else { + if (getParser() != null && getParser().isAffectingEvent(event, getParserOptions().intValue())) { + refreshLabel(); + } + if (getParser() instanceof ISemanticParser) { + ISemanticParser modelParser = (ISemanticParser) getParser(); + if (modelParser.areSemanticElementsAffected(null, event)) { + removeSemanticListeners(); + if (resolveSemanticElement() != null) { + addSemanticListeners(); + } + refreshLabel(); + } + } + } + super.handleNotificationEvent(event); + } + + /** + * @generated + */ + @Override + protected IFigure createFigure() { + IFigure label = createFigurePrim(); + defaultText = getLabelTextHelper(label); + return label; + } + + /** + * @generated + */ + protected IFigure createFigurePrim() { + return new PapyrusWrappingLabel(); + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/UMLEditPartFactory.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/UMLEditPartFactory.java old mode 100755 new mode 100644 index 4a4923ade4e..91b9940ef2c --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/UMLEditPartFactory.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/edit/parts/UMLEditPartFactory.java @@ -115,6 +115,15 @@ public class UMLEditPartFactory implements EditPartFactory { case TimeConstraintAppliedStereotypeEditPart.VISUAL_ID: return new TimeConstraintAppliedStereotypeEditPart(view); + case TimeObservationBorderNodeEditPart.VISUAL_ID: + return new TimeObservationBorderNodeEditPart(view); + + case TimeObservationNameEditPart.VISUAL_ID: + return new TimeObservationNameEditPart(view); + + case TimeObservationAppliedStereotypeEditPart.VISUAL_ID: + return new TimeObservationAppliedStereotypeEditPart(view); + case InteractionInteractionCompartmentEditPart.VISUAL_ID: return new InteractionInteractionCompartmentEditPart(view); diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/Messages.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/Messages.java index 5c750bf205a..a0bd11969ba 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/Messages.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/Messages.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2016 CEA LIST. + * Copyright (c) 2016, 2018 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 2.0 @@ -10,6 +10,7 @@ * * Contributors: * CEA LIST - Initial API and implementation + * Christian W. Damus - bug 536486 */ package org.eclipse.papyrus.uml.diagram.sequence.part; @@ -254,292 +255,292 @@ public class Messages extends NLS { public static String ValidateActionMessage; /** - * @generated + * @generated not */ public static String Nodes1Group_title; /** - * @generated + * @generated not */ public static String Nodes1Group_desc; /** - * @generated + * @generated not */ public static String Edges2Group_title; /** - * @generated + * @generated not */ public static String Edges2Group_desc; /** - * @generated + * @generated not */ public static String Lifeline1CreationTool_title; /** - * @generated + * @generated not */ public static String Lifeline1CreationTool_desc; /** - * @generated + * @generated not */ public static String ActionExecutionSpecification2CreationTool_title; /** - * @generated + * @generated not */ public static String ActionExecutionSpecification2CreationTool_desc; /** - * @generated + * @generated not */ public static String BehaviorExecutionSpecification3CreationTool_title; /** - * @generated + * @generated not */ public static String BehaviorExecutionSpecification3CreationTool_desc; /** - * @generated + * @generated not */ public static String InteractionUse4CreationTool_title; /** - * @generated + * @generated not */ public static String InteractionUse4CreationTool_desc; /** - * @generated + * @generated not */ public static String CombinedFragment5CreationTool_title; /** - * @generated + * @generated not */ public static String CombinedFragment5CreationTool_desc; /** - * @generated + * @generated not */ public static String InteractionOperand6CreationTool_title; /** - * @generated + * @generated not */ public static String InteractionOperand6CreationTool_desc; /** - * @generated + * @generated not */ public static String Continuation7CreationTool_title; /** - * @generated + * @generated not */ public static String Continuation7CreationTool_desc; /** - * @generated + * @generated not */ public static String StateInvariant8CreationTool_title; /** - * @generated + * @generated not */ public static String StateInvariant8CreationTool_desc; /** - * @generated + * @generated not */ public static String Comment9CreationTool_title; /** - * @generated + * @generated not */ public static String Comment9CreationTool_desc; /** - * @generated + * @generated not */ public static String Constraint10CreationTool_title; /** - * @generated + * @generated not */ public static String Constraint10CreationTool_desc; /** - * @generated + * @generated not */ public static String DurationObservation11CreationTool_title; /** - * @generated + * @generated not */ public static String DurationObservation11CreationTool_desc; /** - * @generated + * @generated not */ public static String TimeConstraint12CreationTool_title; /** - * @generated + * @generated not */ public static String TimeConstraint12CreationTool_desc; /** - * @generated + * @generated not */ public static String TimeObservation13CreationTool_title; /** - * @generated + * @generated not */ public static String TimeObservation13CreationTool_desc; /** - * @generated + * @generated not */ public static String DurationConstraint14CreationTool_title; /** - * @generated + * @generated not */ public static String DurationConstraint14CreationTool_desc; /** - * @generated + * @generated not */ public static String NEWGateCreationTool_title; /** - * @generated + * @generated not */ public static String NEWGateCreationTool_desc; /** - * @generated + * @generated not */ public static String ConsiderIgnoreFragment16CreationTool_title; /** - * @generated + * @generated not */ public static String ConsiderIgnoreFragment16CreationTool_desc; /** - * @generated + * @generated not */ public static String MessageSync1CreationTool_title; /** - * @generated + * @generated not */ public static String MessageSync1CreationTool_desc; /** - * @generated + * @generated not */ public static String MessageAsync2CreationTool_title; /** - * @generated + * @generated not */ public static String MessageAsync2CreationTool_desc; /** - * @generated + * @generated not */ public static String MessageReply3CreationTool_title; /** - * @generated + * @generated not */ public static String MessageReply3CreationTool_desc; /** - * @generated + * @generated not */ public static String MessageCreate4CreationTool_title; /** - * @generated + * @generated not */ public static String MessageCreate4CreationTool_desc; /** - * @generated + * @generated not */ public static String MessageDelete5CreationTool_title; /** - * @generated + * @generated not */ public static String MessageDelete5CreationTool_desc; /** - * @generated + * @generated not */ public static String MessageLost6CreationTool_title; /** - * @generated + * @generated not */ public static String MessageLost6CreationTool_desc; /** - * @generated + * @generated not */ public static String MessageFound7CreationTool_title; /** - * @generated + * @generated not */ public static String MessageFound7CreationTool_desc; /** - * @generated + * @generated not */ public static String GeneralOrdering8CreationTool_title; /** - * @generated + * @generated not */ public static String GeneralOrdering8CreationTool_desc; /** - * @generated + * @generated not */ public static String Commentlink9CreationTool_title; /** - * @generated + * @generated not */ public static String Commentlink9CreationTool_desc; /** - * @generated + * @generated not */ public static String Constraintlink10CreationTool_title; /** - * @generated + * @generated not */ public static String Constraintlink10CreationTool_desc; /** - * @generated + * @generated not */ public static String ContextLink11CreationTool_title; /** - * @generated + * @generated not */ public static String ContextLink11CreationTool_desc; diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramEditor.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramEditor.java index 6930fea96d3..d5552fa9e14 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramEditor.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramEditor.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2016 CEA LIST. + * Copyright (c) 2016, 2018 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 2.0 @@ -10,6 +10,7 @@ * * Contributors: * CEA LIST - Initial API and implementation + * Christian W. Damus - bug 536486 */ package org.eclipse.papyrus.uml.diagram.sequence.part; @@ -127,7 +128,7 @@ public class UMLDiagramEditor extends UmlGmfDiagramEditor implements IProviderCh } /** - * @generated + * @generated NOT */ @Override protected PaletteRoot createPaletteRoot(PaletteRoot existingPaletteRoot) { diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramEditorUtil.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramEditorUtil.java index 7c83ae7baa4..2c7f284fdbd 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramEditorUtil.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramEditorUtil.java @@ -189,7 +189,7 @@ public class UMLDiagramEditorUtil { * Create a new instance of domain element associated with canvas. * * - * + * * @generated */ private static Package createInitialModel() { @@ -200,7 +200,7 @@ public class UMLDiagramEditorUtil { * Store model element in the resource. * * - * + * * @generated */ private static void attachModelToResource(Package model, Resource resource) { diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramUpdater.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramUpdater.java index 9d73f6ebb0f..2ffba826292 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramUpdater.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLDiagramUpdater.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2009, 2014 Atos Origin, CEA, and others. + * Copyright (c) 2009, 2018 Atos Origin, CEA, Christian W. Damus, and others. * * * All rights reserved. This program and the accompanying materials @@ -12,6 +12,7 @@ * Contributors: * Atos Origin - Initial API and implementation * Christian W. Damus (CEA) - bug 410909 + * Christian W. Damus - bug 536486 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.part; @@ -59,6 +60,7 @@ import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.MessageSyncEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.SequenceDiagramEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.StateInvariantEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintBorderNodeEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationBorderNodeEditPart; import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes; import org.eclipse.uml2.uml.ActionExecutionSpecification; import org.eclipse.uml2.uml.BehaviorExecutionSpecification; @@ -86,6 +88,7 @@ import org.eclipse.uml2.uml.Package; import org.eclipse.uml2.uml.PackageableElement; import org.eclipse.uml2.uml.StateInvariant; import org.eclipse.uml2.uml.TimeConstraint; +import org.eclipse.uml2.uml.TimeObservation; import org.eclipse.uml2.uml.UMLPackage; /** @@ -129,6 +132,8 @@ public class UMLDiagramUpdater implements DiagramUpdater { return getActionExecutionSpecification_Shape_SemanticChildren(view); case BehaviorExecutionSpecificationEditPart.VISUAL_ID: return getBehaviorExecutionSpecification_Shape_SemanticChildren(view); + case DestructionOccurrenceSpecificationEditPart.VISUAL_ID: + return getDestructionOccurrenceSpecification_Shape_SemanticChildren(view); case InteractionInteractionCompartmentEditPart.VISUAL_ID: return getInteraction_SubfragmentCompartment_SemanticChildren(view); case CombinedFragmentCombinedFragmentCompartmentEditPart.VISUAL_ID: @@ -416,6 +421,33 @@ public class UMLDiagramUpdater implements DiagramUpdater { return result; } + /** + * @generated NOT + */ + public List getDestructionOccurrenceSpecification_Shape_SemanticChildren(View view) { + if (!view.isSetElement()) { + return Collections.emptyList(); + } + DestructionOccurrenceSpecification modelElement = (DestructionOccurrenceSpecification) view.getElement(); + Interaction interaction = modelElement.getEnclosingInteraction(); + if (interaction == null) { + return Collections.emptyList(); + } + LinkedList result = new LinkedList<>(); + for (Iterator it = interaction.getOwnedRules().iterator(); it.hasNext();) { + Constraint childElement = (Constraint) it.next(); + // Does it constrain this destruction occurrence? + if (childElement.getConstrainedElements().contains(modelElement)) { + String visualID = UMLVisualIDRegistry.getNodeVisualID(view, childElement); + if (TimeConstraintBorderNodeEditPart.VISUAL_ID.equals(visualID)) { + result.add(new UMLNodeDescriptor(childElement, visualID)); + continue; + } + } + } + return result; + } + /** * @generated */ @@ -456,6 +488,8 @@ public class UMLDiagramUpdater implements DiagramUpdater { return getGate_Shape_ContainedLinks(view); case TimeConstraintBorderNodeEditPart.VISUAL_ID: return getTimeConstraint_Shape_ContainedLinks(view); + case TimeObservationBorderNodeEditPart.VISUAL_ID: + return getTimeObservation_Shape_ContainedLinks(view); case MessageSyncEditPart.VISUAL_ID: return getMessage_SynchEdge_ContainedLinks(view); case MessageAsyncEditPart.VISUAL_ID: @@ -519,6 +553,8 @@ public class UMLDiagramUpdater implements DiagramUpdater { return getGate_Shape_IncomingLinks(view); case TimeConstraintBorderNodeEditPart.VISUAL_ID: return getTimeConstraint_Shape_IncomingLinks(view); + case TimeObservationBorderNodeEditPart.VISUAL_ID: + return getTimeObservation_Shape_IncomingLinks(view); case MessageSyncEditPart.VISUAL_ID: return getMessage_SynchEdge_IncomingLinks(view); case MessageAsyncEditPart.VISUAL_ID: @@ -582,6 +618,8 @@ public class UMLDiagramUpdater implements DiagramUpdater { return getGate_Shape_OutgoingLinks(view); case TimeConstraintBorderNodeEditPart.VISUAL_ID: return getTimeConstraint_Shape_OutgoingLinks(view); + case TimeObservationBorderNodeEditPart.VISUAL_ID: + return getTimeObservation_Shape_OutgoingLinks(view); case MessageSyncEditPart.VISUAL_ID: return getMessage_SynchEdge_OutgoingLinks(view); case MessageAsyncEditPart.VISUAL_ID: @@ -773,6 +811,13 @@ public class UMLDiagramUpdater implements DiagramUpdater { return result; } + /** + * @generated + */ + public List getTimeObservation_Shape_ContainedLinks(View view) { + return Collections.emptyList(); + } + /** * @generated */ @@ -1194,6 +1239,29 @@ public class UMLDiagramUpdater implements DiagramUpdater { return result; } + /** + * @generated + */ + public List getTimeObservation_Shape_IncomingLinks(View view) { + TimeObservation modelElement = (TimeObservation) view.getElement(); + CrossReferenceAdapter crossReferencer = CrossReferenceAdapter + .getCrossReferenceAdapter(view.eResource().getResourceSet()); + LinkedList result = new LinkedList<>(); + result.addAll(getIncomingTypeModelFacetLinks_Message_SynchEdge(modelElement, crossReferencer)); + result.addAll(getIncomingTypeModelFacetLinks_Message_AsynchEdge(modelElement, crossReferencer)); + result.addAll(getIncomingTypeModelFacetLinks_Message_ReplyEdge(modelElement, crossReferencer)); + result.addAll(getIncomingTypeModelFacetLinks_Message_CreateEdge(modelElement, crossReferencer)); + result.addAll(getIncomingTypeModelFacetLinks_Message_DeleteEdge(modelElement, crossReferencer)); + result.addAll(getIncomingTypeModelFacetLinks_Message_LostEdge(modelElement, crossReferencer)); + result.addAll(getIncomingTypeModelFacetLinks_Message_FoundEdge(modelElement, crossReferencer)); + result.addAll(getIncomingFeatureModelFacetLinks_Comment_AnnotatedElementEdge(modelElement, crossReferencer)); + result.addAll( + getIncomingFeatureModelFacetLinks_Constraint_ConstrainedElementEdge(modelElement, crossReferencer)); + result.addAll(getIncomingTypeModelFacetLinks_DurationConstraint_Edge(modelElement, crossReferencer)); + result.addAll(getIncomingTypeModelFacetLinks_DurationObservation_Edge(modelElement, crossReferencer)); + return result; + } + /** * @generated */ @@ -1699,6 +1767,24 @@ public class UMLDiagramUpdater implements DiagramUpdater { return result; } + /** + * @generated + */ + public List getTimeObservation_Shape_OutgoingLinks(View view) { + TimeObservation modelElement = (TimeObservation) view.getElement(); + LinkedList result = new LinkedList<>(); + result.addAll(getOutgoingTypeModelFacetLinks_Message_SynchEdge(modelElement)); + result.addAll(getOutgoingTypeModelFacetLinks_Message_AsynchEdge(modelElement)); + result.addAll(getOutgoingTypeModelFacetLinks_Message_ReplyEdge(modelElement)); + result.addAll(getOutgoingTypeModelFacetLinks_Message_CreateEdge(modelElement)); + result.addAll(getOutgoingTypeModelFacetLinks_Message_DeleteEdge(modelElement)); + result.addAll(getOutgoingTypeModelFacetLinks_Message_LostEdge(modelElement)); + result.addAll(getOutgoingTypeModelFacetLinks_Message_FoundEdge(modelElement)); + result.addAll(getOutgoingTypeModelFacetLinks_DurationConstraint_Edge(modelElement)); + result.addAll(getOutgoingTypeModelFacetLinks_DurationObservation_Edge(modelElement)); + return result; + } + /** * @generated */ diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLVisualIDRegistry.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLVisualIDRegistry.java index b4e95fc5e3a..6b28e436e29 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLVisualIDRegistry.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/part/UMLVisualIDRegistry.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2009 Atos Origin. + * Copyright (c) 2009, 2018 Atos Origin, Christian W. Damus, CEA LIST, and others. * * * All rights reserved. This program and the accompanying materials @@ -11,6 +11,7 @@ * * Contributors: * Atos Origin - Initial API and implementation + * Christian W. Damus - bug 536486 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.part; @@ -82,6 +83,9 @@ import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.StateInvariantNameEdi import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintAppliedStereotypeEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintBorderNodeEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintNameEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationAppliedStereotypeEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationBorderNodeEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationNameEditPart; import org.eclipse.papyrus.uml.diagram.sequence.expressions.UMLOCLFactory; import org.eclipse.uml2.uml.Message; import org.eclipse.uml2.uml.Package; @@ -229,16 +233,36 @@ public class UMLVisualIDRegistry { .isSuperTypeOf(domainElement.eClass())) { return DestructionOccurrenceSpecificationEditPart.VISUAL_ID; } + if (UMLPackage.eINSTANCE.getTimeConstraint().isSuperTypeOf(domainElement.eClass())) { + return TimeConstraintBorderNodeEditPart.VISUAL_ID; + } + if (UMLPackage.eINSTANCE.getTimeObservation().isSuperTypeOf(domainElement.eClass())) { + return TimeObservationBorderNodeEditPart.VISUAL_ID; + } break; case ActionExecutionSpecificationEditPart.VISUAL_ID: if (UMLPackage.eINSTANCE.getTimeConstraint().isSuperTypeOf(domainElement.eClass())) { return TimeConstraintBorderNodeEditPart.VISUAL_ID; } + if (UMLPackage.eINSTANCE.getTimeObservation().isSuperTypeOf(domainElement.eClass())) { + return TimeObservationBorderNodeEditPart.VISUAL_ID; + } break; case BehaviorExecutionSpecificationEditPart.VISUAL_ID: if (UMLPackage.eINSTANCE.getTimeConstraint().isSuperTypeOf(domainElement.eClass())) { return TimeConstraintBorderNodeEditPart.VISUAL_ID; } + if (UMLPackage.eINSTANCE.getTimeObservation().isSuperTypeOf(domainElement.eClass())) { + return TimeObservationBorderNodeEditPart.VISUAL_ID; + } + break; + case DestructionOccurrenceSpecificationEditPart.VISUAL_ID: + if (UMLPackage.eINSTANCE.getTimeConstraint().isSuperTypeOf(domainElement.eClass())) { + return TimeConstraintBorderNodeEditPart.VISUAL_ID; + } + if (UMLPackage.eINSTANCE.getTimeObservation().isSuperTypeOf(domainElement.eClass())) { + return TimeObservationBorderNodeEditPart.VISUAL_ID; + } break; case InteractionInteractionCompartmentEditPart.VISUAL_ID: if (UMLPackage.eINSTANCE.getConsiderIgnoreFragment().isSuperTypeOf(domainElement.eClass())) { @@ -362,16 +386,28 @@ public class UMLVisualIDRegistry { if (DestructionOccurrenceSpecificationEditPart.VISUAL_ID.equals(nodeVisualID)) { return true; } + if (TimeConstraintBorderNodeEditPart.VISUAL_ID.equals(nodeVisualID)) { + return true; + } + if (TimeObservationBorderNodeEditPart.VISUAL_ID.equals(nodeVisualID)) { + return true; + } break; case ActionExecutionSpecificationEditPart.VISUAL_ID: if (TimeConstraintBorderNodeEditPart.VISUAL_ID.equals(nodeVisualID)) { return true; } + if (TimeObservationBorderNodeEditPart.VISUAL_ID.equals(nodeVisualID)) { + return true; + } break; case BehaviorExecutionSpecificationEditPart.VISUAL_ID: if (TimeConstraintBorderNodeEditPart.VISUAL_ID.equals(nodeVisualID)) { return true; } + if (TimeObservationBorderNodeEditPart.VISUAL_ID.equals(nodeVisualID)) { + return true; + } break; case StateInvariantEditPart.VISUAL_ID: if (StateInvariantNameEditPart.VISUAL_ID.equals(nodeVisualID)) { @@ -381,6 +417,14 @@ public class UMLVisualIDRegistry { return true; } break; + case DestructionOccurrenceSpecificationEditPart.VISUAL_ID: + if (TimeConstraintBorderNodeEditPart.VISUAL_ID.equals(nodeVisualID)) { + return true; + } + if (TimeObservationBorderNodeEditPart.VISUAL_ID.equals(nodeVisualID)) { + return true; + } + break; case ConstraintEditPart.VISUAL_ID: if (ConstraintNameEditPart.VISUAL_ID.equals(nodeVisualID)) { return true; @@ -407,6 +451,14 @@ public class UMLVisualIDRegistry { return true; } break; + case TimeObservationBorderNodeEditPart.VISUAL_ID: + if (TimeObservationNameEditPart.VISUAL_ID.equals(nodeVisualID)) { + return true; + } + if (TimeObservationAppliedStereotypeEditPart.VISUAL_ID.equals(nodeVisualID)) { + return true; + } + break; case InteractionInteractionCompartmentEditPart.VISUAL_ID: if (ConsiderIgnoreFragmentEditPart.VISUAL_ID.equals(nodeVisualID)) { return true; @@ -676,7 +728,7 @@ public class UMLVisualIDRegistry { case ContinuationEditPart.VISUAL_ID: case StateInvariantEditPart.VISUAL_ID: case TimeConstraintBorderNodeEditPart.VISUAL_ID: - case DestructionOccurrenceSpecificationEditPart.VISUAL_ID: + case TimeObservationBorderNodeEditPart.VISUAL_ID: case GateEditPart.VISUAL_ID: return true; } diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/ElementInitializers.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/ElementInitializers.java index 8dada167bcf..8f5f9698425 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/ElementInitializers.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/ElementInitializers.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2009 Atos Origin. + * Copyright (c) 2009, 2018 Atos Origin, Christian W. Damus, CEA LIST, and others. * * * All rights reserved. This program and the accompanying materials @@ -11,6 +11,7 @@ * * Contributors: * Atos Origin - Initial API and implementation + * Christian W. Damus - bug 536486 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.providers; @@ -42,6 +43,7 @@ import org.eclipse.uml2.uml.StateInvariant; import org.eclipse.uml2.uml.TimeConstraint; import org.eclipse.uml2.uml.TimeExpression; import org.eclipse.uml2.uml.TimeInterval; +import org.eclipse.uml2.uml.TimeObservation; import org.eclipse.uml2.uml.UMLFactory; import org.eclipse.uml2.uml.UMLPackage; @@ -210,6 +212,20 @@ public class ElementInitializers { } } + /** + * @generated + */ + public void init_TimeObservation_Shape(TimeObservation instance) { + try { + Object value_0 = name_TimeObservation_Shape(instance); + if (value_0 != null) { + instance.setName((String) value_0); + } + } catch (RuntimeException e) { + UMLDiagramEditorPlugin.getInstance().logError("Element initialization failed", e); //$NON-NLS-1$ + } + } + /** * Initialize a time interval * @@ -368,6 +384,13 @@ public class ElementInitializers { return getNamedElement(it, "", it.eClass().getName(), ""); } + /** + * @generated + */ + private String name_TimeObservation_Shape(TimeObservation it) { + return getNamedElement(it, "", it.eClass().getName(), ""); + } + /** * @generated */ diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLElementTypes.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLElementTypes.java index fd2ed934547..b3a0df15d68 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLElementTypes.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLElementTypes.java @@ -55,6 +55,7 @@ import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.MessageSyncEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.SequenceDiagramEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.StateInvariantEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintBorderNodeEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationBorderNodeEditPart; import org.eclipse.papyrus.uml.diagram.sequence.part.UMLDiagramEditorPlugin; import org.eclipse.swt.graphics.Image; import org.eclipse.uml2.uml.UMLPackage; @@ -167,6 +168,12 @@ public class UMLElementTypes { public static final IElementType TimeConstraint_Shape = getElementTypeByUniqueId( "org.eclipse.papyrus.umldi.TimeConstraint_Shape"); //$NON-NLS-1$ + /** + * @generated + */ + public static final IElementType TimeObservation_Shape = getElementTypeByUniqueId( + "org.eclipse.papyrus.umldi.TimeObservation_Shape"); //$NON-NLS-1$ + /** * @generated */ @@ -307,6 +314,8 @@ public class UMLElementTypes { elements.put(TimeConstraint_Shape, UMLPackage.eINSTANCE.getTimeConstraint()); + elements.put(TimeObservation_Shape, UMLPackage.eINSTANCE.getTimeObservation()); + elements.put(Message_SynchEdge, UMLPackage.eINSTANCE.getMessage()); elements.put(Message_AsynchEdge, UMLPackage.eINSTANCE.getMessage()); @@ -365,6 +374,7 @@ public class UMLElementTypes { KNOWN_ELEMENT_TYPES.add(Comment_Shape); KNOWN_ELEMENT_TYPES.add(Gate_Shape); KNOWN_ELEMENT_TYPES.add(TimeConstraint_Shape); + KNOWN_ELEMENT_TYPES.add(TimeObservation_Shape); KNOWN_ELEMENT_TYPES.add(Message_SynchEdge); KNOWN_ELEMENT_TYPES.add(Message_AsynchEdge); KNOWN_ELEMENT_TYPES.add(Message_ReplyEdge); @@ -430,6 +440,8 @@ public class UMLElementTypes { return Gate_Shape; case TimeConstraintBorderNodeEditPart.VISUAL_ID: return TimeConstraint_Shape; + case TimeObservationBorderNodeEditPart.VISUAL_ID: + return TimeObservation_Shape; case MessageSyncEditPart.VISUAL_ID: return Message_SynchEdge; case MessageAsyncEditPart.VISUAL_ID: diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLParserProvider.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLParserProvider.java index 51849fc45d8..f2e454b174c 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLParserProvider.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLParserProvider.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2009 Atos Origin. + * Copyright (c) 2009, 2018 Atos Origin, Christian W. Damus, CEA LIST, and others. * * * All rights reserved. This program and the accompanying materials @@ -11,6 +11,7 @@ * * Contributors: * Atos Origin - Initial API and implementation + * Christian W. Damus - bug 536486 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.providers; @@ -63,6 +64,8 @@ import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.StateInvariantLabelEd import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.StateInvariantNameEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintAppliedStereotypeEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintNameEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationAppliedStereotypeEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationNameEditPart; import org.eclipse.papyrus.uml.diagram.sequence.parser.custom.InteractionUseCustomParsers; import org.eclipse.papyrus.uml.diagram.sequence.parser.custom.LifelineCustomParsers; import org.eclipse.papyrus.uml.diagram.sequence.parser.custom.MessageCustomParser; @@ -288,6 +291,36 @@ public class UMLParserProvider extends AbstractProvider implements IParserProvid return timeConstraint_StereotypeLabel_Parser; } + /** + * @generated + */ + private ObservationParser timeObservation_NameLabel_Parser; + + /** + * @generated + */ + private IParser getTimeObservation_NameLabel_Parser() { + if (timeObservation_NameLabel_Parser == null) { + timeObservation_NameLabel_Parser = new ObservationParser(); + } + return timeObservation_NameLabel_Parser; + } + + /** + * @generated + */ + private AppliedStereotypeParser timeObservation_StereotypeLabel_Parser; + + /** + * @generated + */ + private IParser getTimeObservation_StereotypeLabel_Parser() { + if (timeObservation_StereotypeLabel_Parser == null) { + timeObservation_StereotypeLabel_Parser = new AppliedStereotypeParser(); + } + return timeObservation_StereotypeLabel_Parser; + } + /** * @generated */ @@ -614,6 +647,11 @@ public class UMLParserProvider extends AbstractProvider implements IParserProvid case TimeConstraintAppliedStereotypeEditPart.VISUAL_ID: return getTimeConstraint_StereotypeLabel_Parser(); + case TimeObservationNameEditPart.VISUAL_ID: + return getTimeObservation_NameLabel_Parser(); + case TimeObservationAppliedStereotypeEditPart.VISUAL_ID: + return getTimeObservation_StereotypeLabel_Parser(); + case MessageSyncNameEditPart.VISUAL_ID: return getMessage_SynchNameLabel_Parser(); case MessageSyncAppliedStereotypeEditPart.VISUAL_ID: diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLViewProvider.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLViewProvider.java index bded96cc179..a790e212465 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLViewProvider.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/src-gen/org/eclipse/papyrus/uml/diagram/sequence/providers/UMLViewProvider.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2009 Atos Origin. + * Copyright (c) 2009, 2018 Atos Origin, Christian W. Damus, CEA LIST, and others. * * * All rights reserved. This program and the accompanying materials @@ -12,6 +12,7 @@ * Contributors: * Atos Origin - Initial API and implementation * Vincent Lorenzo - vincent.lorenzo@cea.fr - CEA - LIST + * Christian W. Damus - bug 536486 *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.sequence.providers; @@ -124,6 +125,9 @@ import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.StateInvariantNameEdi import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintAppliedStereotypeEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintBorderNodeEditPart; import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeConstraintNameEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationAppliedStereotypeEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationBorderNodeEditPart; +import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationNameEditPart; import org.eclipse.papyrus.uml.diagram.sequence.part.UMLVisualIDRegistry; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.FontData; @@ -196,7 +200,7 @@ public class UMLViewProvider extends AbstractProvider implements IViewProvider { *

* This method can be overloaded when diagram editor inherits from another one, but should never be null *

- * + * * @return the unique identifier of the diagram for which views are provided. */ return SequenceDiagramEditPart.MODEL_ID; @@ -265,6 +269,7 @@ public class UMLViewProvider extends AbstractProvider implements IViewProvider { case CommentEditPart.VISUAL_ID: case GateEditPart.VISUAL_ID: case TimeConstraintBorderNodeEditPart.VISUAL_ID: + case TimeObservationBorderNodeEditPart.VISUAL_ID: if (domainElement == null || !visualID .equals(UMLVisualIDRegistry.getNodeVisualID(op.getContainerView(), domainElement))) { return false; // visual id in semantic hint should match visual id for domain element @@ -367,6 +372,8 @@ public class UMLViewProvider extends AbstractProvider implements IViewProvider { return createGate_Shape(domainElement, containerView, index, persisted, preferencesHint); case TimeConstraintBorderNodeEditPart.VISUAL_ID: return createTimeConstraint_Shape(domainElement, containerView, index, persisted, preferencesHint); + case TimeObservationBorderNodeEditPart.VISUAL_ID: + return createTimeObservation_Shape(domainElement, containerView, index, persisted, preferencesHint); } } // can't happen, provided #provides(CreateNodeViewOperation) is correct @@ -725,6 +732,36 @@ public class UMLViewProvider extends AbstractProvider implements IViewProvider { return node; } + /** + * @generated + */ + public Node createTimeObservation_Shape(EObject domainElement, View containerView, int index, boolean persisted, + PreferencesHint preferencesHint) { + Shape node = NotationFactory.eINSTANCE.createShape(); + node.setLayoutConstraint(NotationFactory.eINSTANCE.createBounds()); + node.setType(UMLVisualIDRegistry.getType(TimeObservationBorderNodeEditPart.VISUAL_ID)); + ViewUtil.insertChildView(containerView, node, index, persisted); + node.setElement(domainElement); + // initializeFromPreferences + final IPreferenceStore prefStore = (IPreferenceStore) preferencesHint.getPreferenceStore(); + + PreferenceInitializerForElementHelper.initFontStyleFromPrefs(node, prefStore, "TimeObservation"); + Node timeObservation_NameLabel = createLabel(node, + UMLVisualIDRegistry.getType(TimeObservationNameEditPart.VISUAL_ID)); + timeObservation_NameLabel.setLayoutConstraint(NotationFactory.eINSTANCE.createLocation()); + Location timeObservation_NameLabel_Location = (Location) timeObservation_NameLabel.getLayoutConstraint(); + timeObservation_NameLabel_Location.setX(25); + timeObservation_NameLabel_Location.setY(3); + Node timeObservation_StereotypeLabel = createLabel(node, + UMLVisualIDRegistry.getType(TimeObservationAppliedStereotypeEditPart.VISUAL_ID)); + timeObservation_StereotypeLabel.setLayoutConstraint(NotationFactory.eINSTANCE.createLocation()); + Location timeObservation_StereotypeLabel_Location = (Location) timeObservation_StereotypeLabel + .getLayoutConstraint(); + timeObservation_StereotypeLabel_Location.setX(0); + timeObservation_StereotypeLabel_Location.setY(-22); + return node; + } + /** * @generated */ diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations b/plugins/uml/org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations index 870fc17d12e..5d9fe034be2 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations @@ -1155,7 +1155,9 @@ - - + + + + diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/DestructionOccurrenceSpecificationEditHelperAdvice.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/DestructionOccurrenceSpecificationEditHelperAdvice.java new file mode 100644 index 00000000000..eb718f7733c --- /dev/null +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/DestructionOccurrenceSpecificationEditHelperAdvice.java @@ -0,0 +1,201 @@ +/***************************************************************************** + * Copyright (c) 2018 Christian W. Damus, CEA LIST, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.uml.service.types.helper.advice; + +import static java.util.stream.Collectors.toList; +import static org.eclipse.papyrus.uml.service.types.utils.ElementUtil.isTypeOf; + +import java.util.Collection; +import java.util.stream.Stream; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.gmf.runtime.common.core.command.ICommand; +import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest; +import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyDependentsRequest; +import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest; +import org.eclipse.papyrus.uml.service.types.element.UMLElementTypes; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.Component; +import org.eclipse.uml2.uml.Constraint; +import org.eclipse.uml2.uml.DestructionOccurrenceSpecification; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.ExecutionOccurrenceSpecification; +import org.eclipse.uml2.uml.Interaction; +import org.eclipse.uml2.uml.Message; +import org.eclipse.uml2.uml.Namespace; +import org.eclipse.uml2.uml.OccurrenceSpecification; +import org.eclipse.uml2.uml.TimeConstraint; +import org.eclipse.uml2.uml.TimeObservation; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * Advice for the editing of {@link DestructionOccurrenceSpecification}s. + */ +public class DestructionOccurrenceSpecificationEditHelperAdvice extends InteractionFragmentEditHelperAdvice { + + @Override + public void configureRequest(IEditCommandRequest request) { + super.configureRequest(request); + + if (request instanceof CreateElementRequest) { + configureCreateRequest((CreateElementRequest) request); + } + } + + protected void configureCreateRequest(CreateElementRequest request) { + if (isTypeOf(request.getElementType(), UMLElementTypes.TIME_CONSTRAINT) + && (request.getContainer() instanceof DestructionOccurrenceSpecification)) { + + DestructionOccurrenceSpecification destruction = (DestructionOccurrenceSpecification) request.getContainer(); + + // These constraints can only plausibly be owned by the nearest namespace + Namespace owner = destruction.getEnclosingInteraction(); + if (owner == null) { + owner = destruction.getEnclosingOperand(); + } + if (owner != null) { + // These constraints can only plausibly be owned by the nearest namespace + request.setContainer(owner); + } + } else if (isTypeOf(request.getElementType(), UMLElementTypes.TIME_OBSERVATION) + && (request.getContainer() instanceof DestructionOccurrenceSpecification)) { + + DestructionOccurrenceSpecification destruction = (DestructionOccurrenceSpecification) request.getContainer(); + + // These observations can only plausibly be owned by the nearest package or + // component + Namespace owner = destruction.getNearestPackage(); + Component component = getNearestComponent(destruction); + if (component != null && EcoreUtil.isAncestor(owner, component)) { + owner = component; + } + + if (owner != null) { + // These constraints can only plausibly be owned by the nearest namespace + request.setContainer(owner); + } + } + } + + /** + * Get the nearest {@link Component} containing an {@code element}, recursively. + * + * @param element + * an element + * @return the nearest component containing it, or {@code null} if none + */ + protected Component getNearestComponent(Element element) { + Component result = null; + + for (Element next = element; element != null && result == null; next = next.getOwner()) { + if (next instanceof Component) { + result = (Component) next; + } + } + + return result; + } + + /** + *
+	 * Add a command to associated {@link OccurrenceSpecification} and {@link Message}.
+	 * This command is only added if the start - finish referenced {@link OccurrenceSpecification} is not
+	 * referenced by another element or the start/finish references are of type {@link ExecutionOccurrenceSpecification}.
+	 * 
+ * + * @see org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice#getBeforeDestroyDependentsCommand(org.eclipse.gmf.runtime.emf.type.core.requests.DestroyDependentsRequest) + * + * @param request + * the request + * @return the command to execute before the edit helper work is done + */ + @Override + protected ICommand getBeforeDestroyDependentsCommand(DestroyDependentsRequest request) { + // Destroy any associated time constraints and time observations + DestructionOccurrenceSpecification destruction = (DestructionOccurrenceSpecification) request.getElementToDestroy(); + Interaction interaction = getInteraction(destruction); + + Stream timeConstraints = getTimeConstraints(interaction, destruction); + Stream timeObservations = getTimeObservations(interaction, destruction); + + Collection dependentsToDestroy = Stream.concat(timeConstraints, timeObservations).collect(toList()); + return dependentsToDestroy.isEmpty() + ? null + : request.getDestroyDependentsCommand(dependentsToDestroy); + } + + protected Interaction getInteraction(Element element) { + Interaction result = null; + + for (Element next = element; next != null && result == null; next = next.getOwner()) { + if (next instanceof Interaction) { + result = (Interaction) next; + } + } + + return result; + } + + /** + * Get time constraints in the contextual {@code interaction} that constrain only + * the {@code constrained} element and no others. + * + * @param interaction + * the contextual interaction + * @param constrained + * the constrained element + * + * @return its unique time constraints + */ + protected Stream getTimeConstraints(Interaction interaction, Element constrained) { + if (interaction == null) { + return Stream.empty(); + } + + return CacheAdapter.getCacheAdapter(constrained).getNonNavigableInverseReferences(constrained) + .stream() + .filter(setting -> setting.getEStructuralFeature() == UMLPackage.Literals.CONSTRAINT__CONSTRAINED_ELEMENT) + .map(setting -> (Constraint) setting.getEObject()) + .filter(TimeConstraint.class::isInstance) + .filter(c -> c.getConstrainedElements().size() == 1) + .filter(c -> getInteraction(c) == interaction) + .map(TimeConstraint.class::cast); + } + + /** + * Get time observations in the contextual {@code interaction} that reference the given + * {@code observed} element. + * + * @param interaction + * the contextual interaction + * @param observed + * the observed element + * + * @return its unique time constraints + */ + protected Stream getTimeObservations(Interaction interaction, Element observed) { + if (interaction == null) { + return Stream.empty(); + } + + // These observations are contained by packages, so the interaction context isn't + // actually useful. It is specified for API consistency with other cases + return CacheAdapter.getCacheAdapter(observed).getNonNavigableInverseReferences(observed) + .stream() + .filter(setting -> setting.getEStructuralFeature() == UMLPackage.Literals.TIME_OBSERVATION__EVENT) + .map(setting -> (TimeObservation) setting.getEObject()); + } +} diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/TimeConstraintHelperAdvice.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/TimeConstraintHelperAdvice.java index 28f8780b6e1..fc3733f1a07 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/TimeConstraintHelperAdvice.java +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/TimeConstraintHelperAdvice.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2010 CEA LIST. + * Copyright (c) 2010, 2018 CEA LIST, Christian W. Damus, and others. * * * All rights reserved. This program and the accompanying materials @@ -10,6 +10,7 @@ * SPDX-License-Identifier: EPL-2.0 * * Contributors: + Christian W. Damus - bug 536486 * * Yann Tanguy (CEA LIST) yann.tanguy@cea.fr - Initial API and implementation * @@ -33,7 +34,6 @@ import org.eclipse.papyrus.uml.service.types.utils.SequenceRequestConstant; import org.eclipse.uml2.uml.Message; import org.eclipse.uml2.uml.MessageOccurrenceSpecification; import org.eclipse.uml2.uml.MessageSort; -import org.eclipse.uml2.uml.NamedElement; import org.eclipse.uml2.uml.OccurrenceSpecification; import org.eclipse.uml2.uml.TimeConstraint; @@ -51,11 +51,10 @@ public class TimeConstraintHelperAdvice extends AbstractEditHelperAdvice { protected ICommand getBeforeConfigureCommand(final ConfigureRequest request) { return new ConfigureElementCommand(request) { + @SuppressWarnings("unlikely-arg-type") @Override protected CommandResult doExecuteWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException { - NamedElement element = (NamedElement) request.getElementToConfigure(); - TimeConstraint newElement = (TimeConstraint) request.getElementToConfigure(); // assign the occurrence specification Object paramOccurrence = getRequest().getParameter(SequenceRequestConstant.NEAREST_OCCURRENCE_SPECIFICATION); @@ -64,7 +63,8 @@ public class TimeConstraintHelperAdvice extends AbstractEditHelperAdvice { for (OccurrenceSpecification occurrence : occList) { if (occurrence instanceof MessageOccurrenceSpecification) { Message mess = ((MessageOccurrenceSpecification) occurrence).getMessage(); - if (mess != null && occurrence.equals(mess.getReceiveEvent()) && MessageSort.SYNCH_CALL_LITERAL.equals(mess.getMessageSort())) { + if (mess != null && occurrence.equals(mess.getReceiveEvent()) && MessageSort.SYNCH_CALL_LITERAL.equals(mess.getMessageSort()) + && occList.contains(mess.getSendEvent())) { // filter receive event, we prefer the corresponding start event at the same location continue; } @@ -74,7 +74,8 @@ public class TimeConstraintHelperAdvice extends AbstractEditHelperAdvice { break; } } - return CommandResult.newOKCommandResult(element); + + return CommandResult.newOKCommandResult(newElement); } }; } diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/TimeObservationEditHelperAdvice.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/TimeObservationEditHelperAdvice.java new file mode 100644 index 00000000000..5edae94718f --- /dev/null +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/TimeObservationEditHelperAdvice.java @@ -0,0 +1,76 @@ +/***************************************************************************** + * Copyright (c) 2010, 2018 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 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * CEA LIST - Initial API and implementation + * Christian W. Damus - bug 536486 + * + *****************************************************************************/ +package org.eclipse.papyrus.uml.service.types.helper.advice; + + +import static org.eclipse.papyrus.uml.service.types.helper.advice.TimeConstraintHelperAdvice.getAsOccSpecList; + +import java.util.List; + +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.gmf.runtime.common.core.command.CommandResult; +import org.eclipse.gmf.runtime.common.core.command.ICommand; +import org.eclipse.gmf.runtime.emf.type.core.commands.ConfigureElementCommand; +import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice; +import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest; +import org.eclipse.papyrus.uml.service.types.utils.SequenceRequestConstant; +import org.eclipse.uml2.uml.Message; +import org.eclipse.uml2.uml.MessageOccurrenceSpecification; +import org.eclipse.uml2.uml.MessageSort; +import org.eclipse.uml2.uml.OccurrenceSpecification; +import org.eclipse.uml2.uml.TimeObservation; + +/** + * Advice for configuration and editing of {@link TimeObservation}s. + */ +public class TimeObservationEditHelperAdvice extends AbstractEditHelperAdvice { + + @Override + protected ICommand getBeforeConfigureCommand(final ConfigureRequest request) { + return new ConfigureElementCommand(request) { + + @SuppressWarnings("unlikely-arg-type") + @Override + protected CommandResult doExecuteWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException { + TimeObservation newElement = (TimeObservation) request.getElementToConfigure(); + + // assign the occurrence specification + Object paramOccurrence = getRequest().getParameter(SequenceRequestConstant.NEAREST_OCCURRENCE_SPECIFICATION); + List occList = getAsOccSpecList(paramOccurrence); + if (!occList.isEmpty()) { + for (OccurrenceSpecification occurrence : occList) { + if (occurrence instanceof MessageOccurrenceSpecification) { + Message mess = ((MessageOccurrenceSpecification) occurrence).getMessage(); + if (mess != null && occurrence.equals(mess.getReceiveEvent()) && MessageSort.SYNCH_CALL_LITERAL.equals(mess.getMessageSort()) + && occList.contains(mess.getSendEvent())) { + // filter receive event, we prefer the corresponding start event at the same location + continue; + } + } + // otherwise, first occ is just fine + newElement.setEvent(occurrence); + break; + } + } + + return CommandResult.newOKCommandResult(newElement); + } + }; + } + +} -- cgit v1.2.3