mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
Add back legacy code as separate screens
This commit is contained in:
parent
c91f943f29
commit
7dac2fc4ff
11 changed files with 2383 additions and 99 deletions
|
@ -125,9 +125,11 @@ from aqt import stats, about, preferences, mediasync # isort:skip
|
||||||
class DialogManager:
|
class DialogManager:
|
||||||
_dialogs: dict[str, list] = {
|
_dialogs: dict[str, list] = {
|
||||||
"AddCards": [addcards.AddCards, None],
|
"AddCards": [addcards.AddCards, None],
|
||||||
|
"NewAddCards": [addcards.NewAddCards, None],
|
||||||
"AddonsDialog": [addons.AddonsDialog, None],
|
"AddonsDialog": [addons.AddonsDialog, None],
|
||||||
"Browser": [browser.Browser, None],
|
"Browser": [browser.Browser, None],
|
||||||
"EditCurrent": [editcurrent.EditCurrent, None],
|
"EditCurrent": [editcurrent.EditCurrent, None],
|
||||||
|
"NewEditCurrent": [editcurrent.NewEditCurrent, None],
|
||||||
"FilteredDeckConfigDialog": [filtered_deck.FilteredDeckConfigDialog, None],
|
"FilteredDeckConfigDialog": [filtered_deck.FilteredDeckConfigDialog, None],
|
||||||
"DeckStats": [stats.DeckStats, None],
|
"DeckStats": [stats.DeckStats, None],
|
||||||
"NewDeckStats": [stats.NewDeckStats, None],
|
"NewDeckStats": [stats.NewDeckStats, None],
|
||||||
|
|
|
@ -14,6 +14,7 @@ from anki.models import NotetypeId
|
||||||
from anki.notes import Note, NoteId
|
from anki.notes import Note, NoteId
|
||||||
from anki.utils import html_to_text_line, is_mac
|
from anki.utils import html_to_text_line, is_mac
|
||||||
from aqt import AnkiQt, gui_hooks
|
from aqt import AnkiQt, gui_hooks
|
||||||
|
from aqt.addcards_legacy import *
|
||||||
from aqt.deckchooser import DeckChooser
|
from aqt.deckchooser import DeckChooser
|
||||||
from aqt.notetypechooser import NotetypeChooser
|
from aqt.notetypechooser import NotetypeChooser
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
|
@ -30,7 +31,7 @@ from aqt.utils import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class AddCards(QMainWindow):
|
class NewAddCards(QMainWindow):
|
||||||
def __init__(self, mw: AnkiQt) -> None:
|
def __init__(self, mw: AnkiQt) -> None:
|
||||||
super().__init__(None, Qt.WindowType.Window)
|
super().__init__(None, Qt.WindowType.Window)
|
||||||
self._close_event_has_cleaned_up = False
|
self._close_event_has_cleaned_up = False
|
||||||
|
@ -79,7 +80,7 @@ class AddCards(QMainWindow):
|
||||||
self.setAndFocusNote(new_note)
|
self.setAndFocusNote(new_note)
|
||||||
|
|
||||||
def setupEditor(self) -> None:
|
def setupEditor(self) -> None:
|
||||||
self.editor = aqt.editor.Editor(
|
self.editor = aqt.editor.NewEditor(
|
||||||
self.mw,
|
self.mw,
|
||||||
self.form.fieldsArea,
|
self.form.fieldsArea,
|
||||||
self,
|
self,
|
||||||
|
@ -244,7 +245,7 @@ class AddCards(QMainWindow):
|
||||||
gui_hooks.operation_did_execute.remove(self.on_operation_did_execute)
|
gui_hooks.operation_did_execute.remove(self.on_operation_did_execute)
|
||||||
self.mw.maybeReset()
|
self.mw.maybeReset()
|
||||||
saveGeom(self, "add")
|
saveGeom(self, "add")
|
||||||
aqt.dialogs.markClosed("AddCards")
|
aqt.dialogs.markClosed("NewAddCards")
|
||||||
self._close_event_has_cleaned_up = True
|
self._close_event_has_cleaned_up = True
|
||||||
self.mw.deferred_delete_and_garbage_collect(self)
|
self.mw.deferred_delete_and_garbage_collect(self)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
414
qt/aqt/addcards_legacy.py
Normal file
414
qt/aqt/addcards_legacy.py
Normal file
|
@ -0,0 +1,414 @@
|
||||||
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
|
||||||
|
import aqt.editor
|
||||||
|
import aqt.forms
|
||||||
|
from anki._legacy import deprecated
|
||||||
|
from anki.collection import OpChanges, SearchNode
|
||||||
|
from anki.decks import DeckId
|
||||||
|
from anki.models import NotetypeId
|
||||||
|
from anki.notes import Note, NoteFieldsCheckResult, NoteId
|
||||||
|
from anki.utils import html_to_text_line, is_mac
|
||||||
|
from aqt import AnkiQt, gui_hooks
|
||||||
|
from aqt.deckchooser import DeckChooser
|
||||||
|
from aqt.notetypechooser import NotetypeChooser
|
||||||
|
from aqt.operations.note import add_note
|
||||||
|
from aqt.qt import *
|
||||||
|
from aqt.sound import av_player
|
||||||
|
from aqt.utils import (
|
||||||
|
HelpPage,
|
||||||
|
add_close_shortcut,
|
||||||
|
ask_user_dialog,
|
||||||
|
askUser,
|
||||||
|
downArrow,
|
||||||
|
openHelp,
|
||||||
|
restoreGeom,
|
||||||
|
saveGeom,
|
||||||
|
shortcut,
|
||||||
|
showWarning,
|
||||||
|
tooltip,
|
||||||
|
tr,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddCards(QMainWindow):
|
||||||
|
def __init__(self, mw: AnkiQt) -> None:
|
||||||
|
super().__init__(None, Qt.WindowType.Window)
|
||||||
|
self._close_event_has_cleaned_up = False
|
||||||
|
self.mw = mw
|
||||||
|
self.col = mw.col
|
||||||
|
form = aqt.forms.addcards.Ui_Dialog()
|
||||||
|
form.setupUi(self)
|
||||||
|
self.form = form
|
||||||
|
self.setWindowTitle(tr.actions_add())
|
||||||
|
self.setMinimumHeight(300)
|
||||||
|
self.setMinimumWidth(400)
|
||||||
|
self.setup_choosers()
|
||||||
|
self.setupEditor()
|
||||||
|
add_close_shortcut(self)
|
||||||
|
self._load_new_note()
|
||||||
|
self.setupButtons()
|
||||||
|
self.history: list[NoteId] = []
|
||||||
|
self._last_added_note: Note | None = None
|
||||||
|
gui_hooks.operation_did_execute.append(self.on_operation_did_execute)
|
||||||
|
restoreGeom(self, "add")
|
||||||
|
gui_hooks.add_cards_did_init(self)
|
||||||
|
if not is_mac:
|
||||||
|
self.setMenuBar(None)
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
def set_deck(self, deck_id: DeckId) -> None:
|
||||||
|
self.deck_chooser.selected_deck_id = deck_id
|
||||||
|
|
||||||
|
def set_note_type(self, note_type_id: NotetypeId) -> None:
|
||||||
|
self.notetype_chooser.selected_notetype_id = note_type_id
|
||||||
|
|
||||||
|
def set_note(self, note: Note, deck_id: DeckId | None = None) -> None:
|
||||||
|
"""Set tags, field contents and notetype according to `note`. Deck is set
|
||||||
|
to `deck_id` or the deck last used with the notetype.
|
||||||
|
"""
|
||||||
|
self.notetype_chooser.selected_notetype_id = note.mid
|
||||||
|
if deck_id or (deck_id := self.col.default_deck_for_notetype(note.mid)):
|
||||||
|
self.deck_chooser.selected_deck_id = deck_id
|
||||||
|
|
||||||
|
new_note = self._new_note()
|
||||||
|
new_note.fields = note.fields[:]
|
||||||
|
new_note.tags = note.tags[:]
|
||||||
|
|
||||||
|
self.editor.orig_note_id = note.id
|
||||||
|
self.setAndFocusNote(new_note)
|
||||||
|
|
||||||
|
def setupEditor(self) -> None:
|
||||||
|
self.editor = aqt.editor.Editor(
|
||||||
|
self.mw,
|
||||||
|
self.form.fieldsArea,
|
||||||
|
self,
|
||||||
|
editor_mode=aqt.editor.EditorMode.ADD_CARDS,
|
||||||
|
)
|
||||||
|
|
||||||
|
def setup_choosers(self) -> None:
|
||||||
|
defaults = self.col.defaults_for_adding(
|
||||||
|
current_review_card=self.mw.reviewer.card
|
||||||
|
)
|
||||||
|
|
||||||
|
self.notetype_chooser = NotetypeChooser(
|
||||||
|
mw=self.mw,
|
||||||
|
widget=self.form.modelArea,
|
||||||
|
starting_notetype_id=NotetypeId(defaults.notetype_id),
|
||||||
|
on_button_activated=self.show_notetype_selector,
|
||||||
|
on_notetype_changed=self.on_notetype_change,
|
||||||
|
)
|
||||||
|
self.deck_chooser = DeckChooser(
|
||||||
|
self.mw,
|
||||||
|
self.form.deckArea,
|
||||||
|
starting_deck_id=DeckId(defaults.deck_id),
|
||||||
|
on_deck_changed=self.on_deck_changed,
|
||||||
|
)
|
||||||
|
|
||||||
|
def reopen(self, mw: AnkiQt) -> None:
|
||||||
|
if not self.editor.fieldsAreBlank():
|
||||||
|
return
|
||||||
|
|
||||||
|
defaults = self.col.defaults_for_adding(
|
||||||
|
current_review_card=self.mw.reviewer.card
|
||||||
|
)
|
||||||
|
self.set_note_type(NotetypeId(defaults.notetype_id))
|
||||||
|
self.set_deck(DeckId(defaults.deck_id))
|
||||||
|
|
||||||
|
def helpRequested(self) -> None:
|
||||||
|
openHelp(HelpPage.ADDING_CARD_AND_NOTE)
|
||||||
|
|
||||||
|
def setupButtons(self) -> None:
|
||||||
|
bb = self.form.buttonBox
|
||||||
|
ar = QDialogButtonBox.ButtonRole.ActionRole
|
||||||
|
# add
|
||||||
|
self.addButton = bb.addButton(tr.actions_add(), ar)
|
||||||
|
qconnect(self.addButton.clicked, self.add_current_note)
|
||||||
|
self.addButton.setShortcut(QKeySequence("Ctrl+Return"))
|
||||||
|
# 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)
|
||||||
|
self.addButton.setToolTip(shortcut(tr.adding_add_shortcut_ctrlandenter()))
|
||||||
|
|
||||||
|
# close
|
||||||
|
self.closeButton = QPushButton(tr.actions_close())
|
||||||
|
self.closeButton.setAutoDefault(False)
|
||||||
|
bb.addButton(self.closeButton, QDialogButtonBox.ButtonRole.RejectRole)
|
||||||
|
qconnect(self.closeButton.clicked, self.close)
|
||||||
|
# help
|
||||||
|
self.helpButton = QPushButton(tr.actions_help(), clicked=self.helpRequested) # type: ignore
|
||||||
|
self.helpButton.setAutoDefault(False)
|
||||||
|
bb.addButton(self.helpButton, QDialogButtonBox.ButtonRole.HelpRole)
|
||||||
|
# history
|
||||||
|
b = bb.addButton(f"{tr.adding_history()} {downArrow()}", ar)
|
||||||
|
if is_mac:
|
||||||
|
sc = "Ctrl+Shift+H"
|
||||||
|
else:
|
||||||
|
sc = "Ctrl+H"
|
||||||
|
b.setShortcut(QKeySequence(sc))
|
||||||
|
b.setToolTip(tr.adding_shortcut(val=shortcut(sc)))
|
||||||
|
qconnect(b.clicked, self.onHistory)
|
||||||
|
b.setEnabled(False)
|
||||||
|
self.historyButton = b
|
||||||
|
|
||||||
|
def setAndFocusNote(self, note: Note) -> None:
|
||||||
|
self.editor.set_note(note, focusTo=0)
|
||||||
|
|
||||||
|
def show_notetype_selector(self) -> None:
|
||||||
|
self.editor.call_after_note_saved(self.notetype_chooser.choose_notetype)
|
||||||
|
|
||||||
|
def on_deck_changed(self, deck_id: int) -> None:
|
||||||
|
gui_hooks.add_cards_did_change_deck(deck_id)
|
||||||
|
|
||||||
|
def on_notetype_change(
|
||||||
|
self, notetype_id: NotetypeId, update_deck: bool = True
|
||||||
|
) -> None:
|
||||||
|
# need to adjust current deck?
|
||||||
|
if update_deck:
|
||||||
|
if deck_id := self.col.default_deck_for_notetype(notetype_id):
|
||||||
|
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_note = self.editor.note
|
||||||
|
new_note = self._new_note()
|
||||||
|
if old_note:
|
||||||
|
old_field_names = list(old_note.keys())
|
||||||
|
new_field_names = list(new_note.keys())
|
||||||
|
copied_field_names = set()
|
||||||
|
for f in new_note.note_type()["flds"]:
|
||||||
|
field_name = f["name"]
|
||||||
|
# copy identical non-empty fields
|
||||||
|
if field_name in old_field_names and old_note[field_name]:
|
||||||
|
new_note[field_name] = old_note[field_name]
|
||||||
|
copied_field_names.add(field_name)
|
||||||
|
new_idx = 0
|
||||||
|
for old_idx, old_field_value in enumerate(old_field_names):
|
||||||
|
# skip previously copied identical fields in new note
|
||||||
|
while (
|
||||||
|
new_idx < len(new_field_names)
|
||||||
|
and new_field_names[new_idx] in copied_field_names
|
||||||
|
):
|
||||||
|
new_idx += 1
|
||||||
|
if new_idx >= len(new_field_names):
|
||||||
|
break
|
||||||
|
# copy non-empty old fields
|
||||||
|
if (
|
||||||
|
old_field_value not in copied_field_names
|
||||||
|
and old_note.fields[old_idx]
|
||||||
|
):
|
||||||
|
new_note.fields[new_idx] = old_note.fields[old_idx]
|
||||||
|
new_idx += 1
|
||||||
|
|
||||||
|
new_note.tags = old_note.tags
|
||||||
|
|
||||||
|
# and update editor state
|
||||||
|
self.editor.note = new_note
|
||||||
|
self.editor.loadNote(
|
||||||
|
focusTo=min(self.editor.last_field_index or 0, len(new_note.fields) - 1)
|
||||||
|
)
|
||||||
|
gui_hooks.addcards_did_change_note_type(
|
||||||
|
self, old_note.note_type(), new_note.note_type()
|
||||||
|
)
|
||||||
|
|
||||||
|
def _load_new_note(self, sticky_fields_from: Note | None = None) -> None:
|
||||||
|
note = self._new_note()
|
||||||
|
if old_note := sticky_fields_from:
|
||||||
|
flds = note.note_type()["flds"]
|
||||||
|
# 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]
|
||||||
|
# and tags
|
||||||
|
note.tags = old_note.tags
|
||||||
|
self.setAndFocusNote(note)
|
||||||
|
|
||||||
|
def on_operation_did_execute(
|
||||||
|
self, changes: OpChanges, handler: object | None
|
||||||
|
) -> 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
|
||||||
|
),
|
||||||
|
update_deck=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _new_note(self) -> Note:
|
||||||
|
return self.col.new_note(
|
||||||
|
self.col.models.get(self.notetype_chooser.selected_notetype_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
def addHistory(self, note: Note) -> None:
|
||||||
|
self.history.insert(0, note.id)
|
||||||
|
self.history = self.history[:15]
|
||||||
|
self.historyButton.setEnabled(True)
|
||||||
|
|
||||||
|
def onHistory(self) -> None:
|
||||||
|
m = QMenu(self)
|
||||||
|
for nid in self.history:
|
||||||
|
if self.col.find_notes(self.col.build_search_string(SearchNode(nid=nid))):
|
||||||
|
note = self.col.get_note(nid)
|
||||||
|
fields = note.fields
|
||||||
|
txt = html_to_text_line(", ".join(fields))
|
||||||
|
if len(txt) > 30:
|
||||||
|
txt = f"{txt[:30]}..."
|
||||||
|
line = tr.adding_edit(val=txt)
|
||||||
|
line = gui_hooks.addcards_will_add_history_entry(line, note)
|
||||||
|
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 "&"
|
||||||
|
a = m.addAction(line)
|
||||||
|
qconnect(a.triggered, lambda b, nid=nid: self.editHistory(nid))
|
||||||
|
else:
|
||||||
|
a = m.addAction(tr.adding_note_deleted())
|
||||||
|
a.setEnabled(False)
|
||||||
|
gui_hooks.add_cards_will_show_history_menu(self, m)
|
||||||
|
m.exec(self.historyButton.mapToGlobal(QPoint(0, 0)))
|
||||||
|
|
||||||
|
def editHistory(self, nid: NoteId) -> None:
|
||||||
|
aqt.dialogs.open("Browser", self.mw, search=(SearchNode(nid=nid),))
|
||||||
|
|
||||||
|
def add_current_note(self) -> None:
|
||||||
|
if self.editor.current_notetype_is_image_occlusion():
|
||||||
|
self.editor.update_occlusions_field()
|
||||||
|
self.editor.call_after_note_saved(self._add_current_note)
|
||||||
|
self.editor.reset_image_occlusion()
|
||||||
|
else:
|
||||||
|
self.editor.call_after_note_saved(self._add_current_note)
|
||||||
|
|
||||||
|
def _add_current_note(self) -> None:
|
||||||
|
note = self.editor.note
|
||||||
|
|
||||||
|
if not self._note_can_be_added(note):
|
||||||
|
return
|
||||||
|
|
||||||
|
target_deck_id = self.deck_chooser.selected_deck_id
|
||||||
|
|
||||||
|
def on_success(changes: OpChanges) -> None:
|
||||||
|
# only used for detecting changed sticky fields on close
|
||||||
|
self._last_added_note = note
|
||||||
|
|
||||||
|
self.addHistory(note)
|
||||||
|
|
||||||
|
tooltip(tr.adding_added(), period=500)
|
||||||
|
av_player.stop_and_clear_queue()
|
||||||
|
self._load_new_note(sticky_fields_from=note)
|
||||||
|
gui_hooks.add_cards_did_add_note(note)
|
||||||
|
|
||||||
|
add_note(parent=self, note=note, target_deck_id=target_deck_id).success(
|
||||||
|
on_success
|
||||||
|
).run_in_background()
|
||||||
|
|
||||||
|
def _note_can_be_added(self, note: Note) -> bool:
|
||||||
|
result = note.fields_check()
|
||||||
|
# no problem, duplicate, and confirmed cloze cases
|
||||||
|
problem = None
|
||||||
|
if result == NoteFieldsCheckResult.EMPTY:
|
||||||
|
if self.editor.current_notetype_is_image_occlusion():
|
||||||
|
problem = tr.notetypes_no_occlusion_created2()
|
||||||
|
else:
|
||||||
|
problem = tr.adding_the_first_field_is_empty()
|
||||||
|
elif result == NoteFieldsCheckResult.MISSING_CLOZE:
|
||||||
|
if not askUser(tr.adding_you_have_a_cloze_deletion_note()):
|
||||||
|
return False
|
||||||
|
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()
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
optional_problems: list[str] = []
|
||||||
|
gui_hooks.add_cards_might_add_note(optional_problems, note)
|
||||||
|
if not all(askUser(op) for op in optional_problems):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def keyPressEvent(self, evt: QKeyEvent) -> None:
|
||||||
|
if evt.key() == Qt.Key.Key_Escape:
|
||||||
|
self.close()
|
||||||
|
else:
|
||||||
|
super().keyPressEvent(evt)
|
||||||
|
|
||||||
|
def closeEvent(self, evt: QCloseEvent) -> None:
|
||||||
|
if self._close_event_has_cleaned_up:
|
||||||
|
evt.accept()
|
||||||
|
return
|
||||||
|
self.ifCanClose(self._close)
|
||||||
|
evt.ignore()
|
||||||
|
|
||||||
|
def _close(self) -> None:
|
||||||
|
self.editor.cleanup()
|
||||||
|
self.notetype_chooser.cleanup()
|
||||||
|
self.deck_chooser.cleanup()
|
||||||
|
gui_hooks.operation_did_execute.remove(self.on_operation_did_execute)
|
||||||
|
self.mw.maybeReset()
|
||||||
|
saveGeom(self, "add")
|
||||||
|
aqt.dialogs.markClosed("AddCards")
|
||||||
|
self._close_event_has_cleaned_up = True
|
||||||
|
self.mw.deferred_delete_and_garbage_collect(self)
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def ifCanClose(self, onOk: Callable) -> None:
|
||||||
|
def callback(choice: int) -> None:
|
||||||
|
if choice == 0:
|
||||||
|
onOk()
|
||||||
|
|
||||||
|
def afterSave() -> None:
|
||||||
|
if self.editor.fieldsAreBlank(self._last_added_note):
|
||||||
|
return onOk()
|
||||||
|
|
||||||
|
ask_user_dialog(
|
||||||
|
tr.adding_discard_current_input(),
|
||||||
|
callback=callback,
|
||||||
|
buttons=[
|
||||||
|
QMessageBox.StandardButton.Discard,
|
||||||
|
(tr.adding_keep_editing(), QMessageBox.ButtonRole.RejectRole),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
self.editor.call_after_note_saved(afterSave)
|
||||||
|
|
||||||
|
def closeWithCallback(self, cb: Callable[[], None]) -> None:
|
||||||
|
def doClose() -> None:
|
||||||
|
self._close()
|
||||||
|
cb()
|
||||||
|
|
||||||
|
self.ifCanClose(doClose)
|
||||||
|
|
||||||
|
# legacy aliases
|
||||||
|
|
||||||
|
@property
|
||||||
|
def deckChooser(self) -> DeckChooser:
|
||||||
|
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")
|
||||||
|
return self.deck_chooser
|
||||||
|
|
||||||
|
addCards = add_current_note
|
||||||
|
_addCards = _add_current_note
|
||||||
|
onModelChange = on_notetype_change
|
||||||
|
|
||||||
|
@deprecated(info="obsolete")
|
||||||
|
def addNote(self, note: Note) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@deprecated(info="does nothing; will go away")
|
||||||
|
def removeTempNote(self, note: Note) -> None:
|
||||||
|
pass
|
|
@ -27,7 +27,6 @@ from anki.scheduler.base import ScheduleCardsAsNew
|
||||||
from anki.tags import MARKED_TAG
|
from anki.tags import MARKED_TAG
|
||||||
from anki.utils import is_mac
|
from anki.utils import is_mac
|
||||||
from aqt import AnkiQt, gui_hooks
|
from aqt import AnkiQt, gui_hooks
|
||||||
from aqt.editor import Editor, EditorWebView
|
|
||||||
from aqt.errors import show_exception
|
from aqt.errors import show_exception
|
||||||
from aqt.exporting import ExportDialog as LegacyExportDialog
|
from aqt.exporting import ExportDialog as LegacyExportDialog
|
||||||
from aqt.import_export.exporting import ExportDialog
|
from aqt.import_export.exporting import ExportDialog
|
||||||
|
@ -77,7 +76,7 @@ from aqt.utils import (
|
||||||
tr,
|
tr,
|
||||||
)
|
)
|
||||||
|
|
||||||
from ..addcards import AddCards
|
from ..addcards import NewAddCards as AddCards
|
||||||
from ..changenotetype import change_notetype_dialog
|
from ..changenotetype import change_notetype_dialog
|
||||||
from .card_info import BrowserCardInfo
|
from .card_info import BrowserCardInfo
|
||||||
from .find_and_replace import FindAndReplaceDialog
|
from .find_and_replace import FindAndReplaceDialog
|
||||||
|
@ -111,7 +110,7 @@ class MockModel:
|
||||||
class Browser(QMainWindow):
|
class Browser(QMainWindow):
|
||||||
mw: AnkiQt
|
mw: AnkiQt
|
||||||
col: Collection
|
col: Collection
|
||||||
editor: Editor | None
|
editor: aqt.editor.NewEditor | None
|
||||||
table: Table
|
table: Table
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -267,7 +266,7 @@ class Browser(QMainWindow):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def add_card(self, deck_id: DeckId):
|
def add_card(self, deck_id: DeckId):
|
||||||
add_cards = cast(AddCards, aqt.dialogs.open("AddCards", self.mw))
|
add_cards = cast(AddCards, aqt.dialogs.open("NewAddCards", self.mw))
|
||||||
add_cards.set_deck(deck_id)
|
add_cards.set_deck(deck_id)
|
||||||
|
|
||||||
if note_type_id := self.get_active_note_type_id():
|
if note_type_id := self.get_active_note_type_id():
|
||||||
|
@ -392,7 +391,7 @@ class Browser(QMainWindow):
|
||||||
add_ellipsis_to_action_label(f.action_forget)
|
add_ellipsis_to_action_label(f.action_forget)
|
||||||
add_ellipsis_to_action_label(f.action_grade_now)
|
add_ellipsis_to_action_label(f.action_grade_now)
|
||||||
|
|
||||||
def _editor_web_view(self) -> EditorWebView:
|
def _editor_web_view(self) -> aqt.editor.NewEditorWebView:
|
||||||
assert self.editor is not None
|
assert self.editor is not None
|
||||||
editor_web_view = self.editor.web
|
editor_web_view = self.editor.web
|
||||||
assert editor_web_view is not None
|
assert editor_web_view is not None
|
||||||
|
@ -592,12 +591,14 @@ class Browser(QMainWindow):
|
||||||
def setupEditor(self) -> None:
|
def setupEditor(self) -> None:
|
||||||
QShortcut(QKeySequence("Ctrl+Shift+P"), self, self.onTogglePreview)
|
QShortcut(QKeySequence("Ctrl+Shift+P"), self, self.onTogglePreview)
|
||||||
|
|
||||||
def add_preview_button(editor: Editor) -> None:
|
def add_preview_button(
|
||||||
|
editor: aqt.editor.Editor | aqt.editor.NewEditor,
|
||||||
|
) -> None:
|
||||||
editor._links["preview"] = lambda _editor: self.onTogglePreview()
|
editor._links["preview"] = lambda _editor: self.onTogglePreview()
|
||||||
gui_hooks.editor_did_init.remove(add_preview_button)
|
gui_hooks.editor_did_init.remove(add_preview_button)
|
||||||
|
|
||||||
gui_hooks.editor_did_init.append(add_preview_button)
|
gui_hooks.editor_did_init.append(add_preview_button)
|
||||||
self.editor = aqt.editor.Editor(
|
self.editor = aqt.editor.NewEditor(
|
||||||
self.mw,
|
self.mw,
|
||||||
self.form.fieldsArea,
|
self.form.fieldsArea,
|
||||||
self,
|
self,
|
||||||
|
@ -806,7 +807,7 @@ class Browser(QMainWindow):
|
||||||
assert current_card is not None
|
assert current_card is not None
|
||||||
|
|
||||||
deck_id = current_card.current_deck_id()
|
deck_id = current_card.current_deck_id()
|
||||||
aqt.dialogs.open("AddCards", self.mw).set_note(note, deck_id)
|
aqt.dialogs.open("NewAddCards", self.mw).set_note(note, deck_id)
|
||||||
|
|
||||||
@no_arg_trigger
|
@no_arg_trigger
|
||||||
@skip_if_selection_is_empty
|
@skip_if_selection_is_empty
|
||||||
|
@ -1264,3 +1265,4 @@ class Browser(QMainWindow):
|
||||||
line_edit = self.form.searchEdit.lineEdit()
|
line_edit = self.form.searchEdit.lineEdit()
|
||||||
assert line_edit is not None
|
assert line_edit is not None
|
||||||
return line_edit
|
return line_edit
|
||||||
|
return line_edit
|
||||||
|
|
|
@ -7,11 +7,12 @@ from collections.abc import Callable
|
||||||
import aqt.editor
|
import aqt.editor
|
||||||
from anki.collection import OpChanges
|
from anki.collection import OpChanges
|
||||||
from aqt import gui_hooks
|
from aqt import gui_hooks
|
||||||
|
from aqt.editcurrent_legacy import *
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.utils import add_close_shortcut, restoreGeom, saveGeom, tr
|
from aqt.utils import add_close_shortcut, restoreGeom, saveGeom, tr
|
||||||
|
|
||||||
|
|
||||||
class EditCurrent(QMainWindow):
|
class NewEditCurrent(QMainWindow):
|
||||||
def __init__(self, mw: aqt.AnkiQt) -> None:
|
def __init__(self, mw: aqt.AnkiQt) -> None:
|
||||||
super().__init__(None, Qt.WindowType.Window)
|
super().__init__(None, Qt.WindowType.Window)
|
||||||
self.mw = mw
|
self.mw = mw
|
||||||
|
@ -22,7 +23,7 @@ class EditCurrent(QMainWindow):
|
||||||
self.setMinimumWidth(250)
|
self.setMinimumWidth(250)
|
||||||
if not is_mac:
|
if not is_mac:
|
||||||
self.setMenuBar(None)
|
self.setMenuBar(None)
|
||||||
self.editor = aqt.editor.Editor(
|
self.editor = aqt.editor.NewEditor(
|
||||||
self.mw,
|
self.mw,
|
||||||
self.form.fieldsArea,
|
self.form.fieldsArea,
|
||||||
self,
|
self,
|
||||||
|
@ -46,7 +47,7 @@ class EditCurrent(QMainWindow):
|
||||||
gui_hooks.operation_did_execute.remove(self.on_operation_did_execute)
|
gui_hooks.operation_did_execute.remove(self.on_operation_did_execute)
|
||||||
self.editor.cleanup()
|
self.editor.cleanup()
|
||||||
saveGeom(self, "editcurrent")
|
saveGeom(self, "editcurrent")
|
||||||
aqt.dialogs.markClosed("EditCurrent")
|
aqt.dialogs.markClosed("NewEditCurrent")
|
||||||
|
|
||||||
def reopen(self, mw: aqt.AnkiQt) -> None:
|
def reopen(self, mw: aqt.AnkiQt) -> None:
|
||||||
if card := self.mw.reviewer.card:
|
if card := self.mw.reviewer.card:
|
||||||
|
|
94
qt/aqt/editcurrent_legacy.py
Normal file
94
qt/aqt/editcurrent_legacy.py
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
|
||||||
|
import aqt.editor
|
||||||
|
from anki.collection import OpChanges
|
||||||
|
from anki.errors import NotFoundError
|
||||||
|
from aqt import gui_hooks
|
||||||
|
from aqt.qt import *
|
||||||
|
from aqt.utils import add_close_shortcut, restoreGeom, saveGeom, tr
|
||||||
|
|
||||||
|
|
||||||
|
class EditCurrent(QMainWindow):
|
||||||
|
def __init__(self, mw: aqt.AnkiQt) -> None:
|
||||||
|
super().__init__(None, Qt.WindowType.Window)
|
||||||
|
self.mw = mw
|
||||||
|
self.form = aqt.forms.editcurrent.Ui_Dialog()
|
||||||
|
self.form.setupUi(self)
|
||||||
|
self.setWindowTitle(tr.editing_edit_current())
|
||||||
|
self.setMinimumHeight(400)
|
||||||
|
self.setMinimumWidth(250)
|
||||||
|
if not is_mac:
|
||||||
|
self.setMenuBar(None)
|
||||||
|
self.editor = aqt.editor.Editor(
|
||||||
|
self.mw,
|
||||||
|
self.form.fieldsArea,
|
||||||
|
self,
|
||||||
|
editor_mode=aqt.editor.EditorMode.EDIT_CURRENT,
|
||||||
|
)
|
||||||
|
assert self.mw.reviewer.card is not None
|
||||||
|
self.editor.card = self.mw.reviewer.card
|
||||||
|
self.editor.set_note(self.mw.reviewer.card.note(), focusTo=0)
|
||||||
|
restoreGeom(self, "editcurrent")
|
||||||
|
self.buttonbox = QDialogButtonBox(Qt.Orientation.Horizontal)
|
||||||
|
self.form.verticalLayout.insertWidget(1, self.buttonbox)
|
||||||
|
self.buttonbox.addButton(QDialogButtonBox.StandardButton.Close)
|
||||||
|
qconnect(self.buttonbox.rejected, self.close)
|
||||||
|
close_button = self.buttonbox.button(QDialogButtonBox.StandardButton.Close)
|
||||||
|
assert close_button is not None
|
||||||
|
close_button.setShortcut(QKeySequence("Ctrl+Return"))
|
||||||
|
add_close_shortcut(self)
|
||||||
|
# qt5.14+ doesn't handle numpad enter on Windows
|
||||||
|
self.compat_add_shorcut = QShortcut(QKeySequence("Ctrl+Enter"), self)
|
||||||
|
qconnect(self.compat_add_shorcut.activated, close_button.click)
|
||||||
|
gui_hooks.operation_did_execute.append(self.on_operation_did_execute)
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
def on_operation_did_execute(
|
||||||
|
self, changes: OpChanges, handler: object | None
|
||||||
|
) -> None:
|
||||||
|
if changes.note_text and handler is not self.editor:
|
||||||
|
# reload note
|
||||||
|
note = self.editor.note
|
||||||
|
try:
|
||||||
|
assert note is not None
|
||||||
|
note.load()
|
||||||
|
except NotFoundError:
|
||||||
|
# note's been deleted
|
||||||
|
self.cleanup()
|
||||||
|
self.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
self.editor.set_note(note)
|
||||||
|
|
||||||
|
def cleanup(self) -> None:
|
||||||
|
gui_hooks.operation_did_execute.remove(self.on_operation_did_execute)
|
||||||
|
self.editor.cleanup()
|
||||||
|
saveGeom(self, "editcurrent")
|
||||||
|
aqt.dialogs.markClosed("EditCurrent")
|
||||||
|
|
||||||
|
def reopen(self, mw: aqt.AnkiQt) -> None:
|
||||||
|
if card := self.mw.reviewer.card:
|
||||||
|
self.editor.card = card
|
||||||
|
self.editor.set_note(card.note())
|
||||||
|
|
||||||
|
def closeEvent(self, evt: QCloseEvent | None) -> None:
|
||||||
|
self.editor.call_after_note_saved(self.cleanup)
|
||||||
|
|
||||||
|
def _saveAndClose(self) -> None:
|
||||||
|
self.cleanup()
|
||||||
|
self.mw.deferred_delete_and_garbage_collect(self)
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def closeWithCallback(self, onsuccess: Callable[[], None]) -> None:
|
||||||
|
def callback() -> None:
|
||||||
|
self._saveAndClose()
|
||||||
|
onsuccess()
|
||||||
|
|
||||||
|
self.editor.call_after_note_saved(callback)
|
||||||
|
|
||||||
|
onReset = on_operation_did_execute
|
||||||
|
onReset = on_operation_did_execute
|
|
@ -10,7 +10,6 @@ import mimetypes
|
||||||
import os
|
import os
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from enum import Enum
|
|
||||||
from random import randrange
|
from random import randrange
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
@ -21,58 +20,16 @@ from anki.models import NotetypeId
|
||||||
from anki.notes import Note, NoteId
|
from anki.notes import Note, NoteId
|
||||||
from anki.utils import is_win
|
from anki.utils import is_win
|
||||||
from aqt import AnkiQt, gui_hooks
|
from aqt import AnkiQt, gui_hooks
|
||||||
|
from aqt.editor_legacy import *
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.sound import av_player
|
from aqt.sound import av_player
|
||||||
from aqt.utils import shortcut, showWarning
|
from aqt.utils import shortcut, showWarning
|
||||||
from aqt.webview import AnkiWebView, AnkiWebViewKind
|
from aqt.webview import AnkiWebView, AnkiWebViewKind
|
||||||
|
|
||||||
pics = ("jpg", "jpeg", "png", "gif", "svg", "webp", "ico", "avif")
|
|
||||||
audio = (
|
|
||||||
"3gp",
|
|
||||||
"aac",
|
|
||||||
"avi",
|
|
||||||
"flac",
|
|
||||||
"flv",
|
|
||||||
"m4a",
|
|
||||||
"mkv",
|
|
||||||
"mov",
|
|
||||||
"mp3",
|
|
||||||
"mp4",
|
|
||||||
"mpeg",
|
|
||||||
"mpg",
|
|
||||||
"oga",
|
|
||||||
"ogg",
|
|
||||||
"ogv",
|
|
||||||
"ogx",
|
|
||||||
"opus",
|
|
||||||
"spx",
|
|
||||||
"swf",
|
|
||||||
"wav",
|
|
||||||
"webm",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class EditorMode(Enum):
|
|
||||||
ADD_CARDS = 0
|
|
||||||
EDIT_CURRENT = 1
|
|
||||||
BROWSER = 2
|
|
||||||
|
|
||||||
|
|
||||||
class EditorState(Enum):
|
|
||||||
"""
|
|
||||||
Current input state of the editing UI.
|
|
||||||
"""
|
|
||||||
|
|
||||||
INITIAL = -1
|
|
||||||
FIELDS = 0
|
|
||||||
IO_PICKER = 1
|
|
||||||
IO_MASKS = 2
|
|
||||||
IO_FIELDS = 3
|
|
||||||
|
|
||||||
|
|
||||||
def on_editor_ready(func: Callable) -> Callable:
|
def on_editor_ready(func: Callable) -> Callable:
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def decorated(self: Editor, *args: Any, **kwargs: Any) -> None:
|
def decorated(self: NewEditor, *args: Any, **kwargs: Any) -> None:
|
||||||
if self._ready:
|
if self._ready:
|
||||||
func(self, *args, **kwargs)
|
func(self, *args, **kwargs)
|
||||||
else:
|
else:
|
||||||
|
@ -96,7 +53,7 @@ class NoteInfo:
|
||||||
self.mid = NotetypeId(int(self.mid))
|
self.mid = NotetypeId(int(self.mid))
|
||||||
|
|
||||||
|
|
||||||
class Editor:
|
class NewEditor:
|
||||||
"""The screen that embeds an editing widget should listen for changes via
|
"""The screen that embeds an editing widget should listen for changes via
|
||||||
the `operation_did_execute` hook, and call set_note() when the editor needs
|
the `operation_did_execute` hook, and call set_note() when the editor needs
|
||||||
redrawing.
|
redrawing.
|
||||||
|
@ -152,7 +109,7 @@ class Editor:
|
||||||
self.outerLayout = l
|
self.outerLayout = l
|
||||||
|
|
||||||
def add_webview(self) -> None:
|
def add_webview(self) -> None:
|
||||||
self.web = EditorWebView(self.widget, self)
|
self.web = NewEditorWebView(self.widget, self)
|
||||||
self.web.set_bridge_command(self.onBridgeCmd, self)
|
self.web.set_bridge_command(self.onBridgeCmd, self)
|
||||||
self.web.hide_while_preserving_layout()
|
self.web.hide_while_preserving_layout()
|
||||||
self.outerLayout.addWidget(self.web, 1)
|
self.outerLayout.addWidget(self.web, 1)
|
||||||
|
@ -213,7 +170,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
||||||
self,
|
self,
|
||||||
icon: str | None,
|
icon: str | None,
|
||||||
cmd: str,
|
cmd: str,
|
||||||
func: Callable[[Editor], None],
|
func: Callable[[NewEditor], None],
|
||||||
tip: str = "",
|
tip: str = "",
|
||||||
label: str = "",
|
label: str = "",
|
||||||
id: str | None = None,
|
id: str | None = None,
|
||||||
|
@ -224,7 +181,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Assign func to bridge cmd, register shortcut, return button"""
|
"""Assign func to bridge cmd, register shortcut, return button"""
|
||||||
|
|
||||||
def wrapped_func(editor: Editor) -> None:
|
def wrapped_func(editor: NewEditor) -> None:
|
||||||
self.call_after_note_saved(functools.partial(func, editor), keepFocus=True)
|
self.call_after_note_saved(functools.partial(func, editor), keepFocus=True)
|
||||||
|
|
||||||
self._links[cmd] = wrapped_func
|
self._links[cmd] = wrapped_func
|
||||||
|
@ -553,11 +510,11 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
||||||
|
|
||||||
def _init_links(self) -> None:
|
def _init_links(self) -> None:
|
||||||
self._links: dict[str, Callable] = dict(
|
self._links: dict[str, Callable] = dict(
|
||||||
fields=Editor.onFields,
|
fields=NewEditor.onFields,
|
||||||
cards=Editor.onCardLayout,
|
cards=NewEditor.onCardLayout,
|
||||||
paste=Editor.onPaste,
|
paste=NewEditor.onPaste,
|
||||||
cut=Editor.onCut,
|
cut=NewEditor.onCut,
|
||||||
copy=Editor.onCopy,
|
copy=NewEditor.onCopy,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_note_info(self, on_done: Callable[[NoteInfo], None]) -> None:
|
def get_note_info(self, on_done: Callable[[NoteInfo], None]) -> None:
|
||||||
|
@ -571,8 +528,8 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
|
|
||||||
class EditorWebView(AnkiWebView):
|
class NewEditorWebView(AnkiWebView):
|
||||||
def __init__(self, parent: QWidget, editor: Editor) -> None:
|
def __init__(self, parent: QWidget, editor: NewEditor) -> None:
|
||||||
AnkiWebView.__init__(self, kind=AnkiWebViewKind.EDITOR)
|
AnkiWebView.__init__(self, kind=AnkiWebViewKind.EDITOR)
|
||||||
self.editor = editor
|
self.editor = editor
|
||||||
self.setAcceptDrops(True)
|
self.setAcceptDrops(True)
|
||||||
|
@ -592,3 +549,4 @@ class EditorWebView(AnkiWebView):
|
||||||
|
|
||||||
def onPaste(self) -> None:
|
def onPaste(self) -> None:
|
||||||
self.triggerPageAction(QWebEnginePage.WebAction.Paste)
|
self.triggerPageAction(QWebEnginePage.WebAction.Paste)
|
||||||
|
self.triggerPageAction(QWebEnginePage.WebAction.Paste)
|
||||||
|
|
1790
qt/aqt/editor_legacy.py
Normal file
1790
qt/aqt/editor_legacy.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1280,14 +1280,20 @@ title="{}" {}>{}</button>""".format(
|
||||||
# Other menu operations
|
# Other menu operations
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
def _open_new_or_legacy_dialog(self, name: str, *args: Any, **kwargs: Any) -> None:
|
||||||
|
want_old = KeyboardModifiersPressed().shift
|
||||||
|
if not want_old:
|
||||||
|
name = f"New{name}"
|
||||||
|
aqt.dialogs.open(name, self, *args, **kwargs)
|
||||||
|
|
||||||
def onAddCard(self) -> None:
|
def onAddCard(self) -> None:
|
||||||
aqt.dialogs.open("AddCards", self)
|
self._open_new_or_legacy_dialog("AddCards")
|
||||||
|
|
||||||
def onBrowse(self) -> None:
|
def onBrowse(self) -> None:
|
||||||
aqt.dialogs.open("Browser", self, card=self.reviewer.card)
|
aqt.dialogs.open("Browser", self, card=self.reviewer.card)
|
||||||
|
|
||||||
def onEditCurrent(self) -> None:
|
def onEditCurrent(self) -> None:
|
||||||
aqt.dialogs.open("EditCurrent", self)
|
self._open_new_or_legacy_dialog("EditCurrent")
|
||||||
|
|
||||||
def onOverview(self) -> None:
|
def onOverview(self) -> None:
|
||||||
self.moveToState("overview")
|
self.moveToState("overview")
|
||||||
|
@ -1296,11 +1302,7 @@ title="{}" {}>{}</button>""".format(
|
||||||
deck = self._selectedDeck()
|
deck = self._selectedDeck()
|
||||||
if not deck:
|
if not deck:
|
||||||
return
|
return
|
||||||
want_old = KeyboardModifiersPressed().shift
|
self._open_new_or_legacy_dialog("DeckStats", self)
|
||||||
if want_old:
|
|
||||||
aqt.dialogs.open("DeckStats", self)
|
|
||||||
else:
|
|
||||||
aqt.dialogs.open("NewDeckStats", self)
|
|
||||||
|
|
||||||
def onPrefs(self) -> None:
|
def onPrefs(self) -> None:
|
||||||
aqt.dialogs.open("Preferences", self)
|
aqt.dialogs.open("Preferences", self)
|
||||||
|
|
|
@ -608,10 +608,10 @@ def editor_op_changes_request(endpoint: str) -> bytes:
|
||||||
response.ParseFromString(output)
|
response.ParseFromString(output)
|
||||||
|
|
||||||
def handle_on_main() -> None:
|
def handle_on_main() -> None:
|
||||||
from aqt.editor import Editor
|
from aqt.editor import NewEditor
|
||||||
|
|
||||||
handler = aqt.mw.app.activeWindow()
|
handler = aqt.mw.app.activeWindow()
|
||||||
if handler and isinstance(getattr(handler, "editor", None), Editor):
|
if handler and isinstance(getattr(handler, "editor", None), NewEditor):
|
||||||
handler = handler.editor # type: ignore
|
handler = handler.editor # type: ignore
|
||||||
on_op_finished(aqt.mw, response, handler)
|
on_op_finished(aqt.mw, response, handler)
|
||||||
|
|
||||||
|
@ -808,10 +808,10 @@ def close_add_cards() -> bytes:
|
||||||
req.ParseFromString(request.data)
|
req.ParseFromString(request.data)
|
||||||
|
|
||||||
def handle_on_main() -> None:
|
def handle_on_main() -> None:
|
||||||
from aqt.addcards import AddCards
|
from aqt.addcards import NewAddCards
|
||||||
|
|
||||||
window = aqt.mw.app.activeWindow()
|
window = aqt.mw.app.activeWindow()
|
||||||
if isinstance(window, AddCards):
|
if isinstance(window, NewAddCards):
|
||||||
window._close_if_user_wants_to_discard_changes(req.val)
|
window._close_if_user_wants_to_discard_changes(req.val)
|
||||||
|
|
||||||
aqt.mw.taskman.run_on_main(lambda: QTimer.singleShot(0, handle_on_main))
|
aqt.mw.taskman.run_on_main(lambda: QTimer.singleShot(0, handle_on_main))
|
||||||
|
@ -820,10 +820,10 @@ def close_add_cards() -> bytes:
|
||||||
|
|
||||||
def close_edit_current() -> bytes:
|
def close_edit_current() -> bytes:
|
||||||
def handle_on_main() -> None:
|
def handle_on_main() -> None:
|
||||||
from aqt.editcurrent import EditCurrent
|
from aqt.editcurrent import NewEditCurrent
|
||||||
|
|
||||||
window = aqt.mw.app.activeWindow()
|
window = aqt.mw.app.activeWindow()
|
||||||
if isinstance(window, EditCurrent):
|
if isinstance(window, NewEditCurrent):
|
||||||
window.close()
|
window.close()
|
||||||
|
|
||||||
aqt.mw.taskman.run_on_main(lambda: QTimer.singleShot(0, handle_on_main))
|
aqt.mw.taskman.run_on_main(lambda: QTimer.singleShot(0, handle_on_main))
|
||||||
|
@ -1070,3 +1070,5 @@ def _extract_dynamic_get_request(path: str) -> DynamicRequest | None:
|
||||||
return legacy_page_data
|
return legacy_page_data
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
return None
|
||||||
|
return None
|
||||||
|
|
|
@ -1008,12 +1008,15 @@ hooks = [
|
||||||
###################
|
###################
|
||||||
Hook(
|
Hook(
|
||||||
name="add_cards_will_show_history_menu",
|
name="add_cards_will_show_history_menu",
|
||||||
args=["addcards: aqt.addcards.AddCards", "menu: QMenu"],
|
args=[
|
||||||
|
"addcards: aqt.addcards.AddCards | aqt.addcards.NewAddCards",
|
||||||
|
"menu: QMenu",
|
||||||
|
],
|
||||||
legacy_hook="AddCards.onHistory",
|
legacy_hook="AddCards.onHistory",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="add_cards_did_init",
|
name="add_cards_did_init",
|
||||||
args=["addcards: aqt.addcards.AddCards"],
|
args=["addcards: aqt.addcards.AddCards | aqt.addcards.NewAddCards"],
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="add_cards_did_add_note",
|
name="add_cards_did_add_note",
|
||||||
|
@ -1068,7 +1071,7 @@ hooks = [
|
||||||
Hook(
|
Hook(
|
||||||
name="addcards_did_change_note_type",
|
name="addcards_did_change_note_type",
|
||||||
args=[
|
args=[
|
||||||
"addcards: aqt.addcards.AddCards",
|
"addcards: aqt.addcards.AddCards | aqt.addcards.NewAddCards",
|
||||||
"old: anki.models.NoteType",
|
"old: anki.models.NoteType",
|
||||||
"new: anki.models.NoteType",
|
"new: anki.models.NoteType",
|
||||||
],
|
],
|
||||||
|
@ -1087,20 +1090,26 @@ hooks = [
|
||||||
###################
|
###################
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_did_init_left_buttons",
|
name="editor_did_init_left_buttons",
|
||||||
args=["buttons: list[str]", "editor: aqt.editor.Editor"],
|
args=["buttons: list[str]", "editor: aqt.editor.Editor | aqt.editor.NewEditor"],
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_did_init_buttons",
|
name="editor_did_init_buttons",
|
||||||
args=["buttons: list[str]", "editor: aqt.editor.Editor"],
|
args=["buttons: list[str]", "editor: aqt.editor.Editor | aqt.editor.NewEditor"],
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_did_init_shortcuts",
|
name="editor_did_init_shortcuts",
|
||||||
args=["shortcuts: list[tuple]", "editor: aqt.editor.Editor"],
|
args=[
|
||||||
|
"shortcuts: list[tuple]",
|
||||||
|
"editor: aqt.editor.Editor | aqt.editor.NewEditor",
|
||||||
|
],
|
||||||
legacy_hook="setupEditorShortcuts",
|
legacy_hook="setupEditorShortcuts",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_will_show_context_menu",
|
name="editor_will_show_context_menu",
|
||||||
args=["editor_webview: aqt.editor.EditorWebView", "menu: QMenu"],
|
args=[
|
||||||
|
"editor_webview: aqt.editor.EditorWebView | aqt.editor.NewEditorWebView",
|
||||||
|
"menu: QMenu",
|
||||||
|
],
|
||||||
legacy_hook="EditorWebView.contextMenuEvent",
|
legacy_hook="EditorWebView.contextMenuEvent",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
|
@ -1121,7 +1130,7 @@ hooks = [
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_did_load_note",
|
name="editor_did_load_note",
|
||||||
args=["editor: aqt.editor.Editor"],
|
args=["editor: aqt.editor.Editor | aqt.editor.NewEditor"],
|
||||||
legacy_hook="loadNote",
|
legacy_hook="loadNote",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
|
@ -1131,7 +1140,7 @@ hooks = [
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_will_munge_html",
|
name="editor_will_munge_html",
|
||||||
args=["txt: str", "editor: aqt.editor.Editor"],
|
args=["txt: str", "editor: aqt.editor.Editor | aqt.editor.NewEditor"],
|
||||||
return_type="str",
|
return_type="str",
|
||||||
doc="""Allows manipulating the text that will be saved by the editor""",
|
doc="""Allows manipulating the text that will be saved by the editor""",
|
||||||
),
|
),
|
||||||
|
@ -1143,15 +1152,21 @@ hooks = [
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_web_view_did_init",
|
name="editor_web_view_did_init",
|
||||||
args=["editor_web_view: aqt.editor.EditorWebView"],
|
args=[
|
||||||
|
"editor_web_view: aqt.editor.EditorWebView | aqt.editor.NewEditorWebView"
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_did_init",
|
name="editor_did_init",
|
||||||
args=["editor: aqt.editor.Editor"],
|
args=["editor: aqt.editor.Editor | aqt.editor.NewEditor"],
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_will_load_note",
|
name="editor_will_load_note",
|
||||||
args=["js: str", "note: anki.notes.Note", "editor: aqt.editor.Editor"],
|
args=[
|
||||||
|
"js: str",
|
||||||
|
"note: anki.notes.Note",
|
||||||
|
"editor: aqt.editor.Editor | aqt.editor.NewEditor",
|
||||||
|
],
|
||||||
return_type="str",
|
return_type="str",
|
||||||
doc="""Allows changing the javascript commands to load note before
|
doc="""Allows changing the javascript commands to load note before
|
||||||
executing it and do change in the QT editor.""",
|
executing it and do change in the QT editor.""",
|
||||||
|
@ -1159,7 +1174,7 @@ hooks = [
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_did_paste",
|
name="editor_did_paste",
|
||||||
args=[
|
args=[
|
||||||
"editor: aqt.editor.Editor",
|
"editor: aqt.editor.Editor | aqt.editor.NewEditor",
|
||||||
"html: str",
|
"html: str",
|
||||||
"internal: bool",
|
"internal: bool",
|
||||||
"extended: bool",
|
"extended: bool",
|
||||||
|
@ -1170,7 +1185,7 @@ hooks = [
|
||||||
name="editor_will_process_mime",
|
name="editor_will_process_mime",
|
||||||
args=[
|
args=[
|
||||||
"mime: QMimeData",
|
"mime: QMimeData",
|
||||||
"editor_web_view: aqt.editor.EditorWebView",
|
"editor_web_view: aqt.editor.EditorWebView | aqt.editor.NewEditorWebView",
|
||||||
"internal: bool",
|
"internal: bool",
|
||||||
"extended: bool",
|
"extended: bool",
|
||||||
"drop_event: bool",
|
"drop_event: bool",
|
||||||
|
@ -1194,7 +1209,7 @@ hooks = [
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_state_did_change",
|
name="editor_state_did_change",
|
||||||
args=[
|
args=[
|
||||||
"editor: aqt.editor.Editor",
|
"editor: aqt.editor.Editor | aqt.editor.NewEditor",
|
||||||
"new_state: aqt.editor.EditorState",
|
"new_state: aqt.editor.EditorState",
|
||||||
"old_state: aqt.editor.EditorState",
|
"old_state: aqt.editor.EditorState",
|
||||||
],
|
],
|
||||||
|
@ -1203,7 +1218,10 @@ hooks = [
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_mask_editor_did_load_image",
|
name="editor_mask_editor_did_load_image",
|
||||||
args=["editor: aqt.editor.Editor", "path_or_nid: str | anki.notes.NoteId"],
|
args=[
|
||||||
|
"editor: aqt.editor.Editor | aqt.editor.NewEditor",
|
||||||
|
"path_or_nid: str | anki.notes.NoteId",
|
||||||
|
],
|
||||||
doc="""Called when the image occlusion mask editor has completed
|
doc="""Called when the image occlusion mask editor has completed
|
||||||
loading an image.
|
loading an image.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue