mirror of
https://github.com/fergalmoran/picard.git
synced 2026-01-04 07:33:59 +00:00
Make UI more intuitive
- Add `Close` button - Confirm actions which may lose unsaved edits - Remove `Select` button and automatically select the current script - Save selected script id and open editor to that script - Update the `file_naming_format` setting when script changes are saved
This commit is contained in:
@@ -137,7 +137,7 @@ class PicardScript():
|
||||
# Base class developed to support future tagging script class as possible replacement for currently used tuples in config.setting["list_of_scripts"].
|
||||
|
||||
TYPE = PicardScriptType.BASE
|
||||
OUTPUT_FIELDS = {'title', 'script', 'script_language_version'}
|
||||
OUTPUT_FIELDS = {'title', 'script', 'script_language_version', 'id'}
|
||||
|
||||
# Don't automatically trigger changing the `script_last_updated` property when updating these properties.
|
||||
_last_updated_ignore_list = {'last_updated', 'readonly', 'deletable', 'id'}
|
||||
@@ -153,7 +153,7 @@ class PicardScript():
|
||||
"""
|
||||
self.title = title if title else DEFAULT_SCRIPT_NAME
|
||||
self.script = script
|
||||
if id is None:
|
||||
if not id:
|
||||
self._set_new_id()
|
||||
else:
|
||||
self.id = id
|
||||
@@ -270,7 +270,7 @@ class PicardScript():
|
||||
# TODO: Enable once PyYAML requirement resolved with Python 3.8
|
||||
#
|
||||
# @classmethod
|
||||
# def create_from_yaml(cls, yaml_string):
|
||||
# def create_from_yaml(cls, yaml_string, create_new_id=True):
|
||||
# """Creates an instance based on the contents of the YAML string provided.
|
||||
# Properties in the YAML string that are not found in the script object are ignored.
|
||||
|
||||
@@ -287,15 +287,18 @@ class PicardScript():
|
||||
# if 'title' not in yaml_dict or 'script' not in yaml_dict:
|
||||
# raise ScriptImportError(N_('Invalid script package'))
|
||||
# new_object._update_from_dict(yaml_dict)
|
||||
# if create_new_id or not new_object['id']:
|
||||
# new_object._set_new_id()
|
||||
# return new_object
|
||||
|
||||
@classmethod
|
||||
def create_from_json(cls, json_string):
|
||||
def create_from_json(cls, json_string, create_new_id=True):
|
||||
"""Creates an instance based on the contents of the JSON string provided.
|
||||
Properties in the JSON string that are not found in the script object are ignored.
|
||||
|
||||
Args:
|
||||
json_string (str): JSON string containing the property settings.
|
||||
create_new_id (bool): Do not use the existing id. Defaults to True.
|
||||
|
||||
Returns:
|
||||
object: An instance of the class, populated from the property settings in the JSON string.
|
||||
@@ -305,6 +308,8 @@ class PicardScript():
|
||||
new_object.update_from_json(json_string)
|
||||
if not (new_object['title'] and new_object['script']):
|
||||
raise ScriptImportError(N_('Invalid script package'))
|
||||
if create_new_id or not new_object['id']:
|
||||
new_object._set_new_id()
|
||||
return new_object
|
||||
|
||||
def update_from_json(self, json_string):
|
||||
@@ -325,7 +330,7 @@ class FileNamingScript(PicardScript):
|
||||
"""Picard file naming script class
|
||||
"""
|
||||
TYPE = PicardScriptType.FILENAMING
|
||||
OUTPUT_FIELDS = {'title', 'script', 'author', 'description', 'license', 'version', 'last_updated', 'script_language_version'}
|
||||
OUTPUT_FIELDS = {'title', 'script', 'author', 'description', 'license', 'version', 'last_updated', 'script_language_version', 'id'}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -379,6 +384,7 @@ def get_file_naming_script_presets():
|
||||
return _("Preset %d: %s") % (number, _(title))
|
||||
|
||||
yield FileNamingScript(
|
||||
id="Preset 1",
|
||||
title=preset_title(1, N_("Default file naming script")),
|
||||
script=DEFAULT_FILE_NAMING_FORMAT,
|
||||
readonly=True,
|
||||
@@ -392,6 +398,7 @@ def get_file_naming_script_presets():
|
||||
)
|
||||
|
||||
yield FileNamingScript(
|
||||
id="Preset 2",
|
||||
title=preset_title(2, N_("[album artist]/[album]/[track #]. [title]")),
|
||||
script="%albumartist%/\n"
|
||||
"%album%/\n"
|
||||
@@ -407,6 +414,7 @@ def get_file_naming_script_presets():
|
||||
)
|
||||
|
||||
yield FileNamingScript(
|
||||
id="Preset 3",
|
||||
title=preset_title(3, N_("[album artist]/[album]/[disc and track #] [artist] - [title]")),
|
||||
script="$if2(%albumartist%,%artist%)/\n"
|
||||
"$if(%albumartist%,%album%/,)\n"
|
||||
|
||||
@@ -247,6 +247,11 @@ class ScriptEditorPage(PicardDialog):
|
||||
"file_naming_scripts",
|
||||
[],
|
||||
),
|
||||
TextOption(
|
||||
"setting",
|
||||
"selected_file_naming_script_id",
|
||||
"",
|
||||
),
|
||||
]
|
||||
|
||||
signal_save = QtCore.pyqtSignal()
|
||||
@@ -277,17 +282,19 @@ class ScriptEditorPage(PicardDialog):
|
||||
self.setWindowModality(QtCore.Qt.WindowModal)
|
||||
self.setWindowTitle(self.TITLE)
|
||||
self.displaying = False
|
||||
self.loading = True
|
||||
self.ui = Ui_ScriptEditor()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
self.ui.example_filename_sample_files_button.setToolTip(_(self.examples.tooltip_text) % self.examples.max_samples)
|
||||
self.ui.label.setWordWrap(False)
|
||||
|
||||
self.installEventFilter(self)
|
||||
|
||||
self.ui.file_naming_editor_new.clicked.connect(self.new_script)
|
||||
self.ui.file_naming_editor_save.clicked.connect(self.save_script)
|
||||
self.ui.file_naming_editor_copy.clicked.connect(self.copy_script)
|
||||
self.ui.file_naming_editor_select.clicked.connect(self.save_selected_script)
|
||||
self.ui.file_naming_editor_close.clicked.connect(self.close_window)
|
||||
self.ui.file_naming_editor_delete.clicked.connect(self.delete_script)
|
||||
self.ui.script_details.clicked.connect(self.view_script_details)
|
||||
|
||||
@@ -311,9 +318,11 @@ class ScriptEditorPage(PicardDialog):
|
||||
|
||||
config = get_config()
|
||||
self.naming_scripts = config.setting["file_naming_scripts"]
|
||||
self.populate_script_selector()
|
||||
self.ui.preset_naming_scripts.setCurrentIndex(0)
|
||||
self.selected_script_id = config.setting["selected_file_naming_script_id"]
|
||||
self.selected_script_index = 0
|
||||
idx = self.populate_script_selector()
|
||||
self.ui.preset_naming_scripts.currentIndexChanged.connect(self.select_script)
|
||||
self.ui.preset_naming_scripts.setCurrentIndex(idx)
|
||||
self.select_script()
|
||||
|
||||
self.synchronize_vertical_scrollbars((self.ui.example_filename_before, self.ui.example_filename_after))
|
||||
@@ -322,6 +331,7 @@ class ScriptEditorPage(PicardDialog):
|
||||
self.examples_current_row = -1
|
||||
|
||||
self.load()
|
||||
self.loading = False
|
||||
|
||||
@staticmethod
|
||||
def synchronize_vertical_scrollbars(widgets):
|
||||
@@ -354,31 +364,59 @@ class ScriptEditorPage(PicardDialog):
|
||||
self.update_examples()
|
||||
return False
|
||||
|
||||
def close_window(self):
|
||||
"""Close the window.
|
||||
"""
|
||||
self.close()
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""Custom close event handler to check for unsaved changes.
|
||||
"""
|
||||
if self.unsaved_changes_confirmation():
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def populate_script_selector(self):
|
||||
"""Populate the script selection combo box.
|
||||
|
||||
Returns:
|
||||
int: The index of the selected script in the combo box.
|
||||
"""
|
||||
if not self.selected_script_id:
|
||||
script_item = FileNamingScript(
|
||||
script=get_config().setting["file_naming_format"],
|
||||
title=_("Primary file naming script"),
|
||||
readonly=False,
|
||||
deletable=True,
|
||||
)
|
||||
self.naming_scripts.insert(0, script_item.to_json())
|
||||
self.selected_script_id = script_item['id']
|
||||
|
||||
idx = 0
|
||||
self.ui.preset_naming_scripts.blockSignals(True)
|
||||
self.ui.preset_naming_scripts.clear()
|
||||
script_item = FileNamingScript(
|
||||
script=get_config().setting["file_naming_format"],
|
||||
title=_("Current file naming script saved in configuration"),
|
||||
readonly=False,
|
||||
deletable=False,
|
||||
id="current"
|
||||
)
|
||||
self.set_script(script_item.script)
|
||||
self.ui.preset_naming_scripts.addItem(self.SCRIPT_TITLE_SYSTEM % script_item.title, script_item)
|
||||
|
||||
for script_json in self.naming_scripts:
|
||||
script_item = FileNamingScript().create_from_json(script_json)
|
||||
if script_item['title']:
|
||||
for i in range(len(self.naming_scripts)):
|
||||
try:
|
||||
script_item = FileNamingScript().create_from_json(self.naming_scripts[i], create_new_id=False)
|
||||
except ScriptImportError:
|
||||
pass
|
||||
else:
|
||||
self.naming_scripts[i] = script_item.to_json() # Ensure scripts are stored with id codes
|
||||
self.ui.preset_naming_scripts.addItem(self.SCRIPT_TITLE_USER % script_item.title, script_item)
|
||||
if script_item['id'] == self.selected_script_id:
|
||||
idx = i
|
||||
|
||||
for script_item in get_file_naming_script_presets():
|
||||
title = script_item.title
|
||||
self.ui.preset_naming_scripts.addItem(title, script_item)
|
||||
if script_item['id'] == self.selected_script_id:
|
||||
idx = self.ui.preset_naming_scripts.count() - 1
|
||||
|
||||
self.ui.preset_naming_scripts.blockSignals(False)
|
||||
self.update_scripts_list()
|
||||
return idx
|
||||
|
||||
def toggle_documentation(self):
|
||||
"""Toggle the display of the scripting documentation sidebar.
|
||||
@@ -395,6 +433,15 @@ class ScriptEditorPage(PicardDialog):
|
||||
details_page.raise_()
|
||||
details_page.activateWindow()
|
||||
|
||||
def has_changed(self):
|
||||
"""Check if the current script has pending edits to the title or script that have not been saved.
|
||||
|
||||
Returns:
|
||||
bool: True if there are unsaved changes, otherwise false.
|
||||
"""
|
||||
script_item = self.ui.preset_naming_scripts.itemData(self.selected_script_index)
|
||||
return self.ui.script_title.text().strip() != script_item['title'] or self.get_script() != script_item['script']
|
||||
|
||||
def update_from_details(self):
|
||||
"""Update the script selection combo box and script list after updates from the script details dialog.
|
||||
"""
|
||||
@@ -409,8 +456,9 @@ class ScriptEditorPage(PicardDialog):
|
||||
script_item (FileNamingScript): File naming scrip to insert.
|
||||
"""
|
||||
self.ui.preset_naming_scripts.blockSignals(True)
|
||||
self.ui.preset_naming_scripts.insertItem(1, self.SCRIPT_TITLE_USER % script_item.title, script_item)
|
||||
self.ui.preset_naming_scripts.setCurrentIndex(1)
|
||||
idx = len(self.naming_scripts)
|
||||
self.ui.preset_naming_scripts.insertItem(idx, self.SCRIPT_TITLE_USER % script_item.title, script_item)
|
||||
self.ui.preset_naming_scripts.setCurrentIndex(idx)
|
||||
self.ui.preset_naming_scripts.blockSignals(False)
|
||||
self.update_scripts_list()
|
||||
self.select_script()
|
||||
@@ -418,16 +466,24 @@ class ScriptEditorPage(PicardDialog):
|
||||
def new_script(self):
|
||||
"""Add a new (empty) script to the script selection combo box and script list.
|
||||
"""
|
||||
script_item = FileNamingScript(script='$noop()')
|
||||
self._insert_item(script_item)
|
||||
if self.unsaved_changes_confirmation():
|
||||
script_item = FileNamingScript(script='$noop()')
|
||||
self._insert_item(script_item)
|
||||
|
||||
def copy_script(self):
|
||||
"""Add a copy of the script as a new editable script to the script selection combo box and script list.
|
||||
"""
|
||||
selected = self.ui.preset_naming_scripts.currentIndex()
|
||||
script_item = self.ui.preset_naming_scripts.itemData(selected)
|
||||
new_item = script_item.copy()
|
||||
self._insert_item(new_item)
|
||||
if self.unsaved_changes_confirmation():
|
||||
selected = self.ui.preset_naming_scripts.currentIndex()
|
||||
script_item = self.ui.preset_naming_scripts.itemData(selected)
|
||||
new_item = script_item.copy()
|
||||
self._insert_item(new_item)
|
||||
|
||||
def update_script_in_settings(self, script_item):
|
||||
self.signal_save.emit()
|
||||
config = get_config()
|
||||
config.setting["file_naming_format"] = script_item['script']
|
||||
config.setting["selected_file_naming_script_id"] = self.selected_script_id
|
||||
|
||||
def update_scripts_list(self):
|
||||
"""Refresh the script list in the settings based on the contents of the script selection combo box.
|
||||
@@ -435,7 +491,7 @@ class ScriptEditorPage(PicardDialog):
|
||||
self.naming_scripts = []
|
||||
for idx in range(self.ui.preset_naming_scripts.count()):
|
||||
script_item = self.ui.preset_naming_scripts.itemData(idx)
|
||||
# Only add items that can be removed -- no presets or the current file naming script
|
||||
# Only add items that can be removed -- no presets
|
||||
if script_item.deletable:
|
||||
self.naming_scripts.append(script_item.to_json())
|
||||
config = get_config()
|
||||
@@ -450,14 +506,33 @@ class ScriptEditorPage(PicardDialog):
|
||||
selected = self.ui.preset_naming_scripts.currentIndex()
|
||||
return self.ui.preset_naming_scripts.itemData(selected)
|
||||
|
||||
def unsaved_changes_confirmation(self):
|
||||
"""Check if there are unsaved changes and as the user to confirm the action resulting in their loss.
|
||||
|
||||
Returns:
|
||||
bool: True if no unsaved changes or user confirms the action, otherwise False.
|
||||
"""
|
||||
if not self.loading and self.has_changed() and not self.confirmation_dialog(
|
||||
_("There are unsaved changes to the current script. Do you want to continue and lose these changes?")
|
||||
):
|
||||
self.ui.preset_naming_scripts.blockSignals(True)
|
||||
self.ui.preset_naming_scripts.setCurrentIndex(self.selected_script_index)
|
||||
self.ui.preset_naming_scripts.blockSignals(False)
|
||||
return False
|
||||
return True
|
||||
|
||||
def select_script(self):
|
||||
"""Load the current script from the combo box into the editor.
|
||||
"""
|
||||
script_item = self.get_selected_item()
|
||||
self.ui.script_title.setText(str(script_item.title).strip())
|
||||
self.set_script(script_item.script)
|
||||
self.set_button_states()
|
||||
self.update_examples()
|
||||
if self.unsaved_changes_confirmation():
|
||||
script_item = self.get_selected_item()
|
||||
self.ui.script_title.setText(str(script_item.title).strip())
|
||||
self.set_script(script_item.script)
|
||||
self.selected_script_id = script_item['id']
|
||||
self.selected_script_index = self.ui.preset_naming_scripts.currentIndex()
|
||||
self.update_script_in_settings(script_item)
|
||||
self.set_button_states()
|
||||
self.update_examples()
|
||||
|
||||
def update_combo_box_item(self, idx, script_item):
|
||||
"""Update the title and item data for the specified script selection combo box item.
|
||||
@@ -468,6 +543,8 @@ class ScriptEditorPage(PicardDialog):
|
||||
"""
|
||||
self.ui.preset_naming_scripts.setItemData(idx, script_item)
|
||||
self.ui.preset_naming_scripts.setItemText(idx, self.SCRIPT_TITLE_USER % script_item['title'])
|
||||
self.update_script_in_settings(script_item)
|
||||
self.update_scripts_list()
|
||||
|
||||
def set_button_states(self, save_enabled=True):
|
||||
"""Set the button states based on the readonly and deletable attributes of the currently selected
|
||||
@@ -484,7 +561,6 @@ class ScriptEditorPage(PicardDialog):
|
||||
self.ui.file_naming_format.setReadOnly(script_item.readonly)
|
||||
self.ui.file_naming_editor_save.setEnabled(save_enabled and not script_item.readonly)
|
||||
self.ui.file_naming_editor_copy.setEnabled(save_enabled)
|
||||
self.ui.file_naming_editor_select.setEnabled(save_enabled)
|
||||
self.ui.file_naming_editor_delete.setEnabled(script_item.deletable and save_enabled)
|
||||
self.ui.import_script.setEnabled(save_enabled)
|
||||
self.ui.export_script.setEnabled(save_enabled)
|
||||
@@ -526,23 +602,15 @@ class ScriptEditorPage(PicardDialog):
|
||||
"""Saves changes to the current script to the script list and combo box item.
|
||||
"""
|
||||
selected = self.ui.preset_naming_scripts.currentIndex()
|
||||
if selected == 0:
|
||||
self.signal_save.emit()
|
||||
else:
|
||||
title = str(self.ui.script_title.text()).strip()
|
||||
if title:
|
||||
script_item = self.ui.preset_naming_scripts.itemData(selected)
|
||||
script_item.title = title
|
||||
script_item.script = self.get_script()
|
||||
self.update_combo_box_item(selected, script_item)
|
||||
self.update_scripts_list()
|
||||
else:
|
||||
self.display_error(OptionsCheckError(_("Error"), _("The script title must not be empty.")))
|
||||
|
||||
def save_selected_script(self):
|
||||
"""Emits a `save` signal to trigger appropriate save action in the parent object.
|
||||
"""
|
||||
self.signal_save.emit()
|
||||
title = str(self.ui.script_title.text()).strip()
|
||||
if title:
|
||||
script_item = self.ui.preset_naming_scripts.itemData(selected)
|
||||
script_item.title = title
|
||||
script_item.script = self.get_script()
|
||||
self.update_combo_box_item(selected, script_item)
|
||||
else:
|
||||
self.display_error(OptionsCheckError(_("Error"), _("The script title must not be empty.")))
|
||||
|
||||
def get_script(self):
|
||||
"""Provides the text of the file naming script currently loaded into the editor.
|
||||
@@ -553,7 +621,7 @@ class ScriptEditorPage(PicardDialog):
|
||||
return str(self.ui.file_naming_format.toPlainText()).strip()
|
||||
|
||||
def set_script(self, script_text):
|
||||
"""Sets the text of the file naming script into the editor.
|
||||
"""Sets the text of the file naming script into the editor and settings.
|
||||
|
||||
Args:
|
||||
script_text (str): File naming script text to set in the editor.
|
||||
@@ -634,6 +702,9 @@ class ScriptEditorPage(PicardDialog):
|
||||
FILE_ERROR_IMPORT = N_('Error importing "%s". %s.')
|
||||
FILE_ERROR_DECODE = N_('Error decoding "%s". %s.')
|
||||
|
||||
if not self.unsaved_changes_confirmation():
|
||||
return
|
||||
|
||||
dialog_title = _("Import Script File")
|
||||
dialog_file_types = self.FILE_TYPE_PACKAGE + ";;" + self.FILE_TYPE_SCRIPT + ";;" + self.FILE_TYPE_ALL
|
||||
options = QtWidgets.QFileDialog.Options()
|
||||
@@ -703,13 +774,10 @@ class ScriptEditorPage(PicardDialog):
|
||||
dialog.exec_()
|
||||
|
||||
def load(self):
|
||||
"""Loads the file naming script from the configuration settings.
|
||||
"""Loads the file naming script from the selected combo box item.
|
||||
"""
|
||||
self.toggle_wordwrap()
|
||||
self.toggle_documentation()
|
||||
self.ui.preset_naming_scripts.blockSignals(True)
|
||||
self.ui.preset_naming_scripts.setCurrentIndex(0)
|
||||
self.ui.preset_naming_scripts.blockSignals(False)
|
||||
self.select_script()
|
||||
|
||||
def check_formats(self):
|
||||
|
||||
@@ -46,12 +46,13 @@ class Ui_ScriptEditor(object):
|
||||
self.horizontalLayout_2.setContentsMargins(-1, -1, -1, 0)
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.label = QtWidgets.QLabel(self.frame_4)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
|
||||
self.label.setSizePolicy(sizePolicy)
|
||||
self.label.setMinimumSize(QtCore.QSize(0, 0))
|
||||
self.label.setIndent(0)
|
||||
self.label.setObjectName("label")
|
||||
self.horizontalLayout_2.addWidget(self.label)
|
||||
self.preset_naming_scripts = QtWidgets.QComboBox(self.frame_4)
|
||||
@@ -155,6 +156,7 @@ class Ui_ScriptEditor(object):
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_4.addItem(spacerItem)
|
||||
self.script_details = QtWidgets.QPushButton(self.frame_4)
|
||||
self.script_details.setStatusTip("")
|
||||
self.script_details.setObjectName("script_details")
|
||||
self.horizontalLayout_4.addWidget(self.script_details)
|
||||
self.import_script = QtWidgets.QPushButton(self.frame_4)
|
||||
@@ -163,21 +165,21 @@ class Ui_ScriptEditor(object):
|
||||
self.export_script = QtWidgets.QPushButton(self.frame_4)
|
||||
self.export_script.setObjectName("export_script")
|
||||
self.horizontalLayout_4.addWidget(self.export_script)
|
||||
self.file_naming_editor_delete = QtWidgets.QPushButton(self.frame_4)
|
||||
self.file_naming_editor_delete.setObjectName("file_naming_editor_delete")
|
||||
self.horizontalLayout_4.addWidget(self.file_naming_editor_delete)
|
||||
self.file_naming_editor_save = QtWidgets.QPushButton(self.frame_4)
|
||||
self.file_naming_editor_save.setObjectName("file_naming_editor_save")
|
||||
self.horizontalLayout_4.addWidget(self.file_naming_editor_save)
|
||||
self.file_naming_editor_new = QtWidgets.QPushButton(self.frame_4)
|
||||
self.file_naming_editor_new.setObjectName("file_naming_editor_new")
|
||||
self.horizontalLayout_4.addWidget(self.file_naming_editor_new)
|
||||
self.file_naming_editor_copy = QtWidgets.QPushButton(self.frame_4)
|
||||
self.file_naming_editor_copy.setObjectName("file_naming_editor_copy")
|
||||
self.horizontalLayout_4.addWidget(self.file_naming_editor_copy)
|
||||
self.file_naming_editor_select = QtWidgets.QPushButton(self.frame_4)
|
||||
self.file_naming_editor_select.setObjectName("file_naming_editor_select")
|
||||
self.horizontalLayout_4.addWidget(self.file_naming_editor_select)
|
||||
self.file_naming_editor_delete = QtWidgets.QPushButton(self.frame_4)
|
||||
self.file_naming_editor_delete.setObjectName("file_naming_editor_delete")
|
||||
self.horizontalLayout_4.addWidget(self.file_naming_editor_delete)
|
||||
self.file_naming_editor_save = QtWidgets.QPushButton(self.frame_4)
|
||||
self.file_naming_editor_save.setObjectName("file_naming_editor_save")
|
||||
self.horizontalLayout_4.addWidget(self.file_naming_editor_save)
|
||||
self.file_naming_editor_close = QtWidgets.QPushButton(self.frame_4)
|
||||
self.file_naming_editor_close.setObjectName("file_naming_editor_close")
|
||||
self.horizontalLayout_4.addWidget(self.file_naming_editor_close)
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_4)
|
||||
self.groupBox = QtWidgets.QGroupBox(self.splitter_between_editor_and_examples)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
@@ -236,7 +238,7 @@ class Ui_ScriptEditor(object):
|
||||
|
||||
def retranslateUi(self, ScriptEditor):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
self.label.setText(_("File naming scripts:"))
|
||||
self.label.setText(_("Select the file naming script to use:"))
|
||||
self.preset_naming_scripts.setToolTip(_("Select the file naming script to load into the editor"))
|
||||
self.label_2.setText(_("Title:"))
|
||||
self.file_naming_word_wrap.setToolTip(_("Word wrap long lines in the editor"))
|
||||
@@ -245,22 +247,22 @@ class Ui_ScriptEditor(object):
|
||||
self.show_documentation.setText(_("Show Documentation"))
|
||||
self.example_filename_sample_files_button.setToolTip(_("Up to 10 items chosen at random from files selected in the main window"))
|
||||
self.example_filename_sample_files_button.setText(_("Reload Examples"))
|
||||
self.script_details.setStatusTip(_("Display the details for the currently selected script"))
|
||||
self.script_details.setToolTip(_("Display the details for the script"))
|
||||
self.script_details.setText(_("Details"))
|
||||
self.import_script.setToolTip(_("Import a file to replace the current script"))
|
||||
self.import_script.setToolTip(_("Import a file as a new script"))
|
||||
self.import_script.setText(_("Import"))
|
||||
self.export_script.setToolTip(_("Export the current script to a file"))
|
||||
self.export_script.setToolTip(_("Export the script to a file"))
|
||||
self.export_script.setText(_("Export"))
|
||||
self.file_naming_editor_delete.setToolTip(_("Delete the currently selected script"))
|
||||
self.file_naming_editor_delete.setText(_("Delete"))
|
||||
self.file_naming_editor_save.setToolTip(_("Save changes to the current script"))
|
||||
self.file_naming_editor_save.setText(_("Save"))
|
||||
self.file_naming_editor_new.setToolTip(_("Create a new file naming script"))
|
||||
self.file_naming_editor_new.setText(_("New"))
|
||||
self.file_naming_editor_copy.setToolTip(_("Save a copy of the script as a new script"))
|
||||
self.file_naming_editor_copy.setText(_("Copy"))
|
||||
self.file_naming_editor_select.setToolTip(_("Select the current script to use as the file naming script"))
|
||||
self.file_naming_editor_select.setText(_("Select"))
|
||||
self.file_naming_editor_delete.setToolTip(_("Delete the script"))
|
||||
self.file_naming_editor_delete.setText(_("Delete"))
|
||||
self.file_naming_editor_save.setToolTip(_("Save changes to the script"))
|
||||
self.file_naming_editor_save.setText(_("Save"))
|
||||
self.file_naming_editor_close.setToolTip(_("Close the script editor"))
|
||||
self.file_naming_editor_close.setText(_("Close"))
|
||||
self.groupBox.setTitle(_("Files will be named like this"))
|
||||
self.example_filename_before_label.setText(_("Before"))
|
||||
self.example_filename_after_label.setText(_("After"))
|
||||
|
||||
@@ -57,7 +57,7 @@ class ScriptClassesTest(PicardTestCase):
|
||||
self.assertEqual(test_script['id'], '12345')
|
||||
self.assertEqual(test_script.last_updated, '2021-04-26')
|
||||
self.assertEqual(test_script['last_updated'], '2021-04-26')
|
||||
self.assertEqual(test_script.to_json(), '{"script": "Script text", "script_language_version": "1.0", "title": "Script 1"}')
|
||||
self.assertEqual(test_script.to_json(), '{"id": "12345", "script": "Script text", "script_language_version": "1.0", "title": "Script 1"}')
|
||||
|
||||
def test_script_object_2(self):
|
||||
# Check updating values directly so as not to modify `last_updated`.
|
||||
@@ -105,7 +105,7 @@ class ScriptClassesTest(PicardTestCase):
|
||||
test_script = PicardScript(title='Script 1', script='Script text', id='12345', last_updated='2021-04-26', script_language_version='1.0')
|
||||
test_script.update_script_setting(description='Updated description')
|
||||
self.assertEqual(test_script['last_updated'], '2021-04-26')
|
||||
self.assertEqual(test_script.to_json(), '{"script": "Script text", "script_language_version": "1.0", "title": "Script 1"}')
|
||||
self.assertEqual(test_script.to_json(), '{"id": "12345", "script": "Script text", "script_language_version": "1.0", "title": "Script 1"}')
|
||||
with self.assertRaises(AttributeError):
|
||||
print(test_script.description)
|
||||
|
||||
@@ -114,7 +114,7 @@ class ScriptClassesTest(PicardTestCase):
|
||||
test_script = PicardScript(title='Script 1', script='Script text', id='12345', last_updated='2021-04-26', script_language_version='1.0')
|
||||
test_script.update_from_json('{"description": "Updated description"}')
|
||||
self.assertEqual(test_script['last_updated'], '2021-04-26')
|
||||
self.assertEqual(test_script.to_json(), '{"script": "Script text", "script_language_version": "1.0", "title": "Script 1"}')
|
||||
self.assertEqual(test_script.to_json(), '{"id": "12345", "script": "Script text", "script_language_version": "1.0", "title": "Script 1"}')
|
||||
with self.assertRaises(AttributeError):
|
||||
print(test_script.description)
|
||||
|
||||
@@ -145,27 +145,31 @@ class ScriptClassesTest(PicardTestCase):
|
||||
self.assertEqual(test_script['script'], 'Script text')
|
||||
self.assertEqual(test_script.author, 'Script author')
|
||||
self.assertEqual(test_script['author'], 'Script author')
|
||||
self.assertEqual(test_script.to_json(),
|
||||
'{'
|
||||
'"author": "Script author", '
|
||||
'"description": "Script description", '
|
||||
'"last_updated": "2021-04-26", '
|
||||
'"license": "", '
|
||||
'"script": "Script text", '
|
||||
'"script_language_version": "1.0", '
|
||||
'"title": "Script 1", '
|
||||
'"version": ""'
|
||||
'}'
|
||||
)
|
||||
self.assertEqual(test_script.to_json(indent=4),
|
||||
'{\n'
|
||||
' "author": "Script author",\n'
|
||||
' "description": "Script description",\n'
|
||||
' "last_updated": "2021-04-26",\n'
|
||||
' "license": "",\n'
|
||||
' "script": "Script text",\n'
|
||||
' "script_language_version": "1.0",\n'
|
||||
' "title": "Script 1",\n'
|
||||
' "version": ""\n'
|
||||
'}'
|
||||
)
|
||||
self.assertEqual(
|
||||
test_script.to_json(),
|
||||
'{'
|
||||
'"author": "Script author", '
|
||||
'"description": "Script description", '
|
||||
'"id": "12345", '
|
||||
'"last_updated": "2021-04-26", '
|
||||
'"license": "", '
|
||||
'"script": "Script text", '
|
||||
'"script_language_version": "1.0", '
|
||||
'"title": "Script 1", '
|
||||
'"version": ""'
|
||||
'}'
|
||||
)
|
||||
self.assertEqual(
|
||||
test_script.to_json(indent=4),
|
||||
'{\n'
|
||||
' "author": "Script author",\n'
|
||||
' "description": "Script description",\n'
|
||||
' "id": "12345",\n'
|
||||
' "last_updated": "2021-04-26",\n'
|
||||
' "license": "",\n'
|
||||
' "script": "Script text",\n'
|
||||
' "script_language_version": "1.0",\n'
|
||||
' "title": "Script 1",\n'
|
||||
' "version": ""\n'
|
||||
'}'
|
||||
)
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@@ -83,7 +83,10 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>File naming scripts:</string>
|
||||
<string>Select the file naming script to use:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -340,8 +343,11 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="script_details">
|
||||
<property name="toolTip">
|
||||
<string>Display the details for the script</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Display the details for the currently selected script</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Details</string>
|
||||
@@ -351,7 +357,7 @@
|
||||
<item>
|
||||
<widget class="QPushButton" name="import_script">
|
||||
<property name="toolTip">
|
||||
<string>Import a file to replace the current script</string>
|
||||
<string>Import a file as a new script</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Import</string>
|
||||
@@ -361,33 +367,13 @@
|
||||
<item>
|
||||
<widget class="QPushButton" name="export_script">
|
||||
<property name="toolTip">
|
||||
<string>Export the current script to a file</string>
|
||||
<string>Export the script to a file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Export</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="file_naming_editor_delete">
|
||||
<property name="toolTip">
|
||||
<string>Delete the currently selected script</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="file_naming_editor_save">
|
||||
<property name="toolTip">
|
||||
<string>Save changes to the current script</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="file_naming_editor_new">
|
||||
<property name="toolTip">
|
||||
@@ -409,12 +395,32 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="file_naming_editor_select">
|
||||
<widget class="QPushButton" name="file_naming_editor_delete">
|
||||
<property name="toolTip">
|
||||
<string>Select the current script to use as the file naming script</string>
|
||||
<string>Delete the script</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select</string>
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="file_naming_editor_save">
|
||||
<property name="toolTip">
|
||||
<string>Save changes to the script</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="file_naming_editor_close">
|
||||
<property name="toolTip">
|
||||
<string>Close the script editor</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user