diff --git a/src/calibre/gui2/tweak_book/__init__.py b/src/calibre/gui2/tweak_book/__init__.py index e40b50168c..d9cd99260d 100644 --- a/src/calibre/gui2/tweak_book/__init__.py +++ b/src/calibre/gui2/tweak_book/__init__.py @@ -65,6 +65,9 @@ d['spell_check_case_sensitive_search'] = False d['add_cover_preserve_aspect_ratio'] = False d['templates'] = {} d['auto_close_tags'] = True +d['edit_book_state'] = {} +d['edit_book_state_order'] = [] +d['restore_book_state'] = True del d ucase_map = {l:string.ascii_uppercase[i] for i, l in enumerate(string.ascii_lowercase)} diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py index 442a487025..9475265e7b 100644 --- a/src/calibre/gui2/tweak_book/boss.py +++ b/src/calibre/gui2/tweak_book/boss.py @@ -314,6 +314,9 @@ class Boss(QObject): if isinstance(ef, type('')): ef = [ef] map(self.gui.file_list.request_edit, ef) + else: + if tprefs['restore_book_state']: + self.restore_book_edit_state() self.gui.toc_view.update_if_visible() self.add_savepoint(_('Start of editing session')) @@ -1458,5 +1461,50 @@ class Boss(QObject): def save_state(self): with tprefs: self.gui.save_state() - # }}} + self.save_book_edit_state() + def save_book_edit_state(self): + c = current_container() + if c and c.path_to_ebook: + mem = tprefs['edit_book_state'] + order = tprefs['edit_book_state_order'] + extra = len(order) - 99 + if extra > 0: + order = [k for k in order[extra:] if k in mem] + mem = {k:mem[k] for k in order} + mem[c.path_to_ebook] = { + 'editors':{name:ed.current_editing_state for name, ed in editors.iteritems()}, + 'currently_editing':self.currently_editing, + 'tab_order':self.gui.central.tab_order, + } + try: + order.remove(c.path_to_ebook) + except ValueError: + pass + order.append(c.path_to_ebook) + tprefs['edit_book_state'] = mem + tprefs['edit_book_state_order'] = order + + def restore_book_edit_state(self): + c = current_container() + if c and c.path_to_ebook: + state = tprefs['edit_book_state'].get(c.path_to_ebook) + if state is not None: + opened = set() + eds = state.get('editors', {}) + for name in state.get('tab_order', ()): + if c.has_name(name): + try: + editor = self.edit_file_requested(name) + if editor is not None: + opened.add(name) + es = eds.get(name) + if es is not None: + editor.current_editing_state = es + except Exception: + import traceback + traceback.print_exc() + ce = state.get('currently_editing') + if ce in opened: + self.show_editor(ce) + # }}} diff --git a/src/calibre/gui2/tweak_book/editor/image.py b/src/calibre/gui2/tweak_book/editor/image.py index 6e7fef1f1f..a9d7f9356c 100644 --- a/src/calibre/gui2/tweak_book/editor/image.py +++ b/src/calibre/gui2/tweak_book/editor/image.py @@ -116,6 +116,14 @@ class Editor(QMainWindow): self.modification_state_changed.emit(val) return property(fget=fget, fset=fset) + @dynamic_property + def current_editing_state(self): + def fget(self): + return {} + def fset(self, val): + pass + return property(fget=fget, fset=fset) + @property def undo_available(self): return self.canvas.undo_action.isEnabled() diff --git a/src/calibre/gui2/tweak_book/editor/widget.py b/src/calibre/gui2/tweak_book/editor/widget.py index 2ebee670ec..b8588a19bd 100644 --- a/src/calibre/gui2/tweak_book/editor/widget.py +++ b/src/calibre/gui2/tweak_book/editor/widget.py @@ -149,6 +149,19 @@ class Editor(QMainWindow): self.editor.go_to_line(val) return property(fget=fget, fset=fset) + @dynamic_property + def current_editing_state(self): + def fget(self): + c = self.editor.textCursor() + return {'cursor':(c.anchor(), c.position())} + def fset(self, val): + anchor, position = val.get('cursor', (None, None)) + if anchor is not None and position is not None: + c = self.editor.textCursor() + c.setPosition(anchor), c.setPosition(position, c.KeepAnchor) + self.editor.setTextCursor(c) + return property(fget=fget, fset=fset) + def current_tag(self, for_position_sync=True): return self.editor.current_tag(for_position_sync=for_position_sync) diff --git a/src/calibre/gui2/tweak_book/preferences.py b/src/calibre/gui2/tweak_book/preferences.py index 41ecdf00c0..a46dde0a80 100644 --- a/src/calibre/gui2/tweak_book/preferences.py +++ b/src/calibre/gui2/tweak_book/preferences.py @@ -306,6 +306,13 @@ class MainWindowSettings(BasicSettings): cn = {('top', 'left'): _('The top-left corner'), ('top', 'right'):_('The top-right corner'), ('bottom', 'left'):_('The bottom-left corner'), ('bottom', 'right'):_('The bottom-right corner')}[(v, h)] l.addRow(cn + ':', w) + nd = self('restore_book_state') + nd.setText(_('Restore state of previously edited book when opening it again')) + nd.setToolTip('
' + _( + 'When opening a previously edited book again, restore its state. That means all open' + ' files are automatically re-opened and the cursor is positioned at its previous location.' + )) + l.addRow(nd) class PreviewSettings(BasicSettings): diff --git a/src/calibre/gui2/tweak_book/ui.py b/src/calibre/gui2/tweak_book/ui.py index 3e244f3194..60a9f6095e 100644 --- a/src/calibre/gui2/tweak_book/ui.py +++ b/src/calibre/gui2/tweak_book/ui.py @@ -99,6 +99,16 @@ class Central(QStackedWidget): # {{{ self.editor_tabs.setTabToolTip(index, _('Full path:') + ' ' + name) editor.modification_state_changed.connect(self.editor_modified) + @property + def tab_order(self): + ans = [] + rmap = {v:k for k, v in editors.iteritems()} + for i in xrange(self.editor_tabs.count()): + name = rmap.get(self.editor_tabs.widget(i)) + if name is not None: + ans.append(name) + return ans + def rename_editor(self, editor, name): for i in xrange(self.editor_tabs.count()): if self.editor_tabs.widget(i) is editor: