Skip to content

Commit d6c3b1c

Browse files
committed
[2172] Add keybinding to duplicate tool
Bug: #2172 Signed-off-by: Axel RICHARD <axel.richard@obeo.fr>
1 parent 24b6d9c commit d6c3b1c

7 files changed

Lines changed: 53 additions & 7 deletions

File tree

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ The cache holding standard libraries can be invalidated for a specific test meth
8484
- https://github.com/eclipse-syson/syson/issues/2152[#2152] [diagrams] Leverage the latest selection dialog changes to allow creating a sub action with and without associating the sub action with another `ActionUsage`.
8585
- https://github.com/eclipse-syson/syson/issues/2161[#2161] [diagrams] Leverage the latest selection dialog changes to optionally allow creating a `SatisfyRequirement` graphical node, either standalone, feature typed, or subsetting a `RequirementUsage` by reference.
8686
Also use that same tool in the `interconnection` compartment.
87+
- https://github.com/eclipse-syson/syson/issues/2172[#2172] [diagrams] Add keybinding to the _Duplicate Element_ tool (ctrl+d).
8788

8889
=== New features
8990

backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVDuplicateNodeTest.java

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.eclipse.sirius.components.diagrams.OutsideLabel;
3232
import org.eclipse.sirius.components.diagrams.ViewModifier;
3333
import org.eclipse.sirius.components.diagrams.tests.navigation.DiagramNavigator;
34+
import org.eclipse.sirius.components.view.diagram.NodeTool;
3435
import org.eclipse.sirius.components.view.emf.diagram.IDiagramIdProvider;
3536
import org.eclipse.sirius.web.tests.services.api.IGivenInitialServerState;
3637
import org.eclipse.syson.AbstractIntegrationTests;
@@ -52,6 +53,7 @@
5253
import org.eclipse.syson.sysml.PartUsage;
5354
import org.eclipse.syson.sysml.StateDefinition;
5455
import org.eclipse.syson.sysml.SysmlPackage;
56+
import org.eclipse.syson.sysml.helper.EMFUtils;
5557
import org.eclipse.syson.sysml.helper.LabelConstants;
5658
import org.eclipse.syson.util.IDescriptionNameGenerator;
5759
import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers;
@@ -60,6 +62,7 @@
6062
import org.junit.jupiter.api.Test;
6163
import org.springframework.beans.factory.annotation.Autowired;
6264
import org.springframework.boot.test.context.SpringBootTest;
65+
import org.springframework.test.context.transaction.TestTransaction;
6366
import org.springframework.transaction.annotation.Transactional;
6467

6568
import reactor.core.publisher.Flux;
@@ -132,8 +135,8 @@ public void setUp() {
132135
}
133136

