diff --git a/pylib/anki/collection.py b/pylib/anki/collection.py index 09cbcb19c..dc3da2ade 100644 --- a/pylib/anki/collection.py +++ b/pylib/anki/collection.py @@ -372,7 +372,7 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""", strids = ids2str(ids) # we need to log these independently of cards, as one side may have # more card templates - hooks.notes_will_delete(self, ids) + hooks.notes_will_be_deleted(self, ids) self._logRem(ids, REM_NOTE) self.db.execute("delete from notes where id in %s" % strids) @@ -668,9 +668,7 @@ where c.nid = n.id and c.id in %s group by nid""" fields = runFilter("mungeFields", fields, model, data, self) # allow add-ons to modify the available fields & templates - (qfmt, afmt) = hooks.card_template_will_render( - (qfmt, afmt), fields, model, data - ) + (qfmt, afmt) = hooks.card_will_render((qfmt, afmt), fields, model, data) # render fields qatext = render_card(self, qfmt, afmt, fields, card_ord) @@ -678,7 +676,7 @@ where c.nid = n.id and c.id in %s group by nid""" # allow add-ons to modify the generated result for type in "q", "a": - ret[type] = hooks.card_template_did_render( + ret[type] = hooks.card_did_render( ret[type], type, fields, model, data, self ) diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index f53bae2d9..c2998896f 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -165,7 +165,7 @@ class DeckManager: self.decks[str(id)] = g self.save(g) self.maybeAddToActive() - hooks.deck_did_create(g) + hooks.deck_added(g) return int(id) def rem(self, did: int, cardsToo: bool = False, childrenToo: bool = True) -> None: diff --git a/pylib/anki/exporting.py b/pylib/anki/exporting.py index 5d5ad6153..8b2ae7792 100644 --- a/pylib/anki/exporting.py +++ b/pylib/anki/exporting.py @@ -417,5 +417,5 @@ def exporters() -> List[Tuple[str, Any]]: id(TextNoteExporter), id(TextCardExporter), ] - hooks.exporters_list_did_create(exps) + hooks.exporters_list_created(exps) return exps diff --git a/pylib/anki/find.py b/pylib/anki/find.py index 3e984a3fa..ccd6844d3 100644 --- a/pylib/anki/find.py +++ b/pylib/anki/find.py @@ -40,7 +40,7 @@ class Finder: flag=self._findFlag, ) self.search["is"] = self._findCardState - hooks.search_terms_did_prepare(self.search) + hooks.search_terms_prepared(self.search) def findCards(self, query, order=False) -> Any: "Return a list of card ids for QUERY." diff --git a/pylib/anki/hooks.py b/pylib/anki/hooks.py index 014596020..2539605f8 100644 --- a/pylib/anki/hooks.py +++ b/pylib/anki/hooks.py @@ -54,31 +54,7 @@ class _CardDidLeechHook: card_did_leech = _CardDidLeechHook() -class _CardOdueWasInvalidHook: - _hooks: List[Callable[[], None]] = [] - - def append(self, cb: Callable[[], None]) -> None: - """()""" - self._hooks.append(cb) - - def remove(self, cb: Callable[[], None]) -> None: - if cb in self._hooks: - 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 - - -card_odue_was_invalid = _CardOdueWasInvalidHook() - - -class _CardTemplateDidRenderFilter: +class _CardDidRenderFilter: """Can modify the resulting text after rendering completes.""" _hooks: List[ @@ -150,10 +126,34 @@ class _CardTemplateDidRenderFilter: return text -card_template_did_render = _CardTemplateDidRenderFilter() +card_did_render = _CardDidRenderFilter() -class _CardTemplateWillRenderFilter: +class _CardOdueWasInvalidHook: + _hooks: List[Callable[[], None]] = [] + + def append(self, cb: Callable[[], None]) -> None: + """()""" + self._hooks.append(cb) + + def remove(self, cb: Callable[[], None]) -> None: + if cb in self._hooks: + 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 + + +card_odue_was_invalid = _CardOdueWasInvalidHook() + + +class _CardWillRenderFilter: """Can modify the available fields and question/answer templates prior to rendering.""" _hooks: List[ @@ -197,10 +197,10 @@ class _CardTemplateWillRenderFilter: return templates -card_template_will_render = _CardTemplateWillRenderFilter() +card_will_render = _CardWillRenderFilter() -class _DeckDidCreateHook: +class _DeckAddedHook: _hooks: List[Callable[[Dict[str, Any]], None]] = [] def append(self, cb: Callable[[Dict[str, Any]], None]) -> None: @@ -223,10 +223,10 @@ class _DeckDidCreateHook: runHook("newDeck") -deck_did_create = _DeckDidCreateHook() +deck_added = _DeckAddedHook() -class _ExportersListDidCreateHook: +class _ExportersListCreatedHook: _hooks: List[Callable[[List[Tuple[str, Any]]], None]] = [] def append(self, cb: Callable[[List[Tuple[str, Any]]], None]) -> None: @@ -249,10 +249,10 @@ class _ExportersListDidCreateHook: runHook("exportersList", exporters) -exporters_list_did_create = _ExportersListDidCreateHook() +exporters_list_created = _ExportersListCreatedHook() -class _FieldWillBeFilteredFilter: +class _FieldFilterFilter: _hooks: List[Callable[[str, str, str, Dict[str, str]], str]] = [] def append(self, cb: Callable[[str, str, str, Dict[str, str]], str]) -> None: @@ -276,7 +276,7 @@ class _FieldWillBeFilteredFilter: return field_text -field_will_be_filtered = _FieldWillBeFilteredFilter() +field_filter = _FieldFilterFilter() class _HttpDataDidReceiveHook: @@ -351,7 +351,7 @@ class _MediaFilesDidExportHook: media_files_did_export = _MediaFilesDidExportHook() -class _NoteTypeDidCreateHook: +class _NoteTypeAddedHook: _hooks: List[Callable[[Dict[str, Any]], None]] = [] def append(self, cb: Callable[[Dict[str, Any]], None]) -> None: @@ -374,10 +374,10 @@ class _NoteTypeDidCreateHook: runHook("newModel") -note_type_did_create = _NoteTypeDidCreateHook() +note_type_added = _NoteTypeAddedHook() -class _NotesWillDeleteHook: +class _NotesWillBeDeletedHook: _hooks: List[Callable[["anki.storage._Collection", List[int]], None]] = [] def append( @@ -404,7 +404,7 @@ class _NotesWillDeleteHook: runHook("remNotes", col, ids) -notes_will_delete = _NotesWillDeleteHook() +notes_will_be_deleted = _NotesWillBeDeletedHook() class _SchemaWillChangeFilter: @@ -432,7 +432,7 @@ class _SchemaWillChangeFilter: schema_will_change = _SchemaWillChangeFilter() -class _SearchTermsDidPrepareHook: +class _SearchTermsPreparedHook: _hooks: List[Callable[[Dict[str, Callable]], None]] = [] def append(self, cb: Callable[[Dict[str, Callable]], None]) -> None: @@ -455,7 +455,7 @@ class _SearchTermsDidPrepareHook: runHook("search", searches) -search_terms_did_prepare = _SearchTermsDidPrepareHook() +search_terms_prepared = _SearchTermsPreparedHook() class _SyncProgressDidChangeHook: @@ -510,7 +510,7 @@ class _SyncStageDidChangeHook: sync_stage_did_change = _SyncStageDidChangeHook() -class _TagDidCreateHook: +class _TagAddedHook: _hooks: List[Callable[[str], None]] = [] def append(self, cb: Callable[[str], None]) -> None: @@ -533,7 +533,7 @@ class _TagDidCreateHook: runHook("newTag") -tag_did_create = _TagDidCreateHook() +tag_added = _TagAddedHook() # @@AUTOGEN@@ # Legacy hook handling diff --git a/pylib/anki/latex.py b/pylib/anki/latex.py index 0e2831447..917ace15f 100644 --- a/pylib/anki/latex.py +++ b/pylib/anki/latex.py @@ -184,4 +184,4 @@ def _errMsg(type: str, texpath: str) -> Any: # setup q/a filter - type ignored due to import cycle -hooks.card_template_did_render.append(mungeQA) # type: ignore +hooks.card_did_render.append(mungeQA) # type: ignore diff --git a/pylib/anki/models.py b/pylib/anki/models.py index b355d42a2..d5ec5c0ea 100644 --- a/pylib/anki/models.py +++ b/pylib/anki/models.py @@ -107,7 +107,7 @@ class ModelManager: if templates: self._syncTemplates(m) self.changed = True - hooks.note_type_did_create(m) + hooks.note_type_added(m) def flush(self) -> None: "Flush the registry if any models were changed." diff --git a/pylib/anki/tags.py b/pylib/anki/tags.py index 218c873fa..864c86b11 100644 --- a/pylib/anki/tags.py +++ b/pylib/anki/tags.py @@ -50,7 +50,7 @@ class TagManager: self.tags[t] = self.col.usn() if usn is None else usn self.changed = True if found: - hooks.tag_did_create(t) # pylint: disable=undefined-loop-variable + hooks.tag_added(t) # pylint: disable=undefined-loop-variable def all(self) -> List: return list(self.tags.keys()) diff --git a/pylib/anki/template.py b/pylib/anki/template.py index b483551a1..7352c79b9 100644 --- a/pylib/anki/template.py +++ b/pylib/anki/template.py @@ -72,7 +72,7 @@ def apply_custom_filters( field_text = node.current_text for filter_name in node.filters: - field_text = hooks.field_will_be_filtered( + field_text = hooks.field_filter( field_text, node.field_name, filter_name, fields ) # legacy hook - the second and fifth argument are no longer used diff --git a/pylib/tools/genhooks.py b/pylib/tools/genhooks.py index 3a24eb790..8948a9d36 100644 --- a/pylib/tools/genhooks.py +++ b/pylib/tools/genhooks.py @@ -21,29 +21,29 @@ hooks = [ Hook(name="card_odue_was_invalid"), Hook(name="schema_will_change", args=["proceed: bool"], return_type="bool"), Hook( - name="notes_will_delete", + name="notes_will_be_deleted", args=["col: anki.storage._Collection", "ids: List[int]"], legacy_hook="remNotes", ), Hook( - name="deck_did_create", + name="deck_added", args=["deck: Dict[str, Any]"], legacy_hook="newDeck", legacy_no_args=True, ), Hook(name="media_files_did_export", args=["count: int"]), Hook( - name="exporters_list_did_create", + name="exporters_list_created", args=["exporters: List[Tuple[str, Any]]"], legacy_hook="exportersList", ), Hook( - name="search_terms_did_prepare", + name="search_terms_prepared", args=["searches: Dict[str, Callable]"], legacy_hook="search", ), Hook( - name="note_type_did_create", + name="note_type_added", args=["notetype: Dict[str, Any]"], legacy_hook="newModel", legacy_no_args=True, @@ -53,13 +53,10 @@ hooks = [ Hook(name="http_data_did_send", args=["bytes: int"]), Hook(name="http_data_did_receive", args=["bytes: int"]), Hook( - name="tag_did_create", - args=["tag: str"], - legacy_hook="newTag", - legacy_no_args=True, + name="tag_added", args=["tag: str"], legacy_hook="newTag", legacy_no_args=True, ), Hook( - name="card_template_will_render", + name="card_will_render", args=[ "templates: Tuple[str, str]", "fields: Dict[str, str]", @@ -70,7 +67,7 @@ hooks = [ doc="Can modify the available fields and question/answer templates prior to rendering.", ), Hook( - name="card_template_did_render", + name="card_did_render", args=[ "text: str", "side: str", @@ -86,7 +83,7 @@ hooks = [ doc="Can modify the resulting text after rendering completes.", ), Hook( - name="field_will_be_filtered", + name="field_filter", args=[ "field_text: str", "field_name: str", diff --git a/qt/aqt/addcards.py b/qt/aqt/addcards.py index fce0bad75..50df50134 100644 --- a/qt/aqt/addcards.py +++ b/qt/aqt/addcards.py @@ -156,7 +156,7 @@ class AddCards(QDialog): else: a = m.addAction(_("(Note deleted)")) a.setEnabled(False) - gui_hooks.add_cards_history_menu_will_show(self, m) + gui_hooks.add_cards_will_show_history_menu(self, m) m.exec_(self.historyButton.mapToGlobal(QPoint(0, 0))) def editHistory(self, nid): @@ -196,7 +196,7 @@ question on all cards.""" self.addHistory(note) self.mw.requireReset() self.previousNote = note - gui_hooks.add_cards_note_did_add(note) + gui_hooks.add_cards_did_add_note(note) return note def addCards(self): diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index a420b916c..a7c5c57fe 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -653,7 +653,7 @@ class Browser(QMainWindow): m.addSeparator() for act in self.form.menu_Notes.actions(): m.addAction(act) - gui_hooks.browser_context_menu_will_show(self, m) + gui_hooks.browser_will_show_context_menu(self, m) qtMenuShortcutWorkaround(m) m.exec_(QCursor.pos()) @@ -844,7 +844,7 @@ class Browser(QMainWindow): self.editor.card = self.card self.singleCard = True self._updateFlagsMenu() - gui_hooks.browser_row_did_change(self) + gui_hooks.browser_did_change_row(self) self._renderPreview(True) def refreshCurrentCard(self, note): @@ -1716,7 +1716,9 @@ where id in %s""" play(audio) txt = mungeQA(self.col, txt) - gui_hooks.card_text(txt, c, "preview" + self._previewState.capitalize()) + gui_hooks.card_will_show( + txt, c, "preview" + self._previewState.capitalize() + ) self._lastPreviewState = self._previewStateAndMod() self._updatePreviewButtons() self._previewWeb.eval("{}({},'{}');".format(func, json.dumps(txt), bodyclass)) @@ -2020,22 +2022,22 @@ update cards set usn=?, mod=?, did=? where id in """ def setupHooks(self): gui_hooks.undo_state_did_change.append(self.onUndoState) gui_hooks.state_did_reset.append(self.onReset) - gui_hooks.editor_typing_timer_did_fire.append(self.refreshCurrentCard) - gui_hooks.editor_note_did_load.append(self.onLoadNote) - gui_hooks.editor_field_did_lose_focus.append(self.refreshCurrentCard) - hooks.tag_did_create.append(self.maybeRefreshSidebar) - hooks.note_type_did_create.append(self.maybeRefreshSidebar) - hooks.deck_did_create.append(self.maybeRefreshSidebar) + gui_hooks.editor_did_fire_typing_timer.append(self.refreshCurrentCard) + gui_hooks.editor_did_load_note.append(self.onLoadNote) + gui_hooks.editor_did_unfocus_field.append(self.refreshCurrentCard) + hooks.tag_added.append(self.maybeRefreshSidebar) + hooks.note_type_added.append(self.maybeRefreshSidebar) + hooks.deck_added.append(self.maybeRefreshSidebar) def teardownHooks(self): gui_hooks.undo_state_did_change.remove(self.onUndoState) gui_hooks.state_did_reset.remove(self.onReset) - gui_hooks.editor_typing_timer_did_fire.remove(self.refreshCurrentCard) - gui_hooks.editor_note_did_load.remove(self.onLoadNote) - gui_hooks.editor_field_did_lose_focus.remove(self.refreshCurrentCard) - hooks.tag_did_create.remove(self.maybeRefreshSidebar) - hooks.note_type_did_create.remove(self.maybeRefreshSidebar) - hooks.deck_did_create.remove(self.maybeRefreshSidebar) + gui_hooks.editor_did_fire_typing_timer.remove(self.refreshCurrentCard) + gui_hooks.editor_did_load_note.remove(self.onLoadNote) + gui_hooks.editor_did_unfocus_field.remove(self.refreshCurrentCard) + hooks.tag_added.remove(self.maybeRefreshSidebar) + hooks.note_type_added.remove(self.maybeRefreshSidebar) + hooks.deck_added.remove(self.maybeRefreshSidebar) def onUndoState(self, on): self.form.actionUndo.setEnabled(on) diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py index dafc0bac6..39a991750 100644 --- a/qt/aqt/clayout.py +++ b/qt/aqt/clayout.py @@ -335,10 +335,10 @@ Please create a new card type first.""" bodyclass = bodyClass(self.mw.col, c) q = ti(mungeQA(self.mw.col, c.q(reload=True))) - q = gui_hooks.card_text(q, c, "clayoutQuestion") + q = gui_hooks.card_will_show(q, c, "clayoutQuestion") a = ti(mungeQA(self.mw.col, c.a()), type="a") - a = gui_hooks.card_text(a, c, "clayoutAnswer") + a = gui_hooks.card_will_show(a, c, "clayoutAnswer") # use _showAnswer to avoid the longer delay self.pform.frontWeb.eval("_showAnswer(%s,'%s');" % (json.dumps(q), bodyclass)) diff --git a/qt/aqt/deckbrowser.py b/qt/aqt/deckbrowser.py index 33a6ba96a..9c8d9cfe5 100644 --- a/qt/aqt/deckbrowser.py +++ b/qt/aqt/deckbrowser.py @@ -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)) - gui_hooks.deck_browser_options_menu_will_show(m, did) + gui_hooks.deck_browser_will_show_options_menu(m, did) m.exec_(QCursor.pos()) def _export(self, did): diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index 81dcfab78..98b2a8671 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -141,7 +141,7 @@ class Editor: self._addButton("more", "more"), ] ) - gui_hooks.editor_buttons_did_init(righttopbtns, self) + gui_hooks.editor_did_init_buttons(righttopbtns, self) # legacy filter righttopbtns = runFilter("setupEditorButtons", righttopbtns, self) topbuts = """ @@ -285,7 +285,7 @@ class Editor: ("Ctrl+Shift+X", self.onHtmlEdit), ("Ctrl+Shift+T", self.onFocusTags, True), ] - gui_hooks.editor_shortcuts_did_init(cuts, self) + gui_hooks.editor_did_init_shortcuts(cuts, self) for row in cuts: if len(row) == 2: keys, fn = row # pylint: disable=unbalanced-tuple-unpacking @@ -358,20 +358,20 @@ class Editor: if type == "blur": self.currentField = None # run any filters - if gui_hooks.editor_field_did_lose_focus(False, self.note, ord): + if gui_hooks.editor_did_unfocus_field(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: - gui_hooks.editor_typing_timer_did_fire(self.note) + gui_hooks.editor_did_fire_typing_timer(self.note) self.checkValid() # focused into field? elif cmd.startswith("focus"): (type, num) = cmd.split(":", 1) self.currentField = int(num) - gui_hooks.editor_field_did_gain_focus(self.note, self.currentField) + gui_hooks.editor_did_focus_field(self.note, self.currentField) elif cmd in self._links: self._links[cmd](self) else: @@ -416,7 +416,7 @@ class Editor: self.checkValid() if focusTo is not None: self.web.setFocus() - gui_hooks.editor_note_did_load(self) + gui_hooks.editor_did_load_note(self) js = "setFields(%s); setFonts(%s); focusField(%s); setNoteId(%s)" % ( json.dumps(data), @@ -428,7 +428,7 @@ class Editor: def fonts(self): return [ - (gui_hooks.editor_font_for_field(f["font"]), f["size"], f["rtl"]) + (gui_hooks.editor_will_use_font_for_field(f["font"]), f["size"], f["rtl"]) for f in self.note.model()["flds"] ] @@ -536,7 +536,7 @@ class Editor: self.tags.setText(self.mw.col.tags.join(self.note.tags).strip()) if not self.addMode: self.note.flush() - gui_hooks.editor_tags_did_update(self.note) + gui_hooks.editor_did_update_tags(self.note) def saveAddModeVars(self): if self.addMode: @@ -1111,7 +1111,7 @@ class EditorWebView(AnkiWebView): a.triggered.connect(self.onCopy) a = m.addAction(_("Paste")) a.triggered.connect(self.onPaste) - gui_hooks.editor_context_menu_will_show(self, m) + gui_hooks.editor_will_show_context_menu(self, m) m.popup(QCursor.pos()) @@ -1122,4 +1122,4 @@ def fontMungeHack(font): return re.sub(" L$", " Light", font) -gui_hooks.editor_font_for_field.append(fontMungeHack) +gui_hooks.editor_will_use_font_for_field.append(fontMungeHack) diff --git a/qt/aqt/gui_hooks.py b/qt/aqt/gui_hooks.py index bf27cefd9..1a4cb2ce5 100644 --- a/qt/aqt/gui_hooks.py +++ b/qt/aqt/gui_hooks.py @@ -23,33 +23,7 @@ from aqt.qt import QMenu # @@AUTOGEN@@ -class _AddCardsHistoryMenuWillShowHook: - _hooks: List[Callable[["aqt.addcards.AddCards", QMenu], None]] = [] - - def append(self, cb: Callable[["aqt.addcards.AddCards", QMenu], None]) -> None: - """(addcards: aqt.addcards.AddCards, menu: QMenu)""" - self._hooks.append(cb) - - def remove(self, cb: Callable[["aqt.addcards.AddCards", QMenu], None]) -> None: - if cb in self._hooks: - self._hooks.remove(cb) - - def __call__(self, addcards: aqt.addcards.AddCards, menu: QMenu) -> None: - for hook in self._hooks: - try: - hook(addcards, menu) - except: - # if the hook fails, remove it - self._hooks.remove(hook) - raise - # legacy support - runHook("AddCards.onHistory", addcards, menu) - - -add_cards_history_menu_will_show = _AddCardsHistoryMenuWillShowHook() - - -class _AddCardsNoteDidAddHook: +class _AddCardsDidAddNoteHook: _hooks: List[Callable[["anki.notes.Note"], None]] = [] def append(self, cb: Callable[["anki.notes.Note"], None]) -> None: @@ -72,33 +46,59 @@ class _AddCardsNoteDidAddHook: runHook("AddCards.noteAdded", note) -add_cards_note_did_add = _AddCardsNoteDidAddHook() +add_cards_did_add_note = _AddCardsDidAddNoteHook() -class _BrowserContextMenuWillShowHook: - _hooks: List[Callable[["aqt.browser.Browser", QMenu], None]] = [] +class _AddCardsWillShowHistoryMenuHook: + _hooks: List[Callable[["aqt.addcards.AddCards", QMenu], None]] = [] - def append(self, cb: Callable[["aqt.browser.Browser", QMenu], None]) -> None: - """(browser: aqt.browser.Browser, menu: QMenu)""" + def append(self, cb: Callable[["aqt.addcards.AddCards", QMenu], None]) -> None: + """(addcards: aqt.addcards.AddCards, menu: QMenu)""" self._hooks.append(cb) - def remove(self, cb: Callable[["aqt.browser.Browser", QMenu], None]) -> None: + def remove(self, cb: Callable[["aqt.addcards.AddCards", QMenu], None]) -> None: if cb in self._hooks: self._hooks.remove(cb) - def __call__(self, browser: aqt.browser.Browser, menu: QMenu) -> None: + def __call__(self, addcards: aqt.addcards.AddCards, menu: QMenu) -> None: for hook in self._hooks: try: - hook(browser, menu) + hook(addcards, menu) except: # if the hook fails, remove it self._hooks.remove(hook) raise # legacy support - runHook("browser.onContextMenu", browser, menu) + runHook("AddCards.onHistory", addcards, menu) -browser_context_menu_will_show = _BrowserContextMenuWillShowHook() +add_cards_will_show_history_menu = _AddCardsWillShowHistoryMenuHook() + + +class _BrowserDidChangeRowHook: + _hooks: List[Callable[["aqt.browser.Browser"], None]] = [] + + def append(self, cb: Callable[["aqt.browser.Browser"], None]) -> None: + """(browser: aqt.browser.Browser)""" + self._hooks.append(cb) + + def remove(self, cb: Callable[["aqt.browser.Browser"], None]) -> None: + if cb in self._hooks: + self._hooks.remove(cb) + + def __call__(self, browser: aqt.browser.Browser) -> None: + for hook in self._hooks: + try: + hook(browser) + except: + # if the hook fails, remove it + self._hooks.remove(hook) + raise + # legacy support + runHook("browser.rowChanged", browser) + + +browser_did_change_row = _BrowserDidChangeRowHook() class _BrowserMenusDidInitHook: @@ -127,33 +127,33 @@ class _BrowserMenusDidInitHook: browser_menus_did_init = _BrowserMenusDidInitHook() -class _BrowserRowDidChangeHook: - _hooks: List[Callable[["aqt.browser.Browser"], None]] = [] +class _BrowserWillShowContextMenuHook: + _hooks: List[Callable[["aqt.browser.Browser", QMenu], None]] = [] - def append(self, cb: Callable[["aqt.browser.Browser"], None]) -> None: - """(browser: aqt.browser.Browser)""" + def append(self, cb: Callable[["aqt.browser.Browser", QMenu], None]) -> None: + """(browser: aqt.browser.Browser, menu: QMenu)""" self._hooks.append(cb) - def remove(self, cb: Callable[["aqt.browser.Browser"], None]) -> None: + def remove(self, cb: Callable[["aqt.browser.Browser", QMenu], None]) -> None: if cb in self._hooks: self._hooks.remove(cb) - def __call__(self, browser: aqt.browser.Browser) -> None: + def __call__(self, browser: aqt.browser.Browser, menu: QMenu) -> None: for hook in self._hooks: try: - hook(browser) + hook(browser, menu) except: # if the hook fails, remove it self._hooks.remove(hook) raise # legacy support - runHook("browser.rowChanged", browser) + runHook("browser.onContextMenu", browser, menu) -browser_row_did_change = _BrowserRowDidChangeHook() +browser_will_show_context_menu = _BrowserWillShowContextMenuHook() -class _CardTextFilter: +class _CardWillShowFilter: """Can modify card text before review/preview.""" _hooks: List[Callable[[str, Card, str], str]] = [] @@ -179,7 +179,7 @@ class _CardTextFilter: return text -card_text = _CardTextFilter() +card_will_show = _CardWillShowFilter() class _CollectionDidLoadHook: @@ -234,7 +234,7 @@ class _CurrentNoteTypeDidChangeHook: current_note_type_did_change = _CurrentNoteTypeDidChangeHook() -class _DeckBrowserOptionsMenuWillShowHook: +class _DeckBrowserWillShowOptionsMenuHook: _hooks: List[Callable[[QMenu, int], None]] = [] def append(self, cb: Callable[[QMenu, int], None]) -> None: @@ -257,60 +257,36 @@ class _DeckBrowserOptionsMenuWillShowHook: runHook("showDeckOptions", menu, deck_id) -deck_browser_options_menu_will_show = _DeckBrowserOptionsMenuWillShowHook() +deck_browser_will_show_options_menu = _DeckBrowserWillShowOptionsMenuHook() -class _EditorButtonsDidInitHook: - _hooks: List[Callable[[List, "aqt.editor.Editor"], None]] = [] +class _EditorDidFireTypingTimerHook: + _hooks: List[Callable[["anki.notes.Note"], None]] = [] - def append(self, cb: Callable[[List, "aqt.editor.Editor"], None]) -> None: - """(buttons: List, editor: aqt.editor.Editor)""" + def append(self, cb: Callable[["anki.notes.Note"], None]) -> None: + """(note: anki.notes.Note)""" self._hooks.append(cb) - def remove(self, cb: Callable[[List, "aqt.editor.Editor"], None]) -> None: + def remove(self, cb: Callable[["anki.notes.Note"], None]) -> None: if cb in self._hooks: self._hooks.remove(cb) - def __call__(self, buttons: List, editor: aqt.editor.Editor) -> None: + def __call__(self, note: anki.notes.Note) -> None: for hook in self._hooks: try: - hook(buttons, editor) - except: - # if the hook fails, remove it - self._hooks.remove(hook) - raise - - -editor_buttons_did_init = _EditorButtonsDidInitHook() - - -class _EditorContextMenuWillShowHook: - _hooks: List[Callable[["aqt.editor.EditorWebView", QMenu], None]] = [] - - def append(self, cb: Callable[["aqt.editor.EditorWebView", QMenu], None]) -> None: - """(editor_webview: aqt.editor.EditorWebView, menu: QMenu)""" - self._hooks.append(cb) - - def remove(self, cb: Callable[["aqt.editor.EditorWebView", QMenu], None]) -> None: - if cb in self._hooks: - self._hooks.remove(cb) - - def __call__(self, editor_webview: aqt.editor.EditorWebView, menu: QMenu) -> None: - for hook in self._hooks: - try: - hook(editor_webview, menu) + hook(note) except: # if the hook fails, remove it self._hooks.remove(hook) raise # legacy support - runHook("EditorWebView.contextMenuEvent", editor_webview, menu) + runHook("editTimer", note) -editor_context_menu_will_show = _EditorContextMenuWillShowHook() +editor_did_fire_typing_timer = _EditorDidFireTypingTimerHook() -class _EditorFieldDidGainFocusHook: +class _EditorDidFocusFieldHook: _hooks: List[Callable[["anki.notes.Note", int], None]] = [] def append(self, cb: Callable[["anki.notes.Note", int], None]) -> None: @@ -333,10 +309,86 @@ class _EditorFieldDidGainFocusHook: runHook("editFocusGained", note, current_field_idx) -editor_field_did_gain_focus = _EditorFieldDidGainFocusHook() +editor_did_focus_field = _EditorDidFocusFieldHook() -class _EditorFieldDidLoseFocusFilter: +class _EditorDidInitButtonsHook: + _hooks: List[Callable[[List, "aqt.editor.Editor"], None]] = [] + + def append(self, cb: Callable[[List, "aqt.editor.Editor"], None]) -> None: + """(buttons: List, editor: aqt.editor.Editor)""" + self._hooks.append(cb) + + def remove(self, cb: Callable[[List, "aqt.editor.Editor"], None]) -> None: + if cb in self._hooks: + self._hooks.remove(cb) + + def __call__(self, buttons: List, editor: aqt.editor.Editor) -> None: + for hook in self._hooks: + try: + hook(buttons, editor) + except: + # if the hook fails, remove it + self._hooks.remove(hook) + raise + + +editor_did_init_buttons = _EditorDidInitButtonsHook() + + +class _EditorDidInitShortcutsHook: + _hooks: List[Callable[[List[Tuple], "aqt.editor.Editor"], None]] = [] + + def append(self, cb: Callable[[List[Tuple], "aqt.editor.Editor"], None]) -> None: + """(shortcuts: List[Tuple], editor: aqt.editor.Editor)""" + self._hooks.append(cb) + + def remove(self, cb: Callable[[List[Tuple], "aqt.editor.Editor"], None]) -> None: + if cb in self._hooks: + self._hooks.remove(cb) + + def __call__(self, shortcuts: List[Tuple], editor: aqt.editor.Editor) -> None: + for hook in self._hooks: + try: + hook(shortcuts, editor) + except: + # if the hook fails, remove it + self._hooks.remove(hook) + raise + # legacy support + runHook("setupEditorShortcuts", shortcuts, editor) + + +editor_did_init_shortcuts = _EditorDidInitShortcutsHook() + + +class _EditorDidLoadNoteHook: + _hooks: List[Callable[["aqt.editor.Editor"], None]] = [] + + def append(self, cb: Callable[["aqt.editor.Editor"], None]) -> None: + """(editor: aqt.editor.Editor)""" + self._hooks.append(cb) + + def remove(self, cb: Callable[["aqt.editor.Editor"], None]) -> None: + if cb in self._hooks: + self._hooks.remove(cb) + + def __call__(self, editor: aqt.editor.Editor) -> None: + for hook in self._hooks: + try: + hook(editor) + except: + # if the hook fails, remove it + self._hooks.remove(hook) + raise + # legacy support + runHook("loadNote", editor) + + +editor_did_load_note = _EditorDidLoadNoteHook() + + +class _EditorDidUnfocusFieldFilter: _hooks: List[Callable[[bool, "anki.notes.Note", int], bool]] = [] def append(self, cb: Callable[[bool, "anki.notes.Note", int], bool]) -> None: @@ -362,10 +414,62 @@ class _EditorFieldDidLoseFocusFilter: return changed -editor_field_did_lose_focus = _EditorFieldDidLoseFocusFilter() +editor_did_unfocus_field = _EditorDidUnfocusFieldFilter() -class _EditorFontForFieldFilter: +class _EditorDidUpdateTagsHook: + _hooks: List[Callable[["anki.notes.Note"], None]] = [] + + def append(self, cb: Callable[["anki.notes.Note"], None]) -> None: + """(note: anki.notes.Note)""" + self._hooks.append(cb) + + def remove(self, cb: Callable[["anki.notes.Note"], None]) -> None: + if cb in self._hooks: + self._hooks.remove(cb) + + def __call__(self, note: anki.notes.Note) -> None: + for hook in self._hooks: + try: + hook(note) + except: + # if the hook fails, remove it + self._hooks.remove(hook) + raise + # legacy support + runHook("tagsUpdated", note) + + +editor_did_update_tags = _EditorDidUpdateTagsHook() + + +class _EditorWillShowContextMenuHook: + _hooks: List[Callable[["aqt.editor.EditorWebView", QMenu], None]] = [] + + def append(self, cb: Callable[["aqt.editor.EditorWebView", QMenu], None]) -> None: + """(editor_webview: aqt.editor.EditorWebView, menu: QMenu)""" + self._hooks.append(cb) + + def remove(self, cb: Callable[["aqt.editor.EditorWebView", QMenu], None]) -> None: + if cb in self._hooks: + self._hooks.remove(cb) + + def __call__(self, editor_webview: aqt.editor.EditorWebView, menu: QMenu) -> None: + for hook in self._hooks: + try: + hook(editor_webview, menu) + except: + # if the hook fails, remove it + self._hooks.remove(hook) + raise + # legacy support + runHook("EditorWebView.contextMenuEvent", editor_webview, menu) + + +editor_will_show_context_menu = _EditorWillShowContextMenuHook() + + +class _EditorWillUseFontForFieldFilter: _hooks: List[Callable[[str], str]] = [] def append(self, cb: Callable[[str], str]) -> None: @@ -389,111 +493,7 @@ class _EditorFontForFieldFilter: return font -editor_font_for_field = _EditorFontForFieldFilter() - - -class _EditorNoteDidLoadHook: - _hooks: List[Callable[["aqt.editor.Editor"], None]] = [] - - def append(self, cb: Callable[["aqt.editor.Editor"], None]) -> None: - """(editor: aqt.editor.Editor)""" - self._hooks.append(cb) - - def remove(self, cb: Callable[["aqt.editor.Editor"], None]) -> None: - if cb in self._hooks: - self._hooks.remove(cb) - - def __call__(self, editor: aqt.editor.Editor) -> None: - for hook in self._hooks: - try: - hook(editor) - except: - # if the hook fails, remove it - self._hooks.remove(hook) - raise - # legacy support - runHook("loadNote", editor) - - -editor_note_did_load = _EditorNoteDidLoadHook() - - -class _EditorShortcutsDidInitHook: - _hooks: List[Callable[[List[Tuple], "aqt.editor.Editor"], None]] = [] - - def append(self, cb: Callable[[List[Tuple], "aqt.editor.Editor"], None]) -> None: - """(shortcuts: List[Tuple], editor: aqt.editor.Editor)""" - self._hooks.append(cb) - - def remove(self, cb: Callable[[List[Tuple], "aqt.editor.Editor"], None]) -> None: - if cb in self._hooks: - self._hooks.remove(cb) - - def __call__(self, shortcuts: List[Tuple], editor: aqt.editor.Editor) -> None: - for hook in self._hooks: - try: - hook(shortcuts, editor) - except: - # if the hook fails, remove it - self._hooks.remove(hook) - raise - # legacy support - runHook("setupEditorShortcuts", shortcuts, editor) - - -editor_shortcuts_did_init = _EditorShortcutsDidInitHook() - - -class _EditorTagsDidUpdateHook: - _hooks: List[Callable[["anki.notes.Note"], None]] = [] - - def append(self, cb: Callable[["anki.notes.Note"], None]) -> None: - """(note: anki.notes.Note)""" - self._hooks.append(cb) - - def remove(self, cb: Callable[["anki.notes.Note"], None]) -> None: - if cb in self._hooks: - self._hooks.remove(cb) - - def __call__(self, note: anki.notes.Note) -> None: - for hook in self._hooks: - try: - hook(note) - except: - # if the hook fails, remove it - self._hooks.remove(hook) - raise - # legacy support - runHook("tagsUpdated", note) - - -editor_tags_did_update = _EditorTagsDidUpdateHook() - - -class _EditorTypingTimerDidFireHook: - _hooks: List[Callable[["anki.notes.Note"], None]] = [] - - def append(self, cb: Callable[["anki.notes.Note"], None]) -> None: - """(note: anki.notes.Note)""" - self._hooks.append(cb) - - def remove(self, cb: Callable[["anki.notes.Note"], None]) -> None: - if cb in self._hooks: - self._hooks.remove(cb) - - def __call__(self, note: anki.notes.Note) -> None: - for hook in self._hooks: - try: - hook(note) - except: - # if the hook fails, remove it - self._hooks.remove(hook) - raise - # legacy support - runHook("editTimer", note) - - -editor_typing_timer_did_fire = _EditorTypingTimerDidFireHook() +editor_will_use_font_for_field = _EditorWillUseFontForFieldFilter() class _MpvDidIdleHook: @@ -624,7 +624,7 @@ class _ReviewDidUndoHook: review_did_undo = _ReviewDidUndoHook() -class _ReviewerAnswerDidShowHook: +class _ReviewerDidShowAnswerHook: _hooks: List[Callable[[Card], None]] = [] def append(self, cb: Callable[[Card], None]) -> None: @@ -647,36 +647,10 @@ class _ReviewerAnswerDidShowHook: runHook("showAnswer") -reviewer_answer_did_show = _ReviewerAnswerDidShowHook() +reviewer_did_show_answer = _ReviewerDidShowAnswerHook() -class _ReviewerContextMenuWillShowHook: - _hooks: List[Callable[["aqt.reviewer.Reviewer", QMenu], None]] = [] - - def append(self, cb: Callable[["aqt.reviewer.Reviewer", QMenu], None]) -> None: - """(reviewer: aqt.reviewer.Reviewer, menu: QMenu)""" - self._hooks.append(cb) - - def remove(self, cb: Callable[["aqt.reviewer.Reviewer", QMenu], None]) -> None: - if cb in self._hooks: - self._hooks.remove(cb) - - def __call__(self, reviewer: aqt.reviewer.Reviewer, menu: QMenu) -> None: - for hook in self._hooks: - try: - hook(reviewer, menu) - except: - # if the hook fails, remove it - self._hooks.remove(hook) - raise - # legacy support - runHook("Reviewer.contextMenuEvent", reviewer, menu) - - -reviewer_context_menu_will_show = _ReviewerContextMenuWillShowHook() - - -class _ReviewerQuestionDidShowHook: +class _ReviewerDidShowQuestionHook: _hooks: List[Callable[[Card], None]] = [] def append(self, cb: Callable[[Card], None]) -> None: @@ -699,7 +673,7 @@ class _ReviewerQuestionDidShowHook: runHook("showQuestion") -reviewer_question_did_show = _ReviewerQuestionDidShowHook() +reviewer_did_show_question = _ReviewerDidShowQuestionHook() class _ReviewerWillEndHook: @@ -730,6 +704,32 @@ class _ReviewerWillEndHook: reviewer_will_end = _ReviewerWillEndHook() +class _ReviewerWillShowContextMenuHook: + _hooks: List[Callable[["aqt.reviewer.Reviewer", QMenu], None]] = [] + + def append(self, cb: Callable[["aqt.reviewer.Reviewer", QMenu], None]) -> None: + """(reviewer: aqt.reviewer.Reviewer, menu: QMenu)""" + self._hooks.append(cb) + + def remove(self, cb: Callable[["aqt.reviewer.Reviewer", QMenu], None]) -> None: + if cb in self._hooks: + self._hooks.remove(cb) + + def __call__(self, reviewer: aqt.reviewer.Reviewer, menu: QMenu) -> None: + for hook in self._hooks: + try: + hook(reviewer, menu) + except: + # if the hook fails, remove it + self._hooks.remove(hook) + raise + # legacy support + runHook("Reviewer.contextMenuEvent", reviewer, menu) + + +reviewer_will_show_context_menu = _ReviewerWillShowContextMenuHook() + + class _StateDidChangeHook: _hooks: List[Callable[[str, str], None]] = [] @@ -915,7 +915,7 @@ class _UndoStateDidChangeHook: undo_state_did_change = _UndoStateDidChangeHook() -class _WebviewContextMenuWillShowHook: +class _WebviewWillShowContextMenuHook: _hooks: List[Callable[["aqt.webview.AnkiWebView", QMenu], None]] = [] def append(self, cb: Callable[["aqt.webview.AnkiWebView", QMenu], None]) -> None: @@ -938,5 +938,5 @@ class _WebviewContextMenuWillShowHook: runHook("AnkiWebView.contextMenuEvent", webview, menu) -webview_context_menu_will_show = _WebviewContextMenuWillShowHook() +webview_will_show_context_menu = _WebviewWillShowContextMenuHook() # @@AUTOGEN@@ diff --git a/qt/aqt/main.py b/qt/aqt/main.py index af55e0d91..c702e93cc 100644 --- a/qt/aqt/main.py +++ b/qt/aqt/main.py @@ -1154,7 +1154,7 @@ Difference to correct time: %s.""" def setupHooks(self) -> None: hooks.schema_will_change.append(self.onSchemaMod) - hooks.notes_will_delete.append(self.onRemNotes) + hooks.notes_will_be_deleted.append(self.onRemNotes) hooks.card_odue_was_invalid.append(self.onOdueInvalid) gui_hooks.mpv_will_play.append(self.on_mpv_will_play) diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index b56bc6b42..2fc860c64 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -187,7 +187,7 @@ The front of this card is empty. Please run Tools>Empty Cards.""" playFromText(q) # render & update bottom q = self._mungeQA(q) - q = gui_hooks.card_text(q, c, "reviewQuestion") + q = gui_hooks.card_will_show(q, c, "reviewQuestion") bodyclass = bodyClass(self.mw.col, c) @@ -199,7 +199,7 @@ The front of this card is empty. Please run Tools>Empty Cards.""" if self.typeCorrect: self.mw.web.setFocus() # user hook - gui_hooks.reviewer_question_did_show(c) + gui_hooks.reviewer_did_show_question(c) def autoplay(self, card): return self.mw.col.decks.confForDid(card.odid or card.did)["autoplay"] @@ -229,12 +229,12 @@ The front of this card is empty. Please run Tools>Empty Cards.""" if self.autoplay(c): playFromText(a) a = self._mungeQA(a) - a = gui_hooks.card_text(a, c, "reviewAnswer") + a = gui_hooks.card_will_show(a, c, "reviewAnswer") # render and update bottom self.web.eval("_showAnswer(%s);" % json.dumps(a)) self._showEaseButtons() # user hook - gui_hooks.reviewer_answer_did_show(c) + gui_hooks.reviewer_did_show_answer(c) # Answering a card ############################################################ @@ -694,7 +694,7 @@ time = %(time)d; m = QMenu(self.mw) self._addMenuItems(m, opts) - gui_hooks.reviewer_context_menu_will_show(self, m) + gui_hooks.reviewer_will_show_context_menu(self, m) qtMenuShortcutWorkaround(m) m.exec_(QCursor.pos()) diff --git a/qt/aqt/webview.py b/qt/aqt/webview.py index c94c33f7b..fcae897e9 100644 --- a/qt/aqt/webview.py +++ b/qt/aqt/webview.py @@ -182,7 +182,7 @@ class AnkiWebView(QWebEngineView): # type: ignore m = QMenu(self) a = m.addAction(_("Copy")) a.triggered.connect(self.onCopy) - gui_hooks.webview_context_menu_will_show(self, m) + gui_hooks.webview_will_show_context_menu(self, m) m.popup(QCursor.pos()) def dropEvent(self, evt): diff --git a/qt/tools/genhooks_gui.py b/qt/tools/genhooks_gui.py index 36c635c5a..818c8f427 100644 --- a/qt/tools/genhooks_gui.py +++ b/qt/tools/genhooks_gui.py @@ -20,19 +20,19 @@ hooks = [ # Reviewing ################### Hook( - name="reviewer_question_did_show", + name="reviewer_did_show_question", args=["card: Card"], legacy_hook="showQuestion", legacy_no_args=True, ), Hook( - name="reviewer_answer_did_show", + name="reviewer_did_show_answer", args=["card: Card"], legacy_hook="showAnswer", legacy_no_args=True, ), Hook( - name="reviewer_context_menu_will_show", + name="reviewer_will_show_context_menu", args=["reviewer: aqt.reviewer.Reviewer", "menu: QMenu"], legacy_hook="Reviewer.contextMenuEvent", ), @@ -42,7 +42,7 @@ hooks = [ doc="Called before Anki transitions from the review screen to another screen.", ), Hook( - name="card_text", + name="card_will_show", args=["text: str", "card: Card", "kind: str"], return_type="str", legacy_hook="prepareQA", @@ -56,17 +56,17 @@ hooks = [ legacy_hook="browser.setupMenus", ), Hook( - name="browser_context_menu_will_show", + name="browser_will_show_context_menu", args=["browser: aqt.browser.Browser", "menu: QMenu"], legacy_hook="browser.onContextMenu", ), Hook( - name="browser_row_did_change", + name="browser_did_change_row", args=["browser: aqt.browser.Browser"], legacy_hook="browser.rowChanged", ), Hook( - name="webview_context_menu_will_show", + name="webview_will_show_context_menu", args=["webview: aqt.webview.AnkiWebView", "menu: QMenu"], legacy_hook="AnkiWebView.contextMenuEvent", ), @@ -120,59 +120,59 @@ hooks = [ # Adding cards ################### Hook( - name="add_cards_history_menu_will_show", + name="add_cards_will_show_history_menu", args=["addcards: aqt.addcards.AddCards", "menu: QMenu"], legacy_hook="AddCards.onHistory", ), Hook( - name="add_cards_note_did_add", + name="add_cards_did_add_note", args=["note: anki.notes.Note"], legacy_hook="AddCards.noteAdded", ), # Editing ################### Hook( - name="editor_buttons_did_init", + name="editor_did_init_buttons", args=["buttons: List", "editor: aqt.editor.Editor"], ), Hook( - name="editor_shortcuts_did_init", + name="editor_did_init_shortcuts", args=["shortcuts: List[Tuple]", "editor: aqt.editor.Editor"], legacy_hook="setupEditorShortcuts", ), Hook( - name="editor_context_menu_will_show", + name="editor_will_show_context_menu", args=["editor_webview: aqt.editor.EditorWebView", "menu: QMenu"], legacy_hook="EditorWebView.contextMenuEvent", ), Hook( - name="editor_typing_timer_did_fire", + name="editor_did_fire_typing_timer", args=["note: anki.notes.Note"], legacy_hook="editTimer", ), Hook( - name="editor_field_did_gain_focus", + name="editor_did_focus_field", args=["note: anki.notes.Note", "current_field_idx: int"], legacy_hook="editFocusGained", ), Hook( - name="editor_field_did_lose_focus", + name="editor_did_unfocus_field", args=["changed: bool", "note: anki.notes.Note", "current_field_idx: int"], return_type="bool", legacy_hook="editFocusLost", ), Hook( - name="editor_note_did_load", + name="editor_did_load_note", args=["editor: aqt.editor.Editor"], legacy_hook="loadNote", ), Hook( - name="editor_tags_did_update", + name="editor_did_update_tags", args=["note: anki.notes.Note"], legacy_hook="tagsUpdated", ), Hook( - name="editor_font_for_field", + name="editor_will_use_font_for_field", args=["font: str"], return_type="str", legacy_hook="mungeEditingFontName", @@ -188,7 +188,7 @@ hooks = [ legacy_no_args=True, ), Hook( - name="deck_browser_options_menu_will_show", + name="deck_browser_will_show_options_menu", args=["menu: QMenu", "deck_id: int"], legacy_hook="showDeckOptions", ),