added undo/redu, clipboard
This commit is contained in:
parent
aac1531fae
commit
6f626b7607
@ -38,6 +38,7 @@ public class FileEditor extends JDialog {
|
||||
private JButton prevPageBtn = null;
|
||||
private JButton nextPageBtn = null;
|
||||
private JLabel pageOffsetLabel = null;
|
||||
private javax.swing.undo.UndoManager undoManager;
|
||||
|
||||
public FileEditor(Window parent, File file, AppConfig config, boolean readOnly) {
|
||||
super(parent, (readOnly ? "Prohlížeč - " : "Editor - ") + file.getName(), ModalityType.MODELESS);
|
||||
@ -72,11 +73,11 @@ public class FileEditor extends JDialog {
|
||||
textArea.setTabSize(4);
|
||||
textArea.setEditable(!readOnly);
|
||||
|
||||
// V read-only režimu zajistit viditelnost kurzoru a možnost označování
|
||||
if (readOnly) {
|
||||
textArea.getCaret().setVisible(true);
|
||||
textArea.setCaretColor(Color.BLACK);
|
||||
}
|
||||
// Undo/Redo support
|
||||
undoManager = new javax.swing.undo.UndoManager();
|
||||
textArea.getDocument().addUndoableEditListener(e -> {
|
||||
undoManager.addEdit(e.getEdit());
|
||||
});
|
||||
|
||||
// Sledování změn (pouze pro editovatelný režim)
|
||||
if (!readOnly) {
|
||||
@ -99,6 +100,12 @@ public class FileEditor extends JDialog {
|
||||
statusPanel.add(statusSelLabel, BorderLayout.EAST);
|
||||
add(statusPanel, BorderLayout.SOUTH);
|
||||
|
||||
// Apply appearance settings (colors, contrast caret etc)
|
||||
applyAppearance();
|
||||
|
||||
// Kontextové menu pro clipboard
|
||||
setupContextMenu();
|
||||
|
||||
// Klávesové zkratky
|
||||
setupKeyBindings();
|
||||
|
||||
@ -112,6 +119,109 @@ public class FileEditor extends JDialog {
|
||||
});
|
||||
}
|
||||
|
||||
private void setupContextMenu() {
|
||||
JPopupMenu popup = new JPopupMenu();
|
||||
|
||||
JMenuItem undoItem = new JMenuItem("Zpět");
|
||||
undoItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK));
|
||||
undoItem.addActionListener(e -> { if (undoManager.canUndo()) undoManager.undo(); });
|
||||
|
||||
JMenuItem redoItem = new JMenuItem("Znovu");
|
||||
redoItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK));
|
||||
redoItem.addActionListener(e -> { if (undoManager.canRedo()) undoManager.redo(); });
|
||||
|
||||
popup.add(undoItem);
|
||||
popup.add(redoItem);
|
||||
popup.addSeparator();
|
||||
|
||||
JMenuItem cutItem = new JMenuItem(new javax.swing.text.DefaultEditorKit.CutAction());
|
||||
cutItem.setText("Vyjmout");
|
||||
cutItem.setMnemonic(KeyEvent.VK_X);
|
||||
|
||||
JMenuItem copyItem = new JMenuItem(new javax.swing.text.DefaultEditorKit.CopyAction());
|
||||
copyItem.setText("Kopírovat");
|
||||
copyItem.setMnemonic(KeyEvent.VK_C);
|
||||
|
||||
JMenuItem pasteItem = new JMenuItem(new javax.swing.text.DefaultEditorKit.PasteAction());
|
||||
pasteItem.setText("Vložit");
|
||||
pasteItem.setMnemonic(KeyEvent.VK_V);
|
||||
|
||||
popup.add(cutItem);
|
||||
popup.add(copyItem);
|
||||
popup.add(pasteItem);
|
||||
popup.addSeparator();
|
||||
|
||||
JMenuItem selectAllItem = new JMenuItem("Vybrat vše");
|
||||
selectAllItem.setMnemonic(KeyEvent.VK_A);
|
||||
selectAllItem.addActionListener(e -> textArea.selectAll());
|
||||
popup.add(selectAllItem);
|
||||
|
||||
popup.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent e) {
|
||||
boolean editable = textArea.isEditable();
|
||||
undoItem.setEnabled(editable && undoManager.canUndo());
|
||||
redoItem.setEnabled(editable && undoManager.canRedo());
|
||||
cutItem.setEnabled(editable);
|
||||
pasteItem.setEnabled(editable);
|
||||
}
|
||||
@Override public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent e) {}
|
||||
@Override public void popupMenuCanceled(javax.swing.event.PopupMenuEvent e) {}
|
||||
});
|
||||
|
||||
textArea.setComponentPopupMenu(popup);
|
||||
}
|
||||
|
||||
private void applyAppearance() {
|
||||
Color bg = config.getBackgroundColor();
|
||||
if (bg != null) {
|
||||
boolean dark = isDark(bg);
|
||||
// Apply to JTextArea
|
||||
textArea.setBackground(bg);
|
||||
textArea.setForeground(dark ? Color.WHITE : Color.BLACK);
|
||||
textArea.setCaretColor(dark ? Color.WHITE : Color.BLACK);
|
||||
|
||||
// Apply to the rest of the components recursively
|
||||
applyRecursiveColors(getContentPane(), bg, dark);
|
||||
} else {
|
||||
// Default colors - make sure caret is at least visible
|
||||
Color defaultBg = textArea.getBackground();
|
||||
if (defaultBg != null) {
|
||||
boolean dark = isDark(defaultBg);
|
||||
textArea.setCaretColor(dark ? Color.WHITE : Color.BLACK);
|
||||
} else {
|
||||
textArea.setCaretColor(Color.BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
// Force caret visibility in read-only mode
|
||||
if (readOnly) {
|
||||
textArea.getCaret().setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyRecursiveColors(Container container, Color bg, boolean dark) {
|
||||
if (container == null) return;
|
||||
container.setBackground(bg);
|
||||
for (Component c : container.getComponents()) {
|
||||
if (c instanceof JPanel || c instanceof JScrollPane || c instanceof JViewport) {
|
||||
c.setBackground(bg);
|
||||
}
|
||||
if (c instanceof JLabel) {
|
||||
c.setForeground(dark ? Color.WHITE : Color.BLACK);
|
||||
}
|
||||
if (c instanceof Container) {
|
||||
applyRecursiveColors((Container) c, bg, dark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDark(Color c) {
|
||||
if (c == null) return false;
|
||||
double darkness = 1 - (0.299 * c.getRed() + 0.587 * c.getGreen() + 0.114 * c.getBlue()) / 255;
|
||||
return darkness >= 0.5;
|
||||
}
|
||||
|
||||
private void createMenuBar() {
|
||||
JMenuBar menuBar = new JMenuBar();
|
||||
|
||||
@ -136,6 +246,60 @@ public class FileEditor extends JDialog {
|
||||
|
||||
menuBar.add(fileMenu);
|
||||
|
||||
// Menu Edit
|
||||
JMenu editMenu = new JMenu("Edit");
|
||||
editMenu.setMnemonic(java.awt.event.KeyEvent.VK_E);
|
||||
|
||||
JMenuItem undoItem = new JMenuItem("Zpět");
|
||||
undoItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK));
|
||||
undoItem.addActionListener(e -> { if (undoManager.canUndo()) undoManager.undo(); });
|
||||
editMenu.add(undoItem);
|
||||
|
||||
JMenuItem redoItem = new JMenuItem("Znovu");
|
||||
redoItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK));
|
||||
redoItem.addActionListener(e -> { if (undoManager.canRedo()) undoManager.redo(); });
|
||||
editMenu.add(redoItem);
|
||||
|
||||
editMenu.addSeparator();
|
||||
|
||||
JMenuItem cutItem = new JMenuItem(new javax.swing.text.DefaultEditorKit.CutAction());
|
||||
cutItem.setText("Vyjmout");
|
||||
cutItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_DOWN_MASK));
|
||||
editMenu.add(cutItem);
|
||||
|
||||
JMenuItem copyItem = new JMenuItem(new javax.swing.text.DefaultEditorKit.CopyAction());
|
||||
copyItem.setText("Kopírovat");
|
||||
copyItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK));
|
||||
editMenu.add(copyItem);
|
||||
|
||||
JMenuItem pasteItem = new JMenuItem(new javax.swing.text.DefaultEditorKit.PasteAction());
|
||||
pasteItem.setText("Vložit");
|
||||
pasteItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK));
|
||||
editMenu.add(pasteItem);
|
||||
|
||||
editMenu.addSeparator();
|
||||
|
||||
JMenuItem selectAllItem = new JMenuItem("Vybrat vše");
|
||||
selectAllItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
|
||||
selectAllItem.addActionListener(e -> textArea.selectAll());
|
||||
editMenu.add(selectAllItem);
|
||||
|
||||
// Update menu items state when menu is selected
|
||||
editMenu.addMenuListener(new javax.swing.event.MenuListener() {
|
||||
@Override
|
||||
public void menuSelected(javax.swing.event.MenuEvent e) {
|
||||
boolean editable = textArea.isEditable();
|
||||
undoItem.setEnabled(editable && undoManager.canUndo());
|
||||
redoItem.setEnabled(editable && undoManager.canRedo());
|
||||
cutItem.setEnabled(editable);
|
||||
pasteItem.setEnabled(editable);
|
||||
}
|
||||
@Override public void menuDeselected(javax.swing.event.MenuEvent e) {}
|
||||
@Override public void menuCanceled(javax.swing.event.MenuEvent e) {}
|
||||
});
|
||||
|
||||
menuBar.add(editMenu);
|
||||
|
||||
// Menu Nastavení
|
||||
JMenu settingsMenu = new JMenu("Nastavení");
|
||||
settingsMenu.setMnemonic(java.awt.event.KeyEvent.VK_N);
|
||||
@ -215,6 +379,21 @@ public class FileEditor extends JDialog {
|
||||
},
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0),
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
|
||||
// Ctrl+Z - Undo
|
||||
rootPane.registerKeyboardAction(e -> {
|
||||
if (undoManager.canUndo()) undoManager.undo();
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
|
||||
// Ctrl+Y - Redo
|
||||
rootPane.registerKeyboardAction(e -> {
|
||||
if (undoManager.canRedo()) undoManager.redo();
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
|
||||
// Ctrl+Shift+Z - Redo (alternative shortcut)
|
||||
rootPane.registerKeyboardAction(e -> {
|
||||
if (undoManager.canRedo()) undoManager.redo();
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
}
|
||||
|
||||
private void setHexMode(boolean on) {
|
||||
@ -256,6 +435,7 @@ public class FileEditor extends JDialog {
|
||||
textArea.setEditable(!readOnly);
|
||||
textArea.setFont(config.getEditorFont());
|
||||
}
|
||||
applyAppearance();
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
@ -442,6 +622,7 @@ public class FileEditor extends JDialog {
|
||||
textArea.setCaretPosition(0);
|
||||
}
|
||||
}
|
||||
if (undoManager != null) undoManager.discardAllEdits();
|
||||
modified = false;
|
||||
updateTitle();
|
||||
updateStatus();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user