2019-02-05 04:59:03 +01:00
|
|
|
# Copyright: Ankitects Pty Ltd and contributors
|
2012-12-21 08:51:59 +01:00
|
|
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
2021-10-03 10:59:42 +02:00
|
|
|
from typing import Callable, Optional
|
2012-12-21 08:51:59 +01:00
|
|
|
|
2019-12-20 10:19:03 +01:00
|
|
|
import aqt.editor
|
2012-12-21 08:51:59 +01:00
|
|
|
import aqt.forms
|
2021-08-20 03:37:23 +02:00
|
|
|
from anki._legacy import deprecated
|
undoable ops now return changes directly; add new *_ops.py files
- Introduced a new transact() method that wraps the return value
in a separate struct that describes the changes that were made.
- Changes are now gathered from the undo log, so we don't need to
guess at what was changed - eg if update_note() is called with identical
note contents, no changes are returned. Card changes will only be set
if cards were actually generated by the update_note() call, and tag
will only be set if a new tag was added.
- mw.perform_op() has been updated to expect the op to return the changes,
or a structure with the changes in it, and it will use them to fire the
change hook, instead of fetching the changes from undo_status(), so there
is no risk of race conditions.
- the various calls to mw.perform_op() have been split into separate
files like card_ops.py. Aside from making the code cleaner, this works
around a rather annoying issue with mypy. Because we run it with
no_strict_optional, mypy is happy to accept an operation that returns None,
despite the type signature saying it requires changes to be returned.
Turning no_strict_optional on for the whole codebase is not practical
at the moment, but we can enable it for individual files.
Still todo:
- The cursor keeps moving back to the start of a field when typing -
we need to ignore the refresh hook when we are the initiator.
- The busy cursor icon should probably be delayed a few hundreds ms.
- Still need to think about a nicer way of handling saveNow()
- op_made_changes(), op_affects_study_queue() might be better embedded
as properties in the object instead
2021-03-16 05:26:42 +01:00
|
|
|
from anki.collection import OpChanges, SearchNode
|
2021-03-27 12:38:20 +01:00
|
|
|
from anki.decks import DeckId
|
2021-03-27 13:03:19 +01:00
|
|
|
from anki.models import NotetypeId
|
2021-06-12 10:05:42 +02:00
|
|
|
from anki.notes import Note, NoteFieldsCheckResult, NoteId
|
2019-03-04 08:25:19 +01:00
|
|
|
from anki.utils import htmlToTextLine, isMac
|
2020-01-15 03:46:53 +01:00
|
|
|
from aqt import AnkiQt, gui_hooks
|
2021-04-15 18:18:25 +02:00
|
|
|
from aqt.deckchooser import DeckChooser
|
2021-03-27 13:03:19 +01:00
|
|
|
from aqt.notetypechooser import NotetypeChooser
|
2021-04-03 08:26:10 +02:00
|
|
|
from aqt.operations.note import add_note
|
2019-12-20 10:19:03 +01:00
|
|
|
from aqt.qt import *
|
2020-01-20 11:10:38 +01:00
|
|
|
from aqt.sound import av_player
|
2019-12-23 01:34:10 +01:00
|
|
|
from aqt.utils import (
|
2021-01-25 14:45:47 +01:00
|
|
|
HelpPage,
|
2019-12-23 01:34:10 +01:00
|
|
|
addCloseShortcut,
|
|
|
|
askUser,
|
2021-01-07 05:24:49 +01:00
|
|
|
disable_help_button,
|
2019-12-23 01:34:10 +01:00
|
|
|
downArrow,
|
|
|
|
openHelp,
|
|
|
|
restoreGeom,
|
|
|
|
saveGeom,
|
|
|
|
shortcut,
|
|
|
|
showWarning,
|
|
|
|
tooltip,
|
2020-11-17 08:42:43 +01:00
|
|
|
tr,
|
2019-12-23 01:34:10 +01:00
|
|
|
)
|
2012-12-21 08:51:59 +01:00
|
|
|
|
2019-12-20 09:43:52 +01:00
|
|
|
|
2012-12-21 08:51:59 +01:00
|
|
|
class AddCards(QDialog):
|
2019-12-20 09:43:52 +01:00
|
|
|
def __init__(self, mw: AnkiQt) -> None:
|
2012-12-21 08:51:59 +01:00
|
|
|
QDialog.__init__(self, None, Qt.Window)
|
2021-03-05 04:07:52 +01:00
|
|
|
mw.garbage_collect_on_dialog_finish(self)
|
2012-12-21 08:51:59 +01:00
|
|
|
self.mw = mw
|
2021-03-29 08:12:26 +02:00
|
|
|
self.col = mw.col
|
2021-08-20 03:37:23 +02:00
|
|
|
form = aqt.forms.addcards.Ui_Dialog()
|
|
|
|
form.setupUi(self)
|
|
|
|
self.form = form
|
2021-03-26 04:48:26 +01:00
|
|
|
self.setWindowTitle(tr.actions_add())
|
2021-01-07 05:24:49 +01:00
|
|
|
disable_help_button(self)
|
2012-12-21 08:51:59 +01:00
|
|
|
self.setMinimumHeight(300)
|
|
|
|
self.setMinimumWidth(400)
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
self.setup_choosers()
|
2012-12-21 08:51:59 +01:00
|
|
|
self.setupEditor()
|
|
|
|
self.setupButtons()
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
self._load_new_note()
|
2021-10-03 10:59:42 +02:00
|
|
|
self.history: list[NoteId] = []
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
self._last_added_note: Optional[Note] = None
|
2021-04-30 09:15:59 +02:00
|
|
|
gui_hooks.operation_did_execute.append(self.on_operation_did_execute)
|
2012-12-21 08:51:59 +01:00
|
|
|
restoreGeom(self, "add")
|
2012-12-22 01:11:29 +01:00
|
|
|
addCloseShortcut(self)
|
2020-04-03 10:54:54 +02:00
|
|
|
gui_hooks.add_cards_did_init(self)
|
2012-12-21 08:51:59 +01:00
|
|
|
self.show()
|
|
|
|
|
2019-12-20 09:43:52 +01:00
|
|
|
def setupEditor(self) -> None:
|
2019-12-23 01:34:10 +01:00
|
|
|
self.editor = aqt.editor.Editor(self.mw, self.form.fieldsArea, self, True)
|
2021-08-03 05:52:07 +02:00
|
|
|
self.editor.web.eval("activateStickyShortcuts();")
|
2012-12-21 08:51:59 +01:00
|
|
|
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
def setup_choosers(self) -> None:
|
2021-03-29 08:12:26 +02:00
|
|
|
defaults = self.col.defaults_for_adding(
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
current_review_card=self.mw.reviewer.card
|
|
|
|
)
|
2021-03-27 13:03:19 +01:00
|
|
|
self.notetype_chooser = NotetypeChooser(
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
mw=self.mw,
|
|
|
|
widget=self.form.modelArea,
|
2021-03-27 13:03:19 +01:00
|
|
|
starting_notetype_id=NotetypeId(defaults.notetype_id),
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
on_button_activated=self.show_notetype_selector,
|
|
|
|
on_notetype_changed=self.on_notetype_change,
|
|
|
|
)
|
2021-04-15 18:18:25 +02:00
|
|
|
self.deck_chooser = DeckChooser(
|
2021-03-27 12:38:20 +01:00
|
|
|
self.mw, self.form.deckArea, starting_deck_id=DeckId(defaults.deck_id)
|
2020-10-05 05:33:54 +02:00
|
|
|
)
|
2012-12-21 08:51:59 +01:00
|
|
|
|
2021-02-01 14:28:21 +01:00
|
|
|
def helpRequested(self) -> None:
|
2021-01-25 14:45:47 +01:00
|
|
|
openHelp(HelpPage.ADDING_CARD_AND_NOTE)
|
2012-12-21 08:51:59 +01:00
|
|
|
|
2019-12-20 09:43:52 +01:00
|
|
|
def setupButtons(self) -> None:
|
2012-12-21 08:51:59 +01:00
|
|
|
bb = self.form.buttonBox
|
|
|
|
ar = QDialogButtonBox.ActionRole
|
|
|
|
# add
|
2021-03-26 04:48:26 +01:00
|
|
|
self.addButton = bb.addButton(tr.actions_add(), ar)
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
qconnect(self.addButton.clicked, self.add_current_note)
|
2012-12-21 08:51:59 +01:00
|
|
|
self.addButton.setShortcut(QKeySequence("Ctrl+Return"))
|
2021-06-01 08:25:12 +02:00
|
|
|
# qt5.14 doesn't handle numpad enter on Windows
|
|
|
|
self.compat_add_shorcut = QShortcut(QKeySequence("Ctrl+Enter"), self)
|
|
|
|
qconnect(self.compat_add_shorcut.activated, self.addButton.click)
|
2021-03-26 04:48:26 +01:00
|
|
|
self.addButton.setToolTip(shortcut(tr.adding_add_shortcut_ctrlandenter()))
|
2012-12-21 08:51:59 +01:00
|
|
|
# close
|
2021-03-26 04:48:26 +01:00
|
|
|
self.closeButton = QPushButton(tr.actions_close())
|
2012-12-21 08:51:59 +01:00
|
|
|
self.closeButton.setAutoDefault(False)
|
2016-05-31 10:51:40 +02:00
|
|
|
bb.addButton(self.closeButton, QDialogButtonBox.RejectRole)
|
2012-12-21 08:51:59 +01:00
|
|
|
# help
|
2021-03-26 04:48:26 +01:00
|
|
|
self.helpButton = QPushButton(tr.actions_help(), clicked=self.helpRequested) # type: ignore
|
2012-12-21 08:51:59 +01:00
|
|
|
self.helpButton.setAutoDefault(False)
|
2019-12-23 01:34:10 +01:00
|
|
|
bb.addButton(self.helpButton, QDialogButtonBox.HelpRole)
|
2012-12-21 08:51:59 +01:00
|
|
|
# history
|
2021-03-26 04:48:26 +01:00
|
|
|
b = bb.addButton(f"{tr.adding_history()} {downArrow()}", ar)
|
2013-05-23 07:44:00 +02:00
|
|
|
if isMac:
|
|
|
|
sc = "Ctrl+Shift+H"
|
|
|
|
else:
|
|
|
|
sc = "Ctrl+H"
|
|
|
|
b.setShortcut(QKeySequence(sc))
|
2021-03-26 05:21:04 +01:00
|
|
|
b.setToolTip(tr.adding_shortcut(val=shortcut(sc)))
|
2020-05-04 05:23:08 +02:00
|
|
|
qconnect(b.clicked, self.onHistory)
|
2012-12-21 08:51:59 +01:00
|
|
|
b.setEnabled(False)
|
|
|
|
self.historyButton = b
|
|
|
|
|
2019-12-20 09:43:52 +01:00
|
|
|
def setAndFocusNote(self, note: Note) -> None:
|
2021-03-16 07:39:41 +01:00
|
|
|
self.editor.set_note(note, focusTo=0)
|
2012-12-21 08:51:59 +01:00
|
|
|
|
2020-10-05 05:33:54 +02:00
|
|
|
def show_notetype_selector(self) -> None:
|
2021-03-16 13:40:37 +01:00
|
|
|
self.editor.call_after_note_saved(self.notetype_chooser.choose_notetype)
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
2021-03-27 13:03:19 +01:00
|
|
|
def on_notetype_change(self, notetype_id: NotetypeId) -> None:
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
# need to adjust current deck?
|
2021-03-29 08:12:26 +02:00
|
|
|
if deck_id := self.col.default_deck_for_notetype(notetype_id):
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
self.deck_chooser.selected_deck_id = deck_id
|
|
|
|
|
|
|
|
# only used for detecting changed sticky fields on close
|
|
|
|
self._last_added_note = None
|
|
|
|
|
|
|
|
# copy fields into new note with the new notetype
|
|
|
|
old = self.editor.note
|
|
|
|
new = self._new_note()
|
|
|
|
if old:
|
|
|
|
old_fields = list(old.keys())
|
|
|
|
new_fields = list(new.keys())
|
2021-06-27 04:12:23 +02:00
|
|
|
for n, f in enumerate(new.note_type()["flds"]):
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
field_name = f["name"]
|
2016-04-10 13:11:25 +02:00
|
|
|
# copy identical fields
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
if field_name in old_fields:
|
|
|
|
new[field_name] = old[field_name]
|
2021-06-27 04:12:23 +02:00
|
|
|
elif n < len(old.note_type()["flds"]):
|
2020-04-26 16:52:35 +02:00
|
|
|
# set non-identical fields by field index
|
2021-06-27 04:12:23 +02:00
|
|
|
old_field_name = old.note_type()["flds"][n]["name"]
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
if old_field_name not in new_fields:
|
|
|
|
new.fields[n] = old.fields[n]
|
2021-06-24 12:16:21 +02:00
|
|
|
new.tags = old.tags
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
|
|
|
# and update editor state
|
|
|
|
self.editor.note = new
|
2021-09-13 07:31:24 +02:00
|
|
|
self.editor.loadNote(
|
|
|
|
focusTo=min(self.editor.last_field_index or 0, len(new.fields) - 1)
|
|
|
|
)
|
2021-09-25 04:22:42 +02:00
|
|
|
gui_hooks.add_cards_did_change_note_type(old.note_type(), new.note_type())
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
|
|
|
def _load_new_note(self, sticky_fields_from: Optional[Note] = None) -> None:
|
|
|
|
note = self._new_note()
|
|
|
|
if old_note := sticky_fields_from:
|
2021-06-27 04:12:23 +02:00
|
|
|
flds = note.note_type()["flds"]
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
# copy fields from old note
|
|
|
|
if old_note:
|
|
|
|
for n in range(min(len(note.fields), len(old_note.fields))):
|
|
|
|
if flds[n]["sticky"]:
|
|
|
|
note.fields[n] = old_note.fields[n]
|
2021-05-27 05:18:34 +02:00
|
|
|
# and tags
|
|
|
|
note.tags = old_note.tags
|
2017-08-05 07:15:19 +02:00
|
|
|
self.setAndFocusNote(note)
|
2012-12-21 08:51:59 +01:00
|
|
|
|
2021-04-30 09:15:59 +02:00
|
|
|
def on_operation_did_execute(
|
|
|
|
self, changes: OpChanges, handler: Optional[object]
|
|
|
|
) -> None:
|
|
|
|
if (changes.notetype or changes.deck) and handler is not self.editor:
|
|
|
|
self.on_notetype_change(
|
|
|
|
NotetypeId(
|
|
|
|
self.col.defaults_for_adding(
|
|
|
|
current_review_card=self.mw.reviewer.card
|
|
|
|
).notetype_id
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
def _new_note(self) -> Note:
|
2021-03-29 08:12:26 +02:00
|
|
|
return self.col.new_note(
|
|
|
|
self.col.models.get(self.notetype_chooser.selected_notetype_id)
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
)
|
2012-12-21 08:51:59 +01:00
|
|
|
|
2021-02-01 13:08:56 +01:00
|
|
|
def addHistory(self, note: Note) -> None:
|
2017-01-08 14:48:58 +01:00
|
|
|
self.history.insert(0, note.id)
|
2012-12-21 08:51:59 +01:00
|
|
|
self.history = self.history[:15]
|
|
|
|
self.historyButton.setEnabled(True)
|
|
|
|
|
2020-01-15 22:41:23 +01:00
|
|
|
def onHistory(self) -> None:
|
2012-12-21 08:51:59 +01:00
|
|
|
m = QMenu(self)
|
2017-01-08 14:48:58 +01:00
|
|
|
for nid in self.history:
|
2021-03-29 08:12:26 +02:00
|
|
|
if self.col.find_notes(self.col.build_search_string(SearchNode(nid=nid))):
|
|
|
|
note = self.col.get_note(nid)
|
2020-06-03 23:29:09 +02:00
|
|
|
fields = note.fields
|
2017-03-14 07:48:40 +01:00
|
|
|
txt = htmlToTextLine(", ".join(fields))
|
2017-02-05 08:45:08 +01:00
|
|
|
if len(txt) > 30:
|
2021-02-11 01:09:06 +01:00
|
|
|
txt = f"{txt[:30]}..."
|
2021-03-26 05:21:04 +01:00
|
|
|
line = tr.adding_edit(val=txt)
|
2020-06-03 23:29:09 +02:00
|
|
|
line = gui_hooks.addcards_will_add_history_entry(line, note)
|
2021-08-15 06:32:03 +02:00
|
|
|
line = line.replace("&", "&&")
|
|
|
|
# In qt action "&i" means "underline i, trigger this line when i is pressed".
|
|
|
|
# except for "&&" which is replaced by a single "&"
|
2020-06-03 23:29:09 +02:00
|
|
|
a = m.addAction(line)
|
2020-01-15 22:41:23 +01:00
|
|
|
qconnect(a.triggered, lambda b, nid=nid: self.editHistory(nid))
|
2017-01-09 11:55:30 +01:00
|
|
|
else:
|
2021-03-26 04:48:26 +01:00
|
|
|
a = m.addAction(tr.adding_note_deleted())
|
2017-01-09 11:55:30 +01:00
|
|
|
a.setEnabled(False)
|
2020-01-15 08:45:35 +01:00
|
|
|
gui_hooks.add_cards_will_show_history_menu(self, m)
|
2021-10-05 02:01:45 +02:00
|
|
|
m.exec(self.historyButton.mapToGlobal(QPoint(0, 0)))
|
2012-12-21 08:51:59 +01:00
|
|
|
|
2021-03-27 12:38:20 +01:00
|
|
|
def editHistory(self, nid: NoteId) -> None:
|
2021-02-11 10:57:19 +01:00
|
|
|
aqt.dialogs.open("Browser", self.mw, search=(SearchNode(nid=nid),))
|
2012-12-21 08:51:59 +01:00
|
|
|
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
def add_current_note(self) -> None:
|
2021-03-16 13:40:37 +01:00
|
|
|
self.editor.call_after_note_saved(self._add_current_note)
|
2012-12-21 08:51:59 +01:00
|
|
|
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
def _add_current_note(self) -> None:
|
|
|
|
note = self.editor.note
|
2016-07-14 12:23:44 +02:00
|
|
|
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
if not self._note_can_be_added(note):
|
2012-12-21 08:51:59 +01:00
|
|
|
return
|
2020-10-24 10:47:25 +02:00
|
|
|
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
target_deck_id = self.deck_chooser.selected_deck_id
|
|
|
|
|
undoable ops now return changes directly; add new *_ops.py files
- Introduced a new transact() method that wraps the return value
in a separate struct that describes the changes that were made.
- Changes are now gathered from the undo log, so we don't need to
guess at what was changed - eg if update_note() is called with identical
note contents, no changes are returned. Card changes will only be set
if cards were actually generated by the update_note() call, and tag
will only be set if a new tag was added.
- mw.perform_op() has been updated to expect the op to return the changes,
or a structure with the changes in it, and it will use them to fire the
change hook, instead of fetching the changes from undo_status(), so there
is no risk of race conditions.
- the various calls to mw.perform_op() have been split into separate
files like card_ops.py. Aside from making the code cleaner, this works
around a rather annoying issue with mypy. Because we run it with
no_strict_optional, mypy is happy to accept an operation that returns None,
despite the type signature saying it requires changes to be returned.
Turning no_strict_optional on for the whole codebase is not practical
at the moment, but we can enable it for individual files.
Still todo:
- The cursor keeps moving back to the start of a field when typing -
we need to ignore the refresh hook when we are the initiator.
- The busy cursor icon should probably be delayed a few hundreds ms.
- Still need to think about a nicer way of handling saveNow()
- op_made_changes(), op_affects_study_queue() might be better embedded
as properties in the object instead
2021-03-16 05:26:42 +01:00
|
|
|
def on_success(changes: OpChanges) -> None:
|
|
|
|
# only used for detecting changed sticky fields on close
|
|
|
|
self._last_added_note = note
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
undoable ops now return changes directly; add new *_ops.py files
- Introduced a new transact() method that wraps the return value
in a separate struct that describes the changes that were made.
- Changes are now gathered from the undo log, so we don't need to
guess at what was changed - eg if update_note() is called with identical
note contents, no changes are returned. Card changes will only be set
if cards were actually generated by the update_note() call, and tag
will only be set if a new tag was added.
- mw.perform_op() has been updated to expect the op to return the changes,
or a structure with the changes in it, and it will use them to fire the
change hook, instead of fetching the changes from undo_status(), so there
is no risk of race conditions.
- the various calls to mw.perform_op() have been split into separate
files like card_ops.py. Aside from making the code cleaner, this works
around a rather annoying issue with mypy. Because we run it with
no_strict_optional, mypy is happy to accept an operation that returns None,
despite the type signature saying it requires changes to be returned.
Turning no_strict_optional on for the whole codebase is not practical
at the moment, but we can enable it for individual files.
Still todo:
- The cursor keeps moving back to the start of a field when typing -
we need to ignore the refresh hook when we are the initiator.
- The busy cursor icon should probably be delayed a few hundreds ms.
- Still need to think about a nicer way of handling saveNow()
- op_made_changes(), op_affects_study_queue() might be better embedded
as properties in the object instead
2021-03-16 05:26:42 +01:00
|
|
|
self.addHistory(note)
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
2021-03-26 04:48:26 +01:00
|
|
|
tooltip(tr.adding_added(), period=500)
|
undoable ops now return changes directly; add new *_ops.py files
- Introduced a new transact() method that wraps the return value
in a separate struct that describes the changes that were made.
- Changes are now gathered from the undo log, so we don't need to
guess at what was changed - eg if update_note() is called with identical
note contents, no changes are returned. Card changes will only be set
if cards were actually generated by the update_note() call, and tag
will only be set if a new tag was added.
- mw.perform_op() has been updated to expect the op to return the changes,
or a structure with the changes in it, and it will use them to fire the
change hook, instead of fetching the changes from undo_status(), so there
is no risk of race conditions.
- the various calls to mw.perform_op() have been split into separate
files like card_ops.py. Aside from making the code cleaner, this works
around a rather annoying issue with mypy. Because we run it with
no_strict_optional, mypy is happy to accept an operation that returns None,
despite the type signature saying it requires changes to be returned.
Turning no_strict_optional on for the whole codebase is not practical
at the moment, but we can enable it for individual files.
Still todo:
- The cursor keeps moving back to the start of a field when typing -
we need to ignore the refresh hook when we are the initiator.
- The busy cursor icon should probably be delayed a few hundreds ms.
- Still need to think about a nicer way of handling saveNow()
- op_made_changes(), op_affects_study_queue() might be better embedded
as properties in the object instead
2021-03-16 05:26:42 +01:00
|
|
|
av_player.stop_and_clear_queue()
|
|
|
|
self._load_new_note(sticky_fields_from=note)
|
|
|
|
gui_hooks.add_cards_did_add_note(note)
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
2021-04-06 06:56:36 +02:00
|
|
|
add_note(parent=self, note=note, target_deck_id=target_deck_id).success(
|
|
|
|
on_success
|
|
|
|
).run_in_background()
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
|
|
|
def _note_can_be_added(self, note: Note) -> bool:
|
2021-06-12 10:05:42 +02:00
|
|
|
result = note.fields_check()
|
2021-06-26 00:35:24 +02:00
|
|
|
# no problem, duplicate, and confirmed cloze cases
|
|
|
|
problem = None
|
2021-06-12 10:05:42 +02:00
|
|
|
if result == NoteFieldsCheckResult.EMPTY:
|
2021-03-26 04:48:26 +01:00
|
|
|
problem = tr.adding_the_first_field_is_empty()
|
2021-06-12 10:05:42 +02:00
|
|
|
elif result == NoteFieldsCheckResult.MISSING_CLOZE:
|
2021-06-14 10:20:53 +02:00
|
|
|
if not askUser(tr.adding_you_have_a_cloze_deletion_note()):
|
|
|
|
return False
|
2021-06-12 10:05:42 +02:00
|
|
|
elif result == NoteFieldsCheckResult.NOTETYPE_NOT_CLOZE:
|
|
|
|
problem = tr.adding_cloze_outside_cloze_notetype()
|
|
|
|
elif result == NoteFieldsCheckResult.FIELD_NOT_CLOZE:
|
|
|
|
problem = tr.adding_cloze_outside_cloze_field()
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
|
|
|
# filter problem through add-ons
|
|
|
|
problem = gui_hooks.add_cards_will_add_note(problem, note)
|
|
|
|
if problem is not None:
|
|
|
|
showWarning(problem, help=HelpPage.ADDING_CARD_AND_NOTE)
|
|
|
|
return False
|
|
|
|
|
|
|
|
return True
|
2012-12-21 08:51:59 +01:00
|
|
|
|
2021-02-01 13:08:56 +01:00
|
|
|
def keyPressEvent(self, evt: QKeyEvent) -> None:
|
2012-12-21 08:51:59 +01:00
|
|
|
"Show answer on RET or register answer."
|
2019-12-23 01:34:10 +01:00
|
|
|
if evt.key() in (Qt.Key_Enter, Qt.Key_Return) and self.editor.tags.hasFocus():
|
2012-12-21 08:51:59 +01:00
|
|
|
evt.accept()
|
|
|
|
return
|
|
|
|
return QDialog.keyPressEvent(self, evt)
|
|
|
|
|
2019-12-20 09:43:52 +01:00
|
|
|
def reject(self) -> None:
|
2017-08-16 04:45:33 +02:00
|
|
|
self.ifCanClose(self._reject)
|
|
|
|
|
2019-12-20 09:43:52 +01:00
|
|
|
def _reject(self) -> None:
|
2020-01-20 11:10:38 +01:00
|
|
|
av_player.stop_and_clear_queue()
|
2017-08-16 04:45:33 +02:00
|
|
|
self.editor.cleanup()
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
self.notetype_chooser.cleanup()
|
2021-04-30 09:15:59 +02:00
|
|
|
gui_hooks.operation_did_execute.remove(self.on_operation_did_execute)
|
2012-12-21 08:51:59 +01:00
|
|
|
self.mw.maybeReset()
|
|
|
|
saveGeom(self, "add")
|
2017-08-16 04:45:33 +02:00
|
|
|
aqt.dialogs.markClosed("AddCards")
|
2012-12-21 08:51:59 +01:00
|
|
|
QDialog.reject(self)
|
|
|
|
|
2019-12-20 09:43:52 +01:00
|
|
|
def ifCanClose(self, onOk: Callable) -> None:
|
2021-02-01 14:28:21 +01:00
|
|
|
def afterSave() -> None:
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
ok = self.editor.fieldsAreBlank(self._last_added_note) or askUser(
|
2021-03-26 04:48:26 +01:00
|
|
|
tr.adding_close_and_lose_current_input(), defaultno=True
|
2019-12-23 01:34:10 +01:00
|
|
|
)
|
2017-08-16 04:45:33 +02:00
|
|
|
if ok:
|
|
|
|
onOk()
|
|
|
|
|
2021-03-16 13:40:37 +01:00
|
|
|
self.editor.call_after_note_saved(afterSave)
|
2017-08-16 04:45:33 +02:00
|
|
|
|
2021-02-02 15:00:29 +01:00
|
|
|
def closeWithCallback(self, cb: Callable[[], None]) -> None:
|
2021-02-01 14:28:21 +01:00
|
|
|
def doClose() -> None:
|
2017-08-16 04:45:33 +02:00
|
|
|
self._reject()
|
|
|
|
cb()
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2017-08-16 04:45:33 +02:00
|
|
|
self.ifCanClose(doClose)
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
|
|
|
# legacy aliases
|
|
|
|
|
2021-04-15 18:18:25 +02:00
|
|
|
@property
|
|
|
|
def deckChooser(self) -> DeckChooser:
|
2021-08-20 03:37:23 +02:00
|
|
|
if getattr(self, "form", None):
|
|
|
|
# show this warning only after Qt form has been initialized,
|
|
|
|
# or PyQt's introspection triggers it
|
|
|
|
print("deckChooser is deprecated; use deck_chooser instead")
|
2021-04-15 18:18:25 +02:00
|
|
|
return self.deck_chooser
|
|
|
|
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
addCards = add_current_note
|
|
|
|
_addCards = _add_current_note
|
|
|
|
onModelChange = on_notetype_change
|
|
|
|
|
2021-08-20 03:37:23 +02:00
|
|
|
@deprecated(info="obsolete")
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
def addNote(self, note: Note) -> None:
|
2021-08-20 03:37:23 +02:00
|
|
|
pass
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
|
2021-08-20 03:37:23 +02:00
|
|
|
@deprecated(info="does nothing; will go away")
|
Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:
- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.
It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.
To address these points:
- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-08 14:23:24 +01:00
|
|
|
def removeTempNote(self, note: Note) -> None:
|
2021-08-20 03:37:23 +02:00
|
|
|
pass
|