diff options
| author | Laurent Redor | 2015-03-25 17:36:04 +0000 |
|---|---|---|
| committer | Laurent Redor | 2015-07-06 06:50:34 +0000 |
| commit | 6c1e6980a73095c67de71c78e246582e6510095a (patch) | |
| tree | 70b9f285de1c072b9b581bdb63005b74cfdb23c2 | |
| parent | a37057c793aaa16273ca830340c7d5c655dfc399 (diff) | |
| download | org.eclipse.sirius-6c1e6980a73095c67de71c78e246582e6510095a.tar.gz org.eclipse.sirius-6c1e6980a73095c67de71c78e246582e6510095a.tar.xz org.eclipse.sirius-6c1e6980a73095c67de71c78e246582e6510095a.zip | |
[463485] Add a snap to all shapes mode
* Several edit parts have been updated to use SiriusSnapToHelperUtil
instead of SnapToHelperUtil to choose SiriusSnapToGeometry instead of
SnapToGeometryEx
* SiriusSnapToGeometry extends SnapToGeometryEx to allow to snap to all
visible shapes and not only brothers ones. It uses the snapToAll mode
from extended data of request (set by the below trackers).
* Update tracker NoCopyDragEditPartsTrackerEx to activate the mode
snapToAllShapes when shortcut is pressed.
* Update tracker SiriusResizeTracker to activate the mode
snapToAllShapes when shortcut is pressed. A specific request is used for
this tracker as we can not use the extended meta-data, as for
NoCopyDragEditPartsTrackerEx. Indeed, the meta-data is cleaned before
calling SiriusSnapToGeometry.
* Add automatic tests with zoom, scroll in diagram, scroll in container
with all kind of nodes (container, node, border nodes).
* GraphicalHelper.getAbsoluteBoundsIn100Percent has been improved
because of a lack of precision detected during tests. All similar
methods, ie using translateToAbsolute(), have been also improved.
Bug: 463485
Change-Id: Icaabf7d7d763c9cf2a283e3cab76f1ec0aa0956e
Signed-off-by: Laurent Redor <laurent.redor@obeo.fr>
33 files changed, 1718 insertions, 36 deletions
diff --git a/plugins/org.eclipse.sirius.diagram.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.diagram.ui/META-INF/MANIFEST.MF index a0c2c249f6..3904b6ea79 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.sirius.diagram.ui/META-INF/MANIFEST.MF @@ -179,6 +179,7 @@ Export-Package: org.eclipse.sirius.diagram.description.concern.provider;version= org.eclipse.sirius.diagram.ui.tools.internal.providers.decorators;x-internal:=true;version="2.0.4", org.eclipse.sirius.diagram.ui.tools.internal.resource;x-internal:=true;version="2.0.4", org.eclipse.sirius.diagram.ui.tools.internal.routers;x-internal:=true;version="2.0.4", + org.eclipse.sirius.diagram.ui.tools.internal.ruler;x-internal:=true;version="3.1.0", org.eclipse.sirius.diagram.ui.tools.internal.testers;x-internal:=true;version="2.1.0", org.eclipse.sirius.diagram.ui.tools.internal.ui;x-internal:=true;version="2.0.4", org.eclipse.sirius.diagram.ui.tools.internal.util;x-internal:=true;version="3.0.0", @@ -191,7 +192,8 @@ Bundle-ActivationPolicy: lazy Import-Package: org.eclipse.sirius.ext.base;version="2.0.0", org.eclipse.sirius.ext.draw2d.figure;version="2.0.0", org.eclipse.sirius.ext.emf;version="2.0.0", - org.eclipse.sirius.ext.emf.ui.properties, + org.eclipse.sirius.ext.emf.ui.properties;version="3.0.0", org.eclipse.sirius.ext.gef.editpolicies;version="2.0.0", + org.eclipse.sirius.ext.gef.query;version="3.1.0", org.eclipse.sirius.ext.gmf.runtime.editparts;version="2.0.0", org.eclipse.sirius.ext.swt;version="2.0.0" diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractBorderedDiagramElementEditPart.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractBorderedDiagramElementEditPart.java index 00de07ec0c..bb8b31c9c6 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractBorderedDiagramElementEditPart.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/edit/api/part/AbstractBorderedDiagramElementEditPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 THALES GLOBAL SERVICES. + * Copyright (c) 2013, 2015 THALES GLOBAL SERVICES. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,6 +14,7 @@ import java.util.List; import org.eclipse.draw2d.IFigure; import org.eclipse.emf.ecore.EObject; +import org.eclipse.gef.SnapToHelper; import org.eclipse.gef.editparts.ZoomManager; import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener; import org.eclipse.gmf.runtime.diagram.ui.editparts.AbstractBorderedShapeEditPart; @@ -24,6 +25,7 @@ import org.eclipse.sirius.diagram.ui.edit.internal.part.AbstractDiagramNodeEditP import org.eclipse.sirius.diagram.ui.edit.internal.part.DiagramElementEditPartOperation; import org.eclipse.sirius.diagram.ui.edit.internal.part.EditStatusUpdater; import org.eclipse.sirius.diagram.ui.tools.api.permission.EditPartAuthorityListener; +import org.eclipse.sirius.diagram.ui.tools.internal.ruler.SiriusSnapToHelperUtil; import org.eclipse.sirius.ecore.extender.business.api.permission.IPermissionAuthority; import org.eclipse.sirius.ecore.extender.business.api.permission.PermissionAuthorityRegistry; import org.eclipse.swt.graphics.Image; @@ -83,6 +85,7 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor * * @see org.eclipse.sirius.diagram.edit.api.part.IDiagramElementEditPart#getEAdapterDiagramElement() */ + @Override public NotificationListener getEAdapterDiagramElement() { if (this.adapterDiagramElement == null) { this.adapterDiagramElement = DiagramElementEditPartOperation.createEApdaterDiagramElement(this); @@ -93,6 +96,7 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor /** * {@inheritDoc} */ + @Override public NotificationListener getEditModeListener() { return this.editModeListener; } @@ -102,6 +106,7 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor * * @see org.eclipse.sirius.diagram.edit.api.part.IDiagramElementEditPart#getEditPartAuthorityListener() */ + @Override public EditPartAuthorityListener getEditPartAuthorityListener() { return this.authListener; } @@ -111,6 +116,7 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor * * @see org.eclipse.sirius.diagram.edit.api.part.IDiagramElementEditPart#resolveAllSemanticElements() */ + @Override public List<EObject> resolveAllSemanticElements() { return DiagramElementEditPartOperation.resolveAllSemanticElements(this); } @@ -120,6 +126,7 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor * * @see org.eclipse.sirius.diagram.edit.api.part.IDiagramElementEditPart#resolveDiagramElement() */ + @Override public DDiagramElement resolveDiagramElement() { return DiagramElementEditPartOperation.resolveDiagramElement(this); } @@ -129,6 +136,7 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor * * @see org.eclipse.sirius.diagram.edit.api.part.IDiagramElementEditPart#resolveTargetSemanticElement() */ + @Override public EObject resolveTargetSemanticElement() { return DiagramElementEditPartOperation.resolveTargetSemanticElement(this); } @@ -138,6 +146,7 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor * * @see org.eclipse.sirius.diagram.edit.api.part.IDiagramElementEditPart#getStyleEditPart() */ + @Override public IStyleEditPart getStyleEditPart() { return DiagramElementEditPartOperation.getStyleEditPart(this); } @@ -215,6 +224,7 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor * @see org.eclipse.sirius.diagram.edit.api.part.IAbstractDiagramNodeEditPart#createBorderItemLocator(IFigure, * DDiagramElement) */ + @Override public IBorderItemLocator createBorderItemLocator(final IFigure figure, final DDiagramElement vpElementBorderItem) { return AbstractDiagramNodeEditPartOperation.createBorderItemLocator(this, figure, vpElementBorderItem); } @@ -224,6 +234,7 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor * * @see org.eclipse.sirius.diagram.edit.api.part.IDiagramElementEditPart#getLabelIcon() */ + @Override public Image getLabelIcon() { return DiagramElementEditPartOperation.getLabelIcon(this); } @@ -248,6 +259,7 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor * the tooltip's text. * @since 0.9.0 */ + @Override public void setTooltipText(final String text) { AbstractDiagramNodeEditPartOperation.setTooltipText(this, text); } @@ -257,7 +269,16 @@ public abstract class AbstractBorderedDiagramElementEditPart extends AbstractBor * * @see org.eclipse.sirius.diagram.edit.api.part.IAbstractDiagramNodeEditPart#getZoomManager() */ + @Override public ZoomManager getZoomManager() { return AbstractDiagramNodeEditPartOperation.getZoomManager(this); } + + @Override + public Object getAdapter(Class key) { + if (key == SnapToHelper.class) { + return SiriusSnapToHelperUtil.getSnapHelper(this); + } + return super.getAdapter(key); + } } diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/SiriusResizeTracker.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/SiriusResizeTracker.java index 460c6c0bb1..4f4ff5ebeb 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/SiriusResizeTracker.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/SiriusResizeTracker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014 THALES GLOBAL SERVICES. + * Copyright (c) 2014, 2015 THALES GLOBAL SERVICES. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,7 +11,10 @@ package org.eclipse.sirius.diagram.ui.graphical.edit.policies; import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gef.Request; +import org.eclipse.gef.requests.ChangeBoundsRequest; import org.eclipse.gef.tools.ResizeTracker; +import org.eclipse.sirius.diagram.ui.tools.internal.ui.NoCopyDragEditPartsTrackerEx; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; @@ -55,6 +58,16 @@ public class SiriusResizeTracker extends ResizeTracker { boolean childrenMoveMode = DEFAULT_CHILDREN_MOVE_MODE; /** + * The mode of this tracker concerning the snap to shape: + * <UL> + * <LI>true to snap to all shapes and not only brothers ones,</LI> + * <LI>false otherwise.</LI> + * </UL> + * This variable is used to update the request. + */ + boolean snapToAllShape = NoCopyDragEditPartsTrackerEx.DEFAULT_SNAP_TO_SHAPE_MODE; + + /** * Default constructor. * * @param owner @@ -67,19 +80,43 @@ public class SiriusResizeTracker extends ResizeTracker { } @Override + protected Request createSourceRequest() { + ChangeBoundsRequest request; + // Create a specific request (see javadoc of SnapChangeBoundsRequest for + // more details). + request = new SnapChangeBoundsRequest(REQ_RESIZE); + request.setResizeDirection(getResizeDirection()); + return request; + } + + @Override protected boolean handleKeyDown(KeyEvent event) { + boolean keyHandled = false; if (SiriusResizeTracker.CHILDREN_MOVE_MODE_SHORTCUT_KEY == event.keyCode) { childrenMoveMode = !SiriusResizeTracker.DEFAULT_CHILDREN_MOVE_MODE; - return true; + keyHandled = true; + } else if (NoCopyDragEditPartsTrackerEx.SNAP_TO_ALL == event.keyCode) { + snapToAllShape = !NoCopyDragEditPartsTrackerEx.DEFAULT_SNAP_TO_SHAPE_MODE; + keyHandled = true; + } + if (keyHandled) { + return keyHandled; } return super.handleKeyDown(event); } @Override protected boolean handleKeyUp(KeyEvent event) { + boolean keyHandled = false; if (SiriusResizeTracker.CHILDREN_MOVE_MODE_SHORTCUT_KEY == event.keyCode) { childrenMoveMode = SiriusResizeTracker.DEFAULT_CHILDREN_MOVE_MODE; - return true; + keyHandled = true; + } else if (NoCopyDragEditPartsTrackerEx.SNAP_TO_ALL == event.keyCode) { + snapToAllShape = NoCopyDragEditPartsTrackerEx.DEFAULT_SNAP_TO_SHAPE_MODE; + keyHandled = true; + } + if (keyHandled) { + return keyHandled; } return super.handleKeyUp(event); } @@ -87,11 +124,19 @@ public class SiriusResizeTracker extends ResizeTracker { /** * Set {@link CHILDREN_MOVE_MODE_KEY} extended data after update of request * (the extended data are cleaned during the - * {@link ResizeTracker#updateSourceRequest()}). + * {@link ResizeTracker#updateSourceRequest()}). Also update the request + * with information about snapToAll mode. */ @SuppressWarnings("unchecked") @Override protected void updateSourceRequest() { + if (getSourceRequest() instanceof SnapChangeBoundsRequest) { + if (snapToAllShape) { + ((SnapChangeBoundsRequest) getSourceRequest()).setSnapToAllShape(true); + } else { + ((SnapChangeBoundsRequest) getSourceRequest()).setSnapToAllShape(false); + } + } super.updateSourceRequest(); if (childrenMoveMode) { getSourceRequest().getExtendedData().put(SiriusResizeTracker.CHILDREN_MOVE_MODE_KEY, Boolean.TRUE); @@ -110,7 +155,9 @@ public class SiriusResizeTracker extends ResizeTracker { @Override protected boolean handleButtonUp(int button) { boolean result = super.handleButtonUp(button); + // Clean up the mode to original state. childrenMoveMode = SiriusResizeTracker.DEFAULT_CHILDREN_MOVE_MODE; + snapToAllShape = NoCopyDragEditPartsTrackerEx.DEFAULT_SNAP_TO_SHAPE_MODE; return result; } } diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/SnapChangeBoundsRequest.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/SnapChangeBoundsRequest.java new file mode 100644 index 0000000000..a2d181c5c5 --- /dev/null +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/SnapChangeBoundsRequest.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2015 THALES GLOBAL SERVICES. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.diagram.ui.graphical.edit.policies; + +import org.eclipse.gef.requests.ChangeBoundsRequest; +import org.eclipse.sirius.diagram.ui.tools.internal.ui.NoCopyDragEditPartsTrackerEx; + +/** + * A ChangeBoundsRequest with a specific data concerning the snapToAll feature. + * The {@link org.eclipse.gef.tools.ResizeTracker} does not allow to use the + * extendedMetaData of the Request because it is clean before it can be used in + * the {@link org.eclipse.gef.SnapToGeometry}. + * + * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> + */ +public class SnapChangeBoundsRequest extends ChangeBoundsRequest { + /** + * Reflect the mode of the tracker concerning the snap to shape: + * <UL> + * <LI>true to snap to all shapes and not only brothers ones,</LI> + * <LI>false otherwise.</LI> + * </UL> + */ + boolean snapToAllShape = NoCopyDragEditPartsTrackerEx.DEFAULT_SNAP_TO_SHAPE_MODE; + + /** + * Creates a ChangeBoundsRequest with the given type. + * + * @param type + * The type of Request. + */ + public SnapChangeBoundsRequest(Object type) { + super(type); + } + + /** + * Return true if the snap to all shape mode is activated, false otherwise. + * + * @return the snapToAllShape status + */ + public boolean isSnapToAllShape() { + return snapToAllShape; + } + + /** + * Activate or deactivate the snap to all shape mode. + * + * @param snapToAllShape + * the snapToAllShape to set + */ + public void setSnapToAllShape(boolean snapToAllShape) { + this.snapToAllShape = snapToAllShape; + } +} 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 19040919bb..7e0cb0bc4c 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 @@ -32,6 +32,7 @@ import org.eclipse.gef.DragTracker; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.Request; +import org.eclipse.gef.SnapToHelper; import org.eclipse.gef.commands.Command; import org.eclipse.gef.requests.CreateConnectionRequest; import org.eclipse.gef.requests.ReconnectRequest; @@ -73,6 +74,7 @@ import org.eclipse.sirius.diagram.ui.tools.api.figure.ViewNodeContainerFigureDes import org.eclipse.sirius.diagram.ui.tools.api.requests.RequestConstants; import org.eclipse.sirius.diagram.ui.tools.internal.figure.LabelBorderStyleIds; import org.eclipse.sirius.diagram.ui.tools.internal.graphical.edit.policies.ContainerCompartmentNodeEditPolicy; +import org.eclipse.sirius.diagram.ui.tools.internal.ruler.SiriusSnapToHelperUtil; import org.eclipse.sirius.ext.base.Option; import org.eclipse.sirius.ext.base.Options; import org.eclipse.sirius.ext.gef.editpolicies.SiriusSnapFeedbackPolicy; @@ -549,4 +551,12 @@ public abstract class AbstractDNodeContainerCompartmentEditPart extends ShapeCom return bounds; } }; + + @Override + public Object getAdapter(Class key) { + if (key == SnapToHelper.class) { + return SiriusSnapToHelperUtil.getSnapHelper(this); + } + return super.getAdapter(key); + } } diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/DDiagramEditPart.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/DDiagramEditPart.java index 2872bbe630..a18978a4e3 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/DDiagramEditPart.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/DDiagramEditPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 THALES GLOBAL SERVICES. + * Copyright (c) 2007, 2015 THALES GLOBAL SERVICES. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,6 +12,7 @@ package org.eclipse.sirius.diagram.ui.internal.edit.parts; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.SnapToHelper; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.gmf.runtime.notation.View; @@ -31,6 +32,7 @@ import org.eclipse.sirius.diagram.ui.internal.edit.policies.DDiagramItemSemantic import org.eclipse.sirius.diagram.ui.internal.edit.policies.canonicals.DumnySiriusCanonicalConnectionEditPolicy; import org.eclipse.sirius.diagram.ui.tools.api.policy.CompoundEditPolicy; import org.eclipse.sirius.diagram.ui.tools.api.requests.RequestConstants; +import org.eclipse.sirius.diagram.ui.tools.internal.ruler.SiriusSnapToHelperUtil; import org.eclipse.sirius.tools.api.command.SiriusCommand; /** @@ -48,6 +50,7 @@ public class DDiagramEditPart extends AbstractDDiagramEditPart { */ public static final int VISUAL_ID = 1000; + @Override protected void refreshBackgroundColor() { super.refreshBackgroundColor(); }; @@ -62,6 +65,7 @@ public class DDiagramEditPart extends AbstractDDiagramEditPart { /** * @not-generated add the compound edit policy */ + @Override protected void createDefaultEditPolicies() { super.createDefaultEditPolicies(); installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new DDiagramItemSemanticEditPolicy()); @@ -168,4 +172,11 @@ public class DDiagramEditPart extends AbstractDDiagramEditPart { } + @Override + public Object getAdapter(Class key) { + if (key == SnapToHelper.class) { + return SiriusSnapToHelperUtil.getSnapHelper(this); + } + return super.getAdapter(key); + } } diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/ruler/SiriusSnapToGeometry.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/ruler/SiriusSnapToGeometry.java new file mode 100644 index 0000000000..c1bb672c86 --- /dev/null +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/ruler/SiriusSnapToGeometry.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2015 THALES GLOBAL SERVICES. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.diagram.ui.tools.internal.ruler; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.draw2d.geometry.PrecisionRectangle; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gef.Request; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; +import org.eclipse.gmf.runtime.diagram.ui.internal.ruler.SnapToGeometryEx; +import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractBorderedDiagramElementEditPart; +import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramBorderNodeEditPart; +import org.eclipse.sirius.diagram.ui.graphical.edit.policies.SnapChangeBoundsRequest; +import org.eclipse.sirius.diagram.ui.tools.internal.ui.NoCopyDragEditPartsTrackerEx; +import org.eclipse.sirius.ext.gef.query.EditPartQuery; +import org.eclipse.sirius.ext.gmf.runtime.editparts.GraphicalHelper; + +import com.google.common.collect.Lists; + +/** + * Overridden to support all visible shapes in SnapToShape and not only brothers + * ones. See {@link NoCopyDragEditPartsTrackerEx#SNAP_TO_ALL_SHAPE_KEY}. + * + * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> + */ +public class SiriusSnapToGeometry extends SnapToGeometryEx { + + boolean snapToAll; + + /** + * A vertical or horizontal snapping point.<BR> + * Only overridden to have access to constructor. + */ + class SiriusEntry extends Entry { + protected SiriusEntry(int type, int location) { + super(type, location); + } + } + + /** + * Default constructor. + * + * @param container + * the container editpart + */ + public SiriusSnapToGeometry(GraphicalEditPart container) { + super(container); + } + + @Override + public int snapRectangle(Request request, int snapOrientation, PrecisionRectangle baseRect, PrecisionRectangle result) { + // Get snapToAll mode from request (set by the + // SiriusDragEditPartsTrackerEx or by the SiriusResizeTracker) + Object snapToAllExtendedData = request.getExtendedData().get(NoCopyDragEditPartsTrackerEx.SNAP_TO_ALL_SHAPE_KEY); + boolean oldSnapToAll = snapToAll; + snapToAll = (snapToAllExtendedData == null && NoCopyDragEditPartsTrackerEx.DEFAULT_SNAP_TO_SHAPE_MODE) || (snapToAllExtendedData != null && ((Boolean) snapToAllExtendedData).booleanValue()); + if (!snapToAll && request instanceof SnapChangeBoundsRequest) { + snapToAll = ((SnapChangeBoundsRequest) request).isSnapToAllShape(); + } + + if (oldSnapToAll != snapToAll) { + // Reset previous computed horizontal rows and vertical column + // being snapped to. + rows = null; + cols = null; + } + + return super.snapRectangle(request, snapOrientation, baseRect, result); + } + + @Override + protected List generateSnapPartsList(List exclusions) { + if (!snapToAll) { + return super.generateSnapPartsList(exclusions); + } else { + // Get all potential snap targets + List<Class<?>> expectedClasses = Lists.newArrayList(); + expectedClasses.add(AbstractBorderedDiagramElementEditPart.class); + expectedClasses.add(AbstractDiagramBorderNodeEditPart.class); + List<EditPart> snapPartsList = new ArrayList<EditPart>(new EditPartQuery(container.getRoot()).getAllChildren(false, expectedClasses)); + // Add children of elements that are being dragged + List<EditPart> exclusionsWithChildren = new ArrayList<EditPart>(); + for (Object editPart : exclusions) { + if (editPart instanceof EditPart) { + exclusionsWithChildren.add((EditPart) editPart); + exclusionsWithChildren.addAll(new EditPartQuery((EditPart) editPart).getAllChildren(false, expectedClasses)); + } + } + // Don't snap to any figure that is being dragged + snapPartsList.removeAll(exclusionsWithChildren); + + // Don't snap to hidden figures (not visible for end-user) + for (Iterator<EditPart> iter = snapPartsList.iterator(); iter.hasNext(); /* */) { + EditPart snapPart = iter.next(); + if (snapPart instanceof IGraphicalEditPart && !new org.eclipse.sirius.diagram.ui.tools.internal.util.EditPartQuery((IGraphicalEditPart) snapPart).isVisibleOnViewport()) { + iter.remove(); + } + } + + return snapPartsList; + } + + } + + @Override + protected void populateRowsAndCols(List parts) { + if (!snapToAll) { + super.populateRowsAndCols(parts); + } else { + rows = new Entry[parts.size() * 3]; + cols = new Entry[parts.size() * 3]; + for (int i = 0; i < parts.size(); i++) { + IGraphicalEditPart child = (IGraphicalEditPart) parts.get(i); + Rectangle bounds = GraphicalHelper.getAbsoluteBounds(child); + makeRelative(container.getContentPane(), bounds); + cols[i * 3] = new SiriusEntry(-1, bounds.x); + rows[i * 3] = new SiriusEntry(-1, bounds.y); + cols[i * 3 + 1] = new SiriusEntry(0, bounds.x + (bounds.width - 1) / 2); + rows[i * 3 + 1] = new SiriusEntry(0, bounds.y + (bounds.height - 1) / 2); + cols[i * 3 + 2] = new SiriusEntry(1, bounds.right() - 1); + rows[i * 3 + 2] = new SiriusEntry(1, bounds.bottom() - 1); + } + } + } +} diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/ruler/SiriusSnapToHelperUtil.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/ruler/SiriusSnapToHelperUtil.java new file mode 100644 index 0000000000..e9d07512e6 --- /dev/null +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/ruler/SiriusSnapToHelperUtil.java @@ -0,0 +1,95 @@ +/****************************************************************************** + * Copyright (c) 2007, 2015 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + ****************************************************************************/ +package org.eclipse.sirius.diagram.ui.tools.internal.ruler; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.gef.EditPartViewer; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gef.SnapToGeometry; +import org.eclipse.gef.SnapToGrid; +import org.eclipse.gef.SnapToHelper; +import org.eclipse.gef.rulers.RulerProvider; +import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; +import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.ISurfaceEditPart; +import org.eclipse.gmf.runtime.diagram.ui.internal.ruler.CompoundSnapToHelperEx; +import org.eclipse.gmf.runtime.diagram.ui.internal.ruler.SnapToGridEx; +import org.eclipse.gmf.runtime.diagram.ui.internal.ruler.SnapToGuidesEx; +import org.eclipse.gmf.runtime.diagram.ui.internal.ruler.SnapToHelperUtil; + +/** + * Utility class for the snapping behavior. This class adds the capability to + * snap to all visible figures. + * + * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> + */ +public class SiriusSnapToHelperUtil extends SnapToHelperUtil { + // CHECKSTYLE:OFF Method duplicate from SnapToHelperUtil and not formatted + // to facilitate comparison. + /** + * returns the the appropriate snap helper(s), this method will always reach + * for the first reachable DiagramEditPart using the passed edit part, then + * use this Diagram edit part to get the snap helper + * + * @param editPart + * , edit part to get the snap helper for + * @return + */ + static public Object getSnapHelper(GraphicalEditPart editPart) { + // get the diagram Edit Part + GraphicalEditPart diagramEditPart = editPart; + while (diagramEditPart != null && !(diagramEditPart instanceof DiagramEditPart)) { + diagramEditPart = (GraphicalEditPart) diagramEditPart.getParent(); + } + + if (diagramEditPart == null) + return null; + + // for snap to geometry, attempt to locate a compartment as a parent + GraphicalEditPart parent = editPart; + while (parent != null && !(parent instanceof ISurfaceEditPart)) { + parent = (GraphicalEditPart) parent.getParent(); + } + + if (parent == null) + parent = diagramEditPart; + + List<SnapToHelper> snapStrategies = new ArrayList<SnapToHelper>(); + EditPartViewer viewer = diagramEditPart.getViewer(); + + Boolean val = (Boolean) editPart.getViewer().getProperty(RulerProvider.PROPERTY_RULER_VISIBILITY); + + if (val != null && val.booleanValue()) + snapStrategies.add(new SnapToGuidesEx(diagramEditPart)); + + val = (Boolean) viewer.getProperty(SnapToGeometry.PROPERTY_SNAP_ENABLED); + if (val != null && val.booleanValue()) + snapStrategies.add(new SiriusSnapToGeometry(parent)); + + val = (Boolean) viewer.getProperty(SnapToGrid.PROPERTY_GRID_ENABLED); + + if (val != null && val.booleanValue()) + snapStrategies.add(new SnapToGridEx(diagramEditPart)); + + if (snapStrategies.size() == 0) + return null; + + if (snapStrategies.size() == 1) + return snapStrategies.get(0); + + SnapToHelper ss[] = new SnapToHelper[snapStrategies.size()]; + for (int i = 0; i < snapStrategies.size(); i++) + ss[i] = snapStrategies.get(i); + return new CompoundSnapToHelperEx(ss); + } + // CHECKSTYLE:ON +} diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/ui/NoCopyDragEditPartsTrackerEx.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/ui/NoCopyDragEditPartsTrackerEx.java index 85335ba7ba..84cdfc0a84 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/ui/NoCopyDragEditPartsTrackerEx.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/ui/NoCopyDragEditPartsTrackerEx.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011 THALES GLOBAL SERVICES. + * Copyright (c) 2011, 2015 THALES GLOBAL SERVICES. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,12 +11,18 @@ package org.eclipse.sirius.diagram.ui.tools.internal.ui; import org.eclipse.gef.EditPart; +import org.eclipse.gef.requests.ChangeBoundsRequest; import org.eclipse.gmf.runtime.diagram.ui.tools.DragEditPartsTrackerEx; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; /** * A specific dragEditPartTracket that disable the clone feature. Indeed, in - * Sirius it's not natural to clone a graphical element that will be removed - * on the next refresh. + * Sirius it's not natural to clone a graphical element that will be removed on + * the next refresh. + * + * This tracker also allows to change the behavior of SnapToShape (capability to + * snap to all shapes and not only brothers one). * * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> * @@ -24,6 +30,33 @@ import org.eclipse.gmf.runtime.diagram.ui.tools.DragEditPartsTrackerEx; public class NoCopyDragEditPartsTrackerEx extends DragEditPartsTrackerEx { /** + * Constant passed to extended data of the request to keep the chosen mode + * (with KEY {@link #SNAP_TO_ALL}. + */ + public static final String SNAP_TO_ALL_SHAPE_KEY = "snapToAllShape"; + + /** + * The default mode for {@link #snapToAllShape}. + */ + public static final boolean DEFAULT_SNAP_TO_SHAPE_MODE = false; + + /** + * The key shortcut used to change the default behavior of snap to shape. + */ + public static final int SNAP_TO_ALL = SWT.F4; + + /** + * The mode of this tracker concerning the snap to shape: + * <UL> + * <LI>true to snap to all shapes and not only brothers ones,</LI> + * <LI>false otherwise.</LI> + * </UL> + * This variable is used when the request is updated to add an extended data + * to the request. + */ + boolean snapToAllShape = NoCopyDragEditPartsTrackerEx.DEFAULT_SNAP_TO_SHAPE_MODE; + + /** * Defaul constructor. * * @param sourceEditPart @@ -48,7 +81,6 @@ public class NoCopyDragEditPartsTrackerEx extends DragEditPartsTrackerEx { /* * (non-Javadoc) - * * @see * org.eclipse.gmf.runtime.diagram.ui.tools.DragEditPartsTrackerEx#reveal * (org.eclipse.gef.EditPart) @@ -63,4 +95,46 @@ public class NoCopyDragEditPartsTrackerEx extends DragEditPartsTrackerEx { super.reveal(editpart); } } + + /** + * Overridden to update the {@link ChangeBoundsRequest} with information + * about snapToAll mode. + * + * {@inheritDoc} + */ + @Override + protected void snapPoint(ChangeBoundsRequest request) { + if (snapToAllShape) { + getTargetRequest().getExtendedData().put(NoCopyDragEditPartsTrackerEx.SNAP_TO_ALL_SHAPE_KEY, Boolean.TRUE); + } else { + getTargetRequest().getExtendedData().put(NoCopyDragEditPartsTrackerEx.SNAP_TO_ALL_SHAPE_KEY, Boolean.FALSE); + } + super.snapPoint(request); + } + + @Override + protected boolean handleKeyDown(KeyEvent event) { + if (NoCopyDragEditPartsTrackerEx.SNAP_TO_ALL == event.keyCode) { + snapToAllShape = !NoCopyDragEditPartsTrackerEx.DEFAULT_SNAP_TO_SHAPE_MODE; + return true; + } + return super.handleKeyDown(event); + } + + @Override + protected boolean handleKeyUp(KeyEvent event) { + if (NoCopyDragEditPartsTrackerEx.SNAP_TO_ALL == event.keyCode) { + snapToAllShape = NoCopyDragEditPartsTrackerEx.DEFAULT_SNAP_TO_SHAPE_MODE; + return true; + } + return super.handleKeyUp(event); + } + + @Override + protected boolean handleButtonUp(int button) { + boolean result = super.handleButtonUp(button); + // Clean up the mode to original state. + snapToAllShape = NoCopyDragEditPartsTrackerEx.DEFAULT_SNAP_TO_SHAPE_MODE; + return result; + } } diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/util/EditPartQuery.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/util/EditPartQuery.java index 24c6e4a5e3..179366205b 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/util/EditPartQuery.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/util/EditPartQuery.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 THALES GLOBAL SERVICES. + * Copyright (c) 2010, 2015 THALES GLOBAL SERVICES. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -17,8 +17,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.eclipse.draw2d.FigureCanvas; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.Viewport; +import org.eclipse.draw2d.ViewportUtilities; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.emf.ecore.EObject; @@ -147,6 +150,7 @@ public class EditPartQuery { public List<IBorderItemEditPart> getBorderNodeEditParts(final int expectedSide) { if (part instanceof IBorderedShapeEditPart) { Iterable<IBorderItemEditPart> bordersItemPart = Iterables.filter(part.getChildren(), Predicates.and(Predicates.instanceOf(IBorderItemEditPart.class), new Predicate<IBorderItemEditPart>() { + @Override public boolean apply(IBorderItemEditPart input) { int currentSide = input.getBorderItemLocator().getCurrentSideOfParent(); return expectedSide == currentSide; @@ -226,6 +230,90 @@ public class EditPartQuery { } /** + * Return true if the figure of the current part is currently visible (by + * the end-user), false otherwise. + * + * @return true if the figure of the current part is currently visible (by + * the end-user), false otherwise. + */ + @SuppressWarnings("unchecked") + public boolean isVisibleOnViewport() { + // Traverse the viewport path of the figure (and reduce clipRect + // to what is actually visible); process all viewports up to the + // root viewport + Viewport topViewport = ((FigureCanvas) part.getViewer().getControl()).getViewport(); + IFigure figure = part.getFigure(); + Viewport nearestEnclosingViewport = ViewportUtilities.getNearestEnclosingViewport(figure); + List<Viewport> enclosingViewportsPath; + if (topViewport.equals(nearestEnclosingViewport)) { + enclosingViewportsPath = Lists.newArrayList(topViewport); + } else { + enclosingViewportsPath = ViewportUtilities.getViewportsPath(nearestEnclosingViewport, topViewport, true); + } + Rectangle clipRect = getAbsoluteBoundsAsCopy(figure); + clipAtViewports(clipRect, enclosingViewportsPath); + return !clipRect.isEmpty(); + } + + /** + * Clips the given clipRect at all given viewports. Method copied from + * {@link org.eclipse.draw2d.ViewportAwareConnectionLayerClippingStrategy}. + * + * @param clipRect + * Rectangle to clip + * @param enclosingViewportsPath + * All viewports to use to clip + */ + protected void clipAtViewports(Rectangle clipRect, List<Viewport> enclosingViewportsPath) { + for (Viewport viewport : enclosingViewportsPath) { + clipRect.intersect(getAbsoluteViewportAreaAsCopy(viewport)); + } + } + + /** + * Returns the area covered by the viewport in absolute coordinates. Method + * copied from + * {@link org.eclipse.draw2d.ViewportAwareConnectionLayerClippingStrategy}. + * + * @param viewport + * Concerned Viewport + * @return the area covered by the viewport in absolute coordinates. + */ + protected Rectangle getAbsoluteViewportAreaAsCopy(Viewport viewport) { + return getAbsoluteClientAreaAsCopy(viewport); + } + + /** + * Returns the viewport's client area in absolute coordinates. Method copied + * from + * {@link org.eclipse.draw2d.ViewportAwareConnectionLayerClippingStrategy}. + * + * @param figure + * Concerned figure + * @return a copy of the client area of this figure + */ + protected Rectangle getAbsoluteClientAreaAsCopy(IFigure figure) { + Rectangle absoluteClientArea = figure.getClientArea(); + figure.translateToParent(absoluteClientArea); + figure.translateToAbsolute(absoluteClientArea); + return absoluteClientArea; + } + + /** + * Returns the figure's bounds in absolute coordinates. Method copied from + * {@link org.eclipse.draw2d.ViewportAwareConnectionLayerClippingStrategy}. + * + * @param figure + * Concerned figure + * @return the figure's bounds in absolute coordinates + */ + protected Rectangle getAbsoluteBoundsAsCopy(IFigure figure) { + Rectangle absoluteFigureBounds = figure.getBounds().getCopy(); + figure.translateToAbsolute(absoluteFigureBounds); + return absoluteFigureBounds; + } + + /** * Check that the container of the <code>part</code> is layouted with * "FreeForm" style. * @@ -331,8 +419,8 @@ public class EditPartQuery { expectedNewBounds = borderItemLocator.getValidLocation(expectedNewBounds, borderItemEditPart.getFigure()); } if (PositionConstants.NORTH == resizedSide) { - shiftingAccordingToBorderItemLocator.put((Node) borderItemEditPart.getModel(), new Dimension(expectedNewBounds.x - currentBounds.x, expectedNewBounds.y - currentBounds.y - + parentResizeSize)); + shiftingAccordingToBorderItemLocator.put((Node) borderItemEditPart.getModel(), + new Dimension(expectedNewBounds.x - currentBounds.x, expectedNewBounds.y - currentBounds.y + parentResizeSize)); } else { shiftingAccordingToBorderItemLocator.put((Node) borderItemEditPart.getModel(), new Dimension(expectedNewBounds.x - currentBounds.x, expectedNewBounds.y - currentBounds.y)); } @@ -429,8 +517,8 @@ public class EditPartQuery { expectedNewBounds = borderItemLocator.getValidLocation(expectedNewBounds, borderItemEditPart.getFigure()); } if (PositionConstants.WEST == resizedSide) { - shiftingAccordingToBorderItemLocator.put((Node) borderItemEditPart.getModel(), new Dimension(expectedNewBounds.x - currentBounds.x + parentResizeSize, expectedNewBounds.y - - currentBounds.y)); + shiftingAccordingToBorderItemLocator.put((Node) borderItemEditPart.getModel(), + new Dimension(expectedNewBounds.x - currentBounds.x + parentResizeSize, expectedNewBounds.y - currentBounds.y)); } else { shiftingAccordingToBorderItemLocator.put((Node) borderItemEditPart.getModel(), new Dimension(expectedNewBounds.x - currentBounds.x, expectedNewBounds.y - currentBounds.y)); } @@ -469,6 +557,7 @@ public class EditPartQuery { if (PositionConstants.NORTH == resizedSide) { // Smaller y in first getValueToCompareFunction = new Function<IBorderItemEditPart, Integer>() { + @Override public Integer apply(IBorderItemEditPart from) { Node node = (Node) from.getModel(); if (node.getLayoutConstraint() instanceof Bounds) { @@ -481,6 +570,7 @@ public class EditPartQuery { } else if (PositionConstants.SOUTH == resizedSide) { // Greater (y+height) in first getValueToCompareFunction = new Function<IBorderItemEditPart, Integer>() { + @Override public Integer apply(IBorderItemEditPart from) { Node node = (Node) from.getModel(); if (node.getLayoutConstraint() instanceof Bounds) { @@ -493,6 +583,7 @@ public class EditPartQuery { } else if (PositionConstants.EAST == resizedSide) { // Greater (x+width) in first getValueToCompareFunction = new Function<IBorderItemEditPart, Integer>() { + @Override public Integer apply(IBorderItemEditPart from) { Node node = (Node) from.getModel(); if (node.getLayoutConstraint() instanceof Bounds) { @@ -505,6 +596,7 @@ public class EditPartQuery { } else { // Smaller x in first getValueToCompareFunction = new Function<IBorderItemEditPart, Integer>() { + @Override public Integer apply(IBorderItemEditPart from) { Node node = (Node) from.getModel(); if (node.getLayoutConstraint() instanceof Bounds) { diff --git a/plugins/org.eclipse.sirius.doc/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.sirius.doc/.settings/org.eclipse.core.resources.prefs index 2627c83efb..f30aa98400 100644 --- a/plugins/org.eclipse.sirius.doc/.settings/org.eclipse.core.resources.prefs +++ b/plugins/org.eclipse.sirius.doc/.settings/org.eclipse.core.resources.prefs @@ -6,11 +6,11 @@ encoding//doc/specifier/general/Colors.html=utf-8 encoding//doc/specifier/general/Introduction.html=utf-8 encoding//doc/specifier/general/Model_Operations.html=utf-8 encoding//doc/specifier/general/Writing_Queries.html=utf-8 +encoding//specs/accepted/463485_snapToAllShapes/463485.html=utf-8 encoding//specs/archived/435507_SnapToGridForCreation/435507.html=utf-8 encoding//specs/archived/437097-moveEdgeClosestSegmentWhenMovingNode/437097-moveEdgeClosestSegmentWhenMovingNode.html=utf-8 encoding//specs/archived/441090_ResizeNodeWithoutModifyingContainedElementsLocation/441090.html=utf-8 encoding//specs/archived/442289_DistributeShapesActions/442289_DistributeShapesActions.html=utf-8 -encoding//specs/proposal/463485_snapToAllShapes/463485.html=utf-8 encoding//specs/proposal/464269_selectElementsAfterToolExecution/464269.html=utf-8 encoding//specs/proposal/465328_edgeLabelLocation/465328.html=utf-8 encoding//specs/proposal/471104_edgeAndPortsCompoundMoves/471104.html=utf-8 diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html index 44a180c3e1..8e70782444 100644 --- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html +++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html @@ -16,6 +16,9 @@ <a href="#sirius3.1.0">Changes in Sirius 3.1.0</a> <ol style="list-style: disc;"> <li> + <a href="#UserVisibleChanges">User-Visible Changes</a> + </li> + <li> <a href="#DeveloperVisibleChanges">Developer-Visible Changes</a> </li> </ol> @@ -24,7 +27,7 @@ <a href="#sirius3.0.0">Changes in Sirius 3.0.0</a> <ol style="list-style: disc;"> <li> - <a href="#UserVisibleChanges">User-Visible Changes</a> + <a href="#UserVisibleChanges2">User-Visible Changes</a> </li> <li> <a href="#SpecifierVisibleChanges">Specifier-Visible Changes</a> @@ -38,7 +41,7 @@ <a href="#sirius2.0.0">Changes in Sirius 2.0.0</a> <ol style="list-style: disc;"> <li> - <a href="#UserVisibleChanges2">User-Visible Changes</a> + <a href="#UserVisibleChanges3">User-Visible Changes</a> </li> <li> <a href="#SpecifierVisibleChanges2">Specifier-Visible Changes</a> @@ -55,7 +58,21 @@ <a href="Release_Notes_Previous.html">the release notes from previous versions</a> for details about older releases. </p> <h2 id="sirius3.1.0">Changes in Sirius 3.1.0</h2> + <h3 id="UserVisibleChanges">User-Visible Changes</h3> + <ul> + <li><span class="label label-success">Added</span> A new feature allows to snap to all shapes (instead of just to snap to brother shapes). The <kdb>F4</kdb> shortcut key activates this mode when you resize a node, move a node or move a bendpoint of edge, see + <a href="./user/diagrams/Diagrams.html#snap_to_shapes">documentation</a> for details. + </li> + </ul> <h3 id="DeveloperVisibleChanges">Developer-Visible Changes</h3> + <h4 id="Changesinorg.eclipse.sirius.ext.gef">Changes in + <code>org.eclipse.sirius.ext.gef</code> + </h4> + <ul> + <li><span class="label label-success">Added</span> The new class + <code>org.eclipse.sirius.ext.gef.query.EditPartQuery</code> has been added. It allows to retrieve all children of the current part. + </li> + </ul> <h4 id="Changesinorg.eclipse.sirius.tests.swtbot.support">Changes in <code>org.eclipse.sirius.tests.swtbot.support</code> </h4> @@ -76,9 +93,12 @@ <code>drag(int, int, int, int)</code> method, to precise the key code to press during the drag’n’drop. It is possible to call this method with SWT.None to retrieve the standard behavior of <code>drag</code> method. This method also has a correct behavior for the move of bendpoints of edges. </li> + <li><span class="label label-success">Added</span> + <code>org.eclipse.sirius.tests.swtbot.support.api.condition.TopCondition</code>: New condition to wait that top of the edit part is on the expected location. + </li> </ul> <h2 id="sirius3.0.0">Changes in Sirius 3.0.0</h2> - <h3 id="UserVisibleChanges">User-Visible Changes</h3> + <h3 id="UserVisibleChanges2">User-Visible Changes</h3> <ul> <li><span class="label label-success">Added</span> The ability to print table representations has been re-introduced.</li> <li><span class="label label-success">Added</span> The quick outline feature has been added for tree and table editors, see documentation for details.</li> @@ -1021,7 +1041,7 @@ <code>org.eclipse.sirius.xxx.ui.ext</code>, allowing them not have all that functionalities they may not want. </p> <h2 id="sirius2.0.0">Changes in Sirius 2.0.0</h2> - <h3 id="UserVisibleChanges2">User-Visible Changes</h3> + <h3 id="UserVisibleChanges3">User-Visible Changes</h3> <ul> <li>It is now possible to select element that intersects the selection rectangle and not that is completely contained by the selection rectangle. This new behavior is enabled when user selects elements from right to left. The normal mode (previous mode) remains when the user selects elements from left to right.</li> <li>The edges appearance is now kept, as much as possible, when one of its extremity is moved. A move of an extremity should move only the closest segment of the edge.</li> diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile index b51b58b4d1..1f43fc6ed7 100644 --- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile +++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile @@ -6,13 +6,23 @@ This document contains the release notes for recent major releases of Sirius. Se h2(#sirius3.1.0). Changes in Sirius 3.1.0 +h3. User-Visible Changes + +* <span class="label label-success">Added</span> A new feature allows to snap to all shapes (instead of just to snap to brother shapes). The <kdb>F4</kdb> shortcut key activates this mode when you resize a node, move a node or move a bendpoint of edge, see "documentation":./user/diagrams/Diagrams.html#snap_to_shapes for details. + h3. Developer-Visible Changes +h4. Changes in @org.eclipse.sirius.ext.gef@ + +* <span class="label label-success">Added</span> The new class @org.eclipse.sirius.ext.gef.query.EditPartQuery@ has been added. It allows to retrieve all children of the current part. + h4. Changes in @org.eclipse.sirius.tests.swtbot.support@ * <span class="label label-success">Added</span> The methods @closePerspective(String)@, @closeSiriusPerspective()@ and @closeModelingPerspective()@ have been added in class @org.eclipse.sirius.tests.swtbot.support.api.perspective.DesignerPerspectives@ to allow the closing of perspectives. * <span class="label label-success">Added</span> The @org.eclipse.sirius.tests.swtbot.support.api.condition.PerspectiveActivatedCondition@ new offers the capability to inverse the test. This condition becomes a DeactivatedCondition instead of an ActivatedCondition by using the new constructor with inverse parameter. * <span class="label label-success">Added</span> The method @org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotSiriusDiagramEditor.dragWithKey(int, int, int, int, int)@, and so @SWTBotSiriusGefViewer.dragWithKey@ and @SWTBotSiriusFigureCanvas.mouseDragWithKey@), has an additional parameter, compared to @drag(int, int, int, int)@ method, to precise the key code to press during the drag'n'drop. It is possible to call this method with SWT.None to retrieve the standard behavior of @drag@ method. This method also has a correct behavior for the move of bendpoints of edges. +* <span class="label label-success">Added</span> @org.eclipse.sirius.tests.swtbot.support.api.condition.TopCondition@: New condition to wait that top of the edit part is on the expected location. + h2(#sirius3.0.0). Changes in Sirius 3.0.0 diff --git a/plugins/org.eclipse.sirius.doc/doc/user/diagrams/Diagrams.html b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/Diagrams.html index 18f578947d..9a58eae756 100644 --- a/plugins/org.eclipse.sirius.doc/doc/user/diagrams/Diagrams.html +++ b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/Diagrams.html @@ -29,6 +29,9 @@ <a href="#Resizingelements">Resizing elements</a> </li> <li> + <a href="#Movingelements">Moving elements</a> + </li> + <li> <a href="#Manageedges">Manage edges</a> </li> <li> @@ -185,6 +188,39 @@ <p>Opening existing diagrams and renaming or deleting them works exactly as for any other kind of representation. Refer to the general documentation about the <em>Modeling Project</em> UI for details. </p> + <h4 id="RulersGrid">Rulers & Grid</h4> + <p>Several behaviors concerning the diagram elements editing is conditioned by properties of the diagram accessible through the + <em>Rulers & Grid</em> tab of the + <em>Properties</em> view of the diagram. + <br/> + <img border="0" src="images/properties_view_rulers_and_grid_tab.png"/> + </p> + <h5 id="ShowRuler">Show Ruler</h5> + <p> + <em>Display/Show Ruler</em>: Display an horizonal and vertical ruler according to + <em>Measurement/Ruler Units</em> property. + </p> + <h5 id="ShowGrid">Show Grid </h5> + <p> + <em>Display/Show Grid</em>: Display a grid in background of the diagram according to + <em>Measurement/Grid Spacing</em> and + <em>Grid Line</em> properties. This grid can be in front of all figures if the property + <em>Grid In Front</em> is enabled. + </p> + <h5 id="Snaptogrid">Snap to grid</h5> + <p>Capability to allow edit parts to snap to the grid when editing (during creation, moving or resizing). It is also possible to have connection bendpoints snap to it. Grid snapping and visibility are two distinct properties, and it is possible to enable one without the other.</p> + <h5 id="snap_to_shapes">Snap to shapes</h5> + <p>The + <em>Snap to shapes</em> feature allows you to quickly align parts being dragged or resized to other parts in the diagram or that share the same parent (e.g: edit parts inside a compartment can only snap to each other). The snap is effective on top, bottom, right, left and center of the figure. Feedback is shown in the form of a gray line when a part is being attached to another part. This feature is not enabled on border nodes. + <br/> + <img border="0" src="images/snap_to_shape.png"/> + </p> + <p>By pressing the <kdb>F4</kdb> shortcut key, it is possible to temporarily enable the snap to all shapes currently visible on the diagram. Some screenshots of this feature are shown below. + <br/> + <img border="0" src="images/snap_to_all_shapes.png"/> + <br/> + <img border="0" src="images/snap_to_all_shapes_2.png"/> + </p> <h3 id="Resizingelements">Resizing elements</h3> <p>If the specifier has authorized it, it is possible to resize a shape by dragging them until they are the size that you want.</p> <p>There are specific shortcuts to change the resize behavior:</p> @@ -193,8 +229,25 @@ <li>SHIFT: Resize that keeps the ratio</li> <li>ALT (or CTRL for Mac users): Resize without snap (temporarily disables the snap during the resize if it is activated). </li> <li>F3: Resize with children location relative to the parent. If the shape is resized to the left, upwards, or both, the children (contained nodes for container and border nodes for all shapes) are moved with the same offset that the resize.</li> + <li>F4: Resize with snap to all shapes (if the + <a href="#snap_to_shapes">Snap to shapes</a> is already activated for the current diagram) + </li> + </ul> + <h3 id="Movingelements">Moving elements</h3> + <p>There are specific shortcuts to change the move behavior:</p> + <ul> + <li>SHIFT: Constrained move (only vertical or horizontal move is authorized at once).</li> + <li>ALT (or CTRL for Mac users): Ignore snap while dragging (temporarily disables the snap during the move if it is activated).</li> + <li>F4: Move with snap to all shapes (if the + <a href="#snap_to_shapes">Snap to shapes</a> is already activated for the current diagram) + </li> </ul> <h3 id="Manageedges">Manage edges</h3> + <h4 id="Movebendpoints">Move bend-points</h4> + <p>It is possible to snap the bend-points to all shapes by pressing kdb>F4</kdb> shortcut key during the move. This feature is only available if the + <a href="#snap_to_shapes">Snap to shapes</a> is already activated for the current diagram. As for + <em>Snap to grid</em>, and unlike to snap for node, there is no guide drawn during the move. + </p> <h4 id="RemoveBendpoints">Remove Bend-points</h4> <p>You can define some bend-points (or inflection points) on an edge. It is possible to remove all these bend-points to retrieve the original Straight edge. This action is available within the edge context menu or by using the shortcut «Ctrl» + «Shift» + «-». This action is only available on edges with a «Straight» routing style.</p> <p>The edge state just after its creation: diff --git a/plugins/org.eclipse.sirius.doc/doc/user/diagrams/Diagrams.textile b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/Diagrams.textile index 72a8719e0a..17648bd4c9 100644 --- a/plugins/org.eclipse.sirius.doc/doc/user/diagrams/Diagrams.textile +++ b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/Diagrams.textile @@ -42,6 +42,32 @@ h3. Managing Diagrams Opening existing diagrams and renaming or deleting them works exactly as for any other kind of representation. Refer to the general documentation about the _Modeling Project_ UI for details. +h4. Rulers & Grid + +Several behaviors concerning the diagram elements editing is conditioned by properties of the diagram accessible through the _Rulers & Grid_ tab of the _Properties_ view of the diagram. +!images/properties_view_rulers_and_grid_tab.png! + +h5. Show Ruler + +_Display/Show Ruler_: Display an horizonal and vertical ruler according to _Measurement/Ruler Units_ property. + +h5. Show Grid + +_Display/Show Grid_: Display a grid in background of the diagram according to _Measurement/Grid Spacing_ and _Grid Line_ properties. This grid can be in front of all figures if the property _Grid In Front_ is enabled. + +h5. Snap to grid + +Capability to allow edit parts to snap to the grid when editing (during creation, moving or resizing). It is also possible to have connection bendpoints snap to it. Grid snapping and visibility are two distinct properties, and it is possible to enable one without the other. + +h5(#snap_to_shapes). Snap to shapes + +The _Snap to shapes_ feature allows you to quickly align parts being dragged or resized to other parts in the diagram or that share the same parent (e.g: edit parts inside a compartment can only snap to each other). The snap is effective on top, bottom, right, left and center of the figure. Feedback is shown in the form of a gray line when a part is being attached to another part. This feature is not enabled on border nodes. +!images/snap_to_shape.png! + +By pressing the <kdb>F4</kdb> shortcut key, it is possible to temporarily enable the snap to all shapes currently visible on the diagram. Some screenshots of this feature are shown below. +!images/snap_to_all_shapes.png! +!images/snap_to_all_shapes_2.png! + h3. Resizing elements If the specifier has authorized it, it is possible to resize a shape by dragging them until they are the size that you want. @@ -51,9 +77,22 @@ There are specific shortcuts to change the resize behavior: * SHIFT: Resize that keeps the ratio * ALT (or CTRL for Mac users): Resize without snap (temporarily disables the snap during the resize if it is activated). * F3: Resize with children location relative to the parent. If the shape is resized to the left, upwards, or both, the children (contained nodes for container and border nodes for all shapes) are moved with the same offset that the resize. +* F4: Resize with snap to all shapes (if the "Snap to shapes":#snap_to_shapes is already activated for the current diagram) + + +h3. Moving elements + +There are specific shortcuts to change the move behavior: +* SHIFT: Constrained move (only vertical or horizontal move is authorized at once). +* ALT (or CTRL for Mac users): Ignore snap while dragging (temporarily disables the snap during the move if it is activated). +* F4: Move with snap to all shapes (if the "Snap to shapes":#snap_to_shapes is already activated for the current diagram) h3. Manage edges +h4. Move bend-points + +It is possible to snap the bend-points to all shapes by pressing kdb>F4</kdb> shortcut key during the move. This feature is only available if the "Snap to shapes":#snap_to_shapes is already activated for the current diagram. As for _Snap to grid_, and unlike to snap for node, there is no guide drawn during the move. + h4. Remove Bend-points You can define some bend-points (or inflection points) on an edge. It is possible to remove all these bend-points to retrieve the original Straight edge. This action is available within the edge context menu or by using the shortcut "Ctrl" + "Shift" + "-". This action is only available on edges with a "Straight" routing style. diff --git a/plugins/org.eclipse.sirius.doc/doc/user/diagrams/images/properties_view_rulers_and_grid_tab.png b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/images/properties_view_rulers_and_grid_tab.png Binary files differnew file mode 100644 index 0000000000..ed89cf93d6 --- /dev/null +++ b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/images/properties_view_rulers_and_grid_tab.png diff --git a/plugins/org.eclipse.sirius.doc/specs/proposal/463485_snapToAllShapes/images/snapToAllShapes.png b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/images/snap_to_all_shapes.png Binary files differindex 9e4c69dc79..9e4c69dc79 100644 --- a/plugins/org.eclipse.sirius.doc/specs/proposal/463485_snapToAllShapes/images/snapToAllShapes.png +++ b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/images/snap_to_all_shapes.png diff --git a/plugins/org.eclipse.sirius.doc/specs/proposal/463485_snapToAllShapes/images/snapToAllShapes_2.png b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/images/snap_to_all_shapes_2.png Binary files differindex 2bb1bbbac7..2bb1bbbac7 100644 --- a/plugins/org.eclipse.sirius.doc/specs/proposal/463485_snapToAllShapes/images/snapToAllShapes_2.png +++ b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/images/snap_to_all_shapes_2.png diff --git a/plugins/org.eclipse.sirius.doc/doc/user/diagrams/images/snap_to_shape.png b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/images/snap_to_shape.png Binary files differnew file mode 100644 index 0000000000..dab9d6d0f6 --- /dev/null +++ b/plugins/org.eclipse.sirius.doc/doc/user/diagrams/images/snap_to_shape.png diff --git a/plugins/org.eclipse.sirius.doc/specs/proposal/463485_snapToAllShapes/463485.html b/plugins/org.eclipse.sirius.doc/specs/accepted/463485_snapToAllShapes/463485.html index da43bec486..da43bec486 100644 --- a/plugins/org.eclipse.sirius.doc/specs/proposal/463485_snapToAllShapes/463485.html +++ b/plugins/org.eclipse.sirius.doc/specs/accepted/463485_snapToAllShapes/463485.html diff --git a/plugins/org.eclipse.sirius.doc/specs/proposal/463485_snapToAllShapes/463485.textile b/plugins/org.eclipse.sirius.doc/specs/accepted/463485_snapToAllShapes/463485.textile index f47e3363ee..f47e3363ee 100644 --- a/plugins/org.eclipse.sirius.doc/specs/proposal/463485_snapToAllShapes/463485.textile +++ b/plugins/org.eclipse.sirius.doc/specs/accepted/463485_snapToAllShapes/463485.textile diff --git a/plugins/org.eclipse.sirius.doc/specs/accepted/463485_snapToAllShapes/images/snapToAllShapes.png b/plugins/org.eclipse.sirius.doc/specs/accepted/463485_snapToAllShapes/images/snapToAllShapes.png Binary files differnew file mode 100644 index 0000000000..9e4c69dc79 --- /dev/null +++ b/plugins/org.eclipse.sirius.doc/specs/accepted/463485_snapToAllShapes/images/snapToAllShapes.png diff --git a/plugins/org.eclipse.sirius.doc/specs/accepted/463485_snapToAllShapes/images/snapToAllShapes_2.png b/plugins/org.eclipse.sirius.doc/specs/accepted/463485_snapToAllShapes/images/snapToAllShapes_2.png Binary files differnew file mode 100644 index 0000000000..2bb1bbbac7 --- /dev/null +++ b/plugins/org.eclipse.sirius.doc/specs/accepted/463485_snapToAllShapes/images/snapToAllShapes_2.png diff --git a/plugins/org.eclipse.sirius.ext.emf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.ext.emf.ui/META-INF/MANIFEST.MF index b28e15bbfe..89f9ff4b89 100644 --- a/plugins/org.eclipse.sirius.ext.emf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.sirius.ext.emf.ui/META-INF/MANIFEST.MF @@ -7,5 +7,5 @@ Bundle-Vendor: %providerName Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-Localization: plugin Require-Bundle: org.eclipse.emf.edit.ui;bundle-version="2.8.0" -Export-Package: org.eclipse.sirius.ext.emf.ui, - org.eclipse.sirius.ext.emf.ui.properties +Export-Package: org.eclipse.sirius.ext.emf.ui;version="3.0.0", + org.eclipse.sirius.ext.emf.ui.properties;version="3.0.0" diff --git a/plugins/org.eclipse.sirius.ext.gef/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.ext.gef/META-INF/MANIFEST.MF index 790cc0cecf..cc99e373d6 100644 --- a/plugins/org.eclipse.sirius.ext.gef/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.sirius.ext.gef/META-INF/MANIFEST.MF @@ -8,4 +8,7 @@ Bundle-Vendor: %providerName Bundle-Localization: plugin Require-Bundle: org.eclipse.gef;bundle-version="3.9.0", org.eclipse.equinox.common;bundle-version="3.6.100" -Export-Package: org.eclipse.sirius.ext.gef.editpolicies;version="2.0.4" +Export-Package: org.eclipse.sirius.ext.gef.editpolicies;version="2.0.4", + org.eclipse.sirius.ext.gef.query;version="3.1.0" +Import-Package: com.google.common.base;version="[11.0.2,16.0)", + com.google.common.collect;version="[11.0.2,16.0)" diff --git a/plugins/org.eclipse.sirius.ext.gef/src/org/eclipse/sirius/ext/gef/query/EditPartQuery.java b/plugins/org.eclipse.sirius.ext.gef/src/org/eclipse/sirius/ext/gef/query/EditPartQuery.java new file mode 100644 index 0000000000..f6540e8588 --- /dev/null +++ b/plugins/org.eclipse.sirius.ext.gef/src/org/eclipse/sirius/ext/gef/query/EditPartQuery.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2015 THALES GLOBAL SERVICES. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.ext.gef.query; + +import java.util.List; +import java.util.Set; + +import org.eclipse.gef.EditPart; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; + +/** + * Queries on GEF edit parts. + * + * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> + */ +public class EditPartQuery { + private final EditPart part; + + /** + * Constructor. + * + * @param part + * the graphical edit part to query. + */ + public EditPartQuery(EditPart part) { + this.part = Preconditions.checkNotNull(part); + } + + /** + * Returns a list including all of the children of the edit part passed in. + * + * @param includeSelf + * true if the edit part must be include in result, false + * otherwise + * @return list of children + */ + public Set<EditPart> getAllChildren(boolean includeSelf) { + return getAllChildren(includeSelf, null); + } + + /** + * Returns a list including all of the children of the edit part passed in. + * + * @param includeSelf + * true if the edit part must be include in result, false + * otherwise + * @param includedKind + * List of expected editPart classes + * @return list of children + */ + public Set<EditPart> getAllChildren(boolean includeSelf, List<Class<?>> includedKind) { + Set<EditPart> result = Sets.newHashSet(); + if (includeSelf) { + if (includedKind == null || isAssignable(part.getClass(), includedKind)) { + result.add(part); + } + } + result.addAll(getAllChildren(part, includedKind)); + return result; + } + + /** + * Returns a list including all of the children of the edit part passed in. + */ + private Set<EditPart> getAllChildren(EditPart editPart, List<Class<?>> includedKind) { + Set<EditPart> result = Sets.newHashSet(); + for (EditPart child : Iterables.filter(editPart.getChildren(), EditPart.class)) { + if (includedKind == null || isAssignable(child.getClass(), includedKind)) { + result.add(child); + } + result.addAll(getAllChildren(child, includedKind)); + } + return result; + } + + private boolean isAssignable(Class<?> aClass, List<Class<?>> assignementTypes) { + for (Class<?> class1 : assignementTypes) { + if (class1.isAssignableFrom(aClass)) { + return true; + } + } + return false; + } +} diff --git a/plugins/org.eclipse.sirius.ext.gmf.runtime/src/org/eclipse/sirius/ext/gmf/runtime/editparts/GraphicalHelper.java b/plugins/org.eclipse.sirius.ext.gmf.runtime/src/org/eclipse/sirius/ext/gmf/runtime/editparts/GraphicalHelper.java index 93c2c5280b..92c4dc5256 100644 --- a/plugins/org.eclipse.sirius.ext.gmf.runtime/src/org/eclipse/sirius/ext/gmf/runtime/editparts/GraphicalHelper.java +++ b/plugins/org.eclipse.sirius.ext.gmf.runtime/src/org/eclipse/sirius/ext/gmf/runtime/editparts/GraphicalHelper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES. + * Copyright (c) 2011, 2015 THALES GLOBAL SERVICES. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -16,6 +16,7 @@ import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.PrecisionPoint; +import org.eclipse.draw2d.geometry.PrecisionRectangle; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; @@ -117,7 +118,8 @@ public final class GraphicalHelper { } /** - * Applies inverse zoom on a point and returns this point for convenience.<BR> + * Applies inverse zoom on a point and returns this point for convenience. + * <BR> * For example: * <UL> * <LI>For a zoom of 200%, the result of this method for the point (100, @@ -311,11 +313,11 @@ public final class GraphicalHelper { * @return The corresponding point to this anchor */ public static Point getAnchorPoint(IGraphicalEditPart parent, IdentityAnchor anchor) { - Rectangle bounds; + PrecisionRectangle bounds; if (parent.getFigure() instanceof HandleBounds) { - bounds = ((HandleBounds) parent.getFigure()).getHandleBounds(); + bounds = new PrecisionRectangle(((HandleBounds) parent.getFigure()).getHandleBounds()); } else { - bounds = parent.getFigure().getBounds(); + bounds = new PrecisionRectangle(parent.getFigure().getBounds()); } parent.getFigure().translateToAbsolute(bounds); @@ -326,7 +328,7 @@ public final class GraphicalHelper { // If anchor is null, the default value is (0.5, 0.5) rel = new PrecisionPoint(0.5, 0.5); } - Point location = new PrecisionPoint(bounds.getLocation().x + bounds.width * rel.preciseX(), bounds.getLocation().y + bounds.height * rel.preciseY()); + Point location = new PrecisionPoint(bounds.preciseX() + bounds.preciseWidth() * rel.preciseX(), bounds.preciseY() + bounds.preciseHeight() * rel.preciseY()); return location; } @@ -438,11 +440,11 @@ public final class GraphicalHelper { * @return The absolute bounds. */ public static Rectangle getAbsoluteBounds(IGraphicalEditPart part) { - Rectangle bounds; + PrecisionRectangle bounds; if (part.getFigure() instanceof HandleBounds) { - bounds = ((HandleBounds) part.getFigure()).getHandleBounds().getCopy(); + bounds = new PrecisionRectangle(((HandleBounds) part.getFigure()).getHandleBounds()); } else { - bounds = part.getFigure().getBounds().getCopy(); + bounds = new PrecisionRectangle(part.getFigure().getBounds()); } part.getFigure().translateToAbsolute(bounds); return bounds; @@ -457,11 +459,11 @@ public final class GraphicalHelper { * @return The absolute bounds. */ public static Rectangle getAbsoluteBoundsIn100Percent(GraphicalEditPart part) { - Rectangle bounds; + PrecisionRectangle bounds; if (part.getFigure() instanceof HandleBounds) { - bounds = ((HandleBounds) part.getFigure()).getHandleBounds().getCopy(); + bounds = new PrecisionRectangle(((HandleBounds) part.getFigure()).getHandleBounds()); } else { - bounds = part.getFigure().getBounds().getCopy(); + bounds = new PrecisionRectangle(part.getFigure().getBounds()); } part.getFigure().translateToAbsolute(bounds); screen2logical(bounds, part); diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TopCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TopCondition.java new file mode 100644 index 0000000000..983d83c4a0 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TopCondition.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2015 THALES GLOBAL SERVICES. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.tests.swtbot.support.api.condition; + +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.sirius.ext.gmf.runtime.editparts.GraphicalHelper; +import org.eclipse.swtbot.swt.finder.waits.DefaultCondition; + +/** + * A specific condition to wait that the top of the edit part is on the expected + * axis. + * + * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> + */ +public final class TopCondition extends DefaultCondition { + /** Element to move. */ + private final GraphicalEditPart part; + + /** The expected y location */ + private int expectedYLocation; + + /** + * A delta of one pixel can be tolerated, in case of zoom different from + * 100% for example. + */ + private boolean addOnePixelDelta; + + /** Failure message when a test fails */ + private String failureMessage = ""; + + private int actual; + + /** + * Default constructor. + * + * @param part + * Part to check + * @param expectedYLocation + * The expected y location + * @param failureMessage + * Failure message when a test fails + * @param addOnePixelDelta + * A delta of one pixel can be tolerated, in case of zoom + * different from 100% for example + */ + public TopCondition(GraphicalEditPart part, int expectedYLocation, String failureMessage, boolean addOnePixelDelta) { + this.expectedYLocation = expectedYLocation; + this.part = part; + this.failureMessage = failureMessage; + this.addOnePixelDelta = addOnePixelDelta; + } + + @Override + public boolean test() throws Exception { + Rectangle newBounds = GraphicalHelper.getAbsoluteBoundsIn100Percent(part); + actual = newBounds.getTop().y; + if (addOnePixelDelta) { + return (expectedYLocation - 1) <= actual && actual <= (expectedYLocation + 1); + } else { + return expectedYLocation == actual; + } + } + + @Override + public String getFailureMessage() { + return failureMessage + ", expected:<" + expectedYLocation + "> but was:<" + actual + ">"; + } +} diff --git a/plugins/org.eclipse.sirius.tests.swtbot/data/unit/snap/My.ecore b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/snap/My.ecore new file mode 100644 index 0000000000..2246cb4eb9 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/snap/My.ecore @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="root"> + <eSubpackages name="p1"> + <eClassifiers xsi:type="ecore:EClass" name="C1"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="att1"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="toC2" eType="#//p2/C2"/> + </eClassifiers> + <eSubpackages name="subP1"> + <eClassifiers xsi:type="ecore:EClass" name="C1Sub"/> + </eSubpackages> + </eSubpackages> + <eSubpackages name="p2"> + <eClassifiers xsi:type="ecore:EClass" name="C2"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="att2"/> + </eClassifiers> + </eSubpackages> +</ecore:EPackage> diff --git a/plugins/org.eclipse.sirius.tests.swtbot/data/unit/snap/representations.aird b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/snap/representations.aird new file mode 100644 index 0000000000..50565baacd --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/snap/representations.aird @@ -0,0 +1,443 @@ +<?xml version="1.0" encoding="UTF-8"?> +<viewpoint:DAnalysis xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:description="http://www.eclipse.org/sirius/description/1.1.0" xmlns:description_1="http://www.eclipse.org/sirius/diagram/description/1.1.0" xmlns:diagram="http://www.eclipse.org/sirius/diagram/1.1.0" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/sirius/diagram/description/style/1.1.0" xmlns:viewpoint="http://www.eclipse.org/sirius/1.1.0" xsi:schemaLocation="http://www.eclipse.org/sirius/description/1.1.0 http://www.eclipse.org/sirius/1.1.0#//description http://www.eclipse.org/sirius/diagram/description/1.1.0 http://www.eclipse.org/sirius/diagram/1.1.0#//description http://www.eclipse.org/sirius/diagram/description/style/1.1.0 http://www.eclipse.org/sirius/diagram/1.1.0#//description/style" xmi:id="_mXL0MBWbEeW7GcqVYwuCiQ" selectedViews="_LWb4wBWdEeW7GcqVYwuCiQ" version="10.0.0.201505222000"> + <semanticResources>My.ecore</semanticResources> + <ownedViews xmi:type="viewpoint:DRepresentationContainer" xmi:id="_LWb4wBWdEeW7GcqVYwuCiQ"> + <ownedRepresentations xmi:type="diagram:DSemanticDiagram" xmi:id="_M0HXsBWdEeW7GcqVYwuCiQ" name="snapToAllDiagram"> + <ownedAnnotationEntries xmi:type="description:AnnotationEntry" xmi:id="_M0HXsRWdEeW7GcqVYwuCiQ" source="DANNOTATION_CUSTOMIZATION_KEY"> + <data xmi:type="diagram:ComputedStyleDescriptionRegistry" xmi:id="_M0HXshWdEeW7GcqVYwuCiQ"/> + </ownedAnnotationEntries> + <ownedAnnotationEntries xmi:type="description:AnnotationEntry" xmi:id="_M0a5sBWdEeW7GcqVYwuCiQ" source="GMF_DIAGRAMS"> + <data xmi:type="notation:Diagram" xmi:id="_M0bgwBWdEeW7GcqVYwuCiQ" type="Sirius" element="_M0HXsBWdEeW7GcqVYwuCiQ" measurementUnit="Pixel"> + <children xmi:type="notation:Node" xmi:id="_OrCLQBaIEeWQ3O79R6E3Ug" type="2001" element="_OpprMBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrI48BaIEeWQ3O79R6E3Ug" type="5002"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OrI48RaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrRb0BaIEeWQ3O79R6E3Ug" type="3001" element="_OpyOEBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrSC4BaIEeWQ3O79R6E3Ug" type="5001"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OrSC4RaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OralwBaIEeWQ3O79R6E3Ug" type="3003" element="_OpyOERaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OralwRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OralwhaIEeWQ3O79R6E3Ug"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrbM0BaIEeWQ3O79R6E3Ug" type="3001" element="_Op0qUBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_Orbz4BaIEeWQ3O79R6E3Ug" type="5001"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_Orbz4RaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Orca8BaIEeWQ3O79R6E3Ug" type="3003" element="_Op0qURaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Orca8RaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Orca8haIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrbM0RaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrbM0haIEeWQ3O79R6E3Ug" x="-83" width="91" height="51"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrRb0RaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrRb0haIEeWQ3O79R6E3Ug" x="-92" width="100" height="101"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrZ-sBaIEeWQ3O79R6E3Ug" type="3003" element="_OpujsBaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrZ-sRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrZ-shaIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrCLQRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrCLQhaIEeWQ3O79R6E3Ug" x="198" y="88" width="126" height="250"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrKuIBaIEeWQ3O79R6E3Ug" type="2001" element="_OpwY4BaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrLVMBaIEeWQ3O79R6E3Ug" type="5002"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OrLVMRaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrdpEBaIEeWQ3O79R6E3Ug" type="3001" element="_Op2fgBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OreQIBaIEeWQ3O79R6E3Ug" type="5001"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OreQIRaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrgFUBaIEeWQ3O79R6E3Ug" type="3003" element="_Op2fgRaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrgFURaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrgFUhaIEeWQ3O79R6E3Ug"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrgsYBaIEeWQ3O79R6E3Ug" type="3001" element="_Op6J4BaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrhTcBaIEeWQ3O79R6E3Ug" type="5001"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OrhTcRaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Orh6gBaIEeWQ3O79R6E3Ug" type="3003" element="_Op6w8BaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Orh6gRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Orh6ghaIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrgsYRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrgsYhaIEeWQ3O79R6E3Ug" x="-102" y="10" width="110" height="38"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrdpERaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrdpEhaIEeWQ3O79R6E3Ug" x="-92" width="100" height="60"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Ore3MBaIEeWQ3O79R6E3Ug" type="3003" element="_Opw_8BaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Ore3MRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Ore3MhaIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrKuIRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrKuIhaIEeWQ3O79R6E3Ug" x="275" y="-100" width="250" height="118"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrNxcBaIEeWQ3O79R6E3Ug" type="2002" element="_Op7_EBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrO_kBaIEeWQ3O79R6E3Ug" type="5006"/> + <children xmi:type="notation:Node" xmi:id="_OrPmoBaIEeWQ3O79R6E3Ug" type="7001"> + <children xmi:type="notation:Node" xmi:id="_OrmL8BaIEeWQ3O79R6E3Ug" type="3008" element="_OqCswBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrmzABaIEeWQ3O79R6E3Ug" type="5005"/> + <children xmi:type="notation:Node" xmi:id="_OrnaEBaIEeWQ3O79R6E3Ug" type="7002"> + <children xmi:type="notation:Node" xmi:id="_OrsSkBaIEeWQ3O79R6E3Ug" type="3007" element="_OqFJABaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_Ors5oBaIEeWQ3O79R6E3Ug" type="5003"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_Ors5oRaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrtgsBaIEeWQ3O79R6E3Ug" type="3003" element="_OqFwEBaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrtgsRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrtgshaIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrsSkRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrsSkhaIEeWQ3O79R6E3Ug" x="31" y="33" width="100" height="36"/> + </children> + <styles xmi:type="notation:SortingStyle" xmi:id="_OrnaERaIEeWQ3O79R6E3Ug"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_OrnaEhaIEeWQ3O79R6E3Ug"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrqdYBaIEeWQ3O79R6E3Ug" type="3012" element="_OqDT0BaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrrEcBaIEeWQ3O79R6E3Ug" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OrrEcRaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OruHwBaIEeWQ3O79R6E3Ug" type="3003" element="_OqD64BaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OruHwRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OruHwhaIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrqdYRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrqdYhaIEeWQ3O79R6E3Ug" x="-92" y="11" width="100" height="31"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrmL8RaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrmL8haIEeWQ3O79R6E3Ug" x="169" y="-55" width="168" height="52"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OroBIBaIEeWQ3O79R6E3Ug" type="3007" element="_OqG-MBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrooMBaIEeWQ3O79R6E3Ug" type="5003"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OrooMRaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Oruu0BaIEeWQ3O79R6E3Ug" type="3001" element="_OqKBgBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrvV4BaIEeWQ3O79R6E3Ug" type="5001"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OrvV4RaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrwkABaIEeWQ3O79R6E3Ug" type="3003" element="_OqKBgRaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrwkARaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrwkAhaIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Oruu0RaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Oruu0haIEeWQ3O79R6E3Ug" x="-90" width="98" height="50"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Orv88BaIEeWQ3O79R6E3Ug" type="3003" element="_OqHlQBaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Orv88RaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Orv88haIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OroBIRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OroBIhaIEeWQ3O79R6E3Ug" x="128" y="33" width="100" height="100"/> + </children> + <styles xmi:type="notation:SortingStyle" xmi:id="_OrPmoRaIEeWQ3O79R6E3Ug"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_OrPmohaIEeWQ3O79R6E3Ug"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrjIoBaIEeWQ3O79R6E3Ug" type="3012" element="_Op-bUBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrjvsBaIEeWQ3O79R6E3Ug" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OrjvsRaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OryZMBaIEeWQ3O79R6E3Ug" type="3003" element="_Op_CYBaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OryZMRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OryZMhaIEeWQ3O79R6E3Ug"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrzAQBaIEeWQ3O79R6E3Ug" type="3012" element="_OqA3kBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrznUBaIEeWQ3O79R6E3Ug" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OrznURaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Or0OYBaIEeWQ3O79R6E3Ug" type="3003" element="_OqA3kRaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Or0OYRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Or0OYhaIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrzAQRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrzAQhaIEeWQ3O79R6E3Ug" x="-49" y="50" width="84" height="50"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrjIoRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrjIohaIEeWQ3O79R6E3Ug" x="-92" y="225" width="100" height="100"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrNxcRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrNxchaIEeWQ3O79R6E3Ug" x="351" y="182" width="403" height="378"/> + </children> + <children xmi:type="notation:Node" xmi:id="_OrQNsBaIEeWQ3O79R6E3Ug" type="2002" element="_Op9NMBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_OrQ0wBaIEeWQ3O79R6E3Ug" type="5006"/> + <children xmi:type="notation:Node" xmi:id="_OrQ0wRaIEeWQ3O79R6E3Ug" type="7001"> + <children xmi:type="notation:Node" xmi:id="_Or4f0BaIEeWQ3O79R6E3Ug" type="3007" element="_OqO6ABaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_Or5G4BaIEeWQ3O79R6E3Ug" type="5003"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_Or5G4RaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Or5t8BaIEeWQ3O79R6E3Ug" type="3001" element="_OqQvMBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_Or6VABaIEeWQ3O79R6E3Ug" type="5001"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_Or6VARaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Or7jIBaIEeWQ3O79R6E3Ug" type="3003" element="_OqRWQBaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Or7jIRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Or7jIhaIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Or5t8RaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Or5t8haIEeWQ3O79R6E3Ug" x="243" y="25" width="184" height="50"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Or68EBaIEeWQ3O79R6E3Ug" type="3003" element="_OqPhEBaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Or68ERaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Or68EhaIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Or4f0RaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Or4f0haIEeWQ3O79R6E3Ug" x="17" y="256" width="251" height="101"/> + </children> + <styles xmi:type="notation:SortingStyle" xmi:id="_OrQ0whaIEeWQ3O79R6E3Ug"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_OrQ0wxaIEeWQ3O79R6E3Ug"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Or1cgBaIEeWQ3O79R6E3Ug" type="3012" element="_OqLPoBaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_Or3RsBaIEeWQ3O79R6E3Ug" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_Or3RsRaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Or8KMBaIEeWQ3O79R6E3Ug" type="3003" element="_OqL2sBaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Or8KMRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Or8KMhaIEeWQ3O79R6E3Ug"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Or8xQBaIEeWQ3O79R6E3Ug" type="3012" element="_OqNE0BaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_Or9YUBaIEeWQ3O79R6E3Ug" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_Or9YURaIEeWQ3O79R6E3Ug" y="5"/> + </children> + <children xmi:type="notation:Node" xmi:id="_Or9_YBaIEeWQ3O79R6E3Ug" type="3003" element="_OqNr4BaIEeWQ3O79R6E3Ug"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Or9_YRaIEeWQ3O79R6E3Ug" fontName="Ubuntu"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Or9_YhaIEeWQ3O79R6E3Ug"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Or8xQRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Or8xQhaIEeWQ3O79R6E3Ug" x="-175" y="28" width="176" height="26"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_Or1cgRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Or1cghaIEeWQ3O79R6E3Ug" x="448" y="150" width="100" height="104"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_OrQNsRaIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OrQNshaIEeWQ3O79R6E3Ug" x="1024" y="112" width="458" height="578"/> + </children> + <styles xmi:type="notation:DiagramStyle" xmi:id="_M0bgwRWdEeW7GcqVYwuCiQ"/> + <edges xmi:type="notation:Edge" xmi:id="_UTFY4BaIEeWQ3O79R6E3Ug" type="4001" element="_US1hQBaIEeWQ3O79R6E3Ug" source="_OroBIBaIEeWQ3O79R6E3Ug" target="_Or4f0BaIEeWQ3O79R6E3Ug"> + <children xmi:type="notation:Node" xmi:id="_UTF_8BaIEeWQ3O79R6E3Ug" type="6001"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_UTF_8RaIEeWQ3O79R6E3Ug" y="-10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_UTGnABaIEeWQ3O79R6E3Ug" type="6002"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_UTGnARaIEeWQ3O79R6E3Ug" y="10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_UTHOEBaIEeWQ3O79R6E3Ug" type="6003"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_UTHOERaIEeWQ3O79R6E3Ug" y="10"/> + </children> + <styles xmi:type="notation:ConnectorStyle" xmi:id="_UTFY4RaIEeWQ3O79R6E3Ug"/> + <styles xmi:type="notation:FontStyle" xmi:id="_UTFY4haIEeWQ3O79R6E3Ug" fontName="Ubuntu" fontHeight="8"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_UTFY4xaIEeWQ3O79R6E3Ug" points="[8, -13, -467, -91]$[197, -300, -278, -378]$[352, 141, -123, 63]$[470, 80, -5, 2]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_UTNUsBaIEeWQ3O79R6E3Ug" id="(0.92,0.71)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_UTNUsRaIEeWQ3O79R6E3Ug" id="(0.0199203187250996,0.504950495049505)"/> + </edges> + </data> + </ownedAnnotationEntries> + <ownedDiagramElements xmi:type="diagram:DNode" xmi:id="_OpprMBaIEeWQ3O79R6E3Ug" name="Node_p1" width="25" height="25" resizeKind="NSEW"> + <target xmi:type="ecore:EPackage" href="My.ecore#//p1"/> + <semanticElements xmi:type="ecore:EPackage" href="My.ecore#//p1"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_OpyOEBaIEeWQ3O79R6E3Ug" name="BNN_C1" width="10" height="10" resizeKind="NSEW"> + <target xmi:type="ecore:EClass" href="My.ecore#//p1/C1"/> + <semanticElements xmi:type="ecore:EClass" href="My.ecore#//p1/C1"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_Op0qUBaIEeWQ3O79R6E3Ug" name="BNBNN_att1" width="5" height="5" resizeKind="NSEW"> + <target xmi:type="ecore:EAttribute" href="My.ecore#//p1/C1/att1"/> + <semanticElements xmi:type="ecore:EAttribute" href="My.ecore#//p1/C1/att1"/> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_Op0qURaIEeWQ3O79R6E3Ug" borderColor="204,242,166" labelPosition="node" width="5" height="5" color="255,245,181"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']/@borderedNodeMappings[name='EClassOnNode']/@borderedNodeMappings[name='EAttributeOnEClassOnNode']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']/@borderedNodeMappings[name='EClassOnNode']/@borderedNodeMappings[name='EAttributeOnEClassOnNode']"/> + </ownedBorderedNodes> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OpyOERaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="10" height="10" color="246,139,139"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']/@borderedNodeMappings[name='EClassOnNode']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']/@borderedNodeMappings[name='EClassOnNode']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OpujsBaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="25" height="25" color="217,196,215"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DNode" xmi:id="_OpwY4BaIEeWQ3O79R6E3Ug" name="Node_p2" width="25" height="25" resizeKind="NSEW"> + <target xmi:type="ecore:EPackage" href="My.ecore#//p2"/> + <semanticElements xmi:type="ecore:EPackage" href="My.ecore#//p2"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_Op2fgBaIEeWQ3O79R6E3Ug" name="BNN_C2" width="10" height="10" resizeKind="NSEW"> + <target xmi:type="ecore:EClass" href="My.ecore#//p2/C2"/> + <semanticElements xmi:type="ecore:EClass" href="My.ecore#//p2/C2"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_Op6J4BaIEeWQ3O79R6E3Ug" name="BNBNN_att2" width="5" height="5" resizeKind="NSEW"> + <target xmi:type="ecore:EAttribute" href="My.ecore#//p2/C2/att2"/> + <semanticElements xmi:type="ecore:EAttribute" href="My.ecore#//p2/C2/att2"/> + <ownedStyle xmi:type="diagram:Square" xmi:id="_Op6w8BaIEeWQ3O79R6E3Ug" borderColor="204,242,166" labelPosition="node" width="5" height="5" color="255,245,181"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']/@borderedNodeMappings[name='EClassOnNode']/@borderedNodeMappings[name='EAttributeOnEClassOnNode']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']/@borderedNodeMappings[name='EClassOnNode']/@borderedNodeMappings[name='EAttributeOnEClassOnNode']"/> + </ownedBorderedNodes> + <ownedStyle xmi:type="diagram:Square" xmi:id="_Op2fgRaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="10" height="10" color="246,139,139"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']/@borderedNodeMappings[name='EClassOnNode']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']/@borderedNodeMappings[name='EClassOnNode']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_Opw_8BaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="25" height="25" color="217,196,215"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@nodeMappings[name='NodePackage']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" xmi:id="_Op7_EBaIEeWQ3O79R6E3Ug" name="Container_p1"> + <target xmi:type="ecore:EPackage" href="My.ecore#//p1"/> + <semanticElements xmi:type="ecore:EPackage" href="My.ecore#//p1"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_Op-bUBaIEeWQ3O79R6E3Ug" name="BNC_C1" width="10" height="10" resizeKind="NSEW"> + <target xmi:type="ecore:EClass" href="My.ecore#//p1/C1"/> + <semanticElements xmi:type="ecore:EClass" href="My.ecore#//p1/C1"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_OqA3kBaIEeWQ3O79R6E3Ug" name="BNBNC_att1" width="5" height="5" resizeKind="NSEW"> + <target xmi:type="ecore:EAttribute" href="My.ecore#//p1/C1/att1"/> + <semanticElements xmi:type="ecore:EAttribute" href="My.ecore#//p1/C1/att1"/> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OqA3kRaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="5" height="5" color="246,139,139"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@borderedNodeMappings[name='EClassOnContainer']/@borderedNodeMappings[name='EAttribute']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@borderedNodeMappings[name='EClassOnContainer']/@borderedNodeMappings[name='EAttribute']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_Op_CYBaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="10" height="10" color="217,196,215"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@borderedNodeMappings[name='EClassOnContainer']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@borderedNodeMappings[name='EClassOnContainer']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:FlatContainerStyle" xmi:id="_Op8mIBaIEeWQ3O79R6E3Ug" borderColor="39,76,114" foregroundColor="194,239,255"> + <description xmi:type="style:FlatContainerStyleDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']"/> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" xmi:id="_OqCswBaIEeWQ3O79R6E3Ug" name="Container_subP1"> + <target xmi:type="ecore:EPackage" href="My.ecore#//p1/subP1"/> + <semanticElements xmi:type="ecore:EPackage" href="My.ecore#//p1/subP1"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_OqDT0BaIEeWQ3O79R6E3Ug" name="BNC_C1Sub" width="10" height="10" resizeKind="NSEW"> + <target xmi:type="ecore:EClass" href="My.ecore#//p1/subP1/C1Sub"/> + <semanticElements xmi:type="ecore:EClass" href="My.ecore#//p1/subP1/C1Sub"/> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OqD64BaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="10" height="10" color="217,196,215"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@borderedNodeMappings[name='EClassOnContainer']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@borderedNodeMappings[name='EClassOnContainer']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:FlatContainerStyle" xmi:id="_OqCswRaIEeWQ3O79R6E3Ug" borderColor="39,76,114" foregroundColor="194,239,255"> + <description xmi:type="style:FlatContainerStyleDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']"/> + <ownedDiagramElements xmi:type="diagram:DNode" xmi:id="_OqFJABaIEeWQ3O79R6E3Ug" name="NC_C1Sub" width="10" height="10" resizeKind="NSEW"> + <target xmi:type="ecore:EClass" href="My.ecore#//p1/subP1/C1Sub"/> + <semanticElements xmi:type="ecore:EClass" href="My.ecore#//p1/subP1/C1Sub"/> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OqFwEBaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="10" height="10" color="217,196,215"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']"/> + </ownedDiagramElements> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DNode" xmi:id="_OqG-MBaIEeWQ3O79R6E3Ug" name="NC_C1" outgoingEdges="_US1hQBaIEeWQ3O79R6E3Ug" width="10" height="10" resizeKind="NSEW"> + <target xmi:type="ecore:EClass" href="My.ecore#//p1/C1"/> + <semanticElements xmi:type="ecore:EClass" href="My.ecore#//p1/C1"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_OqKBgBaIEeWQ3O79R6E3Ug" name="BNNC_att1" width="5" height="5" resizeKind="NSEW"> + <target xmi:type="ecore:EAttribute" href="My.ecore#//p1/C1/att1"/> + <semanticElements xmi:type="ecore:EAttribute" href="My.ecore#//p1/C1/att1"/> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OqKBgRaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="5" height="5" color="246,139,139"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']/@borderedNodeMappings[name='EAttribute']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']/@borderedNodeMappings[name='EAttribute']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OqHlQBaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="10" height="10" color="217,196,215"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']"/> + </ownedDiagramElements> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" xmi:id="_Op9NMBaIEeWQ3O79R6E3Ug" name="Container_p2"> + <target xmi:type="ecore:EPackage" href="My.ecore#//p2"/> + <semanticElements xmi:type="ecore:EPackage" href="My.ecore#//p2"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_OqLPoBaIEeWQ3O79R6E3Ug" name="BNC_C2" width="10" height="10" resizeKind="NSEW"> + <target xmi:type="ecore:EClass" href="My.ecore#//p2/C2"/> + <semanticElements xmi:type="ecore:EClass" href="My.ecore#//p2/C2"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_OqNE0BaIEeWQ3O79R6E3Ug" name="BNBNC_att2" width="5" height="5" resizeKind="NSEW"> + <target xmi:type="ecore:EAttribute" href="My.ecore#//p2/C2/att2"/> + <semanticElements xmi:type="ecore:EAttribute" href="My.ecore#//p2/C2/att2"/> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OqNr4BaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="5" height="5" color="246,139,139"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@borderedNodeMappings[name='EClassOnContainer']/@borderedNodeMappings[name='EAttribute']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@borderedNodeMappings[name='EClassOnContainer']/@borderedNodeMappings[name='EAttribute']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OqL2sBaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="10" height="10" color="217,196,215"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@borderedNodeMappings[name='EClassOnContainer']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@borderedNodeMappings[name='EClassOnContainer']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:FlatContainerStyle" xmi:id="_Op9NMRaIEeWQ3O79R6E3Ug" borderColor="39,76,114" foregroundColor="194,239,255"> + <description xmi:type="style:FlatContainerStyleDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']"/> + <ownedDiagramElements xmi:type="diagram:DNode" xmi:id="_OqO6ABaIEeWQ3O79R6E3Ug" name="NC_C2" incomingEdges="_US1hQBaIEeWQ3O79R6E3Ug" width="10" height="10" resizeKind="NSEW"> + <target xmi:type="ecore:EClass" href="My.ecore#//p2/C2"/> + <semanticElements xmi:type="ecore:EClass" href="My.ecore#//p2/C2"/> + <ownedBorderedNodes xmi:type="diagram:DNode" xmi:id="_OqQvMBaIEeWQ3O79R6E3Ug" name="BNNC_att2" width="5" height="5" resizeKind="NSEW"> + <target xmi:type="ecore:EAttribute" href="My.ecore#//p2/C2/att2"/> + <semanticElements xmi:type="ecore:EAttribute" href="My.ecore#//p2/C2/att2"/> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OqRWQBaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="5" height="5" color="246,139,139"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']/@borderedNodeMappings[name='EAttribute']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']/@borderedNodeMappings[name='EAttribute']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:Square" xmi:id="_OqPhEBaIEeWQ3O79R6E3Ug" borderColor="114,73,110" labelPosition="node" width="10" height="10" color="217,196,215"> + <description xmi:type="style:SquareDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']"/> + </ownedDiagramElements> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DEdge" xmi:id="_US1hQBaIEeWQ3O79R6E3Ug" name="toC2" sourceNode="_OqG-MBaIEeWQ3O79R6E3Ug" targetNode="_OqO6ABaIEeWQ3O79R6E3Ug"> + <target xmi:type="ecore:EReference" href="My.ecore#//p1/C1/toC2"/> + <semanticElements xmi:type="ecore:EReference" href="My.ecore#//p1/C1/toC2"/> + <ownedStyle xmi:type="diagram:EdgeStyle" xmi:id="_US4kkBaIEeWQ3O79R6E3Ug" size="2"> + <description xmi:type="style:EdgeStyleDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@edgeMappings[name='Reference']/@style"/> + <centerLabelStyle xmi:type="diagram:CenterLabelStyle" xmi:id="_US4kkRaIEeWQ3O79R6E3Ug"/> + </ownedStyle> + <actualMapping xmi:type="description_1:EdgeMapping" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@edgeMappings[name='Reference']"/> + </ownedDiagramElements> + <description xmi:type="description_1:DiagramDescription" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']"/> + <filterVariableHistory xmi:type="diagram:FilterVariableHistory" xmi:id="_M0HXtxWdEeW7GcqVYwuCiQ"/> + <activatedLayers xmi:type="description_1:Layer" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer"/> + <target xmi:type="ecore:EPackage" href="My.ecore#/"/> + </ownedRepresentations> + <viewpoint xmi:type="description:Viewpoint" href="snapToAll.odesign#//@ownedViewpoints[name='snapToAll']"/> + </ownedViews> +</viewpoint:DAnalysis> diff --git a/plugins/org.eclipse.sirius.tests.swtbot/data/unit/snap/snapToAll.odesign b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/snap/snapToAll.odesign new file mode 100644 index 0000000000..b94721d7e6 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/snap/snapToAll.odesign @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="ASCII"?> +<description:Group xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:description="http://www.eclipse.org/sirius/description/1.1.0" xmlns:description_1="http://www.eclipse.org/sirius/diagram/description/1.1.0" xmlns:style="http://www.eclipse.org/sirius/diagram/description/style/1.1.0" name="snapToAll" version="10.0.0.201505222000"> + <ownedViewpoints name="snapToAll" modelFileExtension="ecore"> + <ownedRepresentations xsi:type="description_1:DiagramDescription" name="snapToAllDiagram" domainClass="EPackage"> + <defaultLayer name="Default"> + <nodeMappings name="NodePackage" semanticCandidatesExpression="feature:eContents" domainClass="EPackage"> + <borderedNodeMappings name="EClassOnNode" semanticCandidatesExpression="feature:eContents" domainClass="EClass"> + <borderedNodeMappings name="EAttributeOnEClassOnNode" semanticCandidatesExpression="feature:eContents" domainClass="EAttribute"> + <style xsi:type="style:SquareDescription" labelExpression="aql:'BNBNN_' + self.name" labelPosition="node" resizeKind="NSEW" width="5" height="5"> + <borderColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='light_green']"/> + <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/> + <color xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='light_yellow']"/> + </style> + </borderedNodeMappings> + <style xsi:type="style:SquareDescription" labelExpression="aql:'BNN_' + self.name" labelPosition="node" resizeKind="NSEW" width="10" height="10"> + <borderColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='dark_purple']"/> + <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/> + <color xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='light_red']"/> + </style> + </borderedNodeMappings> + <style xsi:type="style:SquareDescription" labelExpression="aql:'Node_' + self.name" labelPosition="node" resizeKind="NSEW" width="25" height="25"> + <borderColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='dark_purple']"/> + <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/> + <color xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='light_purple']"/> + </style> + </nodeMappings> + <edgeMappings name="Reference" sourceMapping="//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']" targetMapping="//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']/@subNodeMappings[name='EClassInContainer']" targetFinderExpression="feature:eType" sourceFinderExpression="feature:eContainer" domainClass="EReference" useDomainElement="true"> + <style sizeComputationExpression="2"> + <strokeColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='gray']"/> + <centerLabelStyleDescription labelExpression="feature:name"> + <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/> + </centerLabelStyleDescription> + </style> + </edgeMappings> + <containerMappings name="ContainerPackage" semanticCandidatesExpression="feature:eContents" domainClass="EPackage" reusedContainerMappings="//@ownedViewpoints[name='snapToAll']/@ownedRepresentations[name='snapToAllDiagram']/@defaultLayer/@containerMappings[name='ContainerPackage']"> + <borderedNodeMappings name="EClassOnContainer" semanticCandidatesExpression="feature:eContents" domainClass="EClass"> + <borderedNodeMappings name="EAttribute" semanticCandidatesExpression="feature:eContents" domainClass="EAttribute"> + <style xsi:type="style:SquareDescription" labelExpression="aql:'BNBNC_' + self.name" labelPosition="node" resizeKind="NSEW" width="5" height="5"> + <borderColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='dark_purple']"/> + <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/> + <color xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='light_red']"/> + </style> + </borderedNodeMappings> + <style xsi:type="style:SquareDescription" labelExpression="aql:'BNC_' + self.name" labelPosition="node" resizeKind="NSEW" width="10" height="10"> + <borderColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='dark_purple']"/> + <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/> + <color xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='light_purple']"/> + </style> + </borderedNodeMappings> + <subNodeMappings name="EClassInContainer" semanticCandidatesExpression="feature:eContents" domainClass="EClass"> + <borderedNodeMappings name="EAttribute" semanticCandidatesExpression="feature:eContents" domainClass="EAttribute"> + <style xsi:type="style:SquareDescription" labelExpression="aql:'BNNC_' + self.name" labelPosition="node" resizeKind="NSEW" width="5" height="5"> + <borderColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='dark_purple']"/> + <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/> + <color xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='light_red']"/> + </style> + </borderedNodeMappings> + <style xsi:type="style:SquareDescription" labelExpression="aql:'NC_' + self.name" labelPosition="node" resizeKind="NSEW" width="10" height="10"> + <borderColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='dark_purple']"/> + <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/> + <color xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='light_purple']"/> + </style> + </subNodeMappings> + <style xsi:type="style:FlatContainerStyleDescription" arcWidth="1" arcHeight="1" labelExpression="aql:'Container_' + self.name"> + <borderColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='dark_blue']"/> + <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/> + <backgroundColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='white']"/> + <foregroundColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='light_blue']"/> + </style> + </containerMappings> + </defaultLayer> + </ownedRepresentations> + </ownedViewpoints> +</description:Group> diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/SnapAllShapesTest.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/SnapAllShapesTest.java new file mode 100644 index 0000000000..dbbe3c4431 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/SnapAllShapesTest.java @@ -0,0 +1,295 @@ +/******************************************************************************* + * Copyright (c) 2015 THALES GLOBAL SERVICES. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.tests.swtbot; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PrecisionPoint; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; +import org.eclipse.sirius.diagram.DDiagram; +import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramBorderNodeEditPart; +import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramContainerEditPart; +import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramNodeEditPart; +import org.eclipse.sirius.ext.gmf.runtime.editparts.GraphicalHelper; +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.condition.TopCondition; +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.swt.SWT; +import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart; + +/** + * Check the snap to all feature (move and resize). + * + * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> + */ +public class SnapAllShapesTest extends AbstractSiriusSwtBotGefTestCase { + private static final String SEMANTIC_RESOURCE_NAME = "My.ecore"; + + private static final String SESSION_RESOURCE_NAME = "representations.aird"; + + private static final String MODELER_RESOURCE_NAME = "snapToAll.odesign"; + + private static final String DATA_UNIT_DIR = "data/unit/snap/"; + + @Override + protected void onSetUpBeforeClosingWelcomePage() throws Exception { + copyFileToTestProject(Activator.PLUGIN_ID, DATA_UNIT_DIR, SEMANTIC_RESOURCE_NAME, SESSION_RESOURCE_NAME, MODELER_RESOURCE_NAME); + } + + @Override + protected void onSetUpAfterOpeningDesignerPerspective() throws Exception { + // Close the outline view + bot.viewById("org.eclipse.ui.views.ContentOutline").close(); + SWTBotUtils.waitAllUiEvents(); + + // Open the session + UIResource sessionAirdResource = new UIResource(designerProject, SESSION_RESOURCE_NAME); + localSession = designerPerspective.openSessionFromFile(sessionAirdResource, true); + + // Open the editor + editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(), "snapToAllDiagram", "snapToAllDiagram", DDiagram.class, true, false); + editor.maximize(); + } + + @Override + protected void tearDown() throws Exception { + if (editor != null) { + editor.zoom(ZoomLevel.ZOOM_100); + editor.restore(); + editor.scrollTo(0, 0); + } + // Close the editor before opening the outline + if (editor != null) { + editor.close(); + SWTBotUtils.waitAllUiEvents(); + } + + // Reopen outline + new DesignerViews(bot).openOutlineView(); + SWTBotUtils.waitAllUiEvents(); + super.tearDown(); + } + + /** + * Move a container a first time without F4 and check the location is the + * expected one.<BR> + * Move a container a second time with F4 and check the location is the + * expected one (snap to another figure).<BR> + * This test also handles the case of scroll bar in diagram. + */ + public void testMoveContainer() { + moveTopOfElementNearBottomOfAnother("Container_p1", AbstractDiagramContainerEditPart.class, "BNBNN_att1", AbstractDiagramBorderNodeEditPart.class); + } + + /** + * Move a node a first time without F4 and check the location is the + * expected one.<BR> + * Move a node a second time with F4 and check the location is the expected + * one (snap to another figure).<BR> + * This test also handles the case of scroll bar in diagram. + */ + public void testMoveNode() { + moveTopOfElementNearBottomOfAnother("Node_p1", AbstractDiagramNodeEditPart.class, "BNNC_att1", AbstractDiagramBorderNodeEditPart.class); + } + + /** + * Move a node in container a first time without F4 and check the location + * is the expected one.<BR> + * Move a node in container a second time with F4 and check the location is + * the expected one (snap to another figure).<BR> + * This test also handles the case of scroll bar in diagram and in + * container. + */ + + public void testMoveNodeInContainer() { + moveTopOfElementNearBottomOfAnother("NC_C1", AbstractDiagramNodeEditPart.class, "Node_p1", AbstractDiagramNodeEditPart.class); + } + + /** + * Move a node in container a first time without F4 and check the location + * is the expected one.<BR> + * Move a node in container a second time with F4 and check the location is + * the expected one (snap to another figure).<BR> + * This test also handles the case of scroll bar in diagram and in container + * and with zoom different from 100%. + */ + public void testMoveNodeInContainerWithZoom125() { + moveTopOfElementNearBottomOfAnother("NC_C1", AbstractDiagramNodeEditPart.class, "Node_p1", AbstractDiagramNodeEditPart.class, ZoomLevel.ZOOM_125); + } + + /** + * Resize a container a first time without F4 and check the location is the + * expected one.<BR> + * Resize a container a second time with F4 and check the location is the + * expected one (snap to another figure).<BR> + * This test also handles the case of scroll bar in diagram. + */ + public void testResizeContainer() { + resizeTopOfElementNearBottomOfAnother("Container_p1", AbstractDiagramContainerEditPart.class, "BNBNN_att1", AbstractDiagramBorderNodeEditPart.class); + } + + /** + * Resize a node a first time without F4 and check the location is the + * expected one.<BR> + * Resize a node a second time with F4 and check the location is the + * expected one (snap to another figure).<BR> + * This test also handles the case of scroll bar in diagram. + */ + public void testResizeNode() { + resizeTopOfElementNearBottomOfAnother("Node_p1", AbstractDiagramNodeEditPart.class, "BNNC_att1", AbstractDiagramBorderNodeEditPart.class); + } + + /** + * Resize a node in container a first time without F4 and check the location + * is the expected one.<BR> + * Resize a node in container a second time with F4 and check the location + * is the expected one (snap to another figure).<BR> + * This test also handles the case of scroll bar in diagram and in + * container. + */ + + public void testResizeNodeInContainer() { + resizeTopOfElementNearBottomOfAnother("NC_C1", AbstractDiagramNodeEditPart.class, "Node_p1", AbstractDiagramNodeEditPart.class); + } + + /** + * Resize a node in container a first time without F4 and check the location + * is the expected one.<BR> + * Resize a node in container a second time with F4 and check the location + * is the expected one (snap to another figure).<BR> + * This test also handles the case of scroll bar in diagram and in container + * and with zoom different from 100%. + */ + public void testResizeNodeInContainerWithZoom125() { + resizeTopOfElementNearBottomOfAnother("NC_C1", AbstractDiagramNodeEditPart.class, "Node_p1", AbstractDiagramNodeEditPart.class, ZoomLevel.ZOOM_125); + } + + private void moveTopOfElementNearBottomOfAnother(String elementNameToMove, Class<? extends EditPart> expectedEditPartTypeOfMovedElement, String referenceElementName, + Class<? extends EditPart> expectedEditPartTypeOfReferenceElement) { + moveTopOfElementNearBottomOfAnother(elementNameToMove, expectedEditPartTypeOfMovedElement, referenceElementName, expectedEditPartTypeOfReferenceElement, ZoomLevel.ZOOM_100); + } + + /** + * Move element a first time without F4 and check the location is the + * expected one.<BR> + * Move element a second time with F4 and check the location is the expected + * one (snap to another figure).<BR> + */ + private void moveTopOfElementNearBottomOfAnother(String elementNameToMove, Class<? extends EditPart> expectedEditPartTypeOfMovedElement, String referenceElementName, + Class<? extends EditPart> expectedEditPartTypeOfReferenceElement, ZoomLevel zoomLevel) { + editor.zoom(zoomLevel); + editor.scrollTo(0, 0); + + SWTBotGefEditPart elementToMove = editor.getEditPart(elementNameToMove, expectedEditPartTypeOfMovedElement); + // Select the element to move + editor.select(elementToMove); + + // Get the top center coordinates, just a little below, of the element + // to move + final Rectangle originalBounds = GraphicalHelper.getAbsoluteBoundsIn100Percent((GraphicalEditPart) elementToMove.part()); + final Point pointToDrag = originalBounds.getTop().getTranslated(0, 3); + Point scaledPointToDrag = new PrecisionPoint(pointToDrag); + GraphicalHelper.logical2screen(scaledPointToDrag, (IGraphicalEditPart) elementToMove.part()); + // Compute the drop destination (at 4 pixels of the bottom of another + // part) + final Rectangle targetNodeBounds = GraphicalHelper.getAbsoluteBoundsIn100Percent((GraphicalEditPart) editor.getEditPart(referenceElementName, expectedEditPartTypeOfReferenceElement).part()); + final Point endpoint = new Point(pointToDrag.x, targetNodeBounds.getBottom().y - 1); + Point scaledEndpoint = new PrecisionPoint(endpoint); + GraphicalHelper.logical2screen(scaledEndpoint, (IGraphicalEditPart) elementToMove.part()); + + // First move without F4 key pressed + editor.drag(scaledPointToDrag.x, scaledPointToDrag.y, scaledEndpoint.x, scaledEndpoint.y); + SWTBotUtils.waitAllUiEvents(); + // Get the new bounds and compare with the expected. It should be + // precisely where the drag has been done: at 4 pixels of the bottom of + // the other figure + Rectangle newBounds = GraphicalHelper.getAbsoluteBoundsIn100Percent((GraphicalEditPart) elementToMove.part()); + assertEquals("Element \"" + elementNameToMove + "\" is not at expected y location after move without F4 key pressed", targetNodeBounds.getBottom().y - 4, newBounds.getTop().y); + + // Move to initial location + undo(localSession.getOpenedSession()); + // Scroll to 0, 0 is needed because the first move can cause a scroll of + // the diagram not reverted by the Undo. + editor.scrollTo(0, 0); + + // Second move with F4 key pressed + editor.dragWithKey(scaledPointToDrag.x, scaledPointToDrag.y, scaledEndpoint.x, scaledEndpoint.y, SWT.F4); + SWTBotUtils.waitAllUiEvents(); + // Get the new bounds and compare with the expected. It should be + // aligned to the bottom of the other figure: at 1 pixel of the bottom + // as computed guide in SiriusSnapToGeometry.populateRowsAndCols(List) + newBounds = GraphicalHelper.getAbsoluteBoundsIn100Percent((GraphicalEditPart) elementToMove.part()); + assertEquals("Element \"" + elementNameToMove + "\" is not at expected location after move with F4 key pressed", targetNodeBounds.getBottom().y - 1, newBounds.getTop().y); + } + + private void resizeTopOfElementNearBottomOfAnother(String elementNameToMove, Class<? extends EditPart> expectedEditPartTypeOfMovedElement, String referenceElementName, + Class<? extends EditPart> expectedEditPartTypeOfReferenceElement) { + resizeTopOfElementNearBottomOfAnother(elementNameToMove, expectedEditPartTypeOfMovedElement, referenceElementName, expectedEditPartTypeOfReferenceElement, ZoomLevel.ZOOM_100); + } + + /** + * Resize element a first time without F4 and check the location is the + * expected one.<BR> + * Resize element a second time with F4 and check the location is the + * expected one (snap to another figure).<BR> + */ + private void resizeTopOfElementNearBottomOfAnother(String elementNameToMove, Class<? extends EditPart> expectedEditPartTypeOfMovedElement, String referenceElementName, + Class<? extends EditPart> expectedEditPartTypeOfReferenceElement, final ZoomLevel zoomLevel) { + editor.zoom(zoomLevel); + editor.scrollTo(0, 0); + + final SWTBotGefEditPart elementToMove = editor.getEditPart(elementNameToMove, expectedEditPartTypeOfMovedElement); + // Select the element to move + editor.select(elementToMove); + + // Get the top center coordinates of the element to move + final Rectangle originalBounds = GraphicalHelper.getAbsoluteBoundsIn100Percent((GraphicalEditPart) elementToMove.part()); + final Point pointToDrag = originalBounds.getTop(); + Point scaledPointToDrag = new PrecisionPoint(pointToDrag); + GraphicalHelper.logical2screen(scaledPointToDrag, (IGraphicalEditPart) elementToMove.part()); + // Compute the drop destination (at 4 pixels of the bottom of another + // part) + final Rectangle targetNodeBounds = GraphicalHelper.getAbsoluteBoundsIn100Percent((GraphicalEditPart) editor.getEditPart(referenceElementName, expectedEditPartTypeOfReferenceElement).part()); + final Point endpoint = new Point(pointToDrag.x, targetNodeBounds.getBottom().y - 4); + Point scaledEndpoint = new PrecisionPoint(endpoint); + GraphicalHelper.logical2screen(scaledEndpoint, (IGraphicalEditPart) elementToMove.part()); + + // First move without F4 key pressed + editor.drag(scaledPointToDrag.x, scaledPointToDrag.y, scaledEndpoint.x, scaledEndpoint.y); + SWTBotUtils.waitAllUiEvents(); + // Get the new bounds and compare with the expected. It should be + // precisely where the drag has been done: at 4 pixels of the bottom of + // the other figure + bot.waitUntil(new TopCondition((GraphicalEditPart) elementToMove.part(), targetNodeBounds.getBottom().y - 4, + "Element \"" + elementNameToMove + "\" is not at expected y location after resize without F4 key pressed", !ZoomLevel.ZOOM_100.equals(zoomLevel))); + + // Move to initial location + undo(localSession.getOpenedSession()); + // Scroll to 0, 0 is needed because the first move can cause a scroll of + // the diagram not reverted by the Undo. + editor.scrollTo(0, 0); + + // Second move with F4 key pressed + editor.dragWithKey(scaledPointToDrag.x, scaledPointToDrag.y, scaledEndpoint.x, scaledEndpoint.y, SWT.F4); + SWTBotUtils.waitAllUiEvents(); + // Get the new bounds and compare with the expected. It should be + // aligned to the bottom of the other figure: at 1 pixel of the bottom + // as computed guide in SiriusSnapToGeometry.populateRowsAndCols(List) + bot.waitUntil(new TopCondition((GraphicalEditPart) elementToMove.part(), targetNodeBounds.getBottom().y - 1, + "Element \"" + elementNameToMove + "\" is not at expected y location after resize with F4 key pressed", !ZoomLevel.ZOOM_100.equals(zoomLevel))); + } +} 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 34f69a03c9..bee4f57362 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 @@ -181,6 +181,7 @@ public class AllTestSuite extends TestCase { suite.addTestSuite(CloseWithoutSavingTest.class); suite.addTestSuite(CreateMandatoryElementsTest.class); suite.addTestSuite(LockedModelExplorerTest.class); + suite.addTestSuite(SnapAllShapesTest.class); } /** |
