diff --git a/picard/script/__init__.py b/picard/script/__init__.py
index ff8db2bef..b09d68a77 100644
--- a/picard/script/__init__.py
+++ b/picard/script/__init__.py
@@ -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"
diff --git a/picard/ui/scripteditor.py b/picard/ui/scripteditor.py
index 0081885ed..23f9e5cc1 100644
--- a/picard/ui/scripteditor.py
+++ b/picard/ui/scripteditor.py
@@ -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):
diff --git a/picard/ui/ui_scripteditor.py b/picard/ui/ui_scripteditor.py
index 904d74737..1e43b0bc5 100644
--- a/picard/ui/ui_scripteditor.py
+++ b/picard/ui/ui_scripteditor.py
@@ -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"))
diff --git a/test/test_scriptclasses.py b/test/test_scriptclasses.py
index f670dcad3..28fdda427 100644
--- a/test/test_scriptclasses.py
+++ b/test/test_scriptclasses.py
@@ -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'
+ '}'
+ )
diff --git a/ui/scripteditor.ui b/ui/scripteditor.ui
index 018323244..9ddaf6077 100644
--- a/ui/scripteditor.ui
+++ b/ui/scripteditor.ui
@@ -71,7 +71,7 @@
-
-
+
0
0
@@ -83,7 +83,10 @@
- File naming scripts:
+ Select the file naming script to use:
+
+
+ 0
@@ -340,8 +343,11 @@
-
+
+ Display the details for the script
+
- Display the details for the currently selected script
+
Details
@@ -351,7 +357,7 @@
-
- Import a file to replace the current script
+ Import a file as a new script
Import
@@ -361,33 +367,13 @@
-
- Export the current script to a file
+ Export the script to a file
Export
- -
-
-
- Delete the currently selected script
-
-
- Delete
-
-
-
- -
-
-
- Save changes to the current script
-
-
- Save
-
-
-
-
@@ -409,12 +395,32 @@
-
-
+
- Select the current script to use as the file naming script
+ Delete the script
- Select
+ Delete
+
+
+
+ -
+
+
+ Save changes to the script
+
+
+ Save
+
+
+
+ -
+
+
+ Close the script editor
+
+
+ Close