diff --git a/qt/aqt/gui_hooks.py b/qt/aqt/gui_hooks.py index d8f33b119..16f26bc6f 100644 --- a/qt/aqt/gui_hooks.py +++ b/qt/aqt/gui_hooks.py @@ -149,6 +149,8 @@ browser_row_did_change_hook = _BrowserRowDidChangeHook() class _CardTextFilter: + """Can modify card text before review/preview.""" + _hooks: List[Callable[[str, Card, str], str]] = [] def append(self, cb: Callable[[str, Card, str], str]) -> None: @@ -674,6 +676,33 @@ class _ReviewerQuestionDidShowHook: reviewer_question_did_show_hook = _ReviewerQuestionDidShowHook() +class _ReviewerWillEndHook: + """Called before Anki transitions from the review screen to another screen.""" + + _hooks: List[Callable[[], None]] = [] + + def append(self, cb: Callable[[], None]) -> None: + """()""" + self._hooks.append(cb) + + def remove(self, cb: Callable[[], None]) -> None: + self._hooks.remove(cb) + + def __call__(self) -> None: + for hook in self._hooks: + try: + hook() + except: + # if the hook fails, remove it + self._hooks.remove(hook) + raise + # legacy support + runHook("reviewCleanup") + + +reviewer_will_end_hook = _ReviewerWillEndHook() + + class _StateDidChangeHook: _hooks: List[Callable[[str, str], None]] = [] diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index 42d7fc827..30f16f04c 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -13,7 +13,6 @@ from typing import List import aqt from anki import hooks from anki.cards import Card -from anki.hooks import runHook from anki.lang import _, ngettext from anki.utils import bodyClass, stripHTML from aqt import AnkiQt, gui_hooks @@ -63,7 +62,7 @@ class Reviewer: return def cleanup(self): - runHook("reviewCleanup") + gui_hooks.reviewer_will_end_hook() # Fetching a card ########################################################################## diff --git a/qt/tools/genhooks_gui.py b/qt/tools/genhooks_gui.py index 82ffcdb6c..5af72891b 100644 --- a/qt/tools/genhooks_gui.py +++ b/qt/tools/genhooks_gui.py @@ -17,8 +17,8 @@ from tools.hookslib import Hook, update_file ###################################################################### hooks = [ - Hook(name="mpv_did_idle"), - Hook(name="mpv_will_play", args=["file: str"], legacy_hook="mpvWillPlay"), + # Reviewing + ################### Hook( name="reviewer_question_did_show", args=["card: Card"], @@ -32,11 +32,24 @@ hooks = [ legacy_no_args=True, ), Hook( - name="current_note_type_did_change", - args=["notetype: Dict[str, Any]"], - legacy_hook="currentModelChanged", - legacy_no_args=True, + name="reviewer_context_menu_will_show", + args=["reviewer: aqt.reviewer.Reviewer", "menu: QMenu"], + legacy_hook="Reviewer.contextMenuEvent", ), + Hook( + name="reviewer_will_end", + legacy_hook="reviewCleanup", + doc="Called before Anki transitions from the review screen to another screen.", + ), + Hook( + name="card_text", + args=["text: str", "card: Card", "kind: str"], + return_type="str", + legacy_hook="prepareQA", + doc="Can modify card text before review/preview.", + ), + # Browser + ################### Hook( name="browser_menus_did_setup", args=["browser: aqt.browser.Browser"], @@ -52,24 +65,13 @@ hooks = [ args=["browser: aqt.browser.Browser"], legacy_hook="browser.rowChanged", ), - Hook( - name="card_text", - args=["text: str", "card: Card", "kind: str"], - return_type="str", - legacy_hook="prepareQA", - ), Hook( name="webview_context_menu_will_show", args=["webview: aqt.webview.AnkiWebView", "menu: QMenu"], legacy_hook="AnkiWebView.contextMenuEvent", ), - Hook( - name="reviewer_context_menu_will_show", - args=["reviewer: aqt.reviewer.Reviewer", "menu: QMenu"], - legacy_hook="Reviewer.contextMenuEvent", - ), - Hook(name="profile_did_open", legacy_hook="profileLoaded"), - Hook(name="profile_will_close", legacy_hook="unloadProfile"), + # States + ################### Hook( name="state_will_change", args=["new_state: str", "old_state: str"], @@ -85,11 +87,6 @@ hooks = [ name="state_shortcuts_will_change", args=["state: str", "shortcuts: List[Tuple[str, Callable]]"], ), - Hook( - name="collection_did_load", - args=["col: anki.storage._Collection"], - legacy_hook="colLoading", - ), Hook( name="state_did_revert", args=["action: str"], @@ -101,6 +98,15 @@ hooks = [ legacy_hook="reset", doc="Called when the interface needs to be redisplayed after non-trivial changes have been made.", ), + # Main + ################### + Hook(name="profile_did_open", legacy_hook="profileLoaded"), + Hook(name="profile_will_close", legacy_hook="unloadProfile"), + Hook( + name="collection_did_load", + args=["col: anki.storage._Collection"], + legacy_hook="colLoading", + ), Hook( name="undo_state_did_change", args=["can_undo: bool"], legacy_hook="undoState" ), @@ -111,6 +117,8 @@ hooks = [ return_type="str", legacy_hook="setupStyle", ), + # Adding cards + ################### Hook( name="add_cards_history_menu_will_show", args=["addcards: aqt.addcards.AddCards", "menu: QMenu"], @@ -121,12 +129,8 @@ hooks = [ args=["note: anki.notes.Note"], legacy_hook="AddCards.noteAdded", ), - Hook( - name="deck_browser_options_menu_will_show", - args=["menu: QMenu", "deck_id: int"], - legacy_hook="showDeckOptions", - ), - # no return like setupEditorButtons + # Editing + ################### Hook( name="editor_buttons_did_setup", args=["buttons: List", "editor: aqt.editor.Editor"], @@ -173,10 +177,21 @@ hooks = [ return_type="str", legacy_hook="mungeEditingFontName", ), - # - # aqt/reviewer.py - # 66: runHook("reviewCleanup") - # + # Other + ################### + Hook(name="mpv_did_idle"), + Hook(name="mpv_will_play", args=["file: str"], legacy_hook="mpvWillPlay"), + Hook( + name="current_note_type_did_change", + args=["notetype: Dict[str, Any]"], + legacy_hook="currentModelChanged", + legacy_no_args=True, + ), + Hook( + name="deck_browser_options_menu_will_show", + args=["menu: QMenu", "deck_id: int"], + legacy_hook="showDeckOptions", + ), ] if __name__ == "__main__":