Add "open image" option to editor (#3431)

* Add "open image" option to editor

* Update qt/aqt/editor.py

Co-authored-by: Ben Nguyen <105088397+bpnguyen107@users.noreply.github.com>

* Update editor.py

* Remove unused import

* Fix "show in folder"

* Fix 'show in folder' on macOS

* Revert "Fix "show in folder""

This reverts commit cf2b33ee9422bcaf8d9e20bd4cce74e5061c13cf.

* Reimplement show_in_folder for Windows (dae)

- Avoid reusing call(), as the startupinfo we were passing in was
breaking the explorer invocation
- Attempt to bring explorer to the front after the window has been show,
as it otherwise appears under Anki (at least when running from source)

---------

Co-authored-by: Ben Nguyen <105088397+bpnguyen107@users.noreply.github.com>
Co-authored-by: Damien Elmes <gpg@ankiweb.net>
This commit is contained in:
user1823 2024-10-04 16:21:55 +05:30 committed by GitHub
parent 85f034b144
commit de3b1754fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 36 additions and 11 deletions

View file

@ -36,6 +36,7 @@ editing-mathjax-chemistry = MathJax chemistry
editing-mathjax-inline = MathJax inline
editing-mathjax-placeholder = Press { $accept } to accept, { $newline } for new line.
editing-media = Media
editing-open-image = Open image
editing-show-in-folder = Show in folder
editing-ordered-list = Ordered list
editing-outdent = Decrease indent

View file

@ -577,6 +577,10 @@ types-protobuf==5.27.0.20240626 \
# via
# -r requirements.dev.in
# mypy-protobuf
types-pywin32==306.0.0.20240822 \
--hash=sha256:31a16f7eaf711166e8aec50ee1ddf0f16b4512e19ecc92a019ae7a0860b64bad \
--hash=sha256:34d22b58aaa2cc86fe585b6e2e1eda88a60b010badea0e0e4a410ebe28744645
# via -r requirements.dev.in
types-requests==2.32.0.20240712 \
--hash=sha256:90c079ff05e549f6bf50e02e910210b98b8ff1ebdd18e19c873cd237737c1358 \
--hash=sha256:f754283e152c752e46e70942fa2a146b5bc70393522257bb85bd1ef7e019dcc3

View file

@ -37,7 +37,7 @@ from anki.httpclient import HttpClient
from anki.models import NotetypeId, StockNotetype
from anki.notes import Note, NoteFieldsCheckResult, NoteId
from anki.utils import checksum, is_lin, is_mac, is_win, namedtmp
from aqt import AnkiQt, colors, gui_hooks, mw
from aqt import AnkiQt, colors, gui_hooks
from aqt.operations import QueryOp
from aqt.operations.note import update_note
from aqt.operations.notetype import update_notetype_legacy
@ -49,13 +49,14 @@ from aqt.utils import (
KeyboardModifiersPressed,
disable_help_button,
getFile,
openFolder,
openHelp,
qtMenuShortcutWorkaround,
restoreGeom,
saveGeom,
shortcut,
show_in_folder,
showInfo,
showinFolder,
showWarning,
tooltip,
tr,
@ -1592,7 +1593,7 @@ class EditorWebView(AnkiWebView):
a = m.addAction(tr.editing_paste())
qconnect(a.triggered, self.onPaste)
if self._opened_context_menu_on_image():
self._add_image_menu(AnkiWebView(self), m)
self._add_image_menu(m)
gui_hooks.editor_will_show_context_menu(self, m)
m.popup(QCursor.pos())
@ -1604,16 +1605,19 @@ class EditorWebView(AnkiWebView):
a = menu.addAction(tr.actions_copy())
qconnect(a.triggered, self.onCopy)
def _add_image_menu(self, webview: AnkiWebView, menu: QMenu) -> None:
def _add_image_menu(self, menu: QMenu) -> None:
a = menu.addAction(tr.editing_copy_image())
qconnect(a.triggered, self.on_copy_image)
url = self.lastContextMenuRequest().mediaUrl()
file_name = url.fileName()
path = os.path.join(self.editor.mw.col.media.dir(), file_name)
a = menu.addAction(tr.editing_open_image())
qconnect(a.triggered, lambda: openFolder(path))
if is_win or is_mac:
url = webview.lastContextMenuRequest().mediaUrl()
file_name = url.fileName()
path = os.path.join(mw.col.media.dir(), file_name)
a = menu.addAction(tr.editing_show_in_folder())
qconnect(a.triggered, lambda: showinFolder(path))
qconnect(a.triggered, lambda: show_in_folder(path))
# QFont returns "Kozuka Gothic Pro L" but WebEngine expects "Kozuka Gothic Pro Light"

View file

@ -886,14 +886,14 @@ def openFolder(path: str) -> None:
QDesktopServices.openUrl(QUrl(f"file://{path}"))
def showinFolder(path: str) -> None:
def show_in_folder(path: str) -> None:
if is_win:
call(["explorer", "/select,", f"file://{path}"])
_show_in_folder_win32(path)
elif is_mac:
script = f"""
tell application "Finder"
activate
select POSIX file '{path}'
select POSIX file "{path}"
end tell
"""
call(osascript_to_args(script))
@ -903,6 +903,22 @@ def showinFolder(path: str) -> None:
QDesktopServices.openUrl(QUrl(f"file://{path}"))
def _show_in_folder_win32(path: str) -> None:
import win32con # pylint: disable=import-error
import win32gui # pylint: disable=import-error
from aqt import mw
def focus_explorer():
hwnd = win32gui.FindWindow("CabinetWClass", None)
if hwnd:
win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
win32gui.SetForegroundWindow(hwnd)
subprocess.run(["explorer", f"/select,{path}"], check=False)
mw.progress.single_shot(500, focus_explorer)
def osascript_to_args(script: str):
args = [
item