diff --git a/plugins/org.eclipse.sirius.diagram.model/src/org/eclipse/sirius/diagram/model/business/internal/query/DDiagramElementContainerExperimentalQuery.java b/plugins/org.eclipse.sirius.diagram.model/src/org/eclipse/sirius/diagram/model/business/internal/query/DDiagramElementContainerExperimentalQuery.java index c3f426a17a..3009ff3d40 100644 --- a/plugins/org.eclipse.sirius.diagram.model/src/org/eclipse/sirius/diagram/model/business/internal/query/DDiagramElementContainerExperimentalQuery.java +++ b/plugins/org.eclipse.sirius.diagram.model/src/org/eclipse/sirius/diagram/model/business/internal/query/DDiagramElementContainerExperimentalQuery.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013, 2021 THALES GLOBAL SERVICES and others. + * Copyright (c) 2013, 2024 THALES GLOBAL SERVICES and others. * 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 @@ -12,13 +12,14 @@ *******************************************************************************/ package org.eclipse.sirius.diagram.model.business.internal.query; +import java.util.Optional; + import org.eclipse.emf.ecore.EObject; import org.eclipse.sirius.diagram.DDiagramElementContainer; import org.eclipse.sirius.diagram.DNodeContainer; import org.eclipse.sirius.diagram.FlatContainerStyle; import org.eclipse.sirius.diagram.description.style.FlatContainerStyleDescription; import org.eclipse.sirius.ext.base.Option; -import org.eclipse.sirius.ext.base.Options; import org.eclipse.sirius.viewpoint.description.style.LabelBorderStyleDescription; import org.eclipse.sirius.viewpoint.description.style.StyleDescription; @@ -94,14 +95,14 @@ public boolean isRegionInVerticalStack() { * * @return an {@link Option} with the found label border style if it exists. */ - public Option getLabelBorderStyle() { + public Optional getLabelBorderStyle() { if (container.getStyle() instanceof FlatContainerStyle) { StyleDescription description = container.getStyle().getDescription(); if (description instanceof FlatContainerStyleDescription) { FlatContainerStyleDescription fcsd = (FlatContainerStyleDescription) description; - return Options.newSome(fcsd.getLabelBorderStyle()); + return Optional.ofNullable(fcsd.getLabelBorderStyle()); } } - return Options.newNone(); + return Optional.empty(); } } diff --git a/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/query/SequenceNodeQuery.java b/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/query/SequenceNodeQuery.java index 110a6ae356..08733296d6 100644 --- a/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/query/SequenceNodeQuery.java +++ b/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/query/SequenceNodeQuery.java @@ -64,7 +64,7 @@ public Range getVerticalRange() { result = CacheHelper.getViewToRangeCache().get(node); } if (result == null) { - Rectangle absoluteBounds = GMFHelper.getAbsoluteBounds(node); + Rectangle absoluteBounds = GMFHelper.getAbsoluteBounds(node, false, false, false, true); int y = absoluteBounds.y; int height = absoluteBounds.height; // GMFHelper.getAbsoluteBounds() use default diff --git a/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/refresh/FixBendpointsOnCreationCommand.java b/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/refresh/FixBendpointsOnCreationCommand.java index e2f4ae107d..215c11ba6f 100644 --- a/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/refresh/FixBendpointsOnCreationCommand.java +++ b/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/refresh/FixBendpointsOnCreationCommand.java @@ -152,7 +152,7 @@ private void updateEdge(DEdge dEdge) { private void computeEdgeDataWithoutEdgeLayoutData() { Point firstClick = new Point(0, 0); - Rectangle sourceBounds = GMFHelper.getAbsoluteBounds((Node) source); + Rectangle sourceBounds = GMFHelper.getAbsoluteBounds((Node) source, false, false, false, true); if (source.getElement() instanceof AbstractDNode) { AbstractDNode sourceDNode = (AbstractDNode) source.getElement(); if (sourceDNode.eContainer() instanceof AbstractDNode) { @@ -181,7 +181,7 @@ private void computeEdgeDataWithoutEdgeLayoutData() { sourceTerminal = "(" + sourceRelativeLocation.preciseX() + "," + sourceRelativeLocation.preciseY() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ Point secondClick = new Point(0, 0); - Rectangle targetBounds = GMFHelper.getAbsoluteBounds((Node) target); + Rectangle targetBounds = GMFHelper.getAbsoluteBounds((Node) target, false, false, false, true); if (target.getElement() instanceof AbstractDNode) { AbstractDNode targetDNode = (AbstractDNode) target.getElement(); diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/NodeQuery.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/NodeQuery.java index 1713fdd63d..2fd73b0141 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/NodeQuery.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/NodeQuery.java @@ -30,14 +30,7 @@ import org.eclipse.sirius.diagram.business.api.query.DDiagramElementQuery; import org.eclipse.sirius.diagram.business.api.query.DNodeQuery; import org.eclipse.sirius.diagram.ui.edit.internal.part.PortLayoutHelper; -import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNode2EditPart; -import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNode4EditPart; -import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeContainer2EditPart; -import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeContainerEditPart; -import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeList2EditPart; -import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListEditPart; import org.eclipse.sirius.diagram.ui.internal.refresh.GMFHelper; -import org.eclipse.sirius.diagram.ui.part.SiriusVisualIDRegistry; import org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutUtils; import org.eclipse.sirius.ext.base.Option; import org.eclipse.sirius.ext.base.Options; @@ -51,7 +44,7 @@ * * @author lredor */ -public class NodeQuery { +public class NodeQuery extends ViewQuery { private Node node; @@ -62,6 +55,7 @@ public class NodeQuery { * the starting point. */ public NodeQuery(Node node) { + super(node); this.node = node; } @@ -166,33 +160,12 @@ protected Dimension getDefaultDim(DDiagramElement element) { return dim; } - /** - * Tests whether the queried Node corresponds to a bordered node. - * - * @return true if the queried View corresponds to a bordered node. - */ - public boolean isBorderedNode() { - int type = SiriusVisualIDRegistry.getVisualID(this.node.getType()); - boolean result = type == DNode2EditPart.VISUAL_ID || type == DNode4EditPart.VISUAL_ID; - return result; - } - - /** - * Tests whether the queried Node corresponds to a container (list or not). - * - * @return true if the queried View corresponds to a container node. - */ - public boolean isContainer() { - int type = SiriusVisualIDRegistry.getVisualID(this.node.getType()); - boolean result = type == DNodeContainer2EditPart.VISUAL_ID || type == DNodeContainerEditPart.VISUAL_ID || type == DNodeList2EditPart.VISUAL_ID || type == DNodeListEditPart.VISUAL_ID; - return result; - } - /** * Return the compartment of the GMF node container with "free form" layout. * * @return the compartment or Optional.empty if view is not container or compartment not found */ + @Override public Optional getFreeFormContainerCompartment() { if (new ViewQuery(this.node).isFreeFormContainer()) { List children = this.node.getChildren(); @@ -301,7 +274,7 @@ private Option getParentBorder() { * @return The rectangle used for handles */ public Rectangle getHandleBounds() { - return GMFHelper.getAbsoluteBounds(node, true, true); + return GMFHelper.getAbsoluteBounds(node, true, true, false, false); } /** diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/ViewQuery.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/ViewQuery.java index f9d183de61..2725424a6d 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/ViewQuery.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/ViewQuery.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2021 THALES GLOBAL SERVICES and others. + * Copyright (c) 2012, 2024 THALES GLOBAL SERVICES and others. * 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 @@ -32,6 +32,7 @@ import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.gmf.runtime.notation.JumpLinkStatus; import org.eclipse.gmf.runtime.notation.JumpLinkType; +import org.eclipse.gmf.runtime.notation.Node; import org.eclipse.gmf.runtime.notation.NotationPackage; import org.eclipse.gmf.runtime.notation.Shape; import org.eclipse.gmf.runtime.notation.Style; @@ -40,10 +41,12 @@ import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.sirius.diagram.DDiagram; import org.eclipse.sirius.diagram.DDiagramElement; +import org.eclipse.sirius.diagram.DDiagramElementContainer; import org.eclipse.sirius.diagram.LabelPosition; import org.eclipse.sirius.diagram.NodeStyle; import org.eclipse.sirius.diagram.business.api.query.ContainerMappingQuery; import org.eclipse.sirius.diagram.description.ContainerMapping; +import org.eclipse.sirius.diagram.model.business.internal.query.DDiagramElementContainerExperimentalQuery; import org.eclipse.sirius.diagram.tools.api.DiagramPlugin; import org.eclipse.sirius.diagram.tools.api.preferences.SiriusDiagramCorePreferences; import org.eclipse.sirius.diagram.ui.internal.edit.parts.DEdgeBeginNameEditPart; @@ -61,8 +64,11 @@ import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeEditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeList2EditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListEditPart; +import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListElementEditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListName2EditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListNameEditPart; +import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListViewNodeListCompartment2EditPart; +import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListViewNodeListCompartmentEditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.NotationViewIDs; import org.eclipse.sirius.diagram.ui.part.SiriusVisualIDRegistry; import org.eclipse.sirius.diagram.ui.provider.DiagramUIPlugin; @@ -380,6 +386,46 @@ public boolean isFreeFormCompartment() { || type == DNodeContainerViewNodeContainerCompartment2EditPart.VISUAL_ID; } + /** + * Return if this GMF node is associated to DNodeList Sirius diagram element. + */ + public boolean isListContainer() { + int type = SiriusVisualIDRegistry.getVisualID(this.view.getType()); + return type == DNodeListEditPart.VISUAL_ID || type == DNodeList2EditPart.VISUAL_ID; + } + + /** + * Return if this GMF node is compartment of node corresponding to a Sirius list container. + */ + public boolean isListCompartment() { + int type = SiriusVisualIDRegistry.getVisualID(this.view.getType()); + return type == DNodeListViewNodeListCompartmentEditPart.VISUAL_ID // + || type == DNodeListViewNodeListCompartment2EditPart.VISUAL_ID; + } + + /** + * Return if this GMF node is a list item. + */ + public boolean isListItem() { + int type = SiriusVisualIDRegistry.getVisualID(this.view.getType()); + return type == DNodeListElementEditPart.VISUAL_ID; + } + + /** + * Return if this GMF node is a region. + */ + public boolean isRegion() { + return this.view.getElement() instanceof DDiagramElementContainer ddec // + && new DDiagramElementContainerExperimentalQuery(ddec).isRegion(); + } + + /** + * Return if this GMF node is contained in a vertical stack layout container. + */ + public boolean isVerticalRegion() { + return view.eContainer() instanceof View container && new ViewQuery(container).isVerticalRegionContainerCompartment(); + } + /** * Return if this GMF node have vertical/horizontal stack layout. */ @@ -389,6 +435,69 @@ public boolean isRegionContainer() { && new ContainerMappingQuery(mapping).isRegionContainer(); } + /** + * Return if this GMF node have vertical stack layout. + */ + public boolean isVerticalRegionContainer() { + return this.view.getElement() instanceof DDiagramElement element // + && element.getDiagramElementMapping() instanceof ContainerMapping mapping // + && new ContainerMappingQuery(mapping).isVerticalStackContainer(); + } + + /** + * Return if this GMF node is a compartment of a container having vertical stack layout. + */ + public boolean isVerticalRegionContainerCompartment() { + if (isFreeFormCompartment()) { + if (view.eContainer() instanceof Node container) { + return new ViewQuery(container).isVerticalRegionContainer(); + } + + } + return false; + } + + /** + * Return if this GMF node is contained in an horizontal stack layout container. + */ + public boolean isHorizontalRegion() { + return view.eContainer() instanceof View container && new ViewQuery(container).isHorizontalRegionContainerCompartment(); + } + + /** + * Return if this GMF node have horizontal stack layout. + */ + public boolean isHorizontalRegionContainer() { + return this.view.getElement() instanceof DDiagramElement element // + && element.getDiagramElementMapping() instanceof ContainerMapping mapping // + && new ContainerMappingQuery(mapping).isHorizontalStackContainer(); + } + + /** + * Return if this GMF node is a compartment of a container having horizontal stack layout. + */ + public boolean isHorizontalRegionContainerCompartment() { + if (isFreeFormCompartment()) { + if (view.eContainer() instanceof Node container) { + return new ViewQuery(container).isHorizontalRegionContainer(); + } + } + return false; + } + + /** + * Return if this GMF node is a compartment of a container having an horizontal or a vertical stack layout. + */ + public boolean isRegionContainerCompartment() { + if (isFreeFormCompartment()) { + if (view.eContainer() instanceof Node container) { + return new ViewQuery(container).isRegionContainer(); + } + + } + return false; + } + /** * Return if this GMF node is associated to DNode Sirius diagram element. */ @@ -416,7 +525,7 @@ public boolean isNodeLabel() { * * @return the compartment or Optional.empty if view is not container or compartment not found */ - public Optional getFreeFormContainerCompartment() { + public Optional getFreeFormContainerCompartment() { if (this.isFreeFormContainer()) { List children = this.view.getChildren(); return children.stream() // diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/command/TreeLayoutSetConnectionAnchorsCommand.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/command/TreeLayoutSetConnectionAnchorsCommand.java index ad1f1c78c4..2b67d9c9d7 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/command/TreeLayoutSetConnectionAnchorsCommand.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/command/TreeLayoutSetConnectionAnchorsCommand.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2018 THALES GLOBAL SERVICES and others. + * Copyright (c) 2012, 2024 THALES GLOBAL SERVICES and others. * 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 @@ -12,6 +12,8 @@ *******************************************************************************/ package org.eclipse.sirius.diagram.ui.business.internal.command; +import java.util.Optional; + import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; @@ -33,7 +35,6 @@ import org.eclipse.sirius.diagram.ui.internal.refresh.GMFHelper; import org.eclipse.sirius.diagram.ui.provider.Messages; import org.eclipse.sirius.diagram.ui.tools.internal.util.GMFNotationUtilities; -import org.eclipse.sirius.ext.base.Option; /** * Controls the movement of source and target edge anchor. Use to move vertical @@ -92,8 +93,8 @@ protected void setComplementaryData(boolean sourceAnchorChanged, boolean targetA } else { // We are in reconnection (compute the sourceRefPoint using // GMF model data) - Option optionalSourceBounds = GMFHelper.getAbsoluteBounds(edge.getSource()); - if (optionalSourceBounds.some()) { + Optional optionalSourceBounds = GMFHelper.getAbsoluteBounds(edge.getSource()); + if (optionalSourceBounds.isPresent()) { sourceBounds = optionalSourceBounds.get(); } } @@ -117,8 +118,8 @@ protected void setComplementaryData(boolean sourceAnchorChanged, boolean targetA } else { // We are in reconnection (compute the sourceRefPoint using // GMF model data) - Option optionalTargetBounds = GMFHelper.getAbsoluteBounds(edge.getTarget()); - if (optionalTargetBounds.some()) { + Optional optionalTargetBounds = GMFHelper.getAbsoluteBounds(edge.getTarget()); + if (optionalTargetBounds.isPresent()) { targetBounds = optionalTargetBounds.get(); } } diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/migration/DiagramRepresentationsFileMigrationParticipantV670.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/migration/DiagramRepresentationsFileMigrationParticipantV670.java index c725abbeb4..cd2096292b 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/migration/DiagramRepresentationsFileMigrationParticipantV670.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/migration/DiagramRepresentationsFileMigrationParticipantV670.java @@ -174,7 +174,7 @@ private void avoidOverlaps(Diagram diagram) { Location location = (Location) layoutConstraint; constraint = new Rectangle(location.getX(), location.getY(), -1, -1); } - Point parentAbsoluteLocation = GMFHelper.getAbsoluteLocation(parentNode); + Point parentAbsoluteLocation = GMFHelper.getAbsoluteLocation(parentNode, false, false); constraint.translate(parentAbsoluteLocation.x, parentAbsoluteLocation.y); final Point realLocation = borderItemLocator.getValidLocation(constraint, node, otherBorderedNodesToIgnore); final Dimension d = realLocation.getDifference(parentAbsoluteLocation); @@ -215,7 +215,7 @@ private void migrateGraphicalFiltersAndGMFBounds(Diagram diagram) { LayoutConstraint layoutConstraint = node.getLayoutConstraint(); if (layoutConstraint instanceof Bounds) { Bounds bounds = (Bounds) layoutConstraint; - Rectangle rectBounds = GMFHelper.getAbsoluteBounds(node); + Rectangle rectBounds = GMFHelper.getAbsoluteBounds(node, false, false, false, true); // The GMF node size must be stored in collapse // filter (to can set this size // when this node is expanded). @@ -287,6 +287,7 @@ private void migrateChildrenOfCollapsedNode(Diagram diagram) { * */ private static class IsStandardDiagramPredicate implements Predicate { + @Override public boolean apply(Diagram input) { boolean apply = false; if (input.getElement() instanceof DDiagram) { @@ -311,6 +312,7 @@ public boolean apply(Diagram input) { */ private static class IsBorderedNodePredicate implements Predicate { + @Override public boolean apply(Node input) { // Is this node the main view of a DNode and a border // node ? @@ -327,6 +329,7 @@ public boolean apply(Node input) { */ private static class IsDirectlyCollapsedNodePredicate implements Predicate { + @Override public boolean apply(Node input) { boolean apply = false; diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractDiagramContainerEditPart.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractDiagramContainerEditPart.java index be4b71d029..70a717f117 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractDiagramContainerEditPart.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractDiagramContainerEditPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2022 THALES GLOBAL SERVICES and others. + * Copyright (c) 2007, 2024 THALES GLOBAL SERVICES and others. * 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 @@ -13,6 +13,7 @@ package org.eclipse.sirius.diagram.ui.edit.api.part; import java.util.Iterator; +import java.util.Optional; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.draw2d.IFigure; @@ -59,7 +60,6 @@ import org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutUtils; import org.eclipse.sirius.diagram.ui.tools.api.policy.CompoundEditPolicy; import org.eclipse.sirius.diagram.ui.tools.internal.ui.NoCopyDragEditPartsTrackerEx; -import org.eclipse.sirius.ext.base.Option; import org.eclipse.sirius.ext.gmf.runtime.diagram.ui.tools.RubberbandDragTracker; import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.LabelBorderStyleIds; import org.eclipse.sirius.viewpoint.description.style.LabelBorderStyleDescription; @@ -267,8 +267,8 @@ protected IFigure getContentPaneFor(IGraphicalEditPart editPart) { private boolean hasFullLabelBorder() { EObject element = resolveSemanticElement(); if (element instanceof DDiagramElementContainer) { - Option labelBorderStyle = new DDiagramElementContainerExperimentalQuery((DDiagramElementContainer) element).getLabelBorderStyle(); - return labelBorderStyle.some() && LabelBorderStyleIds.LABEL_FULL_BORDER_STYLE_FOR_CONTAINER_ID.equals(labelBorderStyle.get().getId()); + Optional labelBorderStyle = new DDiagramElementContainerExperimentalQuery((DDiagramElementContainer) element).getLabelBorderStyle(); + return labelBorderStyle.isPresent() && LabelBorderStyleIds.LABEL_FULL_BORDER_STYLE_FOR_CONTAINER_ID.equals(labelBorderStyle.get().getId()); } return false; } diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractDiagramElementContainerEditPart.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractDiagramElementContainerEditPart.java index d1e4af8d49..a68660b90e 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractDiagramElementContainerEditPart.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractDiagramElementContainerEditPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2022 THALES GLOBAL SERVICES and others. + * Copyright (c) 2007, 2024 THALES GLOBAL SERVICES and others. * 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 @@ -15,6 +15,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -95,8 +96,6 @@ import org.eclipse.sirius.diagram.ui.tools.internal.layout.LayoutUtil; import org.eclipse.sirius.diagram.ui.tools.internal.util.EditPartQuery; import org.eclipse.sirius.diagram.ui.tools.internal.util.NotificationQuery; -import org.eclipse.sirius.ext.base.Option; -import org.eclipse.sirius.ext.base.Options; import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.AlphaDropShadowBorder; import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.SiriusDefaultSizeNodeFigure; import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.SiriusWrapLabel; @@ -183,7 +182,7 @@ private List getBrotherRegionParts() { EditPart editPart = this; //@formatter:off @SuppressWarnings("unchecked") - List regionParts = (List) getParent().getChildren().stream() + List regionParts = getParent().getChildren().stream() .filter(ed -> ed instanceof AbstractDiagramElementContainerEditPart && !ed.equals(editPart)) .map(AbstractDiagramElementContainerEditPart.class::cast) .collect(Collectors.toList()); @@ -491,6 +490,7 @@ public Dimension getDefaultDimension() { * @return the default figure dimension of this edit part * @deprecated Only here as security if user activates {@link LayoutUtil#isArrangeAtOpeningChangesDisabled()}. */ + @Deprecated public Dimension oldGetDefaultDimension() { DDiagramElement dde = resolveDiagramElement(); Dimension defaultSize = LayoutUtils.NEW_DEFAULT_CONTAINER_DIMENSION; @@ -513,8 +513,8 @@ protected NodeFigure createNodePlate() { NodeFigure result; DDiagramElement dde = resolveDiagramElement(); Dimension defaultSize = getDefaultDimension(); - Option getLabelBorderStyle = getLabelBorderStyle(dde); - if (getLabelBorderStyle.some()) { + Optional getLabelBorderStyle = getLabelBorderStyle(dde); + if (getLabelBorderStyle.isPresent()) { result = new ContainerWithTitleBlockFigure(getMapMode().DPtoLP(defaultSize.width), getMapMode().DPtoLP(defaultSize.height), dde, getLabelBorderStyle.get()); } else { result = new SiriusDefaultSizeNodeFigure(getMapMode().DPtoLP(defaultSize.width), getMapMode().DPtoLP(defaultSize.height)); @@ -523,11 +523,11 @@ protected NodeFigure createNodePlate() { return result; } - private Option getLabelBorderStyle(DStylizable viewNode) { + private Optional getLabelBorderStyle(DStylizable viewNode) { if (viewNode instanceof DDiagramElementContainer) { return new DDiagramElementContainerExperimentalQuery((DDiagramElementContainer) viewNode).getLabelBorderStyle(); } - return Options.newNone(); + return Optional.empty(); } /** diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/commands/StraightenToCommand.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/commands/StraightenToCommand.java index 7aafb1d649..752d212cda 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/commands/StraightenToCommand.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/commands/StraightenToCommand.java @@ -667,7 +667,7 @@ private boolean isOverlapped(Node node, StraightenToCommandData data) { // the move. It should be the same as the one stored in GMF but // sometimes, probably caused by some bugs, it could be wrong in // GMF. - Point parentAbsoluteLocation = GMFHelper.getAbsoluteLocation(parentNode); + Point parentAbsoluteLocation = GMFHelper.getAbsoluteLocation(parentNode, false, true); Rectangle initialAsboluteConstraint = initialRelativeConstraint.getTranslated(parentAbsoluteLocation); Point validInitialAbsoluteLocation = borderItemLocator.getValidLocation(initialAsboluteConstraint, node, new ArrayList(Arrays.asList(node))); Rectangle validInitialAbsoluteConstraint = initialAsboluteConstraint.getCopy(); diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeContainerCompartmentEditPart.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeContainerCompartmentEditPart.java index c3d273020d..5a914b74d2 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeContainerCompartmentEditPart.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeContainerCompartmentEditPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2023 THALES GLOBAL SERVICES and others. + * Copyright (c) 2009, 2024 THALES GLOBAL SERVICES and others. * 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 @@ -221,8 +221,8 @@ public IFigure createFigure() { */ protected void configureBorder(ResizableCompartmentFigure rcf) { boolean shouldHaveBorder = isRegionContainerCompartment(); - Option labelBorderStyle = getLabelBorderStyle(); - if (labelBorderStyle.some()) { + Optional labelBorderStyle = getLabelBorderStyle(); + if (labelBorderStyle.isPresent()) { shouldHaveBorder = shouldHaveBorder || LabelBorderStyleIds.LABEL_FULL_BORDER_STYLE_FOR_CONTAINER_ID.equals(labelBorderStyle.get().getId()); } @@ -266,8 +266,8 @@ protected void configureScrollPaneBorder(ScrollPane scrollPane, ContainerStyle o } boolean fullLabelBorder = false; - Option labelBorderStyle = getLabelBorderStyle(); - if (labelBorderStyle.some()) { + Optional labelBorderStyle = getLabelBorderStyle(); + if (labelBorderStyle.isPresent()) { fullLabelBorder = LabelBorderStyleIds.LABEL_FULL_BORDER_STYLE_FOR_CONTAINER_ID.equals(labelBorderStyle.get().getId()); } @@ -319,12 +319,12 @@ private boolean isCollapsed() { return style == null ? false : style.isCollapsed(); } - private Option getLabelBorderStyle() { + private Optional getLabelBorderStyle() { EObject element = resolveSemanticElement(); if (element instanceof DDiagramElementContainer) { return new DDiagramElementContainerExperimentalQuery((DDiagramElementContainer) element).getLabelBorderStyle(); } - return Options.newNone(); + return Optional.empty(); } @Override diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeListCompartmentEditPart.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeListCompartmentEditPart.java index c99b659f3b..7a47e2420a 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeListCompartmentEditPart.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeListCompartmentEditPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2021 THALES GLOBAL SERVICES and others. + * Copyright (c) 2011, 2024 THALES GLOBAL SERVICES and others. * 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 @@ -68,7 +68,6 @@ import org.eclipse.sirius.diagram.ui.internal.edit.policies.RegionCollapseAwarePropertyHandlerEditPolicy; import org.eclipse.sirius.diagram.ui.internal.operation.ComparisonHelper; import org.eclipse.sirius.diagram.ui.tools.api.requests.RequestConstants; -import org.eclipse.sirius.ext.base.Option; import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.LabelBorderStyleIds; import org.eclipse.sirius.viewpoint.DRepresentationElement; import org.eclipse.sirius.viewpoint.description.RepresentationElementMapping; @@ -214,8 +213,8 @@ private boolean isLabelHidden() { private boolean hasLabelBorderStyle() { EObject element = resolveSemanticElement(); if (element instanceof DDiagramElementContainer) { - Option labelBorderStyle = new DDiagramElementContainerExperimentalQuery((DDiagramElementContainer) element).getLabelBorderStyle(); - return labelBorderStyle.some() && !LabelBorderStyleIds.LABEL_FULL_BORDER_STYLE_FOR_CONTAINER_ID.equals(labelBorderStyle.get().getId()); + Optional labelBorderStyle = new DDiagramElementContainerExperimentalQuery((DDiagramElementContainer) element).getLabelBorderStyle(); + return labelBorderStyle.isPresent() && !LabelBorderStyleIds.LABEL_FULL_BORDER_STYLE_FOR_CONTAINER_ID.equals(labelBorderStyle.get().getId()); } return false; } diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/operation/CenterEdgeEndModelChangeOperation.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/operation/CenterEdgeEndModelChangeOperation.java index f915ee12e1..b84a52d1bd 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/operation/CenterEdgeEndModelChangeOperation.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/operation/CenterEdgeEndModelChangeOperation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, 2020 THALES GLOBAL SERVICES and others. + * Copyright (c) 2014, 2024 THALES GLOBAL SERVICES and others. * 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 @@ -58,8 +58,6 @@ import org.eclipse.sirius.diagram.ui.internal.refresh.GMFHelper; import org.eclipse.sirius.diagram.ui.tools.internal.routers.RectilinearEdgeUtil; import org.eclipse.sirius.diagram.ui.tools.internal.util.GMFNotationUtilities; -import org.eclipse.sirius.ext.base.Option; -import org.eclipse.sirius.ext.base.Options; import org.eclipse.sirius.ext.gmf.runtime.editparts.GraphicalHelper; import org.eclipse.ui.IEditorPart; @@ -207,10 +205,10 @@ private void centerEdgeEnds(CenteringStyle center, Routing routingValue) { // We get the edge source and target nodes absolute bounds to // compute absolute anchors coordinates - Option sourceBounds = getAbsoluteSourceBounds(edgeSourceView); - Option targetBounds = getAbsoluteTargetBounds(edgeTargetView); + Optional sourceBounds = getAbsoluteSourceBounds(edgeSourceView); + Optional targetBounds = getAbsoluteTargetBounds(edgeTargetView); - if (sourceBounds.some() && targetBounds.some()) { + if (sourceBounds.isPresent() && targetBounds.isPresent()) { // Calculate the existing anchors absolute location retrieveAndSetExistingAnchorsAbsoluteLocation(sourceBounds.get(), targetBounds.get()); @@ -249,7 +247,7 @@ private void centerEdgeEnds(CenteringStyle center, Routing routingValue) { * true if it represents the edge source, false otherwise. * @return the absolute bounds. */ - private Option getAbsoluteBounds(View gmfView, boolean isSource) { + private Optional getAbsoluteBounds(View gmfView, boolean isSource) { if (connectionEditPart != null) { EditPart editPart = null; if (isSource) { @@ -258,24 +256,24 @@ private Option getAbsoluteBounds(View gmfView, boolean isSource) { editPart = connectionEditPart.getTarget(); } if (editPart instanceof GraphicalEditPart) { - return Options.newSome(GraphicalHelper.getAbsoluteBoundsIn100Percent((GraphicalEditPart) editPart)); + return Optional.ofNullable(GraphicalHelper.getAbsoluteBoundsIn100Percent((GraphicalEditPart) editPart)); } } return GMFHelper.getAbsoluteBounds(gmfView, true, true); } - private Option getAbsoluteSourceBounds(View edgeSourceView) { - Option option = getAbsoluteBounds(edgeSourceView, true); - if (sourceFigureSize != null && option.some()) { + private Optional getAbsoluteSourceBounds(View edgeSourceView) { + Optional option = getAbsoluteBounds(edgeSourceView, true); + if (sourceFigureSize != null && option.isPresent()) { Rectangle rectangle = option.get(); rectangle.setSize(sourceFigureSize); } return option; } - private Option getAbsoluteTargetBounds(View edgeTargetView) { - Option option = getAbsoluteBounds(edgeTargetView, false); - if (targetFigureSize != null && option.some()) { + private Optional getAbsoluteTargetBounds(View edgeTargetView) { + Optional option = getAbsoluteBounds(edgeTargetView, false); + if (targetFigureSize != null && option.isPresent()) { Rectangle rectangle = option.get(); rectangle.setSize(targetFigureSize); } @@ -517,7 +515,7 @@ private void setConnectionIfNull() { if (connection != null || !useFigure) { return; } - Option option = Options.newNone(); + Optional option = Optional.empty(); final IEditorPart editorPart = EclipseUIUtil.getActiveEditor(); if (editorPart instanceof DiagramEditor) { option = GMFHelper.getGraphicalEditPart(edge, (DiagramEditor) editorPart); @@ -533,14 +531,14 @@ private void setConnectionIfNull() { if (object instanceof DiagramEditor) { option = GMFHelper.getGraphicalEditPart(edge, (DiagramEditor) object); } - if (option.some()) { + if (option.isPresent()) { break; } } } - if (option.some()) { + if (option.isPresent()) { GraphicalEditPart editPart = option.get(); if (editPart instanceof DEdgeEditPart) { connectionEditPart = (DEdgeEditPart) editPart; diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/AbstractCanonicalSynchronizer.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/AbstractCanonicalSynchronizer.java index 304daa7c5e..ab2f913243 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/AbstractCanonicalSynchronizer.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/AbstractCanonicalSynchronizer.java @@ -22,6 +22,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.eclipse.core.runtime.IAdaptable; @@ -576,8 +577,8 @@ private LayoutDataResult updateAbstractDNode_ownedBorderedNodes_Bounds(View crea if (size == null) { if (new ViewQuery(createdView).isForNameEditPart()) { - Option optionalRect = GMFHelper.getAbsoluteBounds(createdView); - if (optionalRect.some()) { + Optional optionalRect = GMFHelper.getAbsoluteBounds(createdView); + if (optionalRect.isPresent()) { size = optionalRect.get().getSize(); } } @@ -607,7 +608,7 @@ private LayoutDataResult updateAbstractDNode_ownedBorderedNodes_Bounds(View crea locator.setConstraint(constraint); dummyFigure.setVisible(true); final Rectangle rect = new Rectangle(constraint); - Point parentAbsoluteLocation = GMFHelper.getAbsoluteLocation(parentNode, true); + Point parentAbsoluteLocation = GMFHelper.getAbsoluteLocation(parentNode, true, false); rect.translate(parentAbsoluteLocation.x, parentAbsoluteLocation.y); dummyFigure.setBounds(rect); final Point realLocation = locator.getValidLocation(rect, createdNode, new ArrayList(Arrays.asList(createdNode))); @@ -666,7 +667,7 @@ private LayoutDataResult updateAbstractDNode_ownedBorderedNodes_Bounds(View crea // CanonicalDBorderItemLocator works with absolute GMF parent // location so we need to translate BorderedNode absolute location. - final org.eclipse.draw2d.geometry.Point parentAbsoluteLocation = GMFHelper.getAbsoluteBounds(parentNode).getTopLeft(); + final org.eclipse.draw2d.geometry.Point parentAbsoluteLocation = GMFHelper.getAbsoluteBounds(parentNode, false, false, false, false).getTopLeft(); final Point realLocation = locator.getValidLocation(new Rectangle(location.getTranslated(parentAbsoluteLocation), size), createdNode, Collections.singleton(createdNode)); // Compute the new relative position to the parent diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/GMFHelper.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/GMFHelper.java index 7287d9d61b..46c9031a2e 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/GMFHelper.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/GMFHelper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2023 THALES GLOBAL SERVICES and others. + * Copyright (c) 2011, 2024 THALES GLOBAL SERVICES and others. * 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 @@ -16,9 +16,12 @@ import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import java.util.Map; +import java.util.Optional; import java.util.stream.Stream; import org.eclipse.core.runtime.Path; @@ -27,6 +30,7 @@ import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PrecisionRectangle; import org.eclipse.draw2d.geometry.Rectangle; @@ -38,17 +42,20 @@ import org.eclipse.gef.ConnectionEditPart; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gmf.runtime.diagram.ui.figures.ResizableCompartmentFigure; import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor; import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure; import org.eclipse.gmf.runtime.notation.Bounds; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.gmf.runtime.notation.Edge; +import org.eclipse.gmf.runtime.notation.FontStyle; import org.eclipse.gmf.runtime.notation.LayoutConstraint; import org.eclipse.gmf.runtime.notation.Location; import org.eclipse.gmf.runtime.notation.Node; import org.eclipse.gmf.runtime.notation.NotationPackage; import org.eclipse.gmf.runtime.notation.RelativeBendpoints; import org.eclipse.gmf.runtime.notation.Size; +import org.eclipse.gmf.runtime.notation.Style; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint; import org.eclipse.jface.resource.ImageDescriptor; @@ -72,6 +79,7 @@ import org.eclipse.sirius.diagram.ui.business.internal.query.DNodeContainerQuery; import org.eclipse.sirius.diagram.ui.business.internal.query.DNodeQuery; import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramElementContainerEditPart; +import org.eclipse.sirius.diagram.ui.edit.api.part.IDiagramNameEditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.AbstractDNodeContainerCompartmentEditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeContainer2EditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeList2EditPart; @@ -82,8 +90,6 @@ import org.eclipse.sirius.diagram.ui.provider.Messages; import org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutUtils; import org.eclipse.sirius.diagram.ui.tools.api.util.GMFNotationHelper; -import org.eclipse.sirius.ext.base.Option; -import org.eclipse.sirius.ext.base.Options; import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.AlphaDropShadowBorder; import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.IContainerLabelOffsets; import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.LabelBorderStyleIds; @@ -99,9 +105,6 @@ import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IEditorPart; -import com.google.common.collect.Iterables; -import com.google.common.collect.Iterators; - /** * GMF Helper. * @@ -111,9 +114,14 @@ public final class GMFHelper { /** * see org.eclipse.sirius.diagram.ui.internal.edit.parts. AbstractDNodeContainerCompartmentEditPart.DEFAULT_MARGIN - * the Y value is the DEFAULT_MARGIN + the InvisibleResizableCompartmentFigure top Inset (1px) + * the top value is the DEFAULT_MARGIN + the InvisibleResizableCompartmentFigure top Inset (1px) */ - private static Point CONTAINER_INSETS = new Point(AbstractDNodeContainerCompartmentEditPart.DEFAULT_MARGIN, IContainerLabelOffsets.LABEL_OFFSET); + private static final Insets FREEFORM_CONTAINER_INSETS = new Insets(IContainerLabelOffsets.LABEL_OFFSET, AbstractDNodeContainerCompartmentEditPart.DEFAULT_MARGIN, + AbstractDNodeContainerCompartmentEditPart.DEFAULT_MARGIN, AbstractDNodeContainerCompartmentEditPart.DEFAULT_MARGIN); + + private static final Insets LIST_CONTAINER_INSETS = new Insets(4, 0, 0, 0); + + private static final Insets HV_STACK_CONTAINER_INSETS = new Insets(4, 0, 0, 0); /** * The gap in pixels between the Label's icon and its text @@ -121,6 +129,8 @@ public final class GMFHelper { */ private static final int ICON_TEXT_GAP = 3; + private static Map boundsCache = new HashMap<>(); + private GMFHelper() { // Helper to not instantiate } @@ -130,40 +140,185 @@ private GMFHelper() { * * @param node * the GMF Node + * @param insetsAware + * true to consider the draw2D figures insets. Warning: Those insets are based on the + * current Sirius editParts and could become wrong if a developer customizes them. + * @param adaptBorderNodeLocation + * Useful for specific border nodes, like in sequence diagrams, to center the border nodes if the + * coordinate is 0 (x for EAST or WEST side, y for NORTH or SOUTH side) * * @return the absolute location of the node relative to the origin (Diagram) */ - public static Point getAbsoluteLocation(Node node) { - return getAbsoluteLocation(node, false); + public static Point getAbsoluteLocation(Node node, boolean insetsAware, boolean adaptBorderNodeLocation) { + // TODO: Location of title "DNode*NameEditPart", x coordinate, can be wrong according to label alignment. This + // problem is not yet handled. + + Point location = new Point(0, 0); + LayoutConstraint layoutConstraint = node.getLayoutConstraint(); + if (layoutConstraint instanceof Bounds gmfBounds && !(new ViewQuery(node).isRegion())) { + // The bounds is computed for horizontal or vertical regions, even if it is stored in GMF data + location.setX(gmfBounds.getX()); + location.setY(gmfBounds.getY()); + } + ViewQuery viewQuery = new ViewQuery(node); + if (adaptBorderNodeLocation && viewQuery.isBorderedNode() && layoutConstraint instanceof Bounds gmfBounds) { + // manage location of bordered node with closest side + if (node.getElement() instanceof DNode dNode && node.getElement().eContainer() instanceof AbstractDNode) { + AbstractDNode parentAbstractDNode = (AbstractDNode) dNode.eContainer(); + if (parentAbstractDNode.getOwnedBorderedNodes().contains(dNode)) { + Node parentNode = (Node) node.eContainer(); + LayoutConstraint parentLayoutConstraint = parentNode.getLayoutConstraint(); + if (parentLayoutConstraint instanceof Bounds parentBounds) { + int position = CanonicalDBorderItemLocator.findClosestSideOfParent(new Rectangle(gmfBounds.getX(), gmfBounds.getY(), gmfBounds.getWidth(), gmfBounds.getHeight()), + new Rectangle(parentBounds.getX(), parentBounds.getY(), parentBounds.getWidth(), parentBounds.getHeight())); + centerLocationIfZero(location, position, parentBounds, gmfBounds); + } + } + } + } + if (viewQuery.isListCompartment()) { + // Translate the compartment to be just below the the title, the x coordinate is also the same (same parent + // insets) + Rectangle titleBounds = getAbsoluteBounds(getPreviousChild(node), true, false, false, false); + location.translate(titleBounds.preciseX(), titleBounds.preciseY() + titleBounds.preciseHeight()); + // Translate from the spacing (5 pixels) + location.translate(0, IContainerLabelOffsets.LABEL_OFFSET); + } else if (viewQuery.isListItem()) { + if (node.eContainer() instanceof Node container) { + if (container.getChildren().get(0) == node) { + Point parentNodeLocation = getAbsoluteLocation(container, insetsAware, false); + location.translate(parentNodeLocation); + if (insetsAware) { + translateWithInsets(location, node); + } + } else { + // Translate from the previous children + Rectangle previousChildBounds = getAbsoluteBounds(getPreviousChild(node), true, false, false, false); + location.translate(previousChildBounds.preciseX(), previousChildBounds.preciseY() + previousChildBounds.preciseHeight()); + } + } + } else if (viewQuery.isRegionContainerCompartment()) { + // Translate the compartment to be just below the the title, the x coordinate is also the same (same parent + // insets) + Rectangle titleBounds = getAbsoluteBounds(getPreviousChild(node), true, false, false, false); + location.translate(titleBounds.preciseX(), titleBounds.preciseY() + titleBounds.preciseHeight()); + // Translate from the spacing (5 pixels) + location.translate(0, IContainerLabelOffsets.LABEL_OFFSET); + } else if (viewQuery.isVerticalRegion()) { + if (node.eContainer() instanceof Node container) { + if (container.getChildren().get(0) == node) { + Point parentNodeLocation = getAbsoluteLocation(container, insetsAware, false); + location.translate(parentNodeLocation); + if (insetsAware) { + translateWithInsets(location, node); + } + } else { + // Translate from the previous children + Rectangle previousChildBounds = getAbsoluteBounds(getPreviousChild(node), true, false, false, false); + location.translate(previousChildBounds.preciseX(), previousChildBounds.preciseY() + previousChildBounds.preciseHeight()); + } + } + } else if (viewQuery.isHorizontalRegion()) { + if (node.eContainer() instanceof Node container) { + if (container.getChildren().get(0) == node) { + Point parentNodeLocation = getAbsoluteLocation(container, insetsAware, false); + location.translate(parentNodeLocation); + if (insetsAware) { + translateWithInsets(location, node); + } + } else { + // Translate from the previous children + Rectangle previousChildBounds = getAbsoluteBounds(getPreviousChild(node), true, false, false, false); + location.translate(previousChildBounds.preciseX() + previousChildBounds.preciseWidth(), previousChildBounds.preciseY()); + } + } + } else if (node.eContainer() instanceof Node container) { + Point parentNodeLocation = getAbsoluteLocation(container, insetsAware, true); + location.translate(parentNodeLocation); + if (insetsAware) { + translateWithInsets(location, node); + } + } + return location; + } + + private static Node getPreviousChild(Node searchedNode) { + Node previousChild = null; + boolean found = false; + if (searchedNode.eContainer() instanceof Node container) { + for (Iterator children = container.getChildren().iterator(); children.hasNext() && !found; /* */) { + View child = children.next(); + if (child instanceof Node nodeChild) { + if (searchedNode == nodeChild) { + found = true; + } else { + previousChild = nodeChild; + } + } + } + } + if (found) { + return previousChild; + } else { + return null; + } } /** - * Get the absolute location relative to the origin (Diagram). - * - * @param node - * the GMF Node - * @param insetsAware - * true to consider the draw2D figures insets. Warning: Those insets are based on the - * current Sirius editParts and could become wrong if a developer customizes them. + * Return the top-left insets of this container. The insets also considers its border. * - * @return the absolute location of the node relative to the origin (Diagram) + * @param container + * The container for which we wish to have the insets. This {@link Node} must correspond to a container, + * otherwise, {0,0} is returned + * @return the top-left insets of this container */ - public static Point getAbsoluteLocation(Node node, boolean insetsAware) { - Node currentNode = node; - Point absoluteNodeLocation = getLocation(currentNode); - if (currentNode.eContainer() instanceof Node) { - currentNode = (Node) currentNode.eContainer(); - Point parentNodeLocation = getAbsoluteLocation(currentNode, insetsAware); - absoluteNodeLocation.translate(parentNodeLocation); - if (insetsAware) { - translateWithInsets(absoluteNodeLocation, node); + public static Dimension getTopLeftInsets(Node container) { + Dimension result = new Dimension(0, 0); + NodeQuery nodeQuery = new NodeQuery(container); + if (nodeQuery.isContainer()) { + EObject element = container.getElement(); + if (element instanceof DDiagramElementContainer ddec) { + // RegionContainer do not have containers insets + if (ddec instanceof DNodeContainer dNodeContainer) { + if (new DNodeContainerExperimentalQuery(dNodeContainer).isRegionContainer()) { + result.setHeight(HV_STACK_CONTAINER_INSETS.top); + } else if (hasFullLabelBorder(ddec)) { + result.setHeight(FREEFORM_CONTAINER_INSETS.top); + } else if (new DDiagramElementContainerExperimentalQuery(ddec).isRegion()) { + // No margin + } else { + result.setWidth(FREEFORM_CONTAINER_INSETS.left); + result.setHeight(FREEFORM_CONTAINER_INSETS.top); + } + } else if (element instanceof DNodeList) { + result.setWidth(LIST_CONTAINER_INSETS.left); + result.setHeight(LIST_CONTAINER_INSETS.top); + } + if (!new DDiagramElementContainerExperimentalQuery(ddec).isRegion()) { + Dimension borderSize = getBorderSize(ddec); + result.setWidth(result.width() + borderSize.width()); + result.setHeight(result.height() + borderSize.height()); + } } + } else if (nodeQuery.isListCompartment()) { + // Add the corresponding margin of {1, 4, 0, 4} of + // org.eclipse.sirius.diagram.ui.internal.edit.parts.AbstractDNodeListCompartmentEditPart.createFigure() + result.setWidth(4); + result.setHeight(1); + } else if (nodeQuery.isRegionContainerCompartment()) { + // Add the corresponding OneLineMarginBorder of {1, 0, 0, 0} corresponding to + // org.eclipse.sirius.diagram.ui.edit.internal.part.DiagramContainerEditPartOperation.refreshBorder(AbstractDiagramElementContainerEditPart, + // ViewNodeContainerFigureDesc, ContainerStyle) + // TODO : 1 should be replace by borderSize (style.getBorderSize().intValue()) + result.setWidth(0); + result.setHeight(1); } - return absoluteNodeLocation; + return result; } /** - * Return the top-left insets of the container of this node. The insets also considers its border. + * Return the top-left insets of the container of this node. The insets also considers its border (the + * size of the border). * * @param node * The current node @@ -175,29 +330,72 @@ public static Point getAbsoluteLocation(Node node, boolean insetsAware) { public static Dimension getContainerTopLeftInsets(Node node, boolean searchFirstParentContainer) { Dimension result = new Dimension(0, 0); EObject nodeContainer = node.eContainer(); - if (nodeContainer instanceof Node) { - Node parentNode = (Node) nodeContainer; + if (nodeContainer instanceof Node parentNode) { NodeQuery nodeQuery = new NodeQuery(parentNode); - if (nodeQuery.isContainer()) { - EObject element = parentNode.getElement(); - if (element instanceof DDiagramElementContainer) { - DDiagramElementContainer ddec = (DDiagramElementContainer) element; - // RegionContainer do not have containers insets - if (ddec instanceof DNodeContainer) { - if (new DNodeContainerExperimentalQuery((DNodeContainer) ddec).isRegionContainer() || hasFullLabelBorder(ddec)) { - result.setHeight(CONTAINER_INSETS.y + getLabelSize(parentNode) + AbstractDiagramElementContainerEditPart.DEFAULT_SPACING); + if (nodeQuery.isContainer() || nodeQuery.isListCompartment() || nodeQuery.isRegionContainerCompartment()) { + result = getTopLeftInsets(parentNode); + } else if (searchFirstParentContainer) { + result = getContainerTopLeftInsets(parentNode, searchFirstParentContainer); + } + } + return result; + } + + /** + * Return the bottom-right insets of the container of this node. The insets also considers its border. + * + * @param container + * The container for which we wish to have the insets. This {@link Node} must correspond to a container, + * otherwise, {0,0} is returned + * @return the bottom-right insets of this container + */ + private static Dimension getBottomRightInsets(Node container) { + Dimension result = new Dimension(0, 0); + NodeQuery nodeQuery = new NodeQuery(container); + if (nodeQuery.isContainer()) { + EObject element = container.getElement(); + if (element instanceof DDiagramElementContainer ddec) { + // RegionContainer do not have containers insets + if (ddec instanceof DNodeContainer dNodeContainer) { + if (new DNodeContainerExperimentalQuery(dNodeContainer).isRegionContainer()) { + result.setWidth(LIST_CONTAINER_INSETS.right); + result.setHeight(LIST_CONTAINER_INSETS.bottom); + // TODO: to verify + Dimension borderSize = getBorderSize(ddec); + result.setWidth(result.width() + borderSize.width()); + result.setHeight(result.height() + borderSize.height()); + } else if (new DDiagramElementContainerExperimentalQuery(ddec).isRegion()) { + // No margin, except the border size + Dimension borderSize = getBorderSize(ddec); + result.setWidth(result.width() + borderSize.width()); + result.setHeight(result.height() + borderSize.height()); + } else { + if (hasFullLabelBorder(ddec)) { + // TODO : Not sure about that, to verify + result.setHeight(FREEFORM_CONTAINER_INSETS.bottom); } else { - result.setWidth(CONTAINER_INSETS.x); - result.setHeight(CONTAINER_INSETS.y); + result.setWidth(FREEFORM_CONTAINER_INSETS.right); + result.setHeight(FREEFORM_CONTAINER_INSETS.bottom); } + Dimension borderSize = getBorderSize(ddec); + // Added twice as this insets is used to compute the "global" size including the border + result.setWidth(result.width() + (borderSize.width() * 2)); + result.setHeight(result.height() + (borderSize.height() * 2)); } + } else if (ddec instanceof DNodeList) { + result.setWidth(LIST_CONTAINER_INSETS.right); + result.setHeight(LIST_CONTAINER_INSETS.bottom); + // TODO: to verify Dimension borderSize = getBorderSize(ddec); result.setWidth(result.width() + borderSize.width()); result.setHeight(result.height() + borderSize.height()); } - } else if (searchFirstParentContainer) { - result = getContainerTopLeftInsets(parentNode, searchFirstParentContainer); } + } else if (nodeQuery.isListCompartment()) { + // Add the corresponding margin of {1, 4, 0, 4} of + // org.eclipse.sirius.diagram.ui.internal.edit.parts.AbstractDNodeListCompartmentEditPart.createFigure() + result.setWidth(4); + result.setHeight(0); } return result; } @@ -216,16 +414,15 @@ public static Dimension getContainerTopLeftInsets(Node node, boolean searchFirst public static Dimension getContainerTopLeftInsetsAfterLabel(Node node, boolean searchFirstParentContainer) { Dimension result = new Dimension(0, 0); EObject nodeContainer = node.eContainer(); - if (nodeContainer instanceof Node) { - Node parentNode = (Node) nodeContainer; + if (nodeContainer instanceof Node parentNode) { NodeQuery nodeQuery = new NodeQuery(parentNode); if (nodeQuery.isContainer()) { EObject element = parentNode.getElement(); - if (element instanceof DDiagramElementContainer) { - result.setWidth(CONTAINER_INSETS.x); - result.setHeight(CONTAINER_INSETS.y); + if (element instanceof DDiagramElementContainer dDiagramElementContainer) { + result.setWidth(FREEFORM_CONTAINER_INSETS.left); + result.setHeight(FREEFORM_CONTAINER_INSETS.top); - Dimension borderSize = getBorderSize((DDiagramElementContainer) element); + Dimension borderSize = getBorderSize(dDiagramElementContainer); result.setWidth(result.width() + borderSize.width()); result.setHeight(result.height() + borderSize.height()); } @@ -255,7 +452,7 @@ public static Dimension getBorderSize(DDiagramElementContainer ddec) { result.setWidth(isFirstRegion(ddec) ? 0 : borderSize); result.setHeight(1); } else if (regionQuery.isRegionInVerticalStack()) { - result.setWidth(1); + result.setWidth(0); result.setHeight(isFirstRegion(ddec) ? 1 : borderSize); } else { result.setWidth(borderSize); @@ -274,39 +471,26 @@ public static Dimension getBorderSize(DDiagramElementContainer ddec) { */ private static void translateWithInsets(Point locationToTranslate, Node currentNode) { NodeQuery nodeQuery = new NodeQuery(currentNode); - // bordered node are not concerned by those insets. + // Border nodes are not concerned by those insets. if (!nodeQuery.isBorderedNode()) { locationToTranslate.translate(getContainerTopLeftInsets(currentNode, false)); + if (currentNode.eContainer() instanceof Node container && new ViewQuery(currentNode).isListItem() && container.getChildren().get(0) == currentNode) { + // This is the first list item, add a one margin border over it. + locationToTranslate.translate(0, 1); + } } } private static boolean hasFullLabelBorder(DDiagramElementContainer ddec) { - Option labelBorderStyle = new DDiagramElementContainerExperimentalQuery(ddec).getLabelBorderStyle(); - return labelBorderStyle.some() && LabelBorderStyleIds.LABEL_FULL_BORDER_STYLE_FOR_CONTAINER_ID.equals(labelBorderStyle.get().getId()); - } - - private static int getLabelSize(Node parentNode) { - int labelSize = 0; - for (Node child : Iterables.filter(parentNode.getVisibleChildren(), Node.class)) { - if (new ViewQuery(child).isForNameEditPart()) { - // TODO Compute the real label height - // It depends on the font size - // It might require to set the layout constraint of the label - // GMF node which will not be used by the - // ConstrainedToolbarLayout to locate the label but might be - // usefull to store the value in the model. - labelSize = 16; - break; - } - } - return labelSize; + Optional labelBorderStyle = new DDiagramElementContainerExperimentalQuery(ddec).getLabelBorderStyle(); + return labelBorderStyle.isPresent() && LabelBorderStyleIds.LABEL_FULL_BORDER_STYLE_FOR_CONTAINER_ID.equals(labelBorderStyle.get().getId()); } private static boolean isFirstRegion(DDiagramElementContainer ddec) { EObject potentialRegionContainer = ddec.eContainer(); - if (potentialRegionContainer instanceof DNodeContainer) { - Iterable regions = Iterables.filter(((DNodeContainer) potentialRegionContainer).getOwnedDiagramElements(), DDiagramElementContainer.class); - return !Iterables.isEmpty(regions) && ddec == Iterables.getFirst(regions, null); + if (potentialRegionContainer instanceof DNodeContainer dNodeContainer) { + Optional optionalDDiagramElement = dNodeContainer.getOwnedDiagramElements().stream().filter(DDiagramElementContainer.class::isInstance).findFirst(); + return optionalDDiagramElement.isPresent() && ddec == optionalDDiagramElement.get(); } return false; } @@ -331,43 +515,21 @@ private static void translateWithInsets(Rectangle boundsToTranslate, Node curren * @param node * the node whose location to compute. * @return the location of the node. + * @deprecated Use getAbsoluteLocation instead. This method will be removed in future. */ + @Deprecated public static Point getLocation(Node node) { - Point location = new Point(0, 0); - LayoutConstraint layoutConstraint = node.getLayoutConstraint(); - if (layoutConstraint instanceof Bounds) { - Bounds gmfBounds = (Bounds) layoutConstraint; - location.setX(gmfBounds.getX()); - location.setY(gmfBounds.getY()); - // manage location of bordered node with closest side - if (node.getElement() instanceof DNode && node.getElement().eContainer() instanceof AbstractDNode) { - DNode dNode = (DNode) node.getElement(); - AbstractDNode parentAbstractDNode = (AbstractDNode) dNode.eContainer(); - if (parentAbstractDNode.getOwnedBorderedNodes().contains(dNode)) { - Node parentNode = (Node) node.eContainer(); - LayoutConstraint parentLayoutConstraint = parentNode.getLayoutConstraint(); - if (parentLayoutConstraint instanceof Bounds) { - Bounds parentBounds = (Bounds) parentLayoutConstraint; - int position = CanonicalDBorderItemLocator.findClosestSideOfParent(new Rectangle(gmfBounds.getX(), gmfBounds.getY(), gmfBounds.getWidth(), gmfBounds.getHeight()), - new Rectangle(parentBounds.getX(), parentBounds.getY(), parentBounds.getWidth(), parentBounds.getHeight())); - updateLocation(location, position, parentBounds, gmfBounds); - } - } - } - } - return location; + return getAbsoluteLocation(node, true, true); } - private static void updateLocation(Point location, int position, Bounds parentBounds, Bounds gmfBounds) { + private static void centerLocationIfZero(Point location, int position, Bounds parentBounds, Bounds gmfBounds) { switch (position) { - case PositionConstants.NORTH: - case PositionConstants.SOUTH: + case PositionConstants.NORTH, PositionConstants.SOUTH: if (location.x == 0) { location.setX(location.x + (parentBounds.getWidth() - gmfBounds.getWidth()) / 2); } break; - case PositionConstants.WEST: - case PositionConstants.EAST: + case PositionConstants.WEST, PositionConstants.EAST: if (location.y == 0) { location.setY(location.y + (parentBounds.getHeight() - gmfBounds.getHeight()) / 2); } @@ -377,33 +539,6 @@ private static void updateLocation(Point location, int position, Bounds parentBo } } - /** - * Get the absolute bounds relative to the origin (Diagram). - * - * @param node - * the GMF Node - * - * @return the absolute bounds of the node relative to the origin (Diagram) - */ - public static Rectangle getAbsoluteBounds(Node node) { - return getAbsoluteBounds(node, false, false); - } - - /** - * Get the absolute bounds relative to the origin (Diagram). - * - * @param node - * the GMF Node - * @param insetsAware - * true to consider the draw2D figures insets. Warning: Those insets are based on the - * current Sirius editParts and could become wrong if a developer customizes them. - * - * @return the absolute bounds of the node relative to the origin (Diagram) - */ - public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware) { - return getAbsoluteBounds(node, insetsAware, false); - } - /** * Get the absolute bounds relative to the origin (Diagram). * @@ -415,20 +550,30 @@ public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware) { * @param boxForConnection * true if we want to have the bounds used to compute connection anchor from source or target, false * otherwise + * @param recursiveGetBounds + * true if this method is called from a parent "getBounds" call, false otherwise. + * @param adaptBorderNodeLocation + * Useful for specific border nodes, like in sequence diagrams, to center the border nodes if the + * coordinate is 0 (x for EAST or WEST side, y for NORTH or SOUTH side) + * * @return the absolute bounds of the node relative to the origin (Diagram) */ - public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware, boolean boxForConnection) { - Node currentNode = node; - Rectangle absoluteNodeBounds = getBounds(currentNode, false, false, boxForConnection); - if (currentNode.eContainer() instanceof Node) { - currentNode = (Node) currentNode.eContainer(); - Point parentNodeLocation = getAbsoluteLocation(currentNode, insetsAware); - absoluteNodeBounds = absoluteNodeBounds.getTranslated(parentNodeLocation); - if (insetsAware) { - translateWithInsets(absoluteNodeBounds, node); + public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware, boolean boxForConnection, boolean recursiveGetBounds, boolean adaptBorderNodeLocation) { + if (!recursiveGetBounds) { + boundsCache.clear(); + } + Rectangle result; + if (boundsCache.containsKey(node)) { + result = boundsCache.get(node); + } else { + Point location = getAbsoluteLocation(node, insetsAware, adaptBorderNodeLocation); + Rectangle bounds = getBounds(node, false, false, boxForConnection, recursiveGetBounds, location); + result = new PrecisionRectangle(location.preciseX(), location.preciseY(), bounds.preciseWidth(), bounds.preciseHeight()); + if (recursiveGetBounds) { + boundsCache.put(node, result); } } - return absoluteNodeBounds; + return result.getCopy(); } /** @@ -439,7 +584,7 @@ public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware, boolea * * @return the absolute bounds of the edge relative to the origin (Diagram) */ - public static Option getAbsoluteBounds(Edge edge) { + public static Optional getAbsoluteBounds(Edge edge) { return getAbsoluteBounds(edge, false, false); } @@ -457,14 +602,14 @@ public static Option getAbsoluteBounds(Edge edge) { * * @return the absolute bounds of the edge relative to the origin (Diagram) */ - public static Option getAbsoluteBounds(Edge edge, boolean insetsAware, boolean boxForConnection) { + public static Optional getAbsoluteBounds(Edge edge, boolean insetsAware, boolean boxForConnection) { // Workaround for canonical refresh about edge on edge - Option optionalSourceBounds = getAbsoluteBounds(edge.getSource(), insetsAware, boxForConnection); - Option optionalTargetBounds = getAbsoluteBounds(edge.getTarget(), insetsAware, boxForConnection); - if (optionalSourceBounds.some() && optionalTargetBounds.some()) { - return Options.newSome(optionalSourceBounds.get().union(optionalTargetBounds.get())); + Optional optionalSourceBounds = getAbsoluteBounds(edge.getSource(), insetsAware, boxForConnection); + Optional optionalTargetBounds = getAbsoluteBounds(edge.getTarget(), insetsAware, boxForConnection); + if (optionalSourceBounds.isPresent() && optionalTargetBounds.isPresent()) { + return Optional.ofNullable(optionalSourceBounds.get().union(optionalTargetBounds.get())); } - return Options.newNone(); + return Optional.empty(); } /** @@ -475,7 +620,7 @@ public static Option getAbsoluteBounds(Edge edge, boolean insetsAware * * @return an optional absolute bounds of the node or edge relative to the origin (Diagram) */ - public static Option getAbsoluteBounds(View view) { + public static Optional getAbsoluteBounds(View view) { return getAbsoluteBounds(view, false); } @@ -490,7 +635,7 @@ public static Option getAbsoluteBounds(View view) { * * @return an optional absolute bounds of the node or edge relative to the origin (Diagram) */ - public static Option getAbsoluteBounds(View view, boolean insetsAware) { + public static Optional getAbsoluteBounds(View view, boolean insetsAware) { return getAbsoluteBounds(view, insetsAware, false); } @@ -508,10 +653,10 @@ public static Option getAbsoluteBounds(View view, boolean insetsAware * * @return an optional absolute bounds of the node or edge relative to the origin (Diagram) */ - public static Option getAbsoluteBounds(View view, boolean insetsAware, boolean boxForConnection) { - Option result = Options.newNone(); + public static Optional getAbsoluteBounds(View view, boolean insetsAware, boolean boxForConnection) { + Optional result = Optional.empty(); if (view instanceof Node) { - result = Options.newSome(getAbsoluteBounds((Node) view, insetsAware, boxForConnection)); + result = Optional.ofNullable(getAbsoluteBounds((Node) view, insetsAware, boxForConnection, false, true)); } else if (view instanceof Edge) { result = getAbsoluteBounds((Edge) view, insetsAware, boxForConnection); } @@ -555,7 +700,7 @@ public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstra * @return the bounds of the node. */ public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstraint, boolean forceFigureAutoSize) { - return getBounds(node, useFigureForAutoSizeConstraint, forceFigureAutoSize, false); + return getBounds(node, useFigureForAutoSizeConstraint, forceFigureAutoSize, false, false, new Point()); } /** @@ -571,27 +716,28 @@ public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstra * @param boxForConnection * true if we want to have the bounds used to compute connection anchor from source or target, false * otherwise + * @param recursiveGetBounds + * true if this method is called from a parent "getBounds" call, false otherwise + * @param computedAbsoluteLocation + * The absolute location of the node + * * @return the bounds of the node. */ - public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstraint, boolean forceFigureAutoSize, boolean boxForConnection) { - PrecisionRectangle bounds = new PrecisionRectangle(0, 0, 0, 0); + public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstraint, boolean forceFigureAutoSize, boolean boxForConnection, boolean recursiveGetBounds, + Point computedAbsoluteLocation) { + PrecisionRectangle bounds = new PrecisionRectangle(computedAbsoluteLocation.preciseX(), computedAbsoluteLocation.preciseY(), 0, 0); LayoutConstraint layoutConstraint = node.getLayoutConstraint(); EObject element = node.getElement(); - if (element instanceof AbstractDNode) { - AbstractDNode abstractDNode = (AbstractDNode) element; - if (layoutConstraint instanceof Location) { - bounds.setX(((Location) layoutConstraint).getX()); - bounds.setY(((Location) layoutConstraint).getY()); - } - if (layoutConstraint instanceof Size) { - bounds.setWidth(((Size) layoutConstraint).getWidth()); - bounds.setHeight(((Size) layoutConstraint).getHeight()); + if (element instanceof AbstractDNode abstractDNode) { + if (layoutConstraint instanceof Size size) { + bounds.setWidth(size.getWidth()); + bounds.setHeight(size.getHeight()); } else { bounds.setWidth(-1); bounds.setHeight(-1); } - - if (new ViewQuery(node).isForNameEditPart()) { + ViewQuery viewQuery = new ViewQuery(node); + if (viewQuery.isForNameEditPart() || viewQuery.isListItem()) { if (abstractDNode.getName() == null || abstractDNode.getName().length() == 0) { if (bounds.width == -1) { bounds.setWidth(0); @@ -602,10 +748,10 @@ public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstra } else { // Make a default size for label (this size is purely an average estimate) - replaceAutoSize(node, bounds, useFigureForAutoSizeConstraint, getLabelDimension(node, new Dimension(50, 20))); + replaceAutoSize(node, bounds, useFigureForAutoSizeConstraint, getLabelDimension(node, new Dimension(50, 20)), recursiveGetBounds); } } else { - replaceAutoSize(node, bounds, useFigureForAutoSizeConstraint, null); + replaceAutoSize(node, bounds, useFigureForAutoSizeConstraint, null, recursiveGetBounds); } if (boxForConnection) { @@ -615,8 +761,8 @@ public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstra // This insets corresponds to insets of {@link // org.eclipse.sirius.diagram.ui.tools.api.figure.AlphaDropShadowBorder#getTransparentInsets()}. double shadowBorderSize = getShadowBorderSize(node); - bounds.setWidth(bounds.width - shadowBorderSize); - bounds.setHeight(bounds.height - shadowBorderSize); + bounds.setPreciseWidth(bounds.preciseWidth() - shadowBorderSize); + bounds.setPreciseHeight(bounds.preciseHeight() - shadowBorderSize); } } return bounds; @@ -645,11 +791,11 @@ public static double getShadowBorderSize(Node node) { * * @return false for regions and workspace images, true otherwise. */ - public static boolean isShadowBorderNeeded(Node node) { + private static boolean isShadowBorderNeeded(Node node) { boolean needShadowBorder = false; EObject element = node.getElement(); - if (element instanceof DDiagramElementContainer) { - DDiagramElementContainer ddec = (DDiagramElementContainer) element; + ViewQuery viewQuery = new ViewQuery(node); + if (!viewQuery.isFreeFormCompartment() && !viewQuery.isListCompartment() && !viewQuery.isForNameEditPart() && element instanceof DDiagramElementContainer ddec) { needShadowBorder = !(new DDiagramElementContainerExperimentalQuery(ddec).isRegion() || ddec.getOwnedStyle() instanceof WorkspaceImage); } return needShadowBorder; @@ -667,27 +813,36 @@ public static boolean isShadowBorderNeeded(Node node) { * true to use draw2d figure to get size * @param providedDefaultSize * The size used for creation for this kind of node. It is the minimum size. + * @param recursive + * true if this method is called from a "parent" call, false otherwise. */ - private static void replaceAutoSize(Node node, Rectangle bounds, boolean useFigureForAutoSizeConstraint, Dimension providedDefaultSize) { + private static void replaceAutoSize(Node node, PrecisionRectangle bounds, boolean useFigureForAutoSizeConstraint, Dimension providedDefaultSize, boolean recursive) { if (bounds.width == -1 || bounds.height == -1) { Dimension defaultSize = providedDefaultSize; if (providedDefaultSize == null) { // if there is no default size, we compute it from the given // node. EObject element = node.getElement(); - if (element instanceof AbstractDNode) { - defaultSize = getDefaultSize((AbstractDNode) element); + ViewQuery nodeQuery = new ViewQuery(node); + if (nodeQuery.isFreeFormCompartment() || nodeQuery.isListCompartment()) { + defaultSize = new Dimension(ResizableCompartmentFigure.MIN_CLIENT_DP, ResizableCompartmentFigure.MIN_CLIENT_DP); + if (node.getChildren().isEmpty() && (nodeQuery.isListCompartment() || nodeQuery.isVerticalRegionContainerCompartment() || nodeQuery.isHorizontalRegionContainerCompartment())) { + // Add one margin border (even if empty) + defaultSize.expand(0, 1); + } + } else if (element instanceof AbstractDNode abstractDNode) { + defaultSize = getDefaultSize(abstractDNode); } } if (useFigureForAutoSizeConstraint) { // Use the figure (if founded) to set width and height // instead of (-1, -1) - Option optionalTargetEditPart = getGraphicalEditPart(node); + Optional optionalTargetEditPart = getGraphicalEditPart(node); // CHECKSTYLE:OFF - if (optionalTargetEditPart.some()) { + if (optionalTargetEditPart.isPresent()) { GraphicalEditPart graphicalEditPart = optionalTargetEditPart.get(); - if (graphicalEditPart instanceof AbstractDiagramElementContainerEditPart) { - ((AbstractDiagramElementContainerEditPart) graphicalEditPart).forceFigureAutosize(); + if (graphicalEditPart instanceof AbstractDiagramElementContainerEditPart abstractDiagramElementContainerEditPart) { + abstractDiagramElementContainerEditPart.forceFigureAutosize(); ((GraphicalEditPart) graphicalEditPart.getParent()).getFigure().validate(); } @@ -710,20 +865,33 @@ private static void replaceAutoSize(Node node, Rectangle bounds, boolean useFigu } else { // Compute the bounds of all children and use the lowest // one (y+height) for height and the rightmost one - // (x+width) for width. - Point bottomRight = getBottomRight(node); + // (x+width) for width plus the margin. + Rectangle childrenBounds = getChildrenBounds(node, recursive); + // Add the potential shadow border size and the bottom right insets of the node (i.e. container) + double shadowBorderSize = getShadowBorderSize(node); + Dimension bottomRightInsets = getBottomRightInsets(node); + // Do not add bottom right insets and shadow if there is at least one border node on the corresponding + // side + int borderNodesSides = PositionConstants.NONE; + if (recursive) { + borderNodesSides = getBorderNodesSides(node, childrenBounds); + } + boolean isBorderNodeOnRightSide = (PositionConstants.RIGHT & borderNodesSides) == PositionConstants.RIGHT; + boolean isBorderNodeOnBottomSide = (PositionConstants.BOTTOM & borderNodesSides) == PositionConstants.BOTTOM; + childrenBounds.resize(isBorderNodeOnRightSide ? 0 : bottomRightInsets.width() + shadowBorderSize, isBorderNodeOnBottomSide ? 0 : bottomRightInsets.height() + shadowBorderSize); + // Replace -1 by the new computed values if (bounds.width == -1) { - if (bottomRight.x > defaultSize.width) { - bounds.setWidth(bottomRight.x); - } else { - bounds.setWidth(defaultSize.width); + bounds.setPreciseWidth(defaultSize.preciseWidth()); + double deltaWidth = childrenBounds.getRight().preciseX() - bounds.getRight().preciseX(); + if (deltaWidth > 0) { + bounds.resize(deltaWidth, 0); } } if (bounds.height == -1) { - if (bottomRight.y > defaultSize.height) { - bounds.setHeight(bottomRight.y); - } else { - bounds.setHeight(defaultSize.height); + bounds.setPreciseHeight(defaultSize.preciseHeight()); + double deltaHeight = childrenBounds.getBottom().preciseY() - bounds.getBottom().preciseY(); + if (deltaHeight > 0) { + bounds.resize(0, deltaHeight); } } } @@ -737,20 +905,41 @@ private static void replaceAutoSize(Node node, Rectangle bounds, boolean useFigu } } + private static int getBorderNodesSides(Node container, Rectangle containerChildrenBounds) { + int result = PositionConstants.NONE; + for (ListIterator children = container.getChildren().listIterator(); children.hasNext(); /* */) { + View child = children.next(); + if (child instanceof Node nodeChild && new NodeQuery(nodeChild).isBorderedNode()) { + Rectangle borderNodeBounds = getAbsoluteBounds(nodeChild, true, false, false, false); + if (borderNodeBounds.preciseX() == containerChildrenBounds.preciseX()) { + result = result | PositionConstants.LEFT; + } + if (borderNodeBounds.preciseY() == containerChildrenBounds.preciseY()) { + result = result | PositionConstants.TOP; + } + if (borderNodeBounds.preciseX() + borderNodeBounds.preciseWidth() == containerChildrenBounds.preciseX() + containerChildrenBounds.preciseWidth()) { + result = result | PositionConstants.RIGHT; + } + if (borderNodeBounds.preciseY() + borderNodeBounds.preciseHeight() == containerChildrenBounds.preciseY() + containerChildrenBounds.preciseHeight()) { + result = result | PositionConstants.BOTTOM; + } + } + } + return result; + } + private static void lookForNextRegionLocation(Rectangle bounds, Node node) { EObject element = node.getElement(); - if (element instanceof DDiagramElementContainer && node.eContainer() instanceof Node) { - DDiagramElementContainer ddec = (DDiagramElementContainer) element; + if (element instanceof DDiagramElementContainer ddec && node.eContainer() instanceof Node nodeContainer) { DDiagramElementContainerExperimentalQuery query = new DDiagramElementContainerExperimentalQuery(ddec); boolean isRegion = query.isRegion(); - EList children = ((Node) node.eContainer()).getChildren(); + EList children = nodeContainer.getChildren(); int currentIndex = children.indexOf(node); if (!(currentIndex != 0 && bounds.equals(new Rectangle(0, 0, -1, -1)))) { // We are not in the case of a new region insertion (in this // case, we use the default size) int nextIndex = currentIndex + 1; - if (isRegion && nextIndex != 0 && nextIndex < children.size() && children.get(nextIndex) instanceof Node) { - Node nextNode = (Node) children.get(nextIndex); + if (isRegion && nextIndex != 0 && nextIndex < children.size() && children.get(nextIndex) instanceof Node nextNode) { int visualID = SiriusVisualIDRegistry.getVisualID(nextNode.getType()); if (DNodeContainer2EditPart.VISUAL_ID == visualID || DNodeListEditPart.VISUAL_ID == visualID || DNodeList2EditPart.VISUAL_ID == visualID) { // DNodeContainerEditPart.VISUAL_ID == visualID is not @@ -758,8 +947,7 @@ private static void lookForNextRegionLocation(Rectangle bounds, Node node) { // DNodeContainerEditPart as it is directly contained by // the diagram part. LayoutConstraint layoutConstraint = nextNode.getLayoutConstraint(); - if (layoutConstraint instanceof Location) { - Location nextLocation = (Location) layoutConstraint; + if (layoutConstraint instanceof Location nextLocation) { // Update only the parent stack direction if some // layout has already been done. if (bounds.width == -1 && query.isRegionInHorizontalStack() && nextLocation.getX() != 0) { @@ -779,37 +967,59 @@ private static void lookForNextRegionLocation(Rectangle bounds, Node node) { * Returns a new Point representing the bottom right point of all bounds of children of this Node. Useful for Node * with size of -1x-1 to be more accurate (but it is still not necessarily the same size that draw2d). * - * @param node + * @param container * the node whose bottom right corner is to compute. + * @param considerBorderNode + * true to consider border nodes when computing the bottom right corner point, false otherwise. * * @return Point at the bottom right of the rectangle */ - public static Point getBottomRight(Node node) { - int right = 0; - int bottom = 0; - for (Iterator children = Iterators.filter(node.getChildren().iterator(), Node.class); children.hasNext(); /* */) { - Node child = children.next(); - // The bordered nodes is ignored - if (!(new NodeQuery(node).isBorderedNode())) { - Rectangle bounds = getBounds(child); - Point bottomRight = bounds.getBottomRight(); - if (bottomRight.x > right) { - right = bottomRight.x; - } - if (bottomRight.y > bottom) { - bottom = bottomRight.y; + private static Rectangle getChildrenBounds(Node container, boolean considerBorderNodes) { + Rectangle result = null; + if (container.getChildren().isEmpty()) { + result = new PrecisionRectangle(); + } + ViewQuery containerViewQuery = new ViewQuery(container); + if (containerViewQuery.isListContainer() || containerViewQuery.isListCompartment() || containerViewQuery.isVerticalRegionContainerCompartment()) { + if (!container.getChildren().isEmpty()) { + Node lastChild = getLastChild(container, considerBorderNodes); + result = getAbsoluteBounds(lastChild, true, false, true, false); + } + } else { + for (ListIterator children = container.getChildren().listIterator(); children.hasNext(); /* */) { + View child = children.next(); + // The border nodes are ignored, except if it is expected to consider it (auto-size of a container with + // children having border nodes) + if (child instanceof Node nodeChild && (considerBorderNodes || !(new NodeQuery(nodeChild).isBorderedNode()))) { + Rectangle childAbsoluteBounds = getAbsoluteBounds(nodeChild, true, false, true, false); + if (result == null) { + result = childAbsoluteBounds.getCopy(); + } else { + // Make union of the child bounds and its parent bounds + result.union(childAbsoluteBounds); + } } } } - return new Point(right, bottom); + return result; + } + + private static Node getLastChild(Node container, boolean considerBorderNodes) { + for (int i = container.getChildren().size() - 1; i >= 0; i--) { + Node currentNode = (Node) container.getChildren().get(i); + if (considerBorderNodes || !new NodeQuery(currentNode).isBorderedNode()) { + return currentNode; + } + } + return null; } private static Dimension getDefaultSize(AbstractDNode abstractDNode) { Dimension defaultSize = new Dimension(-1, -1); - if (abstractDNode instanceof DNode) { - defaultSize = new DNodeQuery((DNode) abstractDNode).getDefaultDimension(); - } else if (abstractDNode instanceof DNodeContainer) { - defaultSize = new DNodeContainerQuery((DNodeContainer) abstractDNode).getDefaultDimension(); + if (abstractDNode instanceof DNode dNode) { + defaultSize = new DNodeQuery(dNode).getDefaultDimension(); + } else if (abstractDNode instanceof DNodeContainer dNodeContainer) { + defaultSize = new DNodeContainerQuery(dNodeContainer).getDefaultDimension(); } else if (abstractDNode instanceof DNodeList) { defaultSize = LayoutUtils.NEW_DEFAULT_CONTAINER_DIMENSION; } @@ -824,28 +1034,28 @@ private static Dimension getDefaultSize(AbstractDNode abstractDNode) { * The view element that is searched * @return The optional corresponding edit part. */ - public static Option getGraphicalEditPart(View view) { + public static Optional getGraphicalEditPart(View view) { if (view != null) { Diagram gmfDiagram = view.getDiagram(); // Try the active editor first (most likely case in practice) IEditorPart editor = EclipseUIUtil.getActiveEditor(); if (isEditorFor(editor, gmfDiagram)) { return getGraphicalEditPart(view, (DiagramEditor) editor); - } else if (gmfDiagram.getElement() instanceof DDiagram) { + } else if (gmfDiagram.getElement() instanceof DDiagram dDiagram) { // Otherwise check all active Sirius editors for (IEditingSession uiSession : SessionUIManager.INSTANCE.getUISessions()) { - DialectEditor dialectEditor = uiSession.getEditor((DDiagram) gmfDiagram.getElement()); + DialectEditor dialectEditor = uiSession.getEditor(dDiagram); if (isEditorFor(dialectEditor, gmfDiagram)) { return getGraphicalEditPart(view, (DiagramEditor) dialectEditor); } } } } - return Options. newNone(); + return Optional.empty(); } private static boolean isEditorFor(IEditorPart editor, Diagram diagram) { - return editor instanceof DiagramEditor && ((DiagramEditor) editor).getDiagram() == diagram; + return editor instanceof DiagramEditor diagramEditor && diagramEditor.getDiagram() == diagram; } /** @@ -858,12 +1068,12 @@ private static boolean isEditorFor(IEditorPart editor, Diagram diagram) { * the editor where looking for the edit part. * @return The optional corresponding edit part. */ - public static Option getGraphicalEditPart(View view, DiagramEditor editor) { - Option result = Options.newNone(); + public static Optional getGraphicalEditPart(View view, DiagramEditor editor) { + Optional result = Optional.empty(); final Map editPartRegistry = editor.getDiagramGraphicalViewer().getEditPartRegistry(); final EditPart targetEditPart = (EditPart) editPartRegistry.get(view); - if (targetEditPart instanceof GraphicalEditPart) { - result = Options.newSome((GraphicalEditPart) targetEditPart); + if (targetEditPart instanceof GraphicalEditPart graphicalEditPart) { + result = Optional.of(graphicalEditPart); } return result; } @@ -878,10 +1088,8 @@ public static Option getGraphicalEditPart(View view, DiagramE * when the edgeEditPart is not as expected */ public static List getPointsFromSource(ConnectionEditPart edgeEditPart) throws IllegalArgumentException { - if (edgeEditPart.getModel() instanceof Edge && edgeEditPart.getFigure() instanceof Connection) { + if (edgeEditPart.getModel() instanceof Edge gmfEdge && edgeEditPart.getFigure() instanceof Connection connectionFigure) { List result = new ArrayList<>(); - Edge gmfEdge = (Edge) edgeEditPart.getModel(); - Connection connectionFigure = (Connection) edgeEditPart.getFigure(); Point srcAnchorLoc = connectionFigure.getSourceAnchor().getReferencePoint(); connectionFigure.translateToRelative(srcAnchorLoc); @@ -906,10 +1114,8 @@ public static List getPointsFromSource(ConnectionEditPart edgeEditPart) t * when the edgeEditPart is not as expected */ public static List getPointsFromTarget(ConnectionEditPart edgeEditPart) throws IllegalArgumentException { - if (edgeEditPart.getModel() instanceof Edge && edgeEditPart.getFigure() instanceof Connection) { + if (edgeEditPart.getModel() instanceof Edge gmfEdge && edgeEditPart.getFigure() instanceof Connection connectionFigure) { List result = new ArrayList<>(); - Edge gmfEdge = (Edge) edgeEditPart.getModel(); - Connection connectionFigure = (Connection) edgeEditPart.getFigure(); Point tgtAnchorLoc = connectionFigure.getTargetAnchor().getReferencePoint(); connectionFigure.translateToRelative(tgtAnchorLoc); @@ -938,32 +1144,54 @@ public static Dimension getLabelDimension(Node node, Dimension defaultDimension) Dimension labelSize = defaultDimension; ViewQuery viewQuery = new ViewQuery(node); EObject element = node.getElement(); - if (element instanceof DDiagramElement) { - DDiagramElement dDiagramElement = (DDiagramElement) element; + if (element instanceof DDiagramElement dDiagramElement) { org.eclipse.sirius.viewpoint.Style siriusStyle = dDiagramElement.getStyle(); - if (!new DDiagramElementQuery(dDiagramElement).isLabelHidden()) { - if (siriusStyle instanceof BasicLabelStyle) { - BasicLabelStyle bls = (BasicLabelStyle) siriusStyle; - Font defaultFont = VisualBindingManager.getDefault().getFontFromLabelStyle(bls, (String) viewQuery.getDefaultValue(NotationPackage.Literals.FONT_STYLE__FONT_NAME)); - try { - labelSize = FigureUtilities.getStringExtents(dDiagramElement.getName(), defaultFont); - if (bls.isShowIcon()) { - // Also consider the icon size - Dimension iconDimension = getIconDimension(dDiagramElement, bls); - labelSize.setHeight(Math.max(labelSize.height(), iconDimension.height)); - labelSize.setWidth(labelSize.width() + ICON_TEXT_GAP + iconDimension.width); - } - } catch (SWTException e) { - // Probably an "Invalid thread access" (FigureUtilities - // creates a new Shell to compute the label size). So in - // this case, we use the default size. + if (!new DDiagramElementQuery(dDiagramElement).isLabelHidden() && siriusStyle instanceof BasicLabelStyle bls) { + String fontName = (String) viewQuery.getDefaultValue(NotationPackage.Literals.FONT_STYLE__FONT_NAME); + Optional + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.sirius.tests.swtbot/data/unit/layout/gmfHelper/representations.aird b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/layout/gmfHelper/representations.aird new file mode 100644 index 0000000000..025b7d3e47 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/layout/gmfHelper/representations.aird @@ -0,0 +1,1484 @@ + + + + My.ecore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/BorderedNodeCreationTest.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/BorderedNodeCreationTest.java index 49967a9386..21e4d900be 100644 --- a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/BorderedNodeCreationTest.java +++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/BorderedNodeCreationTest.java @@ -637,7 +637,7 @@ protected void assertBorderedNodeAtLocation(String borderedNodeLabel, Point expe errorMessage = "the BorderedNode has been created at wrong location (for near collapsed bordered node case)."; } // Check GMF - Point gmfNodeLocation = GMFHelper.getAbsoluteLocation((Node) borderNodePart.getModel(), true); + Point gmfNodeLocation = GMFHelper.getAbsoluteLocation((Node) borderNodePart.getModel(), true, true); assertSameLocation("For GMF, " + errorMessage, expectedLocation, gmfNodeLocation, parentLocation, creationLocation, parentPart); // Check Draw2d assertSameLocation("For Draw2d, " + errorMessage, expectedLocation, nodeLocation, parentLocation, creationLocation, parentPart); diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/BorderedNodeCreationWithSnapToGridTest.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/BorderedNodeCreationWithSnapToGridTest.java index fb2c771111..d59b008650 100644 --- a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/BorderedNodeCreationWithSnapToGridTest.java +++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/BorderedNodeCreationWithSnapToGridTest.java @@ -89,8 +89,8 @@ public void testCreateTwoBorderNodesAtSameLocation() { assertFalse("Second border node should not overlap the first one (draw2d).", firstNewNodeAbsoluteBounds.intersects(secondNewNodeAbsoluteLocation)); - Rectangle firstNewNodeGMFBounds = GMFHelper.getAbsoluteBounds((Node) firstNewNode.part().getModel()); - Rectangle secondNewNodeGMFBounds = GMFHelper.getAbsoluteBounds((Node) secondNewNode.part().getModel()); + Rectangle firstNewNodeGMFBounds = GMFHelper.getAbsoluteBounds((Node) firstNewNode.part().getModel(), false, false, false, true); + Rectangle secondNewNodeGMFBounds = GMFHelper.getAbsoluteBounds((Node) secondNewNode.part().getModel(), false, false, false, true); assertFalse("Second border node should not overlap the first one (GMF).", firstNewNodeGMFBounds.intersects(secondNewNodeGMFBounds)); diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/EdgeWithBorderNodeCreationPositionWithSnapToGridTest.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/EdgeWithBorderNodeCreationPositionWithSnapToGridTest.java index c53b8590f4..7a1692b63e 100644 --- a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/EdgeWithBorderNodeCreationPositionWithSnapToGridTest.java +++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/EdgeWithBorderNodeCreationPositionWithSnapToGridTest.java @@ -87,14 +87,14 @@ public String getFailureMessage() { Point draw2DSourceBNLocation = GraphicalHelper.getAbsoluteBoundsIn100Percent(source, true).getTopLeft(); assertTrue("For starting point (" + draw2DSourceBNLocation.preciseX() + ", " + draw2DSourceBNLocation.preciseY() + "), the x or y coordinate should be on the grid (step=" + gridStep + ") or at least one should be the same as parent: " + parentSourceBounds + ".", checkLocation(draw2DSourceBNLocation, parentSourceBounds)); - Point gmfSourceBNLocation = GMFHelper.getAbsoluteLocation((Node) source.getModel(), true); + Point gmfSourceBNLocation = GMFHelper.getAbsoluteLocation((Node) source.getModel(), true, true); assertEquals("The computing starting point from GMF data should be the same than draw2D", draw2DSourceBNLocation, gmfSourceBNLocation); Rectangle parentTargetBounds = GraphicalHelper.getAbsoluteBoundsIn100Percent(target, true); Point draw2DTargetBNLocation = GraphicalHelper.getAbsoluteBoundsIn100Percent(target, true).getTopLeft(); assertTrue("For ending point (" + draw2DTargetBNLocation.preciseX() + ", " + draw2DTargetBNLocation.preciseY() + "), the x or y coordinate should be on the grid (step=" + gridStep + ") or at least one should be the same as parent: " + parentTargetBounds + ".", checkLocation(draw2DTargetBNLocation, parentTargetBounds)); - Point gmfTargetBNLocation = GMFHelper.getAbsoluteLocation((Node) target.getModel(), true); + Point gmfTargetBNLocation = GMFHelper.getAbsoluteLocation((Node) target.getModel(), true, true); assertEquals("The computing starting point from GMF data should be the same than draw2D", draw2DTargetBNLocation, gmfTargetBNLocation); // Contrary to super class, the checkSide are not done because // snapToGrid is enabled and has effect on the side. diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/layout/GMFHelperTest.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/layout/GMFHelperTest.java new file mode 100644 index 0000000000..995e952e50 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/layout/GMFHelperTest.java @@ -0,0 +1,286 @@ +/******************************************************************************* + * Copyright (c) 2024 Obeo. + * 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: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.tests.swtbot.layout; + +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gmf.runtime.notation.Node; +import org.eclipse.sirius.diagram.DDiagram; +import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeContainer2EditPart; +import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeContainerEditPart; +import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListEditPart; +import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListElementEditPart; +import org.eclipse.sirius.diagram.ui.internal.refresh.GMFHelper; +import org.eclipse.sirius.tests.swtbot.Activator; +import org.eclipse.sirius.tests.swtbot.support.api.AbstractSiriusSwtBotGefTestCase; +import org.eclipse.sirius.tests.swtbot.support.api.business.UIDiagramRepresentation.ZoomLevel; +import org.eclipse.sirius.tests.swtbot.support.api.business.UIResource; +import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotSiriusDiagramEditor; +import org.eclipse.sirius.tests.swtbot.support.api.view.DesignerViews; +import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils; +import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart; + +/** + * Tests defined to ensure that GMF Helper returns correct absolute GMF bounds. + * + * TODO: - Add tests for border nodes bounds - Add tests for nodes bounds (inside container) + * + * @author lredor + */ +public class GMFHelperTest extends AbstractSiriusSwtBotGefTestCase { + + private static final String FREE_FORM_CONTAINER_REPRESENTATION_NAME = "DiagramWithFreeFormContainers"; + + private static final String LIST_CONTAINER_REPRESENTATION_NAME = "DiagramWithListContainers"; + + private static final String HSTACK_CONTAINER_REPRESENTATION_NAME = "DiagramWithHStackContainers"; + + private static final String VSTACK_CONTAINER_REPRESENTATION_NAME = "DiagramWithVStackContainers"; + + private static final String MODEL = "My.ecore"; + + private static final String SESSION_FILE = "representations.aird"; + + private static final String ODESIGN_FILE = "My.odesign"; + + private static final String DATA_UNIT_DIR = "data/unit/layout/gmfHelper/"; + + private static final String FILE_DIR = "/"; + + /** + * The name of a container that is empty. + */ + private static final String EMPTY_CONTAINER_NAME = "p1"; + + /** + * The name of a container with children. + */ + private static final String CONTAINER_WITH_CHILDREN_NAME = "p2"; + + /** + * The name of a container that is empty and in another container + */ + private static final String EMPTY_CONTAINER_INSIDE_CONTAINER_NAME = "p22"; + + + /** + * The name of an empty container with border node. + */ + private static final String EMPTY_CONTAINER_WITH_BORDER_NODE_NAME = "p3"; + + /** + * The name of a container with children having border node. + */ + private static final String CONTAINER_WITH_2_CHILDREN_HAVING_BORDER_NODE_NAME = "p4"; + + /** + * The name of an empty container with border node, inside a container. + */ + private static final String EMPTY_CONTAINER_WITH_BORDER_NODE_INSIDE_CONTAINER_2_NAME = "p41"; + + /** + * The name of a container with children having border node. + */ + private static final String CONTAINER_WITH_3_CHILDREN_HAVING_BORDER_NODE_NAME = "p5"; + + /** + * The name of an empty container with border node, inside a container. + */ + private static final String EMPTY_CONTAINER_WITH_BORDER_NODE_INSIDE_CONTAINER_3_NAME = "p53"; + + /** + * {@inheritDoc} + */ + @Override + protected void onSetUpBeforeClosingWelcomePage() throws Exception { + copyFileToTestProject(Activator.PLUGIN_ID, DATA_UNIT_DIR, MODEL, SESSION_FILE, ODESIGN_FILE); + } + + /** + * {@inheritDoc} + */ + @Override + protected void onSetUpAfterOpeningDesignerPerspective() throws Exception { + sessionAirdResource = new UIResource(designerProject, FILE_DIR, SESSION_FILE); + localSession = designerPerspective.openSessionFromFile(sessionAirdResource); + closeOutline(); + } + + /** + * Method to open an editor. It should be called at the beginning of each test. + * + * @param representationName + * The name of the representation to be opened. + */ + private void openEditor(String representationName) { + editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(), representationName, representationName, DDiagram.class, true); + } + + /** + * {@inheritDoc} + */ + @Override + protected void tearDown() throws Exception { + // Go to the origin to avoid scroll bar + editor.scrollTo(0, 0); + // Restore the default zoom level + editor.click(1, 1); // Set the focus on the diagram + editor.zoom(ZoomLevel.ZOOM_100); + // Go to the origin to avoid scroll bar + editor.scrollTo(0, 0); + // Reopen outline + new DesignerViews(bot).openOutlineView(); + SWTBotUtils.waitAllUiEvents(); + super.tearDown(); + } + + public void testFreeFormContainerBounds_1() { + testFreeFormContainerBounds(EMPTY_CONTAINER_NAME, DNodeContainerEditPart.class); + } + + public void testFreeFormContainerBounds_2() { + testFreeFormContainerBounds(CONTAINER_WITH_CHILDREN_NAME, DNodeContainerEditPart.class); + } + + public void testFreeFormContainerBounds_3() { + testFreeFormContainerBounds(EMPTY_CONTAINER_INSIDE_CONTAINER_NAME, DNodeContainer2EditPart.class); + } + + public void testFreeFormContainerBounds_4() { + testFreeFormContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_NAME, DNodeContainerEditPart.class); + } + + public void testFreeFormContainerBounds_5() { + testFreeFormContainerBounds(CONTAINER_WITH_2_CHILDREN_HAVING_BORDER_NODE_NAME, DNodeContainerEditPart.class); + testFreeFormContainerBounds(CONTAINER_WITH_3_CHILDREN_HAVING_BORDER_NODE_NAME, DNodeContainerEditPart.class); + } + + public void testFreeFormContainerBounds_6() { + testFreeFormContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_INSIDE_CONTAINER_2_NAME, DNodeContainer2EditPart.class); + testFreeFormContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_INSIDE_CONTAINER_3_NAME, DNodeContainerEditPart.class); + } + + + public void testListContainerBounds_1() { + testListContainerBounds(EMPTY_CONTAINER_NAME, DNodeListEditPart.class); + } + + public void testListContainerBounds_2() { + testListContainerBounds(CONTAINER_WITH_CHILDREN_NAME, DNodeListEditPart.class); + } + + public void testListContainerBounds_3() { + testListContainerBounds(EMPTY_CONTAINER_INSIDE_CONTAINER_NAME, DNodeListElementEditPart.class); + } + + public void testListContainerBounds_4() { + testListContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_NAME, DNodeListEditPart.class); + } + + public void testListContainerBounds_5() { + testListContainerBounds(CONTAINER_WITH_2_CHILDREN_HAVING_BORDER_NODE_NAME, DNodeListEditPart.class); + testListContainerBounds(CONTAINER_WITH_3_CHILDREN_HAVING_BORDER_NODE_NAME, DNodeListEditPart.class); + } + + public void testListContainerBounds_6() { + testListContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_INSIDE_CONTAINER_2_NAME, DNodeListElementEditPart.class); + testListContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_INSIDE_CONTAINER_3_NAME, DNodeListElementEditPart.class); + } + + public void testHStackContainerBounds_1() { + testHStackContainerBounds(EMPTY_CONTAINER_NAME, DNodeContainerEditPart.class); + } + + public void testHStackContainerBounds_2() { + testHStackContainerBounds(CONTAINER_WITH_CHILDREN_NAME, DNodeContainerEditPart.class); + } + + public void testHStackContainerBounds_3() { + testHStackContainerBounds(EMPTY_CONTAINER_INSIDE_CONTAINER_NAME, DNodeContainer2EditPart.class); + } + + public void testHStackContainerBounds_4() { + testHStackContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_NAME, DNodeContainerEditPart.class); + } + + public void testHStackContainerBounds_5() { + testHStackContainerBounds(CONTAINER_WITH_2_CHILDREN_HAVING_BORDER_NODE_NAME, DNodeContainerEditPart.class); + testHStackContainerBounds(CONTAINER_WITH_3_CHILDREN_HAVING_BORDER_NODE_NAME, DNodeContainerEditPart.class); + } + + public void testHStackContainerBounds_6() { + testHStackContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_INSIDE_CONTAINER_2_NAME, DNodeContainer2EditPart.class); + testHStackContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_INSIDE_CONTAINER_3_NAME, DNodeContainer2EditPart.class); + } + + public void testVStackContainerBounds_1() { + testVStackContainerBounds(EMPTY_CONTAINER_NAME, DNodeContainerEditPart.class); + } + + public void testVStackContainerBounds_2() { + testVStackContainerBounds(CONTAINER_WITH_CHILDREN_NAME, DNodeContainerEditPart.class); + } + + public void testVStackContainerBounds_3() { + testVStackContainerBounds(EMPTY_CONTAINER_INSIDE_CONTAINER_NAME, DNodeContainer2EditPart.class); + } + + public void testVStackContainerBounds_4() { + testVStackContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_NAME, DNodeContainerEditPart.class); + } + + public void testVStackContainerBounds_5() { + testVStackContainerBounds(CONTAINER_WITH_2_CHILDREN_HAVING_BORDER_NODE_NAME, DNodeContainerEditPart.class); + testVStackContainerBounds(CONTAINER_WITH_3_CHILDREN_HAVING_BORDER_NODE_NAME, DNodeContainerEditPart.class); + } + + public void testVStackContainerBounds_6() { + testVStackContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_INSIDE_CONTAINER_2_NAME, DNodeContainer2EditPart.class); + testVStackContainerBounds(EMPTY_CONTAINER_WITH_BORDER_NODE_INSIDE_CONTAINER_3_NAME, DNodeContainer2EditPart.class); + } + + private void testFreeFormContainerBounds(String elementToCheckName, Class expectedEditPartType) { + testContainerBounds(FREE_FORM_CONTAINER_REPRESENTATION_NAME, elementToCheckName, expectedEditPartType); + } + + private void testListContainerBounds(String elementToCheckName, Class expectedEditPartType) { + testContainerBounds(LIST_CONTAINER_REPRESENTATION_NAME, elementToCheckName, expectedEditPartType); + } + + private void testHStackContainerBounds(String elementToCheckName, Class expectedEditPartType) { + testContainerBounds(HSTACK_CONTAINER_REPRESENTATION_NAME, elementToCheckName, expectedEditPartType); + } + + private void testVStackContainerBounds(String elementToCheckName, Class expectedEditPartType) { + testContainerBounds(VSTACK_CONTAINER_REPRESENTATION_NAME, elementToCheckName, expectedEditPartType); + } + + private void testContainerBounds(String representationName, String elementToCheckName, Class expectedEditPartType) { + openEditor(representationName); + SWTBotGefEditPart swtBotEditPart = editor.getEditPart(elementToCheckName, expectedEditPartType); + Rectangle draw2DAbsoluteBounds = editor.getAbsoluteBounds(swtBotEditPart); + // It's strange, the above method does not return absolute bounds. To check in another commit. And the method + // GraphicalHelper.getAbsoluteBoundsIn100Percent consider handleBounds and this is not what is expected here. + ((GraphicalEditPart) swtBotEditPart.part()).getFigure().translateToAbsolute(draw2DAbsoluteBounds); + Rectangle gmfAbsoluteBounds = GMFHelper.getAbsoluteBounds((Node) swtBotEditPart.part().getModel(), true, false, false, false); + assertEquals("The GMF width of " + elementToCheckName + " in " + representationName + " does not correspond to the Draw2D one.", draw2DAbsoluteBounds.preciseWidth(), + gmfAbsoluteBounds.preciseWidth()); + assertEquals("The GMF height of " + elementToCheckName + " in " + representationName + " does not correspond to the Draw2D one.", draw2DAbsoluteBounds.preciseHeight(), + gmfAbsoluteBounds.preciseHeight()); + assertEquals("The GMF x coordinate of " + elementToCheckName + " in " + representationName + " does not correspond to the Draw2D one.", draw2DAbsoluteBounds.preciseX(), + gmfAbsoluteBounds.preciseX()); + assertEquals("The GMF y coordinate of " + elementToCheckName + " in " + representationName + " does not correspond to the Draw2D one.", draw2DAbsoluteBounds.preciseY(), + gmfAbsoluteBounds.preciseY()); + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java index d6333738dc..62ab3555c4 100644 --- a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java +++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java @@ -56,6 +56,7 @@ import org.eclipse.sirius.tests.swtbot.layout.EdgeLabelsAlignAndDistributeTests; import org.eclipse.sirius.tests.swtbot.layout.EdgeLayoutStabilityWithToolWizardTest; import org.eclipse.sirius.tests.swtbot.layout.EdgeStabilityOnCopyPasteLayoutTest; +import org.eclipse.sirius.tests.swtbot.layout.GMFHelperTest; import org.eclipse.sirius.tests.swtbot.layout.LayoutStabilityOnManualRefreshTest; import org.eclipse.sirius.tests.swtbot.layout.ModifyEdgeLayoutAfterRefreshTest; import org.eclipse.sirius.tests.swtbot.layout.PackageLayoutStabilityOnManyViewsCreationToolTest; @@ -442,6 +443,7 @@ public static void addPart2(TestSuite suite) { suite.addTestSuite(PackageLayoutStabilityOnManyViewsCreationToolTest.class); suite.addTestSuite(ResetOriginTest.class); suite.addTestSuite(LayoutStabilityOnManualRefreshTest.class); + suite.addTestSuite(GMFHelperTest.class); suite.addTestSuite(EdgeAndPortStabilityOnSemanticChangeTest.class); suite.addTestSuite(SessionSaveableTest.class); suite.addTest(new JUnit4TestAdapter(DragAndDropFromControlledResourceTest.class)); diff --git a/plugins/org.eclipse.sirius.ui.debug/src/org/eclipse/sirius/ui/debug/SiriusDebugView.java b/plugins/org.eclipse.sirius.ui.debug/src/org/eclipse/sirius/ui/debug/SiriusDebugView.java index 1f6357d38e..87e0a521d0 100644 --- a/plugins/org.eclipse.sirius.ui.debug/src/org/eclipse/sirius/ui/debug/SiriusDebugView.java +++ b/plugins/org.eclipse.sirius.ui.debug/src/org/eclipse/sirius/ui/debug/SiriusDebugView.java @@ -122,6 +122,7 @@ import org.eclipse.sirius.diagram.ui.business.internal.query.EdgeTargetQuery; import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramContainerEditPart; import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramElementContainerEditPart; +import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramListEditPart; import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramNameEditPart; import org.eclipse.sirius.diagram.ui.edit.api.part.IAbstractDiagramNodeEditPart; import org.eclipse.sirius.diagram.ui.edit.api.part.IDiagramEdgeEditPart; @@ -255,24 +256,29 @@ private String getTextFor(IDiagramElementEditPart part) { appendSequenceEventInfo(part, sb); appendBoundsDetails(part, sb); - if (part instanceof AbstractDiagramContainerEditPart && ((AbstractDiagramContainerEditPart) part).isRegionContainer()) { + if (part instanceof AbstractDiagramListEditPart) { + for (IGraphicalEditPart child : Iterables.filter(part.getChildren(), IGraphicalEditPart.class)) { + sb.append("Children bounds (" + child.getClass().getSimpleName() + "):\n"); + appendBoundsDetails(child, sb); + } + } else if (part instanceof AbstractDiagramContainerEditPart && ((AbstractDiagramContainerEditPart) part).isRegionContainer()) { IGraphicalEditPart compartment = null; for (IGraphicalEditPart child : Iterables.filter(part.getChildren(), IGraphicalEditPart.class)) { - sb.append("Children bounds:\n"); + sb.append("Children bounds (" + child.getClass().getSimpleName() + "):\n"); appendBoundsDetails(child, sb); compartment = child; } for (IGraphicalEditPart child2 : Iterables.filter(compartment.getChildren(), IGraphicalEditPart.class)) { - sb.append("Region bounds:\n"); + sb.append("Region bounds (" + child2.getClass().getSimpleName() + "):\n"); appendBoundsDetails(child2, sb); } } else if (part instanceof AbstractDiagramElementContainerEditPart && ((AbstractDiagramElementContainerEditPart) part).isRegion()) { IGraphicalEditPart parent = (IGraphicalEditPart) part.getParent(); - sb.append("Compartment bounds:\n"); + sb.append("Compartment bounds (" + parent.getClass().getSimpleName() + "):\n"); appendBoundsDetails(parent, sb); parent = (IGraphicalEditPart) parent.getParent(); - sb.append("Region Container bounds:\n"); + sb.append("Region Container bounds (" + parent.getClass().getSimpleName() + "):\n"); appendBoundsDetails(parent, sb); } else if (part instanceof InstanceRoleEditPart) { LifelineEditPart lep = Iterables.filter(part.getChildren(), LifelineEditPart.class).iterator().next(); @@ -300,10 +306,10 @@ private void appendBoundsDetails(IGraphicalEditPart part, StringBuilder sb) { sb.append("Location (GMF): Location(" + location.getX() + ", " + location.getY() + ")\n"); } - Rectangle absoluteBounds = GMFHelper.getAbsoluteBounds(node, true); + Rectangle absoluteBounds = GMFHelper.getAbsoluteBounds(node, true, false, false, false); sb.append("Bounds (GMF absolute - insets): " + absoluteBounds + "\n"); - absoluteBounds = GMFHelper.getAbsoluteBounds(node, false); + absoluteBounds = GMFHelper.getAbsoluteBounds(node, false, false, false, false); sb.append("Bounds (GMF absolute - no insets): " + absoluteBounds + "\n"); Option elt = ISequenceElementAccessor.getISequenceElement(part.getNotationView());