From f1a3bc8b2e9ff2fae248d8905c85f9c1eaad0c75 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 13 Oct 2013 08:35:30 +0530 Subject: [PATCH] Start work on global undo/redo for tweaking --- src/calibre/gui2/tweak_book/boss.py | 17 +++++++++++++- src/calibre/gui2/tweak_book/file_list.py | 29 ++++++++++++++++++++---- src/calibre/gui2/tweak_book/ui.py | 11 +++++++++ src/calibre/gui2/tweak_book/undo.py | 19 ++++++++++++++++ 4 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py index 61c11597ed..1857e91900 100644 --- a/src/calibre/gui2/tweak_book/boss.py +++ b/src/calibre/gui2/tweak_book/boss.py @@ -71,12 +71,27 @@ class Boss(QObject): self.current_metadata = self.gui.current_metadata = container.mi self.global_undo.open_book(container) self.gui.update_window_title() - self.gui.file_list.build(container) + self.gui.file_list.build(container, preserve_state=False) + self.update_global_history_actions() + + def update_global_history_actions(self): + gu = self.global_undo + for x, text in (('undo', _('&Undo')), ('redo', '&Redo')): + ac = getattr(self.gui, 'action_global_%s' % x) + ac.setEnabled(getattr(gu, 'can_' + x)) + ac.setText(text + ' ' + getattr(gu, x + '_msg')) def add_savepoint(self, msg): nc = clone_container(current_container(), self.mkdtemp()) self.global_undo.add_savepoint(nc, msg) set_current_container(nc) + self.update_global_history_actions() + + def do_global_undo(self): + pass + + def do_global_redo(self): + pass def delete_requested(self, spine_items, other_items): if not self.check_dirtied(): diff --git a/src/calibre/gui2/tweak_book/file_list.py b/src/calibre/gui2/tweak_book/file_list.py index b7f1dce6d9..910aaaed80 100644 --- a/src/calibre/gui2/tweak_book/file_list.py +++ b/src/calibre/gui2/tweak_book/file_list.py @@ -89,7 +89,25 @@ class FileList(QTreeWidget): 'images':'view-image.png', }.iteritems()} - def build(self, container): + def get_state(self): + s = {'pos':self.verticalScrollBar().value()} + s['expanded'] = {c for c, item in self.categories.iteritems() if item.isExpanded()} + s['selected'] = {unicode(i.data(0, NAME_ROLE).toString()) for i in self.selectedItems()} + return s + + def set_state(self, state): + for category, item in self.categories: + item.setExpanded(category in state['expanded']) + self.verticalScrollBar().setValue(state['pos']) + for parent in self.categories.itervalues(): + for c in (parent.child(i) for i in parent.childCount()): + name = unicode(c.data(0, NAME_ROLE).toString()) + if name in state['selected']: + c.setSelected(True) + + def build(self, container, preserve_state=True): + if preserve_state: + state = self.get_state() self.clear() self.root = self.invisibleRootItem() self.root.setFlags(Qt.ItemIsDragEnabled) @@ -221,7 +239,10 @@ class FileList(QTreeWidget): processed[name] = create_item(name) for c in self.categories.itervalues(): - self.expandItem(c) + c.setExpanded(True) + + if preserve_state: + self.set_state(state) def show_context_menu(self, point): pass @@ -277,7 +298,7 @@ class FileListWidget(QWidget): for x in ('delete_done',): setattr(self, x, getattr(self.file_list, x)) - def build(self, container): - self.file_list.build(container) + def build(self, container, preserve_state=True): + self.file_list.build(container, preserve_state=preserve_state) diff --git a/src/calibre/gui2/tweak_book/ui.py b/src/calibre/gui2/tweak_book/ui.py index d445429f80..93275368a6 100644 --- a/src/calibre/gui2/tweak_book/ui.py +++ b/src/calibre/gui2/tweak_book/ui.py @@ -58,15 +58,26 @@ class Main(MainWindow): return ac self.action_open_book = reg('document_open.png', _('Open &book'), self.boss.open_book, 'open-book', 'Ctrl+O', _('Open a new book')) + self.action_global_undo = reg('back.png', _('&Revert to before'), self.boss.do_global_undo, 'global-undo', 'Ctrl+Left', + _('Revert book to before the last action (Undo)')) + self.action_global_redo = reg('forward.png', _('&Revert to after'), self.boss.do_global_redo, 'global-redo', 'Ctrl+Right', + _('Revert book state to after the next action (Redo)')) def create_menubar(self): b = self.menuBar() + f = b.addMenu(_('&File')) f.addAction(self.action_open_book) + e = b.addMenu(_('&Edit')) + e.addAction(self.action_global_undo) + e.addAction(self.action_global_redo) + def create_toolbar(self): self.global_bar = b = self.addToolBar(_('Global')) b.addAction(self.action_open_book) + b.addAction(self.action_global_undo) + b.addAction(self.action_global_redo) def create_docks(self): self.file_list_dock = d = QDockWidget(_('&Files Browser'), self) diff --git a/src/calibre/gui2/tweak_book/undo.py b/src/calibre/gui2/tweak_book/undo.py index 865ba90ef7..c39b2b5694 100644 --- a/src/calibre/gui2/tweak_book/undo.py +++ b/src/calibre/gui2/tweak_book/undo.py @@ -53,4 +53,23 @@ class GlobalUndoHistory(object): self.pos += 1 return self.current_container + @property + def can_undo(self): + return self.pos > 0 + + @property + def can_redo(self): + return self.pos < len(self.states) - 1 + + @property + def undo_msg(self): + if not self.can_undo: + return '' + return self.states[self.pos - 1].message or '' + + @property + def redo_msg(self): + if not self.can_redo: + return '' + return self.states[self.pos].message or ''