Skip to content

Commit 500313a

Browse files
authored
Add selection tracker for shortcuts, fixes #6218, #6217 (#6304)
1 parent f113ef3 commit 500313a

File tree

5 files changed

+183
-1
lines changed

5 files changed

+183
-1
lines changed

ui/src/main/java/org/apache/hop/ui/hopgui/HopGuiKeyHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ private boolean handleKey(Object parentObject, KeyEvent event, KeyboardShortcut
156156
Method method = parentClass.getMethod(shortcut.getParentMethodName());
157157
if (method != null) {
158158
method.invoke(parentObject);
159-
return true; // Stop looking after 1 execution
159+
// return true; // disable for now until we can clean this up
160160
}
161161
} catch (Exception ex) {
162162
LogChannel.UI.logError(

ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@
178178
import org.apache.hop.ui.hopgui.perspective.execution.ExecutionPerspective;
179179
import org.apache.hop.ui.hopgui.perspective.execution.IExecutionViewer;
180180
import org.apache.hop.ui.hopgui.perspective.explorer.ExplorerPerspective;
181+
import org.apache.hop.ui.hopgui.selection.HopGuiSelectionTracker;
181182
import org.apache.hop.ui.hopgui.shared.SwtGc;
182183
import org.apache.hop.ui.pipeline.dialog.PipelineDialog;
183184
import org.apache.hop.ui.util.EnvironmentUtils;
@@ -758,6 +759,10 @@ public void mouseDown(MouseEvent event) {
758759
selectedTransforms = pipelineMeta.getSelectedTransforms();
759760
selectedTransform = currentTransform;
760761

762+
// Track that a transform was selected
763+
HopGuiSelectionTracker.getInstance()
764+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
765+
761766
for (ITransformSelectionListener listener : currentTransformListeners) {
762767
listener.onUpdateSelection(currentTransform);
763768
}
@@ -825,6 +830,9 @@ else if (event.button == 2 || (event.button == 1 && control)) {
825830
currentNotePad = (NotePadMeta) areaOwner.getOwner();
826831
selectedNotes = pipelineMeta.getSelectedNotes();
827832
selectedNote = currentNotePad;
833+
// Track that a note was selected
834+
HopGuiSelectionTracker.getInstance()
835+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
828836
Point loc = currentNotePad.getLocation();
829837

830838
previousNoteLocations = pipelineMeta.getSelectedNoteLocations();
@@ -957,6 +965,12 @@ public void mouseUp(MouseEvent e) {
957965
pipelineMeta.unselectAll();
958966
selectInRect(pipelineMeta, selectionRegion);
959967
selectionRegion = null;
968+
// Track that transforms were selected via region selection
969+
if (!pipelineMeta.getSelectedTransforms().isEmpty()
970+
|| !pipelineMeta.getSelectedNotes().isEmpty()) {
971+
HopGuiSelectionTracker.getInstance()
972+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
973+
}
960974
updateGui();
961975
return;
962976
}
@@ -1005,6 +1019,11 @@ && showTransformOutputData(areaOwner)) {
10051019
// Flip selection when control is pressed!
10061020
if (control) {
10071021
selectedTransform.flipSelected();
1022+
// Track that a transform selection changed (if it's now selected)
1023+
if (selectedTransform.isSelected()) {
1024+
HopGuiSelectionTracker.getInstance()
1025+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
1026+
}
10081027
} else {
10091028
singleClick = true;
10101029
singleClickType = SingleClickType.Transform;
@@ -1016,11 +1035,19 @@ && showTransformOutputData(areaOwner)) {
10161035
pipelineMeta.unselectAll();
10171036
selectedTransform.setSelected(true);
10181037
}
1038+
// Track that a transform was selected
1039+
HopGuiSelectionTracker.getInstance()
1040+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
10191041
}
10201042
} else {
10211043
// Find out which Transforms & Notes are selected
10221044
selectedTransforms = pipelineMeta.getSelectedTransforms();
10231045
selectedNotes = pipelineMeta.getSelectedNotes();
1046+
// Track that transforms were selected
1047+
if (!selectedTransforms.isEmpty() || !selectedNotes.isEmpty()) {
1048+
HopGuiSelectionTracker.getInstance()
1049+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
1050+
}
10241051

10251052
// We moved around some items: store undo info...
10261053
//
@@ -1079,6 +1106,11 @@ && showTransformOutputData(areaOwner)) {
10791106
// Flip selection when control is pressed!
10801107
if (control) {
10811108
selectedNote.flipSelected();
1109+
// Track that a note selection changed (if it's now selected)
1110+
if (selectedNote.isSelected()) {
1111+
HopGuiSelectionTracker.getInstance()
1112+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
1113+
}
10821114
} else {
10831115
// single click on a note: ask what needs to happen...
10841116
//
@@ -1092,11 +1124,19 @@ && showTransformOutputData(areaOwner)) {
10921124
pipelineMeta.unselectAll();
10931125
selectedNote.setSelected(true);
10941126
}
1127+
// Track that a note was selected
1128+
HopGuiSelectionTracker.getInstance()
1129+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
10951130
}
10961131
} else {
10971132
// Find out which Transforms & Notes are selected
10981133
selectedTransforms = pipelineMeta.getSelectedTransforms();
10991134
selectedNotes = pipelineMeta.getSelectedNotes();
1135+
// Track that notes were selected
1136+
if (!selectedTransforms.isEmpty() || !selectedNotes.isEmpty()) {
1137+
HopGuiSelectionTracker.getInstance()
1138+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
1139+
}
11001140

11011141
// We moved around some items: store undo info...
11021142

@@ -1516,13 +1556,19 @@ else if (areaOwner.getAreaType() == AreaOwner.AreaType.NOTE) {
15161556
selectedTransforms = new ArrayList<>();
15171557
selectedTransforms.add(selectedTransform);
15181558
previousTransformLocations = new Point[] {selectedTransform.getLocation()};
1559+
// Track that a transform was selected
1560+
HopGuiSelectionTracker.getInstance()
1561+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
15191562
doRedraw = true;
15201563
} else if (selectedNote != null && !selectedNote.isSelected()) {
15211564
pipelineMeta.unselectAll();
15221565
selectedNote.setSelected(true);
15231566
selectedNotes = new ArrayList<>();
15241567
selectedNotes.add(selectedNote);
15251568
previousNoteLocations = new Point[] {selectedNote.getLocation()};
1569+
// Track that a note was selected
1570+
HopGuiSelectionTracker.getInstance()
1571+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
15261572
doRedraw = true;
15271573
} else if (selectionRegion != null && startHopTransform == null) {
15281574
// Did we select a region...?
@@ -5243,6 +5289,19 @@ public void cutSelectedToClipboard() {
52435289
@GuiKeyboardShortcut(key = SWT.DEL)
52445290
@Override
52455291
public void deleteSelected() {
5292+
// Only handle delete if a pipeline graph item was the last selected item
5293+
// OR if there are actually selected transforms/notes in the pipeline
5294+
HopGuiSelectionTracker selectionTracker = HopGuiSelectionTracker.getInstance();
5295+
boolean hasPipelineSelection =
5296+
!pipelineMeta.getSelectedTransforms().isEmpty()
5297+
|| !pipelineMeta.getSelectedNotes().isEmpty();
5298+
boolean isLastPipelineSelection =
5299+
selectionTracker.isLastSelection(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
5300+
5301+
if (!isLastPipelineSelection || !hasPipelineSelection) {
5302+
return;
5303+
}
5304+
52465305
delSelected(null);
52475306
updateGui();
52485307
}

ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
import org.apache.hop.ui.hopgui.perspective.execution.ExecutionPerspective;
135135
import org.apache.hop.ui.hopgui.perspective.execution.IExecutionViewer;
136136
import org.apache.hop.ui.hopgui.perspective.explorer.ExplorerPerspective;
137+
import org.apache.hop.ui.hopgui.selection.HopGuiSelectionTracker;
137138
import org.apache.hop.ui.hopgui.shared.SwtGc;
138139
import org.apache.hop.ui.util.EnvironmentUtils;
139140
import org.apache.hop.ui.util.HelpUtils;
@@ -691,6 +692,9 @@ else if (event.button == 2 || (event.button == 1 && control)) {
691692
currentNotePad = (NotePadMeta) areaOwner.getOwner();
692693
selectedNotes = workflowMeta.getSelectedNotes();
693694
selectedNote = currentNotePad;
695+
// Track that a note was selected
696+
HopGuiSelectionTracker.getInstance()
697+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
694698
Point loc = currentNotePad.getLocation();
695699

696700
previousNoteLocations = workflowMeta.getSelectedNoteLocations();
@@ -828,6 +832,12 @@ public void mouseUp(MouseEvent event) {
828832
workflowMeta.unselectAll();
829833
selectInRect(workflowMeta, selectionRegion);
830834
selectionRegion = null;
835+
// Track that actions/notes were selected via region selection
836+
if (!workflowMeta.getSelectedActions().isEmpty()
837+
|| !workflowMeta.getSelectedNotes().isEmpty()) {
838+
HopGuiSelectionTracker.getInstance()
839+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
840+
}
831841
updateGui();
832842
return;
833843
}
@@ -880,11 +890,19 @@ public void mouseUp(MouseEvent event) {
880890
workflowMeta.unselectAll();
881891
selectedAction.setSelected(true);
882892
}
893+
// Track that an action was selected
894+
HopGuiSelectionTracker.getInstance()
895+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
883896
}
884897
} else {
885898
// Find out which Transforms & Notes are selected
886899
selectedActions = workflowMeta.getSelectedActions();
887900
selectedNotes = workflowMeta.getSelectedNotes();
901+
// Track that actions/notes were selected
902+
if (!selectedActions.isEmpty() || !selectedNotes.isEmpty()) {
903+
HopGuiSelectionTracker.getInstance()
904+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
905+
}
888906

889907
// We moved around some items: store undo info...
890908
//
@@ -977,11 +995,19 @@ public void mouseUp(MouseEvent event) {
977995
workflowMeta.unselectAll();
978996
selectedNote.setSelected(true);
979997
}
998+
// Track that a note was selected
999+
HopGuiSelectionTracker.getInstance()
1000+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
9801001
}
9811002
} else {
9821003
// Find out which Transforms & Notes are selected
9831004
selectedActions = workflowMeta.getSelectedActions();
9841005
selectedNotes = workflowMeta.getSelectedNotes();
1006+
// Track that actions/notes were selected
1007+
if (!selectedActions.isEmpty() || !selectedNotes.isEmpty()) {
1008+
HopGuiSelectionTracker.getInstance()
1009+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
1010+
}
9851011

9861012
// We moved around some items: store undo info...
9871013
boolean also = false;
@@ -2070,6 +2096,12 @@ public void cutSelectedToClipboard() {
20702096
@GuiKeyboardShortcut(key = SWT.DEL)
20712097
@Override
20722098
public void deleteSelected() {
2099+
// Only handle delete if a workflow graph item was the last selected item
2100+
HopGuiSelectionTracker selectionTracker = HopGuiSelectionTracker.getInstance();
2101+
if (!selectionTracker.isLastSelection(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH)) {
2102+
return;
2103+
}
2104+
20732105
deleteSelected(null);
20742106
}
20752107

ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/ExplorerPerspective.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
import org.apache.hop.ui.hopgui.perspective.explorer.file.IExplorerFileTypeHandler;
9393
import org.apache.hop.ui.hopgui.perspective.explorer.file.types.FolderFileType;
9494
import org.apache.hop.ui.hopgui.perspective.explorer.file.types.GenericFileType;
95+
import org.apache.hop.ui.hopgui.selection.HopGuiSelectionTracker;
9596
import org.apache.hop.workflow.WorkflowMeta;
9697
import org.apache.hop.workflow.engine.IWorkflowEngine;
9798
import org.eclipse.swt.SWT;
@@ -1541,6 +1542,12 @@ public void expandCollapse(TreeItem item, boolean expand) {
15411542
@GuiKeyboardShortcut(key = SWT.DEL)
15421543
@GuiOsxKeyboardShortcut(key = SWT.DEL)
15431544
public void deleteFile() {
1545+
// Only handle delete if a file was the last selected item
1546+
HopGuiSelectionTracker selectionTracker = HopGuiSelectionTracker.getInstance();
1547+
if (!selectionTracker.isLastSelection(HopGuiSelectionTracker.SelectionType.FILE_EXPLORER)) {
1548+
return;
1549+
}
1550+
15441551
TreeItem[] selection = tree.getSelection();
15451552
if (selection == null || selection.length == 0) {
15461553
return;
@@ -1872,6 +1879,9 @@ public void updateSelection() {
18721879
if (tif == null) {
18731880
return;
18741881
}
1882+
// Track that a file was selected
1883+
HopGuiSelectionTracker.getInstance()
1884+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.FILE_EXPLORER);
18751885
}
18761886

18771887
boolean isFolderSelected = tif != null && tif.fileType instanceof FolderFileType;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.hop.ui.hopgui.selection;
19+
20+
/**
21+
* Tracks the last selected item type to help route keyboard shortcuts correctly. This is needed
22+
* when multiple components (like file explorer and pipeline graph) share the same keyboard
23+
* shortcuts but need to act on different types of items.
24+
*/
25+
public class HopGuiSelectionTracker {
26+
27+
private static HopGuiSelectionTracker instance;
28+
29+
/** The type of item that was last selected */
30+
public enum SelectionType {
31+
/** A file or folder in the file explorer */
32+
FILE_EXPLORER,
33+
/** A transform, note, or hop in a pipeline graph */
34+
PIPELINE_GRAPH,
35+
/** An action, note, or hop in a workflow graph */
36+
WORKFLOW_GRAPH,
37+
/** No specific selection */
38+
NONE
39+
}
40+
41+
private SelectionType lastSelectionType = SelectionType.NONE;
42+
43+
private HopGuiSelectionTracker() {
44+
// Singleton
45+
}
46+
47+
public static HopGuiSelectionTracker getInstance() {
48+
if (instance == null) {
49+
instance = new HopGuiSelectionTracker();
50+
}
51+
return instance;
52+
}
53+
54+
/**
55+
* Set the last selected item type
56+
*
57+
* @param selectionType The type of item that was selected
58+
*/
59+
public void setLastSelectionType(SelectionType selectionType) {
60+
this.lastSelectionType = selectionType;
61+
}
62+
63+
/**
64+
* Get the last selected item type
65+
*
66+
* @return The type of item that was last selected
67+
*/
68+
public SelectionType getLastSelectionType() {
69+
return lastSelectionType;
70+
}
71+
72+
/**
73+
* Check if the last selection matches the given type
74+
*
75+
* @param selectionType The type to check against
76+
* @return true if the last selection matches the given type
77+
*/
78+
public boolean isLastSelection(SelectionType selectionType) {
79+
return lastSelectionType == selectionType;
80+
}
81+
}

0 commit comments

Comments
 (0)