disk selection fix

This commit is contained in:
Radek Davidek 2026-01-20 18:48:13 +01:00
parent a3f97f9369
commit 7cbff72d38

View File

@ -19,6 +19,7 @@ public class FilePanel extends JPanel {
private JLabel driveInfoLabel; private JLabel driveInfoLabel;
private cz.kamma.kfmanager.config.AppConfig appConfig; private cz.kamma.kfmanager.config.AppConfig appConfig;
private Runnable onDirectoryChangedAll; private Runnable onDirectoryChangedAll;
private boolean ignoreComboActions = false;
public FilePanel(String initialPath) { public FilePanel(String initialPath) {
initComponents(); initComponents();
@ -112,22 +113,31 @@ public class FilePanel extends JPanel {
driveInfoLabel.setFont(new Font("SansSerif", Font.PLAIN, 12)); driveInfoLabel.setFont(new Font("SansSerif", Font.PLAIN, 12));
driveInfoLabel.setBorder(BorderFactory.createEmptyBorder(0,6,0,6)); driveInfoLabel.setBorder(BorderFactory.createEmptyBorder(0,6,0,6));
// Require explicit confirmation (Enter) to load selected drive. // Interaction behavior:
// Selection changes (mouse/typing) only update the selected item; loading occurs on Enter. // - Mouse click in dropdown: Refresh immediately.
driveCombo.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER, 0), "confirmDrive"); // - Keyboard navigation (arrows): Update info label only, refresh only on Enter.
driveCombo.getActionMap().put("confirmDrive", new AbstractAction() { driveCombo.addActionListener(e -> {
@Override if (ignoreComboActions) return;
public void actionPerformed(ActionEvent e) {
Object selObj = driveCombo.getSelectedItem(); // Determine if we should trigger directory load.
if (selObj instanceof File) { // We want to skip arrow keys and only react to Mouse or Enter.
File sel = (File) selObj; java.awt.AWTEvent currentEvent = java.awt.EventQueue.getCurrentEvent();
FilePanelTab currentTab = getCurrentTab(); if (currentEvent instanceof java.awt.event.KeyEvent) {
if (currentTab != null) { java.awt.event.KeyEvent ke = (java.awt.event.KeyEvent) currentEvent;
currentTab.loadDirectory(sel); if (ke.getKeyCode() != java.awt.event.KeyEvent.VK_ENTER) {
SwingUtilities.invokeLater(() -> { return;
try { currentTab.getFileTable().requestFocusInWindow(); } catch (Exception ignore) {} }
}); }
}
Object selObj = driveCombo.getSelectedItem();
if (selObj instanceof File) {
File sel = (File) selObj;
FilePanelTab currentTab = getCurrentTab();
if (currentTab != null) {
currentTab.loadDirectory(sel);
SwingUtilities.invokeLater(() -> {
try { currentTab.getFileTable().requestFocusInWindow(); } catch (Exception ignore) {}
});
} }
} }
}); });
@ -413,65 +423,70 @@ public class FilePanel extends JPanel {
} }
private void populateDrives() { private void populateDrives() {
driveCombo.removeAllItems(); ignoreComboActions = true;
java.util.Set<File> driveSet = new java.util.LinkedHashSet<>(); try {
driveCombo.removeAllItems();
java.util.Set<File> driveSet = new java.util.LinkedHashSet<>();
// Add standard roots // Add standard roots
File[] roots = File.listRoots(); File[] roots = File.listRoots();
if (roots != null) { if (roots != null) {
for (File r : roots) { for (File r : roots) {
driveSet.add(r); driveSet.add(r);
}
} }
}
// Add home directory // Add home directory
driveSet.add(new File(System.getProperty("user.home"))); driveSet.add(new File(System.getProperty("user.home")));
// On Linux/Unix, add common mount points // On Linux/Unix, add common mount points
String os = System.getProperty("os.name").toLowerCase(); String os = System.getProperty("os.name").toLowerCase();
if (!os.contains("win")) { if (!os.contains("win")) {
// Common Linux/Unix mount points // Common Linux/Unix mount points
String user = System.getProperty("user.name"); String user = System.getProperty("user.name");
// Typical locations for removable media // Typical locations for removable media
String[] commonMountPoints = { String[] commonMountPoints = {
"/media/" + user, "/media/" + user,
"/run/media/" + user, "/run/media/" + user,
"/mnt", "/mnt",
"/Volumes" // macOS "/Volumes" // macOS
}; };
for (String path : commonMountPoints) { for (String path : commonMountPoints) {
File dir = new File(path); File dir = new File(path);
if (dir.exists() && dir.isDirectory()) { if (dir.exists() && dir.isDirectory()) {
File[] subDirs = dir.listFiles(); File[] subDirs = dir.listFiles();
if (subDirs != null) { if (subDirs != null) {
for (File sub : subDirs) { for (File sub : subDirs) {
if (sub.isDirectory()) { if (sub.isDirectory()) {
driveSet.add(sub); driveSet.add(sub);
}
} }
} else if (!path.contains(user)) {
// For /mnt we might also add the directory itself if it's empty but meant to be used
driveSet.add(dir);
} }
} else if (!path.contains(user)) {
// For /mnt we might also add the directory itself if it's empty but meant to be used
driveSet.add(dir);
} }
} }
} }
}
for (File d : driveSet) { for (File d : driveSet) {
try { try {
driveCombo.addItem(d); driveCombo.addItem(d);
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
// Initialize selection // Initialize selection
if (driveCombo.getItemCount() > 0) { if (driveCombo.getItemCount() > 0) {
driveCombo.setSelectedIndex(0); driveCombo.setSelectedIndex(0);
} }
// Update info for currently selected drive // Update info for currently selected drive
updateDriveInfoFromSelection(); updateDriveInfoFromSelection();
} finally {
ignoreComboActions = false;
}
// Update info label on selection changes (visual selection only) // Update info label on selection changes (visual selection only)
driveCombo.addItemListener(ev -> { driveCombo.addItemListener(ev -> {
@ -577,6 +592,7 @@ public class FilePanel extends JPanel {
FilePanelTab currentTab = getCurrentTab(); FilePanelTab currentTab = getCurrentTab();
if (currentTab != null) { if (currentTab != null) {
// Update drive combo selection to match current directory // Update drive combo selection to match current directory
ignoreComboActions = true;
try { try {
File cur = currentTab.getCurrentDirectory(); File cur = currentTab.getCurrentDirectory();
if (cur != null) { if (cur != null) {
@ -585,7 +601,10 @@ public class FilePanel extends JPanel {
// also update info label to reflect current tab's root // also update info label to reflect current tab's root
updateDriveInfo(root); updateDriveInfo(root);
} }
} catch (Exception ignore) {} } catch (Exception ignore) {
} finally {
ignoreComboActions = false;
}
} }
} }