diff --git a/resources/images/edit-undo.png b/resources/images/edit-undo.png index f6d7e8ba56..5071aa1dd3 100644 Binary files a/resources/images/edit-undo.png and b/resources/images/edit-undo.png differ diff --git a/src/calibre/gui2/tweak_book/__init__.py b/src/calibre/gui2/tweak_book/__init__.py index afb7ca1f3d..ab9390ef53 100644 --- a/src/calibre/gui2/tweak_book/__init__.py +++ b/src/calibre/gui2/tweak_book/__init__.py @@ -22,3 +22,5 @@ def current_container(): def set_current_container(container): global _current_container _current_container = container + +actions = {} diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py index 134c7973de..62569986d0 100644 --- a/src/calibre/gui2/tweak_book/boss.py +++ b/src/calibre/gui2/tweak_book/boss.py @@ -21,7 +21,7 @@ from calibre.ebooks.oeb.polish.container import get_container as _gc, clone_cont from calibre.ebooks.oeb.polish.replace import rename_files from calibre.gui2 import error_dialog, choose_files, question_dialog, info_dialog from calibre.gui2.dialogs.confirm_delete import confirm -from calibre.gui2.tweak_book import set_current_container, current_container, tprefs +from calibre.gui2.tweak_book import set_current_container, current_container, tprefs, actions from calibre.gui2.tweak_book.undo import GlobalUndoHistory from calibre.gui2.tweak_book.save import SaveManager from calibre.gui2.tweak_book.editor import editor_from_syntax, syntax_from_mime @@ -49,6 +49,7 @@ class Boss(QObject): fl.reorder_spine.connect(self.reorder_spine) fl.rename_requested.connect(self.rename_requested) fl.edit_file.connect(self.edit_file_requested) + self.gui.central.current_editor_changed.connect(self.apply_current_editor_state) def mkdtemp(self): self.container_count += 1 @@ -217,11 +218,12 @@ class Boss(QObject): editor = self.editors.get(name, None) if editor is None: editor = self.editors[name] = editor_from_syntax(syntax, self.gui.editor_tabs) + editor.undo_redo_state_changed.connect(self.editor_undo_redo_state_changed) + editor.modification_state_changed.connect(self.editor_modification_state_changed) self.gui.central.add_editor(name, editor) c = current_container() editor.load_text(c.decode(c.open(name).read())) self.gui.central.show_editor(editor) - self.gui.keyboard.set_mode(syntax) def edit_file_requested(self, name, syntax, mime): if name in self.editors: @@ -234,6 +236,33 @@ class Boss(QObject): _('Editing of files of type %s is not supported' % mime), show=True) self.edit_file(name, syntax) + def do_editor_undo(self): + ed = self.gui.central.current_editor + if ed is not None: + ed.undo() + + def do_editor_redo(self): + ed = self.gui.central.current_editor + if ed is not None: + ed.redo() + + def editor_undo_redo_state_changed(self, *args): + self.apply_current_editor_state(update_keymap=False) + + def editor_modification_state_changed(self, *args): + self.apply_current_editor_state(update_keymap=False) + + def apply_current_editor_state(self, update_keymap=True): + ed = self.gui.central.current_editor + if ed is not None: + actions['editor-undo'].setEnabled(ed.undo_available) + actions['editor-redo'].setEnabled(ed.redo_available) + actions['editor-save'].setEnabled(ed.is_modified) + self.gui.keyboard.set_mode(ed.syntax) + + def do_editor_save(self): + pass # TODO: Implement this + # Shutdown {{{ def quit(self): if not self.confirm_quit(): diff --git a/src/calibre/gui2/tweak_book/editor/widget.py b/src/calibre/gui2/tweak_book/editor/widget.py index 36e02c755f..72e615a1e7 100644 --- a/src/calibre/gui2/tweak_book/editor/widget.py +++ b/src/calibre/gui2/tweak_book/editor/widget.py @@ -8,11 +8,13 @@ __copyright__ = '2013, Kovid Goyal ' from PyQt4.Qt import QMainWindow, Qt, QApplication, pyqtSignal +from calibre.gui2.tweak_book import actions from calibre.gui2.tweak_book.editor.text import TextEdit class Editor(QMainWindow): modification_state_changed = pyqtSignal(object) + undo_redo_state_changed = pyqtSignal(object, object) def __init__(self, syntax, parent=None): QMainWindow.__init__(self, parent) @@ -23,10 +25,28 @@ class Editor(QMainWindow): self.setCentralWidget(self.editor) self.editor.modificationChanged.connect(self.modification_state_changed.emit) self.create_toolbars() + self.undo_available = False + self.redo_available = False + self.editor.undoAvailable.connect(self._undo_available) + self.editor.redoAvailable.connect(self._redo_available) + + def _undo_available(self, available): + self.undo_available = available + self.undo_redo_state_changed.emit(self.undo_available, self.redo_available) + + def _redo_available(self, available): + self.redo_available = available + self.undo_redo_state_changed.emit(self.undo_available, self.redo_available) def load_text(self, raw): self.editor.load_text(raw, syntax=self.syntax) + def undo(self): + self.editor.undo() + + def redo(self): + self.editor.redo() + @dynamic_property def is_modified(self): def fget(self): @@ -38,6 +58,9 @@ class Editor(QMainWindow): def create_toolbars(self): self.action_bar = b = self.addToolBar(_('Edit actions tool bar')) b.setObjectName('action_bar') # Needed for saveState + b.addAction(actions['editor-save']) + b.addAction(actions['editor-undo']) + b.addAction(actions['editor-redo']) def launch_editor(path_to_edit, path_is_raw=False, syntax='html'): diff --git a/src/calibre/gui2/tweak_book/ui.py b/src/calibre/gui2/tweak_book/ui.py index f4c536f254..9bbec5bc39 100644 --- a/src/calibre/gui2/tweak_book/ui.py +++ b/src/calibre/gui2/tweak_book/ui.py @@ -8,11 +8,11 @@ __copyright__ = '2013, Kovid Goyal ' from PyQt4.Qt import ( QDockWidget, Qt, QLabel, QIcon, QAction, QApplication, QWidget, - QVBoxLayout, QStackedWidget, QTabWidget, QImage, QPixmap) + QVBoxLayout, QStackedWidget, QTabWidget, QImage, QPixmap, pyqtSignal) from calibre.constants import __appname__, get_version from calibre.gui2.main_window import MainWindow -from calibre.gui2.tweak_book import current_container, tprefs +from calibre.gui2.tweak_book import current_container, tprefs, actions from calibre.gui2.tweak_book.file_list import FileListWidget from calibre.gui2.tweak_book.job import BlockingJob from calibre.gui2.tweak_book.boss import Boss @@ -21,6 +21,8 @@ from calibre.gui2.tweak_book.keyboard import KeyboardManager class Central(QStackedWidget): ' The central widget, hosts the editors ' + current_editor_changed = pyqtSignal() + def __init__(self, parent=None): QStackedWidget.__init__(self, parent) self.welcome = w = QLabel('

