Skip to content

Commit 3017b38

Browse files
committed
Adding new validation logic to prevent deletion of custom profile which is currently used or the default project (in settings). Also validating custom profile has a unique description. Adding icons to Profile context menu. Added a new "Set as Default Profile" context menu option. Updated translations.
1 parent 5cdefbf commit 3017b38

File tree

5 files changed

+92
-54
lines changed

5 files changed

+92
-54
lines changed

src/language/OpenShot/OpenShot.pot

+46-42
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ msgid ""
88
msgstr ""
99
"Project-Id-Version: OpenShot Video Editor (version: 3.2.1-dev)\n"
1010
"Report-Msgid-Bugs-To: Jonathan Thomas <[email protected]>\n"
11-
"POT-Creation-Date: 2024-10-09 16:12:14.191928\n"
11+
"POT-Creation-Date: 2024-10-11 13:36:18.474319\n"
1212
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313
"Last-Translator: Jonathan Thomas <[email protected]>\n"
1414
"Language-Team: https://translations.launchpad.net/+groups/launchpad-translators\n"
@@ -50,7 +50,7 @@ msgstr ""
5050
#: /home/jonathan/apps/openshot-qt/src/windows/export.py:91
5151
#: /home/jonathan/apps/openshot-qt/src/windows/export.py:889
5252
#: /home/jonathan/apps/openshot-qt/src/windows/export.py:900
53-
#: /home/jonathan/apps/openshot-qt/src/windows/export.py:1243 Settings for
53+
#: /home/jonathan/apps/openshot-qt/src/windows/export.py:1250 Settings for
5454
#: actionExportVideo
5555
#: /home/jonathan/apps/openshot-qt/src/windows/ui/export.ui:20
5656
msgid "Export Video"
@@ -78,7 +78,7 @@ msgstr ""
7878
#: /home/jonathan/apps/openshot-qt/src/windows/export.py:164
7979
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:660
8080
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:758
81-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2606
81+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2597
8282
#: /home/jonathan/apps/openshot-qt/src/classes/exporters/edl.py:56
8383
#: /home/jonathan/apps/openshot-qt/src/classes/exporters/final_cut_pro.py:90
8484
msgid "Untitled Project"
@@ -157,8 +157,8 @@ msgstr ""
157157

158158
#: /home/jonathan/apps/openshot-qt/src/windows/export.py:489
159159
#: /home/jonathan/apps/openshot-qt/src/windows/file_properties.py:161
160-
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:54
161-
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:68 libopenshot
160+
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:80
161+
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:94 libopenshot
162162
#: (Clip Properties)
163163
msgid "No"
164164
msgstr ""
@@ -228,7 +228,7 @@ msgid ""
228228
"%s"
229229
msgstr ""
230230

231-
#: /home/jonathan/apps/openshot-qt/src/windows/export.py:1244
231+
#: /home/jonathan/apps/openshot-qt/src/windows/export.py:1251
232232
msgid "Are you sure you want to cancel the export?"
233233
msgstr ""
234234

@@ -288,7 +288,7 @@ msgstr ""
288288

289289
#: /home/jonathan/apps/openshot-qt/src/windows/views/properties_tableview.py:700
290290
#: /home/jonathan/apps/openshot-qt/src/windows/views/timeline.py:149
291-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2185
291+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2176
292292
#: /home/jonathan/apps/openshot-qt/src/windows/models/properties_model.py:784
293293
#: /home/jonathan/apps/openshot-qt/src/windows/models/properties_model.py:873
294294
#: /home/jonathan/apps/openshot-qt/src/windows/add_to_timeline.py:480
@@ -972,23 +972,27 @@ msgstr ""
972972

973973
#: /home/jonathan/apps/openshot-qt/src/windows/views/files_listview.py:98
974974
#: /home/jonathan/apps/openshot-qt/src/windows/views/files_treeview.py:101
975-
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:50
975+
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:74
976976
#: /home/jonathan/apps/openshot-qt/src/windows/ui/profile-edit.ui:14
977977
msgid "Create Profile"
978978
msgstr ""
979979

