Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checkpoint / Undo feature not working as expected with new Anki #200

Open
mjuhanne opened this issue Sep 1, 2023 · 0 comments
Open

Checkpoint / Undo feature not working as expected with new Anki #200

mjuhanne opened this issue Sep 1, 2023 · 0 comments
Labels
bug Something isn't working

Comments

@mjuhanne
Copy link
Contributor

mjuhanne commented Sep 1, 2023

I also noticed that the checkpoint facility doesn't seem to work in new Anki as it should (ctrl-z should undo all the added characters in one step). Instead it removes them one by one, up to maximum of 30 (undo queue limit).

Let's look at the function in kanji.py more closely:

 def make_cards_from_characters(self, card_type, new_characters, checkpoint=None):
        from . import add_note_no_hook
        # Just to be sure...
        self.recalc_user_cards(card_type)
        characters = self.new_characters(card_type, new_characters)
        deck_name = card_type.deck_name
        model_name = card_type.model_name
        deck = aqt.mw.col.decks.byName(deck_name)

        if deck is None:
            raise InvalidDeckError(card_type)

        if checkpoint is not None:
            aqt.mw.checkpoint(checkpoint)
        deck_id = deck["id"]
        model = aqt.mw.col.models.byName(model_name)

        for c in characters:
            note = anki.notes.Note(aqt.mw.col, model)
            note["Character"] = c
            self.refresh_note(note)
            add_note_no_hook(aqt.mw.col, note, deck_id)

        self.recalc_user_cards(card_type)

The mw.checkpoint() in current version doesn't seem to do anything worthwhile, since add_note_no_hook (call to pylib.anki.collection.Collection.add_note) will always reset the undo queue anyway, and so one extra checkpoint is added per new note.

I've tried really hard to understand the porting to Anki 2.1.45 notes here

In the porting note's there's an example how to use the CollectionOp facility:

def my_blocking_action(col: Collection):
    pos = col.add_custom_undo_entry("change due")
    card1 = col.get_card(CardId(123))
    card1.due = 456
    col.update_card(card1)
    card2 = col.get_card(CardId(100))
    card2.due = 400
    col.update_card(card2)
    return col.merge_undo_entries(pos)

def my_op(*, parent: QWidget) -> CollectionOp[OpChanges]:
    return CollectionOp(parent, lambda col: my_blocking_action(col))

my_op(parent=mw).run_in_background() 

So we should be using col.add_custom_undo_entry() / col.merge_undo_entries() instead of mw.checkpoint()
The CollectionOp wrapping here is needed for GUI to be updated.
However I'm not sure how to apply this to our code since we need to call recalc_user_cards() after adding the notes. How to wait for it to complete?

@mjuhanne mjuhanne added the bug Something isn't working label Sep 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant