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 @@ def __init__(self, main_view):
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 @@ def set_context_menu(self, menu):
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 @@ def handle_mouse_press_event(self, ev):
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 @@ def search(self, text, reset=True):
# 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 @@ def scroll_to_row(self, row):
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 @@ def move_highlighted_row(self, forward):
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()
self.setFocus(Qt.OtherFocusReason)
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 @@ def row_count(self):
class DeviceBooksView(BooksView): # {{{
is_library_view = False
def __init__(self, parent):
BooksView.__init__(self, parent, DeviceBooksModel,
use_edit_metadata_dialog=False)