Edit Book: When re-opening a previously edited book, restore all open files and the cursor position. Can be disabled in Preferences->Main Window

This commit is contained in:
Kovid Goyal 2015-03-13 13:47:21 +05:30
parent 466dc2e144
commit fd47b19b2f
6 changed files with 90 additions and 1 deletions

View File

@ -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)}

View File

@ -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)
# }}}

View File

@ -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()

View File

@ -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)

View File

@ -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('<p>' + _(
'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):

View File

@ -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: