Skip to content

Commit

Permalink
[2759] Reactivate the SelectionDialog
Browse files Browse the repository at this point in the history
In addition, this commit introduces the generic concept of Dialog
to make it possible to define any kind of dialog for diagram node tools.

Bug: #2759
Signed-off-by: Florian Barbin <[email protected]>
  • Loading branch information
florianbarbin committed Jun 20, 2024
1 parent a66d309 commit 99bd75e
Show file tree
Hide file tree
Showing 70 changed files with 1,951 additions and 1,151 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ More existing APIs will be migrated to this new common pattern.
- https://github.com/eclipse-sirius/sirius-web/issues/3575[#3575] [core] Restore support for studio palette colors
- https://github.com/eclipse-sirius/sirius-web/issues/3582[#3582] [tree] Restore the initial direct edit tree item label for the explorer
- https://github.com/eclipse-sirius/sirius-web/issues/3611[#3611] [diagram] Fix missing creation tool image in the contextual palette
- https://github.com/eclipse-sirius/sirius-web/issues/2759[#2759] [diagram] Reactivate the Selection Dialog

=== New Features

Expand Down
13 changes: 13 additions & 0 deletions doc/reference/variables.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,16 @@ Used to compute the nodes which should be considered as target of the edge
- `self`: The current element on which the operation is performed
- `editingContext`: The editing context is an abstraction used to access all the semantic data
- `environment`: The environment may contain some information on the application currently running

== NodeTool

=== SelectionDialogDescription

If a `SelectionDialogDescription` is defined on the `NodeTool`, the following variable becomes available:
- `selectedObject`: own the semantic element selected by the user in the selection dialog.

=== SelectionDialogDescription#SelectionCandidatesExpression

