fixed esc
This commit is contained in:
parent
803e1e707b
commit
d4bfeab00d
@ -5,6 +5,7 @@ import cz.kamma.kfmanager.model.FileItem;
|
|||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -47,6 +48,7 @@ public class FilePanel extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
tabbedPane = new JTabbedPane();
|
||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||||
|
|
||||||
@ -55,6 +57,16 @@ public class FilePanel extends JPanel {
|
|||||||
|
|
||||||
// Drive selection dropdown placed before the path field
|
// Drive selection dropdown placed before the path field
|
||||||
driveCombo = new JComboBox<>();
|
driveCombo = new JComboBox<>();
|
||||||
|
// Return focus to table when ESC is pressed in the combo
|
||||||
|
driveCombo.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel-drive-selection");
|
||||||
|
driveCombo.getActionMap().put("cancel-drive-selection", new AbstractAction() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
driveCombo.hidePopup();
|
||||||
|
FilePanelTab tab = getCurrentTab();
|
||||||
|
if (tab != null) tab.getFileTable().requestFocusInWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
// Allow the combo to receive focus so keyboard navigation and popup interaction work
|
// Allow the combo to receive focus so keyboard navigation and popup interaction work
|
||||||
driveCombo.setFocusable(true);
|
driveCombo.setFocusable(true);
|
||||||
driveCombo.setToolTipText("Select drive");
|
driveCombo.setToolTipText("Select drive");
|
||||||
@ -156,7 +168,6 @@ public class FilePanel extends JPanel {
|
|||||||
add(topPanel, BorderLayout.NORTH);
|
add(topPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
// JTabbedPane for tabs
|
// JTabbedPane for tabs
|
||||||
tabbedPane = new JTabbedPane();
|
|
||||||
tabbedPane.setTabPlacement(JTabbedPane.TOP);
|
tabbedPane.setTabPlacement(JTabbedPane.TOP);
|
||||||
|
|
||||||
// Listener for updating path and style on tab change
|
// Listener for updating path and style on tab change
|
||||||
|
|||||||
@ -62,6 +62,7 @@ public class FilePanelTab extends JPanel {
|
|||||||
// we can cleanup older temp directories when navigation changes.
|
// we can cleanup older temp directories when navigation changes.
|
||||||
private Path currentArchiveTempDir = null;
|
private Path currentArchiveTempDir = null;
|
||||||
private File currentArchiveSourceFile = null;
|
private File currentArchiveSourceFile = null;
|
||||||
|
private boolean inlineRenameActive = false;
|
||||||
|
|
||||||
public FilePanelTab(String initialPath) {
|
public FilePanelTab(String initialPath) {
|
||||||
this(initialPath, true);
|
this(initialPath, true);
|
||||||
@ -88,8 +89,14 @@ public class FilePanelTab extends JPanel {
|
|||||||
editCol = 0; // name column in FULL
|
editCol = 0; // name column in FULL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable editing temporarily
|
||||||
|
inlineRenameActive = true;
|
||||||
|
|
||||||
// Only allow editing if the cell represents a real item
|
// Only allow editing if the cell represents a real item
|
||||||
if (!tableModel.isCellEditable(selRow, editCol)) return;
|
if (!tableModel.isCellEditable(selRow, editCol)) {
|
||||||
|
inlineRenameActive = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Start editing and select all text in editor
|
// Start editing and select all text in editor
|
||||||
boolean started = fileTable.editCellAt(selRow, editCol);
|
boolean started = fileTable.editCellAt(selRow, editCol);
|
||||||
@ -100,6 +107,8 @@ public class FilePanelTab extends JPanel {
|
|||||||
tf.requestFocusInWindow();
|
tf.requestFocusInWindow();
|
||||||
tf.selectAll();
|
tf.selectAll();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
inlineRenameActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +214,18 @@ public class FilePanelTab extends JPanel {
|
|||||||
// Also override mouse-motion processing to suppress drag events and
|
// Also override mouse-motion processing to suppress drag events and
|
||||||
// prevent any drag-and-drop transfer handling.
|
// prevent any drag-and-drop transfer handling.
|
||||||
fileTable = new JTable(tableModel) {
|
fileTable = new JTable(tableModel) {
|
||||||
|
@Override
|
||||||
|
public void editingStopped(javax.swing.event.ChangeEvent e) {
|
||||||
|
super.editingStopped(e);
|
||||||
|
inlineRenameActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void editingCanceled(javax.swing.event.ChangeEvent e) {
|
||||||
|
super.editingCanceled(e);
|
||||||
|
inlineRenameActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void processMouseEvent(java.awt.event.MouseEvent e) {
|
protected void processMouseEvent(java.awt.event.MouseEvent e) {
|
||||||
// Show system-like context menu on popup trigger (right-click) without
|
// Show system-like context menu on popup trigger (right-click) without
|
||||||
@ -586,6 +607,11 @@ public class FilePanelTab extends JPanel {
|
|||||||
} else if (e.getKeyCode() == java.awt.event.KeyEvent.VK_INSERT) {
|
} else if (e.getKeyCode() == java.awt.event.KeyEvent.VK_INSERT) {
|
||||||
toggleSelectionAndMoveDown();
|
toggleSelectionAndMoveDown();
|
||||||
e.consume();
|
e.consume();
|
||||||
|
} else if (e.getKeyCode() == java.awt.event.KeyEvent.VK_ESCAPE) {
|
||||||
|
if (fileTable.isEditing()) {
|
||||||
|
fileTable.getCellEditor().cancelCellEditing();
|
||||||
|
e.consume();
|
||||||
|
}
|
||||||
} else if (viewMode == ViewMode.BRIEF) {
|
} else if (viewMode == ViewMode.BRIEF) {
|
||||||
handleBriefKeyNavigation(e);
|
handleBriefKeyNavigation(e);
|
||||||
} else if (viewMode == ViewMode.FULL) {
|
} else if (viewMode == ViewMode.FULL) {
|
||||||
@ -1156,11 +1182,17 @@ public class FilePanelTab extends JPanel {
|
|||||||
} else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
|
} else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
|
||||||
// 3. Fallback to system default
|
// 3. Fallback to system default
|
||||||
Desktop.getDesktop().open(file);
|
Desktop.getDesktop().open(file);
|
||||||
|
// Try to keep focus or at least set it back for when user returns
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
fileTable.requestFocusInWindow();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
try {
|
try {
|
||||||
JOptionPane.showMessageDialog(this, "Error opening file: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(this, "Error opening file: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
} catch (Exception ignore) {}
|
} catch (Exception ignore) {}
|
||||||
|
} finally {
|
||||||
|
fileTable.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1196,7 +1228,7 @@ public class FilePanelTab extends JPanel {
|
|||||||
} catch (Exception ignore) {}
|
} catch (Exception ignore) {}
|
||||||
currentArchiveTempDir = temp;
|
currentArchiveTempDir = temp;
|
||||||
currentArchiveSourceFile = item.getFile();
|
currentArchiveSourceFile = item.getFile();
|
||||||
loadDirectory(temp.toFile());
|
loadDirectory(temp.toFile(), true, true);
|
||||||
}
|
}
|
||||||
} else if (item.isDirectory()) {
|
} else if (item.isDirectory()) {
|
||||||
loadDirectory(item.getFile());
|
loadDirectory(item.getFile());
|
||||||
@ -1364,7 +1396,7 @@ public class FilePanelTab extends JPanel {
|
|||||||
PropertiesDialog dialog = new PropertiesDialog(parent, f);
|
PropertiesDialog dialog = new PropertiesDialog(parent, f);
|
||||||
dialog.setVisible(true);
|
dialog.setVisible(true);
|
||||||
// Refresh current directory after potential attribute changes
|
// Refresh current directory after potential attribute changes
|
||||||
loadDirectory(getCurrentDirectory());
|
loadDirectory(getCurrentDirectory(), false, true);
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
try { JOptionPane.showMessageDialog(FilePanelTab.this, "Cannot show properties: " + ex.getMessage()); } catch (Exception ignore) {}
|
try { JOptionPane.showMessageDialog(FilePanelTab.this, "Cannot show properties: " + ex.getMessage()); } catch (Exception ignore) {}
|
||||||
@ -1414,11 +1446,11 @@ public class FilePanelTab extends JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectItemByName(String name) {
|
public void selectItemByName(String name) {
|
||||||
selectItemByName(name, true);
|
selectItemByName(name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectItemByName(String name, boolean requestFocus) {
|
public void selectItemByName(String name, boolean requestFocus) {
|
||||||
if (viewMode == ViewMode.BRIEF) {
|
if (viewMode == ViewMode.BRIEF) {
|
||||||
// Re-calculate layout if needed before searching to ensure current mapping
|
// Re-calculate layout if needed before searching to ensure current mapping
|
||||||
if (tableModel.items.size() > 0 && (tableModel.briefColumns == 0 || tableModel.briefRowsPerColumn == 0)) {
|
if (tableModel.items.size() > 0 && (tableModel.briefColumns == 0 || tableModel.briefRowsPerColumn == 0)) {
|
||||||
@ -2545,6 +2577,8 @@ public class FilePanelTab extends JPanel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||||
|
if (!inlineRenameActive) return false;
|
||||||
|
|
||||||
if (viewMode == ViewMode.BRIEF) {
|
if (viewMode == ViewMode.BRIEF) {
|
||||||
FileItem it = getItemFromBriefLayout(rowIndex, columnIndex);
|
FileItem it = getItemFromBriefLayout(rowIndex, columnIndex);
|
||||||
return it != null; // allow editing name in brief cells
|
return it != null; // allow editing name in brief cells
|
||||||
|
|||||||
@ -687,6 +687,7 @@ public class MainWindow extends JFrame {
|
|||||||
dlg.setVisible(true);
|
dlg.setVisible(true);
|
||||||
// After dialog closed, ensure appearance applied
|
// After dialog closed, ensure appearance applied
|
||||||
applyAppearanceSettings();
|
applyAppearanceSettings();
|
||||||
|
requestFocusInActivePanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -839,9 +840,18 @@ public class MainWindow extends JFrame {
|
|||||||
|
|
||||||
// ESC - global escape to return focus to panels
|
// ESC - global escape to return focus to panels
|
||||||
rootPane.registerKeyboardAction(e -> {
|
rootPane.registerKeyboardAction(e -> {
|
||||||
|
boolean textCleared = false;
|
||||||
Object currentItem = commandLine.getEditor().getItem();
|
Object currentItem = commandLine.getEditor().getItem();
|
||||||
if (currentItem != null && !currentItem.toString().isEmpty()) {
|
if (currentItem != null && !currentItem.toString().isEmpty()) {
|
||||||
commandLine.getEditor().setItem("");
|
commandLine.getEditor().setItem("");
|
||||||
|
textCleared = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we just cleared text, or if focus is not in any table, return focus to active panel
|
||||||
|
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
||||||
|
boolean inTable = (focusOwner instanceof JTable);
|
||||||
|
|
||||||
|
if (textCleared || !inTable) {
|
||||||
if (activePanel != null && activePanel.getFileTable() != null) {
|
if (activePanel != null && activePanel.getFileTable() != null) {
|
||||||
activePanel.getFileTable().requestFocusInWindow();
|
activePanel.getFileTable().requestFocusInWindow();
|
||||||
}
|
}
|
||||||
@ -1178,6 +1188,7 @@ public class MainWindow extends JFrame {
|
|||||||
"No files selected",
|
"No files selected",
|
||||||
"Copy",
|
"Copy",
|
||||||
JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
requestFocusInActivePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1210,6 +1221,7 @@ public class MainWindow extends JFrame {
|
|||||||
"No files selected",
|
"No files selected",
|
||||||
"Move",
|
"Move",
|
||||||
JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
requestFocusInActivePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1242,6 +1254,7 @@ public class MainWindow extends JFrame {
|
|||||||
"No files selected",
|
"No files selected",
|
||||||
"Delete",
|
"Delete",
|
||||||
JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
requestFocusInActivePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// remember current selection index so we can restore selection after deletion
|
// remember current selection index so we can restore selection after deletion
|
||||||
@ -1296,6 +1309,7 @@ public class MainWindow extends JFrame {
|
|||||||
"No files selected",
|
"No files selected",
|
||||||
"Zip",
|
"Zip",
|
||||||
JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
requestFocusInActivePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1360,6 +1374,7 @@ public class MainWindow extends JFrame {
|
|||||||
"No files selected",
|
"No files selected",
|
||||||
"Unzip",
|
"Unzip",
|
||||||
JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
requestFocusInActivePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1369,6 +1384,7 @@ public class MainWindow extends JFrame {
|
|||||||
"Selected file is not a ZIP archive",
|
"Selected file is not a ZIP archive",
|
||||||
"Unzip",
|
"Unzip",
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
requestFocusInActivePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1407,6 +1423,7 @@ public class MainWindow extends JFrame {
|
|||||||
"Select one file to rename",
|
"Select one file to rename",
|
||||||
"Rename",
|
"Rename",
|
||||||
JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
requestFocusInActivePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FileItem item = selectedItems.get(0);
|
FileItem item = selectedItems.get(0);
|
||||||
@ -1455,6 +1472,12 @@ public class MainWindow extends JFrame {
|
|||||||
*/
|
*/
|
||||||
private void showSearchDialog() {
|
private void showSearchDialog() {
|
||||||
SearchDialog dialog = new SearchDialog(this, activePanel.getCurrentDirectory(), config);
|
SearchDialog dialog = new SearchDialog(this, activePanel.getCurrentDirectory(), config);
|
||||||
|
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosed(java.awt.event.WindowEvent e) {
|
||||||
|
requestFocusInActivePanel();
|
||||||
|
}
|
||||||
|
});
|
||||||
dialog.setVisible(true);
|
dialog.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1543,6 +1566,12 @@ public class MainWindow extends JFrame {
|
|||||||
// Removed previous 10 MB limit: allow opening large files in the viewer (paged hex will stream large binaries).
|
// Removed previous 10 MB limit: allow opening large files in the viewer (paged hex will stream large binaries).
|
||||||
|
|
||||||
FileEditor viewer = new FileEditor(this, file, config, true);
|
FileEditor viewer = new FileEditor(this, file, config, true);
|
||||||
|
viewer.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosed(java.awt.event.WindowEvent e) {
|
||||||
|
requestFocusInActivePanel();
|
||||||
|
}
|
||||||
|
});
|
||||||
viewer.setVisible(true);
|
viewer.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1581,6 +1610,12 @@ public class MainWindow extends JFrame {
|
|||||||
|
|
||||||
// Removed previous 10 MB limit: allow opening large files in the editor. The editor may still choose hex/paged mode for large binaries.
|
// Removed previous 10 MB limit: allow opening large files in the editor. The editor may still choose hex/paged mode for large binaries.
|
||||||
FileEditor editor = new FileEditor(this, file, config, false);
|
FileEditor editor = new FileEditor(this, file, config, false);
|
||||||
|
editor.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosed(java.awt.event.WindowEvent e) {
|
||||||
|
requestFocusInActivePanel();
|
||||||
|
}
|
||||||
|
});
|
||||||
editor.setVisible(true);
|
editor.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1846,6 +1881,7 @@ public class MainWindow extends JFrame {
|
|||||||
"Backspace - Parent directory",
|
"Backspace - Parent directory",
|
||||||
"About",
|
"About",
|
||||||
JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
requestFocusInActivePanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2028,4 +2064,10 @@ public class MainWindow extends JFrame {
|
|||||||
private interface FileOperation {
|
private interface FileOperation {
|
||||||
void execute(FileOperations.ProgressCallback callback) throws Exception;
|
void execute(FileOperations.ProgressCallback callback) throws Exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void requestFocusInActivePanel() {
|
||||||
|
if (activePanel != null && activePanel.getFileTable() != null) {
|
||||||
|
activePanel.getFileTable().requestFocusInWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -542,6 +542,12 @@ public class SearchDialog extends JDialog {
|
|||||||
try {
|
try {
|
||||||
Frame owner = (Frame) SwingUtilities.getWindowAncestor(this);
|
Frame owner = (Frame) SwingUtilities.getWindowAncestor(this);
|
||||||
FileEditor viewer = new FileEditor(owner, item.getFile(), config, true);
|
FileEditor viewer = new FileEditor(owner, item.getFile(), config, true);
|
||||||
|
viewer.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosed(java.awt.event.WindowEvent e) {
|
||||||
|
resultsTable.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
viewer.setVisible(true);
|
viewer.setVisible(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
JOptionPane.showMessageDialog(this, "Chyba při otevírání souboru: " + e.getMessage(), "Chyba", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(this, "Chyba při otevírání souboru: " + e.getMessage(), "Chyba", JOptionPane.ERROR_MESSAGE);
|
||||||
@ -561,6 +567,12 @@ public class SearchDialog extends JDialog {
|
|||||||
try {
|
try {
|
||||||
Frame owner = (Frame) SwingUtilities.getWindowAncestor(this);
|
Frame owner = (Frame) SwingUtilities.getWindowAncestor(this);
|
||||||
FileEditor editor = new FileEditor(owner, item.getFile(), config, false);
|
FileEditor editor = new FileEditor(owner, item.getFile(), config, false);
|
||||||
|
editor.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosed(java.awt.event.WindowEvent e) {
|
||||||
|
resultsTable.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
editor.setVisible(true);
|
editor.setVisible(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
JOptionPane.showMessageDialog(this, "Chyba při otevírání souboru: " + e.getMessage(), "Chyba", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(this, "Chyba při otevírání souboru: " + e.getMessage(), "Chyba", JOptionPane.ERROR_MESSAGE);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user