# Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html from __future__ import annotations from typing import Optional, Sequence import aqt from anki.cards import CardId from anki.collection import ( CARD_TYPE_NEW, Config, OpChanges, OpChangesWithCount, OpChangesWithId, ) from anki.decks import DeckId from anki.notes import NoteId from anki.scheduler import FilteredDeckForUpdate from aqt.operations import CollectionOp from aqt.qt import * from aqt.utils import disable_help_button, getText, tooltip, tr 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 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 reposition_new_cards_dialog( *, parent: QWidget, card_ids: Sequence[CardId] ) -> Optional[CollectionOp[OpChangesWithCount]]: from aqt import mw assert mw assert mw.col.db row = mw.col.db.first( f"select min(due), max(due) from cards where type={CARD_TYPE_NEW} and odid=0" ) assert row (min_position, max_position) = row min_position = max(min_position or 0, 0) max_position = max_position or 0 d = QDialog(parent) disable_help_button(d) d.setWindowModality(Qt.WindowModal) frm = aqt.forms.reposition.Ui_Dialog() frm.setupUi(d) txt = tr.browsing_queue_top(val=min_position) txt += "\n" + tr.browsing_queue_bottom(val=max_position) frm.label.setText(txt) frm.start.selectAll() if not d.exec_(): return None start = frm.start.value() step = frm.step.value() randomize = frm.randomize.isChecked() shift = frm.shift.isChecked() return reposition_new_cards( parent=parent, card_ids=card_ids, starting_from=start, step_size=step, randomize=randomize, shift_existing=shift, ) 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 suspend_cards( *, parent: QWidget, card_ids: Sequence[CardId], ) -> CollectionOp[OpChangesWithCount]: return CollectionOp(parent, lambda col: col.sched.suspend_cards(card_ids)) def suspend_note( *, parent: QWidget, note_ids: Sequence[NoteId], ) -> CollectionOp[OpChangesWithCount]: return CollectionOp(parent, lambda col: col.sched.suspend_notes(note_ids)) def unsuspend_cards( *, parent: QWidget, card_ids: Sequence[CardId] ) -> CollectionOp[OpChanges]: return CollectionOp(parent, lambda col: col.sched.unsuspend_cards(card_ids)) def bury_cards( *, parent: QWidget, card_ids: Sequence[CardId], ) -> CollectionOp[OpChangesWithCount]: return CollectionOp(parent, lambda col: col.sched.bury_cards(card_ids)) def bury_notes( *, parent: QWidget, note_ids: Sequence[NoteId], ) -> CollectionOp[OpChangesWithCount]: return CollectionOp(parent, lambda col: col.sched.bury_notes(note_ids)) def rebuild_filtered_deck( *, parent: QWidget, deck_id: DeckId ) -> CollectionOp[OpChangesWithCount]: return CollectionOp(parent, lambda col: col.sched.rebuild_filtered_deck(deck_id)) def empty_filtered_deck(*, parent: QWidget, deck_id: DeckId) -> CollectionOp[OpChanges]: return CollectionOp(parent, lambda col: col.sched.empty_filtered_deck(deck_id)) 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))