diff --git a/src/calibre/gui2/actions/choose_library.py b/src/calibre/gui2/actions/choose_library.py index 00b8b176c3..0a361209e6 100644 --- a/src/calibre/gui2/actions/choose_library.py +++ b/src/calibre/gui2/actions/choose_library.py @@ -10,7 +10,7 @@ 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 @@ def genesis(self): 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 @@ def library_name(self): 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 @@ def check_library(self): 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_() diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py index 5e394fbadb..106ee89808 100644 --- a/src/calibre/gui2/library/views.py +++ b/src/calibre/gui2/library/views.py @@ -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 @@ def __enter__(self): 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): # {{{