Preserve current book when doing searches

When doing searches or switching between virtual libraries in the main
book list, preserve the current book. The currently selected book will
remain visible if it is present in the results of the search or the
selected virtual library. Fixes #1216713 [After selecting books which belongs to same serie, when returning to main window, we are at the top of the list and not at previously selected item](https://bugs.launchpad.net/calibre/+bug/1216713)
This commit is contained in:
Kovid Goyal 2013-09-10 14:13:02 +05:30
parent 778edcbab8
commit c43a3e7969
3 changed files with 68 additions and 1 deletions

View File

@ -226,6 +226,7 @@ class AlternateViews(object):
self.stack = None
self.break_link = False
self.main_connected = False
self.current_book_state = None
def set_stack(self, stack):
self.stack = stack
@ -290,6 +291,15 @@ class AlternateViews(object):
for view in self.views.itervalues():
if view is not self.main_view:
view.set_context_menu(menu)
def save_current_book_state(self):
self.current_book_state = self.current_view, self.current_view.current_book_state()
def restore_current_book_state(self):
if self.current_book_state is not None:
if self.current_book_state[0] is self.current_view:
self.current_view.restore_current_book_state(self.current_book_state[1])
self.current_book_state = None
# }}}
# Rendering of covers {{{
@ -773,4 +783,26 @@ class GridView(QListView):
sm.select(QItemSelection(top, bottom), sm.Select)
else:
return QListView.mousePressEvent(self, ev)
@property
def current_book(self):
ci = self.currentIndex()
if ci.isValid():
try:
return self.model().db.data.index_to_id(ci.row())
except (IndexError, ValueError, KeyError, TypeError, AttributeError):
pass
def current_book_state(self):
return self.current_book
def restore_current_book_state(self, state):
book_id = state
try:
row = self.model().db.data.id_to_index(book_id)
except (IndexError, ValueError, KeyError, TypeError, AttributeError):
return
self.set_current_row(row)
self.select_rows((row,))
self.scrollTo(self.model().index(row, 0), self.PositionAtCenter)
# }}}

View File

@ -120,6 +120,7 @@ class BooksModel(QAbstractTableModel): # {{{
new_bookdisplay_data = pyqtSignal(object)
count_changed_signal = pyqtSignal(int)
searched = pyqtSignal(object)
search_done = pyqtSignal()
def __init__(self, parent=None, buffer=40):
QAbstractTableModel.__init__(self, parent)
@ -392,6 +393,7 @@ class BooksModel(QAbstractTableModel): # {{{
# Do not issue search done for the null search. It is used to clear
# the search and count records for restrictions
self.searched.emit(True)
self.search_done.emit()
def sort(self, col, order, reset=True):
if not self.db:

View File

@ -149,6 +149,7 @@ class BooksView(QTableView): # {{{
files_dropped = pyqtSignal(object)
add_column_signal = pyqtSignal()
is_library_view = True
def viewportEvent(self, event):
if (event.type() == event.ToolTip and not gprefs['book_list_tooltips']):
@ -776,6 +777,28 @@ class BooksView(QTableView): # {{{
self.scrollTo(self.model().index(row, i), self.PositionAtCenter)
break
@property
def current_book(self):
ci = self.currentIndex()
if ci.isValid():
try:
return self.model().db.data.index_to_id(ci.row())
except (IndexError, ValueError, KeyError, TypeError, AttributeError):
pass
def current_book_state(self):
return self.current_book, self.horizontalScrollBar().value()
def restore_current_book_state(self, state):
book_id, hpos = state
try:
row = self.model().db.data.id_to_index(book_id)
except (IndexError, ValueError, KeyError, TypeError, AttributeError):
return
self.set_current_row(row)
self.scroll_to_row(row)
self.horizontalScrollBar().setValue(hpos)
def set_current_row(self, row=0, select=True, for_sync=False):
if row > -1 and row < self.model().rowCount(QModelIndex()):
h = self.horizontalHeader()
@ -929,18 +952,26 @@ class BooksView(QTableView): # {{{
self.select_rows([id_to_select], using_ids=True)
def search_proxy(self, txt):
if self.is_library_view:
# Save the current book before doing the search, after the search
# is completed, this book will become the current book and be
# scrolled to if it is present in the search results
self.alternate_views.save_current_book_state()
self._model.search(txt)
id_to_select = self._model.get_current_highlighted_id()
if id_to_select is not None:
self.select_rows([id_to_select], using_ids=True)
elif self._model.highlight_only:
self.clearSelection()
if self.isVisible():
self.setFocus(Qt.OtherFocusReason)
def connect_to_search_box(self, sb, search_done):
sb.search.connect(self.search_proxy)
self._search_done = search_done
self._model.searched.connect(self.search_done)
if self.is_library_view:
self._model.search_done.connect(self.alternate_views.restore_current_book_state)
def connect_to_book_display(self, bd):
self._model.new_bookdisplay_data.connect(bd)
@ -955,6 +986,8 @@ class BooksView(QTableView): # {{{
class DeviceBooksView(BooksView): # {{{
is_library_view = False
def __init__(self, parent):
BooksView.__init__(self, parent, DeviceBooksModel,
use_edit_metadata_dialog=False)