migrate more ops to CollectionOp

This commit is contained in:
Damien Elmes 2021-04-06 14:36:13 +10:00
parent 27c032a158
commit bc78b6ef17
11 changed files with 111 additions and 116 deletions

View file

@ -677,7 +677,7 @@ where id in %s"""
return return
did = self.col.decks.id(ret.name) did = self.col.decks.id(ret.name)
set_card_deck(mw=self.mw, card_ids=cids, deck_id=did) set_card_deck(parent=self, card_ids=cids, deck_id=did).run_in_background()
# legacy # legacy
@ -696,7 +696,7 @@ where id in %s"""
return return
add_tags_to_notes( add_tags_to_notes(
parent=self, note_ids=self.selected_notes(), space_separated_tags=tags parent=self, note_ids=self.selected_notes(), space_separated_tags=tags
).run(handler=self) ).run_in_background(initiator=self)
@ensure_editor_saved_on_trigger @ensure_editor_saved_on_trigger
def remove_tags_from_selected_notes(self, tags: Optional[str] = None) -> None: def remove_tags_from_selected_notes(self, tags: Optional[str] = None) -> None:
@ -708,7 +708,7 @@ where id in %s"""
remove_tags_from_notes( remove_tags_from_notes(
parent=self, note_ids=self.selected_notes(), space_separated_tags=tags parent=self, note_ids=self.selected_notes(), space_separated_tags=tags
).run(handler=self) ).run_in_background(initiator=self)
def _prompt_for_tags(self, prompt: str) -> Optional[str]: def _prompt_for_tags(self, prompt: str) -> Optional[str]:
(tags, ok) = getTag(self, self.col, prompt) (tags, ok) = getTag(self, self.col, prompt)
@ -719,7 +719,7 @@ where id in %s"""
@ensure_editor_saved_on_trigger @ensure_editor_saved_on_trigger
def clear_unused_tags(self) -> None: def clear_unused_tags(self) -> None:
clear_unused_tags(parent=self).run() clear_unused_tags(parent=self).run_in_background()
addTags = add_tags_to_selected_notes addTags = add_tags_to_selected_notes
deleteTags = remove_tags_from_selected_notes deleteTags = remove_tags_from_selected_notes
@ -760,7 +760,9 @@ where id in %s"""
if flag == self.card.user_flag(): if flag == self.card.user_flag():
flag = 0 flag = 0
set_card_flag(mw=self.mw, card_ids=self.selected_cards(), flag=flag) set_card_flag(
parent=self, card_ids=self.selected_cards(), flag=flag
).run_in_background()
def _update_flags_menu(self) -> None: def _update_flags_menu(self) -> None:
flag = self.card and self.card.user_flag() flag = self.card and self.card.user_flag()
@ -859,7 +861,7 @@ where id in %s"""
###################################################################### ######################################################################
def undo(self) -> None: def undo(self) -> None:
undo(mw=self.mw, parent=self) undo(parent=self)
def onUndoState(self, on: bool) -> None: def onUndoState(self, on: bool) -> None:
self.form.actionUndo.setEnabled(on) self.form.actionUndo.setEnabled(on)

View file

@ -278,7 +278,9 @@ class DeckBrowser:
if not new_name or new_name == deck.name: if not new_name or new_name == deck.name:
return return
else: else:
rename_deck(mw=self.mw, deck_id=did, new_name=new_name) rename_deck(
parent=self.mw, deck_id=did, new_name=new_name
).run_in_background()
self.mw.query_op(lambda: self.mw.col.get_deck(did), success=prompt) self.mw.query_op(lambda: self.mw.col.get_deck(did), success=prompt)
@ -293,18 +295,20 @@ class DeckBrowser:
if node: if node:
node.collapsed = not node.collapsed node.collapsed = not node.collapsed
set_deck_collapsed( set_deck_collapsed(
mw=self.mw, parent=self.mw,
deck_id=did, deck_id=did,
collapsed=node.collapsed, collapsed=node.collapsed,
scope=DeckCollapseScope.REVIEWER, scope=DeckCollapseScope.REVIEWER,
) ).run_in_background()
self._renderPage(reuse=True) self._renderPage(reuse=True)
def _handle_drag_and_drop(self, source: DeckId, target: DeckId) -> None: def _handle_drag_and_drop(self, source: DeckId, target: DeckId) -> None:
reparent_decks(mw=self.mw, parent=self.mw, deck_ids=[source], new_parent=target) reparent_decks(
parent=self.mw, deck_ids=[source], new_parent=target
).run_in_background()
def _delete(self, did: DeckId) -> None: def _delete(self, did: DeckId) -> None:
remove_decks(mw=self.mw, parent=self.mw, deck_ids=[did]) remove_decks(parent=self.mw, deck_ids=[did]).run_in_background()
# Top buttons # Top buttons
###################################################################### ######################################################################
@ -335,7 +339,8 @@ class DeckBrowser:
openLink(f"{aqt.appShared}decks/") openLink(f"{aqt.appShared}decks/")
def _on_create(self) -> None: def _on_create(self) -> None:
add_deck_dialog(mw=self.mw, parent=self.mw) if op := add_deck_dialog(parent=self.mw):
op.run_in_background()
###################################################################### ######################################################################

