Compare commits

...

12 Commits

Author SHA1 Message Date
Tobias Manske 2d45296b14
Merge pull request #23 from gugutu/master
continuous-integration/drone/tag Build is passing Details
2024-03-05 00:56:47 +01:00
gugutu def0045819
Fix the issue of incorrect JS file names introduced under Anki 23.12.1 2024-03-05 03:47:12 +08:00
gugutu 6acf2d5bb5
Fix for Anki version 24.04+ 2024-03-01 16:30:31 +08:00
gugutu d6034c6dcf
Fix for Anki version 24.04+ 2024-03-01 16:19:38 +08:00
gugutu 65cc6c0b12
Modify the implementation method of "avoiding secondary refresh"
The previous implementation may encounter issues in specific scenarios and could potentially become invalid after Anki updates. Now, the approach has been modified to check whether the note content has been modified, which is a simpler and more understandable method.
2024-02-25 05:11:17 +08:00
gugutu 8487bb86d0
Increase the setSizes parameter
If the parameter given to setSizes is very small and smaller than QSplitter, the sub windows within QSplitter will be stretched. It is advisable to set a larger parameter for setSizes as much as possible.
2024-02-02 09:12:49 +08:00
gugutu 74d12576cd
Fix memory leakage caused by hook not releasing
Due to Anki not providing a hook when closing the editor, refactoring to use set filter to check which editors are not active and avoid creating a large number of hooks. By traversing the set, it is determined whether the current editor needs to be refreshed.
2024-02-02 08:50:17 +08:00
gugutu deca35908a
Improve compatibility with other plugins
Wrap a widget on the outer layer of the webview so that other plugins can continue to modify the layout.
2024-02-02 07:28:16 +08:00
gugutu 2023cea60c
Fix second refresh after loading note 2024-02-02 07:10:47 +08:00
Tobias Manske cefa65eadf
Merge pull request #20 from spacelord47/fix/use_qt6_enums_properly
continuous-integration/drone/tag Build is passing Details
Fixes: #19 
Fixes: #18
2023-11-05 16:02:06 +01:00
spacelord47 766d246f46
fix: use Qt6 enums properly
New Anki version(23.10) dropped compatibility for Qt5: https://forums.ankiweb.net/t/porting-tips-for-anki-23-10/35916#enumerations-6
2023-11-05 13:53:17 +00:00
Tobias Manske 23f9c0cb68
Patch version check for new versioning scheme
I haven't taken a look at anything in the new version yet.
But that closes #16.
2023-09-25 11:50:44 +02:00
2 changed files with 49 additions and 20 deletions

1
.gitignore vendored
View File

@ -117,6 +117,7 @@ venv/
ENV/
env.bak/
venv.bak/
.idea
# Spyder project settings
.spyderproject

View File

