diff --git a/src/calibre/gui2/fts/search.py b/src/calibre/gui2/fts/search.py index 632c023da0..120bc81673 100644 --- a/src/calibre/gui2/fts/search.py +++ b/src/calibre/gui2/fts/search.py @@ -56,6 +56,7 @@ from calibre.utils.localization import ngettext ROOT = QModelIndex() sanitize_text_pat = re.compile(r'\s+') fts_url = 'https://www.sqlite.org/fts5.html#full_text_query_syntax' +jump_shortcut = '' def mark_books(*book_ids): @@ -317,7 +318,10 @@ class ResultsModel(QAbstractItemModel): # wait for some time so that other threads/processes that try to access the db can be scheduled if abort.wait(0.01): return - self.result_found.emit(query_id, result) + try: + self.result_found.emit(query_id, result) + except RuntimeError: # if dialog is deleted from under us + return self.all_results_found.emit(query_id) def result_with_text_found(self, query_id, result): @@ -594,9 +598,6 @@ class ResultDetails(QWidget): def __init__(self, parent=None): super().__init__(parent) - self.jump_action = ac = QAction(self) - ac.triggered.connect(self.jump_to_current_book) - ac.setShortcut(QKeySequence('Ctrl+S', QKeySequence.SequenceFormat.PortableText)) self.key = None self.pixmap_label = pl = QLabel(self) pl.setScaledContents(True) @@ -620,7 +621,7 @@ class ResultDetails(QWidget): if url.host() == 'mark': mark_books(self.current_book_id) elif url.host() == 'jump': - jump_to_book(self.current_book_id) + jump_to_book(self.current_book_id, self) elif url.host() == 'unindex': db = get_db() db.fts_unindex(self.current_book_id) @@ -634,10 +635,6 @@ class ResultDetails(QWidget): ' to see updated results.'), show=True) self.remove_book_from_results.emit(self.current_book_id) - def jump_to_current_book(self): - if self.current_book_id > -1: - jump_to_book(self.current_book_id) - def results_anchor_clicked(self, url): if self.current_book_id > 0 and url.scheme() == 'book': book_id, result_num, fmt = url.path().strip('/').split('/') @@ -699,7 +696,7 @@ class ResultDetails(QWidget): ict = '' text += '

{2}\xa0{0}\xa0\xa0\xa0 '.format( _('Select'), '

' + _('Scroll to this book in the calibre library book list and select it [{}]').format( - self.jump_action.shortcut().toString(QKeySequence.SequenceFormat.NativeText)), ict.format('lt.png')) + jump_shortcut), ict.format('lt.png')) text += '{2}\xa0{0}

'.format( _('Mark'), '

' + _( 'Put a pin on this book in the calibre library, for future reference.' @@ -845,6 +842,8 @@ class SplitView(QSplitter): self.details = d = DetailsPanel(parent=self) self.addWidget(d) model.result_with_context_found.connect(d.result_with_context_found) + model.matches_found.connect(self.matches_found) + model.search_started.connect(self.search_started) d.show_in_viewer.connect(self.show_in_viewer) d.remove_book_from_results.connect(self.remove_book_from_results) rv.current_changed.connect(d.show_result) @@ -874,12 +873,24 @@ class SplitView(QSplitter): return None, None +class CardView(QWidget): + + def __init__(self, model, parent=None): + super().__init__(parent) + QVBoxLayout(self) + + class ResultsPanel(QWidget): switch_to_scan_panel = pyqtSignal() def __init__(self, parent=None): + global jump_shortcut super().__init__(parent) + self.jump_to_current_book_action = ac = QAction(self) + ac.triggered.connect(self.jump_to_current_book) + ac.setShortcut(QKeySequence('Ctrl+S', QKeySequence.SequenceFormat.PortableText)) + jump_shortcut = ac.shortcut().toString(QKeySequence.SequenceFormat.NativeText) if isinstance(parent, QDialog): parent.finished.connect(self.shutdown) self.results_model = m = ResultsModel(self) @@ -896,15 +907,21 @@ class ResultsPanel(QWidget): sv.remove_book_from_results.connect(self.remove_book_from_results) QStackedLayout(self) self.layout().addWidget(sv) + self.card_view = cv = CardView(self.results_model, self) + self.layout().addWidget(cv) self.set_view_mode() def set_view_mode(self, is_split=True): if is_split: self.split_view.left_panel.layout().insertWidget(0, self.sip) + self.layout().setCurrentIndex(0) + else: + self.card_view.layout().insertWidget(0, self.sip) + self.layout().setCurrentIndex(1) @property def current_view(self): - return self.split_view + self.layout().currentWidget() def search(self, text: str): gui = get_gui() @@ -915,19 +932,18 @@ class ResultsPanel(QWidget): self.results_model.search(text, restrict_to_book_ids=restrict, use_stemming=gprefs['fts_library_use_stemmer']) def search_started(self): - self.split_view.search_started() self.sip.start() def search_complete(self): self.sip.stop() def matches_found(self, num): - self.split_view.matches_found(num) self.sip.matches_found(num) - @property - def jump_to_current_book_action(self): - return self.split_view.details.result_details.jump_action + def jump_to_current_book(self): + results, match = self.current_view.current_result() + if results: + jump_to_book(results.book_id, self) def view_current_result(self): results, match = self.current_view.current_result()