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();
|
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;
|
private Runnable switchPanelCallback;
|
||||||
|
|
||||||
public void setSwitchPanelCallback(Runnable cb) {
|
public void setSwitchPanelCallback(Runnable cb) {
|
||||||
|
|||||||
@ -1564,6 +1564,91 @@ public class FilePanelTab extends JPanel {
|
|||||||
updateStatus();
|
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) {
|
public void copyToClipboard(boolean cut) {
|
||||||
List<FileItem> selected = getSelectedItems();
|
List<FileItem> selected = getSelectedItems();
|
||||||
if (selected.isEmpty()) return;
|
if (selected.isEmpty()) return;
|
||||||
|
|||||||
@ -205,6 +205,9 @@ public class MainWindow extends JFrame {
|
|||||||
leftPanel.getFileTable().addFocusListener(new FocusAdapter() {
|
leftPanel.getFileTable().addFocusListener(new FocusAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void focusGained(FocusEvent e) {
|
public void focusGained(FocusEvent e) {
|
||||||
|
activePanel = leftPanel;
|
||||||
|
updateActivePanelBorder();
|
||||||
|
updateCommandLinePrompt();
|
||||||
// Ensure some row is selected
|
// Ensure some row is selected
|
||||||
JTable leftTable = leftPanel.getFileTable();
|
JTable leftTable = leftPanel.getFileTable();
|
||||||
if (leftTable.getSelectedRow() == -1 && leftTable.getRowCount() > 0) {
|
if (leftTable.getSelectedRow() == -1 && leftTable.getRowCount() > 0) {
|
||||||
@ -222,6 +225,9 @@ public class MainWindow extends JFrame {
|
|||||||
rightPanel.getFileTable().addFocusListener(new FocusAdapter() {
|
rightPanel.getFileTable().addFocusListener(new FocusAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void focusGained(FocusEvent e) {
|
public void focusGained(FocusEvent e) {
|
||||||
|
activePanel = rightPanel;
|
||||||
|
updateActivePanelBorder();
|
||||||
|
updateCommandLinePrompt();
|
||||||
// Ensure some row is selected
|
// Ensure some row is selected
|
||||||
JTable rightTable = rightPanel.getFileTable();
|
JTable rightTable = rightPanel.getFileTable();
|
||||||
if (rightTable.getSelectedRow() == -1 && rightTable.getRowCount() > 0) {
|
if (rightTable.getSelectedRow() == -1 && rightTable.getRowCount() > 0) {
|
||||||
@ -285,8 +291,12 @@ public class MainWindow extends JFrame {
|
|||||||
@Override
|
@Override
|
||||||
public void keyPressed(KeyEvent e) {
|
public void keyPressed(KeyEvent e) {
|
||||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||||
|
if (!tf.getText().isEmpty()) {
|
||||||
tf.setText("");
|
tf.setText("");
|
||||||
|
if (activePanel != null && activePanel.getFileTable() != null) {
|
||||||
activePanel.getFileTable().requestFocusInWindow();
|
activePanel.getFileTable().requestFocusInWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
e.consume();
|
e.consume();
|
||||||
} else if (e.getKeyCode() == KeyEvent.VK_TAB) {
|
} else if (e.getKeyCode() == KeyEvent.VK_TAB) {
|
||||||
activePanel.getFileTable().requestFocusInWindow();
|
activePanel.getFileTable().requestFocusInWindow();
|
||||||
@ -614,6 +624,10 @@ public class MainWindow extends JFrame {
|
|||||||
searchItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK));
|
searchItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK));
|
||||||
searchItem.addActionListener(e -> showSearchDialog());
|
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");
|
JMenuItem refreshItem = new JMenuItem("Refresh");
|
||||||
refreshItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F5, InputEvent.CTRL_DOWN_MASK));
|
refreshItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F5, InputEvent.CTRL_DOWN_MASK));
|
||||||
refreshItem.addActionListener(e -> refreshPanels());
|
refreshItem.addActionListener(e -> refreshPanels());
|
||||||
@ -623,6 +637,7 @@ public class MainWindow extends JFrame {
|
|||||||
exitItem.addActionListener(e -> saveConfigAndExit());
|
exitItem.addActionListener(e -> saveConfigAndExit());
|
||||||
|
|
||||||
fileMenu.add(searchItem);
|
fileMenu.add(searchItem);
|
||||||
|
fileMenu.add(selectWildcardItem);
|
||||||
fileMenu.add(refreshItem);
|
fileMenu.add(refreshItem);
|
||||||
fileMenu.addSeparator();
|
fileMenu.addSeparator();
|
||||||
fileMenu.add(exitItem);
|
fileMenu.add(exitItem);
|
||||||
@ -824,11 +839,13 @@ 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 -> {
|
||||||
if (activePanel != null) {
|
Object currentItem = commandLine.getEditor().getItem();
|
||||||
// Always clear command line and return focus to panels
|
if (currentItem != null && !currentItem.toString().isEmpty()) {
|
||||||
commandLine.getEditor().setItem("");
|
commandLine.getEditor().setItem("");
|
||||||
|
if (activePanel != null && activePanel.getFileTable() != null) {
|
||||||
activePanel.getFileTable().requestFocusInWindow();
|
activePanel.getFileTable().requestFocusInWindow();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
|
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
|
||||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||||
|
|
||||||
@ -919,6 +936,11 @@ public class MainWindow extends JFrame {
|
|||||||
rootPane.registerKeyboardAction(e -> showCommandLineHistory(),
|
rootPane.registerKeyboardAction(e -> showCommandLineHistory(),
|
||||||
KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK),
|
KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK),
|
||||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
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
|
* Attach TAB handling to switch panels
|
||||||
*/
|
*/
|
||||||
private void addTabKeyHandler(JTable table) {
|
private void addTabKeyHandler(JTable table) {
|
||||||
|
if (table == null) return;
|
||||||
|
|
||||||
// Remove standard Swing TAB behavior
|
// Remove standard Swing TAB behavior
|
||||||
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
||||||
.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "switchPanel");
|
.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);
|
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
|
* Show the given file's parent directory in the panel that currently has focus
|
||||||
* and select the file in that panel.
|
* 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