diff --git a/qt/aqt/import_export/exporting.py b/qt/aqt/import_export/exporting.py index f02924f42..29f674b65 100644 --- a/qt/aqt/import_export/exporting.py +++ b/qt/aqt/import_export/exporting.py @@ -18,6 +18,7 @@ from anki.notes import NoteId from aqt import gui_hooks from aqt.errors import show_exception from aqt.operations import QueryOp +from aqt.progress import ProgressUpdate from aqt.qt import * from aqt.utils import ( checkInvalidFilename, @@ -195,7 +196,7 @@ class ColpkgExporter(Exporter): options.out_path, include_media=options.include_media, legacy=False ), success=on_success, - ).with_backend_progress(export_progress_label).failure( + ).with_backend_progress(export_progress_update).failure( on_failure ).run_in_background() @@ -223,10 +224,12 @@ class ApkgExporter(Exporter): success=lambda count: tooltip( tr.exporting_note_exported(count=count), parent=mw ), - ).with_backend_progress(export_progress_label).run_in_background() + ).with_backend_progress(export_progress_update).run_in_background() -def export_progress_label(progress: Progress) -> str | None: +def export_progress_update(progress: Progress) -> ProgressUpdate | None: if not progress.HasField("exporting"): return None - return tr.exporting_exported_media_file(count=progress.exporting) + return ProgressUpdate( + label=tr.exporting_exported_media_file(count=progress.exporting) + ) diff --git a/qt/aqt/import_export/importing.py b/qt/aqt/import_export/importing.py index 3260817d7..4ac351acb 100644 --- a/qt/aqt/import_export/importing.py +++ b/qt/aqt/import_export/importing.py @@ -10,6 +10,7 @@ import aqt.main from anki.collection import Collection, ImportLogWithChanges, Progress from anki.errors import Interrupted from aqt.operations import CollectionOp, QueryOp +from aqt.progress import ProgressUpdate from aqt.qt import * from aqt.utils import askUser, getFile, showInfo, showText, showWarning, tooltip, tr @@ -96,7 +97,7 @@ def import_collection_package_op( ) return QueryOp(parent=mw, op=op, success=lambda _: success()).with_backend_progress( - import_progress_label + import_progress_update ) @@ -104,7 +105,7 @@ def import_anki_package(mw: aqt.main.AnkiQt, path: str) -> None: CollectionOp( parent=mw, op=lambda col: col.import_anki_package(path), - ).with_backend_progress(import_progress_label).success( + ).with_backend_progress(import_progress_update).success( show_import_log ).run_in_background() @@ -142,5 +143,7 @@ def stringify_log(log: Any) -> str: ) -def import_progress_label(progress: Progress) -> str | None: - return progress.importing if progress.HasField("importing") else None +def import_progress_update(progress: Progress) -> ProgressUpdate | None: + if progress.HasField("importing"): + return ProgressUpdate(label=progress.importing) + return None diff --git a/qt/aqt/operations/__init__.py b/qt/aqt/operations/__init__.py index 221bc35b2..abf921531 100644 --- a/qt/aqt/operations/__init__.py +++ b/qt/aqt/operations/__init__.py @@ -19,6 +19,7 @@ from anki.collection import ( Progress, ) from aqt.errors import show_exception +from aqt.progress import ProgressUpdate from aqt.qt import QWidget @@ -68,7 +69,7 @@ class CollectionOp(Generic[ResultWithChanges]): _success: Callable[[ResultWithChanges], Any] | None = None _failure: Callable[[Exception], Any] | None = None - _label_from_progress: Callable[[Progress], str | None] | None = None + _progress_update: Callable[[Progress], ProgressUpdate | None] | None = None def __init__(self, parent: QWidget, op: Callable[[Collection], ResultWithChanges]): self._parent = parent @@ -87,9 +88,9 @@ class CollectionOp(Generic[ResultWithChanges]): return self def with_backend_progress( - self, label_from_progress: Callable[[Progress], str | None] | None + self, progress_update: Callable[[Progress], ProgressUpdate | None] | None ) -> CollectionOp[ResultWithChanges]: - self._label_from_progress = label_from_progress + self._progress_update = progress_update return self def run_in_background(self, *, initiator: object | None = None) -> None: @@ -133,9 +134,9 @@ class CollectionOp(Generic[ResultWithChanges]): op: Callable[[], ResultWithChanges], on_done: Callable[[Future], None], ) -> None: - if self._label_from_progress: + if self._progress_update: mw.taskman.with_backend_progress( - op, self._label_from_progress, on_done=on_done, parent=self._parent + op, self._progress_update, on_done=on_done, parent=self._parent ) else: mw.taskman.with_progress(op, on_done, parent=self._parent) @@ -195,7 +196,7 @@ class QueryOp(Generic[T]): _failure: Callable[[Exception], Any] | None = None _progress: bool | str = False - _label_from_progress: Callable[[Progress], str | None] | None = None + _progress_update: Callable[[Progress], ProgressUpdate | None] | None = None def __init__( self, @@ -221,9 +222,9 @@ class QueryOp(Generic[T]): return self def with_backend_progress( - self, label_from_progress: Callable[[Progress], str | None] | None + self, progress_update: Callable[[Progress], ProgressUpdate | None] | None ) -> QueryOp[T]: - self._label_from_progress = label_from_progress + self._progress_update = progress_update return self def run_in_background(self) -> None: @@ -264,10 +265,10 @@ class QueryOp(Generic[T]): on_done: Callable[[Future], None], ) -> None: label = self._progress if isinstance(self._progress, str) else None - if self._label_from_progress: + if self._progress_update: mw.taskman.with_backend_progress( op, - self._label_from_progress, + self._progress_update, on_done=on_done, start_label=label, parent=self._parent, diff --git a/qt/aqt/progress.py b/qt/aqt/progress.py index b0a93830d..7f2c471b8 100644 --- a/qt/aqt/progress.py +++ b/qt/aqt/progress.py @@ -3,6 +3,7 @@ from __future__ import annotations import time +from dataclasses import asdict, dataclass import aqt.forms from anki._legacy import print_deprecation_warning @@ -170,7 +171,7 @@ class ProgressManager: def start_with_backend_updates( self, - label_from_progress: Callable[[Progress], str | None], + progress_update: Callable[[Progress], ProgressUpdate | None], start_label: str | None = None, parent: QWidget | None = None, ) -> None: @@ -185,11 +186,11 @@ class ProgressManager: assert self.mw progress = self.mw.backend.latest_progress() - if not (label := label_from_progress(progress)): + if not (update := progress_update(progress)): return if dialog and dialog.wantCancel: self.mw.backend.set_wants_abort() - self.update(label=label) + self.update(**asdict(update)) qconnect(self._backend_timer.timeout, on_progress) self._backend_timer.start() @@ -326,3 +327,12 @@ class ProgressDialog(QDialog): if evt.key() == Qt.Key.Key_Escape: evt.ignore() self.wantCancel = True + + +@dataclass +class ProgressUpdate: + label: str | None = None + value: int | None = None + process: bool = True + maybeShow: bool = True + max: int | None = None diff --git a/qt/aqt/taskman.py b/qt/aqt/taskman.py index acf34adbc..13d984100 100644 --- a/qt/aqt/taskman.py +++ b/qt/aqt/taskman.py @@ -16,6 +16,7 @@ from typing import Any, Callable import aqt from anki.collection import Progress +from aqt.progress import ProgressUpdate from aqt.qt import * Closure = Callable[[], None] @@ -93,13 +94,13 @@ class TaskManager(QObject): def with_backend_progress( self, task: Callable, - label_from_progress: Callable[[Progress], str | None], + progress_update: Callable[[Progress], ProgressUpdate | None], on_done: Callable[[Future], None] | None = None, parent: QWidget | None = None, start_label: str | None = None, ) -> None: self.mw.progress.start_with_backend_updates( - label_from_progress, + progress_update, parent=parent, start_label=start_label, )