From 7be08919e28f79533defb4b70fe412bfc671de21 Mon Sep 17 00:00:00 2001 From: Thomas B Date: Fri, 14 Aug 2020 13:52:20 -0400 Subject: [PATCH] Add hook for initializing answer buttons --- qt/aqt/gui_hooks.py | 46 ++++++++++++++++++++++++++++++++++++++++ qt/aqt/reviewer.py | 18 ++++++++++------ qt/tools/genhooks_gui.py | 11 ++++++++++ 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/qt/aqt/gui_hooks.py b/qt/aqt/gui_hooks.py index 71aec7506..b66efa6ea 100644 --- a/qt/aqt/gui_hooks.py +++ b/qt/aqt/gui_hooks.py @@ -2079,6 +2079,52 @@ class _ReviewerDidShowQuestionHook: reviewer_did_show_question = _ReviewerDidShowQuestionHook() +class _ReviewerWillInitAnswerButtonsFilter: + """Used to modify the answer buttons shown for a card. + """ + + _hooks: List[ + Callable["aqt.reviewer.Reviewer", Card], Tuple[Tuple[int, str]]] + ] = [] + + def append( + self, + cb: Callable[ + "aqt.reviewer.Reviewer", Card], Tuple[Tuple[int, str]]] + ], + ) -> None: + """(reviewer: aqt.reviewer.Reviewer, card: Card)""" + self._hooks.append(cb) + + def remove( + self, + cb: Callable[ + "aqt.reviewer.Reviewer", Card], Tuple[Tuple[int, str]]] + ], + ) -> None: + if cb in self._hooks: + self._hooks.remove(cb) + + def count(self) -> int: + return len(self._hooks) + + def __call__( + self, reviewer: aqt.reviewer.Reviewer, card: Card + ) -> Tuple[Tuple[int, str]]: + buttons_tuple = None + for filter in self._hooks: + try: + buttons_tuple = filter(reviewer, card) + except: + # if the hook fails, remove it + self._hooks.remove(filter) + raise + return buttons_tuple + + +reviewer_will_init_answer_buttons = _ReviewerWillInitAnswerButtonsFilter() + + class _ReviewerWillAnswerCardFilter: """Used to modify the ease at which a card is rated or to bypass rating the card completely. diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index 01d847afe..f39feb97d 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -622,14 +622,18 @@ time = %(time)d; return 2 def _answerButtonList(self) -> Sequence[Tuple[int, str]]: - l = ((1, _("Again")),) - cnt = self.mw.col.sched.answerButtons(self.card) - if cnt == 2: - return l + ((2, _("Good")),) - elif cnt == 3: - return l + ((2, _("Good")), (3, _("Easy"))) + buttons_tuple = gui_hooks.reviewer_will_init_answer_buttons(self, self.card) + if buttons_tuple is not None: + return buttons_tuple else: - return l + ((2, _("Hard")), (3, _("Good")), (4, _("Easy"))) + l = ((1, _("Again")),) + cnt = self.mw.col.sched.answerButtons(self.card) + if cnt == 2: + return l + ((2, _("Good")),) + elif cnt == 3: + return l + ((2, _("Good")), (3, _("Easy"))) + else: + return l + ((2, _("Hard")), (3, _("Good")), (4, _("Easy"))) def _answerButtons(self) -> str: default = self._defaultEase() diff --git a/qt/tools/genhooks_gui.py b/qt/tools/genhooks_gui.py index a9d5b1096..118e783bf 100644 --- a/qt/tools/genhooks_gui.py +++ b/qt/tools/genhooks_gui.py @@ -58,6 +58,17 @@ hooks = [ legacy_hook="showAnswer", legacy_no_args=True, ), + Hook( + name="reviewer_will_init_answer_buttons", + args=["reviewer: aqt.reviewer.Reviewer", "card: Card"], + doc="""Used to modify list of answer buttons + + Return a tuple of the form ((1, "Label1"), (2, "Label2")) + + import _ from anki.lang to support translation, as + ((1, _("Label1)), ...) + """, + ), Hook( name="reviewer_will_answer_card", args=[