mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Allow clicking on the spinner to abort a search
This commit is contained in:
parent
6e86eb53f3
commit
7d8fe94078
@ -6,6 +6,7 @@
|
|||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from functools import partial
|
from functools import partial
|
||||||
@ -21,7 +22,7 @@ from threading import Event, Thread
|
|||||||
from calibre import fit_image, prepare_string_for_xml
|
from calibre import fit_image, prepare_string_for_xml
|
||||||
from calibre.db import FTSQueryError
|
from calibre.db import FTSQueryError
|
||||||
from calibre.ebooks.metadata import authors_to_string, fmt_sidx
|
from calibre.ebooks.metadata import authors_to_string, fmt_sidx
|
||||||
from calibre.gui2 import config, error_dialog, gprefs, safe_open_url
|
from calibre.gui2 import config, error_dialog, gprefs, question_dialog, safe_open_url
|
||||||
from calibre.gui2.fts.utils import get_db
|
from calibre.gui2.fts.utils import get_db
|
||||||
from calibre.gui2.library.annotations import BusyCursor
|
from calibre.gui2.library.annotations import BusyCursor
|
||||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||||
@ -173,6 +174,11 @@ class ResultsModel(QAbstractItemModel):
|
|||||||
self.endResetModel()
|
self.endResetModel()
|
||||||
self.search_complete.emit()
|
self.search_complete.emit()
|
||||||
|
|
||||||
|
def abort_search(self):
|
||||||
|
self.current_thread_abort.set()
|
||||||
|
self.signal_search_complete(self.current_query_id)
|
||||||
|
self.current_search_key = None # so that re-doing the search works
|
||||||
|
|
||||||
def search(self, fts_engine_query, use_stemming=True, restrict_to_book_ids=None):
|
def search(self, fts_engine_query, use_stemming=True, restrict_to_book_ids=None):
|
||||||
db = get_db()
|
db = get_db()
|
||||||
failure = []
|
failure = []
|
||||||
@ -394,6 +400,13 @@ class ResultsView(QTreeView):
|
|||||||
|
|
||||||
class Spinner(ProgressIndicator):
|
class Spinner(ProgressIndicator):
|
||||||
|
|
||||||
|
last_mouse_press_at = 0
|
||||||
|
clicked = pyqtSignal(object)
|
||||||
|
|
||||||
|
def __init__(self, *a):
|
||||||
|
super().__init__(*a)
|
||||||
|
self.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||||
|
|
||||||
def sizeHint(self):
|
def sizeHint(self):
|
||||||
return QSize(8, 8)
|
return QSize(8, 8)
|
||||||
|
|
||||||
@ -401,11 +414,28 @@ class Spinner(ProgressIndicator):
|
|||||||
if self.isAnimated():
|
if self.isAnimated():
|
||||||
super().paintEvent(ev)
|
super().paintEvent(ev)
|
||||||
|
|
||||||
|
def mousePressEvent(self, ev):
|
||||||
|
if ev.button() == Qt.MouseButton.LeftButton:
|
||||||
|
self.last_mouse_press_at = time.monotonic()
|
||||||
|
ev.accept()
|
||||||
|
super().mousePressEvent(ev)
|
||||||
|
|
||||||
|
def mouseReleaseEvent(self, ev):
|
||||||
|
if ev.button() == Qt.MouseButton.LeftButton:
|
||||||
|
dt = time.monotonic() - self.last_mouse_press_at
|
||||||
|
self.last_mouse_press_at = 0
|
||||||
|
if dt < 0.5:
|
||||||
|
self.clicked.emit(ev)
|
||||||
|
ev.accept()
|
||||||
|
return
|
||||||
|
super().mouseReleaseEvent(ev)
|
||||||
|
|
||||||
|
|
||||||
class SearchInputPanel(QWidget):
|
class SearchInputPanel(QWidget):
|
||||||
|
|
||||||
search_signal = pyqtSignal(object)
|
search_signal = pyqtSignal(object)
|
||||||
clear_search = pyqtSignal()
|
clear_search = pyqtSignal()
|
||||||
|
request_stop_search = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -443,6 +473,7 @@ class SearchInputPanel(QWidget):
|
|||||||
self.v2 = v2 = QVBoxLayout()
|
self.v2 = v2 = QVBoxLayout()
|
||||||
v2.addWidget(sb)
|
v2.addWidget(sb)
|
||||||
self.pi = pi = Spinner(self)
|
self.pi = pi = Spinner(self)
|
||||||
|
pi.clicked.connect(self.request_stop_search)
|
||||||
v2.addWidget(pi)
|
v2.addWidget(pi)
|
||||||
|
|
||||||
self.layout().addLayout(v2)
|
self.layout().addLayout(v2)
|
||||||
@ -684,6 +715,7 @@ class ResultsPanel(QWidget):
|
|||||||
s.addWidget(lp)
|
s.addWidget(lp)
|
||||||
l = lp.layout()
|
l = lp.layout()
|
||||||
self.sip = sip = SearchInputPanel(parent=self)
|
self.sip = sip = SearchInputPanel(parent=self)
|
||||||
|
sip.request_stop_search.connect(self.request_stop_search)
|
||||||
l.addWidget(sip)
|
l.addWidget(sip)
|
||||||
self.results_view = rv = ResultsView(parent=self)
|
self.results_view = rv = ResultsView(parent=self)
|
||||||
l.addWidget(rv)
|
l.addWidget(rv)
|
||||||
@ -700,6 +732,10 @@ class ResultsPanel(QWidget):
|
|||||||
rv.result_with_context_found.connect(d.result_with_context_found)
|
rv.result_with_context_found.connect(d.result_with_context_found)
|
||||||
s.addWidget(d)
|
s.addWidget(d)
|
||||||
|
|
||||||
|
def request_stop_search(self):
|
||||||
|
if question_dialog(self, _('Are you sure?'), _('Abort the current search?')):
|
||||||
|
self.results_view.m.abort_search()
|
||||||
|
|
||||||
def specialize_button_box(self, bb):
|
def specialize_button_box(self, bb):
|
||||||
bb.clear()
|
bb.clear()
|
||||||
bb.addButton(QDialogButtonBox.StandardButton.Close)
|
bb.addButton(QDialogButtonBox.StandardButton.Close)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user