From a4f2079dabc1211ba3c516335b65173cde001153 Mon Sep 17 00:00:00 2001 From: Axel RICHARD Date: Wed, 29 Apr 2026 14:26:11 +0200 Subject: [PATCH] [2179] Improve selection dialog tree contents Bug: https://github.com/eclipse-syson/syson/issues/2179 Signed-off-by: Axel RICHARD --- CHANGELOG.adoc | 1 + .../general/view/GVTopNodeCreationTests.java | 64 ++++- .../services/DiagramQueryExposeService.java | 13 +- .../services/aql/DiagramQueryAQLService.java | 8 - ...electionDialogFragmentIdentityService.java | 50 ++++ ...ONSelectionDialogFragmentLabelService.java | 54 ++++ ...ONSelectionDialogFragmentServicesTest.java | 140 ++++++++++ .../views/syson-diagram-common-view/pom.xml | 4 + .../common/view/services/ViewToolService.java | 248 ++++++++++++------ .../ActorCompartmentNodeToolProvider.java | 3 +- .../tools/ExhibitStateNodeToolProvider.java | 8 +- .../view/tools/FlowNodeToolProvider.java | 3 +- .../NamespaceImportNodeToolProvider.java | 3 +- ...equirementCompartmentNodeToolProvider.java | 13 +- .../tools/PerformActionNodeToolProvider.java | 3 +- .../view/tools/SatisfyNodeToolProvider.java | 4 +- .../SatisfyRequirementNodeToolProvider.java | 4 +- ...akeholdersCompartmentNodeToolProvider.java | 3 +- .../tools/StateSubactionNodeToolProvider.java | 3 +- .../SubjectCompartmentNodeToolProvider.java | 3 +- .../pages/release-notes/2026.5.0.adoc | 1 + scripts/check-coverage.jsh | 4 +- 22 files changed, 525 insertions(+), 112 deletions(-) create mode 100644 backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/selectiondialog/services/SysONSelectionDialogFragmentIdentityService.java create mode 100644 backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/selectiondialog/services/SysONSelectionDialogFragmentLabelService.java create mode 100644 backend/services/syson-tree-services/src/test/java/org/eclipse/syson/tree/explorer/services/SysONSelectionDialogFragmentServicesTest.java diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 65ab6497e..d32824422 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -88,6 +88,7 @@ Also use that same tool in the `interconnection` compartment. - https://github.com/eclipse-syson/syson/issues/2172[#2172] [diagrams] Add keybinding to the _Duplicate Element_ tool (ctrl+d). - https://github.com/eclipse-syson/syson/issues/2166[#2166] [diagrams] Reorganize tools to create `ExhibitStateUsage` graphical nodes, to ends up with two tools, one for parallel, one for non-parallel. Both tools optionally allow selecting an existing `StateUsage` to exhibit. +- https://github.com/eclipse-syson/syson/issues/2179[#2179] [diagrams] Improve selection dialog by regrouping all standard libraries candidates under a "Libraries" category. === New features diff --git a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVTopNodeCreationTests.java b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVTopNodeCreationTests.java index 5c54dea2f..290e517c2 100644 --- a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVTopNodeCreationTests.java +++ b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVTopNodeCreationTests.java @@ -48,6 +48,7 @@ import org.eclipse.sirius.components.graphql.tests.ExecuteEditingContextFunctionRunner; import org.eclipse.sirius.components.graphql.tests.ExecuteEditingContextFunctionSuccessPayload; import org.eclipse.sirius.components.trees.Tree; +import org.eclipse.sirius.components.trees.TreeItem; import org.eclipse.sirius.components.view.diagram.NodeTool; import org.eclipse.sirius.components.view.diagram.SelectionDialogDescription; import org.eclipse.sirius.components.view.emf.diagram.IDiagramIdProvider; @@ -73,6 +74,7 @@ import org.eclipse.syson.sysml.LibraryPackage; import org.eclipse.syson.sysml.Namespace; import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.tree.explorer.fragments.LibrariesDirectory; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers; import org.eclipse.syson.util.ViewConstants; @@ -98,6 +100,10 @@ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class GVTopNodeCreationTests extends AbstractIntegrationTests { + private static final String KERML_SELECTION_DIALOG_ID = UUID.nameUUIDFromBytes("SysON_KerML_Directory".getBytes()).toString(); + + private static final String SYSML_SELECTION_DIALOG_ID = UUID.nameUUIDFromBytes("SysON_SysML_Directory".getBytes()).toString(); + private final IDescriptionNameGenerator descriptionNameGenerator = new SDVDescriptionNameGenerator(); @Autowired @@ -358,12 +364,62 @@ public void givenAnEmptySysMLProjectWhenWeSubscribeToTheSelectionDialogTreeOfThe var input = new SelectionDialogTreeEventInput(UUID.randomUUID(), GeneralViewEmptyTestProjectData.EDITING_CONTEXT, representationId); var treeFlux = this.selectionDialogTreeEventSubscriptionRunner.run(input).flux(); - var hasResourceRootContent = this.getTreeSubscriptionConsumer(tree -> { - // 95 is the number of standard libraries - assertThat(tree.getChildren()).isNotEmpty().hasSize(95); + var hasSelectionDialogRootContent = this.getTreeSubscriptionConsumer(tree -> { + assertThat(tree.getChildren()).isNotEmpty(); + + TreeItem librariesItem = tree.getChildren().stream() + .filter(treeItem -> LibrariesDirectory.LIBRARIES_DIRECTORY_ID.equals(treeItem.getId())) + .findFirst() + .orElseThrow(); + assertThat(librariesItem.getLabel().toString()).isEqualTo("Libraries"); + assertThat(librariesItem.isEditable()).isFalse(); + assertThat(librariesItem.isDeletable()).isFalse(); + assertThat(librariesItem.isSelectable()).isFalse(); + assertThat(librariesItem.isHasChildren()).isTrue(); + + assertThat(tree.getChildren()).anySatisfy(treeItem -> { + assertThat(treeItem.getId()).isEqualTo(LibrariesDirectory.LIBRARIES_DIRECTORY_ID); + assertThat(treeItem.getLabel().toString()).isEqualTo("Libraries"); + }); }); + + var expandedRepresentationId = this.representationIdBuilder.buildSelectionRepresentationId(selectionDialogDescriptionId.get().get(), GeneralViewEmptyTestProjectData.EDITING_CONTEXT, + List.of(LibrariesDirectory.LIBRARIES_DIRECTORY_ID)); + var expandedInput = new SelectionDialogTreeEventInput(UUID.randomUUID(), GeneralViewEmptyTestProjectData.EDITING_CONTEXT, expandedRepresentationId); + var expandedTreeFlux = this.selectionDialogTreeEventSubscriptionRunner.run(expandedInput).flux(); + + var hasExpandedLibrariesContent = this.getTreeSubscriptionConsumer(tree -> { + TreeItem librariesItem = tree.getChildren().stream() + .filter(treeItem -> LibrariesDirectory.LIBRARIES_DIRECTORY_ID.equals(treeItem.getId())) + .findFirst() + .orElseThrow(); + + assertThat(librariesItem.getChildren()).hasSize(2); + assertThat(librariesItem.getChildren()).anySatisfy(treeItem -> { + assertThat(treeItem.getId()).isEqualTo(KERML_SELECTION_DIALOG_ID); + assertThat(treeItem.getLabel().toString()).isEqualTo("KerML"); + assertThat(treeItem.isEditable()).isFalse(); + assertThat(treeItem.isDeletable()).isFalse(); + assertThat(treeItem.isSelectable()).isFalse(); + assertThat(treeItem.isHasChildren()).isTrue(); + }); + assertThat(librariesItem.getChildren()).anySatisfy(treeItem -> { + assertThat(treeItem.getId()).isEqualTo(SYSML_SELECTION_DIALOG_ID); + assertThat(treeItem.getLabel().toString()).isEqualTo("SysML"); + assertThat(treeItem.isEditable()).isFalse(); + assertThat(treeItem.isDeletable()).isFalse(); + assertThat(treeItem.isSelectable()).isFalse(); + assertThat(treeItem.isHasChildren()).isTrue(); + }); + }); + StepVerifier.create(treeFlux) - .consumeNextWith(hasResourceRootContent) + .consumeNextWith(hasSelectionDialogRootContent) + .thenCancel() + .verify(Duration.ofSeconds(10)); + + StepVerifier.create(expandedTreeFlux) + .consumeNextWith(hasExpandedLibrariesContent) .thenCancel() .verify(Duration.ofSeconds(10)); } diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryExposeService.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryExposeService.java index 35b76a90c..d1b74fcb7 100644 --- a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryExposeService.java +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryExposeService.java @@ -17,10 +17,8 @@ import java.util.List; import java.util.Objects; import java.util.Set; -import java.util.stream.Stream; import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EObject; import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.syson.diagram.services.utils.ViewFilterSwitch; @@ -130,16 +128,7 @@ public List getExposedSubjects(Element element, EClass domainTyp .toList(); } - public List getAllReachableRequirements(EObject eObject) { - List allRequirementUsages = this.utilService.getAllReachableType(eObject, SysmlPackage.eINSTANCE.getRequirementUsage(), false); - List allRequirementDefinitions = this.utilService.getAllReachableType(eObject, SysmlPackage.eINSTANCE.getRequirementDefinition(), false); - return Stream.concat(allRequirementUsages.stream(), allRequirementDefinitions.stream()) - .filter(Element.class::isInstance) - .map(Element.class::cast) - .toList(); - } - - Set getDirectExposedElements(ViewUsage viewUsage) { + private Set getDirectExposedElements(ViewUsage viewUsage) { var directExposedElements = new HashSet(); List exposedElements = viewUsage.getOwnedRelationship().stream() .filter(Expose.class::isInstance) diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramQueryAQLService.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramQueryAQLService.java index eecfab937..862b47e43 100644 --- a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramQueryAQLService.java +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramQueryAQLService.java @@ -16,7 +16,6 @@ import java.util.Objects; import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EObject; import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.diagrams.Diagram; @@ -79,13 +78,6 @@ public boolean canCreateFlowUsage(ConnectionUsage connection) { return this.diagramQueryElementService.canCreateFlowUsage(connection); } - /** - * {@link DiagramQueryExposeService#getAllReachableRequirements(EObject)}. - */ - public List getAllReachableRequirements(EObject eObject) { - return this.diagramQueryExposeService.getAllReachableRequirements(eObject); - } - /** * {@link DiagramQueryLabelService#getBorderNodeUsageLabel(Usage)}. */ diff --git a/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/selectiondialog/services/SysONSelectionDialogFragmentIdentityService.java b/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/selectiondialog/services/SysONSelectionDialogFragmentIdentityService.java new file mode 100644 index 000000000..27cb393bd --- /dev/null +++ b/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/selectiondialog/services/SysONSelectionDialogFragmentIdentityService.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2026 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.syson.tree.selectiondialog.services; + +import org.eclipse.sirius.components.core.api.IIdentityServiceDelegate; +import org.eclipse.syson.tree.explorer.services.api.ISysONExplorerFragment; +import org.springframework.stereotype.Service; + +/** + * Identity service for SelectionDialog, to handle ISysONExplorerFragment elements. + * + * @author arichard + */ +@Service +public class SysONSelectionDialogFragmentIdentityService implements IIdentityServiceDelegate { + + @Override + public boolean canHandle(Object object) { + return object instanceof ISysONExplorerFragment; + } + + @Override + public String getId(Object object) { + String id = null; + if (object instanceof ISysONExplorerFragment fragment) { + id = fragment.getId(); + } + return id; + } + + @Override + public String getKind(Object object) { + String kind = null; + if (object instanceof ISysONExplorerFragment fragment) { + kind = fragment.getKind(); + } + return kind; + } + +} diff --git a/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/selectiondialog/services/SysONSelectionDialogFragmentLabelService.java b/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/selectiondialog/services/SysONSelectionDialogFragmentLabelService.java new file mode 100644 index 000000000..e87baf582 --- /dev/null +++ b/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/selectiondialog/services/SysONSelectionDialogFragmentLabelService.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2026 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.syson.tree.selectiondialog.services; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.sirius.components.core.api.ILabelServiceDelegate; +import org.eclipse.sirius.components.core.api.labels.StyledString; +import org.eclipse.syson.tree.explorer.services.api.ISysONExplorerFragment; +import org.springframework.stereotype.Service; + +/** + * Label service for SelectionDialog, to handle ISysONExplorerFragment elements. + * + * @author arichard + */ +@Service +public class SysONSelectionDialogFragmentLabelService implements ILabelServiceDelegate { + + @Override + public boolean canHandle(Object object) { + return object instanceof ISysONExplorerFragment; + } + + @Override + public StyledString getStyledLabel(Object object) { + String label = ""; + if (object instanceof ISysONExplorerFragment fragment) { + label = fragment.getLabel(); + } + return StyledString.of(label); + } + + @Override + public List getImagePaths(Object object) { + List imagePaths = new ArrayList<>(); + if (object instanceof ISysONExplorerFragment fragment) { + imagePaths = fragment.getIconURL(); + } + return imagePaths; + } + +} diff --git a/backend/services/syson-tree-services/src/test/java/org/eclipse/syson/tree/explorer/services/SysONSelectionDialogFragmentServicesTest.java b/backend/services/syson-tree-services/src/test/java/org/eclipse/syson/tree/explorer/services/SysONSelectionDialogFragmentServicesTest.java new file mode 100644 index 000000000..562557cf1 --- /dev/null +++ b/backend/services/syson-tree-services/src/test/java/org/eclipse/syson/tree/explorer/services/SysONSelectionDialogFragmentServicesTest.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2026 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.syson.tree.explorer.services; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.RepresentationMetadata; +import org.eclipse.syson.tree.explorer.services.api.ISysONExplorerFragment; +import org.eclipse.syson.tree.selectiondialog.services.SysONSelectionDialogFragmentIdentityService; +import org.eclipse.syson.tree.selectiondialog.services.SysONSelectionDialogFragmentLabelService; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** + * Tests for selection dialog services handling {@link ISysONExplorerFragment}. + * + * @author arichard + */ +@SuppressWarnings("checkstyle:MultipleStringLiterals") +public class SysONSelectionDialogFragmentServicesTest { + + @Test + @DisplayName("GIVEN a selection dialog fragment identity service, WHEN the input is a fragment or not, THEN ids and kinds are resolved with the expected fallback") + public void identityServiceHandlesFragmentsAndFallsBackForOtherObjects() { + var service = new SysONSelectionDialogFragmentIdentityService(); + var fragment = new TestFragment("fragment-id", "fragment-kind", "Fragment", List.of("icons/LibraryResource.svg")); + + assertThat(service.canHandle(fragment)).isTrue(); + assertThat(service.canHandle("not-a-fragment")).isFalse(); + assertThat(service.getId(fragment)).isEqualTo("fragment-id"); + assertThat(service.getKind(fragment)).isEqualTo("fragment-kind"); + assertThat(service.getId("not-a-fragment")).isNull(); + assertThat(service.getKind("not-a-fragment")).isNull(); + } + + @Test + @DisplayName("GIVEN a selection dialog fragment label service, WHEN the input is a fragment or not, THEN labels and icons are resolved with the expected fallback") + public void labelServiceHandlesFragmentsAndFallsBackForOtherObjects() { + var service = new SysONSelectionDialogFragmentLabelService(); + var fragment = new TestFragment("fragment-id", "fragment-kind", "Fragment", List.of("icons/LibraryResource.svg")); + + assertThat(service.canHandle(fragment)).isTrue(); + assertThat(service.canHandle("not-a-fragment")).isFalse(); + assertThat(service.getStyledLabel(fragment).toString()).isEqualTo("Fragment"); + assertThat(service.getImagePaths(fragment)).containsExactly("icons/LibraryResource.svg"); + assertThat(service.getStyledLabel("not-a-fragment").toString()).isEmpty(); + assertThat(service.getImagePaths("not-a-fragment")).isEmpty(); + } + + /** + * Simple {@link ISysONExplorerFragment} stub used to exercise selection dialog delegates. + * + * @author arichard + */ + private static final class TestFragment implements ISysONExplorerFragment { + + private final String id; + + private final String kind; + + private final String label; + + private final List iconURL; + + private TestFragment(String id, String kind, String label, List iconURL) { + this.id = id; + this.kind = kind; + this.label = label; + this.iconURL = iconURL; + } + + @Override + public String getId() { + return this.id; + } + + @Override + public String getTooltip() { + return this.label; + } + + @Override + public String getLabel() { + return this.label; + } + + @Override + public String getKind() { + return this.kind; + } + + @Override + public Object getParent() { + return null; + } + + @Override + public List getIconURL() { + return this.iconURL; + } + + @Override + public boolean hasChildren(IEditingContext editingContext, List existingRepresentations, List expandedIds, List activeFilterIds) { + return false; + } + + @Override + public List getChildren(IEditingContext editingContext, List existingRepresentations, List expandedIds, List activeFilterIds) { + return List.of(); + } + + @Override + public boolean isEditable() { + return false; + } + + @Override + public boolean isDeletable() { + return false; + } + + @Override + public boolean isSelectable() { + return true; + } + } +} diff --git a/backend/views/syson-diagram-common-view/pom.xml b/backend/views/syson-diagram-common-view/pom.xml index 3def9eef6..81d5fe079 100644 --- a/backend/views/syson-diagram-common-view/pom.xml +++ b/backend/views/syson-diagram-common-view/pom.xml @@ -71,6 +71,10 @@ org.eclipse.syson syson-diagram-services + + org.eclipse.syson + syson-tree-services + org.testcontainers diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java index 260df08cf..fb39b78dc 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java @@ -18,20 +18,17 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; -import java.util.Optional; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.core.api.IFeedbackMessageService; import org.eclipse.sirius.components.core.api.IIdentityService; import org.eclipse.sirius.components.core.api.IObjectSearchService; import org.eclipse.sirius.components.emf.ResourceMetadataAdapter; -import org.eclipse.sirius.components.emf.services.api.IEMFEditingContext; import org.eclipse.sirius.components.representations.Message; import org.eclipse.sirius.components.representations.MessageLevel; import org.eclipse.sirius.components.view.emf.IViewRepresentationDescriptionSearchService; @@ -66,6 +63,8 @@ import org.eclipse.syson.sysml.Usage; import org.eclipse.syson.sysml.UseCaseDefinition; import org.eclipse.syson.sysml.UseCaseUsage; +import org.eclipse.syson.tree.explorer.services.api.ISysONExplorerFragment; +import org.eclipse.syson.tree.explorer.services.api.ISysONExplorerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -76,16 +75,17 @@ */ public class ViewToolService extends ToolService { - private static final String STATE_TRANSITION_COMPARTMENT_NAME = "state transition"; - protected final IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService; + protected final ISysONExplorerService sysONExplorerService; + protected final Logger logger = LoggerFactory.getLogger(ViewToolService.class); public ViewToolService(IIdentityService identityService, IObjectSearchService objectSearchService, IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService, - IFeedbackMessageService feedbackMessageService, ISysMLMoveElementService moveService) { + IFeedbackMessageService feedbackMessageService, ISysMLMoveElementService moveService, ISysONExplorerService sysONExplorerService) { super(identityService, objectSearchService, feedbackMessageService, moveService); this.viewRepresentationDescriptionSearchService = Objects.requireNonNull(viewRepresentationDescriptionSearchService); + this.sysONExplorerService = Objects.requireNonNull(sysONExplorerService); } /** @@ -389,40 +389,38 @@ public Element moveToClosestContainingPackage(Usage usage) { * the editing context * @return the list of resources that contain at least one {@link Package} */ - public List getNamespaceImportSelectionDialogElements(IEditingContext editingContext) { - var optionalResourceSet = Optional.of(editingContext) - .filter(IEMFEditingContext.class::isInstance) - .map(IEMFEditingContext.class::cast) - .map(IEMFEditingContext::getDomain) - .map(EditingDomain::getResourceSet); - var resources = optionalResourceSet.map(resourceSet -> resourceSet.getResources().stream() - .filter(resource -> this.containsDirectlyOrIndirectlyInstancesOf(resource, List.of(SysmlPackage.eINSTANCE.getPackage()))) - .toList()) - .orElseGet(ArrayList::new); - return resources.stream().sorted((r1, r2) -> this.getResourceName(r1).compareTo(this.getResourceName(r2))).toList(); + public List getNamespaceImportSelectionDialogElements(IEditingContext editingContext) { + return this.getAllResourcesWithInstancesOf(editingContext, List.of(SysmlPackage.eINSTANCE.getPackage())); } /** * Service to retrieve the children of a given element in the selection dialog of the NamespaceImport creation tool. * - * @param self - * an element of the tree - * @return the list of {@link Package} element found under the given root element. + * @param selectionDialogTreeElement + * a (non-{@code null}) selection dialog tree element. + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @param expandedIds + * the list of already expanded treeItems, by their Ids. + * @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) or are + * {@link Package}. */ - public List getNamespaceImportSelectionDialogChildren(Object self) { - List result = new ArrayList<>(); - if (self instanceof Resource resource) { - resource.getContents().stream() - .filter(Element.class::isInstance) - .map(Element.class::cast) - .forEach(element -> result.addAll(this.findClosestPackageInChildren(element))); - } else if (self instanceof Package packageElement) { - packageElement.getOwnedRelationship().stream() - .filter(Membership.class::isInstance) - .map(Membership.class::cast) - .forEach(membership -> result.addAll(this.findClosestPackageInChildren(membership))); - } - return result; + public List getNamespaceImportSelectionDialogChildren(Object selectionDialogTreeElement, IEditingContext editingContext, List expandedIds) { + // List result = new ArrayList<>(); + // if (self instanceof Resource resource) { + // resource.getContents().stream() + // .filter(Element.class::isInstance) + // .map(Element.class::cast) + // .forEach(element -> result.addAll(this.findClosestPackageInChildren(element))); + // } else if (self instanceof Package packageElement) { + // packageElement.getOwnedRelationship().stream() + // .filter(Membership.class::isInstance) + // .map(Membership.class::cast) + // .forEach(membership -> result.addAll(this.findClosestPackageInChildren(membership))); + // } + // return result; + return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, List.of(SysmlPackage.eINSTANCE.getPackage())); + } /** @@ -430,9 +428,10 @@ public List getNamespaceImportSelectionDialogChildren(Object self) { * * @param editingContext * the (non-{@code null}) {@link IEditingContext}. - * @return the (non-{@code null}) {@link List} of all {@link Resource} that contain at least one {@link PartUsage}. + * @return the (non-{@code null}) {@link List} of all {@link Resource} and {@link ISysONExplorerFragment} that + * contain at least one {@link PartUsage}. */ - public List getStakeholderSelectionDialogElements(IEditingContext editingContext) { + public List getStakeholderSelectionDialogElements(IEditingContext editingContext) { return this.getAllResourcesWithInstancesOf(editingContext, List.of(SysmlPackage.eINSTANCE.getPartUsage())); } @@ -441,11 +440,15 @@ public List getStakeholderSelectionDialogElements(IEditingContext edit * * @param selectionDialogTreeElement * a (non-{@code null}) selection dialog tree element. + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @param expandedIds + * the list of already expanded treeItems, by their Ids. * @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) or are * {@link PartUsage}. */ - public List getStakeholderSelectionDialogChildren(Object selectionDialogTreeElement) { - return this.getChildrenWithInstancesOf(selectionDialogTreeElement, List.of(SysmlPackage.eINSTANCE.getPartUsage())); + public List getStakeholderSelectionDialogChildren(Object selectionDialogTreeElement, IEditingContext editingContext, List expandedIds) { + return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, List.of(SysmlPackage.eINSTANCE.getPartUsage())); } /** @@ -453,9 +456,10 @@ public List getStakeholderSelectionDialogChildren(Object selec * * @param editingContext * the (non-{@code null}) {@link IEditingContext}. - * @return the (non-{@code null}) {@link List} of all {@link Resource} that contain at least one {@link Type}. + * @return the (non-{@code null}) {@link List} of all {@link Resource} and {@link ISysONExplorerFragment} that + * contain at least one {@link Type}. */ - public List getSubjectSelectionDialogElements(IEditingContext editingContext) { + public List getSubjectSelectionDialogElements(IEditingContext editingContext) { return this.getAllResourcesWithInstancesOf(editingContext, List.of(SysmlPackage.eINSTANCE.getType())); } @@ -464,11 +468,15 @@ public List getSubjectSelectionDialogElements(IEditingContext editingC * * @param selectionDialogTreeElement * a (non-{@code null}) selection dialog tree element. + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @param expandedIds + * the list of already expanded treeItems, by their Ids. * @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) or are * {@link Usage}. */ - public List getSubjectSelectionDialogChildren(Object selectionDialogTreeElement) { - return this.getChildrenWithInstancesOf(selectionDialogTreeElement, List.of(SysmlPackage.eINSTANCE.getType())); + public List getSubjectSelectionDialogChildren(Object selectionDialogTreeElement, IEditingContext editingContext, List expandedIds) { + return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, List.of(SysmlPackage.eINSTANCE.getType())); } /** @@ -476,23 +484,52 @@ public List getSubjectSelectionDialogChildren(Object selection * * @param editingContext * the (non-{@code null}) {@link IEditingContext}. - * @return the (non-{@code null}) {@link List} of all {@link Resource} that contain at least one {@link PartUsage} - * or {@link PartDefinition}. + * @return the (non-{@code null}) {@link List} of all {@link Resource} and {@link ISysONExplorerFragment} that + * contain at least one {@link PartUsage} or {@link PartDefinition}. */ - public List getActorSelectionDialogElements(IEditingContext editingContext) { + public List getActorSelectionDialogElements(IEditingContext editingContext) { return this.getAllResourcesWithInstancesOf(editingContext, List.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getPartDefinition())); } + /** + * Provides the children of element in the tree of the selection dialog for the Objective Requirement creation tool. + * + * @param selectionDialogTreeElement + * a (non-{@code null}) selection dialog tree element. + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) or are + * {@link RequirementUsage} or {@link RequirementDefinition}. + */ + public List getObjectiveRequirementSelectionDialogChildren(Object selectionDialogTreeElement, IEditingContext editingContext, List expandedIds) { + return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, + List.of(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementDefinition())); + } + + /** + * Provides the root elements in the tree of the selection dialog for the Objective Requirement creation tool. + * + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @return the (non-{@code null}) {@link List} of all {@link Resource} and {@link ISysONExplorerFragment} that + * contain at least one {@link RequirementUsage} or {@link RequirementDefinition}. + */ + public List getObjectiveRequirementSelectionDialogElements(IEditingContext editingContext) { + return this.getAllResourcesWithInstancesOf(editingContext, List.of(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementDefinition())); + } + /** * Provides the children of element in the tree of the selection dialog for the ActorParameter creation tool. * * @param selectionDialogTreeElement * a (non-{@code null}) selection dialog tree element. + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. * @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) or are * {@link PartUsage} or {@link PartDefinition}. */ - public List getActorSelectionDialogChildren(Object selectionDialogTreeElement) { - return this.getChildrenWithInstancesOf(selectionDialogTreeElement, List.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getPartDefinition())); + public List getActorSelectionDialogChildren(Object selectionDialogTreeElement, IEditingContext editingContext, List expandedIds) { + return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, List.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getPartDefinition())); } /** @@ -500,9 +537,10 @@ public List getActorSelectionDialogChildren(Object selectionDi * * @param editingContext * the (non-{@code null}) {@link IEditingContext}. - * @return the (non-{@code null}) {@link List} of all {@link Resource} that contain at least one {@link ActionUsage}. + * @return the (non-{@code null}) {@link List} of all {@link Resource} and {@link ISysONExplorerFragment} that + * contain at least one {@link ActionUsage}. */ - public List getActionReferenceSelectionDialogElements(IEditingContext editingContext) { + public List getActionReferenceSelectionDialogElements(IEditingContext editingContext) { return this.getAllResourcesWithInstancesOf(editingContext, List.of(SysmlPackage.eINSTANCE.getActionUsage())); } @@ -511,10 +549,43 @@ public List getActionReferenceSelectionDialogElements(IEditingContext * * @param selectionDialogTreeElement * a (non-{@code null}) selection dialog tree element. - * @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) an {@link ActionUsage}. + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @param expandedIds + * the list of already expanded treeItems, by their Ids. + * @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) an + * {@link ActionUsage}. + */ + public List getActionReferenceSelectionDialogChildren(Object selectionDialogTreeElement, IEditingContext editingContext, List expandedIds) { + return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, List.of(SysmlPackage.eINSTANCE.getActionUsage())); + } + + /** + * Provides the root elements in the tree of the selection dialog for presenting all existing StateUsage. + * + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @return the (non-{@code null}) {@link List} of all {@link Resource} and {@link ISysONExplorerFragment} that + * contain at least one {@link StateUsage}. + */ + public List getExhibitStateSelectionDialogElements(IEditingContext editingContext) { + return this.getAllResourcesWithInstancesOf(editingContext, List.of(SysmlPackage.eINSTANCE.getStateUsage())); + } + + /** + * Provides the children of element in the tree of the selection dialog for presenting all existing StateUsage. + * + * @param selectionDialogTreeElement + * a (non-{@code null}) selection dialog tree element. + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @param expandedIds + * the list of already expanded treeItems, by their Ids. + * @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) an + * {@link StateUsage}. */ - public List getActionReferenceSelectionDialogChildren(Object selectionDialogTreeElement) { - return this.getChildrenWithInstancesOf(selectionDialogTreeElement, List.of(SysmlPackage.eINSTANCE.getActionUsage())); + public List getExhibitStateSelectionDialogChildren(Object selectionDialogTreeElement, IEditingContext editingContext, List expandedIds) { + return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, List.of(SysmlPackage.eINSTANCE.getStateUsage())); } /** @@ -526,7 +597,7 @@ public List getActionReferenceSelectionDialogChildren(Object s * the EClassifier candidates. * @return the (non-{@code null}) {@link List} of all {@link Resource} that contain at least one candidates. */ - public List getSelectionDialogElements(IEditingContext editingContext, List candidates) { + public List getSelectionDialogElements(IEditingContext editingContext, List candidates) { return this.getAllResourcesWithInstancesOf(editingContext, candidates); } @@ -535,32 +606,36 @@ public List getSelectionDialogElements(IEditingContext editingContext, * * @param selectionDialogTreeElement * a (non-{@code null}) selection dialog tree element. + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @param expandedIds + * the list of already expanded treeItems, by their Ids. * @param candidates * the EClassifier candidates. * @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) or are candidates. */ - public List getSelectionDialogChildren(Object selectionDialogTreeElement, List candidates) { - return this.getChildrenWithInstancesOf(selectionDialogTreeElement, candidates); - } - - protected List getAllResourcesWithInstancesOf(IEditingContext editingContext, List eClassifiers) { - Objects.requireNonNull(editingContext); + public List getSelectionDialogChildren(Object selectionDialogTreeElement, IEditingContext editingContext, List expandedIds, List candidates) { + return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, candidates); + } + + protected List getAllResourcesWithInstancesOf(IEditingContext editingContext, List eClassifiers) { + var elementsContainingClassifiers = new ArrayList<>(); + List elements = this.sysONExplorerService.getElements(editingContext, List.of()); + for (Object rootElement : elements) { + if (rootElement instanceof Resource resource && this.containsDirectlyOrIndirectlyInstancesOf(resource, eClassifiers)) { + elementsContainingClassifiers.add(resource); + } else if (rootElement instanceof ISysONExplorerFragment fragment) { + elementsContainingClassifiers.add(fragment); + } + } - var optResourceSet = Optional.of(editingContext) - .filter(IEMFEditingContext.class::isInstance) - .map(IEMFEditingContext.class::cast) - .map(IEMFEditingContext::getDomain) - .map(EditingDomain::getResourceSet); - var resourcesContainingPartUsage = optResourceSet.map(resourceSet -> resourceSet.getResources().stream() - .filter(resource -> this.containsDirectlyOrIndirectlyInstancesOf(resource, eClassifiers)) - .toList()) - .orElseGet(ArrayList::new); - return resourcesContainingPartUsage.stream().sorted(Comparator.comparing(r -> this.getResourceName(r))).toList(); + return elementsContainingClassifiers.stream() + .sorted(Comparator.comparingInt(this::getSelectionDialogRootSortRank) + .thenComparing(this::getElementName, String.CASE_INSENSITIVE_ORDER)) + .toList(); } - protected List getChildrenWithInstancesOf(Object selectionDialogTreeElement, List eClassifiers) { - Objects.requireNonNull(selectionDialogTreeElement); - + protected List getChildrenWithInstancesOf(Object selectionDialogTreeElement, IEditingContext editingContext, List expandedIds, List eClassifiers) { final List result; if (selectionDialogTreeElement instanceof Resource resource) { @@ -568,12 +643,19 @@ protected List getChildrenWithInstancesOf(Object selectionDial .filter(content -> eClassifiers.stream().anyMatch(eClassifier -> eClassifier.isInstance(content)) || this.containsDirectlyOrIndirectlyInstancesOf(content, eClassifiers)) .toList(); } else if (selectionDialogTreeElement instanceof Element sysmlElement) { - return sysmlElement.getOwnedRelationship().stream() + result = sysmlElement.getOwnedRelationship().stream() .filter(Membership.class::isInstance) .map(Membership.class::cast) .map(Membership::getOwnedRelatedElement).flatMap(List::stream) .filter(content -> eClassifiers.stream().anyMatch(eClassifier -> eClassifier.isInstance(content)) || this.containsDirectlyOrIndirectlyInstancesOf(content, eClassifiers)) .toList(); + } else if (selectionDialogTreeElement instanceof ISysONExplorerFragment fragment) { + result = fragment.getChildren(editingContext, List.of(), expandedIds, List.of()).stream().filter(child -> { + if (child instanceof Resource childResource && !this.containsDirectlyOrIndirectlyInstancesOf(childResource, eClassifiers)) { + return false; + } + return true; + }).toList(); } else { result = new ArrayList<>(); } @@ -620,6 +702,26 @@ protected String getResourceName(Resource resource) { .orElse(resource.getURI().lastSegment()); } + protected String getElementName(Object element) { + String elementName = ""; + if (element instanceof Resource resource) { + elementName = this.getResourceName(resource); + } else if (element instanceof ISysONExplorerFragment fragment) { + elementName = fragment.getLabel(); + } + return elementName; + } + + protected int getSelectionDialogRootSortRank(Object element) { + int rank = Integer.MAX_VALUE; + if (element instanceof Resource) { + rank = 0; + } else if (element instanceof ISysONExplorerFragment) { + rank = 1; + } + return rank; + } + protected List findClosestPackageInChildren(Element element) { var result = new ArrayList(); if (element instanceof Package packageElement) { diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ActorCompartmentNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ActorCompartmentNodeToolProvider.java index 793f62b75..ddd0718ee 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ActorCompartmentNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ActorCompartmentNodeToolProvider.java @@ -13,6 +13,7 @@ package org.eclipse.syson.diagram.common.view.tools; import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.diagram.SelectionDialogDescription; import org.eclipse.syson.diagram.common.view.services.ViewCreateService; import org.eclipse.syson.diagram.common.view.services.ViewToolService; @@ -40,7 +41,7 @@ protected SelectionDialogDescription getSelectionDialogDescription() { var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() .elementsExpression(ServiceMethod.of0(ViewToolService::getActorSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT)) - .childrenExpression(ServiceMethod.of0(ViewToolService::getActorSelectionDialogChildren).aqlSelf()) + .childrenExpression(ServiceMethod.of2(ViewToolService::getActorSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED)) .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + partUsageType + ") or self.oclIsKindOf(" + partDefType + ")") .build(); return this.diagramBuilderHelper.newSelectionDialogDescription() diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ExhibitStateNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ExhibitStateNodeToolProvider.java index 714a203bb..d738eef28 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ExhibitStateNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ExhibitStateNodeToolProvider.java @@ -15,6 +15,7 @@ import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; import org.eclipse.sirius.components.view.builder.generated.diagram.DiagramBuilders; import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilders; @@ -23,6 +24,7 @@ import org.eclipse.sirius.components.view.diagram.SelectionDialogDescription; import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; import org.eclipse.syson.diagram.common.view.services.ViewCreateService; +import org.eclipse.syson.diagram.common.view.services.ViewToolService; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.services.UtilService; import org.eclipse.syson.sysml.SysmlPackage; @@ -116,13 +118,15 @@ private SelectionDialogDescription getSelectionDialog() { var domainType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getStateUsage()); var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() - .elementsExpression(ServiceMethod.of1(UtilService::getAllReachable).aqlSelf(domainType)) + .elementsExpression(ServiceMethod.of0(ViewToolService::getExhibitStateSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT)) + .childrenExpression(ServiceMethod.of2(ViewToolService::getExhibitStateSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED)) + .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + domainType + ")") .build(); String elementToCreateLabel = "Exhibit State"; if (this.isParallel) { - elementToCreateLabel = "parallel Exhibit State"; + elementToCreateLabel = "Exhibit State Parallel"; } var selectExistingStateUsage = this.diagramBuilderHelper.newSelectionDialogDescription() diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/FlowNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/FlowNodeToolProvider.java index 13ccbcff8..bce2fe554 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/FlowNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/FlowNodeToolProvider.java @@ -13,6 +13,7 @@ package org.eclipse.syson.diagram.common.view.tools; import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; import org.eclipse.sirius.components.view.builder.generated.diagram.DiagramBuilders; import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilders; @@ -65,7 +66,7 @@ private SelectionDialogDescription getSelectionDialogDescription() { var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() .elementsExpression(ServiceMethod.of1(ViewToolService::getSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT, "Sequence{" + domainType + "}")) - .childrenExpression(ServiceMethod.of1(ViewToolService::getSelectionDialogChildren).aqlSelf("Sequence{" + domainType + "}")) + .childrenExpression(ServiceMethod.of3(ViewToolService::getSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED, "Sequence{" + domainType + "}")) .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + domainType + ")") .build(); return this.diagramBuilderHelper.newSelectionDialogDescription() diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/NamespaceImportNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/NamespaceImportNodeToolProvider.java index c5a642feb..89042e398 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/NamespaceImportNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/NamespaceImportNodeToolProvider.java @@ -16,6 +16,7 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; import org.eclipse.sirius.components.view.builder.generated.diagram.DiagramBuilders; import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilders; @@ -85,7 +86,7 @@ private SelectionDialogDescription getSelectionDialogDescription() { var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() .elementsExpression(ServiceMethod.of0(ViewToolService::getNamespaceImportSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT)) - .childrenExpression(ServiceMethod.of0(ViewToolService::getNamespaceImportSelectionDialogChildren).aqlSelf()) + .childrenExpression(ServiceMethod.of2(ViewToolService::getNamespaceImportSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED)) .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + domainType + ")") .build(); return this.diagramBuilderHelper.newSelectionDialogDescription() diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ObjectiveRequirementCompartmentNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ObjectiveRequirementCompartmentNodeToolProvider.java index 90dcdede7..a6ebacb5f 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ObjectiveRequirementCompartmentNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ObjectiveRequirementCompartmentNodeToolProvider.java @@ -12,12 +12,16 @@ *******************************************************************************/ package org.eclipse.syson.diagram.common.view.tools; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.diagram.SelectionDialogDescription; import org.eclipse.syson.diagram.common.view.services.ViewCreateService; -import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; +import org.eclipse.syson.diagram.common.view.services.ViewToolService; import org.eclipse.syson.sysml.RequirementUsage; +import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.ServiceMethod; +import org.eclipse.syson.util.SysMLMetamodelHelper; /** * Node tool provider for objective compartment in the element that need such compartment. @@ -38,8 +42,13 @@ protected String getServiceCallExpression() { @Override protected SelectionDialogDescription getSelectionDialogDescription() { + String reqUsageType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getRequirementUsage()); + String reqDefType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getRequirementDefinition()); + var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() - .elementsExpression(ServiceMethod.of0(DiagramQueryAQLService::getAllReachableRequirements).aqlSelf()) + .elementsExpression(ServiceMethod.of0(ViewToolService::getObjectiveRequirementSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT)) + .childrenExpression(ServiceMethod.of2(ViewToolService::getObjectiveRequirementSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED)) + .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + reqUsageType + ") or self.oclIsKindOf(" + reqDefType + ")") .build(); return this.diagramBuilderHelper.newSelectionDialogDescription() .selectionDialogTreeDescription(selectionDialogTree) diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/PerformActionNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/PerformActionNodeToolProvider.java index 3c71dd778..556819c32 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/PerformActionNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/PerformActionNodeToolProvider.java @@ -15,6 +15,7 @@ import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; import org.eclipse.sirius.components.view.diagram.NodeTool; import org.eclipse.sirius.components.view.diagram.SelectionDialogDescription; @@ -108,7 +109,7 @@ protected SelectionDialogDescription getSelectionDialogDescription() { var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + actionUsageType + ")") .elementsExpression(ServiceMethod.of0(ViewToolService::getActionReferenceSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT)) - .childrenExpression(ServiceMethod.of0(ViewToolService::getActionReferenceSelectionDialogChildren).aqlSelf()) + .childrenExpression(ServiceMethod.of2(ViewToolService::getActionReferenceSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED)) .build(); return this.diagramBuilderHelper.newSelectionDialogDescription() diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SatisfyNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SatisfyNodeToolProvider.java index 412eb6a7f..2af3ed2c0 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SatisfyNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SatisfyNodeToolProvider.java @@ -17,6 +17,7 @@ import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; import org.eclipse.sirius.components.view.builder.generated.diagram.DiagramBuilders; import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilders; @@ -51,7 +52,8 @@ public NodeTool create(IViewDiagramElementFinder cache) { var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() .elementsExpression(ServiceMethod.of1(ViewToolService::getSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT, AQLUtils.aqlSequence(List.of(reqUsageType)))) - .childrenExpression(ServiceMethod.of1(ViewToolService::getSelectionDialogChildren).aqlSelf(AQLUtils.aqlSequence(List.of(reqUsageType)))) + .childrenExpression( + ServiceMethod.of3(ViewToolService::getSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED, AQLUtils.aqlSequence(List.of(reqUsageType)))) .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + reqUsageType + ")") .build(); var selectionDialog = this.diagramBuilderHelper.newSelectionDialogDescription() diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SatisfyRequirementNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SatisfyRequirementNodeToolProvider.java index cfa2e2160..aaf66b23a 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SatisfyRequirementNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SatisfyRequirementNodeToolProvider.java @@ -17,6 +17,7 @@ import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; import org.eclipse.sirius.components.view.builder.generated.diagram.DiagramBuilders; import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilders; @@ -73,7 +74,8 @@ private DialogDescription getDialogDescription() { var selectionDialogTreeDescription = this.diagramBuilderHelper.newSelectionDialogTreeDescription() .elementsExpression(ServiceMethod.of1(ViewToolService::getSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT, AQLUtils.aqlSequence(selectableTypes))) - .childrenExpression(ServiceMethod.of1(ViewToolService::getSelectionDialogChildren).aqlSelf(AQLUtils.aqlSequence(selectableTypes))) + .childrenExpression( + ServiceMethod.of3(ViewToolService::getSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED, AQLUtils.aqlSequence(selectableTypes))) .isSelectableExpression(AQLConstants.AQL + "self.oclIsKindOf(" + defType + ") or self.oclIsKindOf(" + reqUsageType + ")") .build(); diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StakeholdersCompartmentNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StakeholdersCompartmentNodeToolProvider.java index 6b50ef944..714200664 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StakeholdersCompartmentNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StakeholdersCompartmentNodeToolProvider.java @@ -13,6 +13,7 @@ package org.eclipse.syson.diagram.common.view.tools; import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.diagram.SelectionDialogDescription; import org.eclipse.syson.diagram.common.view.services.ViewCreateService; import org.eclipse.syson.diagram.common.view.services.ViewToolService; @@ -41,7 +42,7 @@ protected SelectionDialogDescription getSelectionDialogDescription() { var domainName = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getPartUsage()); var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() .elementsExpression(ServiceMethod.of0(ViewToolService::getStakeholderSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT)) - .childrenExpression(ServiceMethod.of0(ViewToolService::getStakeholderSelectionDialogChildren).aqlSelf()) + .childrenExpression(ServiceMethod.of2(ViewToolService::getStakeholderSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED)) .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + domainName + ")") .build(); return this.diagramBuilderHelper.newSelectionDialogDescription() diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StateSubactionNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StateSubactionNodeToolProvider.java index fca431fa2..cdce66566 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StateSubactionNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StateSubactionNodeToolProvider.java @@ -19,6 +19,7 @@ import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.ChangeContext; import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; import org.eclipse.sirius.components.view.builder.generated.diagram.DiagramBuilders; @@ -86,7 +87,7 @@ private DialogDescription getExistingActionSelectionDialog() { var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + actionUsageType + ")") .elementsExpression(ServiceMethod.of0(ViewToolService::getActionReferenceSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT)) - .childrenExpression(ServiceMethod.of0(ViewToolService::getActionReferenceSelectionDialogChildren).aqlSelf()) + .childrenExpression(ServiceMethod.of2(ViewToolService::getActionReferenceSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED)) .build(); var actionKind = StringUtils.capitalize(this.kind.getName()); diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SubjectCompartmentNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SubjectCompartmentNodeToolProvider.java index 74be91bac..5cb7da823 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SubjectCompartmentNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/SubjectCompartmentNodeToolProvider.java @@ -13,6 +13,7 @@ package org.eclipse.syson.diagram.common.view.tools; import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; import org.eclipse.sirius.components.view.diagram.SelectionDialogDescription; import org.eclipse.syson.diagram.common.view.services.ViewCreateService; import org.eclipse.syson.diagram.common.view.services.ViewToolService; @@ -38,7 +39,7 @@ protected SelectionDialogDescription getSelectionDialogDescription() { String domainType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getType()); var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() .elementsExpression(ServiceMethod.of0(ViewToolService::getSubjectSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT)) - .childrenExpression(ServiceMethod.of0(ViewToolService::getSubjectSelectionDialogChildren).aqlSelf()) + .childrenExpression(ServiceMethod.of2(ViewToolService::getSubjectSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED)) .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + domainType + ")") .build(); return this.diagramBuilderHelper.newSelectionDialogDescription() diff --git a/doc/content/modules/user-manual/pages/release-notes/2026.5.0.adoc b/doc/content/modules/user-manual/pages/release-notes/2026.5.0.adoc index c5afb8a59..2c0eca061 100644 --- a/doc/content/modules/user-manual/pages/release-notes/2026.5.0.adoc +++ b/doc/content/modules/user-manual/pages/release-notes/2026.5.0.adoc @@ -45,6 +45,7 @@ image::release-notes-stakeholder-node.png[Default representation of Stakeholder ** Improve the tool to create a `SatisfyRequirement` graphical node, either standalone, feature typed, or subsetting a `RequirementUsage` by reference. ** Reorganize the three tools to create `ExhibitStateUsage` graphical nodes into two tools, one for parallel `ExhibitStateUsage`, one for non-parallel `ExhibitStateUsage`. Both tools optionally allow selecting an existing `StateUsage` to exhibit. +** Improve the selection dialog used in various tools by regrouping all standard libraries candidates under a "Libraries" category. * In the _Explorer_ view: diff --git a/scripts/check-coverage.jsh b/scripts/check-coverage.jsh index a5db0fc83..fa187902c 100755 --- a/scripts/check-coverage.jsh +++ b/scripts/check-coverage.jsh @@ -43,12 +43,12 @@ var moduleCoverageData = List.of( new ModuleCoverage("syson-services", 68.0), new ModuleCoverage("syson-siriusweb-customnodes-metamodel", 41.0), new ModuleCoverage("syson-siriusweb-customnodes-metamodel-edit", 0.0), - new ModuleCoverage("syson-standard-diagrams-view", 97.0), + new ModuleCoverage("syson-standard-diagrams-view", 98.0), new ModuleCoverage("syson-sysml-export", 71.0), new ModuleCoverage("syson-sysml-import", 85.0), new ModuleCoverage("syson-sysml-metamodel", 77.0), new ModuleCoverage("syson-sysml-metamodel-edit", 17.0), - new ModuleCoverage("syson-sysml-metamodel-services", 92.0), + new ModuleCoverage("syson-sysml-metamodel-services", 93.0), new ModuleCoverage("syson-sysml-rest-api-services", 93.0), new ModuleCoverage("syson-sysml-validation", 97.0), new ModuleCoverage("syson-table-requirements-view", 73.0),