When switching libraries preserve the position and selected books if you switch back to a previously opened library. Fixes #994514 (New wish: stay on the same line in a library)

This commit is contained in:
Kovid Goyal 2012-05-05 14:06:51 +05:30
parent 4ab0a53cee
commit 4602530abc
2 changed files with 43 additions and 6 deletions

View File

@ -10,7 +10,7 @@ from functools import partial
from PyQt4.Qt import (QMenu, Qt, QInputDialog, QToolButton, QDialog,
QDialogButtonBox, QGridLayout, QLabel, QLineEdit, QIcon, QSize,
QCoreApplication)
QCoreApplication, pyqtSignal)
from calibre import isbytestring, sanitize_file_name_unicode
from calibre.constants import filesystem_encoding, iswindows
@ -142,6 +142,7 @@ class ChooseLibraryAction(InterfaceAction):
dont_add_to = frozenset(['context-menu-device'])
action_add_menu = True
action_menu_clone_qaction = _('Switch/create library...')
restore_view_state = pyqtSignal(object)
def genesis(self):
self.base_text = _('%d books')
@ -206,6 +207,17 @@ class ChooseLibraryAction(InterfaceAction):
self.maintenance_menu.addAction(ac)
self.choose_menu.addMenu(self.maintenance_menu)
self.view_state_map = {}
self.restore_view_state.connect(self._restore_view_state,
type=Qt.QueuedConnection)
@property
def preserve_state_on_switch(self):
ans = getattr(self, '_preserve_state_on_switch', None)
if ans is None:
self._preserve_state_on_switch = ans = \
self.gui.library_view.preserve_state(require_selected_ids=False)
return ans
def pick_random(self, *args):
self.gui.iactions['Pick Random Book'].pick_random()
@ -221,6 +233,13 @@ class ChooseLibraryAction(InterfaceAction):
def library_changed(self, db):
self.stats.library_used(db)
self.build_menus()
state = self.view_state_map.get(self.stats.canonicalize_path(
db.library_path), None)
if state is not None:
self.restore_view_state.emit(state)
def _restore_view_state(self, state):
self.preserve_state_on_switch.state = state
def initialization_complete(self):
self.library_changed(self.gui.library_view.model().db)
@ -401,8 +420,11 @@ class ChooseLibraryAction(InterfaceAction):
def switch_requested(self, location):
if not self.change_library_allowed():
return
db = self.gui.library_view.model().db
current_lib = self.stats.canonicalize_path(db.library_path)
self.view_state_map[current_lib] = self.preserve_state_on_switch.state
loc = location.replace('/', os.sep)
exists = self.gui.library_view.model().db.exists_at(loc)
exists = db.exists_at(loc)
if not exists:
d = MovedDialog(self.stats, location, self.gui)
ret = d.exec_()

View File

@ -32,8 +32,10 @@ class PreserveViewState(object): # {{{
and dont affect the scroll position.
'''
def __init__(self, view, preserve_hpos=True, preserve_vpos=True):
def __init__(self, view, preserve_hpos=True, preserve_vpos=True,
require_selected_ids=True):
self.view = view
self.require_selected_ids = require_selected_ids
self.selected_ids = set()
self.current_id = None
self.preserve_hpos = preserve_hpos
@ -51,15 +53,28 @@ class PreserveViewState(object): # {{{
traceback.print_exc()
def __exit__(self, *args):
if self.selected_ids:
if self.selected_ids or not self.require_selected_ids:
if self.current_id is not None:
self.view.current_id = self.current_id
self.view.select_rows(self.selected_ids, using_ids=True,
scroll=False, change_current=self.current_id is None)
if self.selected_ids:
self.view.select_rows(self.selected_ids, using_ids=True,
scroll=False, change_current=self.current_id is None)
if self.preserve_vpos:
self.view.verticalScrollBar().setValue(self.vscroll)
if self.preserve_hpos:
self.view.horizontalScrollBar().setValue(self.hscroll)
@dynamic_property
def state(self):
def fget(self):
self.__enter__()
return {x:getattr(self, x) for x in ('selected_ids', 'current_id',
'vscroll', 'hscroll')}
def fset(self, state):
for k, v in state.iteritems(): setattr(self, k, v)
self.__exit__()
return property(fget=fget, fset=fset)
# }}}
class BooksView(QTableView): # {{{