This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new 500313afed Add selection tracker for shortcuts, fixes #6218, #6217
(#6304)
500313afed is described below
commit 500313afed4b00b1d75f13bffa8c5464395053df
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Wed Jan 7 21:08:16 2026 +0100
Add selection tracker for shortcuts, fixes #6218, #6217 (#6304)
---
.../org/apache/hop/ui/hopgui/HopGuiKeyHandler.java | 2 +-
.../hopgui/file/pipeline/HopGuiPipelineGraph.java | 59 ++++++++++++++++
.../hopgui/file/workflow/HopGuiWorkflowGraph.java | 32 +++++++++
.../perspective/explorer/ExplorerPerspective.java | 10 +++
.../hopgui/selection/HopGuiSelectionTracker.java | 81 ++++++++++++++++++++++
5 files changed, 183 insertions(+), 1 deletion(-)
diff --git a/ui/src/main/java/org/apache/hop/ui/hopgui/HopGuiKeyHandler.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/HopGuiKeyHandler.java
index c56400829a..2498f3efc1 100644
--- a/ui/src/main/java/org/apache/hop/ui/hopgui/HopGuiKeyHandler.java
+++ b/ui/src/main/java/org/apache/hop/ui/hopgui/HopGuiKeyHandler.java
@@ -156,7 +156,7 @@ public class HopGuiKeyHandler extends KeyAdapter {
Method method = parentClass.getMethod(shortcut.getParentMethodName());
if (method != null) {
method.invoke(parentObject);
- return true; // Stop looking after 1 execution
+ // return true; // disable for now until we can clean this up
}
} catch (Exception ex) {
LogChannel.UI.logError(
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
index 1ce78d8b3c..4ec638fb22 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
@@ -178,6 +178,7 @@ import
org.apache.hop.ui.hopgui.file.shared.HopGuiTooltipExtension;
import org.apache.hop.ui.hopgui.perspective.execution.ExecutionPerspective;
import org.apache.hop.ui.hopgui.perspective.execution.IExecutionViewer;
import org.apache.hop.ui.hopgui.perspective.explorer.ExplorerPerspective;
+import org.apache.hop.ui.hopgui.selection.HopGuiSelectionTracker;
import org.apache.hop.ui.hopgui.shared.SwtGc;
import org.apache.hop.ui.pipeline.dialog.PipelineDialog;
import org.apache.hop.ui.util.EnvironmentUtils;
@@ -758,6 +759,10 @@ public class HopGuiPipelineGraph extends
HopGuiAbstractGraph
selectedTransforms = pipelineMeta.getSelectedTransforms();
selectedTransform = currentTransform;
+ // Track that a transform was selected
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
+
for (ITransformSelectionListener listener :
currentTransformListeners) {
listener.onUpdateSelection(currentTransform);
}
@@ -825,6 +830,9 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
currentNotePad = (NotePadMeta) areaOwner.getOwner();
selectedNotes = pipelineMeta.getSelectedNotes();
selectedNote = currentNotePad;
+ // Track that a note was selected
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
Point loc = currentNotePad.getLocation();
previousNoteLocations = pipelineMeta.getSelectedNoteLocations();
@@ -957,6 +965,12 @@ public class HopGuiPipelineGraph extends
HopGuiAbstractGraph
pipelineMeta.unselectAll();
selectInRect(pipelineMeta, selectionRegion);
selectionRegion = null;
+ // Track that transforms were selected via region selection
+ if (!pipelineMeta.getSelectedTransforms().isEmpty()
+ || !pipelineMeta.getSelectedNotes().isEmpty()) {
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
+ }
updateGui();
return;
}
@@ -1005,6 +1019,11 @@ public class HopGuiPipelineGraph extends
HopGuiAbstractGraph
// Flip selection when control is pressed!
if (control) {
selectedTransform.flipSelected();
+ // Track that a transform selection changed (if it's now selected)
+ if (selectedTransform.isSelected()) {
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
+ }
} else {
singleClick = true;
singleClickType = SingleClickType.Transform;
@@ -1016,11 +1035,19 @@ public class HopGuiPipelineGraph extends
HopGuiAbstractGraph
pipelineMeta.unselectAll();
selectedTransform.setSelected(true);
}
+ // Track that a transform was selected
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
}
} else {
// Find out which Transforms & Notes are selected
selectedTransforms = pipelineMeta.getSelectedTransforms();
selectedNotes = pipelineMeta.getSelectedNotes();
+ // Track that transforms were selected
+ if (!selectedTransforms.isEmpty() || !selectedNotes.isEmpty()) {
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
+ }
// We moved around some items: store undo info...
//
@@ -1079,6 +1106,11 @@ public class HopGuiPipelineGraph extends
HopGuiAbstractGraph
// Flip selection when control is pressed!
if (control) {
selectedNote.flipSelected();
+ // Track that a note selection changed (if it's now selected)
+ if (selectedNote.isSelected()) {
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
+ }
} else {
// single click on a note: ask what needs to happen...
//
@@ -1092,11 +1124,19 @@ public class HopGuiPipelineGraph extends
HopGuiAbstractGraph
pipelineMeta.unselectAll();
selectedNote.setSelected(true);
}
+ // Track that a note was selected
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
}
} else {
// Find out which Transforms & Notes are selected
selectedTransforms = pipelineMeta.getSelectedTransforms();
selectedNotes = pipelineMeta.getSelectedNotes();
+ // Track that notes were selected
+ if (!selectedTransforms.isEmpty() || !selectedNotes.isEmpty()) {
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
+ }
// We moved around some items: store undo info...
@@ -1516,6 +1556,9 @@ public class HopGuiPipelineGraph extends
HopGuiAbstractGraph
selectedTransforms = new ArrayList<>();
selectedTransforms.add(selectedTransform);
previousTransformLocations = new Point[]
{selectedTransform.getLocation()};
+ // Track that a transform was selected
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
doRedraw = true;
} else if (selectedNote != null && !selectedNote.isSelected()) {
pipelineMeta.unselectAll();
@@ -1523,6 +1566,9 @@ public class HopGuiPipelineGraph extends
HopGuiAbstractGraph
selectedNotes = new ArrayList<>();
selectedNotes.add(selectedNote);
previousNoteLocations = new Point[] {selectedNote.getLocation()};
+ // Track that a note was selected
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
doRedraw = true;
} else if (selectionRegion != null && startHopTransform == null) {
// Did we select a region...?
@@ -5243,6 +5289,19 @@ public class HopGuiPipelineGraph extends
HopGuiAbstractGraph
@GuiKeyboardShortcut(key = SWT.DEL)
@Override
public void deleteSelected() {
+ // Only handle delete if a pipeline graph item was the last selected item
+ // OR if there are actually selected transforms/notes in the pipeline
+ HopGuiSelectionTracker selectionTracker =
HopGuiSelectionTracker.getInstance();
+ boolean hasPipelineSelection =
+ !pipelineMeta.getSelectedTransforms().isEmpty()
+ || !pipelineMeta.getSelectedNotes().isEmpty();
+ boolean isLastPipelineSelection =
+
selectionTracker.isLastSelection(HopGuiSelectionTracker.SelectionType.PIPELINE_GRAPH);
+
+ if (!isLastPipelineSelection || !hasPipelineSelection) {
+ return;
+ }
+
delSelected(null);
updateGui();
}
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
index fc9cbfe573..a8883521f2 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
@@ -134,6 +134,7 @@ import
org.apache.hop.ui.hopgui.file.workflow.extension.HopGuiWorkflowGraphExten
import org.apache.hop.ui.hopgui.perspective.execution.ExecutionPerspective;
import org.apache.hop.ui.hopgui.perspective.execution.IExecutionViewer;
import org.apache.hop.ui.hopgui.perspective.explorer.ExplorerPerspective;
+import org.apache.hop.ui.hopgui.selection.HopGuiSelectionTracker;
import org.apache.hop.ui.hopgui.shared.SwtGc;
import org.apache.hop.ui.util.EnvironmentUtils;
import org.apache.hop.ui.util.HelpUtils;
@@ -691,6 +692,9 @@ public class HopGuiWorkflowGraph extends HopGuiAbstractGraph
currentNotePad = (NotePadMeta) areaOwner.getOwner();
selectedNotes = workflowMeta.getSelectedNotes();
selectedNote = currentNotePad;
+ // Track that a note was selected
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
Point loc = currentNotePad.getLocation();
previousNoteLocations = workflowMeta.getSelectedNoteLocations();
@@ -828,6 +832,12 @@ public class HopGuiWorkflowGraph extends
HopGuiAbstractGraph
workflowMeta.unselectAll();
selectInRect(workflowMeta, selectionRegion);
selectionRegion = null;
+ // Track that actions/notes were selected via region selection
+ if (!workflowMeta.getSelectedActions().isEmpty()
+ || !workflowMeta.getSelectedNotes().isEmpty()) {
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
+ }
updateGui();
return;
}
@@ -880,11 +890,19 @@ public class HopGuiWorkflowGraph extends
HopGuiAbstractGraph
workflowMeta.unselectAll();
selectedAction.setSelected(true);
}
+ // Track that an action was selected
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
}
} else {
// Find out which Transforms & Notes are selected
selectedActions = workflowMeta.getSelectedActions();
selectedNotes = workflowMeta.getSelectedNotes();
+ // Track that actions/notes were selected
+ if (!selectedActions.isEmpty() || !selectedNotes.isEmpty()) {
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
+ }
// We moved around some items: store undo info...
//
@@ -977,11 +995,19 @@ public class HopGuiWorkflowGraph extends
HopGuiAbstractGraph
workflowMeta.unselectAll();
selectedNote.setSelected(true);
}
+ // Track that a note was selected
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
}
} else {
// Find out which Transforms & Notes are selected
selectedActions = workflowMeta.getSelectedActions();
selectedNotes = workflowMeta.getSelectedNotes();
+ // Track that actions/notes were selected
+ if (!selectedActions.isEmpty() || !selectedNotes.isEmpty()) {
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH);
+ }
// We moved around some items: store undo info...
boolean also = false;
@@ -2070,6 +2096,12 @@ public class HopGuiWorkflowGraph extends
HopGuiAbstractGraph
@GuiKeyboardShortcut(key = SWT.DEL)
@Override
public void deleteSelected() {
+ // Only handle delete if a workflow graph item was the last selected item
+ HopGuiSelectionTracker selectionTracker =
HopGuiSelectionTracker.getInstance();
+ if
(!selectionTracker.isLastSelection(HopGuiSelectionTracker.SelectionType.WORKFLOW_GRAPH))
{
+ return;
+ }
+
deleteSelected(null);
}
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/ExplorerPerspective.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/ExplorerPerspective.java
index 3990d52213..acc57af337 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/ExplorerPerspective.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/ExplorerPerspective.java
@@ -92,6 +92,7 @@ import
org.apache.hop.ui.hopgui.perspective.explorer.file.ExplorerFileType;
import
org.apache.hop.ui.hopgui.perspective.explorer.file.IExplorerFileTypeHandler;
import org.apache.hop.ui.hopgui.perspective.explorer.file.types.FolderFileType;
import
org.apache.hop.ui.hopgui.perspective.explorer.file.types.GenericFileType;
+import org.apache.hop.ui.hopgui.selection.HopGuiSelectionTracker;
import org.apache.hop.workflow.WorkflowMeta;
import org.apache.hop.workflow.engine.IWorkflowEngine;
import org.eclipse.swt.SWT;
@@ -1541,6 +1542,12 @@ public class ExplorerPerspective implements
IHopPerspective, TabClosable {
@GuiKeyboardShortcut(key = SWT.DEL)
@GuiOsxKeyboardShortcut(key = SWT.DEL)
public void deleteFile() {
+ // Only handle delete if a file was the last selected item
+ HopGuiSelectionTracker selectionTracker =
HopGuiSelectionTracker.getInstance();
+ if
(!selectionTracker.isLastSelection(HopGuiSelectionTracker.SelectionType.FILE_EXPLORER))
{
+ return;
+ }
+
TreeItem[] selection = tree.getSelection();
if (selection == null || selection.length == 0) {
return;
@@ -1872,6 +1879,9 @@ public class ExplorerPerspective implements
IHopPerspective, TabClosable {
if (tif == null) {
return;
}
+ // Track that a file was selected
+ HopGuiSelectionTracker.getInstance()
+
.setLastSelectionType(HopGuiSelectionTracker.SelectionType.FILE_EXPLORER);
}
boolean isFolderSelected = tif != null && tif.fileType instanceof
FolderFileType;
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/selection/HopGuiSelectionTracker.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/selection/HopGuiSelectionTracker.java
new file mode 100644
index 0000000000..6957873f95
--- /dev/null
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/selection/HopGuiSelectionTracker.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.ui.hopgui.selection;
+
+/**
+ * Tracks the last selected item type to help route keyboard shortcuts
correctly. This is needed
+ * when multiple components (like file explorer and pipeline graph) share the
same keyboard
+ * shortcuts but need to act on different types of items.
+ */
+public class HopGuiSelectionTracker {
+
+ private static HopGuiSelectionTracker instance;
+
+ /** The type of item that was last selected */
+ public enum SelectionType {
+ /** A file or folder in the file explorer */
+ FILE_EXPLORER,
+ /** A transform, note, or hop in a pipeline graph */
+ PIPELINE_GRAPH,
+ /** An action, note, or hop in a workflow graph */
+ WORKFLOW_GRAPH,
+ /** No specific selection */
+ NONE
+ }
+
+ private SelectionType lastSelectionType = SelectionType.NONE;
+
+ private HopGuiSelectionTracker() {
+ // Singleton
+ }
+
+ public static HopGuiSelectionTracker getInstance() {
+ if (instance == null) {
+ instance = new HopGuiSelectionTracker();
+ }
+ return instance;
+ }
+
+ /**
+ * Set the last selected item type
+ *
+ * @param selectionType The type of item that was selected
+ */
+ public void setLastSelectionType(SelectionType selectionType) {
+ this.lastSelectionType = selectionType;
+ }
+
+ /**
+ * Get the last selected item type
+ *
+ * @return The type of item that was last selected
+ */
+ public SelectionType getLastSelectionType() {
+ return lastSelectionType;
+ }
+
+ /**
+ * Check if the last selection matches the given type
+ *
+ * @param selectionType The type to check against
+ * @return true if the last selection matches the given type
+ */
+ public boolean isLastSelection(SelectionType selectionType) {
+ return lastSelectionType == selectionType;
+ }
+}