diff --git a/picard/ui/options/renaming_compat.py b/picard/ui/options/renaming_compat.py
index 201464253..1b428f153 100644
--- a/picard/ui/options/renaming_compat.py
+++ b/picard/ui/options/renaming_compat.py
@@ -43,6 +43,7 @@ from PyQt5 import (
from picard.config import (
BoolOption,
Option,
+ TextOption,
get_config,
)
from picard.const.sys import IS_WIN
@@ -73,6 +74,7 @@ class RenamingCompatOptionsPage(OptionsPage):
BoolOption("setting", "windows_long_paths", system_supports_long_paths() if IS_WIN else False),
BoolOption("setting", "ascii_filenames", False),
BoolOption("setting", "replace_spaces_with_underscores", False),
+ TextOption("setting", "replace_dir_separator", DEFAULT_REPLACEMENT),
Option("setting", "win_compat_replacements", {
'*': DEFAULT_REPLACEMENT,
':': DEFAULT_REPLACEMENT,
@@ -96,6 +98,7 @@ class RenamingCompatOptionsPage(OptionsPage):
self.ui.windows_compatibility.toggled.connect(self.on_options_changed)
self.ui.windows_long_paths.toggled.connect(self.on_options_changed)
self.ui.replace_spaces_with_underscores.toggled.connect(self.on_options_changed)
+ self.ui.replace_dir_separator.textChanged.connect(self.on_options_changed)
self.ui.btn_windows_compatibility_change.clicked.connect(self.open_win_compat_dialog)
def load(self):
@@ -113,6 +116,7 @@ class RenamingCompatOptionsPage(OptionsPage):
self.ui.windows_long_paths.setChecked(config.setting["windows_long_paths"])
self.ui.ascii_filenames.setChecked(config.setting["ascii_filenames"])
self.ui.replace_spaces_with_underscores.setChecked(config.setting["replace_spaces_with_underscores"])
+ self.ui.replace_dir_separator.setText(config.setting["replace_dir_separator"])
self.ui.windows_long_paths.toggled.connect(self.toggle_windows_long_paths)
def save(self):
@@ -144,6 +148,7 @@ class RenamingCompatOptionsPage(OptionsPage):
'windows_compatibility': self.ui.windows_compatibility.isChecked(),
'windows_long_paths': self.ui.windows_long_paths.isChecked(),
'replace_spaces_with_underscores': self.ui.replace_spaces_with_underscores.isChecked(),
+ 'replace_dir_separator': self.ui.replace_dir_separator.text(),
'win_compat_replacements': self.win_compat_replacements,
}
diff --git a/picard/ui/ui_options_renaming_compat.py b/picard/ui/ui_options_renaming_compat.py
index c7bd5b9bd..420524d17 100644
--- a/picard/ui/ui_options_renaming_compat.py
+++ b/picard/ui/ui_options_renaming_compat.py
@@ -44,6 +44,28 @@ class Ui_RenamingCompatOptionsPage(object):
self.replace_spaces_with_underscores = QtWidgets.QCheckBox(RenamingCompatOptionsPage)
self.replace_spaces_with_underscores.setObjectName("replace_spaces_with_underscores")
self.verticalLayout_5.addWidget(self.replace_spaces_with_underscores)
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.label_replace_dir_separator = QtWidgets.QLabel(RenamingCompatOptionsPage)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.label_replace_dir_separator.sizePolicy().hasHeightForWidth())
+ self.label_replace_dir_separator.setSizePolicy(sizePolicy)
+ self.label_replace_dir_separator.setObjectName("label_replace_dir_separator")
+ self.horizontalLayout_2.addWidget(self.label_replace_dir_separator)
+ self.replace_dir_separator = QtWidgets.QLineEdit(RenamingCompatOptionsPage)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.replace_dir_separator.sizePolicy().hasHeightForWidth())
+ self.replace_dir_separator.setSizePolicy(sizePolicy)
+ self.replace_dir_separator.setMaximumSize(QtCore.QSize(20, 16777215))
+ self.replace_dir_separator.setText("_")
+ self.replace_dir_separator.setMaxLength(1)
+ self.replace_dir_separator.setObjectName("replace_dir_separator")
+ self.horizontalLayout_2.addWidget(self.replace_dir_separator)
+ self.verticalLayout_5.addLayout(self.horizontalLayout_2)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_5.addItem(spacerItem)
self.example_selection_note = QtWidgets.QLabel(RenamingCompatOptionsPage)
@@ -65,3 +87,4 @@ class Ui_RenamingCompatOptionsPage(object):
self.btn_windows_compatibility_change.setText(_("Customize..."))
self.windows_long_paths.setText(_("Allow paths longer than 259 characters"))
self.replace_spaces_with_underscores.setText(_("Replace spaces with underscores"))
+ self.label_replace_dir_separator.setText(_("Replace directory separators with:"))
diff --git a/picard/util/scripttofilename.py b/picard/util/scripttofilename.py
index a72c39497..e76fb6ff7 100644
--- a/picard/util/scripttofilename.py
+++ b/picard/util/scripttofilename.py
@@ -57,9 +57,12 @@ def script_to_filename_with_metadata(naming_format, metadata, file=None, setting
# make sure every metadata can safely be used in a path name
win_compat = IS_WIN or settings["windows_compatibility"]
new_metadata = Metadata()
+ replace_dir_separator = settings["replace_dir_separator"]
for name in metadata:
- new_metadata[name] = [sanitize_filename(str(v), win_compat=win_compat)
- for v in metadata.getall(name)]
+ new_metadata[name] = [
+ sanitize_filename(str(v), repl=replace_dir_separator, win_compat=win_compat)
+ for v in metadata.getall(name)
+ ]
naming_format = naming_format.replace("\t", "").replace("\n", "")
filename = ScriptParser().eval(naming_format, new_metadata, file)
if settings["ascii_filenames"]:
diff --git a/test/formats/common.py b/test/formats/common.py
index 0cdde9e1f..9bdad58c9 100644
--- a/test/formats/common.py
+++ b/test/formats/common.py
@@ -63,6 +63,7 @@ settings = {
'remove_wave_riff_info': False,
'wave_riff_info_encoding': 'iso-8859-1',
'replace_spaces_with_underscores': False,
+ 'replace_dir_separator': '_',
'win_compat_replacements': {},
}
diff --git a/test/test_coverart_image.py b/test/test_coverart_image.py
index 8764bd9c4..952706f2b 100644
--- a/test/test_coverart_image.py
+++ b/test/test_coverart_image.py
@@ -169,6 +169,7 @@ class CoverArtImageTest(PicardTestCase):
'win_compat_replacements': {},
'windows_long_paths': False,
'replace_spaces_with_underscores': False,
+ 'replace_dir_separator': '_',
'enabled_plugins': [],
'ascii_filenames': False,
'save_images_overwrite': False,
@@ -202,6 +203,7 @@ class CoverArtImageMakeFilenameTest(PicardTestCase):
'enabled_plugins': [],
'ascii_filenames': False,
'replace_spaces_with_underscores': False,
+ 'replace_dir_separator': '_',
})
def compare_paths(self, path1, path2):
diff --git a/test/test_file.py b/test/test_file.py
index 952cacd44..4b115a130 100644
--- a/test/test_file.py
+++ b/test/test_file.py
@@ -213,6 +213,7 @@ class FileNamingTest(PicardTestCase):
'win_compat_replacements': {},
'windows_long_paths': False,
'replace_spaces_with_underscores': False,
+ 'replace_dir_separator': '_',
'file_renaming_scripts': {'test_id': {'script': '%album%/%title%'}},
'selected_file_naming_script_id': 'test_id',
})
diff --git a/test/test_scripttofilename.py b/test/test_scripttofilename.py
index 214a593ed..3c1277c66 100644
--- a/test/test_scripttofilename.py
+++ b/test/test_scripttofilename.py
@@ -41,6 +41,7 @@ settings = {
'windows_compatibility': False,
'win_compat_replacements': {},
'replace_spaces_with_underscores': False,
+ 'replace_dir_separator': '_',
}
@@ -142,6 +143,14 @@ class ScriptToFilenameTest(PicardTestCase):
filename = script_to_filename('%artist%', metadata, settings=settings)
self.assertEqual('The_New_Artist', filename)
+ def test_replace_dir_separator(self):
+ metadata = Metadata()
+ metadata['artist'] = 'AC/DC'
+ settings = config.setting.copy()
+ settings['replace_dir_separator'] = '-'
+ filename = script_to_filename('/music/%artist%', metadata, settings=settings)
+ self.assertEqual('/music/AC-DC', filename)
+
@unittest.skipUnless(IS_WIN, "windows test")
def test_ascii_win_save(self):
self._test_ascii_windows_compatibility()
diff --git a/ui/options_renaming_compat.ui b/ui/options_renaming_compat.ui
index af560d478..8d12dffb6 100644
--- a/ui/options_renaming_compat.ui
+++ b/ui/options_renaming_compat.ui
@@ -19,7 +19,7 @@
0
-
+
-
@@ -71,6 +71,45 @@
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Replace directory separators with:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 20
+ 16777215
+
+
+
+ _
+
+
+ 1
+
+
+
+
+
-