Add a hook for modifiying pasted MIME data

This commit is contained in:
Ren Tatsumoto 2021-09-05 13:20:27 +03:00
parent e5409a25b5
commit 9ff37d9baa
2 changed files with 37 additions and 20 deletions

View file

@ -863,13 +863,12 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
self.web.eval(f"pasteHTML({json.dumps(html)}, {json.dumps(internal)}, {ext});")
gui_hooks.editor_did_paste(self, html, internal, extended)
def doDrop(self, html: str, internal: bool, extended: bool = False) -> None:
def doDrop(self, html: str, internal: bool, extended: bool, cursor_pos: QPoint) -> None:
def pasteIfField(ret: bool) -> None:
if ret:
self.doPaste(html, internal, extended)
p = self.web.mapFromGlobal(QCursor.pos())
self.web.evalWithCallback(f"focusIfField({p.x()}, {p.y()});", pasteIfField)
self.web.evalWithCallback(f"focusIfField({cursor_pos.x()}, {cursor_pos.y()});", pasteIfField)
def onPaste(self) -> None:
self.web.onPaste()
@ -1138,30 +1137,34 @@ class EditorWebView(AnkiWebView):
def dropEvent(self, evt: QDropEvent) -> None:
extended = self._wantsExtendedPaste()
mime = evt.mimeData()
cursor_pos = self.mapFromGlobal(QCursor.pos())
if evt.source() and mime.hasHtml():
# don't filter html from other fields
html, internal = mime.html(), True
else:
html, internal = self._processMime(mime, extended)
html, internal = self._processMime(mime, extended, drop_event=True)
if not html:
return
self.editor.doDrop(html, internal, extended)
self.editor.doDrop(html, internal, extended, cursor_pos)
# returns (html, isInternal)
def _processMime(self, mime: QMimeData, extended: bool = False) -> Tuple[str, bool]:
def _processMime(self, mime: QMimeData, extended: bool = False, drop_event: bool = False) -> Tuple[str, bool]:
# print("html=%s image=%s urls=%s txt=%s" % (
# mime.hasHtml(), mime.hasImage(), mime.hasUrls(), mime.hasText()))
# print("html", mime.html())
# print("urls", mime.urls())
# print("text", mime.text())
internal = mime.html().startswith("<!--anki-->")
mime = gui_hooks.editor_will_process_mime(self, mime, internal, extended, drop_event)
# try various content types in turn
html, internal = self._processHtml(mime)
if html:
return html, internal
if mime.hasHtml():
return mime.html().replace("<!--anki-->", ''), internal
# favour url if it's a local link
if mime.hasUrls() and mime.urls()[0].toString().startswith("file://"):
@ -1227,17 +1230,6 @@ class EditorWebView(AnkiWebView):
processed.pop()
return "".join(processed)
def _processHtml(self, mime: QMimeData) -> Tuple[Optional[str], bool]:
if not mime.hasHtml():
return None, False
html = mime.html()
# no filtering required for internal pastes
if html.startswith("<!--anki-->"):
return html[11:], True
return html, False
def _processImage(self, mime: QMimeData, extended: bool = False) -> Optional[str]:
if not mime.hasImage():
return None

View file

@ -864,6 +864,31 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
],
doc="""Called after some data is pasted by python into an editor field.""",
),
Hook(
name="editor_will_process_mime",
args=[
"editor_web_view: aqt.editor.EditorWebView",
"mime: QMimeData",
"internal: bool",
"extended: bool",
"drop_event: bool",
],
return_type="QMimeData",
doc="""
Used to modify MIME data stored in the clipboard after a drop or a paste.
Called after the user pastes or drag-and-drops something to Anki
before Anki processes the data.
The function should return a new or existing QMimeData object.
"mime" contains the corresponding QMimeData object.
"internal" indicates whether the drop or paste is performed between Anki fields.
Most likely you want to skip processing if "internal" was set to True.
"extended" indicates whether the user requested an extended paste.
"drop_event" indicates whether the event was triggered by a drag-and-drop
or by a right-click paste.
""",
),
# Tag
###################
Hook(name="tag_editor_did_process_key", args=["tag_edit: TagEdit", "evt: QEvent"]),