From 177f63f48572271e3e4c695af2078635618e233e Mon Sep 17 00:00:00 2001 From: Radek Davidek Date: Thu, 26 Feb 2026 13:14:57 +0100 Subject: [PATCH] search in panel with ctrl alt --- src/main/java/cz/kamma/kfmanager/MainApp.java | 2 +- .../cz/kamma/kfmanager/ui/FilePanelTab.java | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/main/java/cz/kamma/kfmanager/MainApp.java b/src/main/java/cz/kamma/kfmanager/MainApp.java index 9053d2f..6855bdd 100644 --- a/src/main/java/cz/kamma/kfmanager/MainApp.java +++ b/src/main/java/cz/kamma/kfmanager/MainApp.java @@ -15,7 +15,7 @@ import java.io.InputStreamReader; */ public class MainApp { - public static final String APP_VERSION = "1.1.8"; + public static final String APP_VERSION = "1.1.9"; public enum OS { WINDOWS, LINUX, MACOS, UNKNOWN diff --git a/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java b/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java index a1803d5..ec726c3 100644 --- a/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java +++ b/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java @@ -26,6 +26,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Locale; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; @@ -71,6 +72,9 @@ public class FilePanelTab extends JPanel { private boolean active = false; private final Map changeTimestamps = new HashMap<>(); private static final long CHANGE_HIGHLIGHT_DURATION = 500; // 0.5 seconds per item + private String ctrlAltTypeBuffer = ""; + private long ctrlAltTypeLastTs = 0L; + private static final long CTRL_ALT_TYPE_RESET_MS = 1200; public FilePanelTab(String initialPath) { this(initialPath, true); @@ -869,6 +873,17 @@ public class FilePanelTab extends JPanel { fileTable.addKeyListener(new java.awt.event.KeyAdapter() { @Override public void keyPressed(java.awt.event.KeyEvent e) { + if ((e.isControlDown() && (e.isAltDown() || e.isAltGraphDown()) && !e.isMetaDown())) { + char typed = e.getKeyChar(); + if (typed == KeyEvent.CHAR_UNDEFINED || typed < 32) { + typed = keyCodeToChar(e.getKeyCode(), e.isShiftDown()); + } + if (typed != 0) { + handleCtrlAltTypeSearch(typed); + e.consume(); + return; + } + } if (e.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER && !e.isControlDown()) { openSelectedItem(); e.consume(); @@ -920,8 +935,59 @@ public class FilePanelTab extends JPanel { } } } + + @Override + public void keyTyped(java.awt.event.KeyEvent e) { + // Intentionally empty: Ctrl+Alt combinations often bypass keyTyped. + } }); } + + private void handleCtrlAltTypeSearch(char c) { + if (inlineRenameActive || fileTable.isEditing()) return; + long now = System.currentTimeMillis(); + if (now - ctrlAltTypeLastTs > CTRL_ALT_TYPE_RESET_MS) { + ctrlAltTypeBuffer = ""; + } + ctrlAltTypeLastTs = now; + ctrlAltTypeBuffer += Character.toLowerCase(c); + + String match = findFirstItemStartingWith(ctrlAltTypeBuffer); + if (match == null && ctrlAltTypeBuffer.length() > 1) { + ctrlAltTypeBuffer = String.valueOf(Character.toLowerCase(c)); + match = findFirstItemStartingWith(ctrlAltTypeBuffer); + } + if (match != null) { + selectItemByName(match, true); + } + } + + private String findFirstItemStartingWith(String prefix) { + if (prefix == null || prefix.isEmpty()) return null; + String p = prefix.toLowerCase(Locale.ROOT); + for (FileItem item : tableModel.items) { + if (item == null) continue; + String name = item.getName(); + if (name != null && name.toLowerCase(Locale.ROOT).startsWith(p)) { + return name; + } + } + return null; + } + + private static char keyCodeToChar(int keyCode, boolean shift) { + if (keyCode >= KeyEvent.VK_A && keyCode <= KeyEvent.VK_Z) { + char base = (char) ('a' + (keyCode - KeyEvent.VK_A)); + return shift ? Character.toUpperCase(base) : base; + } + if (keyCode >= KeyEvent.VK_0 && keyCode <= KeyEvent.VK_9) { + return (char) ('0' + (keyCode - KeyEvent.VK_0)); + } + if (keyCode >= KeyEvent.VK_NUMPAD0 && keyCode <= KeyEvent.VK_NUMPAD9) { + return (char) ('0' + (keyCode - KeyEvent.VK_NUMPAD0)); + } + return 0; + } private void handleBriefKeyNavigation(java.awt.event.KeyEvent e) { switch (e.getKeyCode()) {