Merge pull request #2503 from zas/filedialog_wrappers

Filedialog wrappers
This commit is contained in:
Laurent Monin
2024-06-02 18:35:56 +02:00
committed by GitHub
12 changed files with 129 additions and 53 deletions

View File

@@ -47,6 +47,8 @@ from picard.i18n import (
)
from picard.util import make_filename_from_title
from picard.ui.util import FileDialog
@unique
class ScriptSerializerType(IntEnum):
@@ -222,10 +224,10 @@ class ScriptSerializer():
dialog_title = _("Export Script File")
dialog_file_types = self._get_dialog_filetypes()
filename, file_type = QtWidgets.QFileDialog.getSaveFileName(
filename, file_type = FileDialog.getSaveFileName(
parent=parent,
caption=dialog_title,
directory=default_path,
dir=default_path,
filter=dialog_file_types,
)
if not filename:
@@ -264,10 +266,10 @@ class ScriptSerializer():
dialog_title = _("Import Script File")
dialog_file_types = cls._get_dialog_filetypes()
default_script_directory = os.path.normpath(QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.StandardLocation.DocumentsLocation))
filename, file_type = QtWidgets.QFileDialog.getOpenFileName(
filename, file_type = FileDialog.getOpenFileName(
parent=parent,
caption=dialog_title,
directory=default_script_directory,
dir=default_script_directory,
filter=dialog_file_types,
)
if not filename:

View File

@@ -166,6 +166,7 @@ from picard.ui.mainwindow import MainWindow
from picard.ui.searchdialog.album import AlbumSearchDialog
from picard.ui.searchdialog.artist import ArtistSearchDialog
from picard.ui.searchdialog.track import TrackSearchDialog
from picard.ui.util import FileDialog
# A "fix" for https://bugs.python.org/issue1438480
@@ -1201,7 +1202,7 @@ class Tagger(QtWidgets.QApplication):
traceback=self._debug)
def lookup_discid_from_logfile(self):
file_chooser = QtWidgets.QFileDialog(parent=self.window)
file_chooser = FileDialog(parent=self.window)
file_chooser.setNameFilters([
_("All supported log files") + " (*.log *.txt)",
_("EAC / XLD / Whipper / fre:ac log files") + " (*.log)",

View File

@@ -65,6 +65,7 @@ from picard.util import (
from picard.util.lrucache import LRUCache
from picard.ui.colors import interface_colors
from picard.ui.util import FileDialog
from picard.ui.widgets import ActiveLabel
@@ -607,7 +608,7 @@ class CoverArtBox(QtWidgets.QGroupBox):
return coverartimage
def choose_local_file(self):
file_chooser = QtWidgets.QFileDialog(parent=self)
file_chooser = FileDialog(parent=self)
extensions = ['*' + ext for ext in imageinfo.get_supported_extensions()]
extensions.sort()
file_chooser.setNameFilters([

View File

@@ -52,6 +52,7 @@ from picard.ui import (
PicardDialog,
)
from picard.ui.colors import interface_colors
from picard.ui.util import FileDialog
class LogViewDialog(PicardDialog):
@@ -275,7 +276,7 @@ class LogView(LogViewCommon):
return self.formats[level]
def _save_log_as_do(self):
path, ok = QtWidgets.QFileDialog.getSaveFileName(
path, ok = FileDialog.getSaveFileName(
parent=self,
caption=_("Save Log View to File"),
options=QtWidgets.QFileDialog.Option.DontConfirmOverwrite,

View File

@@ -146,7 +146,7 @@ from picard.ui.statusindicator import (
)
from picard.ui.tagsfromfilenames import TagsFromFileNamesDialog
from picard.ui.util import (
MultiDirsSelectDialog,
FileDialog,
find_starting_directory,
menu_builder,
)
@@ -847,9 +847,9 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry):
extensions.sort()
formats.insert(0, _("All supported formats") + " (%s)" % " ".join(extensions))
formats.insert(1, _("All files") + " (*)")
files, _filter = QtWidgets.QFileDialog.getOpenFileNames(
files, _filter = FileDialog.getOpenFileNames(
parent=self,
directory=current_directory,
dir=current_directory,
filter=";;".join(formats),
)
if files:
@@ -864,19 +864,17 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry):
dir_list = []
config = get_config()
if not config.setting['allow_multi_dirs_selection']:
directory = QtWidgets.QFileDialog.getExistingDirectory(
directory = FileDialog.getExistingDirectory(
parent=self,
directory=current_directory,
dir=current_directory,
)
if directory:
dir_list.append(directory)
else:
file_dialog = MultiDirsSelectDialog(
dir_list = FileDialog.getMultipleDirectories(
parent=self,
directory=current_directory,
)
if file_dialog.exec() == QtWidgets.QDialog.DialogCode.Accepted:
dir_list = file_dialog.selectedFiles()
dir_count = len(dir_list)
if dir_count:

View File

@@ -29,7 +29,6 @@ import os
from PyQt6 import (
QtCore,
QtGui,
QtWidgets,
)
from picard.acoustid import find_fpcalc
@@ -48,6 +47,7 @@ from picard.ui.options import (
OptionsCheckError,
OptionsPage,
)
from picard.ui.util import FileDialog
class ApiKeyValidator(QtGui.QValidator):
@@ -120,9 +120,9 @@ class FingerprintingOptionsPage(OptionsPage):
self._acoustid_fpcalc_check()
def acoustid_fpcalc_browse(self):
path, _filter = QtWidgets.QFileDialog.getOpenFileName(
path, _filter = FileDialog.getOpenFileName(
parent=self,
directory=self.ui.acoustid_fpcalc.text(),
dir=self.ui.acoustid_fpcalc.text(),
)
if path:
path = os.path.normpath(path)

View File

@@ -53,7 +53,10 @@ from picard.ui.theme import (
OS_SUPPORTS_THEMES,
UiTheme,
)
from picard.ui.util import changes_require_restart_warning
from picard.ui.util import (
FileDialog,
changes_require_restart_warning,
)
class InterfaceOptionsPage(OptionsPage):
@@ -197,9 +200,9 @@ class InterfaceOptionsPage(OptionsPage):
def starting_directory_browse(self):
item = self.ui.starting_directory_path
path = QtWidgets.QFileDialog.getExistingDirectory(
path = FileDialog.getExistingDirectory(
parent=self,
directory=item.text(),
dir=item.text(),
)
if path:
path = os.path.normpath(path)

View File

@@ -53,7 +53,10 @@ from picard.ui.forms.ui_options_interface_toolbar import (
)
from picard.ui.moveable_list_view import MoveableListView
from picard.ui.options import OptionsPage
from picard.ui.util import qlistwidget_items
from picard.ui.util import (
FileDialog,
qlistwidget_items,
)
ToolbarButtonDesc = namedtuple('ToolbarButtonDesc', ('label', 'icon'))
@@ -162,9 +165,9 @@ class InterfaceToolbarOptionsPage(OptionsPage):
def starting_directory_browse(self):
item = self.ui.starting_directory_path
path = QtWidgets.QFileDialog.getExistingDirectory(
path = FileDialog.getExistingDirectory(
parent=self,
directory=item.text(),
dir=item.text(),
)
if path:
path = os.path.normpath(path)

View File

@@ -47,6 +47,7 @@ from picard.util import open_local_path
from picard.ui.forms.ui_options_maintenance import Ui_MaintenanceOptionsPage
from picard.ui.options import OptionsPage
from picard.ui.util import FileDialog
OPTIONS_NOT_IN_PAGES = {
@@ -141,9 +142,9 @@ class MaintenanceOptionsPage(OptionsPage):
dialog.exec()
def _dialog_autobackup_dir_browse(self):
path = QtWidgets.QFileDialog.getExistingDirectory(
path = FileDialog.getExistingDirectory(
parent=self,
directory=self.get_current_autobackup_dir(),
dir=self.get_current_autobackup_dir(),
)
if path:
self.set_current_autobackup_dir(path)
@@ -237,11 +238,11 @@ class MaintenanceOptionsPage(OptionsPage):
dialog.exec()
def _dialog_ask_backup_filename(self, default_path, ext):
filename, file_type = QtWidgets.QFileDialog.getSaveFileName(
self,
_("Backup Configuration File"),
default_path,
self._get_dialog_filetypes(ext),
filename, file_type = FileDialog.getSaveFileName(
parent=self,
caption=_("Backup Configuration File"),
dir=default_path,
filter=self._get_dialog_filetypes(ext),
)
return filename
@@ -316,11 +317,11 @@ class MaintenanceOptionsPage(OptionsPage):
dialog.exec()
def _dialog_load_backup_select_filename(self, directory, ext):
filename, file_type = QtWidgets.QFileDialog.getOpenFileName(
self,
_("Select Configuration File to Load"),
directory,
self._get_dialog_filetypes(ext),
filename, file_type = FileDialog.getOpenFileName(
parent=self,
caption=_("Select Configuration File to Load"),
dir=directory,
filter=self._get_dialog_filetypes(ext),
)
return filename

View File

@@ -65,6 +65,7 @@ from picard.ui import HashableTreeWidgetItem
from picard.ui.forms.ui_options_plugins import Ui_PluginsOptionsPage
from picard.ui.options import OptionsPage
from picard.ui.theme import theme
from picard.ui.util import FileDialog
COLUMN_NAME, COLUMN_VERSION, COLUMN_ACTIONS = range(3)
@@ -659,9 +660,9 @@ class PluginsOptionsPage(OptionsPage):
self.refresh_details(item)
def open_plugins(self):
files, _filter = QtWidgets.QFileDialog.getOpenFileNames(
files, _filter = FileDialog.getOpenFileNames(
parent=self,
directory=QtCore.QDir.homePath(),
dir=QtCore.QDir.homePath(),
filter="Picard plugin (*.py *.pyc *.zip)",
)
if files:

View File

@@ -35,7 +35,6 @@
import os.path
from PyQt6 import QtWidgets
from PyQt6.QtGui import QPalette
from picard.config import get_config
@@ -62,6 +61,7 @@ from picard.ui.scripteditor import (
populate_script_selection_combo_box,
synchronize_vertical_scrollbars,
)
from picard.ui.util import FileDialog
class RenamingOptionsPage(OptionsPage):
@@ -280,9 +280,9 @@ class RenamingOptionsPage(OptionsPage):
super().display_error(error)
def move_files_to_browse(self):
path = QtWidgets.QFileDialog.getExistingDirectory(
path = FileDialog.getExistingDirectory(
parent=self,
directory=self.ui.move_files_to.text(),
dir=self.ui.move_files_to.text(),
)
if path:
path = os.path.normpath(path)

View File

@@ -32,6 +32,7 @@ from PyQt6 import (
QtWidgets,
)
from picard import PICARD_DISPLAY_NAME
from picard.config import get_config
from picard.const.sys import (
IS_LINUX,
@@ -81,25 +82,85 @@ def find_starting_directory():
return find_existing_path(path)
class MultiDirsSelectDialog(QtWidgets.QFileDialog):
def _picardize_caption(caption):
return _("%s - %s") % (caption, PICARD_DISPLAY_NAME)
"""Custom file selection dialog which allows the selection
of multiple directories.
Depending on the platform, dialog may fallback on non-native.
"""
def _filedialog_caption(caption, default_caption=""):
if not caption:
caption = default_caption
return _picardize_caption(caption)
def _filedialog_options(options, default=None):
if options is None:
# returns default flags or empty enum flag
return default or QtWidgets.QFileDialog.Option(0)
else:
return options
class FileDialog(QtWidgets.QFileDialog):
"""Wrap QFileDialog & its static methods"""
def __init__(self, parent=None, caption="", directory="", filter=""):
if not caption:
caption = _("Select a file or a directory")
caption = _picardize_caption(caption)
super().__init__(parent=parent, caption=caption, directory=directory, filter=filter)
self.setFileMode(QtWidgets.QFileDialog.FileMode.Directory)
self.setOption(QtWidgets.QFileDialog.Option.ShowDirsOnly)
@staticmethod
def getSaveFileName(parent=None, caption="", dir="", filter="", selectedFilter="", options=None):
caption = _filedialog_caption(caption, _("Select a target file"))
options = _filedialog_options(options)
return QtWidgets.QFileDialog.getSaveFileName(
parent=parent, caption=caption, directory=dir,
filter=filter, initialFilter=selectedFilter, options=options
)
@staticmethod
def getOpenFileName(parent=None, caption="", dir="", filter="", selectedFilter="", options=None):
caption = _filedialog_caption(caption, _("Select a file"))
options = _filedialog_options(options)
return QtWidgets.QFileDialog.getOpenFileName(
parent=parent, caption=caption, directory=dir,
filter=filter, initialFilter=selectedFilter, options=options
)
@staticmethod
def getOpenFileNames(parent=None, caption="", dir="", filter="", selectedFilter="", options=None):
caption = _filedialog_caption(caption, _("Select one or more files"))
options = _filedialog_options(options)
return QtWidgets.QFileDialog.getOpenFileNames(
parent=parent, caption=caption, directory=dir,
filter=filter, initialFilter=selectedFilter, options=options
)
@staticmethod
def getExistingDirectory(parent=None, caption="", dir="", options=None):
caption = _filedialog_caption(caption, _("Select a directory"))
options = _filedialog_options(options, default=QtWidgets.QFileDialog.Option.ShowDirsOnly)
return QtWidgets.QFileDialog.getExistingDirectory(
parent=parent, caption=caption, directory=dir, options=options
)
@staticmethod
def getMultipleDirectories(parent=None, caption="", directory="", filter=""):
"""Custom file selection dialog which allows the selection
of multiple directories.
Depending on the platform, dialog may fallback on non-native.
"""
if not caption:
caption = _("Select one or more directories")
file_dialog = FileDialog(parent=parent, caption=caption, directory=directory, filter=filter)
file_dialog.setFileMode(QtWidgets.QFileDialog.FileMode.Directory)
file_dialog.setOption(QtWidgets.QFileDialog.Option.ShowDirsOnly)
# The native dialog doesn't allow selecting >1 directory
self.setOption(QtWidgets.QFileDialog.Option.DontUseNativeDialog)
for view in self.findChildren((QtWidgets.QListView, QtWidgets.QTreeView)):
file_dialog.setOption(QtWidgets.QFileDialog.Option.DontUseNativeDialog)
for view in file_dialog.findChildren((QtWidgets.QListView, QtWidgets.QTreeView)):
if isinstance(view.model(), QtGui.QFileSystemModel):
view.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection)
self.set_sidebar_locations()
def set_sidebar_locations(self):
# Allow access to all mounted drives in the sidebar
root_volume = "/"
volume_paths = []
@@ -116,7 +177,11 @@ class MultiDirsSelectDialog(QtWidgets.QFileDialog):
QtCore.QDir.homePath(),
QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.StandardLocation.MusicLocation),
]
self.setSidebarUrls(QtCore.QUrl.fromLocalFile(p) for p in paths + sorted(volume_paths) if p)
file_dialog.setSidebarUrls(QtCore.QUrl.fromLocalFile(p) for p in paths + sorted(volume_paths) if p)
dirs = ()
if file_dialog.exec() == QtWidgets.QDialog.DialogCode.Accepted:
dirs = file_dialog.selectedFiles()
return tuple(dirs)
def qlistwidget_items(qlistwidget):