Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to show image from editor in folder #3412

Merged
merged 3 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ftl/core/editing.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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-show-in-folder = Show in folder
editing-ordered-list = Ordered list
editing-outdent = Decrease indent
editing-paste = Paste
Expand Down
41 changes: 24 additions & 17 deletions qt/aqt/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
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_win, namedtmp
from aqt import AnkiQt, colors, gui_hooks
from anki.utils import checksum, is_lin, is_mac, is_win, namedtmp
from aqt import AnkiQt, colors, gui_hooks, mw
from aqt.operations import QueryOp
from aqt.operations.note import update_note
from aqt.operations.notetype import update_notetype_legacy
Expand All @@ -55,6 +55,7 @@
saveGeom,
shortcut,
showInfo,
showinFolder,
showWarning,
tooltip,
tr,
Expand Down Expand Up @@ -1585,28 +1586,34 @@ def _processImage(self, mime: QMimeData, extended: bool = False) -> str | None:

def contextMenuEvent(self, evt: QContextMenuEvent) -> None:
m = QMenu(self)
self._maybe_add_cut_action(m)
self._maybe_add_copy_action(m)
if self.hasSelection():
self._add_cut_action(m)
self._add_copy_action(m)
a = m.addAction(tr.editing_paste())
qconnect(a.triggered, self.onPaste)
self._maybe_add_copy_image_action(m)
if self._opened_context_menu_on_image():
self._add_image_menu(AnkiWebView(self), m)
gui_hooks.editor_will_show_context_menu(self, m)
m.popup(QCursor.pos())

def _maybe_add_cut_action(self, menu: QMenu) -> None:
if self.hasSelection():
a = menu.addAction(tr.editing_cut())
qconnect(a.triggered, self.onCut)
def _add_cut_action(self, menu: QMenu) -> None:
a = menu.addAction(tr.editing_cut())
qconnect(a.triggered, self.onCut)

def _maybe_add_copy_action(self, menu: QMenu) -> None:
if self.hasSelection():
a = menu.addAction(tr.actions_copy())
qconnect(a.triggered, self.onCopy)
def _add_copy_action(self, menu: QMenu) -> None:
a = menu.addAction(tr.actions_copy())
qconnect(a.triggered, self.onCopy)

def _maybe_add_copy_image_action(self, menu: QMenu) -> None:
if self._opened_context_menu_on_image():
a = menu.addAction(tr.editing_copy_image())
qconnect(a.triggered, self.on_copy_image)
def _add_image_menu(self, webview: AnkiWebView, menu: QMenu) -> None:
a = menu.addAction(tr.editing_copy_image())
qconnect(a.triggered, self.on_copy_image)

if is_win or is_mac:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any feature we add should work across all OSes - is there a reason why non-Mac/Windows has been excluded here?

Copy link
Contributor Author

@user1823 user1823 Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would definitely be better to make a feature work on all platforms. But, I have no idea how to make it work with all the different file managers in Linux. Even if this doesn't work on Linux, it is still an improvement over what we currently have, especially when you consider that Windows + Mac users comprise most of the Anki's userbase.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"We can't do it on Linux easily" is a reasonable answer for now :-) Thanks for clarifying.

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))


# QFont returns "Kozuka Gothic Pro L" but WebEngine expects "Kozuka Gothic Pro Light"
Expand Down
28 changes: 28 additions & 0 deletions qt/aqt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from anki.collection import Collection, HelpPage
from anki.lang import TR, tr_legacyglobal # pylint: disable=unused-import
from anki.utils import (
call,
invalid_filename,
is_mac,
is_win,
Expand Down Expand Up @@ -885,6 +886,33 @@ def openFolder(path: str) -> None:
QDesktopServices.openUrl(QUrl(f"file://{path}"))


def showinFolder(path: str) -> None:
if is_win:
call(["explorer", "/select,", f"file://{path}"])
elif is_mac:
script = f"""
tell application "Finder"
activate
select POSIX file '{path}'
end tell
"""
call(osascript_to_args(script))
else:
# Just open the file in any other platform
with no_bundled_libs():
QDesktopServices.openUrl(QUrl(f"file://{path}"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you copied+pasted this code from somewhere? From a quick read of the Qt docs, it looks like openUrl() should do what we want on all platforms?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For local files, openUrl() opens the file in the default viewer if it can. But, we want it to highlight the file even when there is a viewer available.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I was under the mistaken impression that it would select the file, not open it directly.



def osascript_to_args(script: str):
args = [
item
for line in script.splitlines()
for item in ("-e", line.strip())
if line.strip()
]
return ["osascript"] + args


def shortcut(key: str) -> str:
if is_mac:
return re.sub("(?i)ctrl", "Command", key)
Expand Down