980-
#: /home/jonathan/apps/openshot-qt/src/windows/views/profiles_treeview.py:90
981-
msgid "Edit"
980+
#: /home/jonathan/apps/openshot-qt/src/windows/views/profiles_treeview.py:99
981+
msgid "Set as Default Profile"
982982
msgstr ""
983983

984-
#: /home/jonathan/apps/openshot-qt/src/windows/views/profiles_treeview.py:94
984+
#: /home/jonathan/apps/openshot-qt/src/windows/views/profiles_treeview.py:105
985985
#: Settings for actionDuplicate
986986
#: /home/jonathan/apps/openshot-qt/src/windows/ui/main-window.ui:1554
987987
#: /home/jonathan/apps/openshot-qt/src/windows/ui/main-window.ui:1557
988988
msgid "Duplicate"
989989
msgstr ""
990990

991-
#: /home/jonathan/apps/openshot-qt/src/windows/views/profiles_treeview.py:100
991+
#: /home/jonathan/apps/openshot-qt/src/windows/views/profiles_treeview.py:113
992+
msgid "Edit"
993+
msgstr ""
994+
995+
#: /home/jonathan/apps/openshot-qt/src/windows/views/profiles_treeview.py:118
992996
msgid "Delete"
993997
msgstr ""
994998

@@ -1267,78 +1271,78 @@ msgstr ""
12671271
msgid "Enable Razor"
12681272
msgstr ""
12691273

1270-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:1768
1271-
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:156
1272-
msgid "Error"
1274+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:1773
1275+
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:181
1276+
msgid "Profile Error"
12731277
msgstr ""
12741278

1275-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:1768
1276-
msgid "You can not delete the current profile."
1279+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:1774
1280+
msgid "You can not delete the <b>current</b> or <b>default</b> profile."
12771281
msgstr ""
12781282

1279-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2116
1283+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2107
12801284
msgid "Error Removing Track"
12811285
msgstr ""
12821286

1283-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2116
1287+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2107
12841288
msgid "You must keep at least 1 track"
12851289
msgstr ""
12861290

1287-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2187
1291+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2178
12881292
#: /home/jonathan/apps/openshot-qt/src/windows/ui/main-window.ui:1440
12891293
#: /home/jonathan/apps/openshot-qt/src/windows/ui/main-window.ui:1443
12901294
msgid "Rename Track"
12911295
msgstr ""
12921296

1293-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2187
1297+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2178
12941298
msgid "Track Name:"
12951299
msgstr ""
12961300

1297-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2365
1301+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2356
12981302
msgid "Docks"
12991303
msgstr ""
13001304

1301-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2559
1305+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2550
13021306
msgid "Enter caption text..."
13031307
msgstr ""
13041308

1305-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2777
1309+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2768
13061310
msgid "Recent Projects"
13071311
msgstr ""
13081312

1309-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2786
1313+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2777
13101314
msgid "No Recent Projects"
13111315
msgstr ""
13121316

1313-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2842
1314-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2858
1315-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2876
1316-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2886
1317-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:3514
1317+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2833
1318+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2849
1319+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2867
1320+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2877
1321+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:3505
13181322
#: /home/jonathan/apps/openshot-qt/src/windows/ui/main-window.ui:432
13191323
msgid "Filter"
13201324
msgstr ""
13211325

1322-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2901
1326+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2892
13231327
msgid "Caption Toolbar"
13241328
msgstr ""
13251329

1326-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2973
1330+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2964
13271331
#: /home/jonathan/apps/openshot-qt/src/windows/ui/main-window.ui:1452
13281332
#: /home/jonathan/apps/openshot-qt/src/windows/ui/main-window.ui:1455
13291333
msgid "Update Available"
13301334
msgstr ""
13311335

