From 660685375fc423f241d09050ed934455ad25aa11 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 15 Jan 2020 12:46:53 +1000 Subject: [PATCH] migrate most of the remaining runHook() calls --- qt/aqt/addcards.py | 8 ++--- qt/aqt/deckbrowser.py | 4 +-- qt/aqt/editor.py | 24 +++++++------ qt/aqt/gui_hooks.py | 74 +++++++++++++++++++++------------------- qt/aqt/main.py | 28 ++++++++------- qt/aqt/reviewer.py | 1 - qt/aqt/sound.py | 2 +- qt/tools/genhooks_gui.py | 15 +++++--- 8 files changed, 83 insertions(+), 73 deletions(-) diff --git a/qt/aqt/addcards.py b/qt/aqt/addcards.py index 8324d9936..70df81aa1 100644 --- a/qt/aqt/addcards.py +++ b/qt/aqt/addcards.py @@ -7,11 +7,11 @@ import aqt.deckchooser import aqt.editor import aqt.forms import aqt.modelchooser -from anki.hooks import addHook, remHook, runHook +from anki.hooks import addHook, remHook from anki.lang import _ from anki.notes import Note from anki.utils import htmlToTextLine, isMac -from aqt import AnkiQt +from aqt import AnkiQt, gui_hooks from aqt.qt import * from aqt.sound import clearAudioQueue from aqt.utils import ( @@ -157,7 +157,7 @@ class AddCards(QDialog): else: a = m.addAction(_("(Note deleted)")) a.setEnabled(False) - runHook("AddCards.onHistory", self, m) + gui_hooks.add_cards_history_menu_will_show_hook(self, m) m.exec_(self.historyButton.mapToGlobal(QPoint(0, 0))) def editHistory(self, nid): @@ -197,7 +197,7 @@ question on all cards.""" self.addHistory(note) self.mw.requireReset() self.previousNote = note - runHook("AddCards.noteAdded", note) + gui_hooks.add_cards_note_did_add_hook(note) return note def addCards(self): diff --git a/qt/aqt/deckbrowser.py b/qt/aqt/deckbrowser.py index 8944bc9da..b99d3ad24 100644 --- a/qt/aqt/deckbrowser.py +++ b/qt/aqt/deckbrowser.py @@ -6,9 +6,9 @@ from typing import Any import aqt from anki.errors import DeckRenameError -from anki.hooks import runHook from anki.lang import _, ngettext from anki.utils import fmtTimeSpan, ids2str +from aqt import gui_hooks from aqt.qt import * from aqt.sound import clearAudioQueue from aqt.utils import askUser, getOnlyText, openHelp, openLink, shortcut, showWarning @@ -245,7 +245,7 @@ where id > ?""", a.triggered.connect(lambda b, did=did: self._export(did)) a = m.addAction(_("Delete")) a.triggered.connect(lambda b, did=did: self._delete(did)) - runHook("showDeckOptions", m, did) + gui_hooks.deck_browser_options_menu_will_show_hook(m, did) m.exec_(QCursor.pos()) def _export(self, did): diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index 5a64b4c70..10cbc2a3c 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -19,11 +19,11 @@ from bs4 import BeautifulSoup import aqt import aqt.sound -from anki.hooks import addHook, runFilter, runHook +from anki.hooks import addHook, runFilter from anki.lang import _ from anki.sync import AnkiRequestsClient from anki.utils import checksum, isWin, namedtmp, stripHTMLMedia -from aqt import AnkiQt +from aqt import AnkiQt, gui_hooks from aqt.qt import * from aqt.sound import getAudio from aqt.utils import ( @@ -141,6 +141,8 @@ class Editor: self._addButton("more", "more"), ] ) + gui_hooks.editor_buttons_did_setup_hook(righttopbtns, self) + # legacy filter righttopbtns = runFilter("setupEditorButtons", righttopbtns, self) topbuts = """
@@ -283,7 +285,7 @@ class Editor: ("Ctrl+Shift+X", self.onHtmlEdit), ("Ctrl+Shift+T", self.onFocusTags, True), ] - runHook("setupEditorShortcuts", cuts, self) + gui_hooks.editor_shortcuts_did_setup_hook(cuts, self) for row in cuts: if len(row) == 2: keys, fn = row # pylint: disable=unbalanced-tuple-unpacking @@ -328,7 +330,7 @@ class Editor: ###################################################################### def onBridgeCmd(self, cmd): - if not self.note or not runHook: + if not self.note: # shutdown return # focus lost or key/button pressed? @@ -356,20 +358,20 @@ class Editor: if type == "blur": self.currentField = None # run any filters - if runFilter("editFocusLost", False, self.note, ord): + if gui_hooks.editor_field_did_lose_focus_filter(False, self.note, ord): # something updated the note; update it after a subsequent focus # event has had time to fire self.mw.progress.timer(100, self.loadNoteKeepingFocus, False) else: self.checkValid() else: - runHook("editTimer", self.note) + gui_hooks.editor_typing_timer_did_fire_hook(self.note) self.checkValid() # focused into field? elif cmd.startswith("focus"): (type, num) = cmd.split(":", 1) self.currentField = int(num) - runHook("editFocusGained", self.note, self.currentField) + gui_hooks.editor_field_did_gain_focus_hook(self.note, self.currentField) elif cmd in self._links: self._links[cmd](self) else: @@ -414,7 +416,7 @@ class Editor: self.checkValid() if focusTo is not None: self.web.setFocus() - runHook("loadNote", self) + gui_hooks.editor_note_did_load_hook(self) js = "setFields(%s); setFonts(%s); focusField(%s); setNoteId(%s)" % ( json.dumps(data), @@ -426,7 +428,7 @@ class Editor: def fonts(self): return [ - (runFilter("mungeEditingFontName", f["font"]), f["size"], f["rtl"]) + (gui_hooks.editor_font_for_field_filter(f["font"]), f["size"], f["rtl"]) for f in self.note.model()["flds"] ] @@ -534,7 +536,7 @@ class Editor: self.tags.setText(self.mw.col.tags.join(self.note.tags).strip()) if not self.addMode: self.note.flush() - runHook("tagsUpdated", self.note) + gui_hooks.editor_tags_did_update_hook(self.note) def saveAddModeVars(self): if self.addMode: @@ -1109,7 +1111,7 @@ class EditorWebView(AnkiWebView): a.triggered.connect(self.onCopy) a = m.addAction(_("Paste")) a.triggered.connect(self.onPaste) - runHook("EditorWebView.contextMenuEvent", self, m) + gui_hooks.editor_context_menu_will_show_hook(self, m) m.popup(QCursor.pos()) diff --git a/qt/aqt/gui_hooks.py b/qt/aqt/gui_hooks.py index c0021f396..d8f33b119 100644 --- a/qt/aqt/gui_hooks.py +++ b/qt/aqt/gui_hooks.py @@ -13,7 +13,7 @@ import anki import aqt from anki.cards import Card from anki.hooks import runFilter, runHook -from aqt.qt import QMenu, QShortcut +from aqt.qt import QMenu # New hook/filter handling ############################################################################## @@ -376,7 +376,7 @@ class _EditorFontForFieldFilter: editor_font_for_field_filter = _EditorFontForFieldFilter() -class _EditorNoteDidUpdateHook: +class _EditorNoteDidLoadHook: _hooks: List[Callable[["aqt.editor.Editor"], None]] = [] def append(self, cb: Callable[["aqt.editor.Editor"], None]) -> None: @@ -398,7 +398,7 @@ class _EditorNoteDidUpdateHook: runHook("loadNote", editor) -editor_note_did_update_hook = _EditorNoteDidUpdateHook() +editor_note_did_load_hook = _EditorNoteDidLoadHook() class _EditorShortcutsDidSetupHook: @@ -476,7 +476,7 @@ class _EditorTypingTimerDidFireHook: editor_typing_timer_did_fire_hook = _EditorTypingTimerDidFireHook() -class _MpvIdleHook: +class _MpvDidIdleHook: _hooks: List[Callable[[], None]] = [] def append(self, cb: Callable[[], None]) -> None: @@ -496,7 +496,7 @@ class _MpvIdleHook: raise -mpv_idle_hook = _MpvIdleHook() +mpv_did_idle_hook = _MpvDidIdleHook() class _MpvWillPlayHook: @@ -674,32 +674,6 @@ class _ReviewerQuestionDidShowHook: reviewer_question_did_show_hook = _ReviewerQuestionDidShowHook() -class _SetupStyleFilter: - _hooks: List[Callable[[str], str]] = [] - - def append(self, cb: Callable[[str], str]) -> None: - """(style: str)""" - self._hooks.append(cb) - - def remove(self, cb: Callable[[str], str]) -> None: - self._hooks.remove(cb) - - def __call__(self, style: str) -> str: - for filter in self._hooks: - try: - style = filter(style) - except: - # if the hook fails, remove it - self._hooks.remove(filter) - raise - # legacy support - runFilter("setupStyle", style) - return style - - -setup_style_filter = _SetupStyleFilter() - - class _StateDidChangeHook: _hooks: List[Callable[[str, str], None]] = [] @@ -753,6 +727,8 @@ state_did_reset_hook = _StateDidResetHook() class _StateDidRevertHook: + """Called when user used the undo option to restore to an earlier database state.""" + _hooks: List[Callable[[str], None]] = [] def append(self, cb: Callable[[str], None]) -> None: @@ -778,16 +754,16 @@ state_did_revert_hook = _StateDidRevertHook() class _StateShortcutsWillChangeHook: - _hooks: List[Callable[[str, List[QShortcut]], None]] = [] + _hooks: List[Callable[[str, List[Tuple[str, Callable]]], None]] = [] - def append(self, cb: Callable[[str, List[QShortcut]], None]) -> None: - """(state: str, shortcuts: List[QShortcut])""" + def append(self, cb: Callable[[str, List[Tuple[str, Callable]]], None]) -> None: + """(state: str, shortcuts: List[Tuple[str, Callable]])""" self._hooks.append(cb) - def remove(self, cb: Callable[[str, List[QShortcut]], None]) -> None: + def remove(self, cb: Callable[[str, List[Tuple[str, Callable]]], None]) -> None: self._hooks.remove(cb) - def __call__(self, state: str, shortcuts: List[QShortcut]) -> None: + def __call__(self, state: str, shortcuts: List[Tuple[str, Callable]]) -> None: for hook in self._hooks: try: hook(state, shortcuts) @@ -825,6 +801,32 @@ class _StateWillChangeHook: state_will_change_hook = _StateWillChangeHook() +class _StyleDidSetupFilter: + _hooks: List[Callable[[str], str]] = [] + + def append(self, cb: Callable[[str], str]) -> None: + """(style: str)""" + self._hooks.append(cb) + + def remove(self, cb: Callable[[str], str]) -> None: + self._hooks.remove(cb) + + def __call__(self, style: str) -> str: + for filter in self._hooks: + try: + style = filter(style) + except: + # if the hook fails, remove it + self._hooks.remove(filter) + raise + # legacy support + runFilter("setupStyle", style) + return style + + +style_did_setup_filter = _StyleDidSetupFilter() + + class _UndoStateDidChangeHook: _hooks: List[Callable[[bool], None]] = [] diff --git a/qt/aqt/main.py b/qt/aqt/main.py index 3ede4ea24..4572cb1ad 100644 --- a/qt/aqt/main.py +++ b/qt/aqt/main.py @@ -26,7 +26,7 @@ import aqt.toolbar import aqt.webview from anki import hooks from anki.collection import _Collection -from anki.hooks import addHook, runFilter, runHook +from anki.hooks import addHook, runHook from anki.lang import _, ngettext from anki.storage import Collection from anki.utils import devMode, ids2str, intTime, isMac, isWin, splitFields @@ -341,7 +341,7 @@ close the profile or restart Anki.""" else: self.handleImport(self.pendingImport) self.pendingImport = None - runHook("profileLoaded") + gui_hooks.profile_did_open_hook() if onsuccess: onsuccess() @@ -350,7 +350,7 @@ close the profile or restart Anki.""" self._unloadProfile() onsuccess() - runHook("unloadProfile") + gui_hooks.profile_will_close_hook() self.unloadCollection(callback) def _unloadProfile(self) -> None: @@ -560,11 +560,11 @@ from the profile screen." cleanup(state) self.clearStateShortcuts() self.state = state - runHook("beforeStateChange", state, oldState, *args) + gui_hooks.state_will_change_hook(state, oldState) getattr(self, "_" + state + "State")(oldState, *args) if state != "resetRequired": self.bottomWeb.show() - runHook("afterStateChange", state, oldState, *args) + gui_hooks.state_did_change_hook(state, oldState) def _deckBrowserState(self, oldState: str) -> None: self.deckBrowser.show() @@ -574,7 +574,7 @@ from the profile screen." self.enableColMenuItems() # ensure cwd is set if media dir exists self.col.media.dir() - runHook("colLoading", self.col) + gui_hooks.collection_did_load_hook(self.col) self.moveToState("overview") def _selectedDeck(self) -> Optional[Dict[str, Any]]: @@ -605,7 +605,7 @@ from the profile screen." if self.col: if not guiOnly: self.col.reset() - runHook("reset") + gui_hooks.state_did_reset_hook() self.maybeEnableUndo() self.moveToState(self.state) @@ -847,7 +847,7 @@ QTreeWidget { """ # allow addons to modify the styling - buf = runFilter("setupStyle", buf) + buf = gui_hooks.style_did_setup_filter(buf) # allow users to extend styling p = os.path.join(aqt.mw.pm.base, "style.css") @@ -884,6 +884,8 @@ QTreeWidget { return qshortcuts def setStateShortcuts(self, shortcuts: List[Tuple[str, Callable]]) -> None: + gui_hooks.state_shortcuts_will_change_hook(self.state, shortcuts) + # legacy hook runHook(self.state + "StateShortcuts", shortcuts) self.stateShortcuts = self.applyShortcuts(shortcuts) @@ -926,22 +928,22 @@ QTreeWidget { self.col.sched.reset() self.reviewer.cardQueue.append(card) self.reviewer.nextCard() - runHook("revertedCard", cid) + gui_hooks.review_did_undo_hook(cid) else: self.reset() tooltip(_("Reverted to state prior to '%s'.") % n.lower()) - runHook("revertedState", n) + gui_hooks.state_did_revert_hook(n) self.maybeEnableUndo() def maybeEnableUndo(self) -> None: if self.col and self.col.undoName(): self.form.actionUndo.setText(_("Undo %s") % self.col.undoName()) self.form.actionUndo.setEnabled(True) - runHook("undoState", True) + gui_hooks.undo_state_did_change_hook(True) else: self.form.actionUndo.setText(_("Undo")) self.form.actionUndo.setEnabled(False) - runHook("undoState", False) + gui_hooks.undo_state_did_change_hook(False) def checkpoint(self, name): self.col.save(name) @@ -1156,7 +1158,7 @@ Difference to correct time: %s.""" hooks.odue_invalid_hook.append(self.onOdueInvalid) gui_hooks.mpv_will_play_hook.append(self.on_mpv_will_play) - gui_hooks.mpv_idle_hook.append(self.on_mpv_idle) + gui_hooks.mpv_did_idle_hook.append(self.on_mpv_idle) self._activeWindowOnPlay: Optional[QWidget] = None diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index 200b3ec47..42d7fc827 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -696,7 +696,6 @@ time = %(time)d; self._addMenuItems(m, opts) gui_hooks.reviewer_context_menu_will_show_hook(self, m) - runHook("Reviewer.contextMenuEvent", self, m) qtMenuShortcutWorkaround(m) m.exec_(QCursor.pos()) diff --git a/qt/aqt/sound.py b/qt/aqt/sound.py index 09182c6df..fb19b18ef 100644 --- a/qt/aqt/sound.py +++ b/qt/aqt/sound.py @@ -173,7 +173,7 @@ class MpvManager(MPV): self.command("seek", secs, "relative") def on_idle(self) -> None: - gui_hooks.mpv_idle_hook() + gui_hooks.mpv_did_idle_hook() def setMpvConfigBase(base) -> None: diff --git a/qt/tools/genhooks_gui.py b/qt/tools/genhooks_gui.py index 480c93bfd..82ffcdb6c 100644 --- a/qt/tools/genhooks_gui.py +++ b/qt/tools/genhooks_gui.py @@ -17,7 +17,7 @@ from tools.hookslib import Hook, update_file ###################################################################### hooks = [ - Hook(name="mpv_idle"), + Hook(name="mpv_did_idle"), Hook(name="mpv_will_play", args=["file: str"], legacy_hook="mpvWillPlay"), Hook( name="reviewer_question_did_show", @@ -83,14 +83,19 @@ hooks = [ # different sig to original Hook( name="state_shortcuts_will_change", - args=["state: str", "shortcuts: List[QShortcut]"], + 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"], legacy_hook="revertedState"), + Hook( + name="state_did_revert", + args=["action: str"], + legacy_hook="revertedState", + doc="Called when user used the undo option to restore to an earlier database state.", + ), Hook( name="state_did_reset", legacy_hook="reset", @@ -101,7 +106,7 @@ hooks = [ ), Hook(name="review_did_undo", args=["card_id: int"], legacy_hook="revertedCard"), Hook( - name="setup_style", + name="style_did_setup", args=["style: str"], return_type="str", legacy_hook="setupStyle", @@ -153,7 +158,7 @@ hooks = [ legacy_hook="editFocusLost", ), Hook( - name="editor_note_did_update", + name="editor_note_did_load", args=["editor: aqt.editor.Editor"], legacy_hook="loadNote", ),