134137
@DisplayName("GIVEN a General View diagram, WHEN duplicating a Part Usage node with attributes, THEN the semantic element is duplicated with its content and its representation")
135-
@Test
136138
@GivenSysONServer({ GeneralViewItemAndAttributeProjectData.SCRIPT_PATH })
139+
@Test
137140
public void checkTopUsageNodeDuplication() {
138141
var flux = this.givenSubscriptionToDiagram();
139142

@@ -189,9 +192,32 @@ public void checkTopUsageNodeDuplication() {
189192
.verify(Duration.ofSeconds(10));
190193
}
191194

192-
@DisplayName("GIVEN a General View diagram, WHEN duplicating an ItemUsage bordered node, THEN the semantic element is duplicated with its representation")
195+
@DisplayName("GIVEN a General View diagram, WHEN inspecting duplicate tools, THEN they provide the Ctrl+D keybinding")
196+
@GivenSysONServer({ GeneralViewItemAndAttributeProjectData.SCRIPT_PATH })
193197
@Test
198+
public void checkDuplicateToolsKeyBinding() {
199+
TestTransaction.flagForCommit();
200+
TestTransaction.end();
201+
202+
var diagramDescription = this.givenDiagramDescription.getDiagramDescription(GeneralViewItemAndAttributeProjectData.EDITING_CONTEXT_ID,
203+
SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID);
204+
205+
var duplicateElementTool = EMFUtils.allContainedObjectOfType(diagramDescription, NodeTool.class)
206+
.filter(nodeTool -> "Duplicate Element".equals(nodeTool.getName()))
207+
.findFirst();
208+
assertThat(duplicateElementTool).isPresent();
209+
this.assertCtrlDKeyBinding(duplicateElementTool.get());
210+
211+
var duplicateElementsGroupTool = EMFUtils.allContainedObjectOfType(diagramDescription.getGroupPalette(), NodeTool.class)
212+
.filter(nodeTool -> "Duplicate Elements".equals(nodeTool.getName()))
213+
.findFirst();
214+
assertThat(duplicateElementsGroupTool).isPresent();
215+
this.assertCtrlDKeyBinding(duplicateElementsGroupTool.get());
216+
}
217+
218+
@DisplayName("GIVEN a General View diagram, WHEN duplicating an ItemUsage bordered node, THEN the semantic element is duplicated with its representation")
194219
@GivenSysONServer({ GeneralViewItemAndAttributeProjectData.SCRIPT_PATH })
220+
@Test
195221
public void checkBorderedNodeUsageNodeDuplication() {
196222
var flux = this.givenSubscriptionToDiagram();
197223

@@ -325,8 +351,8 @@ public void checkCompartmentItemUsageNodeDuplication() {
325351
}
326352

327353
@DisplayName("GIVEN a General View diagram, WHEN duplicating two top container nodes, THEN both semantic elements and representations are duplicated")
328-
@Test
329354
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
355+
@Test
330356
public void checkMultiSelectionContainerNodeDuplication() {
331357
var flux = this.givenSubscriptionToDiagram(GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, GeneralViewWithTopNodesTestProjectData.GraphicalIds.DIAGRAM_ID);
332358
var topNodesSemanticCheckerService = new SemanticCheckerService(this.semanticRunnableFactory, this.objectSearchService, GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID,
@@ -387,8 +413,8 @@ public void checkMultiSelectionContainerNodeDuplication() {
387413
}
388414

389415
@DisplayName("GIVEN a General View diagram, WHEN a part is created in a Package and duplicated with a StateDefinition, THEN both semantic elements and representations are duplicated")
390-
@Test
391416
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
417+
@Test
392418
public void checkMultiSelectionDifferentContainerNodeDuplication() {
393419
var flux = this.givenSubscriptionToDiagram(GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, GeneralViewWithTopNodesTestProjectData.GraphicalIds.DIAGRAM_ID);
394420
var topNodesSemanticCheckerService = new SemanticCheckerService(this.semanticRunnableFactory, this.objectSearchService, GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID,
@@ -499,4 +525,15 @@ private boolean containsLabel(Node node, String label) {
499525
return match;
500526
}
501527

528+
private void assertCtrlDKeyBinding(NodeTool nodeTool) {
529+
assertThat(nodeTool.getKeyBindings())
530+
.singleElement()
531+
.satisfies(keyBinding -> {
532+
assertThat(keyBinding.isCtrl()).isTrue();
533+
assertThat(keyBinding.isAlt()).isFalse();
534+
assertThat(keyBinding.isMeta()).isFalse();
535+
assertThat(keyBinding.getKey()).isEqualTo("d");
536+
});
537+
}
538+
502539
}

backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractNodeDescriptionProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ protected NodeTool getDuplicateElementAndNodeTool() {
100100
return this.diagramBuilderHelper.newNodeTool()
101101
.name("Duplicate Element")
102102
.iconURLsExpression("/images/content_copy.svg")
103+
.keyBindings(this.viewBuilderHelper.newKeyBinding().ctrl(true).key("d").build())
103104
.preconditionExpression(AQLConstants.AQL + "self.oclIsKindOf(sysml::Element) and not self.oclIsKindOf(sysml::Relationship)")
104105
.body(this.viewBuilderHelper.newChangeContext()
105106
.expression(
@@ -117,6 +118,7 @@ protected NodeTool getDuplicateElementsAndNodesTool() {
117118
return this.diagramBuilderHelper.newNodeTool()
118119
.name("Duplicate Element")
119120
.iconURLsExpression("/images/content_copy.svg")
121+
.keyBindings(this.viewBuilderHelper.newKeyBinding().ctrl(true).key("d").build())
120122
.preconditionExpression(AQLConstants.AQL
121123
+ "selectedNodes->notEmpty() and selectedEdges->isEmpty() and self->forAll(e | e.oclIsKindOf(sysml::Element) and not e.oclIsKindOf(sysml::Relationship))")
122124
.body(this.viewBuilderHelper.newChangeContext()

backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVDiagramDescriptionProvider.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ private NodeTool createDuplicateElementsGroupTool() {
417417
return this.diagramBuilderHelper.newNodeTool()
418418
.name("Duplicate Elements")
419419
.iconURLsExpression("/images/content_copy.svg")
420+
.keyBindings(this.viewBuilderHelper.newKeyBinding().ctrl(true).key("d").build())
420421
.preconditionExpression("aql:selectedNodes->notEmpty() and selectedEdges->isEmpty() and self->forAll(e | e.oclIsKindOf(sysml::Element) and not e.oclIsKindOf(sysml::Relationship))")
421422
.body(this.viewBuilderHelper.newChangeContext()
422423
.expression(ServiceMethod.of4(DiagramMutationAQLService::duplicateElementAndExpose)

doc/content/modules/user-manual/pages/features/keyboard-shortcuts.adoc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ User can press `F2` key or start typing the new value directly to efficiently up
2121

2222
Explore further by referring to the following how-tos for xref:user-manual:features/general-view.adoc#edit-label[Edit Label action].
2323

24+
== Duplicate
25+
26+
User can press `Ctrl+d` to duplicate the selected element from the representation editor.
27+
2428
== Multi-selection
2529

2630
Two ways to select several elements exist:
@@ -39,4 +43,4 @@ After releasing the click, all element in the area are selected.
3943

4044
User can display the filter bar by holding `Ctrl+f` (Windows/Linux) or `Cmd+f` (MacOS) from the {explorer} view.
4145

42-
Explore further by referring to the following how-tos for xref:hands-on/how-tos/explorer.adoc#explorer-filter[Filter elements].
46+
Explore further by referring to the following how-tos for xref:hands-on/how-tos/explorer.adoc#explorer-filter[Filter elements].

doc/content/modules/user-manual/pages/release-notes/2026.5.0.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ image::release-notes-stakeholder-node.png[Default representation of Stakeholder
3838
** Improve the tool to create a `FlowUsage` from a `ConnectionUsage` by making the payload selection optional.
3939
** Merge the two objective creation tools into a single tool by leveraging the updated selection dialog which make the specialization selection optional.
4040
** Merge the two perform action creation tools into a single tool by leveraging the updated selection dialog which make the selection of a referenced action optional.
41-
** Improve the _Duplicate Element_ tool to support multi-selection in standard diagrams.
41+
** Improve the _Duplicate Element_ tool to support multi-selection in standard diagrams, and also associate it with a keybinding (_ctrl+d_).
4242
** Improve the _View As_ tool on graphical nodes to support multi-selection in standard diagrams.
4343
** Improve the _Add existing elements_ tool on graphical nodes to support multi-selection in standard diagrams.
4444
** Improve the tools to create `PerformActionUsage` by making the selection of a subsetted reference optional.

doc/content/modules/user-manual/partials/manage-elements-diagram.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,6 @@ You can reset it by deleting the {product} data in cache of your browser.
5757
=== Duplicate Element
5858

5959
User can duplicate an `Element` (and its representation node) by clicking on the _Duplicate Element_ button in the palette.
60+
User can also duplicate the selected `Element` with the `Ctrl+d` keyboard shortcut from the representation editor.
6061

61-
image::manage-elements-duplicate-from-diagram.png[Duplicate element from Diagram]
62+
image::manage-elements-duplicate-from-diagram.png[Duplicate element from Diagram]

0 commit comments

Comments
 (0)