diff --git a/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java b/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java index 28d031f..5c6644d 100644 --- a/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java +++ b/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java @@ -1,6 +1,7 @@ package cz.kamma.kfmanager.ui; import cz.kamma.kfmanager.model.FileItem; +import cz.kamma.kfmanager.config.AppConfig; import cz.kamma.kfmanager.service.ClipboardService; import cz.kamma.kfmanager.service.FileOperations; @@ -901,8 +902,23 @@ public class FilePanelTab extends JPanel { } public void loadDirectory(File directory, boolean autoSelectFirst, boolean requestFocus, final Runnable postLoadAction) { + // Ensure we load an existing directory - try parents if necessary + File dirToLoad = directory; + while (dirToLoad != null && !dirToLoad.isDirectory()) { + dirToLoad = dirToLoad.getParentFile(); + } + + if (dirToLoad == null) { + dirToLoad = new File(System.getProperty("user.home")); + if (!dirToLoad.isDirectory()) { + dirToLoad = new File(File.separator); + } + } + directory = dirToLoad; + // If we are switching directories, cleanup any previously extracted archive temp dirs cleanupArchiveTempDirIfNeeded(directory); + if (directory == null || !directory.isDirectory()) { return; } @@ -1375,26 +1391,7 @@ public class FilePanelTab extends JPanel { } if (command != null && !command.trim().isEmpty()) { - String fullPath = file.getAbsolutePath(); - String fileName = file.getName(); - String trimmedCmd = command.trim(); - boolean hasPlaceholder = trimmedCmd.contains("%f") || trimmedCmd.contains("%n"); - - java.util.List cmdList = new java.util.ArrayList<>(); - String[] parts = trimmedCmd.split("\\s+"); - for (String part : parts) { - String processed = part.replace("%f", fullPath).replace("%n", fileName); - if (processed.startsWith("\"") && processed.endsWith("\"") && processed.length() >= 2) { - processed = processed.substring(1, processed.length() - 1); - } - cmdList.add(processed); - } - - if (!hasPlaceholder) { - cmdList.add(fullPath); - } - - new ProcessBuilder(cmdList).directory(file.getParentFile()).start(); + runExternalCommand(command, file); return; } } @@ -1421,6 +1418,35 @@ public class FilePanelTab extends JPanel { } } + private void runExternalCommand(String command, File file) { + if (command == null || command.trim().isEmpty() || file == null) return; + try { + String fullPath = file.getAbsolutePath(); + String fileName = file.getName(); + String trimmedCmd = command.trim(); + + boolean hasPlaceholder = trimmedCmd.contains("%f") || trimmedCmd.contains("%n"); + + java.util.List cmdList = new java.util.ArrayList<>(); + String[] parts = trimmedCmd.split("\\s+"); + for (String part : parts) { + String processed = part.replace("%f", fullPath).replace("%n", fileName); + if (processed.startsWith("\"") && processed.endsWith("\"") && processed.length() >= 2) { + processed = processed.substring(1, processed.length() - 1); + } + cmdList.add(processed); + } + + if (!hasPlaceholder) { + cmdList.add(fullPath); + } + + new ProcessBuilder(cmdList).directory(file.getParentFile()).start(); + } catch (Exception ex) { + try { JOptionPane.showMessageDialog(this, "Cannot execute command: " + ex.getMessage()); } catch (Exception ignore) {} + } + } + /** * Open the item located at the given point (used for double-clicks while * mouse-driven selection is blocked). This mirrors the behavior of @@ -1482,6 +1508,36 @@ public class FilePanelTab extends JPanel { }); menu.add(openItem); + // Open with + if (!item.getName().equals("..")) { + java.util.List owEntries = persistedConfig != null ? persistedConfig.getOpenWithEntries() : new java.util.ArrayList<>(); + String itemType; + if (item.isDirectory()) { + itemType = "directory"; + } else { + String name = item.getFile().getName().toLowerCase(); + int dot = name.lastIndexOf('.'); + itemType = (dot > 0 && dot < name.length() - 1) ? name.substring(dot + 1) : ""; + } + + java.util.List filtered = new java.util.ArrayList<>(); + for (AppConfig.OpenWithEntry e : owEntries) { + if (e.type != null && e.type.equalsIgnoreCase(itemType)) { + filtered.add(e); + } + } + + if (!filtered.isEmpty()) { + JMenu openWithMenu = new JMenu("Open with"); + for (AppConfig.OpenWithEntry e : filtered) { + JMenuItem owItem = new JMenuItem(e.label); + owItem.addActionListener(ae -> runExternalCommand(e.command, item.getFile())); + openWithMenu.add(owItem); + } + menu.add(openWithMenu); + } + } + // Edit JMenuItem editItem = new JMenuItem("Edit"); editItem.addActionListener(ae -> {