View file

@ -21,7 +21,6 @@ from typing import (
List, List,
Literal, Literal,
Optional, Optional,
Protocol,
Sequence, Sequence,
TextIO, TextIO,
Tuple, Tuple,
@ -40,15 +39,7 @@ import aqt.toolbar
import aqt.webview import aqt.webview
from anki import hooks from anki import hooks
from anki._backend import RustBackend as _RustBackend from anki._backend import RustBackend as _RustBackend
from anki.collection import ( from anki.collection import Collection, Config, OpChanges, UndoStatus
Collection,
Config,
OpChanges,
OpChangesAfterUndo,
OpChangesWithCount,
OpChangesWithId,
UndoStatus,
)
from anki.decks import DeckDict, DeckId from anki.decks import DeckDict, DeckId
from anki.hooks import runHook from anki.hooks import runHook
from anki.notes import NoteId from anki.notes import NoteId
@ -1198,7 +1189,7 @@ title="%s" %s>%s</button>""" % (
def undo(self) -> None: def undo(self) -> None:
"Call collection_ops.py:undo() directly instead." "Call collection_ops.py:undo() directly instead."
undo(mw=self, parent=self) undo(parent=self)
def update_undo_actions(self, status: Optional[UndoStatus] = None) -> None: def update_undo_actions(self, status: Optional[UndoStatus] = None) -> None:
"""Update menu text and enable/disable menu item as appropriate. """Update menu text and enable/disable menu item as appropriate.

View file

@ -77,11 +77,13 @@ class CollectionOp(Generic[ResultWithChanges]):
self._success = success self._success = success
return self return self
def failure(self, failure: Optional[CollectionOpFailureCallback]) -> CollectionOp[ResultWithChanges]: def failure(
self, failure: Optional[CollectionOpFailureCallback]
) -> CollectionOp[ResultWithChanges]:
self._failure = failure self._failure = failure
return self return self
def run(self, *, handler: Optional[object] = None) -> None: def run_in_background(self, *, initiator: Optional[object] = None) -> None:
aqt.mw._increase_background_ops() aqt.mw._increase_background_ops()
def wrapped_op() -> ResultWithChanges: def wrapped_op() -> ResultWithChanges:
@ -110,7 +112,7 @@ class CollectionOp(Generic[ResultWithChanges]):
status = aqt.mw.col.undo_status() status = aqt.mw.col.undo_status()
aqt.mw._update_undo_actions_for_status_and_save(status) aqt.mw._update_undo_actions_for_status_and_save(status)
# fire change hooks # fire change hooks
self._fire_change_hooks_after_op_performed(result, handler) self._fire_change_hooks_after_op_performed(result, initiator)
aqt.mw.taskman.with_progress(wrapped_op, wrapped_done) aqt.mw.taskman.with_progress(wrapped_op, wrapped_done)

View file

@ -3,28 +3,25 @@
from __future__ import annotations from __future__ import annotations
from typing import Optional, Sequence from typing import Sequence
from anki.cards import CardId from anki.cards import CardId
from anki.collection import OpChanges
from anki.decks import DeckId from anki.decks import DeckId
from aqt import AnkiQt from aqt.operations import CollectionOp
from aqt.main import PerformOpOptionalSuccessCallback from aqt.qt import QWidget
def set_card_deck(*, mw: AnkiQt, card_ids: Sequence[CardId], deck_id: DeckId) -> None: def set_card_deck(
mw.perform_op(lambda: mw.col.set_deck(card_ids, deck_id)) *, parent: QWidget, card_ids: Sequence[CardId], deck_id: DeckId
) -> CollectionOp[OpChanges]:
return CollectionOp(parent, lambda col: col.set_deck(card_ids, deck_id))
def set_card_flag( def set_card_flag(
*, *,
mw: AnkiQt, parent: QWidget,
card_ids: Sequence[CardId], card_ids: Sequence[CardId],
flag: int, flag: int,
handler: Optional[object] = None, ) -> CollectionOp[OpChanges]:
success: PerformOpOptionalSuccessCallback = None, return CollectionOp(parent, lambda col: col.set_user_flag_for_cards(flag, card_ids))
) -> None:
mw.perform_op(
lambda: mw.col.set_user_flag_for_cards(flag, card_ids),
handler=handler,
success=success,
)

View file

@ -3,34 +3,34 @@
from __future__ import annotations from __future__ import annotations
import aqt from anki.collection import LegacyCheckpoint, LegacyReviewUndo
from anki.collection import LegacyCheckpoint, LegacyReviewUndo, OpChangesAfterUndo
from anki.errors import UndoEmpty from anki.errors import UndoEmpty
from anki.types import assert_exhaustive from anki.types import assert_exhaustive
from aqt import gui_hooks from aqt import gui_hooks
from aqt.operations import CollectionOp
from aqt.qt import QWidget from aqt.qt import QWidget
from aqt.utils import showInfo, showWarning, tooltip, tr from aqt.utils import showInfo, showWarning, tooltip, tr
def undo(*, mw: aqt.AnkiQt, parent: QWidget) -> None: def undo(*, parent: QWidget) -> None:
"Undo the last operation, and refresh the UI." "Undo the last operation, and refresh the UI."
def on_success(out: OpChangesAfterUndo) -> None:
mw.update_undo_actions(out.new_status)
tooltip(tr.undo_action_undone(action=out.operation), parent=parent)
def on_failure(exc: Exception) -> None: def on_failure(exc: Exception) -> None:
if isinstance(exc, UndoEmpty): if isinstance(exc, UndoEmpty):
# backend has no undo, but there may be a checkpoint # backend has no undo, but there may be a checkpoint
# or v1/v2 review waiting # or v1/v2 review waiting
_legacy_undo(mw=mw, parent=parent) _legacy_undo(parent=parent)
else: else:
showWarning(str(exc), parent=parent) showWarning(str(exc), parent=parent)
mw.perform_op(mw.col.undo, success=on_success, failure=on_failure) CollectionOp(parent, lambda col: col.undo()).success(
lambda out: tooltip(tr.undo_action_undone(action=out.operation), parent=parent)
).failure(on_failure).run_in_background()
def _legacy_undo(*, mw: aqt.AnkiQt, parent: QWidget) -> None: def _legacy_undo(*, parent: QWidget) -> None:
from aqt import mw
reviewing = mw.state == "review" reviewing = mw.state == "review"
just_refresh_reviewer = False just_refresh_reviewer = False

View file

@ -5,81 +5,74 @@ from __future__ import annotations
from typing import Optional, Sequence from typing import Optional, Sequence
from anki.collection import OpChanges, OpChangesWithCount, OpChangesWithId
from anki.decks import DeckCollapseScope, DeckId from anki.decks import DeckCollapseScope, DeckId
from aqt import AnkiQt, QWidget from aqt import QWidget
from aqt.main import PerformOpOptionalSuccessCallback from aqt.operations import CollectionOp
from aqt.utils import getOnlyText, tooltip, tr from aqt.utils import getOnlyText, tooltip, tr
def remove_decks( def remove_decks(
*, *,
mw: AnkiQt,
parent: QWidget, parent: QWidget,
deck_ids: Sequence[DeckId], deck_ids: Sequence[DeckId],
) -> None: ) -> CollectionOp[OpChangesWithCount]:
mw.perform_op( return CollectionOp(parent, lambda col: col.decks.remove(deck_ids)).success(
lambda: mw.col.decks.remove(deck_ids), lambda out: tooltip(tr.browsing_cards_deleted(count=out.count), parent=parent)
success=lambda out: tooltip(
tr.browsing_cards_deleted(count=out.count), parent=parent
),
) )
def reparent_decks( def reparent_decks(
*, mw: AnkiQt, parent: QWidget, deck_ids: Sequence[DeckId], new_parent: DeckId *, parent: QWidget, deck_ids: Sequence[DeckId], new_parent: DeckId
) -> None: ) -> CollectionOp[OpChangesWithCount]:
mw.perform_op( return CollectionOp(
lambda: mw.col.decks.reparent(deck_ids=deck_ids, new_parent=new_parent), parent, lambda col: col.decks.reparent(deck_ids=deck_ids, new_parent=new_parent)
success=lambda out: tooltip( ).success(
lambda out: tooltip(
tr.browsing_reparented_decks(count=out.count), parent=parent tr.browsing_reparented_decks(count=out.count), parent=parent
), )
) )
def rename_deck( def rename_deck(
*, *,
mw: AnkiQt, parent: QWidget,
deck_id: DeckId, deck_id: DeckId,
new_name: str, new_name: str,
) -> None: ) -> CollectionOp[OpChanges]:
mw.perform_op( return CollectionOp(
lambda: mw.col.decks.rename(deck_id, new_name), parent,
lambda col: col.decks.rename(deck_id, new_name),
) )
def add_deck_dialog( def add_deck_dialog(
*, *,
mw: AnkiQt,
parent: QWidget, parent: QWidget,
default_text: str = "", default_text: str = "",
success: PerformOpOptionalSuccessCallback = None, ) -> Optional[CollectionOp[OpChangesWithId]]:
) -> None:
if name := getOnlyText( if name := getOnlyText(
tr.decks_new_deck_name(), default=default_text, parent=parent tr.decks_new_deck_name(), default=default_text, parent=parent
).strip(): ).strip():
add_deck(mw=mw, name=name, success=success) return add_deck(parent=parent, name=name)
else:
return None
def add_deck( def add_deck(*, parent: QWidget, name: str) -> CollectionOp[OpChangesWithId]:
*, mw: AnkiQt, name: str, success: PerformOpOptionalSuccessCallback = None return CollectionOp(parent, lambda col: col.decks.add_normal_deck_with_name(name))
) -> None:
mw.perform_op(
lambda: mw.col.decks.add_normal_deck_with_name(name),
success=success,
)
def set_deck_collapsed( def set_deck_collapsed(
*, *,
mw: AnkiQt, parent: QWidget,
deck_id: DeckId, deck_id: DeckId,
collapsed: bool, collapsed: bool,
scope: DeckCollapseScope.V, scope: DeckCollapseScope.V,
handler: Optional[object] = None, ) -> CollectionOp[OpChanges]:
) -> None: return CollectionOp(
mw.perform_op( parent,
lambda: mw.col.decks.set_collapsed( lambda col: col.decks.set_collapsed(
deck_id=deck_id, collapsed=collapsed, scope=scope deck_id=deck_id, collapsed=collapsed, scope=scope
), ),
handler=handler,
) )

View file

@ -5,9 +5,9 @@ from __future__ import annotations
from typing import Sequence from typing import Sequence
from anki.collection import OpChangesWithCount from anki.collection import OpChanges, OpChangesWithCount
from anki.notes import NoteId from anki.notes import NoteId
from aqt import AnkiQt, QWidget from aqt import QWidget
from aqt.operations import CollectionOp from aqt.operations import CollectionOp
from aqt.utils import showInfo, tooltip, tr from aqt.utils import showInfo, tooltip, tr
@ -17,7 +17,7 @@ def add_tags_to_notes(
parent: QWidget, parent: QWidget,
note_ids: Sequence[NoteId], note_ids: Sequence[NoteId],
space_separated_tags: str, space_separated_tags: str,
) -> CollectionOp: ) -> CollectionOp[OpChangesWithCount]:
return CollectionOp( return CollectionOp(
parent, lambda col: col.tags.bulk_add(note_ids, space_separated_tags) parent, lambda col: col.tags.bulk_add(note_ids, space_separated_tags)
).success( ).success(
@ -30,7 +30,7 @@ def remove_tags_from_notes(
parent: QWidget, parent: QWidget,
note_ids: Sequence[NoteId], note_ids: Sequence[NoteId],
space_separated_tags: str, space_separated_tags: str,
) -> CollectionOp: ) -> CollectionOp[OpChangesWithCount]:
return CollectionOp( return CollectionOp(
parent, lambda col: col.tags.bulk_remove(note_ids, space_separated_tags) parent, lambda col: col.tags.bulk_remove(note_ids, space_separated_tags)
).success( ).success(
@ -38,7 +38,7 @@ def remove_tags_from_notes(
) )
def clear_unused_tags(*, parent: QWidget) -> CollectionOp: def clear_unused_tags(*, parent: QWidget) -> CollectionOp[OpChangesWithCount]:
return CollectionOp(parent, lambda col: col.tags.clear_unused_tags()).success( return CollectionOp(parent, lambda col: col.tags.clear_unused_tags()).success(
lambda out: tooltip( lambda out: tooltip(
tr.browsing_removed_unused_tags_count(count=out.count), parent=parent tr.browsing_removed_unused_tags_count(count=out.count), parent=parent
@ -51,7 +51,7 @@ def rename_tag(
parent: QWidget, parent: QWidget,
current_name: str, current_name: str,
new_name: str, new_name: str,
) -> CollectionOp: ) -> CollectionOp[OpChangesWithCount]:
def success(out: OpChangesWithCount) -> None: def success(out: OpChangesWithCount) -> None:
if out.count: if out.count:
tooltip(tr.browsing_notes_updated(count=out.count), parent=parent) tooltip(tr.browsing_notes_updated(count=out.count), parent=parent)
@ -66,7 +66,7 @@ def rename_tag(
def remove_tags_from_all_notes( def remove_tags_from_all_notes(
*, parent: QWidget, space_separated_tags: str *, parent: QWidget, space_separated_tags: str
) -> CollectionOp: ) -> CollectionOp[OpChangesWithCount]:
return CollectionOp( return CollectionOp(
parent, lambda col: col.tags.remove(space_separated_tags=space_separated_tags) parent, lambda col: col.tags.remove(space_separated_tags=space_separated_tags)
).success( ).success(
@ -76,7 +76,7 @@ def remove_tags_from_all_notes(
def reparent_tags( def reparent_tags(
*, parent: QWidget, tags: Sequence[str], new_parent: str *, parent: QWidget, tags: Sequence[str], new_parent: str
) -> CollectionOp: ) -> CollectionOp[OpChangesWithCount]:
return CollectionOp( return CollectionOp(
parent, lambda col: col.tags.reparent(tags=tags, new_parent=new_parent) parent, lambda col: col.tags.reparent(tags=tags, new_parent=new_parent)
).success( ).success(
@ -84,7 +84,9 @@ def reparent_tags(
) )
def set_tag_collapsed(*, parent: QWidget, tag: str, collapsed: bool) -> CollectionOp: def set_tag_collapsed(
*, parent: QWidget, tag: str, collapsed: bool
) -> CollectionOp[OpChanges]:
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)
) )

View file

@ -835,13 +835,9 @@ time = %(time)d;
else: else:
flag = desired_flag flag = desired_flag
set_card_flag( set_card_flag(parent=self.mw, card_ids=[self.card.id], flag=flag).success(
mw=self.mw, redraw_flag
card_ids=[self.card.id], ).run_in_background(initiator=self)
flag=flag,
handler=self,
success=redraw_flag,
)
def toggle_mark_on_current_note(self) -> None: def toggle_mark_on_current_note(self) -> None:
def redraw_mark(out: OpChangesWithCount) -> None: def redraw_mark(out: OpChangesWithCount) -> None:
@ -852,13 +848,13 @@ time = %(time)d;
if note.has_tag(MARKED_TAG): if note.has_tag(MARKED_TAG):
remove_tags_from_notes( remove_tags_from_notes(
parent=self.mw, note_ids=[note.id], space_separated_tags=MARKED_TAG parent=self.mw, note_ids=[note.id], space_separated_tags=MARKED_TAG
).success(redraw_mark).run(handler=self) ).success(redraw_mark).run_in_background(initiator=self)
else: else:
add_tags_to_notes( add_tags_to_notes(
parent=self.mw, parent=self.mw,
note_ids=[note.id], note_ids=[note.id],
space_separated_tags=MARKED_TAG, space_separated_tags=MARKED_TAG,
).success(redraw_mark).run(handler=self) ).success(redraw_mark).run_in_background(initiator=self)
def on_set_due(self) -> None: def on_set_due(self) -> None:
if self.mw.state != "review" or not self.card: if self.mw.state != "review" or not self.card:

View file

@ -631,8 +631,8 @@ class SidebarTreeView(QTreeView):
new_parent = DeckId(target.id) new_parent = DeckId(target.id)
reparent_decks( reparent_decks(
mw=self.mw, parent=self.browser, deck_ids=deck_ids, new_parent=new_parent parent=self.browser, deck_ids=deck_ids, new_parent=new_parent
) ).run_in_background()
return True return True
@ -652,7 +652,9 @@ class SidebarTreeView(QTreeView):
else: else:
new_parent = target.full_name new_parent = target.full_name
reparent_tags(parent=self.browser, tags=tags, new_parent=new_parent).run() reparent_tags(
parent=self.browser, tags=tags, new_parent=new_parent
).run_in_background()
return True return True
@ -948,7 +950,7 @@ class SidebarTreeView(QTreeView):
full_name = head + node.name full_name = head + node.name
return lambda expanded: set_tag_collapsed( return lambda expanded: set_tag_collapsed(
parent=self, tag=full_name, collapsed=not expanded parent=self, tag=full_name, collapsed=not expanded
).run() ).run_in_background()
for node in nodes: for node in nodes:
item = SidebarItem( item = SidebarItem(
@ -993,11 +995,12 @@ class SidebarTreeView(QTreeView):
) -> None: ) -> None:
def toggle_expand(node: DeckTreeNode) -> Callable[[bool], None]: def toggle_expand(node: DeckTreeNode) -> Callable[[bool], None]:
return lambda expanded: set_deck_collapsed( return lambda expanded: set_deck_collapsed(
mw=self.mw, parent=self,
deck_id=DeckId(node.deck_id), deck_id=DeckId(node.deck_id),
collapsed=not expanded, collapsed=not expanded,
scope=DeckCollapseScope.BROWSER, scope=DeckCollapseScope.BROWSER,
handler=self, ).run_in_background(
initiator=self,
) )
for node in nodes: for node in nodes:
@ -1192,15 +1195,15 @@ class SidebarTreeView(QTreeView):
return return
rename_deck( rename_deck(
mw=self.mw, parent=self,
deck_id=deck_id, deck_id=deck_id,
new_name=full_name, new_name=full_name,
) ).run_in_background()
self.mw.query_op(lambda: self.mw.col.get_deck(deck_id), success=after_fetch) self.mw.query_op(lambda: self.mw.col.get_deck(deck_id), success=after_fetch)
def delete_decks(self, _item: SidebarItem) -> None: def delete_decks(self, _item: SidebarItem) -> None:
remove_decks(mw=self.mw, parent=self.browser, deck_ids=self._selected_decks()) remove_decks(parent=self, deck_ids=self._selected_decks()).run_in_background()
# Tags # Tags
########################### ###########################
@ -1209,7 +1212,9 @@ class SidebarTreeView(QTreeView):
tags = self.mw.col.tags.join(self._selected_tags()) tags = self.mw.col.tags.join(self._selected_tags())
item.name = "..." item.name = "..."
remove_tags_from_all_notes(parent=self.browser, space_separated_tags=tags).run() remove_tags_from_all_notes(
parent=self.browser, space_separated_tags=tags
).run_in_background()
def rename_tag(self, item: SidebarItem, new_name: str) -> None: def rename_tag(self, item: SidebarItem, new_name: str) -> None:
if not new_name or new_name == item.name: if not new_name or new_name == item.name:
@ -1227,7 +1232,7 @@ class SidebarTreeView(QTreeView):
parent=self.browser, parent=self.browser,
current_name=old_name, current_name=old_name,
new_name=new_name, new_name=new_name,
).run() ).run_in_background()
# Saved searches # Saved searches
#################################### ####################################

View file

@ -175,4 +175,6 @@ class StudyDeck(QDialog):
QDialog.accept(self) QDialog.accept(self)
add_deck_dialog(mw=self.mw, parent=self, default_text=default, success=success) add_deck_dialog(parent=self, default_text=default).success(
success
).run_in_background()