diff --git a/qt/aqt/browser/previewer.py b/qt/aqt/browser/previewer.py index db09ff121..43ec93b66 100644 --- a/qt/aqt/browser/previewer.py +++ b/qt/aqt/browser/previewer.py @@ -83,6 +83,8 @@ class Previewer(QDialog): self.bbox = QDialogButtonBox() self.bbox.setLayoutDirection(Qt.LayoutDirection.LeftToRight) + gui_hooks.card_review_webview_did_init(self._web, AnkiWebViewKind.PREVIEWER) + self._replay = self.bbox.addButton( tr.actions_replay_audio(), QDialogButtonBox.ButtonRole.ActionRole ) @@ -110,6 +112,8 @@ class Previewer(QDialog): self._on_close() def _on_replay_audio(self) -> None: + gui_hooks.audio_will_replay(self._web, self.card(), self._state == "question") + if self._state == "question": replay_audio(self.card(), True) elif self._state == "answer": @@ -240,6 +244,10 @@ class Previewer(QDialog): def _on_show_both_sides(self, toggle: bool) -> None: self._show_both_sides = toggle self.mw.col.set_config_bool(Config.Bool.PREVIEW_BOTH_SIDES, toggle) + gui_hooks.previewer_will_redraw_after_show_both_sides_toggled( + self._web, self.card(), self._state == "question", toggle + ) + if self._state == "answer" and not toggle: self._state = "question" self.render_card() diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py index c2ea9a399..52d3fe5fc 100644 --- a/qt/aqt/clayout.py +++ b/qt/aqt/clayout.py @@ -359,6 +359,10 @@ class CardLayout(QDialog): self.preview_web.eval("_blockDefaultDragDropBehavior();") self.preview_web.set_bridge_command(self._on_bridge_cmd, self) + gui_hooks.card_review_webview_did_init( + self.preview_web, AnkiWebViewKind.CARD_LAYOUT + ) + if self._isCloze(): nums = list(self.note.cloze_numbers_in_fields()) if self.ord + 1 not in nums: diff --git a/qt/aqt/main.py b/qt/aqt/main.py index 2f40772ba..0f2764f66 100644 --- a/qt/aqt/main.py +++ b/qt/aqt/main.py @@ -248,6 +248,8 @@ class AnkiQt(QMainWindow): def finish_ui_setup(self) -> None: "Actions that are deferred until after add-on loading." self.toolbar.draw() + # add-ons are only available here after setupAddons + gui_hooks.reviewer_did_init(self.reviewer) def setupProfileAfterWebviewsLoaded(self) -> None: for w in (self.web, self.bottomWeb): @@ -901,6 +903,8 @@ title="{}" {}>{}""".format( for webview in self.web, self.bottomWeb: webview.force_load_hack() + gui_hooks.card_review_webview_did_init(self.web, AnkiWebViewKind.MAIN) + def closeAllWindows(self, onsuccess: Callable) -> None: aqt.dialogs.closeAll(onsuccess) diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index d6bbd1646..b4da9e885 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -291,6 +291,7 @@ class Reviewer: replay_audio(self.card, True) elif self.state == "answer": replay_audio(self.card, False) + gui_hooks.audio_will_replay(self.web, self.card, self.state == "question") # Initializing the webview ########################################################################## @@ -505,6 +506,7 @@ class Reviewer: def on_pause_audio(self) -> None: av_player.toggle_pause() + gui_hooks.audio_did_pause_or_unpause(self.web) seek_secs = 5 diff --git a/qt/tools/genhooks_gui.py b/qt/tools/genhooks_gui.py index e5208b9fb..db8ff4629 100644 --- a/qt/tools/genhooks_gui.py +++ b/qt/tools/genhooks_gui.py @@ -215,6 +215,11 @@ hooks = [ name="reviewer_will_bury_card", args=["id: int"], ), + Hook( + name="audio_did_pause_or_unpause", + args=["webview: aqt.webview.AnkiWebView"], + doc="""Called when the audio is paused or unpaused.""", + ), # Debug ################### Hook( @@ -238,8 +243,21 @@ hooks = [ doc="""Allow to change the display of the card layout. After most values are set and before the window is actually shown.""", ), + # Reviewer + ################### + Hook( + name="reviewer_did_init", + args=["reviewer: aqt.reviewer.Reviewer"], + doc="""Called after the reviewer is initialized.""", + ), # Multiple windows ################### + # reviewer and previewer + Hook( + name="audio_will_replay", + args=["webview: aqt.webview.AnkiWebView", "card: Card", "is_front_side: bool"], + doc="""Called when the user uses the 'replay audio' action, but not when they click on a play button.""", + ), # reviewer, clayout and browser Hook( name="card_will_show", @@ -248,6 +266,15 @@ hooks = [ legacy_hook="prepareQA", doc="Can modify card text before review/preview.", ), + # reviewer, main and clayout + Hook( + name="card_review_webview_did_init", + args=[ + "webview: aqt.webview.AnkiWebView", + "kind: aqt.webview.AnkiWebViewKind", + ], + doc="Called when initializing the webview for the review screen, the card layout screen, and the preview screen.", + ), # Deck browser ################### Hook( @@ -527,6 +554,16 @@ hooks = [ args=["previewer: aqt.browser.previewer.Previewer"], doc="""Called after the previewer is initialized.""", ), + Hook( + name="previewer_will_redraw_after_show_both_sides_toggled", + args=[ + "webview: aqt.webview.AnkiWebView", + "card: Card", + "is_front_side: bool", + "show_both_sides: bool", + ], + doc="""Called when the checkbox is toggled by the user.""", + ), # Main window states ################### # these refer to things like deckbrowser, overview and reviewer state,