Used to compute the list of elements that should be displayed in the selection dialog
- `self`: The current diagram element on which the tool is currently applied.
- `targetElement` The semantic target element of the diagram element in the `self` variable.
3 changes: 3 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ private ITool convertTool(org.eclipse.sirius.components.diagrams.tools.ITool too
if (tool instanceof org.eclipse.sirius.components.diagrams.tools.SingleClickOnDiagramElementTool singleClickOnDiagramElementTool) {
convertedTool = new SingleClickOnDiagramElementTool(singleClickOnDiagramElementTool.getId(), singleClickOnDiagramElementTool.getLabel(),
singleClickOnDiagramElementTool.getIconURL(), singleClickOnDiagramElementTool.getTargetDescriptions(),
singleClickOnDiagramElementTool.getSelectionDescriptionId(), singleClickOnDiagramElementTool.isAppliesToDiagramRoot());
singleClickOnDiagramElementTool.getDialogDescriptionId(), singleClickOnDiagramElementTool.isAppliesToDiagramRoot());
}
if (tool instanceof org.eclipse.sirius.components.diagrams.tools.SingleClickOnTwoDiagramElementsTool singleClickOnTwoDiagramElementsTool) {
List<SingleClickOnTwoDiagramElementsCandidate> candidates = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ private SingleClickOnDiagramElementTool convertNodeCreationDescription(Map<Strin
List<String> imagePath = this.toolImageProvider.getIcon(nodeCreationTool);
List<IDiagramElementDescription> targetDescriptions = this.getParentNodeDescriptions(nodeCreationTool.getNodeMappings(), id2NodeDescriptions);
var selectModelElementVariableOpt = new SelectModelElementVariableProvider().getSelectModelElementVariable(nodeCreationTool.getVariable());
String selectionDescriptionId = null;
String dialogDescriptionId = null;
if (selectModelElementVariableOpt.isPresent()) {
selectionDescriptionId = this.identifierProvider.getIdentifier(selectModelElementVariableOpt.get());
dialogDescriptionId = this.identifierProvider.getIdentifier(selectModelElementVariableOpt.get());
}
// @formatter:off
return SingleClickOnDiagramElementTool.newSingleClickOnDiagramElementTool(id)
Expand All @@ -245,7 +245,7 @@ private SingleClickOnDiagramElementTool convertNodeCreationDescription(Map<Strin
.handler(this.createNodeCreationHandler(interpreter, nodeCreationTool))
.targetDescriptions(targetDescriptions)
.appliesToDiagramRoot(this.atLeastOneRootMapping(nodeCreationTool.getNodeMappings()))
.selectionDescriptionId(selectionDescriptionId)
.dialogDescriptionId(dialogDescriptionId)
.build();
// @formatter:on
}
Expand All @@ -257,9 +257,9 @@ private SingleClickOnDiagramElementTool convertContainerCreationDescription(Map<
List<String> imagePath = this.toolImageProvider.getIcon(containerCreationDescription);
List<IDiagramElementDescription> targetDescriptions = this.getParentNodeDescriptions(containerCreationDescription.getContainerMappings(), id2NodeDescriptions);
var selectModelElementVariableOpt = new SelectModelElementVariableProvider().getSelectModelElementVariable(containerCreationDescription.getVariable());
String selectionDescriptionId = null;
String dialogDescriptionId = null;
if (selectModelElementVariableOpt.isPresent()) {
selectionDescriptionId = this.identifierProvider.getIdentifier(selectModelElementVariableOpt.get());
dialogDescriptionId = this.identifierProvider.getIdentifier(selectModelElementVariableOpt.get());
}
// @formatter:off
return SingleClickOnDiagramElementTool.newSingleClickOnDiagramElementTool(id)
Expand All @@ -268,7 +268,7 @@ private SingleClickOnDiagramElementTool convertContainerCreationDescription(Map<
.handler(this.createContainerCreationHandler(interpreter, containerCreationDescription))
.targetDescriptions(targetDescriptions)
.appliesToDiagramRoot(this.atLeastOneRootMapping(containerCreationDescription.getContainerMappings()))
.selectionDescriptionId(selectionDescriptionId)
.dialogDescriptionId(dialogDescriptionId)
.build();
// @formatter:on
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*******************************************************************************/
package org.eclipse.sirius.components.collaborative.diagrams.dto;

import java.util.List;
import java.util.UUID;

import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramInput;
Expand All @@ -22,5 +23,5 @@
* @author pcdavid
*/
public record InvokeSingleClickOnDiagramElementToolInput(UUID id, String editingContextId, String representationId, String diagramElementId, String toolId, double startingPositionX,
double startingPositionY, String selectedObjectId) implements IDiagramInput {
double startingPositionY, List<ToolVariable> variables) implements IDiagramInput {
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*
* @author mcharfadi
*/
public record SingleClickOnDiagramElementTool(String id, String label, List<String> iconURL, List<IDiagramElementDescription> targetDescriptions, String selectionDescriptionId,
public record SingleClickOnDiagramElementTool(String id, String label, List<String> iconURL, List<IDiagramElementDescription> targetDescriptions, String dialogDescriptionId,
boolean appliesToDiagramRoot) implements ITool {

public SingleClickOnDiagramElementTool {
Expand Down Expand Up @@ -53,7 +53,7 @@ public static final class Builder {

private List<IDiagramElementDescription> targetDescriptions;

private String selectionDescriptionId;
private String dialogDescriptionId;

private boolean appliesToDiagramRoot;

Expand Down Expand Up @@ -81,13 +81,13 @@ public Builder appliesToDiagramRoot(boolean appliesToDiagramRoot) {
return this;
}

public Builder selectionDescriptionId(String selectionDescriptionId) {
this.selectionDescriptionId = selectionDescriptionId;
public Builder dialogDescriptionId(String dialogDescriptionId) {
this.dialogDescriptionId = dialogDescriptionId;
return this;
}

public SingleClickOnDiagramElementTool build() {
return new SingleClickOnDiagramElementTool(this.id, this.label, this.iconURL, this.targetDescriptions, this.selectionDescriptionId, this.appliesToDiagramRoot);
return new SingleClickOnDiagramElementTool(this.id, this.label, this.iconURL, this.targetDescriptions, this.dialogDescriptionId, this.appliesToDiagramRoot);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.components.collaborative.diagrams.dto;

/**
* Represents a ToolVariable entry.
* @author fbarbin
*/
public record ToolVariable(String name, String value, ToolVariableType type) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.components.collaborative.diagrams.dto;

/**
* Represent the Type of the Tool Variable.
*
* @author fbarbin
*/
public enum ToolVariableType {
/**
* The Value is a simple string.
*/
STRING,
/**
* The value represents an Object ID.
*/
OBJECT_ID,
/**
* The value represent an Array of Object IDs, separated by a ",".
*/
OBJECT_ID_ARRAY
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*******************************************************************************/
package org.eclipse.sirius.components.collaborative.diagrams.handlers;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

Expand All @@ -27,6 +28,7 @@
import org.eclipse.sirius.components.collaborative.diagrams.api.IToolService;
import org.eclipse.sirius.components.collaborative.diagrams.dto.InvokeSingleClickOnDiagramElementToolInput;
import org.eclipse.sirius.components.collaborative.diagrams.dto.InvokeSingleClickOnDiagramElementToolSuccessPayload;
import org.eclipse.sirius.components.collaborative.diagrams.dto.ToolVariable;
import org.eclipse.sirius.components.collaborative.diagrams.messages.ICollaborativeDiagramMessageService;
import org.eclipse.sirius.components.core.api.Environment;
import org.eclipse.sirius.components.core.api.ErrorPayload;
Expand Down Expand Up @@ -62,6 +64,8 @@
@Service
public class InvokeSingleClickOnDiagramElementToolEventHandler implements IDiagramEventHandler {

private static final String OBJECT_ID_ARRAY_SEPARATOR = ",";

private final Logger logger = LoggerFactory.getLogger(InvokeSingleClickOnDiagramElementToolEventHandler.class);

private final IObjectService objectService;
Expand All @@ -76,6 +80,7 @@ public class InvokeSingleClickOnDiagramElementToolEventHandler implements IDiagr

private final IRepresentationDescriptionSearchService representationDescriptionSearchService;


public InvokeSingleClickOnDiagramElementToolEventHandler(IObjectService objectService, IDiagramQueryService diagramQueryService, IToolService toolService,
ICollaborativeDiagramMessageService messageService, MeterRegistry meterRegistry, IRepresentationDescriptionSearchService representationDescriptionSearchService) {
this.objectService = Objects.requireNonNull(objectService);
Expand Down Expand Up @@ -114,7 +119,7 @@ public void handle(One<IPayload> payloadSink, Many<ChangeDescription> changeDesc
// @formatter:on
if (optionalTool.isPresent()) {
IStatus status = this.executeTool(editingContext, diagramContext, input.diagramElementId(), optionalTool.get(), input.startingPositionX(), input.startingPositionY(),
input.selectedObjectId());
input.variables());
if (status instanceof Success success) {
WorkbenchSelection newSelection = null;
Object newSelectionParameter = success.getParameters().get(Success.NEW_SELECTION);
Expand All @@ -134,7 +139,7 @@ public void handle(One<IPayload> payloadSink, Many<ChangeDescription> changeDesc
}

private IStatus executeTool(IEditingContext editingContext, IDiagramContext diagramContext, String diagramElementId, SingleClickOnDiagramElementTool tool, double startingPositionX,
double startingPositionY, String selectedObjectId) {
double startingPositionY, List<ToolVariable> variables) {
IStatus result = new Failure("");
Diagram diagram = diagramContext.getDiagram();
Optional<Node> node = this.diagramQueryService.findNodeById(diagram, diagramElementId);
Expand All @@ -149,24 +154,47 @@ private IStatus executeTool(IEditingContext editingContext, IDiagramContext diag

if (self.isPresent()) {
VariableManager variableManager = this.populateVariableManager(editingContext, diagramContext, node, edge, self);
String selectionDescriptionId = tool.getSelectionDescriptionId();
if (selectionDescriptionId != null && selectedObjectId != null) {
var selectionDescriptionOpt = this.representationDescriptionSearchService.findById(editingContext, selectionDescriptionId);
var selectedObjectOpt = this.objectService.getObject(editingContext, selectedObjectId);
if (selectionDescriptionOpt.isPresent() && selectedObjectOpt.isPresent()) {
variableManager.put(SingleClickOnDiagramElementTool.SELECTED_OBJECT, selectedObjectOpt.get());
}
String dialogDescriptionId = tool.getDialogDescriptionId();
if (dialogDescriptionId != null && !variables.isEmpty()) {
this.handleDialogVariables(editingContext, variableManager, variables);
}
if (selectionDescriptionId == null || selectedObjectId != null) {

//We do not apply the tool if a dialog is defined but no variables have been provided
if (dialogDescriptionId == null || !variables.isEmpty()) {
result = tool.getHandler().apply(variableManager);
Position newPosition = Position.at(startingPositionX, startingPositionY);

diagramContext.getDiagramEvents().add(new SinglePositionEvent(diagramElementId, newPosition));
}
}
return result;
}

private void handleDialogVariables(IEditingContext editingContext, VariableManager variableManager, List<ToolVariable> variables) {
variables.forEach(toolVariable -> {
this.handleToolVariable(toolVariable, editingContext, variableManager);
});
}

private void handleToolVariable(ToolVariable toolvariable, IEditingContext editingContext, VariableManager variableManager) {
switch (toolvariable.type()) {
case STRING -> variableManager.put(toolvariable.name(), toolvariable.value());
case OBJECT_ID -> {
var optionalObject = this.objectService.getObject(editingContext, toolvariable.value());
variableManager.put(toolvariable.name(), optionalObject.orElse(null));
}
case OBJECT_ID_ARRAY -> {
String value = toolvariable.value();
List<String> objectsIds = List.of(value.split(OBJECT_ID_ARRAY_SEPARATOR));
List<Object> objects = objectsIds.stream()
.map(objectId -> this.objectService.getObject(editingContext, objectId))
.map(optionalObject -> optionalObject.orElse(null))
.toList();
variableManager.put(toolvariable.name(), objects);
}
default -> this.logger.warn("Unexpected value: " + toolvariable.type());
}
}

private Optional<Object> getCurrentContext(IEditingContext editingContext, String diagramElementId, SingleClickOnDiagramElementTool tool, Diagram diagram, Optional<Node> node,
Optional<Edge> edge) {
Optional<Object> self = Optional.empty();
Expand Down
Loading

0 comments on commit 99bd75e

Please sign in to comment.