diff --git a/picard/ui/infodialog.py b/picard/ui/infodialog.py index a3930b187..e1686175f 100644 --- a/picard/ui/infodialog.py +++ b/picard/ui/infodialog.py @@ -52,6 +52,7 @@ from picard.util import ( bytes2human, encode_filename, format_time, + open_local_path, union_sorted_lists, ) @@ -271,8 +272,7 @@ class InfoDialog(PicardDialog): return filename = data.tempfile_filename if filename: - url = QtCore.QUrl.fromLocalFile(filename) - QtGui.QDesktopServices.openUrl(url) + open_local_path(filename) def format_file_info(file_): diff --git a/picard/ui/mainwindow.py b/picard/ui/mainwindow.py index e939084e5..1d2f300b5 100644 --- a/picard/ui/mainwindow.py +++ b/picard/ui/mainwindow.py @@ -92,6 +92,7 @@ from picard.util import ( icontheme, iter_files_from_objects, iter_unique, + open_local_path, reconnect, restore_method, thread, @@ -1377,12 +1378,9 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry): self.tagger.generate_fingerprints(self.selected_objects) self._ensure_fingerprinting_configured(callback) - def _openUrl(self, url): - return QtCore.QUrl.fromLocalFile(url) - def play_file(self): for file in iter_files_from_objects(self.selected_objects): - QtGui.QDesktopServices.openUrl(self._openUrl(file.filename)) + open_local_path(file.filename) def _on_player_error(self, error, msg): self.set_statusbar_message(msg, echo=log.warning, translate=None) @@ -1392,7 +1390,7 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry): os.path.dirname(f.filename) for f in iter_files_from_objects(self.selected_objects)) for folder in folders: - QtGui.QDesktopServices.openUrl(self._openUrl(folder)) + open_local_path(folder) def _ensure_fingerprinting_configured(self, callback): config = get_config() diff --git a/picard/ui/options/maintenance.py b/picard/ui/options/maintenance.py index dbb548bb5..a64f1d59b 100644 --- a/picard/ui/options/maintenance.py +++ b/picard/ui/options/maintenance.py @@ -37,6 +37,7 @@ from picard.config import ( load_new_config, ) from picard.config_upgrade import upgrade_config +from picard.util import open_local_path from picard.ui.options import ( OptionsPage, @@ -159,7 +160,7 @@ class MaintenanceOptionsPage(OptionsPage): def open_config_dir(self): config = get_config() config_dir = path.split(config.fileName())[0] - QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(config_dir)) + open_local_path(config_dir) def _get_dialog_filetypes(self, _ext='.ini'): return ";;".join(( diff --git a/picard/ui/options/plugins.py b/picard/ui/options/plugins.py index 131666645..086398f41 100644 --- a/picard/ui/options/plugins.py +++ b/picard/ui/options/plugins.py @@ -54,7 +54,10 @@ from picard.const import ( PLUGINS_API, USER_PLUGIN_DIR, ) -from picard.util import reconnect +from picard.util import ( + open_local_path, + reconnect, +) from picard.ui import HashableTreeWidgetItem from picard.ui.options import ( @@ -688,7 +691,7 @@ class PluginsOptionsPage(OptionsPage): @staticmethod def open_plugin_dir(): - QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(USER_PLUGIN_DIR)) + open_local_path(USER_PLUGIN_DIR) def mimeTypes(self): return ["text/uri-list"] diff --git a/picard/util/__init__.py b/picard/util/__init__.py index e982ada34..393b34821 100644 --- a/picard/util/__init__.py +++ b/picard/util/__init__.py @@ -4,7 +4,7 @@ # # Copyright (C) 2004 Robert Kaye # Copyright (C) 2006-2009, 2011-2012, 2014 Lukáš Lalinský -# Copyright (C) 2008-2011, 2014, 2018-2022 Philipp Wolfer +# Copyright (C) 2008-2011, 2014, 2018-2023 Philipp Wolfer # Copyright (C) 2009 Carlin Mangar # Copyright (C) 2009 david # Copyright (C) 2010 fatih @@ -62,6 +62,7 @@ import unicodedata from dateutil.parser import parse from PyQt5 import QtCore +from PyQt5.QtGui import QDesktopServices from picard import log from picard.const import ( @@ -428,6 +429,14 @@ def run_executable(executable, *args, timeout=None): return ret.returncode, ret.stdout.decode(sys.stdout.encoding), ret.stderr.decode(sys.stderr.encoding) +def open_local_path(path): + url = QtCore.QUrl.fromLocalFile(path) + if os.environ.get('SNAP'): + run_executable('xdg-open', url.toString()) + else: + QDesktopServices.openUrl(url) + + _mbid_format = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' _re_mbid_val = re.compile(_mbid_format, re.IGNORECASE) def mbid_validate(string): # noqa: E302