diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index 6f182d890..8ff59aaa8 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -22,6 +22,7 @@ from bs4 import BeautifulSoup import aqt import aqt.sound +from anki._legacy import deprecated from anki.cards import Card from anki.collection import Config, SearchNode from anki.consts import MODEL_CLOZE @@ -588,46 +589,6 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{ setNote = set_note - # HTML editing - ###################################################################### - - def onHtmlEdit(self) -> None: - field = self.currentField - self.call_after_note_saved(lambda: self._onHtmlEdit(field)) - - def _onHtmlEdit(self, field: int) -> None: - d = QDialog(self.widget, Qt.Window) - form = aqt.forms.edithtml.Ui_Dialog() - form.setupUi(d) - restoreGeom(d, "htmlEditor") - disable_help_button(d) - qconnect( - form.buttonBox.helpRequested, lambda: openHelp(HelpPage.EDITING_FEATURES) - ) - font = QFont("Courier") - font.setStyleHint(QFont.TypeWriter) - form.textEdit.setFont(font) - form.textEdit.setPlainText(self.note.fields[field]) - d.show() - form.textEdit.moveCursor(QTextCursor.End) - d.exec_() - html = form.textEdit.toPlainText() - if html.find(">") > -1: - # filter html through beautifulsoup so we can strip out things like a - # leading - html_escaped = self.mw.col.media.escape_media_filenames(html) - with warnings.catch_warnings(): - warnings.simplefilter("ignore", UserWarning) - html_escaped = str(BeautifulSoup(html_escaped, "html.parser")) - html = self.mw.col.media.escape_media_filenames( - html_escaped, unescape=True - ) - self.note.fields[field] = html - if not self.addMode: - self._save_current_note() - self.loadNote(focusTo=field) - saveGeom(d, "htmlEditor") - # Tag handling ###################################################################### @@ -682,88 +643,6 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{ saveTags = blur_tags_if_focused - # Format buttons - ###################################################################### - - def toggleBold(self) -> None: - self.web.eval("setFormat('bold');") - - def toggleItalic(self) -> None: - self.web.eval("setFormat('italic');") - - def toggleUnderline(self) -> None: - self.web.eval("setFormat('underline');") - - def toggleSuper(self) -> None: - self.web.eval("setFormat('superscript');") - - def toggleSub(self) -> None: - self.web.eval("setFormat('subscript');") - - def removeFormat(self) -> None: - self.web.eval("setFormat('removeFormat');") - - def onCloze(self) -> None: - self.call_after_note_saved(self._onCloze, keepFocus=True) - - def _onCloze(self) -> None: - # check that the model is set up for cloze deletion - if self.note.note_type()["type"] != MODEL_CLOZE: - if self.addMode: - tooltip(tr.editing_warning_cloze_deletions_will_not_work()) - else: - showInfo(tr.editing_to_make_a_cloze_deletion_on()) - return - # find the highest existing cloze - highest = 0 - for name, val in list(self.note.items()): - m = re.findall(r"\{\{c(\d+)::", val) - if m: - highest = max(highest, sorted([int(x) for x in m])[-1]) - # reuse last? - if not KeyboardModifiersPressed().alt: - highest += 1 - # must start at 1 - highest = max(1, highest) - self.web.eval("wrap('{{c%d::', '}}');" % highest) - - # Foreground colour - ###################################################################### - - def setupForegroundButton(self) -> None: - self.fcolour = self.mw.pm.profile.get("lastColour", "#00f") - self.onColourChanged() - - # use last colour - def onForeground(self) -> None: - self._wrapWithColour(self.fcolour) - - # choose new colour - def onChangeCol(self) -> None: - if isLin: - new = QColorDialog.getColor( - QColor(self.fcolour), None, None, QColorDialog.DontUseNativeDialog - ) - else: - new = QColorDialog.getColor(QColor(self.fcolour), None) - # native dialog doesn't refocus us for some reason - self.parentWindow.activateWindow() - if new.isValid(): - self.fcolour = new.name() - self.onColourChanged() - self._wrapWithColour(self.fcolour) - - def _updateForegroundButton(self) -> None: - # self.web.eval(f"setFGButton('{self.fcolour}')") - pass - - def onColourChanged(self) -> None: - self._updateForegroundButton() - self.mw.pm.profile["lastColour"] = self.fcolour - - def _wrapWithColour(self, colour: str) -> None: - self.web.eval(f"setFormat('forecolor', '{colour}')") - # Audio/video/images ###################################################################### @@ -998,9 +877,138 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{ def onCutOrCopy(self) -> None: self.web.flagAnkiText() - # Advanced menu + # Legacy editing routines ###################################################################### + _js_legacy = "this routine has been moved into JS, and will be removed soon" + + @deprecated(info=_js_legacy) + def onHtmlEdit(self) -> None: + field = self.currentField + self.call_after_note_saved(lambda: self._onHtmlEdit(field)) + + @deprecated(info=_js_legacy) + def _onHtmlEdit(self, field: int) -> None: + d = QDialog(self.widget, Qt.Window) + form = aqt.forms.edithtml.Ui_Dialog() + form.setupUi(d) + restoreGeom(d, "htmlEditor") + disable_help_button(d) + qconnect( + form.buttonBox.helpRequested, lambda: openHelp(HelpPage.EDITING_FEATURES) + ) + font = QFont("Courier") + font.setStyleHint(QFont.TypeWriter) + form.textEdit.setFont(font) + form.textEdit.setPlainText(self.note.fields[field]) + d.show() + form.textEdit.moveCursor(QTextCursor.End) + d.exec_() + html = form.textEdit.toPlainText() + if html.find(">") > -1: + # filter html through beautifulsoup so we can strip out things like a + # leading + html_escaped = self.mw.col.media.escape_media_filenames(html) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", UserWarning) + html_escaped = str(BeautifulSoup(html_escaped, "html.parser")) + html = self.mw.col.media.escape_media_filenames( + html_escaped, unescape=True + ) + self.note.fields[field] = html + if not self.addMode: + self._save_current_note() + self.loadNote(focusTo=field) + saveGeom(d, "htmlEditor") + + @deprecated(info=_js_legacy) + def toggleBold(self) -> None: + self.web.eval("setFormat('bold');") + + @deprecated(info=_js_legacy) + def toggleItalic(self) -> None: + self.web.eval("setFormat('italic');") + + @deprecated(info=_js_legacy) + def toggleUnderline(self) -> None: + self.web.eval("setFormat('underline');") + + @deprecated(info=_js_legacy) + def toggleSuper(self) -> None: + self.web.eval("setFormat('superscript');") + + @deprecated(info=_js_legacy) + def toggleSub(self) -> None: + self.web.eval("setFormat('subscript');") + + @deprecated(info=_js_legacy) + def removeFormat(self) -> None: + self.web.eval("setFormat('removeFormat');") + + @deprecated(info=_js_legacy) + def onCloze(self) -> None: + self.call_after_note_saved(self._onCloze, keepFocus=True) + + @deprecated(info=_js_legacy) + def _onCloze(self) -> None: + # check that the model is set up for cloze deletion + if self.note.note_type()["type"] != MODEL_CLOZE: + if self.addMode: + tooltip(tr.editing_warning_cloze_deletions_will_not_work()) + else: + showInfo(tr.editing_to_make_a_cloze_deletion_on()) + return + # find the highest existing cloze + highest = 0 + for name, val in list(self.note.items()): + m = re.findall(r"\{\{c(\d+)::", val) + if m: + highest = max(highest, sorted([int(x) for x in m])[-1]) + # reuse last? + if not KeyboardModifiersPressed().alt: + highest += 1 + # must start at 1 + highest = max(1, highest) + self.web.eval("wrap('{{c%d::', '}}');" % highest) + + def setupForegroundButton(self) -> None: + self.fcolour = self.mw.pm.profile.get("lastColour", "#00f") + + # use last colour + @deprecated(info=_js_legacy) + def onForeground(self) -> None: + self._wrapWithColour(self.fcolour) + + # choose new colour + @deprecated(info=_js_legacy) + def onChangeCol(self) -> None: + if isLin: + new = QColorDialog.getColor( + QColor(self.fcolour), None, None, QColorDialog.DontUseNativeDialog + ) + else: + new = QColorDialog.getColor(QColor(self.fcolour), None) + # native dialog doesn't refocus us for some reason + self.parentWindow.activateWindow() + if new.isValid(): + self.fcolour = new.name() + self.onColourChanged() + self._wrapWithColour(self.fcolour) + + @deprecated(info=_js_legacy) + def _updateForegroundButton(self) -> None: + pass + + @deprecated(info=_js_legacy) + def onColourChanged(self) -> None: + self._updateForegroundButton() + self.mw.pm.profile["lastColour"] = self.fcolour + + @deprecated(info=_js_legacy) + def _wrapWithColour(self, colour: str) -> None: + self.web.eval(f"setFormat('forecolor', '{colour}')") + + @deprecated(info=_js_legacy) def onAdvanced(self) -> None: m = QMenu(self.mw) @@ -1025,24 +1033,27 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{ m.exec_(QCursor.pos()) - # LaTeX - ###################################################################### - + @deprecated(info=_js_legacy) def insertLatex(self) -> None: self.web.eval("wrap('[latex]', '[/latex]');") + @deprecated(info=_js_legacy) def insertLatexEqn(self) -> None: self.web.eval("wrap('[$]', '[/$]');") + @deprecated(info=_js_legacy) def insertLatexMathEnv(self) -> None: self.web.eval("wrap('[$$]', '[/$$]');") + @deprecated(info=_js_legacy) def insertMathjaxInline(self) -> None: self.web.eval("wrap('\\\\(', '\\\\)');") + @deprecated(info=_js_legacy) def insertMathjaxBlock(self) -> None: self.web.eval("wrap('\\\\[', '\\\\]');") + @deprecated(info=_js_legacy) def insertMathjaxChemistry(self) -> None: self.web.eval("wrap('\\\\(\\\\ce{', '}\\\\)');")