command history, translate to english
This commit is contained in:
parent
61fb75854e
commit
2c32493e73
@ -5,21 +5,21 @@ import com.kfmanager.ui.MainWindow;
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Hlavní třída aplikace KF File Manager
|
||||
* Main application class for KF File Manager
|
||||
*/
|
||||
public class MainApp {
|
||||
|
||||
public static final String APP_VERSION = "0.0.2";
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Nastavení look and feel podle systému
|
||||
// Set look and feel to system default
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Spuštění GUI v Event Dispatch Thread
|
||||
// Start GUI in Event Dispatch Thread
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
MainWindow mainWindow = new MainWindow();
|
||||
mainWindow.setVisible(true);
|
||||
|
||||
@ -28,7 +28,7 @@ public class AppConfig {
|
||||
try (FileInputStream fis = new FileInputStream(configFile)) {
|
||||
properties.load(fis);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Nepodařilo se načíst konfiguraci: " + e.getMessage());
|
||||
System.err.println("Could not load configuration: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -48,7 +48,7 @@ public class AppConfig {
|
||||
try (FileOutputStream fos = new FileOutputStream(configFile)) {
|
||||
properties.store(fos, "KF File Manager Configuration");
|
||||
} catch (IOException e) {
|
||||
System.err.println("Nepodařilo se uložit konfiguraci: " + e.getMessage());
|
||||
System.err.println("Could not save configuration: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ public class AppConfig {
|
||||
properties.setProperty("rightPanel.path", path);
|
||||
}
|
||||
|
||||
// ViewMode konfigurace
|
||||
// ViewMode configuration
|
||||
public String getLeftPanelViewMode() {
|
||||
return properties.getProperty("leftPanel.viewMode", "FULL");
|
||||
}
|
||||
@ -178,7 +178,7 @@ public class AppConfig {
|
||||
properties.setProperty("rightPanel.selectedIndex", String.valueOf(selectedIndex));
|
||||
}
|
||||
|
||||
// Font konfigurace
|
||||
// Font configuration
|
||||
public String getEditorFontName() {
|
||||
return properties.getProperty("editor.font.name", "Monospaced");
|
||||
}
|
||||
@ -533,4 +533,32 @@ public class AppConfig {
|
||||
properties.remove("search.content.history." + i);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Command line history persistence ---
|
||||
public java.util.List<String> getCommandLineHistory() {
|
||||
java.util.List<String> list = new java.util.ArrayList<>();
|
||||
int count = Integer.parseInt(properties.getProperty("cmd.history.count", "0"));
|
||||
for (int i = 0; i < count; i++) {
|
||||
String v = properties.getProperty("cmd.history." + i, null);
|
||||
if (v != null && !v.isEmpty()) list.add(v);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void saveCommandLineHistory(java.util.List<String> history) {
|
||||
if (history == null) {
|
||||
properties.setProperty("cmd.history.count", "0");
|
||||
return;
|
||||
}
|
||||
int limit = Math.min(history.size(), 50);
|
||||
properties.setProperty("cmd.history.count", String.valueOf(limit));
|
||||
for (int i = 0; i < limit; i++) {
|
||||
properties.setProperty("cmd.history." + i, history.get(i));
|
||||
}
|
||||
// remove old entries beyond limit
|
||||
int old = Integer.parseInt(properties.getProperty("cmd.history.count", "0"));
|
||||
for (int i = limit; i < old; i++) {
|
||||
properties.remove("cmd.history." + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ public class FileItem {
|
||||
this.isDirectory = file.isDirectory();
|
||||
this.marked = false;
|
||||
|
||||
// Načíst ikonu ze systému
|
||||
// Load icon from system
|
||||
this.icon = FileSystemView.getFileSystemView().getSystemIcon(file);
|
||||
}
|
||||
|
||||
|
||||
@ -367,7 +367,7 @@ public class FileOperations {
|
||||
// legacy matchesPattern removed — filename wildcard handling is done via a precompiled Pattern
|
||||
|
||||
/**
|
||||
* Callback pro progress operací
|
||||
* Callback for operation progress
|
||||
*/
|
||||
public interface ProgressCallback {
|
||||
void onProgress(long current, long total, String currentFile);
|
||||
@ -375,7 +375,7 @@ public class FileOperations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback pro vyhledávání
|
||||
* Callback for search
|
||||
*/
|
||||
public interface SearchCallback {
|
||||
void onFileFound(File file);
|
||||
|
||||
@ -144,11 +144,11 @@ public class FilePanel extends JPanel {
|
||||
|
||||
add(topPanel, BorderLayout.NORTH);
|
||||
|
||||
// JTabbedPane pro taby
|
||||
// JTabbedPane for tabs
|
||||
tabbedPane = new JTabbedPane();
|
||||
tabbedPane.setTabPlacement(JTabbedPane.TOP);
|
||||
|
||||
// Listener pro aktualizaci cesty a stylu při změně tabu
|
||||
// Listener for updating path and style on tab change
|
||||
tabbedPane.addChangeListener(e -> {
|
||||
updatePathField();
|
||||
updateTabStyles();
|
||||
@ -174,19 +174,19 @@ public class FilePanel extends JPanel {
|
||||
* Add a new tab with a directory
|
||||
*/
|
||||
public void addNewTab(String path) {
|
||||
// Získat view mode z aktuálního tabu
|
||||
// Get view mode from current tab
|
||||
ViewMode currentMode = getViewMode();
|
||||
|
||||
FilePanelTab tab = new FilePanelTab(path);
|
||||
if (appConfig != null) tab.setAppConfig(appConfig);
|
||||
|
||||
// Nastavit callback pro aktualizaci názvu tabu při změně adresáře
|
||||
// Set callback for updating tab title on directory change
|
||||
tab.setOnDirectoryChanged(() -> updateTabTitle(tab));
|
||||
|
||||
// Forward switchPanel callback to the tab so TAB works from any tab
|
||||
tab.setOnSwitchPanelRequested(switchPanelCallback);
|
||||
|
||||
// Nastavit stejný view mode jako má aktuální tab
|
||||
// Set same view mode as current tab
|
||||
if (currentMode != null) {
|
||||
tab.setViewMode(currentMode);
|
||||
}
|
||||
@ -196,11 +196,11 @@ public class FilePanel extends JPanel {
|
||||
tabbedPane.addTab(tabTitle, tab);
|
||||
tabbedPane.setSelectedComponent(tab);
|
||||
|
||||
// Aktualizovat path field
|
||||
// Update path field
|
||||
updatePathField();
|
||||
updateTabStyles();
|
||||
|
||||
// Nastavit focus na tabulku v novém tabu
|
||||
// Set focus to the table in the new tab
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
tab.getFileTable().requestFocusInWindow();
|
||||
// Ensure renderers are attached now that the tab is added to the UI
|
||||
@ -209,7 +209,7 @@ public class FilePanel extends JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Přidá nový tab a explicitně nastaví ViewMode pro tento tab.
|
||||
* Add a new tab and explicitly set the ViewMode for this tab.
|
||||
*/
|
||||
public void addNewTabWithMode(String path, ViewMode mode) {
|
||||
FilePanelTab tab = new FilePanelTab(path);
|
||||
@ -278,7 +278,7 @@ public class FilePanel extends JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Obnoví sadu tabů podle zadaných cest a view módů. Pokud je seznam prázdný, nic se nestane.
|
||||
* Restore the set of tabs according to specified paths and view modes. If the list is empty, nothing happens.
|
||||
*/
|
||||
public void restoreTabs(java.util.List<String> paths, java.util.List<String> viewModes, int selectedIndex) {
|
||||
if (paths == null || paths.isEmpty()) return;
|
||||
@ -338,7 +338,7 @@ public class FilePanel extends JPanel {
|
||||
private String getTabTitle(String path) {
|
||||
String tabTitle = new File(path).getName();
|
||||
if (tabTitle.isEmpty()) {
|
||||
tabTitle = path; // Pro root cesty jako "C:\"
|
||||
tabTitle = path; // For root paths like "C:\"
|
||||
}
|
||||
return tabTitle;
|
||||
}
|
||||
@ -351,7 +351,7 @@ public class FilePanel extends JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualizuje styl tabů - zvýrazní aktivní tab tučným písmem a barvou.
|
||||
* Updates tab style - highlights the active tab with bold font and color.
|
||||
*/
|
||||
private void updateTabStyles() {
|
||||
if (tabbedPane == null) return;
|
||||
@ -364,11 +364,11 @@ public class FilePanel extends JPanel {
|
||||
String title = getTabTitle(dir != null ? dir.getAbsolutePath() : "");
|
||||
|
||||
if (i == selectedIndex) {
|
||||
// Aktivní tab: tučné písmo a tmavě modrá barva
|
||||
// Active tab: bold font and dark blue color
|
||||
tabbedPane.setTitleAt(i, "<html><b>" + title + "</b></html>");
|
||||
tabbedPane.setForegroundAt(i, new Color(0, 51, 153));
|
||||
} else {
|
||||
// Neaktivní tab: normální písmo a výchozí barva
|
||||
// Inactive tab: normal font and default color
|
||||
tabbedPane.setTitleAt(i, title);
|
||||
tabbedPane.setForegroundAt(i, null);
|
||||
}
|
||||
@ -479,7 +479,7 @@ public class FilePanel extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
// Delegování metod na aktuální tab
|
||||
// Delegation of methods to current tab
|
||||
|
||||
/**
|
||||
* Switch to the next tab in this panel.
|
||||
|
||||
@ -355,16 +355,16 @@ public class FilePanelTab extends JPanel {
|
||||
// remain visible.
|
||||
fileTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
|
||||
|
||||
// Nastavit Cell Selection mode pouze v BRIEF režimu
|
||||
// Set Cell Selection mode only in BRIEF mode
|
||||
fileTable.setCellSelectionEnabled(false);
|
||||
fileTable.setRowSelectionAllowed(true);
|
||||
fileTable.setColumnSelectionAllowed(false);
|
||||
|
||||
// Odstranit bordery z tabulky
|
||||
// Remove table borders
|
||||
fileTable.setShowGrid(false);
|
||||
fileTable.setIntercellSpacing(new java.awt.Dimension(0, 0));
|
||||
|
||||
// Nastavit pozadí tabulky stejné jako pozadí panelu
|
||||
// Set table background same as panel background
|
||||
fileTable.setBackground(this.getBackground());
|
||||
fileTable.setOpaque(true);
|
||||
|
||||
@ -383,9 +383,9 @@ public class FilePanelTab extends JPanel {
|
||||
@Override
|
||||
public void componentResized(java.awt.event.ComponentEvent e) {
|
||||
if (viewMode == ViewMode.BRIEF) {
|
||||
// Při změně velikosti v BRIEF módu přepočítat layout
|
||||
// Recalculate layout on resize in BRIEF mode
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
// Zapamatovat si vybranou položku
|
||||
// Remember selected item
|
||||
String selectedItemName = null;
|
||||
int selectedRow = fileTable.getSelectedRow();
|
||||
if (selectedRow >= 0) {
|
||||
@ -395,13 +395,13 @@ public class FilePanelTab extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
// Přepočítat layout
|
||||
// Recalculate layout
|
||||
tableModel.calculateBriefLayout();
|
||||
tableModel.fireTableStructureChanged();
|
||||
updateColumnRenderers();
|
||||
updateColumnWidths();
|
||||
|
||||
// Znovu vybrat položku
|
||||
// Re-select item
|
||||
if (selectedItemName != null) {
|
||||
selectItemByName(selectedItemName);
|
||||
}
|
||||
@ -716,7 +716,7 @@ public class FilePanelTab extends JPanel {
|
||||
|
||||
updateStatus();
|
||||
|
||||
// Oznámit změnu adresáře
|
||||
// Notify directory change
|
||||
if (onDirectoryChanged != null) {
|
||||
onDirectoryChanged.run();
|
||||
}
|
||||
@ -1207,8 +1207,8 @@ public class FilePanelTab extends JPanel {
|
||||
private void updateColumnRenderers() {
|
||||
int columnCount = tableModel.getColumnCount();
|
||||
if (columnCount == 0 || fileTable.getColumnModel().getColumnCount() != columnCount) {
|
||||
// Sloupce tabulky se možná ještě nepřevedly po změně struktury.
|
||||
// Zkusíme to znovu asynchronně po krátkém odložení.
|
||||
// Table columns might not have been converted yet after structure change.
|
||||
// Try again asynchronously after a short delay.
|
||||
SwingUtilities.invokeLater(() -> updateColumnRenderers());
|
||||
return;
|
||||
}
|
||||
@ -1296,7 +1296,7 @@ public class FilePanelTab extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
// Zobrazit ikonu pro názvy souborů
|
||||
// Show icon for file names
|
||||
Icon icon = item.getIcon();
|
||||
if (item.getName().equals("..")) {
|
||||
icon = new UpArrowIcon(getForeground());
|
||||
@ -1305,10 +1305,10 @@ public class FilePanelTab extends JPanel {
|
||||
}
|
||||
|
||||
if (viewMode == ViewMode.BRIEF) {
|
||||
// V BRIEF módu jsou všechny sloupce názvy
|
||||
// In BRIEF mode all columns are names
|
||||
setIcon(icon);
|
||||
} else if (viewMode == ViewMode.FULL && column == 0) {
|
||||
// V FULL módu je ikona pouze v prvním sloupci (názvy)
|
||||
// In FULL mode the icon is only in the first column (names)
|
||||
setIcon(icon);
|
||||
} else {
|
||||
setIcon(null);
|
||||
@ -1340,9 +1340,9 @@ public class FilePanelTab extends JPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pokud se ColumnModel ještě nepřizpůsobil nové struktuře (např. po fireTableStructureChanged()),
|
||||
// počkej a zkus nastavit renderery později - jinak nové sloupce nedostanou renderer a ikony se
|
||||
// neprojeví v FULL módu.
|
||||
// If ColumnModel has not yet adapted to the new structure (e.g. after fireTableStructureChanged()),
|
||||
// wait and try to set renderers later - otherwise new columns won't get a renderer and icons won't
|
||||
// show up in FULL mode.
|
||||
if (fileTable.getColumnModel().getColumnCount() != columnCount) {
|
||||
SwingUtilities.invokeLater(() -> updateColumnRenderers());
|
||||
return;
|
||||
@ -1423,7 +1423,7 @@ public class FilePanelTab extends JPanel {
|
||||
}
|
||||
|
||||
if (markedCount > 0) {
|
||||
statusLabel.setText(String.format(" Označeno: %d souborů, %d adresářů (%s)",
|
||||
statusLabel.setText(String.format(" Selected: %d files, %d directories (%s)",
|
||||
fileCount, dirCount, formatSize(totalSize)));
|
||||
} else {
|
||||
int selectedRow = fileTable.getSelectedRow();
|
||||
@ -1448,10 +1448,10 @@ public class FilePanelTab extends JPanel {
|
||||
item.getFormattedDate()));
|
||||
}
|
||||
} else {
|
||||
statusLabel.setText(String.format(" Položek: %d", tableModel.items.size()));
|
||||
statusLabel.setText(String.format(" Items: %d", tableModel.items.size()));
|
||||
}
|
||||
} else {
|
||||
statusLabel.setText(String.format(" Položek: %d", tableModel.items.size()));
|
||||
statusLabel.setText(String.format(" Items: %d", tableModel.items.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1794,7 +1794,7 @@ public class FilePanelTab extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
// Gettery
|
||||
// Getters
|
||||
public JTable getFileTable() {
|
||||
return fileTable;
|
||||
}
|
||||
@ -1807,10 +1807,10 @@ public class FilePanelTab extends JPanel {
|
||||
return viewMode;
|
||||
}
|
||||
|
||||
// FileTableModel - stejný jako v původním FilePanel
|
||||
// FileTableModel
|
||||
private class FileTableModel extends AbstractTableModel {
|
||||
private List<FileItem> items = new ArrayList<>();
|
||||
private String[] columnNames = {"Název", "Velikost", "Datum"};
|
||||
private String[] columnNames = {"Name", "Size", "Date"};
|
||||
public int briefColumns = 1;
|
||||
public int briefRowsPerColumn = 10;
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ public class MainWindow extends JFrame {
|
||||
private FilePanel rightPanel;
|
||||
private FilePanel activePanel;
|
||||
private JPanel buttonPanel;
|
||||
private JTextField commandLine;
|
||||
private JComboBox<String> commandLine;
|
||||
private AppConfig config;
|
||||
|
||||
public MainWindow() {
|
||||
@ -75,7 +75,7 @@ public class MainWindow extends JFrame {
|
||||
ViewMode leftViewMode = ViewMode.valueOf(config.getLeftPanelViewMode());
|
||||
leftPanel.setViewMode(leftViewMode);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Výchozí hodnota FULL je již nastavena
|
||||
// Default value FULL is already set
|
||||
}
|
||||
|
||||
// Right panel - load path and ViewMode from configuration
|
||||
@ -91,7 +91,7 @@ public class MainWindow extends JFrame {
|
||||
ViewMode rightViewMode = ViewMode.valueOf(config.getRightPanelViewMode());
|
||||
rightPanel.setViewMode(rightViewMode);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Výchozí hodnota FULL je již nastavena
|
||||
// Default value FULL is already set
|
||||
}
|
||||
|
||||
mainPanel.add(leftPanel);
|
||||
@ -146,19 +146,19 @@ public class MainWindow extends JFrame {
|
||||
public void focusGained(FocusEvent e) {
|
||||
activePanel = leftPanel;
|
||||
updateActivePanelBorder();
|
||||
// Zajistit, že je vybrán nějaký řádek
|
||||
// Ensure some row is selected
|
||||
JTable leftTable = leftPanel.getFileTable();
|
||||
if (leftTable.getSelectedRow() == -1 && leftTable.getRowCount() > 0) {
|
||||
leftTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
// Překreslit oba panely
|
||||
// Repaint both panels
|
||||
leftPanel.getFileTable().repaint();
|
||||
rightPanel.getFileTable().repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
// Překreslit při ztrátě focusu
|
||||
// Repaint on focus loss
|
||||
leftPanel.getFileTable().repaint();
|
||||
}
|
||||
});
|
||||
@ -168,19 +168,19 @@ public class MainWindow extends JFrame {
|
||||
public void focusGained(FocusEvent e) {
|
||||
activePanel = rightPanel;
|
||||
updateActivePanelBorder();
|
||||
// Zajistit, že je vybrán nějaký řádek
|
||||
// Ensure some row is selected
|
||||
JTable rightTable = rightPanel.getFileTable();
|
||||
if (rightTable.getSelectedRow() == -1 && rightTable.getRowCount() > 0) {
|
||||
rightTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
// Překreslit oba panely
|
||||
// Repaint both panels
|
||||
leftPanel.getFileTable().repaint();
|
||||
rightPanel.getFileTable().repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
// Překreslit při ztrátě focusu
|
||||
// Repaint on focus loss
|
||||
rightPanel.getFileTable().repaint();
|
||||
}
|
||||
});
|
||||
@ -218,28 +218,42 @@ public class MainWindow extends JFrame {
|
||||
cmdLabel.setFont(new Font("Monospaced", Font.BOLD, 12));
|
||||
cmdPanel.add(cmdLabel, BorderLayout.WEST);
|
||||
|
||||
commandLine = new JTextField();
|
||||
commandLine = new JComboBox<>();
|
||||
commandLine.setEditable(true);
|
||||
commandLine.setFont(new Font("Monospaced", Font.PLAIN, 12));
|
||||
commandLine.setFocusTraversalKeysEnabled(false);
|
||||
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().requestFocusInWindow();
|
||||
e.consume();
|
||||
} else if (e.getKeyCode() == KeyEvent.VK_TAB) {
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
e.consume();
|
||||
// Handle the editor component (usually a JTextField)
|
||||
Component editorComp = commandLine.getEditor().getEditorComponent();
|
||||
if (editorComp instanceof JTextField) {
|
||||
JTextField tf = (JTextField) editorComp;
|
||||
tf.setFocusTraversalKeysEnabled(false);
|
||||
tf.addActionListener(e -> executeCommand(tf.getText()));
|
||||
|
||||
// Let the panels catch focus back if user presses ESC or TAB in command line
|
||||
tf.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
tf.setText("");
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
e.consume();
|
||||
} else if (e.getKeyCode() == KeyEvent.VK_TAB) {
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
cmdPanel.add(commandLine, BorderLayout.CENTER);
|
||||
|
||||
// Load history from config
|
||||
java.util.List<String> history = config.getCommandLineHistory();
|
||||
for (int i = 0; i < history.size(); i++) {
|
||||
commandLine.addItem(history.get(i));
|
||||
}
|
||||
commandLine.getEditor().setItem(""); // Ensure it starts empty
|
||||
|
||||
bottomContainer.add(cmdPanel, BorderLayout.NORTH);
|
||||
|
||||
// Bottom panel with buttons
|
||||
@ -285,7 +299,7 @@ public class MainWindow extends JFrame {
|
||||
|
||||
toolBar.addSeparator();
|
||||
|
||||
// Informační label
|
||||
// Info label
|
||||
JLabel infoLabel = new JLabel(" View Mode ");
|
||||
infoLabel.setFont(infoLabel.getFont().deriveFont(Font.PLAIN, 10f));
|
||||
toolBar.add(infoLabel);
|
||||
@ -493,7 +507,7 @@ public class MainWindow extends JFrame {
|
||||
private void setupKeyBindings() {
|
||||
JRootPane rootPane = getRootPane();
|
||||
|
||||
// F3 - Prohlížeč
|
||||
// F3 - Viewer
|
||||
rootPane.registerKeyboardAction(e -> viewFile(),
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0),
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
@ -560,7 +574,7 @@ public class MainWindow extends JFrame {
|
||||
rootPane.registerKeyboardAction(e -> {
|
||||
if (activePanel != null) {
|
||||
// Always clear command line and return focus to panels
|
||||
commandLine.setText("");
|
||||
commandLine.getEditor().setItem("");
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
|
||||
@ -616,6 +630,11 @@ public class MainWindow extends JFrame {
|
||||
rootPane.registerKeyboardAction(e -> closeCurrentTabInActivePanel(),
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK),
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
|
||||
// Ctrl+E - Command line history
|
||||
rootPane.registerKeyboardAction(e -> showCommandLineHistory(),
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK),
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -687,7 +706,7 @@ public class MainWindow extends JFrame {
|
||||
* Attach TAB handling to switch panels
|
||||
*/
|
||||
private void addTabKeyHandler(JTable table) {
|
||||
// Odstraníme standardní chování TAB ve Swing
|
||||
// Remove standard Swing TAB behavior
|
||||
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
||||
.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "switchPanel");
|
||||
table.getActionMap().put("switchPanel", new AbstractAction() {
|
||||
@ -709,7 +728,7 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
});
|
||||
|
||||
// Přidáme F8 pro mazání s vyšší prioritou než defaultní Swing akce
|
||||
// Add F8 for deleting with higher priority than default Swing actions
|
||||
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
|
||||
.put(KeyStroke.getKeyStroke(KeyEvent.VK_F8, 0), "deleteFiles");
|
||||
table.getActionMap().put("deleteFiles", new AbstractAction() {
|
||||
@ -757,7 +776,8 @@ public class MainWindow extends JFrame {
|
||||
// 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);
|
||||
String current = commandLine.getEditor().getItem().toString();
|
||||
commandLine.getEditor().setItem(current + c);
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
@ -767,7 +787,7 @@ public class MainWindow extends JFrame {
|
||||
private void copyFocusedToCommandLine(boolean fullPath) {
|
||||
FileItem focused = activePanel.getFocusedItem();
|
||||
if (focused != null && !focused.getName().equals("..")) {
|
||||
String current = commandLine.getText();
|
||||
String current = commandLine.getEditor().getItem().toString();
|
||||
String toAdd = fullPath ? focused.getFile().getAbsolutePath() : focused.getName();
|
||||
|
||||
// If it contains spaces, wrap in quotes
|
||||
@ -776,9 +796,9 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
|
||||
if (!current.isEmpty() && !current.endsWith(" ")) {
|
||||
commandLine.setText(current + " " + toAdd);
|
||||
commandLine.getEditor().setItem(current + " " + toAdd);
|
||||
} else {
|
||||
commandLine.setText(current + toAdd);
|
||||
commandLine.getEditor().setItem(current + toAdd);
|
||||
}
|
||||
commandLine.requestFocusInWindow();
|
||||
}
|
||||
@ -808,7 +828,7 @@ public class MainWindow extends JFrame {
|
||||
if (result == JOptionPane.OK_OPTION) {
|
||||
performFileOperation((callback) -> {
|
||||
FileOperations.copy(selectedItems, targetDir, callback);
|
||||
}, "Kopírování dokončeno", true, targetPanel);
|
||||
}, "Copy completed", true, targetPanel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -836,7 +856,7 @@ public class MainWindow extends JFrame {
|
||||
if (result == JOptionPane.OK_OPTION) {
|
||||
performFileOperation((callback) -> {
|
||||
FileOperations.move(selectedItems, targetDir, callback);
|
||||
}, "Přesouvání dokončeno", false, activePanel, targetPanel);
|
||||
}, "Move completed", false, activePanel, targetPanel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -867,14 +887,14 @@ public class MainWindow extends JFrame {
|
||||
|
||||
int result = JOptionPane.showConfirmDialog(this,
|
||||
message.toString(),
|
||||
"Mazání",
|
||||
"Delete",
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
|
||||
if (result == JOptionPane.YES_OPTION) {
|
||||
performFileOperation((callback) -> {
|
||||
FileOperations.delete(selectedItems, callback);
|
||||
}, "Mazání dokončeno", false, activePanel);
|
||||
}, "Delete completed", false, activePanel);
|
||||
|
||||
// After deletion and refresh, restore selection: stay on same row if possible,
|
||||
// otherwise move selection one row up.
|
||||
@ -949,7 +969,7 @@ public class MainWindow extends JFrame {
|
||||
final File finalTargetZip = targetZip;
|
||||
performFileOperation((callback) -> {
|
||||
FileOperations.zip(selectedItems, finalTargetZip, callback);
|
||||
}, "Zabaleno do " + zipName, false, targetPanel);
|
||||
}, "Zipped into " + zipName, false, targetPanel);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -985,7 +1005,7 @@ public class MainWindow extends JFrame {
|
||||
if (result == JOptionPane.OK_OPTION) {
|
||||
performFileOperation((callback) -> {
|
||||
FileOperations.unzip(zipFile, targetDir, callback);
|
||||
}, "Rozbaleno do " + targetDir.getName(), false, targetPanel);
|
||||
}, "Unzipped into " + targetDir.getName(), false, targetPanel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1014,7 +1034,7 @@ public class MainWindow extends JFrame {
|
||||
if (newName != null && !newName.trim().isEmpty() && !newName.equals(item.getName())) {
|
||||
performFileOperation((callback) -> {
|
||||
FileOperations.rename(item.getFile(), newName.trim());
|
||||
}, "Přejmenování dokončeno", false, activePanel);
|
||||
}, "Rename completed", false, activePanel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1139,8 +1159,8 @@ public class MainWindow extends JFrame {
|
||||
} catch (Exception ex) {
|
||||
// Fall back to internal editor if external fails
|
||||
JOptionPane.showMessageDialog(this,
|
||||
"Nelze spustit externí editor: " + ex.getMessage() + "\nPoužije se interní editor.",
|
||||
"Chyba", JOptionPane.ERROR_MESSAGE);
|
||||
"Could not start external editor: " + ex.getMessage() + "\nUsing internal editor.",
|
||||
"Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1153,8 +1173,8 @@ public class MainWindow extends JFrame {
|
||||
* Refresh both panels
|
||||
*/
|
||||
private void refreshPanels() {
|
||||
// Refresh je nyní automatický při změnách
|
||||
// Pokud je potřeba manuální refresh, můžeme zavolat loadDirectory
|
||||
// Refresh is now automatic upon changes
|
||||
// If manual refresh is needed, we can call loadDirectory
|
||||
if (leftPanel.getCurrentDirectory() != null) {
|
||||
leftPanel.loadDirectory(leftPanel.getCurrentDirectory());
|
||||
}
|
||||
@ -1172,6 +1192,16 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show history of command line
|
||||
*/
|
||||
private void showCommandLineHistory() {
|
||||
if (commandLine != null) {
|
||||
commandLine.requestFocusInWindow();
|
||||
commandLine.showPopup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new tab to the active panel
|
||||
*/
|
||||
@ -1247,8 +1277,8 @@ public class MainWindow extends JFrame {
|
||||
|
||||
} catch (Exception e) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
"Chyba při otevírání terminálu: " + e.getMessage(),
|
||||
"Chyba",
|
||||
"Error opening terminal: " + e.getMessage(),
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
@ -1259,6 +1289,9 @@ public class MainWindow extends JFrame {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add to history
|
||||
addCommandToHistory(command.trim());
|
||||
|
||||
File currentDir = activePanel.getCurrentDirectory();
|
||||
if (currentDir == null) {
|
||||
currentDir = new File(System.getProperty("user.home"));
|
||||
@ -1309,18 +1342,39 @@ public class MainWindow extends JFrame {
|
||||
if (pb != null) {
|
||||
pb.directory(currentDir);
|
||||
pb.start();
|
||||
commandLine.setText(""); // Clear after execution
|
||||
|
||||
// Clear after execution
|
||||
Component editorComp = commandLine.getEditor().getEditorComponent();
|
||||
if (editorComp instanceof JTextField) {
|
||||
((JTextField) editorComp).setText("");
|
||||
} else {
|
||||
commandLine.setSelectedItem("");
|
||||
}
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
"Chyba při spouštění příkazu: " + e.getMessage(),
|
||||
"Chyba",
|
||||
"Error executing command: " + e.getMessage(),
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private void addCommandToHistory(String command) {
|
||||
if (command == null || command.isEmpty()) return;
|
||||
|
||||
// Remove if already exists to move it to the top
|
||||
for (int i = 0; i < commandLine.getItemCount(); i++) {
|
||||
if (command.equals(commandLine.getItemAt(i))) {
|
||||
commandLine.removeItemAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
commandLine.insertItemAt(command, 0);
|
||||
// We don't necessarily want to select it here as it might interfere with the editor state
|
||||
}
|
||||
|
||||
/**
|
||||
* Show About dialog
|
||||
*/
|
||||
@ -1351,7 +1405,7 @@ public class MainWindow extends JFrame {
|
||||
* Execute file operation with error handling
|
||||
*/
|
||||
private void performFileOperation(FileOperation operation, String successMessage, boolean showBytes, FilePanel... panelsToRefresh) {
|
||||
ProgressDialog progressDialog = new ProgressDialog(this, "Operační systém");
|
||||
ProgressDialog progressDialog = new ProgressDialog(this, "File Operation");
|
||||
progressDialog.setDisplayAsBytes(showBytes);
|
||||
|
||||
FileOperations.ProgressCallback callback = new FileOperations.ProgressCallback() {
|
||||
@ -1379,15 +1433,15 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
}
|
||||
if (callback.isCancelled()) {
|
||||
JOptionPane.showMessageDialog(MainWindow.this, "Operace byla přerušena uživatelem.");
|
||||
JOptionPane.showMessageDialog(MainWindow.this, "Operation was cancelled by user.");
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
progressDialog.dispose();
|
||||
JOptionPane.showMessageDialog(MainWindow.this,
|
||||
"Chyba: " + e.getMessage(),
|
||||
"Chyba",
|
||||
"Error: " + e.getMessage(),
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
});
|
||||
}
|
||||
@ -1446,7 +1500,14 @@ public class MainWindow extends JFrame {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// Uložit konfiguraci do souboru
|
||||
// Save command history
|
||||
java.util.List<String> cmdHistory = new java.util.ArrayList<>();
|
||||
for (int i = 0; i < commandLine.getItemCount(); i++) {
|
||||
cmdHistory.add(commandLine.getItemAt(i));
|
||||
}
|
||||
config.saveCommandLineHistory(cmdHistory);
|
||||
|
||||
// Save configuration to file
|
||||
config.saveConfig();
|
||||
|
||||
// Exit application
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user