diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 40ae3b1919..f73257e344 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -431,6 +431,7 @@ class Cache: def initialize_fts(self): self.fts_queue_thread = None self.fts_job_queue = Queue() + self.fts_indexing_left = self.fts_indexing_total = 0 fts = self.backend.initialize_fts(weakref.ref(self)) if self.is_fts_enabled(): self.start_fts_pool() @@ -448,14 +449,20 @@ class Cache: def is_fts_enabled(self): return self.backend.fts_enabled - @read_api + @api def fts_indexing_progress(self): - if not self.is_fts_enabled(): - return 0, 0 - num_to_scan = self.backend.fts.number_dirtied() - if not num_to_scan: - return 0, 1 - return num_to_scan, (self.backend.get('SELECT COUNT(*) FROM main.data')[0][0] or 0) + return self.fts_indexing_left, self.fts_indexing_total + + def _update_fts_indexing_numbers(self): + # this is called when new formats are added and when a format is + # indexed, but NOT when books or formats are deleted, so total may not + # be up to date. + nl = self.backend.fts.number_dirtied() + nt = self.backend.get('SELECT COUNT(*) FROM main.data')[0][0] or 0 + if (self.fts_indexing_left, self.fts_indexing_total) != (nl, nt): + self.fts_indexing_left = nl + self.fts_indexing_total = nt + self.event_dispatcher(EventType.indexing_progress_changed, nl, nt) @write_api def enable_fts(self, enabled=True, start_pool=True): @@ -527,10 +534,13 @@ class Cache: if not self.backend.fts_enabled: return self.fts_job_queue.put(True) + self._update_fts_indexing_numbers() @write_api def commit_fts_result(self, book_id, fmt, fmt_size, fmt_hash, text, err_msg): - return self.backend.commit_fts_result(book_id, fmt, fmt_size, fmt_hash, text, err_msg) + ans = self.backend.commit_fts_result(book_id, fmt, fmt_size, fmt_hash, text, err_msg) + self._update_fts_indexing_numbers() + return ans @api def reindex_fts(self): diff --git a/src/calibre/db/listeners.py b/src/calibre/db/listeners.py index 11cf14912e..20b0c58a54 100644 --- a/src/calibre/db/listeners.py +++ b/src/calibre/db/listeners.py @@ -40,6 +40,9 @@ class EventType(Enum): #: When a book format is edited, with arguments: (book_id, fmt) book_edited = auto() + #: When the indexing progress changes + indexing_progress_changed = auto() + class EventDispatcher(Thread): diff --git a/src/calibre/gui2/fts/scan.py b/src/calibre/gui2/fts/scan.py index a956078e7c..bbe04e4eb8 100644 --- a/src/calibre/gui2/fts/scan.py +++ b/src/calibre/gui2/fts/scan.py @@ -5,13 +5,15 @@ import os from qt.core import ( QCheckBox, QDialog, QDialogButtonBox, QHBoxLayout, QIcon, QLabel, QPushButton, - QRadioButton, QTimer, QVBoxLayout, QWidget, pyqtSignal + QRadioButton, QVBoxLayout, QWidget, pyqtSignal ) from calibre import detect_ncpus from calibre.db.cache import Cache +from calibre.db.listeners import EventType from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.fts.utils import get_db +from calibre.gui2.ui import get_gui class IndexingProgress: @@ -139,11 +141,20 @@ class ScanStatus(QWidget): l.addStretch(10) self.apply_fts_state() self.enable_fts.toggled.connect(self.change_fts_state) - self.indexing_status_timer = t = QTimer(self) - t.timeout.connect(self.update_stats) - t.setInterval(1000) - t.start() self.update_stats() + gui = get_gui() + if gui is None: + self.db.add_listener(self) + else: + gui.add_db_listener(self.gui_update_event) + + def gui_update_event(self, db, event_type, event_data): + if event_type is EventType.indexing_progress_changed: + self.update_stats() + + def __call__(self, event_type, library_id, event_data): + if event_type is EventType.indexing_progress_changed: + self.update_stats() def update_stats(self): changed = self.indexing_progress.update(*self.db.fts_indexing_progress()) @@ -200,10 +211,9 @@ class ScanStatus(QWidget): self.apply_fts_state() def startup(self): - self.indexing_status_timer.start() + pass def shutdown(self): - self.indexing_status_timer.stop() self.scan_progress.slow_button.setChecked(True) self.reset_indexing_state_for_current_db()