Hook to decide whether a note should be added.

This commit is contained in:
Arthur Milchior 2020-03-06 16:25:02 +01:00
parent e3a57a4193
commit e4ae41340f
3 changed files with 56 additions and 1 deletions

View File

@ -167,8 +167,12 @@ class AddCards(QDialog):
def addNote(self, note) -> Optional[Note]: def addNote(self, note) -> Optional[Note]:
note.model()["did"] = self.deckChooser.selectedId() note.model()["did"] = self.deckChooser.selectedId()
ret = note.dupeOrEmpty() ret = note.dupeOrEmpty()
rejection = None
if ret == 1: if ret == 1:
showWarning(_("The first field is empty."), help="AddItems#AddError") rejection = _("The first field is empty.")
rejection = gui_hooks.add_card_accepts(rejection, note)
if rejection is not None:
showWarning(rejection, help="AddItems#AddError")
return None return None
if "{{cloze:" in note.model()["tmpls"][0]["qfmt"]: if "{{cloze:" in note.model()["tmpls"][0]["qfmt"]:
if not self.mw.col.models._availClozeOrds( if not self.mw.col.models._availClozeOrds(

View File

@ -23,6 +23,45 @@ from aqt.qt import QDialog, QMenu
# @@AUTOGEN@@ # @@AUTOGEN@@
class _AddCardAcceptsFilter:
"""Decides whether the note should be added to the collection or
not. It is assumed to come from the addCards window.
reason_to_already_reject is the first reason to reject that
was found, or None. If your filter wants to reject, it should
replace return the reason to reject. Otherwise return the
input."""
_hooks: List[Callable[[Optional[str], "anki.notes.Note"], Optional[str]]] = []
def append(
self, cb: Callable[[Optional[str], "anki.notes.Note"], Optional[str]]
) -> None:
"""(reason_to_already_reject: Optional[str], note: anki.notes.Note)"""
self._hooks.append(cb)
def remove(
self, cb: Callable[[Optional[str], "anki.notes.Note"], Optional[str]]
) -> None:
if cb in self._hooks:
self._hooks.remove(cb)
def __call__(
self, reason_to_already_reject: Optional[str], note: anki.notes.Note
) -> Optional[str]:
for filter in self._hooks:
try:
reason_to_already_reject = filter(reason_to_already_reject, note)
except:
# if the hook fails, remove it
self._hooks.remove(filter)
raise
return reason_to_already_reject
add_card_accepts = _AddCardAcceptsFilter()
class _AddCardsDidAddNoteHook: class _AddCardsDidAddNoteHook:
_hooks: List[Callable[["anki.notes.Note"], None]] = [] _hooks: List[Callable[["anki.notes.Note"], None]] = []

View File

@ -412,6 +412,18 @@ def emptyNewCard():
args=["note: anki.notes.Note"], args=["note: anki.notes.Note"],
legacy_hook="AddCards.noteAdded", legacy_hook="AddCards.noteAdded",
), ),
Hook(
name="add_card_accepts",
args=["reason_to_already_reject: Optional[str]", "note: anki.notes.Note"],
return_type="Optional[str]",
doc="""Decides whether the note should be added to the collection or
not. It is assumed to come from the addCards window.
reason_to_already_reject is the first reason to reject that
was found, or None. If your filter wants to reject, it should
replace return the reason to reject. Otherwise return the
input.""",
),
# Editing # Editing
################### ###################
Hook( Hook(