Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCamille Letavernier2018-05-16 08:30:05 +0000
committerNicolas FAUVERGUE2018-05-22 15:58:01 +0000
commit42f3cf0568da9d6dcb5c15134a4e6591c648fec2 (patch)
treedb0bcd254076582d6dae5ad85661fcab3c8b263b
parentcf83366837c594724208ceaec5a6a9f1a951e352 (diff)
downloadorg.eclipse.papyrus-42f3cf0568da9d6dcb5c15134a4e6591c648fec2.tar.gz
org.eclipse.papyrus-42f3cf0568da9d6dcb5c15134a4e6591c648fec2.tar.xz
org.eclipse.papyrus-42f3cf0568da9d6dcb5c15134a4e6591c648fec2.zip
Bug 533770: [Sequence Diagram] Layout operands in a CombinedFragment
https://bugs.eclipse.org/bugs/show_bug.cgi?id=533770 - Add tests Change-Id: Id32713b6fd4efdd74425250ee5609738d09ce6e0 Signed-off-by: Camille Letavernier <cletavernier@eclipsesource.com>
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/UmlSequenceDiagramForMultiEditor.java3
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/FixInteractionOperandsOnOpening.java119
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.di2
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.notation62
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.uml19
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/style.css3
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/BugTests.java3
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/TestCombinedFragmentOperandsLayout.java362
8 files changed, 450 insertions, 123 deletions
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/UmlSequenceDiagramForMultiEditor.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/UmlSequenceDiagramForMultiEditor.java
index 3bb842f59f4..7b03eea31c1 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/UmlSequenceDiagramForMultiEditor.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/UmlSequenceDiagramForMultiEditor.java
@@ -28,7 +28,6 @@ import org.eclipse.papyrus.infra.internationalization.utils.utils.LabelInternati
import org.eclipse.papyrus.uml.diagram.sequence.part.UMLDiagramEditor;
import org.eclipse.papyrus.uml.diagram.sequence.part.UMLDiagramEditorPlugin;
import org.eclipse.papyrus.uml.diagram.sequence.util.FixGateViewOnOpening;
-import org.eclipse.papyrus.uml.diagram.sequence.util.FixInteractionOperandsOnOpening;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
@@ -65,8 +64,6 @@ public class UmlSequenceDiagramForMultiEditor extends UMLDiagramEditor {
*/
public UmlSequenceDiagramForMultiEditor(ServicesRegistry servicesRegistry, Diagram diagram) throws BackboneException, ServiceException {
super(servicesRegistry, diagram);
- // Fix interaction operand bounds (see bug 400460)
- new FixInteractionOperandsOnOpening().fix(diagram);
// Fix to add graphical view of gate. (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=389531)
new FixGateViewOnOpening().fix(diagram);
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/FixInteractionOperandsOnOpening.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/FixInteractionOperandsOnOpening.java
deleted file mode 100644
index 4f5952034d5..00000000000
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/FixInteractionOperandsOnOpening.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*****************************************************************************
- * Copyright (c) 2011 CEA LIST.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *
- * CEA LIST - Initial API and implementation (ansgar.radermacher@cea.fr)
- *
- *****************************************************************************/
-package org.eclipse.papyrus.uml.diagram.sequence.util;
-
-import java.util.Iterator;
-
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.emf.common.command.Command;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.transaction.RecordingCommand;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.emf.transaction.util.TransactionUtil;
-import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
-import org.eclipse.gmf.runtime.notation.Bounds;
-import org.eclipse.gmf.runtime.notation.Diagram;
-import org.eclipse.gmf.runtime.notation.Shape;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.InteractionOperandEditPart;
-
-/**
- * This class fixes the bounds of an interaction operation within a combined fragment.
- * The bounds have not values, if the model was made with Papyrus 0.8.X, see bug 400460
- */
-public class FixInteractionOperandsOnOpening {
-
- // height of header (e.g. "seg") in combined fragment (TODO: is there a better way to determine this height?)
- public final int TOP_HEIGHT = 20;
-
- /**
- * This method fixes the bounds of interaction operands
- *
- * @param diagram
- * the diagram
- */
- public void fix(Diagram diagram) {
- String IAO_ID = "" + InteractionOperandEditPart.VISUAL_ID;
- // Parse diagram content
- Iterator<EObject> it = diagram.eAllContents();
- while (it.hasNext()) {
- EObject current = it.next();
- // Select only shapes
- if (!(current instanceof Shape)) {
- continue;
- }
- String currentType = ((Shape) current).getType();
- if (IAO_ID.equals(currentType)) {
- Shape iaOperandShape = (Shape) current;
- View parentDecoration = ViewUtil.getViewContainer(iaOperandShape);
- if (parentDecoration != null) {
- View parentParentView = ViewUtil.getViewContainer(parentDecoration);
- if (parentParentView instanceof Shape) {
- Shape parentShape = (Shape) parentParentView;
- Bounds iaOperandShapeBounds = (Bounds) iaOperandShape.getLayoutConstraint();
- Bounds parentShapeBounds = (Bounds) parentShape.getLayoutConstraint();
- if ((iaOperandShapeBounds.getX() == 0) && (iaOperandShapeBounds.getY() == 0) && (iaOperandShapeBounds.getWidth() == -1)) {
- // distribute operands equally within the combined fragment.
- int size = parentDecoration.getChildren().size();
- int index = parentDecoration.getChildren().indexOf(iaOperandShape);
- int height = (parentShapeBounds.getHeight() - TOP_HEIGHT) / size;
- int y = index * height;
- final Rectangle newBounds = new Rectangle(0, y, parentShapeBounds.getWidth() - 2, height);
- // Fix when current location is not the valid location (only possible if parent size is set)
- TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(diagram);
- Command fixCommand = new FixLocationCommand(editingDomain, "Fix combined fragment on opening", iaOperandShapeBounds, newBounds);
- editingDomain.getCommandStack().execute(fixCommand);
- }
- }
- }
- }
- }
- }
-
- /**
- * This command sets the new bounds
- */
- public class FixLocationCommand extends RecordingCommand {
-
- /**
- * Interaction operand bounds
- */
- private Bounds iaViewBounds;
-
- /**
- * New (corrected) bounds
- */
- private Rectangle iaViewNewBounds;
-
- /** Constructor. */
- public FixLocationCommand(TransactionalEditingDomain domain, String label, Bounds iaViewBounds, Rectangle iaViewNewBounds) {
- super(domain, label);
- this.iaViewBounds = iaViewBounds;
- this.iaViewNewBounds = iaViewNewBounds;
- }
-
- @Override
- protected void doExecute() {
- iaViewBounds.setX(iaViewNewBounds.x());
- iaViewBounds.setY(iaViewNewBounds.y());
- iaViewBounds.setWidth(iaViewNewBounds.width());
- iaViewBounds.setHeight(iaViewNewBounds.height());
- }
-
- @Override
- public boolean canUndo() {
- return false;
- }
- }
-}
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.di b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.di
new file mode 100644
index 00000000000..8c549eecdc6
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<architecture:ArchitectureDescription xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:architecture="http://www.eclipse.org/papyrus/infra/core/architecture" contextId="org.eclipse.papyrus.infra.services.edit.TypeContext"/>
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.notation b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.notation
new file mode 100644
index 00000000000..aeb0148ea6d
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.notation
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:css="http://www.eclipse.org/papyrus/infra/gmfdiag/css" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/gmfdiag/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <notation:Diagram xmi:id="_UrrUwFjeEeiaQ6n7T6ZY4g" type="PapyrusUMLSequenceDiagram" name="operandsLayoutTest" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_UrrUwVjeEeiaQ6n7T6ZY4g" type="Interaction_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_UrrUwljeEeiaQ6n7T6ZY4g" type="Interaction_NameLabel"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_UrrUw1jeEeiaQ6n7T6ZY4g" type="Interaction_SubfragmentCompartment">
+ <children xmi:type="notation:Shape" xmi:id="_XoKUAFjeEeiaQ6n7T6ZY4g" type="CombinedFragment_Shape">
+ <children xmi:type="notation:BasicCompartment" xmi:id="_XoK7EVjeEeiaQ6n7T6ZY4g" type="CombinedFragment_SubfragmentCompartment">
+ <children xmi:type="notation:Shape" xmi:id="_XoLiIFjeEeiaQ6n7T6ZY4g" type="InteractionOperand_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_XoLiIljeEeiaQ6n7T6ZY4g" type="InteractionOperand_Guard">
+ <element xmi:type="uml:InteractionConstraint" href="Bug533770-OperandsLayout.uml#_Xn4AIFjeEeiaQ6n7T6ZY4g"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XoLiI1jeEeiaQ6n7T6ZY4g" x="5" y="5"/>
+ </children>
+ <element xmi:type="uml:InteractionOperand" href="Bug533770-OperandsLayout.uml#_Xn3ZEFjeEeiaQ6n7T6ZY4g"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XoLiIVjeEeiaQ6n7T6ZY4g" height="141"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_fp4VcFjjEeiaQ6n7T6ZY4g" type="InteractionOperand_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_fp4VcljjEeiaQ6n7T6ZY4g" type="InteractionOperand_Guard">
+ <element xmi:type="uml:InteractionConstraint" href="Bug533770-OperandsLayout.uml#_fpmBkFjjEeiaQ6n7T6ZY4g"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_fp4Vc1jjEeiaQ6n7T6ZY4g" x="5" y="5"/>
+ </children>
+ <element xmi:type="uml:InteractionOperand" href="Bug533770-OperandsLayout.uml#_fpiXMFjjEeiaQ6n7T6ZY4g"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_fp4VcVjjEeiaQ6n7T6ZY4g" height="81"/>
+ </children>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_XoK7EljeEeiaQ6n7T6ZY4g"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_XoK7E1jeEeiaQ6n7T6ZY4g"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XoK7FFjeEeiaQ6n7T6ZY4g"/>
+ </children>
+ <element xmi:type="uml:CombinedFragment" href="Bug533770-OperandsLayout.uml#_XnsZ8FjeEeiaQ6n7T6ZY4g"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XoK7EFjeEeiaQ6n7T6ZY4g" x="114" y="76" width="441" height="241"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_Wk6uUFjeEeiaQ6n7T6ZY4g" type="Lifeline_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_Wk78cFjeEeiaQ6n7T6ZY4g" type="Lifeline_NameLabel"/>
+ <element xmi:type="uml:Lifeline" href="Bug533770-OperandsLayout.uml#_Wki64FjeEeiaQ6n7T6ZY4g"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Wk7VYFjeEeiaQ6n7T6ZY4g" x="154" y="10"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_W0SnEFjeEeiaQ6n7T6ZY4g" type="Lifeline_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_W0SnEljeEeiaQ6n7T6ZY4g" type="Lifeline_NameLabel"/>
+ <element xmi:type="uml:Lifeline" href="Bug533770-OperandsLayout.uml#_W0IPAFjeEeiaQ6n7T6ZY4g"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_W0SnEVjeEeiaQ6n7T6ZY4g" x="394" y="10"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_W_X1sFjeEeiaQ6n7T6ZY4g" type="Lifeline_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_W_X1sljeEeiaQ6n7T6ZY4g" type="Lifeline_NameLabel"/>
+ <element xmi:type="uml:Lifeline" href="Bug533770-OperandsLayout.uml#_W_RIAFjeEeiaQ6n7T6ZY4g"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_W_X1sVjeEeiaQ6n7T6ZY4g" x="654" y="10"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_UrrUxFjeEeiaQ6n7T6ZY4g"/>
+ </children>
+ <element xmi:type="uml:Interaction" href="Bug533770-OperandsLayout.uml#_UrUIYFjeEeiaQ6n7T6ZY4g"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_UrrUxVjeEeiaQ6n7T6ZY4g"/>
+ </children>
+ <styles xmi:type="notation:StringValueStyle" xmi:id="_UrrUxljeEeiaQ6n7T6ZY4g" name="diagram_compatibility_version" stringValue="1.4.0"/>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_UrrUx1jeEeiaQ6n7T6ZY4g"/>
+ <styles xmi:type="style:PapyrusDiagramStyle" xmi:id="_UrrUyFjeEeiaQ6n7T6ZY4g" diagramKindId="org.eclipse.papyrus.uml.diagram.sequence">
+ <owner xmi:type="uml:Model" href="Bug533770-OperandsLayout.uml#_UqAg0FjeEeiaQ6n7T6ZY4g"/>
+ </styles>
+ <element xmi:type="uml:Interaction" href="Bug533770-OperandsLayout.uml#_UrUIYFjeEeiaQ6n7T6ZY4g"/>
+ </notation:Diagram>
+ <css:ModelStyleSheets xmi:id="_h0RisFjeEeiaQ6n7T6ZY4g">
+ <stylesheets xmi:type="css:StyleSheetReference" xmi:id="_h0YQYFjeEeiaQ6n7T6ZY4g" path="style.css"/>
+ </css:ModelStyleSheets>
+</xmi:XMI>
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.uml b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.uml
new file mode 100644
index 00000000000..9bfd2f6ace6
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/Bug533770-OperandsLayout.uml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_UqAg0FjeEeiaQ6n7T6ZY4g" name="Bug533770-OperandsLayout">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_U2VsoFjeEeiaQ6n7T6ZY4g">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Interaction" xmi:id="_UrUIYFjeEeiaQ6n7T6ZY4g" name="Interaction1">
+ <lifeline xmi:type="uml:Lifeline" xmi:id="_Wki64FjeEeiaQ6n7T6ZY4g" name="Lifeline1" coveredBy="_Xn3ZEFjeEeiaQ6n7T6ZY4g _fpiXMFjjEeiaQ6n7T6ZY4g"/>
+ <lifeline xmi:type="uml:Lifeline" xmi:id="_W0IPAFjeEeiaQ6n7T6ZY4g" name="Lifeline2" coveredBy="_Xn3ZEFjeEeiaQ6n7T6ZY4g _fpiXMFjjEeiaQ6n7T6ZY4g"/>
+ <lifeline xmi:type="uml:Lifeline" xmi:id="_W_RIAFjeEeiaQ6n7T6ZY4g" name="Lifeline3" coveredBy="_fpiXMFjjEeiaQ6n7T6ZY4g _Xn3ZEFjeEeiaQ6n7T6ZY4g"/>
+ <fragment xmi:type="uml:CombinedFragment" xmi:id="_XnsZ8FjeEeiaQ6n7T6ZY4g" name="TestedCF">
+ <operand xmi:type="uml:InteractionOperand" xmi:id="_Xn3ZEFjeEeiaQ6n7T6ZY4g" name="InteractionOperand0" covered="_W_RIAFjeEeiaQ6n7T6ZY4g _W0IPAFjeEeiaQ6n7T6ZY4g _Wki64FjeEeiaQ6n7T6ZY4g">
+ <guard xmi:type="uml:InteractionConstraint" xmi:id="_Xn4AIFjeEeiaQ6n7T6ZY4g" name="guard"/>
+ </operand>
+ <operand xmi:type="uml:InteractionOperand" xmi:id="_fpiXMFjjEeiaQ6n7T6ZY4g" name="InteractionOperand2" covered="_W_RIAFjeEeiaQ6n7T6ZY4g _W0IPAFjeEeiaQ6n7T6ZY4g _Wki64FjeEeiaQ6n7T6ZY4g">
+ <guard xmi:type="uml:InteractionConstraint" xmi:id="_fpmBkFjjEeiaQ6n7T6ZY4g" name="guard"/>
+ </operand>
+ </fragment>
+ </packagedElement>
+</uml:Model>
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/style.css b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/style.css
new file mode 100644
index 00000000000..eaddd93f659
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/style.css
@@ -0,0 +1,3 @@
+* {
+ fontName: Roboto; /* Used a fixed font to make sure the layout is deterministic */
+}
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/BugTests.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/BugTests.java
index dd5c472bd39..eb64d422e3c 100644
--- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/BugTests.java
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/BugTests.java
@@ -1,6 +1,6 @@
/*****************************************************************************
* Copyright (c) 2012, 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
* which accompanies this distribution, and is available at
@@ -34,6 +34,7 @@ import org.junit.runners.Suite.SuiteClasses;
TestAdvancedDragDrop_364696.class,
TestGuardEdition_364808.class,
CombinedFragmentRegressionTest.class,
+ TestCombinedFragmentOperandsLayout.class,
})
public class BugTests {
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/TestCombinedFragmentOperandsLayout.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/TestCombinedFragmentOperandsLayout.java
new file mode 100644
index 00000000000..1bde54d8d0c
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/TestCombinedFragmentOperandsLayout.java
@@ -0,0 +1,362 @@
+/*****************************************************************************
+ * Copyright (c) 2018 EclipseSource and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * EclipseSource - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.diagram.sequence.tests.bug;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Objects;
+
+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.gef.EditPart;
+import org.eclipse.gef.RequestConstants;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateUnspecifiedTypeRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil;
+import org.eclipse.papyrus.junit.framework.classification.tests.AbstractPapyrusTest;
+import org.eclipse.papyrus.junit.utils.rules.ActiveDiagram;
+import org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture;
+import org.eclipse.papyrus.junit.utils.rules.PluginResource;
+import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes;
+import org.eclipse.papyrus.uml.diagram.sequence.requests.MoveSeparatorRequest;
+import org.eclipse.uml2.uml.CombinedFragment;
+import org.eclipse.uml2.uml.InteractionOperand;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test the layout of Operands in a CombinedFragment,
+ * as implemented in Bug 533770 (And subtasks)
+ */
+@PluginResource({ "resource/bugs/Bug533770-OperandsLayout.di", "resource/bugs/style.css" })
+@ActiveDiagram("operandsLayoutTest")
+public class TestCombinedFragmentOperandsLayout extends AbstractPapyrusTest {
+
+ /**
+ * Size of the CF Label (It is fixed on all platforms, because we use a font explicitly shipped with Papyrus)
+ */
+ private static final int CF_LABEL_HEIGHT = 19;
+ /**
+ * Initial value for the CF Width
+ */
+ private static final int CF_WIDTH = 441;
+ /**
+ * Initial value for the CF Height
+ */
+ private static final int CF_HEIGHT = 241;
+ /**
+ * Initial value for the first operand height
+ */
+ private static final int OP1_H = 141;
+ /**
+ * Initial value for the second operand height
+ */
+ private static final int OP2_H = 81;
+
+ private GraphicalEditPart cfEditPart;
+ private GraphicalEditPart op1EditPart;
+ private GraphicalEditPart op2EditPart;
+
+ @Rule
+ public final PapyrusEditorFixture editor = new PapyrusEditorFixture();
+
+ @Before
+ public void initParts() {
+ cfEditPart = (GraphicalEditPart) editor.findEditPart("TestedCF", CombinedFragment.class);
+ op1EditPart = (GraphicalEditPart) editor.findEditPart("InteractionOperand0", InteractionOperand.class);
+ op2EditPart = (GraphicalEditPart) editor.findEditPart("InteractionOperand2", InteractionOperand.class);
+ }
+
+ @Test
+ public void testSimpleLayout() {
+ IFigure cfFigure = cfEditPart.getFigure();
+ Rectangle bounds = cfFigure.getBounds();
+
+ assertSize(CF_WIDTH, CF_HEIGHT, bounds.getSize());
+
+ assertOperandSize(CF_WIDTH, OP1_H, op1EditPart);
+ assertOperandSize(CF_WIDTH, OP2_H, op2EditPart);
+ }
+
+ @Test
+ public void testResizeFragmentSE() {
+ ChangeBoundsRequest request = new ChangeBoundsRequest(RequestConstants.REQ_RESIZE);
+ int deltaW = 40;
+ int deltaH = 80;
+ request.setEditParts(cfEditPart);
+ request.setSizeDelta(new Dimension(deltaW, deltaH));
+ request.setResizeDirection(PositionConstants.SOUTH_EAST);
+
+ Command command = cfEditPart.getCommand(request);
+ editor.execute(command);
+
+ IFigure cfFigure = cfEditPart.getFigure();
+ Rectangle bounds = cfFigure.getBounds();
+
+ // check the CF was properly resized
+ assertSize(CF_WIDTH + deltaW, CF_HEIGHT + deltaH, bounds.getSize());
+
+ GraphicalEditPart firstOperand = (GraphicalEditPart) editor.findEditPart("InteractionOperand0", InteractionOperand.class);
+ GraphicalEditPart secondOperand = (GraphicalEditPart) editor.findEditPart("InteractionOperand2", InteractionOperand.class);
+
+ // check that the last operand was properly resized
+ assertOperandSize(CF_WIDTH + deltaW, OP1_H, firstOperand);
+ assertOperandSize(CF_WIDTH + deltaW, OP2_H + deltaH, secondOperand);
+ }
+
+ @Test
+ public void testResizeFragmentNW() {
+ ChangeBoundsRequest request = new ChangeBoundsRequest(RequestConstants.REQ_RESIZE);
+ int deltaW = 60;
+ int deltaH = 25;
+ request.setEditParts(cfEditPart);
+ request.setSizeDelta(new Dimension(deltaW, deltaH));
+ request.setMoveDelta(new Point(-deltaW, -deltaH));
+ request.setResizeDirection(PositionConstants.NORTH_WEST);
+
+ Command command = cfEditPart.getCommand(request);
+ editor.execute(command);
+
+ IFigure cfFigure = cfEditPart.getFigure();
+ Rectangle bounds = cfFigure.getBounds();
+
+ // check the CF was properly resized
+ assertSize(CF_WIDTH + deltaW, CF_HEIGHT + deltaH, bounds.getSize());
+
+ GraphicalEditPart firstOperand = (GraphicalEditPart) editor.findEditPart("InteractionOperand0", InteractionOperand.class);
+ GraphicalEditPart secondOperand = (GraphicalEditPart) editor.findEditPart("InteractionOperand2", InteractionOperand.class);
+
+ // check that the first operand was properly resized
+ assertOperandSize(CF_WIDTH + deltaW, OP1_H + deltaH, firstOperand);
+ assertOperandSize(CF_WIDTH + deltaW, OP2_H, secondOperand);
+ }
+
+ @Test
+ public void testCreateOperand() {
+ int height = 55;
+
+ assertOperandSize(CF_WIDTH, OP1_H, op1EditPart);
+ assertOperandSize(CF_WIDTH, OP2_H, op2EditPart);
+
+ Rectangle initialOp2Bounds = op2EditPart.getFigure().getBounds().getCopy();
+
+ GraphicalEditPart op3EditPart = createOperand(op1EditPart, at(200, height, op1EditPart));
+
+ // The first operand is shrunk, and gets the new height (Delta between its top and mouse location)
+ assertOperandSize(CF_WIDTH, height, op1EditPart);
+ // The new operand is inserted in the middle, and gets the remaining height
+ assertOperandSize(CF_WIDTH, OP1_H - height, op3EditPart);
+ // Op2 is not affected
+ assertOperandSize(CF_WIDTH, OP2_H, op2EditPart);
+
+ // Double-check that Op2 is not affected, by also checking its location.
+ Assert.assertEquals(initialOp2Bounds, op2EditPart.getFigure().getBounds());
+ }
+
+ @Test
+ public void testResizeOperand() {
+ // Create a few more operands first. We want several separators, to make sure we can manipulate each of them (First, Last, Middle)
+ GraphicalEditPart op3EditPart = createOperand(op1EditPart, at(200, 55, op1EditPart));
+ GraphicalEditPart op4EditPart = createOperand(op3EditPart, at(200, 35, op3EditPart));
+
+ // Sizes before resize
+ int op1Height = 55;
+ int op2Height = 81;
+ int op3Height = 35;
+ int op4Height = 51; // 141 - 55 - 35
+
+ // Check that initial state is what we expect
+ assertOperandSize(CF_WIDTH, op1Height, op1EditPart);
+ assertOperandSize(CF_WIDTH, op2Height, op2EditPart);
+ assertOperandSize(CF_WIDTH, op3Height, op3EditPart);
+ assertOperandSize(CF_WIDTH, op4Height, op4EditPart);
+
+ // Operands order: 1, 3, 4, 2
+
+ { // Move the first separator down (Between 1 and 3)
+ MoveSeparatorRequest resizeOp1Op3 = new MoveSeparatorRequest(0);
+ Point separatorLocation = at(100, 0, op3EditPart);
+
+ int deltaH = 15;
+ resizeOp1Op3.setMoveDelta(new Point(0, deltaH));
+ resizeOp1Op3.setLocation(separatorLocation);
+ resizeOp1Op3.setEditParts(Collections.singletonList(cfEditPart));
+ editor.execute(cfEditPart.getCommand(resizeOp1Op3));
+
+ op1Height += deltaH; // 55 -> 70
+ op3Height -= deltaH; // 35 -> 20
+
+ assertOperandSize(CF_WIDTH, op1Height, op1EditPart);
+ assertOperandSize(CF_WIDTH, op3Height, op3EditPart);
+ }
+
+ { // Move the middle separator down (Between 3 and 4)
+
+ MoveSeparatorRequest resizeOp3Op4 = new MoveSeparatorRequest(1);
+ Point separatorLocation = at(100, 0, op4EditPart);
+
+ int deltaH = 30;
+ resizeOp3Op4.setMoveDelta(new Point(0, deltaH));
+ resizeOp3Op4.setLocation(separatorLocation);
+ resizeOp3Op4.setEditParts(Collections.singletonList(cfEditPart));
+ editor.execute(cfEditPart.getCommand(resizeOp3Op4));
+
+ op3Height += deltaH; // 20 -> 50
+ op4Height -= deltaH; // 51 -> 21
+
+ assertOperandSize(CF_WIDTH, op3Height, op3EditPart);
+ assertOperandSize(CF_WIDTH, op4Height, op4EditPart);
+ }
+
+
+ { // Move the last separator up (Between 4 and 2)
+ MoveSeparatorRequest resizeOp4Op2 = new MoveSeparatorRequest(2);
+ Point separatorLocation = at(100, 0, op2EditPart);
+
+ int deltaH = -10;
+ resizeOp4Op2.setMoveDelta(new Point(0, deltaH));
+ resizeOp4Op2.setLocation(separatorLocation);
+ resizeOp4Op2.setEditParts(Collections.singletonList(cfEditPart));
+ editor.execute(cfEditPart.getCommand(resizeOp4Op2));
+
+ op4Height += deltaH; // 21 -> 11
+ op2Height -= deltaH; // 81 -> 91
+
+ assertOperandSize(CF_WIDTH, op4Height, op4EditPart);
+ assertOperandSize(CF_WIDTH, op2Height, op2EditPart);
+ }
+ }
+
+ @Test
+ public void testDeleteOperand() {
+ // Create a few more operands first.
+ GraphicalEditPart op3EditPart = createOperand(op1EditPart, at(200, 55, op1EditPart));
+ GraphicalEditPart op4EditPart = createOperand(op3EditPart, at(200, 35, op3EditPart));
+ GraphicalEditPart op5EditPart = createOperand(op2EditPart, at(150, 52, op2EditPart));
+
+ int op1Height = 55;
+ int op2Height = 52;
+ int op3Height = 35;
+ int op4Height = 51; // 141 - 55 - 35
+ int op5Height = 29; // 81 - 52
+
+ // Check that initial state is what we expect
+ assertOperandSize(CF_WIDTH, op1Height, op1EditPart);
+ assertOperandSize(CF_WIDTH, op2Height, op2EditPart);
+ assertOperandSize(CF_WIDTH, op3Height, op3EditPart);
+ assertOperandSize(CF_WIDTH, op4Height, op4EditPart);
+ assertOperandSize(CF_WIDTH, op5Height, op5EditPart);
+
+ // Operands order: 1, 3, 4, 2, 5
+
+ { // Delete the first one. It should expand the next one (3)
+ editor.delete(op1EditPart);
+
+ op3Height += op1Height; // 35 -> 90
+ assertOperandSize(CF_WIDTH, op3Height, op3EditPart);
+ }
+
+ { // Delete the last one. It should expand the previous one (2)
+ editor.delete(op5EditPart);
+
+ op2Height += op5Height; // 52 -> 81
+ assertOperandSize(CF_WIDTH, op2Height, op2EditPart);
+ }
+
+ { // Delete the middle one. It should expand the previous one (3)
+ editor.delete(op4EditPart);
+
+ op3Height += op4Height; // 90 -> 141
+ assertOperandSize(CF_WIDTH, op3Height, op3EditPart);
+ }
+
+ { // Delete the first one
+ editor.delete(op3EditPart);
+
+ op2Height += op3Height; // 81 -> 222
+ assertOperandSize(CF_WIDTH, op2Height, op2EditPart);
+
+ int cfHeight = cfEditPart.getFigure().getBounds().height();
+
+ // Operand2 is the last remaining operand; it should now take all available height
+ Assert.assertEquals(cfHeight - CF_LABEL_HEIGHT, op2Height);
+ }
+ }
+
+ // Don't use editor.createShape(), because we need a special type of request to create operands.
+ // The "InsertAt" behavior will only be computed if we use a CreateUnspecifiedTypeRequest (From the palette)
+ // and target an Operand. The Operand will then be responsible for setting the InsertAt parameter
+ // and delegate to the CombinedFragment compartment for the actual creation
+ private GraphicalEditPart createOperand(GraphicalEditPart targetVisualPart, Point location) {
+ CreateUnspecifiedTypeRequest request = new CreateUnspecifiedTypeRequest(Collections.singletonList(UMLElementTypes.InteractionOperand_Shape), targetVisualPart.getDiagramPreferencesHint());
+
+ request.setLocation(location);
+
+ EditPart target = targetVisualPart.getTargetEditPart(request);
+ assertThat("No target edit part", target, notNullValue());
+ org.eclipse.gef.commands.Command command = target.getCommand(request);
+ editor.execute(command);
+
+ // Find the new edit-part
+ Object result = request.getNewObject();
+ Assert.assertThat(result, instanceOf(Collection.class));
+ Collection<?> results = (Collection<?>) result;
+ return results.stream()
+ .filter(ViewDescriptor.class::isInstance).map(ViewDescriptor.class::cast)
+ .map(desc -> desc.getAdapter(View.class)).map(View.class::cast)
+ .filter(Objects::nonNull)
+ .map(view -> DiagramEditPartsUtil.getEditPartFromView(view, targetVisualPart))
+ .filter(GraphicalEditPart.class::isInstance).map(GraphicalEditPart.class::cast)
+ .filter(Objects::nonNull)
+ .findAny().orElseThrow(() -> new IllegalStateException("Could not find new shape edit-part"));
+ }
+
+ // Convert a point that is relative to the given part to a point relative to the current Viewport (Taking zoom & translate into account).
+ // This can be used to get a "Mouse Location" to configure Requests
+ private static Point at(int x, int y, GraphicalEditPart relativeTo) {
+ Point at = new Point(x, y);
+
+ IFigure figure = relativeTo.getContentPane();
+ Point layoutOrigin = figure.getClientArea().getLocation();
+
+ at.performTranslate(layoutOrigin.x, layoutOrigin.y);
+ figure.translateToParent(at);
+ figure.translateToAbsolute(at);
+
+ return at;
+ }
+
+ private void assertOperandSize(int width, int height, GraphicalEditPart operand) {
+ IFigure operandFigure = operand.getFigure();
+ Dimension operandSize = operandFigure.getBounds().getSize();
+ assertSize(width, height, operandSize);
+ }
+
+ private void assertSize(int width, int height, Dimension actual) {
+ Assert.assertEquals(new Dimension(width, height), actual);
+ }
+
+}

Back to the top