added command line
This commit is contained in:
parent
25ce987859
commit
b4226db038
@ -454,6 +454,21 @@ public class FilePanel extends JPanel {
|
||||
}
|
||||
|
||||
// Delegování metod na aktuální tab
|
||||
|
||||
/**
|
||||
* Switch to the next tab in this panel.
|
||||
*/
|
||||
public void nextTab() {
|
||||
int count = tabbedPane.getTabCount();
|
||||
if (count > 1) {
|
||||
int nextIndex = (tabbedPane.getSelectedIndex() + 1) % count;
|
||||
tabbedPane.setSelectedIndex(nextIndex);
|
||||
FilePanelTab tab = getCurrentTab();
|
||||
if (tab != null) {
|
||||
tab.getFileTable().requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JTable getFileTable() {
|
||||
FilePanelTab tab = getCurrentTab();
|
||||
@ -469,6 +484,11 @@ public class FilePanel extends JPanel {
|
||||
FilePanelTab tab = getCurrentTab();
|
||||
return tab != null ? tab.getSelectedItems() : java.util.Collections.emptyList();
|
||||
}
|
||||
|
||||
public FileItem getFocusedItem() {
|
||||
FilePanelTab tab = getCurrentTab();
|
||||
return tab != null ? tab.getFocusedItem() : null;
|
||||
}
|
||||
|
||||
public void setViewMode(ViewMode mode) {
|
||||
FilePanelTab tab = getCurrentTab();
|
||||
|
||||
@ -301,6 +301,7 @@ public class FilePanelTab extends JPanel {
|
||||
// to ensure no drag gestures or DnD occur.
|
||||
fileTable.setDragEnabled(false);
|
||||
fileTable.setTransferHandler(null);
|
||||
fileTable.setFocusTraversalKeysEnabled(false);
|
||||
try {
|
||||
fileTable.setDropMode(null);
|
||||
} catch (Exception ignore) {
|
||||
@ -433,7 +434,7 @@ public class FilePanelTab extends JPanel {
|
||||
fileTable.addKeyListener(new java.awt.event.KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(java.awt.event.KeyEvent e) {
|
||||
if (e.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER) {
|
||||
if (e.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER && !e.isControlDown()) {
|
||||
openSelectedItem();
|
||||
e.consume();
|
||||
} else if (e.getKeyCode() == java.awt.event.KeyEvent.VK_BACK_SPACE) {
|
||||
@ -1142,6 +1143,18 @@ public class FilePanelTab extends JPanel {
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
public FileItem getFocusedItem() {
|
||||
int selectedRow = fileTable.getSelectedRow();
|
||||
if (selectedRow >= 0) {
|
||||
if (viewMode == ViewMode.BRIEF) {
|
||||
return tableModel.getItemFromBriefLayout(selectedRow, briefCurrentColumn);
|
||||
} else {
|
||||
return tableModel.getItem(selectedRow);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setViewMode(ViewMode mode) {
|
||||
if (this.viewMode != mode) {
|
||||
|
||||
@ -19,10 +19,11 @@ public class MainWindow extends JFrame {
|
||||
private FilePanel rightPanel;
|
||||
private FilePanel activePanel;
|
||||
private JPanel buttonPanel;
|
||||
private JTextField commandLine;
|
||||
private AppConfig config;
|
||||
|
||||
public MainWindow() {
|
||||
super("KF File Manager");
|
||||
super("KF Manager");
|
||||
|
||||
// Load configuration
|
||||
config = new AppConfig();
|
||||
@ -182,14 +183,68 @@ public class MainWindow extends JFrame {
|
||||
rightPanel.getFileTable().repaint();
|
||||
}
|
||||
});
|
||||
|
||||
// Click on panel anywhere should request focus to its table
|
||||
leftPanel.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
leftPanel.getFileTable().requestFocusInWindow();
|
||||
}
|
||||
});
|
||||
rightPanel.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
rightPanel.getFileTable().requestFocusInWindow();
|
||||
}
|
||||
});
|
||||
|
||||
// Add TAB handler to switch between panels
|
||||
addTabKeyHandler(leftPanel.getFileTable());
|
||||
addTabKeyHandler(rightPanel.getFileTable());
|
||||
|
||||
// Bottom panel with buttons
|
||||
// Add command line focus redirection
|
||||
addCommandLineRedirect(leftPanel.getFileTable());
|
||||
addCommandLineRedirect(rightPanel.getFileTable());
|
||||
|
||||
// Container for everything below the file panels
|
||||
JPanel bottomContainer = new JPanel(new BorderLayout());
|
||||
|
||||
// Command line panel
|
||||
JPanel cmdPanel = new JPanel(new BorderLayout(5, 0));
|
||||
cmdPanel.setBorder(BorderFactory.createEmptyBorder(2, 5, 0, 5));
|
||||
|
||||
JLabel cmdLabel = new JLabel(System.getProperty("user.name") + ">");
|
||||
cmdLabel.setFont(new Font("Monospaced", Font.BOLD, 12));
|
||||
cmdPanel.add(cmdLabel, BorderLayout.WEST);
|
||||
|
||||
commandLine = new JTextField();
|
||||
commandLine.setFont(new Font("Monospaced", Font.PLAIN, 12));
|
||||
commandLine.addActionListener(e -> executeCommand(commandLine.getText()));
|
||||
|
||||
// Let the panels catch focus back if user presses ESC or TAB in command line
|
||||
commandLine.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
commandLine.setText("");
|
||||
activePanel.getFileTable().requestFocus();
|
||||
e.consume();
|
||||
} else if (e.getKeyCode() == KeyEvent.VK_TAB) {
|
||||
activePanel.getFileTable().requestFocus();
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cmdPanel.add(commandLine, BorderLayout.CENTER);
|
||||
|
||||
bottomContainer.add(cmdPanel, BorderLayout.NORTH);
|
||||
|
||||
// Bottom panel with buttons
|
||||
createButtonPanel();
|
||||
add(buttonPanel, BorderLayout.SOUTH);
|
||||
bottomContainer.add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
add(bottomContainer, BorderLayout.SOUTH);
|
||||
|
||||
// Menu
|
||||
createMenuBar();
|
||||
@ -491,6 +546,14 @@ public class MainWindow extends JFrame {
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_F9, 0),
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
|
||||
// Ctrl+TAB - switch tabs in active panel
|
||||
rootPane.registerKeyboardAction(e -> {
|
||||
if (activePanel != null) {
|
||||
activePanel.nextTab();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_DOWN_MASK),
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
|
||||
// Delete key - global delete binding (also added per-table)
|
||||
rootPane.registerKeyboardAction(e -> deleteFiles(),
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0),
|
||||
@ -621,6 +684,18 @@ public class MainWindow extends JFrame {
|
||||
switchPanels();
|
||||
}
|
||||
});
|
||||
|
||||
// Add Ctrl+Tab handling at the table level
|
||||
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
||||
.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_DOWN_MASK), "nextTab");
|
||||
table.getActionMap().put("nextTab", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (activePanel != null) {
|
||||
activePanel.nextTab();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Přidáme F8 pro mazání s vyšší prioritou než defaultní Swing akce
|
||||
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
||||
@ -638,6 +713,63 @@ public class MainWindow extends JFrame {
|
||||
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
||||
.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, InputEvent.SHIFT_DOWN_MASK), "deleteFiles");
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically focus command line when user starts typing on a table
|
||||
*/
|
||||
private void addCommandLineRedirect(JTable table) {
|
||||
// Use InputMap/ActionMap for Ctrl+Enter and Ctrl+Shift+Enter as KeyListener might be bypassed by JTable
|
||||
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
||||
.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.CTRL_DOWN_MASK), "copyNameToCmd");
|
||||
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
||||
.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK), "copyPathToCmd");
|
||||
|
||||
table.getActionMap().put("copyNameToCmd", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
copyFocusedToCommandLine(false);
|
||||
}
|
||||
});
|
||||
|
||||
table.getActionMap().put("copyPathToCmd", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
copyFocusedToCommandLine(true);
|
||||
}
|
||||
});
|
||||
|
||||
table.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
char c = e.getKeyChar();
|
||||
// Printable characters only (exclude control keys like Enter, Backspace, Esc, Tab)
|
||||
if (c != KeyEvent.CHAR_UNDEFINED && c != '\b' && c != '\n' && c != '\t' && c != 27) {
|
||||
commandLine.requestFocusInWindow();
|
||||
commandLine.setText(commandLine.getText() + c);
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void copyFocusedToCommandLine(boolean fullPath) {
|
||||
FileItem focused = activePanel.getFocusedItem();
|
||||
if (focused != null && !focused.getName().equals("..")) {
|
||||
String current = commandLine.getText();
|
||||
String toAdd = fullPath ? focused.getFile().getAbsolutePath() : focused.getName();
|
||||
|
||||
// If it contains spaces, wrap in quotes
|
||||
if (toAdd.contains(" ")) {
|
||||
toAdd = "\"" + toAdd + "\"";
|
||||
}
|
||||
|
||||
if (!current.isEmpty() && !current.endsWith(" ")) {
|
||||
commandLine.setText(current + " " + toAdd);
|
||||
} else {
|
||||
commandLine.setText(current + toAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy selected files to the opposite panel
|
||||
@ -1108,6 +1240,72 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
private void executeCommand(String command) {
|
||||
if (command == null || command.trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
File currentDir = activePanel.getCurrentDirectory();
|
||||
if (currentDir == null) {
|
||||
currentDir = new File(System.getProperty("user.home"));
|
||||
}
|
||||
|
||||
try {
|
||||
String osName = System.getProperty("os.name").toLowerCase();
|
||||
ProcessBuilder pb;
|
||||
|
||||
if (osName.contains("win")) {
|
||||
// Windows: cmd /c command && pause
|
||||
pb = new ProcessBuilder("cmd.exe", "/c", "start", "cmd.exe", "/k", command);
|
||||
} else if (osName.contains("mac")) {
|
||||
// macOS: Open terminal and execute
|
||||
String appleScript = String.format(
|
||||
"tell application \"Terminal\" to do script \"cd '%s' && %s\"",
|
||||
currentDir.getAbsolutePath(), command.replace("\"", "\\\"")
|
||||
);
|
||||
pb = new ProcessBuilder("osascript", "-e", appleScript);
|
||||
} else {
|
||||
// Linux: Try common terminals with -e or --command
|
||||
String[] terminals = {"gnome-terminal", "konsole", "xfce4-terminal", "mate-terminal", "xterm"};
|
||||
pb = null;
|
||||
|
||||
for (String terminal : terminals) {
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(new String[]{"which", terminal});
|
||||
if (p.waitFor() == 0) {
|
||||
if (terminal.equals("gnome-terminal") || terminal.equals("xfce4-terminal") || terminal.equals("mate-terminal")) {
|
||||
pb = new ProcessBuilder(terminal, "--working-directory=" + currentDir.getAbsolutePath(), "--", "bash", "-c", command + "; echo; echo 'Press Enter to close...'; read");
|
||||
} else if (terminal.equals("konsole")) {
|
||||
pb = new ProcessBuilder(terminal, "--workdir", currentDir.getAbsolutePath(), "-e", "bash", "-c", command + "; echo; echo 'Press Enter to close...'; read");
|
||||
} else {
|
||||
pb = new ProcessBuilder(terminal, "-e", "bash -c \"" + command + "; echo; echo 'Press Enter to close...'; read\"");
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// try next
|
||||
}
|
||||
}
|
||||
|
||||
if (pb == null) {
|
||||
pb = new ProcessBuilder("xterm", "-e", "bash -c \"" + command + "; echo; echo 'Press Enter to close...'; read\"");
|
||||
}
|
||||
}
|
||||
|
||||
if (pb != null) {
|
||||
pb.directory(currentDir);
|
||||
pb.start();
|
||||
commandLine.setText(""); // Clear after execution
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
"Chyba při spouštění příkazu: " + e.getMessage(),
|
||||
"Chyba",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show About dialog
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user