Skip to content

Commit

Permalink
[1574] Add support of Edges as targets of single click tools
Browse files Browse the repository at this point in the history
Bug: #1574
Signed-off-by: Axel RICHARD <axel.richard@obeo.fr>
  • Loading branch information
AxelRICHARD committed Jan 12, 2023
1 parent 22a313f commit 4ce2602
Show file tree
Hide file tree
Showing 14 changed files with 621 additions and 77 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Expand Up @@ -10,6 +10,7 @@
=== Breaking changes

- [core] Records are now used as the implementations of `IInput`
- https://github.com/eclipse-sirius/sirius-components/issues/1574[#1574] [diagram] In `diagram.graphqls`, `SingleClickOnDiagramElementTool` member's `targetDescriptions` is now of new type `DiagramElementDescription` instead of `NodeDescription`.

=== Dependency update

Expand All @@ -24,6 +25,7 @@
- https://github.com/eclipse-sirius/sirius-components/issues/1559[#1559] [view] It is now possible to specify the (computed) width and height separately for a _Node Style_ (instead of a single size before, which always resulted in square shapes).
- https://github.com/eclipse-sirius/sirius-components/issues/1560[#1560] Remove unused `EditingContextCompletionProposalsDataFetcher`
- https://github.com/eclipse-sirius/sirius-components/issues/1426[#1426] [view] Add missing data type on initialDirectEditLabelExpression
- https://github.com/eclipse-sirius/sirius-components/issues/1574[#1574] [diagram] Single click tools can now be executed on Edges in addition to Nodes.