'+_( @@ -47,6 +49,7 @@ class Central(QStackedWidget): self.modified_icon = QIcon(QPixmap.fromImage(i)) else: self.modified_icon = QIcon(I('modified.png')) + self.editor_tabs.currentChanged.connect(self.current_editor_changed) def add_editor(self, name, editor): fname = name.rpartition('/')[2] @@ -65,6 +68,10 @@ class Central(QStackedWidget): modified = getattr(editor, 'is_modified', False) tb.setTabIcon(i, self.modified_icon if modified else QIcon()) + @property + def current_editor(self): + return self.editor_tabs.currentWidget() + class Main(MainWindow): APP_NAME = _('Tweak Book') @@ -113,7 +120,7 @@ class Main(MainWindow): group = _('Global Actions') def reg(icon, text, target, sid, keys, description): - ac = QAction(QIcon(I(icon)), text, self) + ac = actions[sid] = QAction(QIcon(I(icon)), text, self) ac.setObjectName('action-' + sid) ac.triggered.connect(target) if isinstance(keys, type('')): @@ -132,6 +139,14 @@ class Main(MainWindow): self.action_save.setEnabled(False) self.action_quit = reg('quit.png', _('&Quit'), self.boss.quit, 'quit', 'Ctrl+Q', _('Quit')) + # Editor actions + self.action_editor_undo = reg('edit-undo.png', _('&Undo'), self.boss.do_editor_undo, 'editor-undo', 'Ctrl+Z', + _('Undo typing')) + self.action_editor_redo = reg('edit-redo.png', _('&Redo'), self.boss.do_editor_redo, 'editor-redo', 'Ctrl+Y', + _('Redo typing')) + self.action_editor_save = reg('save.png', _('&Save'), self.boss.do_editor_save, 'editor-save', 'Ctrl+S', + _('Save changes to the current file')) + def create_menubar(self): b = self.menuBar()