diff --git a/anki/collection.py b/anki/collection.py index 5f98c7177..fac6fe2f2 100644 --- a/anki/collection.py +++ b/anki/collection.py @@ -391,6 +391,10 @@ select id from notes where id in %s and id not in (select nid from cards)""" % ids2str(nids)) self._remNotes(nids) + def remEmptyCards(self, ids): + if runFilter("remEmptyCards", len(ids), True): + self.remCards(ids) + # Field checksums and sorting fields ########################################################################## diff --git a/anki/models.py b/anki/models.py index f1412f9f0..d9a091bd4 100644 --- a/anki/models.py +++ b/anki/models.py @@ -348,7 +348,7 @@ select id from notes where mid = ?)""" % " ".join(map), def _syncTemplates(self, m): rem = self.col.genCards(self.nids(m)) - self.col.remCards(rem) + self.col.remEmptyCards(rem) # Model changing ########################################################################## diff --git a/anki/notes.py b/anki/notes.py index 9895e38f2..25618c354 100644 --- a/anki/notes.py +++ b/anki/notes.py @@ -157,4 +157,5 @@ insert or replace into notes values (?,?,?,?,?,?,?,?,?,?,?,?)""", def _postFlush(self): # generate missing cards if not self.newlyAdded: - self.col.genCards([self.id]) + ids = self.col.genCards([self.id]) + self.col.remEmptyCards(ids) diff --git a/tests/test_cards.py b/tests/test_cards.py index c1efab053..aea5b1251 100644 --- a/tests/test_cards.py +++ b/tests/test_cards.py @@ -5,6 +5,7 @@ from anki.db import DB from anki.consts import * from anki.utils import hexifyID from tests.shared import getEmptyDeck +from anki.hooks import addHook, remHook def test_previewCards(): deck = getEmptyDeck() @@ -75,6 +76,18 @@ def test_genrem(): mm.save(m, templates=True) assert len(f.cards()) == 1 # if we add to the note, a card should be automatically generated + f.load() f['Back'] = "1" f.flush() assert len(f.cards()) == 2 + # deleteion calls a hook to let the user abort the delete. let's abort it: + def abort(val, *args): + return False + addHook("remEmptyCards", abort) + f['Back'] = "" + f.flush() + assert len(f.cards()) == 2 + # if there's no filter, or it returns true, the cards get deleted + remHook("remEmptyCards", abort) + f.flush() + assert len(f.cards()) == 1