diff --git a/qt/aqt/addcards.py b/qt/aqt/addcards.py index 70df81aa1..c8eb7c581 100644 --- a/qt/aqt/addcards.py +++ b/qt/aqt/addcards.py @@ -7,7 +7,6 @@ import aqt.deckchooser import aqt.editor import aqt.forms import aqt.modelchooser -from anki.hooks import addHook, remHook from anki.lang import _ from anki.notes import Note from anki.utils import htmlToTextLine, isMac @@ -44,8 +43,8 @@ class AddCards(QDialog): self.history: List[int] = [] self.previousNote = None restoreGeom(self, "add") - addHook("reset", self.onReset) - addHook("currentModelChanged", self.onModelChange) + gui_hooks.state_did_reset_hook.append(self.onReset) + gui_hooks.current_note_type_did_change_hook.append(self.onModelChange) addCloseShortcut(self) self.show() @@ -90,7 +89,7 @@ class AddCards(QDialog): def setAndFocusNote(self, note: Note) -> None: self.editor.setNote(note, focusTo=0) - def onModelChange(self) -> None: + def onModelChange(self, unused) -> None: oldNote = self.editor.note note = self.mw.col.newNote() self.previousNote = None @@ -224,8 +223,8 @@ question on all cards.""" self.ifCanClose(self._reject) def _reject(self) -> None: - remHook("reset", self.onReset) - remHook("currentModelChanged", self.onModelChange) + gui_hooks.state_did_reset_hook.remove(self.onReset) + gui_hooks.current_note_type_did_change_hook.remove(self.onModelChange) clearAudioQueue() self.removeTempNote(self.editor.note) self.editor.cleanup() diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index 642f6df7d..19f2f2f7b 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -13,9 +13,9 @@ from typing import Callable, List, Optional import anki import aqt.forms +from anki import hooks from anki.collection import _Collection from anki.consts import * -from anki.hooks import addHook, remHook from anki.lang import _, ngettext from anki.utils import ( bodyClass, @@ -2020,22 +2020,24 @@ update cards set usn=?, mod=?, did=? where id in """ ###################################################################### def setupHooks(self): - addHook("undoState", self.onUndoState) - addHook("reset", self.onReset) - addHook("editTimer", self.refreshCurrentCard) - addHook("loadNote", self.onLoadNote) - addHook("editFocusLost", self.refreshCurrentCardFilter) - for t in "newTag", "newModel", "newDeck": - addHook(t, self.maybeRefreshSidebar) + gui_hooks.undo_state_did_change_hook.append(self.onUndoState) + gui_hooks.state_did_reset_hook.append(self.onReset) + gui_hooks.editor_typing_timer_did_fire_hook.append(self.refreshCurrentCard) + gui_hooks.editor_note_did_load_hook.append(self.onLoadNote) + gui_hooks.editor_field_did_lose_focus_filter.append(self.refreshCurrentCard) + hooks.tag_created_hook.append(self.maybeRefreshSidebar) + hooks.note_type_created_hook.append(self.maybeRefreshSidebar) + hooks.deck_created_hook.append(self.maybeRefreshSidebar) def teardownHooks(self): - remHook("reset", self.onReset) - remHook("editTimer", self.refreshCurrentCard) - remHook("loadNote", self.onLoadNote) - remHook("editFocusLost", self.refreshCurrentCardFilter) - remHook("undoState", self.onUndoState) - for t in "newTag", "newModel", "newDeck": - remHook(t, self.maybeRefreshSidebar) + gui_hooks.undo_state_did_change_hook.remove(self.onUndoState) + gui_hooks.state_did_reset_hook.remove(self.onReset) + gui_hooks.editor_typing_timer_did_fire_hook.remove(self.refreshCurrentCard) + gui_hooks.editor_note_did_load_hook.remove(self.onLoadNote) + gui_hooks.editor_field_did_lose_focus_filter.remove(self.refreshCurrentCard) + hooks.tag_created_hook.remove(self.maybeRefreshSidebar) + hooks.note_type_created_hook.remove(self.maybeRefreshSidebar) + hooks.deck_created_hook.remove(self.maybeRefreshSidebar) def onUndoState(self, on): self.form.actionUndo.setEnabled(on) @@ -2269,8 +2271,8 @@ class ChangeModel(QDialog): self.setWindowModality(Qt.WindowModal) self.setup() restoreGeom(self, "changeModel") - addHook("reset", self.onReset) - addHook("currentModelChanged", self.onReset) + gui_hooks.state_did_reset_hook.append(self.onReset) + gui_hooks.current_note_type_did_change_hook.append(self.onReset) self.exec_() def setup(self): @@ -2393,8 +2395,8 @@ class ChangeModel(QDialog): ) def cleanup(self): - remHook("reset", self.onReset) - remHook("currentModelChanged", self.onReset) + gui_hooks.state_did_reset_hook.remove(self.onReset) + gui_hooks.current_note_type_did_change_hook.remove(self.onReset) self.modelChooser.cleanup() saveGeom(self, "changeModel") diff --git a/qt/aqt/deckchooser.py b/qt/aqt/deckchooser.py index 495033fd5..6248a6fe5 100644 --- a/qt/aqt/deckchooser.py +++ b/qt/aqt/deckchooser.py @@ -2,8 +2,8 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from anki.hooks import addHook, remHook from anki.lang import _ +from aqt import gui_hooks from aqt.qt import * from aqt.utils import shortcut @@ -19,7 +19,7 @@ class DeckChooser(QHBoxLayout): self.setSpacing(8) self.setupDecks() self.widget.setLayout(self) - addHook("currentModelChanged", self.onModelChange) + gui_hooks.current_note_type_did_change_hook.append(self.onModelChange) def setupDecks(self): if self.label: @@ -64,7 +64,7 @@ class DeckChooser(QHBoxLayout): self.widget.hide() def cleanup(self): - remHook("currentModelChanged", self.onModelChange) + gui_hooks.current_note_type_did_change_hook.remove(self.onModelChange) def onModelChange(self): if not self.mw.col.conf.get("addToCur", True): diff --git a/qt/aqt/downloader.py b/qt/aqt/downloader.py index 2363db2bd..0e01a8e4e 100644 --- a/qt/aqt/downloader.py +++ b/qt/aqt/downloader.py @@ -6,7 +6,7 @@ import re import time import aqt -from anki.hooks import addHook, remHook +from anki import hooks from anki.lang import _ from anki.sync import AnkiRequestsClient from aqt.qt import * @@ -57,7 +57,7 @@ class Downloader(QThread): self.recvTotal += bytes self.recv.emit() - addHook("httpRecv", recvEvent) + hooks.http_data_received_hook.append(recvEvent) client = AnkiRequestsClient() try: resp = client.get(aqt.appShared + "download/%s?v=2.1" % self.code) @@ -75,7 +75,7 @@ class Downloader(QThread): self.error = _("Please check your internet connection.") + "\n\n" + str(e) return finally: - remHook("httpRecv", recvEvent) + hooks.http_data_received_hook.remove(recvEvent) self.fname = re.match( "attachment; filename=(.+)", resp.headers["content-disposition"] diff --git a/qt/aqt/editcurrent.py b/qt/aqt/editcurrent.py index 7f7ae988f..2b22411b8 100644 --- a/qt/aqt/editcurrent.py +++ b/qt/aqt/editcurrent.py @@ -3,8 +3,8 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import aqt.editor -from anki.hooks import addHook, remHook from anki.lang import _ +from aqt import gui_hooks from aqt.qt import * from aqt.utils import restoreGeom, saveGeom, tooltip @@ -26,7 +26,7 @@ class EditCurrent(QDialog): self.editor.card = self.mw.reviewer.card self.editor.setNote(self.mw.reviewer.card.note(), focusTo=0) restoreGeom(self, "editcurrent") - addHook("reset", self.onReset) + gui_hooks.state_did_reset_hook.append(self.onReset) self.mw.requireReset() self.show() # reset focus after open, taking care not to retain webview @@ -40,7 +40,7 @@ class EditCurrent(QDialog): n.load() # reload in case the model changed except: # card's been deleted - remHook("reset", self.onReset) + gui_hooks.state_did_reset_hook.remove(self.onReset) self.editor.setNote(None) self.mw.reset() aqt.dialogs.markClosed("EditCurrent") @@ -59,7 +59,7 @@ class EditCurrent(QDialog): self.editor.saveNow(self._saveAndClose) def _saveAndClose(self): - remHook("reset", self.onReset) + gui_hooks.state_did_reset_hook.remove(self.onReset) r = self.mw.reviewer try: r.card.load() diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index 10cbc2a3c..3e287e458 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -19,7 +19,7 @@ from bs4 import BeautifulSoup import aqt import aqt.sound -from anki.hooks import addHook, runFilter +from anki.hooks import runFilter from anki.lang import _ from anki.sync import AnkiRequestsClient from anki.utils import checksum, isWin, namedtmp, stripHTMLMedia @@ -1122,4 +1122,4 @@ def fontMungeHack(font): return re.sub(" L$", " Light", font) -addHook("mungeEditingFontName", fontMungeHack) +gui_hooks.editor_font_for_field_filter.append(fontMungeHack) diff --git a/qt/aqt/exporting.py b/qt/aqt/exporting.py index 396adfa01..8f84fc093 100644 --- a/qt/aqt/exporting.py +++ b/qt/aqt/exporting.py @@ -6,8 +6,8 @@ import re import time import aqt +from anki import hooks from anki.exporting import exporters -from anki.hooks import addHook, remHook from anki.lang import _, ngettext from aqt.qt import * from aqt.utils import checkInvalidFilename, getSaveFile, showInfo, showWarning, tooltip @@ -132,9 +132,9 @@ class ExportDialog(QDialog): ) % cnt ) - addHook("exportedMediaFiles", exportedMedia) + hooks.exported_media_files_hook.append(exportedMedia) self.exporter.exportInto(file) - remHook("exportedMediaFiles", exportedMedia) + hooks.exported_media_files_hook.remove(exportedMedia) period = 3000 if self.isVerbatim: msg = _("Collection exported.") diff --git a/qt/aqt/importing.py b/qt/aqt/importing.py index 1696abb74..e8d6fd1b3 100644 --- a/qt/aqt/importing.py +++ b/qt/aqt/importing.py @@ -14,9 +14,8 @@ import anki.importing as importing import aqt.deckchooser import aqt.forms import aqt.modelchooser -from anki.hooks import addHook, remHook from anki.lang import _, ngettext -from aqt import AnkiQt +from aqt import AnkiQt, gui_hooks from aqt.qt import * from aqt.utils import ( askUser, @@ -87,7 +86,7 @@ class ImportDialog(QDialog): self.setupOptions() self.modelChanged() self.frm.autoDetect.setVisible(self.importer.needDelimiter) - addHook("currentModelChanged", self.modelChanged) + gui_hooks.current_note_type_did_change_hook.append(self.modelChanged) self.frm.autoDetect.clicked.connect(self.onDelimiter) self.updateDelimiterButtonText() self.frm.allowHTML.setChecked(self.mw.pm.profile.get("allowHTML", True)) @@ -105,7 +104,7 @@ class ImportDialog(QDialog): ) self.deck = aqt.deckchooser.DeckChooser(self.mw, self.frm.deckArea, label=False) - def modelChanged(self): + def modelChanged(self, unused=None): self.importer.model = self.mw.col.models.current() self.importer.initMapping() self.showMapping() @@ -281,7 +280,7 @@ you can enter it here. Use \\t to represent tab.""" def reject(self): self.modelChooser.cleanup() self.deck.cleanup() - remHook("currentModelChanged", self.modelChanged) + gui_hooks.current_note_type_did_change_hook.remove(self.modelChanged) QDialog.reject(self) def helpRequested(self): diff --git a/qt/aqt/main.py b/qt/aqt/main.py index 4572cb1ad..072710f75 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, runHook +from anki.hooks import runHook from anki.lang import _, ngettext from anki.storage import Collection from anki.utils import devMode, ids2str, intTime, isMac, isWin, splitFields @@ -1154,7 +1154,7 @@ Difference to correct time: %s.""" def setupHooks(self) -> None: hooks.mod_schema_filter.append(self.onSchemaMod) - addHook("remNotes", self.onRemNotes) + hooks.remove_notes_hook.append(self.onRemNotes) hooks.odue_invalid_hook.append(self.onOdueInvalid) gui_hooks.mpv_will_play_hook.append(self.on_mpv_will_play) diff --git a/qt/aqt/modelchooser.py b/qt/aqt/modelchooser.py index fb0e91e83..a9b3defba 100644 --- a/qt/aqt/modelchooser.py +++ b/qt/aqt/modelchooser.py @@ -2,7 +2,6 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from anki.hooks import addHook, remHook from anki.lang import _ from aqt import gui_hooks from aqt.qt import * @@ -19,7 +18,7 @@ class ModelChooser(QHBoxLayout): self.setContentsMargins(0, 0, 0, 0) self.setSpacing(8) self.setupModels() - addHook("reset", self.onReset) + gui_hooks.state_did_reset_hook.append(self.onReset) self.widget.setLayout(self) def setupModels(self): @@ -42,7 +41,7 @@ class ModelChooser(QHBoxLayout): self.updateModels() def cleanup(self): - remHook("reset", self.onReset) + gui_hooks.state_did_reset_hook.remove(self.onReset) def onReset(self): self.updateModels() diff --git a/qt/aqt/sound.py b/qt/aqt/sound.py index fb19b18ef..4f03741c1 100644 --- a/qt/aqt/sound.py +++ b/qt/aqt/sound.py @@ -11,7 +11,6 @@ import threading import time from typing import Any, Callable, Dict, List, Optional, Tuple -from anki.hooks import addHook from anki.lang import _ from anki.sound import allSounds from anki.utils import isLin, isMac, isWin, tmpdir @@ -378,7 +377,7 @@ def stopMplayer(*args) -> None: cleanupOldMplayerProcesses() -addHook("unloadProfile", stopMplayer) +gui_hooks.profile_will_close_hook.append(stopMplayer) # PyAudio recording ########################################################################## diff --git a/qt/aqt/studydeck.py b/qt/aqt/studydeck.py index f172e6d43..acc250254 100644 --- a/qt/aqt/studydeck.py +++ b/qt/aqt/studydeck.py @@ -3,8 +3,8 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import aqt -from anki.hooks import addHook, remHook from anki.lang import _ +from aqt import gui_hooks from aqt.qt import * from aqt.utils import getOnlyText, openHelp, restoreGeom, saveGeom, shortcut, showInfo @@ -32,7 +32,7 @@ class StudyDeck(QDialog): self.form.setupUi(self) self.form.filter.installEventFilter(self) self.cancel = cancel - addHook("reset", self.onReset) + gui_hooks.state_did_reset_hook.append(self.onReset) self.geomKey = "studyDeck-" + geomKey restoreGeom(self, self.geomKey) if not cancel: @@ -120,7 +120,7 @@ class StudyDeck(QDialog): def accept(self): saveGeom(self, self.geomKey) - remHook("reset", self.onReset) + gui_hooks.state_did_reset_hook.remove(self.onReset) row = self.form.list.currentRow() if row < 0: showInfo(_("Please select something.")) @@ -130,7 +130,7 @@ class StudyDeck(QDialog): def reject(self): saveGeom(self, self.geomKey) - remHook("reset", self.onReset) + gui_hooks.state_did_reset_hook.remove(self.onReset) QDialog.reject(self) def onAddDeck(self): @@ -144,5 +144,5 @@ class StudyDeck(QDialog): self.mw.col.decks.id(n) self.name = n # make sure we clean up reset hook when manually exiting - remHook("reset", self.onReset) + gui_hooks.state_did_reset_hook.remove(self.onReset) QDialog.accept(self) diff --git a/qt/aqt/sync.py b/qt/aqt/sync.py index b17925313..9cbbe0881 100644 --- a/qt/aqt/sync.py +++ b/qt/aqt/sync.py @@ -4,7 +4,7 @@ import gc import time -from anki.hooks import addHook, remHook +from anki import hooks from anki.lang import _ from anki.storage import Collection from anki.sync import FullSyncer, MediaSyncer, RemoteMediaServer, RemoteServer, Syncer @@ -406,10 +406,10 @@ class SyncThread(QThread): self._abort = 2 raise Exception("sync cancelled") - addHook("sync", syncEvent) - addHook("syncMsg", syncMsg) - addHook("httpSend", sendEvent) - addHook("httpRecv", recvEvent) + hooks.sync_stage_hook.append(syncEvent) + hooks.sync_progress_message_hook.append(syncMsg) + hooks.http_data_sent_hook.append(sendEvent) + hooks.http_data_received_hook.append(recvEvent) # run sync and catch any errors try: self._sync() @@ -419,10 +419,10 @@ class SyncThread(QThread): finally: # don't bump mod time unless we explicitly save self.col.close(save=False) - remHook("sync", syncEvent) - remHook("syncMsg", syncMsg) - remHook("httpSend", sendEvent) - remHook("httpRecv", recvEvent) + hooks.sync_stage_hook.remove(syncEvent) + hooks.sync_progress_message_hook.remove(syncMsg) + hooks.http_data_sent_hook.remove(sendEvent) + hooks.http_data_received_hook.remove(recvEvent) def _abortingSync(self): try: