diff --git a/picard/ui/options/renaming.py b/picard/ui/options/renaming.py
index bc148c31e..284715e6e 100644
--- a/picard/ui/options/renaming.py
+++ b/picard/ui/options/renaming.py
@@ -16,6 +16,7 @@
# Copyright (C) 2016 Suhas
# Copyright (C) 2016-2017 Sambhav Kothari
# Copyright (C) 2021 Gabriel Ferreira
+# Copyright (C) 2021 Bob Swift
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -58,6 +59,7 @@ from picard.ui.options import (
OptionsPage,
register_options_page,
)
+from picard.ui.options.renaming_editor import RenamingEditorOptionsPage
from picard.ui.options.scripting import (
ScriptCheckError,
ScriptingDocumentationDialog,
@@ -119,6 +121,7 @@ class RenamingOptionsPage(OptionsPage):
)
self.ui.file_naming_format.textChanged.connect(self.check_formats)
self.ui.file_naming_format_default.clicked.connect(self.set_file_naming_format_default)
+ self.ui.open_script_editor.clicked.connect(self.show_script_editing_page)
self.ui.move_files_to_browse.clicked.connect(self.move_files_to_browse)
script_edit = self.ui.file_naming_format
@@ -147,6 +150,9 @@ class RenamingOptionsPage(OptionsPage):
# Sync example lists vertical scrolling
sync_vertical_scrollbars((self.ui.example_filename_before, self.ui.example_filename_after))
+ def show_script_editing_page(self):
+ RenamingEditorOptionsPage.show_instance(parent=self)
+
def show_scripting_documentation(self):
ScriptingDocumentationDialog.show_instance(parent=self)
@@ -165,6 +171,7 @@ class RenamingOptionsPage(OptionsPage):
active = self.ui.move_files.isChecked() or self.ui.rename_files.isChecked()
self.ui.file_naming_format.setEnabled(active)
self.ui.file_naming_format_default.setEnabled(active)
+ self.ui.open_script_editor.setEnabled(active)
palette = self.script_palette_normal if active else self.script_palette_readonly
self.ui.file_naming_format.setPalette(palette)
diff --git a/picard/ui/options/renaming_editor.py b/picard/ui/options/renaming_editor.py
new file mode 100644
index 000000000..be8257923
--- /dev/null
+++ b/picard/ui/options/renaming_editor.py
@@ -0,0 +1,298 @@
+# -*- coding: utf-8 -*-
+#
+# Picard, the next-generation MusicBrainz tagger
+#
+# Copyright (C) 2006-2008, 2011 Lukáš Lalinský
+# Copyright (C) 2008-2009 Nikolai Prokoschenko
+# Copyright (C) 2009-2010, 2014-2015, 2018-2021 Philipp Wolfer
+# Copyright (C) 2011-2013 Michael Wiencek
+# Copyright (C) 2011-2013 Wieland Hoffmann
+# Copyright (C) 2013 Calvin Walton
+# Copyright (C) 2013 Ionuț Ciocîrlan
+# Copyright (C) 2013-2014 Sophist-UK
+# Copyright (C) 2013-2015, 2018-2019, 2021 Laurent Monin
+# Copyright (C) 2015 Alex Berman
+# Copyright (C) 2015 Ohm Patel
+# Copyright (C) 2016 Suhas
+# Copyright (C) 2016-2017 Sambhav Kothari
+# Copyright (C) 2021 Gabriel Ferreira
+# Copyright (C) 2021 Bob Swift
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+from functools import partial
+import os.path
+
+from picard.config import (
+ TextOption,
+ get_config,
+)
+from picard.const import DEFAULT_FILE_NAMING_FORMAT
+from picard.file import File
+from picard.script import (
+ ScriptError,
+ ScriptParser,
+)
+from picard.util.settingsoverride import SettingsOverride
+
+from picard.ui import (
+ PicardDialog,
+ SingletonDialog,
+)
+from picard.ui.options import (
+ OptionsCheckError,
+ OptionsPage,
+)
+from picard.ui.options.scripting import (
+ ScriptCheckError,
+ ScriptingDocumentationDialog,
+)
+from picard.ui.ui_options_renaming_editor import Ui_RenamingEditorOptionsPage
+
+
+class RenamingEditorOptionsPage(PicardDialog, SingletonDialog):
+
+ NAME = "filerenamingeditor"
+ TITLE = N_("File Naming Editor")
+ PARENT = None
+ SORT_ORDER = 40
+ ACTIVE = True
+ HELP_URL = '/config/options_filerenaming.html'
+ STYLESHEET_ERROR = OptionsPage.STYLESHEET_ERROR
+
+ options = [
+ TextOption(
+ "setting",
+ "file_naming_format",
+ DEFAULT_FILE_NAMING_FORMAT,
+ ),
+ ]
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.ui = Ui_RenamingEditorOptionsPage()
+ self.ui.setupUi(self)
+
+ self.PARENT = parent
+
+ self.ui.file_naming_editor_save.clicked.connect(self.save_script)
+ self.ui.file_naming_editor_cancel.clicked.connect(self.reject)
+
+ self.ui.file_naming_format.setEnabled(True)
+ self.ui.file_naming_format_default.setEnabled(True)
+
+ self.ui.file_naming_format.textChanged.connect(self.check_formats)
+ self.ui.file_naming_format_default.clicked.connect(self.set_file_naming_format_default)
+
+ self.ui.scripting_documentation_button.clicked.connect(self.show_scripting_documentation)
+ self.ui.example_filename_sample_files_button.clicked.connect(self._sample_example_files)
+ self._sampled_example_files = []
+
+ # Sync example lists vertical scrolling
+ def sync_vertical_scrollbars(widgets):
+ """Sync position of vertical scrollbars for listed widgets"""
+ def _sync_scrollbar_vert(widget, value):
+ widget.blockSignals(True)
+ widget.verticalScrollBar().setValue(value)
+ widget.blockSignals(False)
+
+ widgets = set(widgets)
+ for widget in widgets:
+ for other in widgets - {widget}:
+ widget.verticalScrollBar().valueChanged.connect(
+ partial(_sync_scrollbar_vert, other))
+
+ # Sync example lists vertical scrolling
+ sync_vertical_scrollbars((self.ui.example_filename_before, self.ui.example_filename_after))
+
+ self.load()
+
+ def save_script(self):
+ self.PARENT.ui.file_naming_format.setPlainText(self.ui.file_naming_format.toPlainText())
+ self.accept()
+
+ def show_scripting_documentation(self):
+ ScriptingDocumentationDialog.show_instance(parent=self)
+
+ def check_formats(self):
+ self.test()
+ self.update_examples()
+
+ def _example_to_filename(self, file):
+ config = get_config()
+ settings = SettingsOverride(config.setting, {
+ 'ascii_filenames': self.PARENT.ui.ascii_filenames.isChecked(),
+ 'file_naming_format': self.ui.file_naming_format.toPlainText(),
+ 'move_files': self.PARENT.ui.move_files.isChecked(),
+ 'move_files_to': os.path.normpath(self.PARENT.ui.move_files_to.text()),
+ 'rename_files': self.PARENT.ui.rename_files.isChecked(),
+ 'windows_compatibility': self.PARENT.ui.windows_compatibility.isChecked(),
+ })
+
+ try:
+ if config.setting["enable_tagger_scripts"]:
+ for s_pos, s_name, s_enabled, s_text in config.setting["list_of_scripts"]:
+ if s_enabled and s_text:
+ parser = ScriptParser()
+ parser.eval(s_text, file.metadata)
+ filename_before = file.filename
+ filename_after = file.make_filename(filename_before, file.metadata, settings)
+ if not settings["move_files"]:
+ return os.path.basename(filename_before), os.path.basename(filename_after)
+ return filename_before, filename_after
+ except ScriptError:
+ return "", ""
+ except TypeError:
+ return "", ""
+
+ def _sample_example_files(self):
+ # Get a new sample of randomly selected /loaded files to use as renaming examples
+ import random
+ max_samples = 10 # pick up to 10 samples
+ if self.tagger.window.selected_objects:
+ # If files/albums/tracks are selected, sample example files from them
+ files = self.tagger.get_files_from_objects(self.tagger.window.selected_objects)
+ length = min(max_samples, len(files))
+ files = [file for file in random.sample(files, k=length)]
+ else:
+ # If files/albums/tracks are not selected, sample example files from the pool of loaded files
+ files = self.tagger.files
+ length = min(max_samples, len(files))
+ files = [files[key] for key in random.sample(files.keys(), k=length)]
+
+ if not files:
+ # If no file has been loaded, use generic examples
+ files = [self.example_1(), self.example_2()]
+ self._sampled_example_files = files
+ self.update_examples()
+
+ def update_examples(self):
+ self.ui.example_filename_before.clear()
+ self.ui.example_filename_after.clear()
+
+ if not self._sampled_example_files:
+ self._sample_example_files()
+ example_files = self._sampled_example_files
+
+ examples = [self._example_to_filename(example) for example in example_files]
+ for before, after in sorted(examples, key=lambda x: x[1]):
+ self.ui.example_filename_before.addItem(before)
+ self.ui.example_filename_after.addItem(after)
+
+ def load(self):
+ self.ui.file_naming_format.setPlainText(self.PARENT.ui.file_naming_format.toPlainText())
+ self.update_examples()
+
+ def check(self):
+ self.check_format()
+ if self.PARENT.ui.move_files.isChecked() and not self.PARENT.ui.move_files_to.text().strip():
+ raise OptionsCheckError(_("Error"), _("The location to move files to must not be empty."))
+
+ def check_format(self):
+ parser = ScriptParser()
+ try:
+ parser.eval(self.ui.file_naming_format.toPlainText())
+ except Exception as e:
+ raise ScriptCheckError("", str(e))
+ if self.PARENT.ui.rename_files.isChecked():
+ if not self.ui.file_naming_format.toPlainText().strip():
+ raise ScriptCheckError("", _("The file naming format must not be empty."))
+
+ # def save(self):
+ # self.PARENT.ui.file_naming_format.setPlainText(self.ui.file_naming_format.toPlainText())
+
+ def display_error(self, error):
+ # Ignore scripting errors, those are handled inline
+ if not isinstance(error, ScriptCheckError):
+ super().display_error(error)
+
+ def set_file_naming_format_default(self):
+ self.ui.file_naming_format.setText(self.options[0].default)
+# self.ui.file_naming_format.setCursorPosition(0)
+
+ def example_1(self):
+ file = File("ticket_to_ride.mp3")
+ file.state = File.NORMAL
+ file.metadata['album'] = 'Help!'
+ file.metadata['title'] = 'Ticket to Ride'
+ file.metadata['~releasecomment'] = '2014 mono remaster'
+ file.metadata['artist'] = 'The Beatles'
+ file.metadata['artistsort'] = 'Beatles, The'
+ file.metadata['albumartist'] = 'The Beatles'
+ file.metadata['albumartistsort'] = 'Beatles, The'
+ file.metadata['tracknumber'] = '7'
+ file.metadata['totaltracks'] = '14'
+ file.metadata['discnumber'] = '1'
+ file.metadata['totaldiscs'] = '1'
+ file.metadata['originaldate'] = '1965-08-06'
+ file.metadata['originalyear'] = '1965'
+ file.metadata['date'] = '2014-09-08'
+ file.metadata['releasetype'] = ['album', 'soundtrack']
+ file.metadata['~primaryreleasetype'] = ['album']
+ file.metadata['~secondaryreleasetype'] = ['soundtrack']
+ file.metadata['releasestatus'] = 'official'
+ file.metadata['releasecountry'] = 'US'
+ file.metadata['~extension'] = 'mp3'
+ file.metadata['musicbrainz_albumid'] = 'd7fbbb0a-1348-40ad-8eef-cd438d4cd203'
+ file.metadata['musicbrainz_albumartistid'] = 'b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d'
+ file.metadata['musicbrainz_artistid'] = 'b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d'
+ file.metadata['musicbrainz_recordingid'] = 'ed052ae1-c950-47f2-8d2b-46e1b58ab76c'
+ file.metadata['musicbrainz_releasetrackid'] = '392639f5-5629-477e-b04b-93bffa703405'
+ return file
+
+ def example_2(self):
+ config = get_config()
+ file = File("track05.mp3")
+ file.state = File.NORMAL
+ file.metadata['album'] = "Coup d'État, Volume 1: Ku De Ta / Prologue"
+ file.metadata['title'] = "I've Got to Learn the Mambo"
+ file.metadata['artist'] = "Snowboy feat. James Hunter"
+ file.metadata['artistsort'] = "Snowboy feat. Hunter, James"
+ file.metadata['albumartist'] = config.setting['va_name']
+ file.metadata['albumartistsort'] = config.setting['va_name']
+ file.metadata['tracknumber'] = '5'
+ file.metadata['totaltracks'] = '13'
+ file.metadata['discnumber'] = '2'
+ file.metadata['totaldiscs'] = '2'
+ file.metadata['discsubtitle'] = "Beat Up"
+ file.metadata['originaldate'] = '2005-07-04'
+ file.metadata['originalyear'] = '2005'
+ file.metadata['date'] = '2005-07-04'
+ file.metadata['releasetype'] = ['album', 'compilation']
+ file.metadata['~primaryreleasetype'] = 'album'
+ file.metadata['~secondaryreleasetype'] = 'compilation'
+ file.metadata['releasestatus'] = 'official'
+ file.metadata['releasecountry'] = 'AU'
+ file.metadata['compilation'] = '1'
+ file.metadata['~multiartist'] = '1'
+ file.metadata['~extension'] = 'mp3'
+ file.metadata['musicbrainz_albumid'] = '4b50c71e-0a07-46ac-82e4-cb85dc0c9bdd'
+ file.metadata['musicbrainz_recordingid'] = 'b3c487cb-0e55-477d-8df3-01ec6590f099'
+ file.metadata['musicbrainz_releasetrackid'] = 'f8649a05-da39-39ba-957c-7abf8f9012be'
+ file.metadata['musicbrainz_albumartistid'] = '89ad4ac3-39f7-470e-963a-56509c546377'
+ file.metadata['musicbrainz_artistid'] = ['7b593455-d207-482c-8c6f-19ce22c94679',
+ '9e082466-2390-40d1-891e-4803531f43fd']
+ return file
+
+ def test(self):
+ self.ui.renaming_error.setStyleSheet("")
+ self.ui.renaming_error.setText("")
+ try:
+ self.check_format()
+ except ScriptCheckError as e:
+ self.ui.renaming_error.setStyleSheet(self.STYLESHEET_ERROR)
+ self.ui.renaming_error.setText(e.info)
+ return
diff --git a/picard/ui/ui_options_renaming.py b/picard/ui/ui_options_renaming.py
index bf0129fe0..4dda042fe 100644
--- a/picard/ui/ui_options_renaming.py
+++ b/picard/ui/ui_options_renaming.py
@@ -88,13 +88,6 @@ class Ui_RenamingOptionsPage(object):
self.example_filename_sample_files_button = QtWidgets.QPushButton(RenamingOptionsPage)
self.example_filename_sample_files_button.setObjectName("example_filename_sample_files_button")
self.horizontalLayout.addWidget(self.example_filename_sample_files_button)
- spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.horizontalLayout.addItem(spacerItem)
- self.scripting_documentation_button = QtWidgets.QPushButton(RenamingOptionsPage)
- self.scripting_documentation_button.setObjectName("scripting_documentation_button")
- self.horizontalLayout.addWidget(self.scripting_documentation_button)
- spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.horizontalLayout.addItem(spacerItem1)
self.file_naming_format_default = QtWidgets.QPushButton(RenamingOptionsPage)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
@@ -104,6 +97,16 @@ class Ui_RenamingOptionsPage(object):
self.file_naming_format_default.setMinimumSize(QtCore.QSize(0, 0))
self.file_naming_format_default.setObjectName("file_naming_format_default")
self.horizontalLayout.addWidget(self.file_naming_format_default)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
+ self.scripting_documentation_button = QtWidgets.QPushButton(RenamingOptionsPage)
+ self.scripting_documentation_button.setObjectName("scripting_documentation_button")
+ self.horizontalLayout.addWidget(self.scripting_documentation_button)
+ spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem1)
+ self.open_script_editor = QtWidgets.QPushButton(RenamingOptionsPage)
+ self.open_script_editor.setObjectName("open_script_editor")
+ self.horizontalLayout.addWidget(self.open_script_editor)
self.verticalLayout_5.addLayout(self.horizontalLayout)
self.renaming_error = QtWidgets.QLabel(RenamingOptionsPage)
self.renaming_error.setText("")
@@ -142,7 +145,6 @@ class Ui_RenamingOptionsPage(object):
RenamingOptionsPage.setTabOrder(self.move_files_to_browse, self.move_additional_files)
RenamingOptionsPage.setTabOrder(self.move_additional_files, self.move_additional_files_pattern)
RenamingOptionsPage.setTabOrder(self.move_additional_files_pattern, self.delete_empty_dirs)
- RenamingOptionsPage.setTabOrder(self.delete_empty_dirs, self.file_naming_format_default)
def retranslateUi(self, RenamingOptionsPage):
_translate = QtCore.QCoreApplication.translate
@@ -156,8 +158,9 @@ class Ui_RenamingOptionsPage(object):
self.windows_compatibility.setText(_("Windows compatibility"))
self.file_naming_format_label.setText(_("Name files like this"))
self.example_filename_sample_files_button.setText(_("Renew examples"))
- self.scripting_documentation_button.setText(_("Scripting Documentation"))
self.file_naming_format_default.setText(_("Default"))
+ self.scripting_documentation_button.setText(_("Scripting Documentation"))
+ self.open_script_editor.setText(_("Script Editor"))
self.groupBox.setTitle(_("Examples"))
self.example_filename_before_label.setText(_("Before"))
self.example_filename_after_label.setText(_("After"))
diff --git a/picard/ui/ui_options_renaming_editor.py b/picard/ui/ui_options_renaming_editor.py
new file mode 100644
index 000000000..e4f39a026
--- /dev/null
+++ b/picard/ui/ui_options_renaming_editor.py
@@ -0,0 +1,143 @@
+# -*- coding: utf-8 -*-
+
+# Automatically generated - don't edit.
+# Use `python setup.py build_ui` to update it.
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_RenamingEditorOptionsPage(object):
+ def setupUi(self, RenamingEditorOptionsPage):
+ RenamingEditorOptionsPage.setObjectName("RenamingEditorOptionsPage")
+ RenamingEditorOptionsPage.setWindowModality(QtCore.Qt.WindowModal)
+ RenamingEditorOptionsPage.setEnabled(True)
+ RenamingEditorOptionsPage.resize(453, 552)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(RenamingEditorOptionsPage.sizePolicy().hasHeightForWidth())
+ RenamingEditorOptionsPage.setSizePolicy(sizePolicy)
+ self.verticalLayout_5 = QtWidgets.QVBoxLayout(RenamingEditorOptionsPage)
+ self.verticalLayout_5.setObjectName("verticalLayout_5")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_2.setContentsMargins(-1, 0, -1, 0)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.file_naming_format_label = QtWidgets.QLabel(RenamingEditorOptionsPage)
+ self.file_naming_format_label.setObjectName("file_naming_format_label")
+ self.verticalLayout_2.addWidget(self.file_naming_format_label)
+ self.frame = QtWidgets.QFrame(RenamingEditorOptionsPage)
+ self.frame.setMinimumSize(QtCore.QSize(0, 20))
+ self.frame.setFrameShape(QtWidgets.QFrame.NoFrame)
+ self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame.setLineWidth(0)
+ self.frame.setObjectName("frame")
+ self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.frame)
+ self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_3.setObjectName("verticalLayout_3")
+ self.splitter = QtWidgets.QSplitter(self.frame)
+ self.splitter.setOrientation(QtCore.Qt.Vertical)
+ self.splitter.setObjectName("splitter")
+ self.file_naming_format = ScriptTextEdit(self.splitter)
+ self.file_naming_format.setEnabled(False)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.MinimumExpanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.file_naming_format.sizePolicy().hasHeightForWidth())
+ self.file_naming_format.setSizePolicy(sizePolicy)
+ self.file_naming_format.setMinimumSize(QtCore.QSize(0, 250))
+ self.file_naming_format.viewport().setProperty("cursor", QtGui.QCursor(QtCore.Qt.IBeamCursor))
+ self.file_naming_format.setTabChangesFocus(False)
+ self.file_naming_format.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
+ self.file_naming_format.setTabStopWidth(20)
+ self.file_naming_format.setAcceptRichText(False)
+ self.file_naming_format.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
+ self.file_naming_format.setObjectName("file_naming_format")
+ self.groupBox = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
+ self.groupBox.setSizePolicy(sizePolicy)
+ self.groupBox.setMinimumSize(QtCore.QSize(0, 150))
+ self.groupBox.setObjectName("groupBox")
+ self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox)
+ self.verticalLayout_4.setContentsMargins(-1, 6, -1, 0)
+ self.verticalLayout_4.setObjectName("verticalLayout_4")
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.example_filename_before_label = QtWidgets.QLabel(self.groupBox)
+ self.example_filename_before_label.setObjectName("example_filename_before_label")
+ self.horizontalLayout_3.addWidget(self.example_filename_before_label)
+ self.example_filename_after_label = QtWidgets.QLabel(self.groupBox)
+ self.example_filename_after_label.setObjectName("example_filename_after_label")
+ self.horizontalLayout_3.addWidget(self.example_filename_after_label)
+ self.verticalLayout_4.addLayout(self.horizontalLayout_3)
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.example_filename_before = QtWidgets.QListWidget(self.groupBox)
+ self.example_filename_before.setObjectName("example_filename_before")
+ self.horizontalLayout_2.addWidget(self.example_filename_before)
+ self.example_filename_after = QtWidgets.QListWidget(self.groupBox)
+ self.example_filename_after.setObjectName("example_filename_after")
+ self.horizontalLayout_2.addWidget(self.example_filename_after)
+ self.verticalLayout_4.addLayout(self.horizontalLayout_2)
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setSpacing(2)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.example_filename_sample_files_button = QtWidgets.QPushButton(self.groupBox)
+ self.example_filename_sample_files_button.setObjectName("example_filename_sample_files_button")
+ self.horizontalLayout.addWidget(self.example_filename_sample_files_button)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
+ self.scripting_documentation_button = QtWidgets.QPushButton(self.groupBox)
+ self.scripting_documentation_button.setObjectName("scripting_documentation_button")
+ self.horizontalLayout.addWidget(self.scripting_documentation_button)
+ spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem1)
+ self.renaming_error = QtWidgets.QLabel(self.groupBox)
+ self.renaming_error.setText("")
+ self.renaming_error.setAlignment(QtCore.Qt.AlignCenter)
+ self.renaming_error.setObjectName("renaming_error")
+ self.horizontalLayout.addWidget(self.renaming_error)
+ self.file_naming_format_default = QtWidgets.QPushButton(self.groupBox)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.file_naming_format_default.sizePolicy().hasHeightForWidth())
+ self.file_naming_format_default.setSizePolicy(sizePolicy)
+ self.file_naming_format_default.setMinimumSize(QtCore.QSize(0, 0))
+ self.file_naming_format_default.setObjectName("file_naming_format_default")
+ self.horizontalLayout.addWidget(self.file_naming_format_default)
+ self.verticalLayout_4.addLayout(self.horizontalLayout)
+ self.verticalLayout_3.addWidget(self.splitter)
+ self.verticalLayout_2.addWidget(self.frame)
+ self.verticalLayout_5.addLayout(self.verticalLayout_2)
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_4.setContentsMargins(-1, 0, -1, -1)
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem2)
+ self.file_naming_editor_cancel = QtWidgets.QPushButton(RenamingEditorOptionsPage)
+ self.file_naming_editor_cancel.setObjectName("file_naming_editor_cancel")
+ self.horizontalLayout_4.addWidget(self.file_naming_editor_cancel)
+ self.file_naming_editor_save = QtWidgets.QPushButton(RenamingEditorOptionsPage)
+ self.file_naming_editor_save.setObjectName("file_naming_editor_save")
+ self.horizontalLayout_4.addWidget(self.file_naming_editor_save)
+ self.verticalLayout_5.addLayout(self.horizontalLayout_4)
+
+ self.retranslateUi(RenamingEditorOptionsPage)
+ QtCore.QMetaObject.connectSlotsByName(RenamingEditorOptionsPage)
+
+ def retranslateUi(self, RenamingEditorOptionsPage):
+ _translate = QtCore.QCoreApplication.translate
+ self.file_naming_format_label.setText(_("Name files like this"))
+ self.groupBox.setTitle(_("Examples"))
+ self.example_filename_before_label.setText(_("Before"))
+ self.example_filename_after_label.setText(_("After"))
+ self.example_filename_sample_files_button.setText(_("Renew examples"))
+ self.scripting_documentation_button.setText(_("Scripting Documentation"))
+ self.file_naming_format_default.setText(_("Default"))
+ self.file_naming_editor_cancel.setText(_("Cancel"))
+ self.file_naming_editor_save.setText(_("Save"))
+from picard.ui.widgets.scripttextedit import ScriptTextEdit
diff --git a/ui/options_renaming.ui b/ui/options_renaming.ui
index 6ce6280f5..a8280ce80 100644
--- a/ui/options_renaming.ui
+++ b/ui/options_renaming.ui
@@ -173,6 +173,25 @@
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+ Default
+
+
+
-
@@ -207,21 +226,9 @@
-
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
+
- Default
+ Script Editor
@@ -302,7 +309,6 @@
move_additional_files
move_additional_files_pattern
delete_empty_dirs
- file_naming_format_default
diff --git a/ui/options_renaming_editor.ui b/ui/options_renaming_editor.ui
new file mode 100644
index 000000000..d869972d0
--- /dev/null
+++ b/ui/options_renaming_editor.ui
@@ -0,0 +1,295 @@
+
+
+ RenamingEditorOptionsPage
+
+
+ Qt::WindowModal
+
+
+ true
+
+
+
+ 0
+ 0
+ 453
+ 552
+
+
+
+
+ 0
+ 0
+
+
+
+ -
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Name files like this
+
+
+
+ -
+
+
+
+ 0
+ 20
+
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+ 0
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Vertical
+
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 250
+
+
+
+ IBeamCursor
+
+
+ false
+
+
+ QTextEdit::NoWrap
+
+
+ 20
+
+
+ false
+
+
+ Qt::TextEditorInteraction
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 150
+
+
+
+ Examples
+
+
+
+ 6
+
+
+ 0
+
+
-
+
+
-
+
+
+ Before
+
+
+
+ -
+
+
+ After
+
+
+
+
+
+ -
+
+
-
+
+
+ -
+
+
+
+
+ -
+
+
+ 2
+
+
-
+
+
+ Renew examples
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Scripting Documentation
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+ Default
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Cancel
+
+
+
+ -
+
+
+ Save
+
+
+
+
+
+
+
+
+
+ ScriptTextEdit
+ QTextEdit
+ picard.ui.widgets.scripttextedit
+
+
+
+ file_naming_format_default
+
+
+
+