@ -1,4 +1,5 @@
import json
from typing import Set
from anki import hooks, buildinfo
from aqt import editor, gui_hooks, mw
@ -10,6 +11,7 @@ config = mw.addonManager.getConfig(__name__)
class EditorPreview(object):
editors: Set[editor.Editor] = set()
js = [
"js/mathjax.js",
"js/vendor/mathjax/tex-chtml.js",
@ -19,7 +21,18 @@ class EditorPreview(object):
def __init__(self):
gui_hooks.editor_did_init.append(self.editor_init_hook)
gui_hooks.editor_did_init_buttons.append(self.editor_init_button_hook)
if int(buildinfo.version.split(".")[2]) < 45: # < 2.1.45
gui_hooks.editor_did_load_note.append(self.editor_note_hook)
gui_hooks.editor_did_fire_typing_timer.append(self.onedit_hook)
buildversion = buildinfo.version.split(".")
# Anki changed their versioning scheme in 2023 to year.month(.patch), causing things to explode here.
if int(buildversion[0]) >= 24 or (int(buildversion[0]) == 23 and int(buildversion[1]) == 12 and 2 < len(buildversion) and int(buildversion[2])) >= 1: # >= 23.12.1
self.js = [
"js/mathjax.js",
"js/vendor/mathjax/tex-chtml-full.js",
"js/reviewer.js",
]
elif int(buildversion[0]) < 23 and int(buildversion[2]) < 45: # < 2.1.45
self.js = [
"js/vendor/jquery.min.js",
"js/vendor/css_browser_selector.min.js",
@ -42,34 +55,29 @@ class EditorPreview(object):
ed.editor_preview.hide()
self._inject_splitter(ed)
gui_hooks.editor_did_fire_typing_timer.append(lambda o: self.onedit_hook(ed, o))
gui_hooks.editor_did_load_note.append(
lambda o: None if o != ed else self.editor_note_hook(o)
)
def _get_splitter(self, editor):
layout = editor.outerLayout
mainR, editorR = [int(r) for r in config["splitRatio"].split(":")]
mainR, editorR = [int(r) * 10000 for r in config["splitRatio"].split(":")]
location = config["location"]
split = QSplitter()
if location == "above":
split.setOrientation(Qt.Vertical)
split.setOrientation(Qt.Orientation.Vertical)
split.addWidget(editor.editor_preview)
split.addWidget(editor.web)
split.addWidget(editor.wrapped_web)
sizes = [editorR, mainR]
elif location == "below":
split.setOrientation(Qt.Vertical)
split.addWidget(editor.web)
split.setOrientation(Qt.Orientation.Vertical)
split.addWidget(editor.wrapped_web)
split.addWidget(editor.editor_preview)
sizes = [mainR, editorR]
elif location == "left":
split.setOrientation(Qt.Horizontal)
split.setOrientation(Qt.Orientation.Horizontal)
split.addWidget(editor.editor_preview)
split.addWidget(editor.web)
split.addWidget(editor.wrapped_web)
sizes = [editorR, mainR]
elif location == "right":
split.setOrientation(Qt.Horizontal)
split.addWidget(editor.web)
split.setOrientation(Qt.Orientation.Horizontal)
split.addWidget(editor.wrapped_web)
split.addWidget(editor.editor_preview)
sizes = [mainR, editorR]
else:
@ -79,15 +87,31 @@ class EditorPreview(object):
return split
def _inject_splitter(self, editor: editor.Editor):
layout = editor.outerLayout
layout = editor.web.parentWidget().layout()
if layout is None:
layout = QVBoxLayout()
editor.web.parentWidget().setLayout(layout)
web_index = layout.indexOf(editor.web)
layout.removeWidget(editor.web)
# Wrap a widget on the outer layer of the webview
# So that other plugins can continue to modify the layout
editor.wrapped_web = QWidget()
wrapLayout = QHBoxLayout()
editor.wrapped_web.setLayout(wrapLayout)
wrapLayout.addWidget(editor.web)
split = self._get_splitter(editor)
layout.insertWidget(web_index, split)
def editor_note_hook(self, editor):
self.onedit_hook(editor, editor.note)
self.editors = set(filter(lambda it: it.note is not None, self.editors))
self.editors.add(editor)
# The initial loading of notes will also trigger an editing event
# which will cause a second refresh
# Caching the content of notes here will be used to determine if the content has changed
editor.cached_fields = list(editor.note.fields)
self.refresh(editor)
def editor_init_button_hook(self, buttons, editor):
addon_path = os.path.dirname(__file__)
@ -116,9 +140,13 @@ class EditorPreview(object):
return f"_showAnswer({json.dumps(a)},'{bodyclass}');"
def onedit_hook(self, editor, origin):
if editor.note == origin:
editor.editor_preview.eval(self._obtainCardText(editor.note))
def onedit_hook(self, note):
for editor in self.editors:
if editor.note == note and editor.cached_fields != note.fields:
editor.cached_fields = list(note.fields)
self.refresh(editor)
def refresh(self, editor):
editor.editor_preview.eval(self._obtainCardText(editor.note))
eprev = EditorPreview()