diff --git a/plugins/org.eclipse.sirius.diagram.sequence.ui/src/org/eclipse/sirius/diagram/sequence/ui/tool/internal/edit/policy/SequenceContainerCreationPolicy.java b/plugins/org.eclipse.sirius.diagram.sequence.ui/src/org/eclipse/sirius/diagram/sequence/ui/tool/internal/edit/policy/SequenceContainerCreationPolicy.java index 3972dcf652..9b9eea3731 100644 --- a/plugins/org.eclipse.sirius.diagram.sequence.ui/src/org/eclipse/sirius/diagram/sequence/ui/tool/internal/edit/policy/SequenceContainerCreationPolicy.java +++ b/plugins/org.eclipse.sirius.diagram.sequence.ui/src/org/eclipse/sirius/diagram/sequence/ui/tool/internal/edit/policy/SequenceContainerCreationPolicy.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2021 THALES GLOBAL SERVICES and others. + * Copyright (c) 2010, 2024 THALES GLOBAL SERVICES and others. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -101,7 +101,7 @@ protected Command getCreateNodeOnDiagramCommand(CreateRequest request, NodeCreat finishingEndEndPredecessor = SequenceGraphicalHelper.getEndBefore(diag, location.y + size.height); } - CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(startingEndPredecessor, finishingEndEndPredecessor, location), getRealLocation(request), request.getSize(), + CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(startingEndPredecessor, finishingEndEndPredecessor, location), getRealLocation(request), request.getSize(), getHost()); result = creationUtil.getNodeCreationCommand(diagram, tool); } else if (tool instanceof InstanceRoleCreationTool && diagram instanceof SequenceDDiagram) { @@ -110,7 +110,7 @@ protected Command getCreateNodeOnDiagramCommand(CreateRequest request, NodeCreat GraphicalHelper.screen2logical(location, (IGraphicalEditPart) getHost()); EObject predecessor = SequenceGraphicalHelper.getInstanceRoleBefore(diag, location.x); - CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(predecessor, location), getRealLocation(request), request.getSize(), getHost()); + CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(predecessor, location), getRealLocation(request), request.getSize(), getHost()); result = creationUtil.getNodeCreationCommand(diagram, tool); } else { result = super.getCreateNodeOnDiagramCommand(request, tool, diagram); @@ -140,7 +140,7 @@ protected Command getCreateContainerOnDiagramCommand(CreateRequest request, Cont List coverage = creationValidator.getCoverage(); Range expansionZone = creationValidator.getExpansionZone(); - CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(startingEndPredecessor, finishingEndPredecessor, coverage, getCreationRange(request)), + CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(startingEndPredecessor, finishingEndPredecessor, coverage, getCreationRange(request)), getRealLocation(request), getRealSize(ccdTool, request), getHost()); result = creationUtil.getContainerCreationDescription(diagram, ccdTool); diff --git a/plugins/org.eclipse.sirius.diagram.sequence.ui/src/org/eclipse/sirius/diagram/sequence/ui/tool/internal/edit/policy/SequenceNodeCreationPolicy.java b/plugins/org.eclipse.sirius.diagram.sequence.ui/src/org/eclipse/sirius/diagram/sequence/ui/tool/internal/edit/policy/SequenceNodeCreationPolicy.java index b6556720bc..f4930400bd 100644 --- a/plugins/org.eclipse.sirius.diagram.sequence.ui/src/org/eclipse/sirius/diagram/sequence/ui/tool/internal/edit/policy/SequenceNodeCreationPolicy.java +++ b/plugins/org.eclipse.sirius.diagram.sequence.ui/src/org/eclipse/sirius/diagram/sequence/ui/tool/internal/edit/policy/SequenceNodeCreationPolicy.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2013 THALES GLOBAL SERVICES. + * Copyright (c) 2010, 2024 THALES GLOBAL SERVICES. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -148,7 +148,7 @@ public void eraseTargetFeedback(Request request) { * {@inheritDoc} */ @Override - protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreationDescription tool, DNode viewnode) { + protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreationDescription tool, DNode viewnode, EditPart parentEditPartToUse) { if (tool instanceof ExecutionCreationTool || tool instanceof StateCreationTool || tool instanceof ObservationPointCreationTool) { SequenceDiagram sequenceDiagram = EditPartsHelper.getSequenceDiagram(getHost()); SequenceDDiagram diagram = sequenceDiagram.getSequenceDDiagram(); @@ -163,11 +163,11 @@ protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreation GraphicalHelper.logical2screen(bottomRight, (IGraphicalEditPart) getHost()); request.setSize(new Dimension(LayoutConstants.DEFAULT_EXECUTION_WIDTH, LayoutConstants.DEFAULT_EXECUTION_HEIGHT)); } - CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(startingEndPredecessor, startingEndPredecessor, location), getRealLocation(request), request.getSize(), - getHost()); + CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(startingEndPredecessor, startingEndPredecessor, location), getRealLocation(request, parentEditPartToUse), + request.getSize(), getHost()); return creationUtil.getNodeCreationCommand(viewnode, tool); } else { - return super.getCreateNodeOnNodeCommand(request, tool, viewnode); + return super.getCreateNodeOnNodeCommand(request, tool, viewnode, parentEditPartToUse); } } @@ -190,7 +190,8 @@ protected Command getCreateContainerInContainerCommand(CreateRequest request, Co Point location = request.getLocation().getCopy(); GraphicalHelper.screen2logical(location, (IGraphicalEditPart) getHost()); - CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(startingEndPredecessor, startingEndPredecessor, location), getRealLocation(request), getHost()); + CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(startingEndPredecessor, startingEndPredecessor, location), getRealLocation(request, getHost()), + getHost()); result = creationUtil.getContainerCreationDescription((DDiagramElementContainer) viewNodeContainer.eContainer(), tool); } else { result = UnexecutableCommand.INSTANCE; diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/CreationUtil.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/CreationUtil.java index 0c8caca00f..d76768e5bf 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/CreationUtil.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/CreationUtil.java @@ -66,19 +66,13 @@ */ public class CreationUtil { - /** The location of the clicked point. */ - private final Point realLocation; - - /** The computed size of the element to create. */ - private final Dimension realSize; + /** The location of the clicked point, the size and the parent edit part of the element to create. */ + private final RootLayoutData rootLayoutData; /** The EMF Command Factory. */ private final IDiagramCommandFactory emfCommandFactory; - /** The request. */ - private final CreateRequest request; - - /** The edit part. */ + /** The edit part on which the calling policy is installed. */ private final EditPart editPart; /** @@ -91,18 +85,17 @@ public class CreationUtil { * @param realLocation * the location of the clicked point. * @param editPart - * the edit part + * the edit part on which the calling policy is installed. * @since 0.9.0 */ public CreationUtil(final CreateRequest request, final IDiagramCommandFactory commandFactory, final Point realLocation, final EditPart editPart) { - this(request, commandFactory, realLocation, null, editPart); + // The size of the request take into account the zoom (got the size in 100%) + this(commandFactory, new RootLayoutData(editPart, realLocation.getCopy(), CreationUtil.adaptRequestSizeToZoomFactor(request, editPart)), editPart); } /** * Creates a new CreationUtil with the specified request and location. * - * @param request - * the request. * @param commandFactory * the emf command factory. * @param realLocation @@ -110,14 +103,27 @@ public CreationUtil(final CreateRequest request, final IDiagramCommandFactory co * @param realSize * the computed size of the element to create, null if the default size must be used * @param editPart - * the edit part + * the edit part on which the calling policy is installed. * @since 0.9.0 */ - public CreationUtil(final CreateRequest request, final IDiagramCommandFactory commandFactory, final Point realLocation, final Dimension realSize, final EditPart editPart) { - this.realLocation = realLocation; - this.realSize = realSize; - this.request = request; + public CreationUtil(final IDiagramCommandFactory commandFactory, final Point realLocation, final Dimension realSize, final EditPart editPart) { + this(commandFactory, new RootLayoutData(editPart, realLocation.getCopy(), realSize == null ? null : realSize.getCopy()), editPart); + } + + /** + * Creates a new CreationUtil with the specified request and location. + * + * @param commandFactory + * the emf command factory. + * @param rootLayoutData + * the layout data for the created element (clicked point, size and parent edit part). + * @param editPart + * the edit part on which the calling policy is installed. + * @since 0.9.0 + */ + public CreationUtil(final IDiagramCommandFactory commandFactory, final RootLayoutData rootLayoutData, final EditPart editPart) { this.emfCommandFactory = commandFactory; + this.rootLayoutData = rootLayoutData; this.editPart = editPart; } @@ -314,15 +320,7 @@ private Command createLayoutDataCommand() { return new Command() { @Override public void execute() { - // The size of the request take into account the zoom (got - // the size in 100%) - Dimension size = null; - if (realSize != null) { - size = realSize.getCopy(); - } else { - size = adaptRequestSizeToZoomFactor(); - } - SiriusLayoutDataManager.INSTANCE.addData(new RootLayoutData(editPart, realLocation.getCopy(), size)); + SiriusLayoutDataManager.INSTANCE.addData(rootLayoutData); } }; } @@ -332,7 +330,7 @@ public void execute() { * * @return A new dimension */ - private Dimension adaptRequestSizeToZoomFactor() { + public static Dimension adaptRequestSizeToZoomFactor(CreateRequest request, EditPart editPart) { if (request.getSize() == null) { return null; } diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/NodeCreationEditPolicy.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/NodeCreationEditPolicy.java index 9417512a02..92725cc065 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/NodeCreationEditPolicy.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/graphical/edit/policies/NodeCreationEditPolicy.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 THALES GLOBAL SERVICES. + * Copyright (c) 2007, 2024 THALES GLOBAL SERVICES. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -12,23 +12,32 @@ *******************************************************************************/ package org.eclipse.sirius.diagram.ui.graphical.edit.policies; +import java.util.Optional; + import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Point; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.transaction.util.TransactionUtil; +import org.eclipse.gef.EditPart; import org.eclipse.gef.commands.Command; import org.eclipse.gef.requests.CreateRequest; import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.figures.ResizableCompartmentFigure; import org.eclipse.gmf.runtime.notation.Node; +import org.eclipse.sirius.diagram.AbstractDNode; import org.eclipse.sirius.diagram.DDiagramElementContainer; import org.eclipse.sirius.diagram.DNode; +import org.eclipse.sirius.diagram.description.NodeMapping; import org.eclipse.sirius.diagram.description.tool.ContainerCreationDescription; import org.eclipse.sirius.diagram.description.tool.NodeCreationDescription; import org.eclipse.sirius.diagram.tools.api.command.IDiagramCommandFactory; import org.eclipse.sirius.diagram.tools.api.command.IDiagramCommandFactoryProvider; import org.eclipse.sirius.diagram.ui.business.internal.query.RequestQuery; +import org.eclipse.sirius.diagram.ui.business.internal.view.RootLayoutData; +import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramContainerEditPart; +import org.eclipse.sirius.diagram.ui.internal.edit.parts.AbstractDNodeListCompartmentEditPart; import org.eclipse.sirius.diagram.ui.tools.api.draw2d.ui.figures.FigureUtilities; import org.eclipse.sirius.diagram.ui.tools.api.editor.DDiagramEditor; import org.eclipse.sirius.viewpoint.description.tool.AbstractToolDescription; @@ -44,12 +53,25 @@ public class NodeCreationEditPolicy extends SiriusContainerEditPolicy { */ @Override protected Command getCreateCommand(CreateRequest request) { - if (!(getHost().getModel() instanceof Node)) { + + AbstractToolDescription tool = getTool(request); + GraphicalEditPart hostEditPartToUse = (GraphicalEditPart) getHost(); + if (getHost() instanceof GraphicalEditPart) { + boolean isBorderNodeCreationRequest = new RequestQuery(request).isDropOrCreationOfBorderNode(); + if (tool instanceof NodeCreationDescription nodeCreationDescriptionTool && isBorderNodeCreationRequest) { + // Search the correct edit part for this tool. It can be different than the host in case of "extra + // mappings" defined in the tool. + Optional optionalEditPartToUse = getParentEditPartWithExpectedMapping((GraphicalEditPart) getHost(), nodeCreationDescriptionTool.getNodeMappings()); + if (optionalEditPartToUse.isPresent()) { + hostEditPartToUse = optionalEditPartToUse.get(); + } + } + } + if (!(hostEditPartToUse.getModel() instanceof Node)) { return null; } + EObject containerElement = ((Node) hostEditPartToUse.getModel()).getElement(); - EObject containerElement = ((Node) getHost().getModel()).getElement(); - AbstractToolDescription tool = getTool(request); /* * Dispatch to the appropriate specialized command depending on the type * of the container element and the nature of the tool. @@ -58,14 +80,14 @@ protected Command getCreateCommand(CreateRequest request) { if (containerElement instanceof DDiagramElementContainer) { DDiagramElementContainer viewNodeContainer = (DDiagramElementContainer) containerElement; if (tool instanceof NodeCreationDescription) { - result = getCreateNodeInContainerCommand(request, (NodeCreationDescription) tool, viewNodeContainer); + result = getCreateNodeInContainerCommand(request, (NodeCreationDescription) tool, viewNodeContainer, hostEditPartToUse); } else if (tool instanceof ContainerCreationDescription) { result = getCreateContainerInContainerCommand(request, (ContainerCreationDescription) tool, viewNodeContainer); } } else if (containerElement instanceof DNode) { DNode viewNode = (DNode) containerElement; if (tool instanceof NodeCreationDescription) { - result = getCreateNodeOnNodeCommand(request, (NodeCreationDescription) tool, viewNode); + result = getCreateNodeOnNodeCommand(request, (NodeCreationDescription) tool, viewNode, hostEditPartToUse); } } return result; @@ -82,8 +104,8 @@ protected Command getCreateCommand(CreateRequest request) { * the node on which to create the new (bordered) node. * @return a command to create the new node. */ - protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreationDescription tool, DNode viewnode) { - CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(), getRealLocation(request), getHost()); + protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreationDescription tool, DNode viewnode, EditPart parentEditPartToUse) { + CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(), getRealLayoutData(request, parentEditPartToUse), parentEditPartToUse); return creationUtil.getNodeCreationCommand(viewnode, tool); } @@ -99,7 +121,7 @@ protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreation * @return a command to create the new container. */ protected Command getCreateContainerInContainerCommand(CreateRequest request, ContainerCreationDescription tool, DDiagramElementContainer viewNodeContainer) { - CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(), getRealLocation(request), getHost()); + CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(), getRealLocation(request, getHost()), getHost()); return creationUtil.getContainerCreationDescription(viewNodeContainer, tool); } @@ -112,10 +134,13 @@ protected Command getCreateContainerInContainerCommand(CreateRequest request, Co * the node creation tool description. * @param viewNodeContainer * the container on which to create the new (bordered) node. + * @param parentEditPartToUse + * parent EditPart to retrieve layout data (can be same as getHost(), but can also be another edit part + * according to extra mapping defined in tool, for border nodes for example). * @return a command to create the new node. */ - protected Command getCreateNodeInContainerCommand(CreateRequest request, NodeCreationDescription tool, DDiagramElementContainer viewNodeContainer) { - CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(), getRealLocation(request), getHost()); + protected Command getCreateNodeInContainerCommand(CreateRequest request, NodeCreationDescription tool, DDiagramElementContainer viewNodeContainer, EditPart parentEditPartToUse) { + CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(), getRealLayoutData(request, parentEditPartToUse), parentEditPartToUse); return creationUtil.getNodeCreationCommand(viewNodeContainer, tool); } @@ -135,18 +160,34 @@ protected AbstractToolDescription getTool(CreateRequest request) { } /** - * Computes the real location where the element must be created from the raw - * information passed in the request. + * Computes the real location where the element must be created from the raw information passed in the request. * * @param request * the creation request. + * @param parentEditPartToUse + * parent EditPart to retrieve layout data (can be same as getHost(), but can also be another edit part + * according to extra mapping defined in tool, for border nodes for example). * @return the real location where the element must be created. */ - protected Point getRealLocation(final CreateRequest request) { + protected Point getRealLocation(final CreateRequest request, EditPart parentEditPartToUse) { + return getRealLayoutData(request, parentEditPartToUse).getLocation(); + } + + /** + * Computes the real location where the element must be created from the raw information passed in the request. + * + * @param request + * the creation request. + * @param parentEditPartToUse + * parent EditPart to retrieve layout data (can be same as getHost(), but can also be another edit part + * according to extra mapping defined in tool, for border nodes for example). + * @return the real location where the element must be created. + */ + protected RootLayoutData getRealLayoutData(final CreateRequest request, EditPart parentEditPartToUse) { Point location = request.getLocation().getCopy(); final Point realLocation; - if (location != null && getHost() instanceof GraphicalEditPart) { - final IFigure fig = ((GraphicalEditPart) getHost()).getFigure(); + if (location != null && parentEditPartToUse instanceof GraphicalEditPart graphicalParentEditPart) { + final IFigure fig = graphicalParentEditPart.getFigure(); fig.translateToRelative(location); final Point containerLocation = fig.getBounds().getLocation(); location = new Point(location.x - containerLocation.x, location.y - containerLocation.y); @@ -160,7 +201,7 @@ protected Point getRealLocation(final CreateRequest request) { } else { scrollOffset = ((ResizableCompartmentFigure) fig).getScrollPane().getViewport().getViewLocation(); } - final Point shiftFromMarginOffset = FigureUtilities.getShiftFromMarginOffset((ResizableCompartmentFigure) fig, isBorderNodeCreationRequest, getHost()); + final Point shiftFromMarginOffset = FigureUtilities.getShiftFromMarginOffset((ResizableCompartmentFigure) fig, isBorderNodeCreationRequest, parentEditPartToUse); realLocation = new Point(location.x + scrollOffset.x - shiftFromMarginOffset.x, location.y + scrollOffset.y - shiftFromMarginOffset.y); } else { @@ -169,7 +210,30 @@ protected Point getRealLocation(final CreateRequest request) { } else { realLocation = location; } - return realLocation; + return new RootLayoutData(parentEditPartToUse, realLocation.getCopy(), CreationUtil.adaptRequestSizeToZoomFactor(request, parentEditPartToUse)); + } + + private Optional getParentEditPartWithExpectedMapping(GraphicalEditPart editPart, EList nodeMappings) { + Optional result = Optional.empty(); + if (editPart instanceof AbstractDNodeListCompartmentEditPart) { + result = getParentEditPartWithExpectedMapping((GraphicalEditPart) editPart.getParent(), nodeMappings); + } else if (editPart.getParent() instanceof AbstractDiagramContainerEditPart && ((AbstractDiagramContainerEditPart) editPart.getParent()).isRegionContainer()) { + result = getParentEditPartWithExpectedMapping((AbstractDiagramContainerEditPart) editPart.getParent(), nodeMappings); + } else { + for (NodeMapping nodeMapping : nodeMappings) { + if (editPart != null && editPart.getModel() instanceof Node && ((Node) editPart.getModel()).getElement() instanceof AbstractDNode) { + AbstractDNode abstractDNode = (AbstractDNode) ((Node) editPart.getModel()).getElement(); + if (abstractDNode.getMapping().equals(nodeMapping.eContainer())) { + result = Optional.of(editPart); + break; + } + } + } + } + if (result.isEmpty() && editPart.getParent() instanceof GraphicalEditPart) { + result = getParentEditPartWithExpectedMapping((GraphicalEditPart) editPart.getParent(), nodeMappings); + } + return result; } /**