def add_or_update_filtered_deck( *, parent: QWidget, deck: FilteredDeckForUpdate, ) -> CollectionOp[OpChangesWithId]: return CollectionOp( parent, lambda col: col.sched.add_or_update_filtered_deck(deck))
def add_note( *, parent: QWidget, note: Note, target_deck_id: DeckId, ) -> CollectionOp[OpChanges]: return CollectionOp(parent, lambda col: col.add_note(note, target_deck_id))
def set_due_date_dialog( *, parent: QWidget, card_ids: Sequence[CardId], config_key: Optional[Config.String.Key.V], ) -> Optional[CollectionOp[OpChanges]]: assert aqt.mw if not card_ids: return None default_text = (aqt.mw.col.get_config_string(config_key) if config_key is not None else "") prompt = "\n".join([ tr.scheduling_set_due_date_prompt(cards=len(card_ids)), tr.scheduling_set_due_date_prompt_hint(), ]) (days, success) = getText( prompt=prompt, parent=parent, default=default_text, title=tr.actions_set_due_date(), ) if not success or not days.strip(): return None else: return CollectionOp( parent, lambda col: col.sched.set_due_date( card_ids, days, config_key)).success(lambda _: tooltip( tr.scheduling_set_due_date_done(cards=len(card_ids)), parent=parent, ))
def reparent_decks(*, parent: QWidget, deck_ids: Sequence[DeckId], new_parent: DeckId) -> CollectionOp[OpChangesWithCount]: return CollectionOp( parent, lambda col: col.decks. reparent(deck_ids=deck_ids, new_parent=new_parent)).success( lambda out: tooltip(tr.browsing_reparented_decks(count=out.count), parent=parent))
def redo(*, parent: QWidget) -> None: "Redo the last operation, and refresh the UI." def on_success(out: OpChangesAfterUndo) -> None: tooltip(tr.undo_action_redone(action=out.operation), parent=parent) CollectionOp(parent, lambda col: col.redo()).success(on_success).run_in_background()
def remove_decks( *, parent: QWidget, deck_ids: Sequence[DeckId], ) -> CollectionOp[OpChangesWithCount]: return CollectionOp(parent, lambda col: col.decks.remove(deck_ids)).success( lambda out: tooltip(tr.browsing_cards_deleted(count=out.count), parent=parent) )
def remove_notes( *, parent: QWidget, note_ids: Sequence[NoteId], ) -> CollectionOp[OpChangesWithCount]: return CollectionOp( parent, lambda col: col.remove_notes(note_ids)).success( lambda out: tooltip(tr.browsing_cards_deleted(count=out.count)), )
def unbury_deck( *, parent: QWidget, deck_id: DeckId, mode: UnburyDeck.Mode.V = UnburyDeck.ALL, ) -> CollectionOp[OpChanges]: return CollectionOp( parent, lambda col: col.sched.unbury_deck(deck_id=deck_id, mode=mode))
def remove_tags_from_all_notes( *, parent: QWidget, space_separated_tags: str) -> CollectionOp[OpChangesWithCount]: return CollectionOp( parent, lambda col: col.tags.remove(space_separated_tags=space_separated_tags) ).success(lambda out: tooltip(tr.browsing_notes_updated(count=out.count), parent=parent))
def set_card_flag( *, parent: QWidget, card_ids: Sequence[CardId], flag: int, ) -> CollectionOp[OpChanges]: return CollectionOp( parent, lambda col: col.set_user_flag_for_cards(flag, card_ids))
def update_notes(self, parent: QWidget): if self.converted: CollectionOp( parent=parent, op=lambda col: self.update_notes_op(col)).success( lambda out: showInfo(parent=parent, title="Task done", textFormat="rich", text=self.form_report_message() )).run_in_background()
def answer_card( *, parent: QWidget, answer: CardAnswer, ) -> CollectionOp[OpChanges]: def answer_v3(col: Collection) -> OpChanges: assert isinstance(col.sched, V3Scheduler) return col.sched.answer_card(answer) return CollectionOp(parent, answer_v3)
def remove_tags_from_notes( *, parent: QWidget, note_ids: Sequence[NoteId], space_separated_tags: str, ) -> CollectionOp[OpChangesWithCount]: return CollectionOp( parent, lambda col: col.tags.bulk_remove( note_ids, space_separated_tags)).success(lambda out: tooltip( tr.browsing_notes_updated(count=out.count), parent=parent))
def rename_deck( *, parent: QWidget, deck_id: DeckId, new_name: str, ) -> CollectionOp[OpChanges]: return CollectionOp( parent, lambda col: col.decks.rename(deck_id, new_name), )
def forget_cards( *, parent: QWidget, card_ids: Sequence[CardId] ) -> CollectionOp[OpChanges]: return CollectionOp( parent, lambda col: col.sched.schedule_cards_as_new(card_ids) ).success( lambda _: tooltip( tr.scheduling_forgot_cards(cards=len(card_ids)), parent=parent ) )
def set_card_flag( *, parent: QWidget, card_ids: Sequence[CardId], flag: int, ) -> CollectionOp[OpChangesWithCount]: return CollectionOp( parent, lambda col: col.set_user_flag_for_cards(flag, card_ids)).success( lambda out: tooltip(tr.browsing_cards_updated(count=out.count), parent=parent))
def rename_media_files(to_rename: List[Tuple[str, str]], note: Note, parent: Editor): for old_filename, new_filename in to_rename: new_filename = rename_file(old_filename, new_filename) for field_name, field_value in note.items(): note[field_name] = field_value.replace(old_filename, new_filename) CollectionOp( parent=parent.widget, op=lambda col: col.update_note(note)).success(lambda out: tooltip( f"Renamed {len(to_rename)} files", parent=parent.parentWindow) ).run_in_background()
def set_deck_collapsed( *, parent: QWidget, deck_id: DeckId, collapsed: bool, scope: DeckCollapseScope.V, ) -> CollectionOp[OpChanges]: return CollectionOp( parent, lambda col: col.decks.set_collapsed( deck_id=deck_id, collapsed=collapsed, scope=scope), )
def on_put_in_learning(self: Browser) -> None: selected_cards = {self.col.get_card(cid) for cid in self.selected_cards()} new_cards = {card for card in selected_cards if is_new(card)} if len(new_cards) < 1: notify_user("No new cards selected. Nothing to do.") else: CollectionOp( parent=self, op=lambda col: put_cards_in_learning(col, new_cards)).success( lambda out: notify_user( format_message(new_cards, selected_cards - new_cards) )).run_in_background()
def undo(*, parent: QWidget) -> None: "Undo the last operation, and refresh the UI." def on_failure(exc: Exception) -> None: if isinstance(exc, UndoEmpty): # backend has no undo, but there may be a checkpoint # or v1/v2 review waiting _legacy_undo(parent=parent) else: showWarning(str(exc), parent=parent) 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 rename_tag( *, parent: QWidget, current_name: str, new_name: str, ) -> CollectionOp[OpChangesWithCount]: def success(out: OpChangesWithCount) -> None: if out.count: tooltip(tr.browsing_notes_updated(count=out.count), parent=parent) else: showInfo(tr.browsing_tag_rename_warning_empty(), parent=parent) return CollectionOp( parent, lambda col: col.tags.rename(old=current_name, new=new_name), ).success(success)
def reposition_new_cards( *, parent: QWidget, card_ids: Sequence[CardId], starting_from: int, step_size: int, randomize: bool, shift_existing: bool, ) -> CollectionOp[OpChangesWithCount]: return CollectionOp( parent, lambda col: col.sched.reposition_new_cards( card_ids=card_ids, starting_from=starting_from, step_size=step_size, randomize=randomize, shift_existing=shift_existing, ), ).success(lambda out: tooltip( tr.browsing_changed_new_position(count=out.count), parent=parent))
def on_did_answer_card(reviewer: Reviewer, card: Card, ease: Literal[1, 2, 3, 4]) -> None: """Bury card if it was answered 'again' too many times within the specified time.""" # only care about failed cards if ease != 1: return if config['ignore_new_cards'] is True and card.type <= TYPE_LEARNING: return agains = agains_in_the_timeframe(card.id) passed = time_passed().hours() if agains >= threshold(card): if any((config['tag'], config['flag'], config['action'] != Action.No.name)): CollectionOp(parent=reviewer.web, op=lambda col: act_on_card(col, card)).success( lambda out: notify(action_msg(agains, passed)) if out else None).run_in_background() elif config['again_notify'] is True: notify(info_msg(card, agains, passed))
def forget_cards( *, parent: QWidget, card_ids: Sequence[CardId], context: ScheduleCardsAsNew.Context.V | None = None, ) -> CollectionOp[OpChanges] | None: assert aqt.mw dialog = QDialog(parent) disable_help_button(dialog) form = aqt.forms.forget.Ui_Dialog() form.setupUi(dialog) if context is not None: defaults = aqt.mw.col.sched.schedule_cards_as_new_defaults(context) form.restore_position.setChecked(defaults.restore_position) form.reset_counts.setChecked(defaults.reset_counts) if not dialog.exec(): return None restore_position = form.restore_position.isChecked() reset_counts = form.reset_counts.isChecked() return CollectionOp( parent, lambda col: col.sched.schedule_cards_as_new( card_ids, restore_position=restore_position, reset_counts=reset_counts, context=context, ), ).success( lambda _: tooltip( tr.scheduling_forgot_cards(cards=len(card_ids)), parent=parent ) )
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, ), )
def change_notetype_of_notes( *, parent: QWidget, input: ChangeNotetypeIn) -> CollectionOp[OpChanges]: return CollectionOp(parent, lambda col: col.models.change_notetype_of_notes(input))
def remove_notetype( *, parent: QWidget, notetype_id: NotetypeId, ) -> CollectionOp[OpChanges]: return CollectionOp(parent, lambda col: col.models.remove(notetype_id))
def update_notetype_legacy( *, parent: QWidget, notetype: NotetypeDict, ) -> CollectionOp[OpChanges]: return CollectionOp(parent, lambda col: col.models.update_dict(notetype))
def add_notetype_legacy( *, parent: QWidget, notetype: NotetypeDict, ) -> CollectionOp[OpChangesWithId]: return CollectionOp(parent, lambda col: col.models.add_dict(notetype))
def empty_filtered_deck(*, parent: QWidget, deck_id: DeckId) -> CollectionOp[OpChanges]: return CollectionOp(parent, lambda col: col.sched.empty_filtered_deck(deck_id))