Merge pull request #462 from Arthur-Milchior/filter_empty_card

Add a hook to change empty cards to delete
This commit is contained in:
Damien Elmes 2020-02-27 12:53:52 +10:00 committed by GitHub
commit e04cbfd7f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 0 deletions

View File

@ -862,6 +862,51 @@ class _EditorWillUseFontForFieldFilter:
editor_will_use_font_for_field = _EditorWillUseFontForFieldFilter()
class _EmptyCardsWillBeDeletedFilter:
"""Allow to change the list of cards to delete.
For example, an add-on creating a method to delete only empty
new cards would be done as follow:
```
from anki.consts import CARD_TYPE_NEW
from anki.utils import ids2str
from aqt import mw
from aqt import gui_hooks
def filter(cids, col):
return col.db.list(
f"select id from cards where (type={CARD_TYPE_NEW} and (id in {ids2str(cids)))")
def emptyNewCard():
gui_hooks.append(filter)
mw.onEmptyCards()
gui_hooks.remove(filter)
```"""
_hooks: List[Callable[[List[int]], List[int]]] = []
def append(self, cb: Callable[[List[int]], List[int]]) -> None:
"""(cids: List[int])"""
self._hooks.append(cb)
def remove(self, cb: Callable[[List[int]], List[int]]) -> None:
if cb in self._hooks:
self._hooks.remove(cb)
def __call__(self, cids: List[int]) -> List[int]:
for filter in self._hooks:
try:
cids = filter(cids)
except:
# if the hook fails, remove it
self._hooks.remove(filter)
raise
return cids
empty_cards_will_be_deleted = _EmptyCardsWillBeDeletedFilter()
class _MediaSyncDidProgressHook:
_hooks: List[Callable[["aqt.mediasync.LogEntryWithTime"], None]] = []

View File

@ -1303,6 +1303,7 @@ will be lost. Continue?"""
def onEmptyCards(self):
self.progress.start(immediate=True)
cids = self.col.emptyCids()
cids = gui_hooks.empty_cards_will_be_deleted(cids)
if not cids:
self.progress.finish()
tooltip(_("No empty cards."))

View File

@ -346,6 +346,30 @@ hooks = [
name="media_sync_did_progress", args=["entry: aqt.mediasync.LogEntryWithTime"],
),
Hook(name="media_sync_did_start_or_stop", args=["running: bool"]),
Hook(
name="empty_cards_will_be_deleted",
args=["cids: List[int]"],
return_type="List[int]",
doc="""Allow to change the list of cards to delete.
For example, an add-on creating a method to delete only empty
new cards would be done as follow:
```
from anki.consts import CARD_TYPE_NEW
from anki.utils import ids2str
from aqt import mw
from aqt import gui_hooks
def filter(cids, col):
return col.db.list(
f"select id from cards where (type={CARD_TYPE_NEW} and (id in {ids2str(cids)))")
def emptyNewCard():
gui_hooks.append(filter)
mw.onEmptyCards()
gui_hooks.remove(filter)
```""",
),
# Adding cards
###################
Hook(