1332-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2974
1336+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:2965
13331337
#, python-format
13341338
msgid "Update Available: <b>%s</b>"
13351339
msgstr ""
13361340

1337-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:3471
1341+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:3462
13381342
msgid "Error starting local HTTP server"
13391343
msgstr ""
13401344

1341-
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:3472
1345+
#: /home/jonathan/apps/openshot-qt/src/windows/main_window.py:3463
13421346
msgid "Failed multiple attempts to start server:"
13431347
msgstr ""
13441348

@@ -1559,9 +1563,9 @@ msgid "Unknown"
15591563
msgstr ""
15601564

15611565
#: /home/jonathan/apps/openshot-qt/src/windows/file_properties.py:160
1562-
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:53
1563-
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:68
1564-
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:133 libopenshot
1566+
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:79
1567+
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:94
1568+
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:159 libopenshot
15651569
#: (Clip Properties)
15661570
msgid "Yes"
15671571
msgstr ""
@@ -1722,12 +1726,12 @@ msgstr ""
17221726
msgid "OpenShot on GitHub"
17231727
msgstr ""
17241728

1725-
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:48
1726-
msgid "Duplicate Profile"
1729+
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:76
1730+
msgid "Edit Profile"
17271731
msgstr ""
17281732

1729-
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:156
1730-
msgid "Please enter a description for this profile."
1733+
#: /home/jonathan/apps/openshot-qt/src/windows/profile_edit.py:182
1734+
msgid "Please enter a <b>unique</b> description for this profile."
17311735
msgstr ""
17321736

17331737
#: /home/jonathan/apps/openshot-qt/src/classes/exporters/edl.py:59

src/windows/main_window.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -1753,6 +1753,13 @@ def initShortcuts(self):
17531753
# Log shortcut initialization completion
17541754
log.debug("Shortcuts initialized or updated.")
17551755

