mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 00:36:38 -04:00
Add CollectionOpWithBackendProgress
This commit is contained in:
parent
4837e52fe9
commit
2acad4504e
1 changed files with 67 additions and 3 deletions
|
@ -4,10 +4,11 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from concurrent.futures._base import Future
|
from concurrent.futures._base import Future
|
||||||
from typing import Any, Callable, Generic, Protocol, TypeVar, Union
|
from typing import Any, Callable, Generic, Literal, Protocol, TypeVar, Union
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
import aqt.gui_hooks
|
import aqt.gui_hooks
|
||||||
|
import aqt.main
|
||||||
from anki.collection import (
|
from anki.collection import (
|
||||||
Collection,
|
Collection,
|
||||||
OpChanges,
|
OpChanges,
|
||||||
|
@ -16,7 +17,7 @@ from anki.collection import (
|
||||||
OpChangesWithId,
|
OpChangesWithId,
|
||||||
)
|
)
|
||||||
from aqt.errors import show_exception
|
from aqt.errors import show_exception
|
||||||
from aqt.qt import QWidget
|
from aqt.qt import QWidget, QTimer, qconnect
|
||||||
from aqt.utils import showWarning
|
from aqt.utils import showWarning
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,7 +119,15 @@ class CollectionOp(Generic[ResultWithChanges]):
|
||||||
# fire change hooks
|
# fire change hooks
|
||||||
self._fire_change_hooks_after_op_performed(result, initiator)
|
self._fire_change_hooks_after_op_performed(result, initiator)
|
||||||
|
|
||||||
mw.taskman.with_progress(wrapped_op, wrapped_done)
|
self._run(mw, wrapped_op, wrapped_done)
|
||||||
|
|
||||||
|
def _run(
|
||||||
|
self,
|
||||||
|
mw: aqt.main.AnkiQt,
|
||||||
|
op: Callable[[], ResultWithChanges],
|
||||||
|
on_done: Callable[[Future], None],
|
||||||
|
) -> None:
|
||||||
|
mw.taskman.with_progress(op, on_done)
|
||||||
|
|
||||||
def _fire_change_hooks_after_op_performed(
|
def _fire_change_hooks_after_op_performed(
|
||||||
self,
|
self,
|
||||||
|
@ -237,3 +246,58 @@ class QueryOp(Generic[T]):
|
||||||
self._success(future.result())
|
self._success(future.result())
|
||||||
|
|
||||||
mw.taskman.run_in_background(wrapped_op, wrapped_done)
|
mw.taskman.run_in_background(wrapped_op, wrapped_done)
|
||||||
|
|
||||||
|
|
||||||
|
class CollectionOpWithBackendProgress(CollectionOp):
|
||||||
|
"""Periodically queries the backend for progress updates, and enables abortion.
|
||||||
|
|
||||||
|
Requires a key for a string value on the `Progress` proto message."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent: QWidget,
|
||||||
|
op: Callable[[Collection], ResultWithChanges],
|
||||||
|
*,
|
||||||
|
key: Literal["importing"],
|
||||||
|
):
|
||||||
|
self._key = key
|
||||||
|
self.timer = QTimer()
|
||||||
|
self.timer.setSingleShot(False)
|
||||||
|
self.timer.setInterval(100)
|
||||||
|
super().__init__(parent, op)
|
||||||
|
|
||||||
|
def _run(
|
||||||
|
self,
|
||||||
|
mw: aqt.main.AnkiQt,
|
||||||
|
op: Callable[[], ResultWithChanges],
|
||||||
|
on_done: Callable[[Future], None],
|
||||||
|
) -> None:
|
||||||
|
if not (dialog := mw.progress.start(immediate=True)):
|
||||||
|
print("Progress dialog already running; aborting will not work")
|
||||||
|
|
||||||
|
def on_progress() -> None:
|
||||||
|
assert mw
|
||||||
|
|
||||||
|
progress = mw.backend.latest_progress()
|
||||||
|
if not progress.HasField(self._key):
|
||||||
|
return
|
||||||
|
label = getattr(progress, self._key)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if dialog.wantCancel:
|
||||||
|
mw.backend.set_wants_abort()
|
||||||
|
except AttributeError:
|
||||||
|
# dialog may not be active
|
||||||
|
pass
|
||||||
|
|
||||||
|
mw.taskman.run_on_main(lambda: mw.progress.update(label=label))
|
||||||
|
|
||||||
|
def wrapped_on_done(future: Future) -> None:
|
||||||
|
self.timer.deleteLater()
|
||||||
|
assert mw
|
||||||
|
mw.progress.finish()
|
||||||
|
on_done(future)
|
||||||
|
|
||||||
|
qconnect(self.timer.timeout, on_progress)
|
||||||
|
self.timer.start()
|
||||||
|
mw.taskman.run_in_background(task=op, on_done=wrapped_on_done)
|
||||||
|
|
Loading…
Reference in a new issue