mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
update find&replace, and remove perform_op()
This commit is contained in:
parent
84fe309583
commit
5676ad5101
11 changed files with 108 additions and 191 deletions
|
@ -3,11 +3,13 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import List, Optional, Sequence
|
from typing import List, Sequence
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki.notes import NoteId
|
from anki.notes import NoteId
|
||||||
from aqt import AnkiQt, QWidget
|
from aqt import AnkiQt, QWidget
|
||||||
|
from aqt.operations.note import find_and_replace
|
||||||
|
from aqt.operations.tag import find_and_replace_tag
|
||||||
from aqt.qt import QDialog, Qt
|
from aqt.qt import QDialog, Qt
|
||||||
from aqt.utils import (
|
from aqt.utils import (
|
||||||
HelpPage,
|
HelpPage,
|
||||||
|
@ -22,63 +24,10 @@ from aqt.utils import (
|
||||||
save_combo_index_for_session,
|
save_combo_index_for_session,
|
||||||
save_is_checked,
|
save_is_checked,
|
||||||
saveGeom,
|
saveGeom,
|
||||||
tooltip,
|
|
||||||
tr,
|
tr,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def find_and_replace(
|
|
||||||
*,
|
|
||||||
mw: AnkiQt,
|
|
||||||
parent: QWidget,
|
|
||||||
note_ids: Sequence[NoteId],
|
|
||||||
search: str,
|
|
||||||
replacement: str,
|
|
||||||
regex: bool,
|
|
||||||
field_name: Optional[str],
|
|
||||||
match_case: bool,
|
|
||||||
) -> None:
|
|
||||||
mw.perform_op(
|
|
||||||
lambda: mw.col.find_and_replace(
|
|
||||||
note_ids=note_ids,
|
|
||||||
search=search,
|
|
||||||
replacement=replacement,
|
|
||||||
regex=regex,
|
|
||||||
field_name=field_name,
|
|
||||||
match_case=match_case,
|
|
||||||
),
|
|
||||||
success=lambda out: tooltip(
|
|
||||||
tr.findreplace_notes_updated(changed=out.count, total=len(note_ids)),
|
|
||||||
parent=parent,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def find_and_replace_tag(
|
|
||||||
*,
|
|
||||||
mw: AnkiQt,
|
|
||||||
parent: QWidget,
|
|
||||||
note_ids: Sequence[int],
|
|
||||||
search: str,
|
|
||||||
replacement: str,
|
|
||||||
regex: bool,
|
|
||||||
match_case: bool,
|
|
||||||
) -> None:
|
|
||||||
mw.perform_op(
|
|
||||||
lambda: mw.col.tags.find_and_replace(
|
|
||||||
note_ids=note_ids,
|
|
||||||
search=search,
|
|
||||||
replacement=replacement,
|
|
||||||
regex=regex,
|
|
||||||
match_case=match_case,
|
|
||||||
),
|
|
||||||
success=lambda out: tooltip(
|
|
||||||
tr.findreplace_notes_updated(changed=out.count, total=len(note_ids)),
|
|
||||||
parent=parent,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class FindAndReplaceDialog(QDialog):
|
class FindAndReplaceDialog(QDialog):
|
||||||
COMBO_NAME = "BrowserFindAndReplace"
|
COMBO_NAME = "BrowserFindAndReplace"
|
||||||
|
|
||||||
|
@ -146,10 +95,9 @@ class FindAndReplaceDialog(QDialog):
|
||||||
save_is_checked(self.form.re, self.COMBO_NAME + "Regex")
|
save_is_checked(self.form.re, self.COMBO_NAME + "Regex")
|
||||||
save_is_checked(self.form.ignoreCase, self.COMBO_NAME + "ignoreCase")
|
save_is_checked(self.form.ignoreCase, self.COMBO_NAME + "ignoreCase")
|
||||||
|
|
||||||
|
# tags?
|
||||||
if self.form.field.currentIndex() == 1:
|
if self.form.field.currentIndex() == 1:
|
||||||
# tags
|
|
||||||
find_and_replace_tag(
|
find_and_replace_tag(
|
||||||
mw=self.mw,
|
|
||||||
parent=self.parentWidget(),
|
parent=self.parentWidget(),
|
||||||
note_ids=self.note_ids,
|
note_ids=self.note_ids,
|
||||||
search=search,
|
search=search,
|
||||||
|
@ -157,15 +105,14 @@ class FindAndReplaceDialog(QDialog):
|
||||||
regex=regex,
|
regex=regex,
|
||||||
match_case=match_case,
|
match_case=match_case,
|
||||||
)
|
)
|
||||||
return
|
else:
|
||||||
|
# fields
|
||||||
if self.form.field.currentIndex() == 0:
|
if self.form.field.currentIndex() == 0:
|
||||||
field = None
|
field = None
|
||||||
else:
|
else:
|
||||||
field = self.field_names[self.form.field.currentIndex() - 2]
|
field = self.field_names[self.form.field.currentIndex() - 2]
|
||||||
|
|
||||||
find_and_replace(
|
find_and_replace(
|
||||||
mw=self.mw,
|
|
||||||
parent=self.parentWidget(),
|
parent=self.parentWidget(),
|
||||||
note_ids=self.note_ids,
|
note_ids=self.note_ids,
|
||||||
search=search,
|
search=search,
|
||||||
|
|
|
@ -52,11 +52,6 @@ from aqt.emptycards import show_empty_cards
|
||||||
from aqt.legacy import install_pylib_legacy
|
from aqt.legacy import install_pylib_legacy
|
||||||
from aqt.mediacheck import check_media_db
|
from aqt.mediacheck import check_media_db
|
||||||
from aqt.mediasync import MediaSyncer
|
from aqt.mediasync import MediaSyncer
|
||||||
from aqt.operations import (
|
|
||||||
CollectionOpFailureCallback,
|
|
||||||
CollectionOpSuccessCallback,
|
|
||||||
ResultWithChanges,
|
|
||||||
)
|
|
||||||
from aqt.operations.collection import undo
|
from aqt.operations.collection import undo
|
||||||
from aqt.profiles import ProfileManager as ProfileManagerType
|
from aqt.profiles import ProfileManager as ProfileManagerType
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
|
@ -96,9 +91,6 @@ MainWindowState = Literal[
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
PerformOpOptionalSuccessCallback = Optional[CollectionOpSuccessCallback]
|
|
||||||
PerformOpOptionalFailureCallback = Optional[CollectionOpFailureCallback]
|
|
||||||
|
|
||||||
|
|
||||||
class AnkiQt(QMainWindow):
|
class AnkiQt(QMainWindow):
|
||||||
col: Collection
|
col: Collection
|
||||||
|
@ -710,10 +702,9 @@ class AnkiQt(QMainWindow):
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Run an operation that queries the DB on a background thread.
|
"""Run an operation that queries the DB on a background thread.
|
||||||
|
|
||||||
Similar interface to perform_op(), but intended to be used for operations
|
Intended to be used for operations that do not change collection
|
||||||
that do not change collection state. Undo status will not be changed,
|
state. Undo status will not be changed, and `operation_did_execute`
|
||||||
and `operation_did_execute` will not fire. No progress window will
|
will not fire. No progress window will be shown either.
|
||||||
be shown either.
|
|
||||||
|
|
||||||
`operations_will|did_execute` will still fire, so the UI can defer
|
`operations_will|did_execute` will still fire, so the UI can defer
|
||||||
updates during a background task.
|
updates during a background task.
|
||||||
|
@ -743,66 +734,6 @@ class AnkiQt(QMainWindow):
|
||||||
# Resetting state
|
# Resetting state
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def perform_op(
|
|
||||||
self,
|
|
||||||
op: Callable[[], ResultWithChanges],
|
|
||||||
*,
|
|
||||||
success: PerformOpOptionalSuccessCallback = None,
|
|
||||||
failure: PerformOpOptionalFailureCallback = None,
|
|
||||||
handler: Optional[object] = None,
|
|
||||||
) -> None:
|
|
||||||
"""Run the provided operation on a background thread.
|
|
||||||
|
|
||||||
op() should either return OpChanges, or an object with a 'changes'
|
|
||||||
property. The changes will be passed to `operation_did_execute` so that
|
|
||||||
the UI can decide whether it needs to update itself.
|
|
||||||
|
|
||||||
- Shows progress popup for the duration of the op.
|
|
||||||
- Ensures the browser doesn't try to redraw during the operation, which can lead
|
|
||||||
to a frozen UI
|
|
||||||
- Updates undo state at the end of the operation
|
|
||||||
- Commits changes
|
|
||||||
- Fires the `operation_(will|did)_reset` hooks
|
|
||||||
- Fires the legacy `state_did_reset` hook
|
|
||||||
|
|
||||||
Be careful not to call any UI routines in `op`, as that may crash Qt.
|
|
||||||
This includes things select .selectedCards() in the browse screen.
|
|
||||||
|
|
||||||
success() will be called with the return value of op().
|
|
||||||
|
|
||||||
If op() throws an exception, it will be shown in a popup, or
|
|
||||||
passed to failure() if it is provided.
|
|
||||||
"""
|
|
||||||
|
|
||||||
self._increase_background_ops()
|
|
||||||
|
|
||||||
def wrapped_done(future: Future) -> None:
|
|
||||||
self._decrease_background_ops()
|
|
||||||
# did something go wrong?
|
|
||||||
if exception := future.exception():
|
|
||||||
if isinstance(exception, Exception):
|
|
||||||
if failure:
|
|
||||||
failure(exception)
|
|
||||||
else:
|
|
||||||
showWarning(str(exception))
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
# BaseException like SystemExit; rethrow it
|
|
||||||
future.result()
|
|
||||||
|
|
||||||
result = future.result()
|
|
||||||
try:
|
|
||||||
if success:
|
|
||||||
success(result)
|
|
||||||
finally:
|
|
||||||
# update undo status
|
|
||||||
status = self.col.undo_status()
|
|
||||||
self._update_undo_actions_for_status_and_save(status)
|
|
||||||
# fire change hooks
|
|
||||||
self._fire_change_hooks_after_op_performed(result, handler)
|
|
||||||
|
|
||||||
self.taskman.with_progress(op, wrapped_done)
|
|
||||||
|
|
||||||
def _increase_background_ops(self) -> None:
|
def _increase_background_ops(self) -> None:
|
||||||
if not self._background_op_count:
|
if not self._background_op_count:
|
||||||
gui_hooks.backend_will_block()
|
gui_hooks.backend_will_block()
|
||||||
|
@ -814,24 +745,6 @@ class AnkiQt(QMainWindow):
|
||||||
gui_hooks.backend_did_block()
|
gui_hooks.backend_did_block()
|
||||||
assert self._background_op_count >= 0
|
assert self._background_op_count >= 0
|
||||||
|
|
||||||
def _fire_change_hooks_after_op_performed(
|
|
||||||
self,
|
|
||||||
result: ResultWithChanges,
|
|
||||||
handler: Optional[object],
|
|
||||||
) -> None:
|
|
||||||
if isinstance(result, OpChanges):
|
|
||||||
changes = result
|
|
||||||
else:
|
|
||||||
changes = result.changes
|
|
||||||
|
|
||||||
# fire new hook
|
|
||||||
print("op changes:")
|
|
||||||
print(changes)
|
|
||||||
gui_hooks.operation_did_execute(changes, handler)
|
|
||||||
# fire legacy hook so old code notices changes
|
|
||||||
if self.col.op_made_changes(changes):
|
|
||||||
gui_hooks.state_did_reset()
|
|
||||||
|
|
||||||
def _synthesize_op_did_execute_from_reset(self) -> None:
|
def _synthesize_op_did_execute_from_reset(self) -> None:
|
||||||
"""Fire the `operation_did_execute` hook with everything marked as changed,
|
"""Fire the `operation_did_execute` hook with everything marked as changed,
|
||||||
after legacy code has called .reset()"""
|
after legacy code has called .reset()"""
|
||||||
|
@ -879,7 +792,7 @@ class AnkiQt(QMainWindow):
|
||||||
def reset(self, unused_arg: bool = False) -> None:
|
def reset(self, unused_arg: bool = False) -> None:
|
||||||
"""Legacy method of telling UI to refresh after changes made to DB.
|
"""Legacy method of telling UI to refresh after changes made to DB.
|
||||||
|
|
||||||
New code should use mw.perform_op() instead."""
|
New code should use CollectionOp() instead."""
|
||||||
if self.col:
|
if self.col:
|
||||||
# fire new `operation_did_execute` hook first. If the overview
|
# fire new `operation_did_execute` hook first. If the overview
|
||||||
# or review screen are currently open, they will rebuild the study
|
# or review screen are currently open, they will rebuild the study
|
||||||
|
|
|
@ -36,9 +36,6 @@ ResultWithChanges = TypeVar(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
CollectionOpSuccessCallback = Callable[[ResultWithChanges], Any]
|
|
||||||
CollectionOpFailureCallback = Optional[Callable[[Exception], Any]]
|
|
||||||
|
|
||||||
|
|
||||||
class CollectionOp(Generic[ResultWithChanges]):
|
class CollectionOp(Generic[ResultWithChanges]):
|
||||||
"""Helper to perform a mutating DB operation on a background thread, and update UI.
|
"""Helper to perform a mutating DB operation on a background thread, and update UI.
|
||||||
|
@ -65,7 +62,7 @@ class CollectionOp(Generic[ResultWithChanges]):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_success: Optional[Callable[[ResultWithChanges], Any]] = None
|
_success: Optional[Callable[[ResultWithChanges], Any]] = None
|
||||||
_failure: Optional[CollectionOpFailureCallback] = None
|
_failure: Optional[Optional[Callable[[Exception], Any]]] = None
|
||||||
|
|
||||||
def __init__(self, parent: QWidget, op: Callable[[Collection], ResultWithChanges]):
|
def __init__(self, parent: QWidget, op: Callable[[Collection], ResultWithChanges]):
|
||||||
self._parent = parent
|
self._parent = parent
|
||||||
|
@ -78,19 +75,25 @@ class CollectionOp(Generic[ResultWithChanges]):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def failure(
|
def failure(
|
||||||
self, failure: Optional[CollectionOpFailureCallback]
|
self, failure: Optional[Optional[Callable[[Exception], Any]]]
|
||||||
) -> CollectionOp[ResultWithChanges]:
|
) -> CollectionOp[ResultWithChanges]:
|
||||||
self._failure = failure
|
self._failure = failure
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def run_in_background(self, *, initiator: Optional[object] = None) -> None:
|
def run_in_background(self, *, initiator: Optional[object] = None) -> None:
|
||||||
aqt.mw._increase_background_ops()
|
from aqt import mw
|
||||||
|
|
||||||
|
assert mw
|
||||||
|
|
||||||
|
mw._increase_background_ops()
|
||||||
|
|
||||||
def wrapped_op() -> ResultWithChanges:
|
def wrapped_op() -> ResultWithChanges:
|
||||||
return self._op(aqt.mw.col)
|
assert mw
|
||||||
|
return self._op(mw.col)
|
||||||
|
|
||||||
def wrapped_done(future: Future) -> None:
|
def wrapped_done(future: Future) -> None:
|
||||||
aqt.mw._decrease_background_ops()
|
assert mw
|
||||||
|
mw._decrease_background_ops()
|
||||||
# did something go wrong?
|
# did something go wrong?
|
||||||
if exception := future.exception():
|
if exception := future.exception():
|
||||||
if isinstance(exception, Exception):
|
if isinstance(exception, Exception):
|
||||||
|
@ -109,18 +112,22 @@ class CollectionOp(Generic[ResultWithChanges]):
|
||||||
self._success(result)
|
self._success(result)
|
||||||
finally:
|
finally:
|
||||||
# update undo status
|
# update undo status
|
||||||
status = aqt.mw.col.undo_status()
|
status = mw.col.undo_status()
|
||||||
aqt.mw._update_undo_actions_for_status_and_save(status)
|
mw._update_undo_actions_for_status_and_save(status)
|
||||||
# fire change hooks
|
# fire change hooks
|
||||||
self._fire_change_hooks_after_op_performed(result, initiator)
|
self._fire_change_hooks_after_op_performed(result, initiator)
|
||||||
|
|
||||||
aqt.mw.taskman.with_progress(wrapped_op, wrapped_done)
|
mw.taskman.with_progress(wrapped_op, wrapped_done)
|
||||||
|
|
||||||
def _fire_change_hooks_after_op_performed(
|
def _fire_change_hooks_after_op_performed(
|
||||||
self,
|
self,
|
||||||
result: ResultWithChanges,
|
result: ResultWithChanges,
|
||||||
handler: Optional[object],
|
handler: Optional[object],
|
||||||
) -> None:
|
) -> None:
|
||||||
|
from aqt import mw
|
||||||
|
|
||||||
|
assert mw
|
||||||
|
|
||||||
if isinstance(result, OpChanges):
|
if isinstance(result, OpChanges):
|
||||||
changes = result
|
changes = result
|
||||||
else:
|
else:
|
||||||
|
@ -131,5 +138,5 @@ class CollectionOp(Generic[ResultWithChanges]):
|
||||||
print(changes)
|
print(changes)
|
||||||
aqt.gui_hooks.operation_did_execute(changes, handler)
|
aqt.gui_hooks.operation_did_execute(changes, handler)
|
||||||
# fire legacy hook so old code notices changes
|
# fire legacy hook so old code notices changes
|
||||||
if aqt.mw.col.op_made_changes(changes):
|
if mw.col.op_made_changes(changes):
|
||||||
aqt.gui_hooks.state_did_reset()
|
aqt.gui_hooks.state_did_reset()
|
||||||
|
|
|
@ -31,6 +31,9 @@ def undo(*, parent: QWidget) -> None:
|
||||||
def _legacy_undo(*, parent: QWidget) -> None:
|
def _legacy_undo(*, parent: QWidget) -> None:
|
||||||
from aqt import mw
|
from aqt import mw
|
||||||
|
|
||||||
|
assert mw
|
||||||
|
assert mw.col
|
||||||
|
|
||||||
reviewing = mw.state == "review"
|
reviewing = mw.state == "review"
|
||||||
just_refresh_reviewer = False
|
just_refresh_reviewer = False
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Sequence
|
from typing import Optional, Sequence
|
||||||
|
|
||||||
from anki.collection import OpChanges, OpChangesWithCount
|
from anki.collection import OpChanges, OpChangesWithCount
|
||||||
from anki.decks import DeckId
|
from anki.decks import DeckId
|
||||||
|
@ -34,3 +34,31 @@ def remove_notes(
|
||||||
return CollectionOp(parent, lambda col: col.remove_notes(note_ids)).success(
|
return CollectionOp(parent, lambda col: col.remove_notes(note_ids)).success(
|
||||||
lambda out: tooltip(tr.browsing_cards_deleted(count=out.count)),
|
lambda out: tooltip(tr.browsing_cards_deleted(count=out.count)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def find_and_replace(
|
||||||
|
*,
|
||||||
|
parent: QWidget,
|
||||||
|
note_ids: Sequence[NoteId],
|
||||||
|
search: str,
|
||||||
|
replacement: str,
|
||||||
|
regex: bool,
|
||||||
|
field_name: Optional[str],
|
||||||
|
match_case: bool,
|
||||||
|
) -> CollectionOp[OpChangesWithCount]:
|
||||||
|
return CollectionOp(
|
||||||
|
parent,
|
||||||
|
lambda col: col.find_and_replace(
|
||||||
|
note_ids=note_ids,
|
||||||
|
search=search,
|
||||||
|
replacement=replacement,
|
||||||
|
regex=regex,
|
||||||
|
field_name=field_name,
|
||||||
|
match_case=match_case,
|
||||||
|
),
|
||||||
|
).success(
|
||||||
|
lambda out: tooltip(
|
||||||
|
tr.findreplace_notes_updated(changed=out.count, total=len(note_ids)),
|
||||||
|
parent=parent,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
|
@ -28,6 +28,7 @@ def set_due_date_dialog(
|
||||||
card_ids: Sequence[CardId],
|
card_ids: Sequence[CardId],
|
||||||
config_key: Optional[Config.String.Key.V],
|
config_key: Optional[Config.String.Key.V],
|
||||||
) -> Optional[CollectionOp[OpChanges]]:
|
) -> Optional[CollectionOp[OpChanges]]:
|
||||||
|
assert aqt.mw
|
||||||
if not card_ids:
|
if not card_ids:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -76,7 +77,9 @@ def reposition_new_cards_dialog(
|
||||||
) -> Optional[CollectionOp[OpChangesWithCount]]:
|
) -> Optional[CollectionOp[OpChangesWithCount]]:
|
||||||
from aqt import mw
|
from aqt import mw
|
||||||
|
|
||||||
|
assert mw
|
||||||
assert mw.col.db
|
assert mw.col.db
|
||||||
|
|
||||||
row = mw.col.db.first(
|
row = mw.col.db.first(
|
||||||
f"select min(due), max(due) from cards where type={CARD_TYPE_NEW} and odid=0"
|
f"select min(due), max(due) from cards where type={CARD_TYPE_NEW} and odid=0"
|
||||||
)
|
)
|
||||||
|
|
|
@ -90,3 +90,29 @@ def set_tag_collapsed(
|
||||||
return CollectionOp(
|
return CollectionOp(
|
||||||
parent, lambda col: col.tags.set_collapsed(tag=tag, collapsed=collapsed)
|
parent, lambda col: col.tags.set_collapsed(tag=tag, collapsed=collapsed)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def find_and_replace_tag(
|
||||||
|
*,
|
||||||
|
parent: QWidget,
|
||||||
|
note_ids: Sequence[int],
|
||||||
|
search: str,
|
||||||
|
replacement: str,
|
||||||
|
regex: bool,
|
||||||
|
match_case: bool,
|
||||||
|
) -> CollectionOp[OpChangesWithCount]:
|
||||||
|
return CollectionOp(
|
||||||
|
parent,
|
||||||
|
lambda col: col.tags.find_and_replace(
|
||||||
|
note_ids=note_ids,
|
||||||
|
search=search,
|
||||||
|
replacement=replacement,
|
||||||
|
regex=regex,
|
||||||
|
match_case=match_case,
|
||||||
|
),
|
||||||
|
).success(
|
||||||
|
lambda out: tooltip(
|
||||||
|
tr.findreplace_notes_updated(changed=out.count, total=len(note_ids)),
|
||||||
|
parent=parent,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"""
|
"""
|
||||||
Helper for running tasks on background threads.
|
Helper for running tasks on background threads.
|
||||||
|
|
||||||
See mw.query_op() and mw.perform_op() for slightly higher-level routines.
|
See mw.query_op() and CollectionOp() for higher-level routines.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
12
qt/mypy.ini
12
qt/mypy.ini
|
@ -9,17 +9,7 @@ check_untyped_defs = true
|
||||||
disallow_untyped_defs = True
|
disallow_untyped_defs = True
|
||||||
strict_equality = true
|
strict_equality = true
|
||||||
|
|
||||||
[mypy-aqt.scheduling_ops]
|
[mypy-aqt.operations.*]
|
||||||
no_strict_optional = false
|
|
||||||
[mypy-aqt.note_ops]
|
|
||||||
no_strict_optional = false
|
|
||||||
[mypy-aqt.card_ops]
|
|
||||||
no_strict_optional = false
|
|
||||||
[mypy-aqt.deck_ops]
|
|
||||||
no_strict_optional = false
|
|
||||||
[mypy-aqt.find_and_replace]
|
|
||||||
no_strict_optional = false
|
|
||||||
[mypy-aqt.tag_ops]
|
|
||||||
no_strict_optional = false
|
no_strict_optional = false
|
||||||
|
|
||||||
[mypy-aqt.winpaths]
|
[mypy-aqt.winpaths]
|
||||||
|
|
|
@ -451,7 +451,7 @@ hooks = [
|
||||||
Hook(
|
Hook(
|
||||||
name="state_did_reset",
|
name="state_did_reset",
|
||||||
legacy_hook="reset",
|
legacy_hook="reset",
|
||||||
doc="""Legacy 'reset' hook. Called by mw.reset() and mw.perform_op() to redraw the UI.
|
doc="""Legacy 'reset' hook. Called by mw.reset() and CollectionOp() to redraw the UI.
|
||||||
|
|
||||||
New code should use `operation_did_execute` instead.
|
New code should use `operation_did_execute` instead.
|
||||||
""",
|
""",
|
||||||
|
@ -476,7 +476,7 @@ hooks = [
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="backend_will_block",
|
name="backend_will_block",
|
||||||
doc="""Called before one or more operations are executed with mw.perform_op().
|
doc="""Called before one or more DB tasks are run in the background.
|
||||||
|
|
||||||
Subscribers can use this to set a flag to avoid DB queries until the operation
|
Subscribers can use this to set a flag to avoid DB queries until the operation
|
||||||
completes, as doing so will freeze the UI until the long-running operation
|
completes, as doing so will freeze the UI until the long-running operation
|
||||||
|
@ -485,7 +485,7 @@ hooks = [
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="backend_did_block",
|
name="backend_did_block",
|
||||||
doc="""Called after one or more operations are executed with mw.perform_op().
|
doc="""Called after one or more DB tasks finish running in the background.
|
||||||
Called regardless of the success of individual operations, and only called when
|
Called regardless of the success of individual operations, and only called when
|
||||||
there are no outstanding ops.
|
there are no outstanding ops.
|
||||||
""",
|
""",
|
||||||
|
|
|
@ -163,7 +163,7 @@ impl From<String> for Variable {
|
||||||
let kind = match name.as_str() {
|
let kind = match name.as_str() {
|
||||||
"cards" | "notes" | "count" | "amount" | "reviews" | "total" | "selected"
|
"cards" | "notes" | "count" | "amount" | "reviews" | "total" | "selected"
|
||||||
| "kilobytes" | "daysStart" | "daysEnd" | "days" | "secs-per-card" | "remaining"
|
| "kilobytes" | "daysStart" | "daysEnd" | "days" | "secs-per-card" | "remaining"
|
||||||
| "hourStart" | "hourEnd" | "correct" | "decks" => VariableKind::Int,
|
| "hourStart" | "hourEnd" | "correct" | "decks" | "changed" => VariableKind::Int,
|
||||||
"average-seconds" | "cards-per-minute" => VariableKind::Float,
|
"average-seconds" | "cards-per-minute" => VariableKind::Float,
|
||||||
"val" | "found" | "expected" | "part" | "percent" | "day" | "number" | "up"
|
"val" | "found" | "expected" | "part" | "percent" | "day" | "number" | "up"
|
||||||
| "down" | "seconds" | "megs" => VariableKind::Any,
|
| "down" | "seconds" | "megs" => VariableKind::Any,
|
||||||
|
|
Loading…
Reference in a new issue