1756+
def actionProfileDefault_trigger(self, profile=None):
1757+
# Set default profile in settings
1758+
s = get_app().get_settings()
1759+
if profile:
1760+
s.set("default-profile", profile.info.description)
1761+
log.info(f"Setting default profile to '{profile.info.description}'")
1762+
17561763
def actionProfileEdit_trigger(self, profile=None, duplicate=False, delete=False, parent=None):
17571764
# Show profile edit dialog
17581765
from windows.profile_edit import EditProfileDialog
@@ -1763,9 +1770,12 @@ def actionProfileEdit_trigger(self, profile=None, duplicate=False, delete=False,
17631770

17641771
if profile and delete and parent:
17651772
# Delete profile (no dialog)
1773+
error_title = _("Profile Error")
1774+
error_message = _("You can not delete the <b>current</b> or <b>default</b> profile.")
17661775
if os.path.exists(profile.path):
1767-
if profile.info.description == get_app().project.get(['profile']):
1768-
QMessageBox.warning(parent, _("Error"), _("You can not delete the current profile."))
1776+
if (profile.info.description.strip() == get_app().project.get(['profile']).strip() or
1777+
profile.info.description.strip() == get_app().get_settings().get('default-profile').strip()):
1778+
QMessageBox.warning(parent, error_title, error_message)
17691779
return
17701780

17711781
log.info(f"Removing custom profile: {profile.path}")

src/windows/profile.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,7 @@ def __init__(self, initial_profile_desc=None):
108108
self.profile_list.append(profile)
109109

110110
except RuntimeError as e:
111-
# This exception occurs when there's a problem parsing
112-
# the Profile file - display a message and continue
113-
log.error("Failed to parse file '%s' as a profile: %s" % (profile_path, e))
111+
log.warning("Failed to parse file '%s' as a profile: %s" % (profile_path, e))
114112

115113
# Create treeview
116114
self.profileListView = ProfilesTreeView(self, self.profile_list)

src/windows/profile_edit.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,27 @@ def accept(self):
178178
_ = get_app()._tr
179179

180180
# Prevent saving with no description
181+
error_title = _("Profile Error")
182+
error_message = _("Please enter a <b>unique</b> description for this profile.")
181183
if not self.profile.info.description.strip():
182-
QMessageBox.warning(self, _("Error"), _("Please enter a description for this profile."))
184+
QMessageBox.warning(self, error_title, error_message)
183185
return
184186

187+
# Verify description is unique
188+
for profile_folder in [info.USER_PROFILES_PATH, info.PROFILES_PATH]:
189+
for file in reversed(sorted(os.listdir(profile_folder))):
190+
profile_verify_path = os.path.join(profile_folder, file)
191+
if os.path.isdir(profile_verify_path):
192+
continue
193+
try:
194+
# Load Profile
195+
p = openshot.Profile(profile_verify_path)
196+
if p.info.description.strip() == self.profile.info.description.strip():
197+
QMessageBox.warning(self, error_title, error_message)
198+
return
199+
except RuntimeError as e:
200+
log.warning("Failed to parse file '%s' as a profile: %s" % (profile_verify_path, e))
201+
185202
# Save the profile data as a text file in the user profiles folder
186203
profile_path = self.lblFilePathValue.text()
187204
log.info(f"Saving custom profile: {profile_path}")

src/windows/views/profiles_treeview.py

+15-6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"""
2727

2828
from PyQt5.QtCore import Qt, QItemSelectionModel, QRegExp, pyqtSignal, QTimer
29+
from PyQt5.QtGui import QIcon
2930
from PyQt5.QtWidgets import QListView, QTreeView, QAbstractItemView, QSizePolicy, QAction
3031

3132
from classes.app import get_app
@@ -95,19 +96,27 @@ def contextMenuEvent(self, event):
9596

9697
menu = StyledContextMenu(parent=self)
9798

98-
# Determine if the profile is user-created or not
99-
if hasattr(profile, 'user_created') and profile.user_created:
100-
edit_action = QAction(_("Edit"), self)
101-
edit_action.triggered.connect(lambda: get_app().window.actionProfileEdit_trigger(profile, duplicate=False, parent=self))
102-
menu.addAction(edit_action)
99+
default_action = QAction(_("Set as Default Profile"), self)
100+
default_action.setIcon(QIcon(":/icons/Humanity/actions/16/bookmark-new.svg"))
101+
default_action.triggered.connect(lambda: get_app().window.actionProfileDefault_trigger(profile))
102+
menu.addAction(default_action)
103+
menu.addSeparator()
103104

104105
duplicate_action = QAction(_("Duplicate"), self)
106+
duplicate_action.setIcon(QIcon(":/icons/Humanity/actions/16/edit-copy.svg"))
105107
duplicate_action.triggered.connect(lambda: get_app().window.actionProfileEdit_trigger(profile, duplicate=True, parent=self))
106108
menu.addAction(duplicate_action)
107-
menu.addSeparator()
108109

110+
# Determine if the profile is user-created or not
109111
if hasattr(profile, 'user_created') and profile.user_created:
112+
menu.addSeparator()
113+
edit_action = QAction(_("Edit"), self)
114+
edit_action.setIcon(QIcon(":/icons/Humanity/actions/16/gtk-edit.svg"))
115+
edit_action.triggered.connect(lambda: get_app().window.actionProfileEdit_trigger(profile, duplicate=False, parent=self))
116+
menu.addAction(edit_action)
117+
110118
delete_action = QAction(_("Delete"), self)
119+
delete_action.setIcon(QIcon(":/icons/Humanity/actions/16/edit-delete.svg"))
111120
delete_action.triggered.connect(lambda: get_app().window.actionProfileEdit_trigger(profile, delete=True, parent=self))
112121
menu.addAction(delete_action)
113122

0 commit comments

Comments
 (0)