== v2023.1.0
Expand Down
Expand Up @@ -32,6 +32,7 @@
import org.eclipse.sirius.components.diagrams.Node;
import org.eclipse.sirius.components.diagrams.description.DiagramDescription;
import org.eclipse.sirius.components.diagrams.description.EdgeDescription;
import org.eclipse.sirius.components.diagrams.description.IDiagramElementDescription;
import org.eclipse.sirius.components.diagrams.description.NodeDescription;
import org.eclipse.sirius.components.diagrams.description.SynchronizationPolicy;
import org.eclipse.sirius.components.diagrams.tools.ITool;
Expand Down Expand Up @@ -258,15 +259,23 @@ private boolean checkPrecondition(Object targetElement, Object diagramElement, A
private List<ToolSection> createExtraToolSections(Object diagramElementDescription) {
List<ToolSection> extraToolSections = new ArrayList<>();

List<NodeDescription> targetDescriptions = new ArrayList<>();
List<IDiagramElementDescription> targetDescriptions = new ArrayList<>();
boolean unsynchronizedMapping = false;
//@formatter:off
if (diagramElementDescription instanceof NodeDescription) {
targetDescriptions.add((NodeDescription) diagramElementDescription);
unsynchronizedMapping = SynchronizationPolicy.UNSYNCHRONIZED.equals(((NodeDescription) diagramElementDescription).getSynchronizationPolicy());
} else if (diagramElementDescription instanceof EdgeDescription) {
EdgeDescription edgeDescription = (EdgeDescription) diagramElementDescription;
targetDescriptions.addAll(edgeDescription.getSourceNodeDescriptions());
if (diagramElementDescription instanceof NodeDescription nodeDescription) {
targetDescriptions.add(nodeDescription);
unsynchronizedMapping = SynchronizationPolicy.UNSYNCHRONIZED.equals(nodeDescription.getSynchronizationPolicy());
} else if (diagramElementDescription instanceof EdgeDescription edgeDescription) {
var optionalDiagramElementMapping = this.getDiagramElementMapping(edgeDescription);
var domainEdgeMapping = optionalDiagramElementMapping
.filter(EdgeMapping.class::isInstance)
.map(EdgeMapping.class::cast)
.filter(edgeMapping -> edgeMapping.isUseDomainElement());
if (domainEdgeMapping.isPresent()) {
targetDescriptions.add(edgeDescription);
} else {
targetDescriptions.addAll(edgeDescription.getSourceNodeDescriptions());
}
unsynchronizedMapping = SynchronizationPolicy.UNSYNCHRONIZED.equals(((EdgeDescription) diagramElementDescription).getSynchronizationPolicy());
}

Expand Down
Expand Up @@ -32,6 +32,7 @@
import org.eclipse.sirius.components.diagrams.Diagram;
import org.eclipse.sirius.components.diagrams.Node;
import org.eclipse.sirius.components.diagrams.description.EdgeDescription;
import org.eclipse.sirius.components.diagrams.description.IDiagramElementDescription;
import org.eclipse.sirius.components.diagrams.description.NodeDescription;
import org.eclipse.sirius.components.diagrams.tools.ITool;
import org.eclipse.sirius.components.diagrams.tools.SingleClickOnDiagramElementTool;
Expand Down Expand Up @@ -138,7 +139,7 @@ public List<ToolSection> getToolSections(Map<UUID, NodeDescription> id2NodeDescr
// @formatter:off
List<ITool> tools = this.getToolDescriptions(siriusToolSection).stream()
.filter(this::isSupported)
.map(toolDescription -> this.convertTool(id2NodeDescriptions, siriusDiagramDescription, toolDescription, interpreter))
.map(toolDescription -> this.convertTool(id2NodeDescriptions, edgeDescriptions, siriusDiagramDescription, toolDescription, interpreter))
.flatMap(Optional::stream)
.toList();
// @formatter:on
Expand Down Expand Up @@ -190,7 +191,7 @@ private List<AbstractToolDescription> getToolDescriptions(org.eclipse.sirius.dia
//@formatter:on
}

private List<NodeDescription> getParentNodeDescriptions(List<? extends AbstractNodeMapping> nodeMappings, Map<UUID, NodeDescription> id2NodeDescriptions) {
private List<IDiagramElementDescription> getParentNodeDescriptions(List<? extends AbstractNodeMapping> nodeMappings, Map<UUID, NodeDescription> id2NodeDescriptions) {
//@formatter:off
return nodeMappings.stream()
.map(AbstractNodeMapping::eContainer)
Expand All @@ -199,6 +200,9 @@ private List<NodeDescription> getParentNodeDescriptions(List<? extends AbstractN
.map(this.identifierProvider::getIdentifier)
.map(UUID::fromString)
.map(id2NodeDescriptions::get)
.filter(Objects::nonNull)
.filter(IDiagramElementDescription.class::isInstance)
.map(IDiagramElementDescription.class::cast)
.toList();
//@formatter:on
}
Expand All @@ -211,8 +215,8 @@ private boolean atLeastOneRootMapping(List<? extends AbstractNodeMapping> nodeMa
//@formatter:on
}

private Optional<ITool> convertTool(Map<UUID, NodeDescription> id2NodeDescriptions, org.eclipse.sirius.diagram.description.DiagramDescription siriusDiagramDescription,
AbstractToolDescription siriusTool, AQLInterpreter interpreter) {
private Optional<ITool> convertTool(Map<UUID, NodeDescription> id2NodeDescriptions, List<EdgeDescription> edgeDescriptions,
org.eclipse.sirius.diagram.description.DiagramDescription siriusDiagramDescription, AbstractToolDescription siriusTool, AQLInterpreter interpreter) {
Optional<ITool> result = Optional.empty();
if (siriusTool instanceof NodeCreationDescription) {
NodeCreationDescription nodeCreationTool = (NodeCreationDescription) siriusTool;
Expand All @@ -222,7 +226,7 @@ private Optional<ITool> convertTool(Map<UUID, NodeDescription> id2NodeDescriptio
result = Optional.of(this.convertContainerCreationDescription(id2NodeDescriptions, interpreter, containerCreationDescription));
} else if (siriusTool instanceof org.eclipse.sirius.viewpoint.description.tool.ToolDescription) {
org.eclipse.sirius.viewpoint.description.tool.ToolDescription toolDescription = (org.eclipse.sirius.viewpoint.description.tool.ToolDescription) siriusTool;
result = Optional.of(this.convertToolDescription(id2NodeDescriptions, interpreter, siriusDiagramDescription, toolDescription));
result = Optional.of(this.convertToolDescription(id2NodeDescriptions, edgeDescriptions, interpreter, siriusDiagramDescription, toolDescription));
} else if (siriusTool instanceof EdgeCreationDescription) {
EdgeCreationDescription edgeCreationDescription = (EdgeCreationDescription) siriusTool;
result = Optional.of(this.convertEdgeCreationDescription(id2NodeDescriptions, interpreter, edgeCreationDescription));
Expand All @@ -231,7 +235,7 @@ private Optional<ITool> convertTool(Map<UUID, NodeDescription> id2NodeDescriptio
result = Optional.of(this.convertDeleteElementDescription(id2NodeDescriptions, interpreter, deleteElementDescription));
} else if (siriusTool instanceof OperationAction) {
OperationAction operationAction = (OperationAction) siriusTool;
result = Optional.of(this.convertOperationAction(id2NodeDescriptions, interpreter, siriusDiagramDescription, operationAction));
result = Optional.of(this.convertOperationAction(id2NodeDescriptions, edgeDescriptions, interpreter, siriusDiagramDescription, operationAction));
}

return result;
Expand All @@ -241,7 +245,7 @@ private SingleClickOnDiagramElementTool convertNodeCreationDescription(Map<UUID,
String id = this.identifierProvider.getIdentifier(nodeCreationTool);
String label = new IdentifiedElementQuery(nodeCreationTool).getLabel();
String imagePath = this.toolImageProvider.getImage(nodeCreationTool);
List<NodeDescription> targetDescriptions = this.getParentNodeDescriptions(nodeCreationTool.getNodeMappings(), id2NodeDescriptions);
List<IDiagramElementDescription> targetDescriptions = this.getParentNodeDescriptions(nodeCreationTool.getNodeMappings(), id2NodeDescriptions);
var selectModelElementVariableOpt = new SelectModelElementVariableProvider().getSelectModelElementVariable(nodeCreationTool.getVariable());
String selectionDescriptionId = null;
if (selectModelElementVariableOpt.isPresent()) {
Expand All @@ -264,7 +268,7 @@ private SingleClickOnDiagramElementTool convertContainerCreationDescription(Map<
String id = this.identifierProvider.getIdentifier(containerCreationDescription);
String label = new IdentifiedElementQuery(containerCreationDescription).getLabel();
String imagePath = this.toolImageProvider.getImage(containerCreationDescription);
List<NodeDescription> targetDescriptions = this.getParentNodeDescriptions(containerCreationDescription.getContainerMappings(), id2NodeDescriptions);
List<IDiagramElementDescription> targetDescriptions = this.getParentNodeDescriptions(containerCreationDescription.getContainerMappings(), id2NodeDescriptions);
var selectModelElementVariableOpt = new SelectModelElementVariableProvider().getSelectModelElementVariable(containerCreationDescription.getVariable());
String selectionDescriptionId = null;
if (selectModelElementVariableOpt.isPresent()) {
Expand All @@ -282,8 +286,8 @@ private SingleClickOnDiagramElementTool convertContainerCreationDescription(Map<
// @formatter:on
}

private SingleClickOnDiagramElementTool convertToolDescription(Map<UUID, NodeDescription> id2NodeDescriptions, AQLInterpreter interpreter, DiagramDescription siriusDiagramDescription,
ToolDescription toolDescription) {
private SingleClickOnDiagramElementTool convertToolDescription(Map<UUID, NodeDescription> id2NodeDescriptions, List<EdgeDescription> edgeDescriptions, AQLInterpreter interpreter,
DiagramDescription siriusDiagramDescription, ToolDescription toolDescription) {
String id = this.identifierProvider.getIdentifier(toolDescription);
String label = new IdentifiedElementQuery(toolDescription).getLabel();
String imagePath = this.toolImageProvider.getImage(toolDescription);
Expand All @@ -294,10 +298,25 @@ private SingleClickOnDiagramElementTool convertToolDescription(Map<UUID, NodeDes
List<String> targetDescriptionIds = mappings.stream()
.map(this.identifierProvider::getIdentifier)
.toList();
List<NodeDescription> targetDescriptions = targetDescriptionIds.stream()

List<IDiagramElementDescription> targetNodeDescriptions = targetDescriptionIds.stream()
.map(UUID::fromString)
.map(id2NodeDescriptions::get)
.filter(Objects::nonNull)
.filter(IDiagramElementDescription.class::isInstance)
.map(IDiagramElementDescription.class::cast)
.toList();

List<IDiagramElementDescription> targetEdgeDescriptions = targetDescriptionIds.stream()
.map(UUID::fromString)
.flatMap(targetDescriptionUUID -> edgeDescriptions.stream().filter(edgeDescription -> edgeDescription.getId().equals(targetDescriptionUUID)))
.filter(Objects::nonNull)
.filter(IDiagramElementDescription.class::isInstance)
.map(IDiagramElementDescription.class::cast)
.toList();

List<IDiagramElementDescription> targetDescriptions = Stream.concat(targetNodeDescriptions.stream(), targetEdgeDescriptions.stream()).toList();

return SingleClickOnDiagramElementTool.newSingleClickOnDiagramElementTool(id)
.label(label)
.imageURL(imagePath)
Expand All @@ -308,8 +327,8 @@ private SingleClickOnDiagramElementTool convertToolDescription(Map<UUID, NodeDes
// @formatter:on
}

private SingleClickOnDiagramElementTool convertOperationAction(Map<UUID, NodeDescription> id2NodeDescriptions, AQLInterpreter interpreter, DiagramDescription siriusDiagramDescription,
OperationAction operationAction) {
private SingleClickOnDiagramElementTool convertOperationAction(Map<UUID, NodeDescription> id2NodeDescriptions, List<EdgeDescription> edgeDescriptions, AQLInterpreter interpreter,
DiagramDescription siriusDiagramDescription, OperationAction operationAction) {
String id = this.identifierProvider.getIdentifier(operationAction);
String label = new IdentifiedElementQuery(operationAction).getLabel();
String imagePath = this.toolImageProvider.getImage(operationAction);
Expand All @@ -320,10 +339,25 @@ private SingleClickOnDiagramElementTool convertOperationAction(Map<UUID, NodeDes
List<String> targetDescriptionIds = mappings.stream()
.map(this.identifierProvider::getIdentifier)
.toList();
List<NodeDescription> targetDescriptions = targetDescriptionIds.stream()

List<IDiagramElementDescription> targetNodeDescriptions = targetDescriptionIds.stream()
.map(UUID::fromString)
.map(id2NodeDescriptions::get)
.filter(Objects::nonNull)
.filter(IDiagramElementDescription.class::isInstance)
.map(IDiagramElementDescription.class::cast)
.toList();

List<IDiagramElementDescription> targetEdgeDescriptions = targetDescriptionIds.stream()
.map(UUID::fromString)
.flatMap(targetDescriptionUUID -> edgeDescriptions.stream().filter(edgeDescription -> edgeDescription.getId().equals(targetDescriptionUUID)))
.filter(Objects::nonNull)
.filter(IDiagramElementDescription.class::isInstance)
.map(IDiagramElementDescription.class::cast)
.toList();

List<IDiagramElementDescription> targetDescriptions = Stream.concat(targetNodeDescriptions.stream(), targetEdgeDescriptions.stream()).toList();

return SingleClickOnDiagramElementTool.newSingleClickOnDiagramElementTool(id)
.label(label)
.imageURL(imagePath)
Expand All @@ -336,10 +370,12 @@ private SingleClickOnDiagramElementTool convertOperationAction(Map<UUID, NodeDes

private List<DiagramElementMapping> getAllDiagramElementMappings(DiagramDescription siriusDiagramDescription) {
List<DiagramElementMapping> mappings = new ArrayList<>(siriusDiagramDescription.getDefaultLayer().getNodeMappings());
mappings.addAll(siriusDiagramDescription.getDefaultLayer().getEdgeMappings());
mappings.addAll(siriusDiagramDescription.getDefaultLayer().getContainerMappings());
mappings.addAll(this.getAllSubMappings(siriusDiagramDescription.getDefaultLayer().getContainerMappings()));
for (AdditionalLayer additionalLayer : siriusDiagramDescription.getAdditionalLayers()) {
mappings.addAll(additionalLayer.getNodeMappings());
mappings.addAll(additionalLayer.getEdgeMappings());
mappings.addAll(additionalLayer.getContainerMappings());
mappings.addAll(this.getAllSubMappings(additionalLayer.getContainerMappings()));
}
Expand Down Expand Up @@ -404,10 +440,12 @@ private SingleClickOnDiagramElementTool convertDeleteElementDescription(Map<UUID
List<String> targetDescriptionIds = mappings.stream()
.map(this.identifierProvider::getIdentifier)
.toList();
List<NodeDescription> targetDescriptions = targetDescriptionIds.stream()
List<IDiagramElementDescription> targetDescriptions = targetDescriptionIds.stream()
.map(UUID::fromString)
.map(id2NodeDescriptions::get)
.filter(Objects::nonNull)
.filter(IDiagramElementDescription.class::isInstance)
.map(IDiagramElementDescription.class::cast)
.toList();
return SingleClickOnDiagramElementTool.newSingleClickOnDiagramElementTool(id)
.label(label)
Expand Down
Expand Up @@ -23,7 +23,6 @@
import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramInput;
import org.eclipse.sirius.components.collaborative.diagrams.dto.ArrangeAllInput;
import org.eclipse.sirius.components.collaborative.diagrams.dto.ArrangeAllSuccessPayload;
import org.eclipse.sirius.components.collaborative.diagrams.dto.InvokeSingleClickOnDiagramElementToolInput;
import org.eclipse.sirius.components.collaborative.diagrams.messages.ICollaborativeDiagramMessageService;
import org.eclipse.sirius.components.core.api.ErrorPayload;
import org.eclipse.sirius.components.core.api.IEditingContext;
Expand Down Expand Up @@ -67,7 +66,7 @@ public boolean canHandle(IDiagramInput diagramInput) {
public void handle(One<IPayload> payloadSink, Many<ChangeDescription> changeDescriptionSink, IEditingContext editingContext, IDiagramContext diagramContext, IDiagramInput diagramInput) {
this.counter.increment();

String message = this.messageService.invalidInput(diagramInput.getClass().getSimpleName(), InvokeSingleClickOnDiagramElementToolInput.class.getSimpleName());
String message = this.messageService.invalidInput(diagramInput.getClass().getSimpleName(), ArrangeAllInput.class.getSimpleName());
IPayload payload = new ErrorPayload(diagramInput.id(), message);
ChangeDescription changeDescription = new ChangeDescription(ChangeKind.NOTHING, diagramInput.representationId(), diagramInput);

Expand Down

0 comments on commit 4ce2602

Please sign in to comment.