focus on esc fixed
This commit is contained in:
parent
3b1065bc81
commit
28e3e1bdad
@ -34,6 +34,12 @@ public class FilePanel extends JPanel {
|
||||
if (tab != null) tab.startInlineRename();
|
||||
}
|
||||
|
||||
/** Select files by wildcard pattern in the current tab. */
|
||||
public void selectByWildcard(String pattern) {
|
||||
FilePanelTab tab = getCurrentTab();
|
||||
if (tab != null) tab.selectByWildcard(pattern);
|
||||
}
|
||||
|
||||
private Runnable switchPanelCallback;
|
||||
|
||||
public void setSwitchPanelCallback(Runnable cb) {
|
||||
|
||||
@ -1564,6 +1564,91 @@ public class FilePanelTab extends JPanel {
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select all items that match the given wildcard pattern.
|
||||
* Supports * (any characters) and ? (single character).
|
||||
* Example patterns: *.txt, test*.*, file?.dat
|
||||
*/
|
||||
public void selectByWildcard(String pattern) {
|
||||
if (pattern == null || pattern.trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
pattern = pattern.trim();
|
||||
|
||||
// Convert wildcard pattern to regex
|
||||
String regex = wildcardToRegex(pattern);
|
||||
java.util.regex.Pattern compiledPattern;
|
||||
try {
|
||||
compiledPattern = java.util.regex.Pattern.compile(regex, java.util.regex.Pattern.CASE_INSENSITIVE);
|
||||
} catch (Exception e) {
|
||||
return; // Invalid pattern
|
||||
}
|
||||
|
||||
// Mark all matching items
|
||||
int matchCount = 0;
|
||||
for (FileItem item : tableModel.items) {
|
||||
if (item.getName().equals("..")) {
|
||||
continue; // Skip parent directory
|
||||
}
|
||||
|
||||
if (compiledPattern.matcher(item.getName()).matches()) {
|
||||
item.setMarked(true);
|
||||
matchCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh the table to show the marked items
|
||||
fileTable.repaint();
|
||||
updateStatus();
|
||||
|
||||
// Request focus back to the table
|
||||
fileTable.requestFocusInWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert wildcard pattern to regex.
|
||||
* * matches any characters
|
||||
* ? matches single character
|
||||
*/
|
||||
private String wildcardToRegex(String wildcard) {
|
||||
StringBuilder regex = new StringBuilder("^");
|
||||
for (int i = 0; i < wildcard.length(); i++) {
|
||||
char c = wildcard.charAt(i);
|
||||
switch (c) {
|
||||
case '*':
|
||||
regex.append(".*");
|
||||
break;
|
||||
case '?':
|
||||
regex.append(".");
|
||||
break;
|
||||
case '.':
|
||||
regex.append("\\.");
|
||||
break;
|
||||
case '\\':
|
||||
regex.append("\\\\");
|
||||
break;
|
||||
case '(':
|
||||
case ')':
|
||||
case '[':
|
||||
case ']':
|
||||
case '{':
|
||||
case '}':
|
||||
case '^':
|
||||
case '$':
|
||||
case '|':
|
||||
case '+':
|
||||
regex.append("\\").append(c);
|
||||
break;
|
||||
default:
|
||||
regex.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
regex.append("$");
|
||||
return regex.toString();
|
||||
}
|
||||
|
||||
public void copyToClipboard(boolean cut) {
|
||||
List<FileItem> selected = getSelectedItems();
|
||||
if (selected.isEmpty()) return;
|
||||
|
||||
@ -205,6 +205,9 @@ public class MainWindow extends JFrame {
|
||||
leftPanel.getFileTable().addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
activePanel = leftPanel;
|
||||
updateActivePanelBorder();
|
||||
updateCommandLinePrompt();
|
||||
// Ensure some row is selected
|
||||
JTable leftTable = leftPanel.getFileTable();
|
||||
if (leftTable.getSelectedRow() == -1 && leftTable.getRowCount() > 0) {
|
||||
@ -222,6 +225,9 @@ public class MainWindow extends JFrame {
|
||||
rightPanel.getFileTable().addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
activePanel = rightPanel;
|
||||
updateActivePanelBorder();
|
||||
updateCommandLinePrompt();
|
||||
// Ensure some row is selected
|
||||
JTable rightTable = rightPanel.getFileTable();
|
||||
if (rightTable.getSelectedRow() == -1 && rightTable.getRowCount() > 0) {
|
||||
@ -285,8 +291,12 @@ public class MainWindow extends JFrame {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
tf.setText("");
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
if (!tf.getText().isEmpty()) {
|
||||
tf.setText("");
|
||||
if (activePanel != null && activePanel.getFileTable() != null) {
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
e.consume();
|
||||
} else if (e.getKeyCode() == KeyEvent.VK_TAB) {
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
@ -613,6 +623,10 @@ public class MainWindow extends JFrame {
|
||||
JMenuItem searchItem = new JMenuItem("Search...");
|
||||
searchItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK));
|
||||
searchItem.addActionListener(e -> showSearchDialog());
|
||||
|
||||
JMenuItem selectWildcardItem = new JMenuItem("Select by wildcard...");
|
||||
selectWildcardItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
|
||||
selectWildcardItem.addActionListener(e -> showWildcardSelectDialog());
|
||||
|
||||
JMenuItem refreshItem = new JMenuItem("Refresh");
|
||||
refreshItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F5, InputEvent.CTRL_DOWN_MASK));
|
||||
@ -623,6 +637,7 @@ public class MainWindow extends JFrame {
|
||||
exitItem.addActionListener(e -> saveConfigAndExit());
|
||||
|
||||
fileMenu.add(searchItem);
|
||||
fileMenu.add(selectWildcardItem);
|
||||
fileMenu.add(refreshItem);
|
||||
fileMenu.addSeparator();
|
||||
fileMenu.add(exitItem);
|
||||
@ -824,10 +839,12 @@ public class MainWindow extends JFrame {
|
||||
|
||||
// ESC - global escape to return focus to panels
|
||||
rootPane.registerKeyboardAction(e -> {
|
||||
if (activePanel != null) {
|
||||
// Always clear command line and return focus to panels
|
||||
Object currentItem = commandLine.getEditor().getItem();
|
||||
if (currentItem != null && !currentItem.toString().isEmpty()) {
|
||||
commandLine.getEditor().setItem("");
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
if (activePanel != null && activePanel.getFileTable() != null) {
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
@ -919,6 +936,11 @@ public class MainWindow extends JFrame {
|
||||
rootPane.registerKeyboardAction(e -> showCommandLineHistory(),
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK),
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
|
||||
// Ctrl+A - Select files by wildcard
|
||||
rootPane.registerKeyboardAction(e -> showWildcardSelectDialog(),
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK),
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1001,6 +1023,8 @@ public class MainWindow extends JFrame {
|
||||
* Attach TAB handling to switch panels
|
||||
*/
|
||||
private void addTabKeyHandler(JTable table) {
|
||||
if (table == null) return;
|
||||
|
||||
// Remove standard Swing TAB behavior
|
||||
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
||||
.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "switchPanel");
|
||||
@ -1072,6 +1096,16 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Wildcard selection (Ctrl+A)
|
||||
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
||||
.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK), "wildcardSelect");
|
||||
table.getActionMap().put("wildcardSelect", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
showWildcardSelectDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1419,6 +1453,26 @@ public class MainWindow extends JFrame {
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show wildcard select dialog
|
||||
*/
|
||||
public void showWildcardSelectDialog() {
|
||||
if (activePanel == null) return;
|
||||
|
||||
WildcardSelectDialog dialog = new WildcardSelectDialog(this);
|
||||
dialog.setVisible(true);
|
||||
|
||||
String pattern = dialog.getPattern();
|
||||
if (pattern != null && !pattern.isEmpty()) {
|
||||
activePanel.selectByWildcard(pattern);
|
||||
} else {
|
||||
// If cancelled, return focus to the active panel
|
||||
if (activePanel.getFileTable() != null) {
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the given file's parent directory in the panel that currently has focus
|
||||
* and select the file in that panel.
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
package cz.kamma.kfmanager.ui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
/**
|
||||
* Dialog for entering a wildcard pattern to select matching files
|
||||
*/
|
||||
public class WildcardSelectDialog extends JDialog {
|
||||
|
||||
private JTextField patternField;
|
||||
private boolean confirmed = false;
|
||||
|
||||
public WildcardSelectDialog(Frame parent) {
|
||||
super(parent, "Vybrat podle masky", true);
|
||||
initComponents();
|
||||
pack();
|
||||
setLocationRelativeTo(parent);
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
setLayout(new BorderLayout(10, 10));
|
||||
|
||||
// Main panel with padding
|
||||
JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
|
||||
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
|
||||
// Label
|
||||
JLabel label = new JLabel("Zadejte masku (např. *.txt, test*.*, file?.dat):");
|
||||
mainPanel.add(label, BorderLayout.NORTH);
|
||||
|
||||
// Text field for pattern
|
||||
patternField = new JTextField("*", 30);
|
||||
patternField.selectAll();
|
||||
mainPanel.add(patternField, BorderLayout.CENTER);
|
||||
|
||||
add(mainPanel, BorderLayout.CENTER);
|
||||
|
||||
// Button panel
|
||||
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||
|
||||
JButton okButton = new JButton("OK");
|
||||
okButton.addActionListener(e -> {
|
||||
confirmed = true;
|
||||
dispose();
|
||||
});
|
||||
|
||||
JButton cancelButton = new JButton("Zrušit");
|
||||
cancelButton.addActionListener(e -> {
|
||||
confirmed = false;
|
||||
dispose();
|
||||
});
|
||||
|
||||
buttonPanel.add(okButton);
|
||||
buttonPanel.add(cancelButton);
|
||||
|
||||
add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
// Enter confirms
|
||||
patternField.addActionListener(e -> {
|
||||
confirmed = true;
|
||||
dispose();
|
||||
});
|
||||
|
||||
// ESC cancels
|
||||
getRootPane().registerKeyboardAction(e -> {
|
||||
confirmed = false;
|
||||
dispose();
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
}
|
||||
|
||||
public String getPattern() {
|
||||
return confirmed ? patternField.getText().trim() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
if (visible) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
patternField.requestFocusInWindow();
|
||||
patternField.selectAll();
|
||||
});
|
||||
}
|
||||
super.setVisible(visible);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user