From 5149c43ce2f23f837660916cdcc71e02a9d24199 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 21 Jan 2020 11:08:15 +0530 Subject: [PATCH] Wire up the next and previous search controls --- src/calibre/gui2/viewer/search.py | 30 ++++++++++++++++++++++++++--- src/calibre/gui2/viewer/ui.py | 2 ++ src/calibre/gui2/viewer/web_view.py | 3 +++ src/pyj/read_book/search.pyj | 10 ++++++++-- src/pyj/viewer-main.pyj | 2 ++ 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/calibre/gui2/viewer/search.py b/src/calibre/gui2/viewer/search.py index 5f36d6e94f..7fd5a44fa2 100644 --- a/src/calibre/gui2/viewer/search.py +++ b/src/calibre/gui2/viewer/search.py @@ -275,17 +275,35 @@ class ResultsDelegate(QStyledItemDelegate): # {{{ class Results(QListWidget): # {{{ + show_search_result = pyqtSignal(object) + def __init__(self, parent=None): QListWidget.__init__(self, parent) self.setFocusPolicy(Qt.NoFocus) self.setSpacing(2) self.delegate = ResultsDelegate(self) self.setItemDelegate(self.delegate) + self.itemClicked.connect(self.item_activated) def add_result(self, result): i = QListWidgetItem(' ', self) i.setData(Qt.UserRole, result) return self.count() + + def item_activated(self): + i = self.currentItem() + if i: + sr = i.data(Qt.UserRole) + self.show_search_result.emit(sr) + + def find_next(self, previous): + if self.count() < 1: + return + i = self.currentRow() + i += -1 if previous else 1 + i %= self.count() + self.setCurrentRow(i) + self.item_activated() # }}} @@ -315,13 +333,13 @@ class SearchPanel(QWidget): # {{{ def start_search(self, search_query, current_name): if self.current_search is not None and search_query == self.current_search: - # TODO: go to next or previous result as required + self.find_next_requested(search_query.backwards) return if self.searcher is None: self.searcher = Thread(name='Searcher', target=self.run_searches) self.searcher.daemon = True self.searcher.start() - # TODO: Clear the current search results + self.results.clear() self.spinner.start() self.current_search = search_query self.search_tasks.put((search_query, current_name)) @@ -364,7 +382,10 @@ class SearchPanel(QWidget): # {{{ if isinstance(result, SearchFinished): self.spinner.stop() return - self.results.add_result(result) + if self.results.add_result(result) == 1: + # first result + self.results.setCurrentRow(0) + self.results.item_activated() def clear_searches(self): self.current_search = None @@ -377,4 +398,7 @@ class SearchPanel(QWidget): # {{{ self.spinner.stop() self.current_search = None self.searcher = None + + def find_next_requested(self, previous): + self.results.find_next(previous) # }}} diff --git a/src/calibre/gui2/viewer/ui.py b/src/calibre/gui2/viewer/ui.py index 6fe9466497..a3c5945e1e 100644 --- a/src/calibre/gui2/viewer/ui.py +++ b/src/calibre/gui2/viewer/ui.py @@ -158,6 +158,7 @@ class EbookViewer(MainWindow): self.web_view.reload_book.connect(self.reload_book) self.web_view.toggle_toc.connect(self.toggle_toc) self.web_view.show_search.connect(self.show_search) + self.web_view.find_next.connect(self.search_widget.find_next_requested) self.web_view.toggle_bookmarks.connect(self.toggle_bookmarks) self.web_view.toggle_inspector.connect(self.toggle_inspector) self.web_view.toggle_lookup.connect(self.toggle_lookup) @@ -252,6 +253,7 @@ class EbookViewer(MainWindow): name = self.web_view.current_content_file if name: self.search_widget.start_search(search_query, name) + self.web_view.setFocus(Qt.OtherFocusReason) def toggle_bookmarks(self): is_visible = self.bookmarks_dock.isVisible() diff --git a/src/calibre/gui2/viewer/web_view.py b/src/calibre/gui2/viewer/web_view.py index b1463c5e37..401f3daeca 100644 --- a/src/calibre/gui2/viewer/web_view.py +++ b/src/calibre/gui2/viewer/web_view.py @@ -249,6 +249,7 @@ class ViewerBridge(Bridge): toggle_inspector = from_js() toggle_lookup = from_js() show_search = from_js() + find_next = from_js(object) quit = from_js() update_current_toc_nodes = from_js(object, object) toggle_full_screen = from_js() @@ -418,6 +419,7 @@ class WebView(RestartingWebEngineView): reload_book = pyqtSignal() toggle_toc = pyqtSignal() show_search = pyqtSignal() + find_next = pyqtSignal(object) toggle_bookmarks = pyqtSignal() toggle_inspector = pyqtSignal() toggle_lookup = pyqtSignal() @@ -462,6 +464,7 @@ class WebView(RestartingWebEngineView): self.bridge.reload_book.connect(self.reload_book) self.bridge.toggle_toc.connect(self.toggle_toc) self.bridge.show_search.connect(self.show_search) + self.bridge.find_next.connect(self.find_next) self.bridge.toggle_bookmarks.connect(self.toggle_bookmarks) self.bridge.toggle_inspector.connect(self.toggle_inspector) self.bridge.toggle_lookup.connect(self.toggle_lookup) diff --git a/src/pyj/read_book/search.pyj b/src/pyj/read_book/search.pyj index 4d980bb853..a3ce46f81d 100644 --- a/src/pyj/read_book/search.pyj +++ b/src/pyj/read_book/search.pyj @@ -89,10 +89,16 @@ class SearchOverlay: self.view.find(text, backwards) def find_next(self): - self.find(self.search_text, False) + if ui_operations.find_next: + ui_operations.find_next(False) + else: + self.find(self.search_text, False) def find_previous(self): - self.find(self.search_text, True) + if ui_operations.find_next: + ui_operations.find_next(True) + else: + self.find(self.search_text, True) def find_in_serialized_html(data, text): diff --git a/src/pyj/viewer-main.pyj b/src/pyj/viewer-main.pyj index 90552dbba6..40be984e2e 100644 --- a/src/pyj/viewer-main.pyj +++ b/src/pyj/viewer-main.pyj @@ -341,6 +341,8 @@ if window is window.top: to_python.content_file_changed(name) ui_operations.show_search = def(): to_python.show_search() + ui_operations.find_next = def(previous): + to_python.find_next(previous) ui_operations.reset_interface = def(): sd = get_session_data() defaults = session_defaults()