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 25f1d68b97 Add context menu to open file in os file explorer #6564 
(#6645)
25f1d68b97 is described below

commit 25f1d68b97d420add23cbf657c6353d7c00eb9d8
Author: Nicolas Adment <[email protected]>
AuthorDate: Thu Feb 26 08:43:40 2026 +0100

    Add context menu to open file in os file explorer #6564 (#6645)
---
 .../main/java/org/apache/hop/core/vfs/HopVfs.java  |  9 ++++++
 .../perspective/explorer/ExplorerPerspective.java  | 34 ++++++++++++++++++++++
 .../org/apache/hop/ui/util/EnvironmentUtils.java   | 32 ++++++++++++++++++++
 .../explorer/messages/messages_en_US.properties    |  3 ++
 4 files changed, 78 insertions(+)

diff --git a/core/src/main/java/org/apache/hop/core/vfs/HopVfs.java 
b/core/src/main/java/org/apache/hop/core/vfs/HopVfs.java
index f6f85fc44e..a2313dc5f3 100644
--- a/core/src/main/java/org/apache/hop/core/vfs/HopVfs.java
+++ b/core/src/main/java/org/apache/hop/core/vfs/HopVfs.java
@@ -376,6 +376,15 @@ public class HopVfs {
     }
   }
 
+  public static boolean isLocalFileSystem(String path) {
+    try {
+      FileObject fileObject = getFileObject(path);
+      return fileObject instanceof LocalFile;
+    } catch (HopFileException e) {
+      return false;
+    }
+  }
+
   public static InputStream getInputStream(FileObject fileObject) throws 
FileSystemException {
     FileContent content = fileObject.getContent();
     return content.getInputStream();
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 45a3ee9b91..5d23092799 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
@@ -100,6 +100,7 @@ import 
org.apache.hop.ui.hopgui.perspective.explorer.file.IExplorerFileTypeHandl
 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.shared.CanvasZoomHelper;
+import org.apache.hop.ui.util.EnvironmentUtils;
 import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.engine.IWorkflowEngine;
 import org.eclipse.swt.SWT;
@@ -179,6 +180,8 @@ public class ExplorerPerspective implements 
IHopPerspective, TabClosable {
   public static final String CONTEXT_MENU_OPEN = 
"ExplorerPerspective-ContextMenu-10100-Open";
   public static final String CONTEXT_MENU_OPEN_AS_TEXT =
       "ExplorerPerspective-ContextMenu-10101-OpenAsText";
+  public static final String CONTEXT_MENU_OPEN_IN_EXPLORER =
+      "ExplorerPerspective-ContextMenu-10102-OpenInExplorer";
   public static final String CONTEXT_MENU_RENAME = 
"ExplorerPerspective-ContextMenu-10300-Rename";
   public static final String CONTEXT_MENU_COPY_NAME =
       "ExplorerPerspective-ContextMenu-10400-CopyName";
@@ -524,6 +527,11 @@ public class ExplorerPerspective implements 
IHopPerspective, TabClosable {
           if (openAsTextItem != null) {
             openAsTextItem.setEnabled(selection.length == 1 && tif != null && 
!tif.folder);
           }
+          MenuItem openInExplorerItem = 
menuWidgets.findMenuItem(CONTEXT_MENU_OPEN_IN_EXPLORER);
+          if (openInExplorerItem != null) {
+            openInExplorerItem.setEnabled(HopVfs.isLocalFileSystem(tif.path));
+          }
+
           
menuWidgets.findMenuItem(CONTEXT_MENU_RENAME).setEnabled(selection.length == 1);
 
           // Show the menu
@@ -1614,6 +1622,32 @@ public class ExplorerPerspective implements 
IHopPerspective, TabClosable {
     openFile(selection[0]);
   }
 
+  @GuiMenuElement(
+      root = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+      parentId = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+      id = CONTEXT_MENU_OPEN_IN_EXPLORER,
+      label = "i18n::ExplorerPerspective.Menu.OpenInExplorer")
+  public void openFileInExplorer() {
+    TreeItem[] selection = tree.getSelection();
+    if (selection == null || selection.length == 0) {
+      return;
+    }
+
+    TreeItemFolder tif = (TreeItemFolder) selection[0].getData();
+    if (tif != null) {
+      try {
+        EnvironmentUtils.getInstance().openFileExplorer(tif.path);
+      } catch (Throwable e) {
+        new ErrorDialog(
+            getShell(),
+            BaseMessages.getString(PKG, 
"ExplorerPerspective.Error.OpenFileInExplorer.Title"),
+            BaseMessages.getString(
+                PKG, "ExplorerPerspective.Error.OpenFileInExplorer.Message", 
tif.path),
+            e);
+      }
+    }
+  }
+
   @GuiMenuElement(
       root = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
       parentId = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
diff --git a/ui/src/main/java/org/apache/hop/ui/util/EnvironmentUtils.java 
b/ui/src/main/java/org/apache/hop/ui/util/EnvironmentUtils.java
index f33e9d2f10..c53d126fbc 100644
--- a/ui/src/main/java/org/apache/hop/ui/util/EnvironmentUtils.java
+++ b/ui/src/main/java/org/apache/hop/ui/util/EnvironmentUtils.java
@@ -16,7 +16,9 @@
  */
 package org.apache.hop.ui.util;
 
+import java.awt.Desktop;
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.lang.reflect.Method;
@@ -26,6 +28,7 @@ import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.logging.ILogChannel;
 import org.apache.hop.core.logging.LogChannel;
 import org.apache.hop.ui.core.PropsUi;
+import org.apache.hop.ui.core.widget.OsHelper;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.SWTError;
 import org.eclipse.swt.browser.Browser;
@@ -216,6 +219,35 @@ public class EnvironmentUtils {
     return System.getProperty("HOP_WEB_THEME");
   }
 
+  /** Open the file explorer based on OS and select the file */
+  public void openFileExplorer(String path) throws HopException {
+
+    if (path == null || path.isBlank()) {
+      return;
+    }
+
+    try {
+      if (OsHelper.isWindows()) {
+        // Open File Explorer on Windows
+        Runtime.getRuntime().exec("explorer.exe  /select," + path);
+      } else if (OsHelper.isMac()) {
+        // Open Finder on Mac
+        Runtime.getRuntime().exec("open -R " + path);
+      } else if (Desktop.isDesktopSupported()) {
+        File file = new File(path);
+        if (file.exists()) {
+          // If it is a file, open the parent folder
+          if (file.isFile()) {
+            file = file.getParentFile();
+          }
+          Desktop.getDesktop().open(file);
+        }
+      }
+    } catch (IOException e) {
+      throw new HopException("Error opening file in explorer", e);
+    }
+  }
+
   public void openUrl(String url) throws HopException {
     if (isWeb()) {
       try {
diff --git 
a/ui/src/main/resources/org/apache/hop/ui/hopgui/perspective/explorer/messages/messages_en_US.properties
 
b/ui/src/main/resources/org/apache/hop/ui/hopgui/perspective/explorer/messages/messages_en_US.properties
index f0af81d93a..c94ecf6a0a 100644
--- 
a/ui/src/main/resources/org/apache/hop/ui/hopgui/perspective/explorer/messages/messages_en_US.properties
+++ 
b/ui/src/main/resources/org/apache/hop/ui/hopgui/perspective/explorer/messages/messages_en_US.properties
@@ -34,12 +34,15 @@ ExplorerPerspective.Error.RootFolder.Header=Error
 ExplorerPerspective.Error.RootFolder.Message=Error getting root folder/name of 
explorer perspective
 ExplorerPerspective.Error.TreeRefresh.Header=Error
 ExplorerPerspective.Error.TreeRefresh.Message=Error refreshing file explorer 
tree
+ExplorerPerspective.Error.OpenFileInExplorer.Title=Error
+ExplorerPerspective.Error.OpenFileInExplorer.Message=Error opening file in 
explorer:\n''{0}''
 ExplorerPerspective.GuiPlugin.Description=A file explorer for your current 
project
 ExplorerPerspective.Menu.CopyName=Copy name
 ExplorerPerspective.Menu.CopyPath=Copy path
 ExplorerPerspective.Menu.CreateFolder=Create folder
 ExplorerPerspective.Menu.Delete=Delete
 ExplorerPerspective.Menu.Open=Open
+ExplorerPerspective.Menu.OpenInExplorer=Open in explorer
 ExplorerPerspective.Menu.Rename=Rename
 ExplorerPerspective.Menu.ExpandAll=Expand All
 ExplorerPerspective.Menu.CollapseAll=Collapse All

Reply via email to