diff --git a/tagstudio/resources/translations/en.json b/tagstudio/resources/translations/en.json
index 8b9542785..69e041b84 100644
--- a/tagstudio/resources/translations/en.json
+++ b/tagstudio/resources/translations/en.json
@@ -157,6 +157,9 @@
"macros.running.dialog.new_entries": "Running Configured Macros on {count}/{total} New File Entries...",
"macros.running.dialog.title": "Running Macros on New Entries",
"media_player.autoplay": "Autoplay",
+ "menu.delete_selected_files_ambiguous": "Move File(s) to {trash_term}",
+ "menu.delete_selected_files_plural": "Move Files to {trash_term}",
+ "menu.delete_selected_files_singular": "Move File to {trash_term}",
"menu.edit.ignore_list": "Ignore Files and Folders",
"menu.edit.manage_file_extensions": "Manage File Extensions",
"menu.edit.manage_tags": "Manage Tags",
@@ -195,6 +198,11 @@
"sorting.direction.ascending": "Ascending",
"sorting.direction.descending": "Descending",
"splash.opening_library": "Opening Library \"{library_path}\"...",
+ "status.deleted_file_plural": "Deleting {count} files!",
+ "status.deleted_file_singular": "Deleting 1 file!",
+ "status.deleted_none": "Deleting file [{i}/{count}]: \"{path}\"...",
+ "status.deleted_partial_warning": "Only deleted {count} file(s)! Check if any of the files are currently missing or in use.",
+ "status.deleting_file": "Deleting file [{i}/{count}]: \"{path}\"...",
"status.library_backup_in_progress": "Saving Library Backup...",
"status.library_backup_success": "Library Backup Saved at: \"{path}\" ({time_span})",
"status.library_closed": "Library Closed ({time_span})",
@@ -228,6 +236,18 @@
"tag.search_for_tag": "Search for Tag",
"tag.shorthand": "Shorthand",
"tag.tag_name_required": "Tag Name (Required)",
+ "trash.context.ambiguous": "Move file(s) to {trash_term}",
+ "trash.context.plural": "Move files to {trash_term}",
+ "trash.context.singular": "Move file to {trash_term}",
+ "trash.dialog.disambiguation_warning.plural": "This will remove them from TagStudio AND your file system!",
+ "trash.dialog.disambiguation_warning.singular": "This will remove it from TagStudio AND your file system!",
+ "trash.dialog.move.confirmation.plural": "Are you sure you want to move these {count} files to the {trash_term}?",
+ "trash.dialog.move.confirmation.singular": "Are you sure you want to move this file to the {trash_term}?",
+ "trash.dialog.permanent_delete_warning": "WARNING! If this file can't be moved to the {trash_term}, it will be permanently deleted!",
+ "trash.dialog.title.plural": "Delete Files",
+ "trash.dialog.title.singular": "Delete File",
+ "trash.name.recycle_bin": "Recycle Bin",
+ "trash.name.trash": "Trash",
"view.size.0": "Mini",
"view.size.1": "Small",
"view.size.2": "Medium",
diff --git a/tagstudio/src/qt/helpers/file_deleter.py b/tagstudio/src/qt/helpers/file_deleter.py
index 4a94e6be5..a8e50e17c 100644
--- a/tagstudio/src/qt/helpers/file_deleter.py
+++ b/tagstudio/src/qt/helpers/file_deleter.py
@@ -11,7 +11,7 @@
def delete_file(path: str | Path) -> bool:
- """Sends a file to the system trash.
+ """Send a file to the system trash.
Args:
path (str | Path): The path of the file to delete.
diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py
index 84674f54b..3d5348fa7 100644
--- a/tagstudio/src/qt/ts_qt.py
+++ b/tagstudio/src/qt/ts_qt.py
@@ -488,9 +488,17 @@ def start(self) -> None:
edit_menu.addSeparator()
- self.delete_file_action = QAction("Delete Selected File(s)", menu_bar)
+ self.delete_file_action = QAction(menu_bar)
+ trash_term: str = Translations["trash.name.trash"]
+ if platform.system() == "Windows":
+ trash_term = Translations["trash.name.recycle_bin"]
+
+ Translations.translate_qobject(
+ self.delete_file_action, "menu.delete_selected_files_ambiguous", trash_term=trash_term
+ )
self.delete_file_action.triggered.connect(lambda f="": self.delete_files_callback(f))
self.delete_file_action.setShortcut(QtCore.Qt.Key.Key_Delete)
+ self.delete_file_action.setEnabled(False)
edit_menu.addAction(self.delete_file_action)
edit_menu.addSeparator()
@@ -816,10 +824,13 @@ def close_library(self, is_shutdown: bool = False):
self.main_window.setWindowTitle(self.base_title)
- self.selected = []
- self.frame_content = []
+ self.selected.clear()
+ self.frame_content.clear()
[x.set_mode(None) for x in self.item_thumbs]
+ self.set_clipboard_menu_viability()
+ self.set_add_to_selected_visibility()
+
self.preview_panel.update_widgets()
self.main_window.toggle_landing_page(enabled=True)
self.main_window.pagination.setHidden(True)
@@ -955,7 +966,9 @@ def delete_files_callback(self, origin_path: str | Path, origin_id: int | None =
self.preview_panel.thumb.stop_file_use()
if delete_file(self.lib.library_dir / f):
self.main_window.statusbar.showMessage(
- f'Deleting file [{i}/{len(pending)}]: "{f}"...'
+ Translations.translate_formatted(
+ "status.deleting_file", i=i, count=len(pending), path=f
+ )
)
self.main_window.statusbar.repaint()
self.lib.remove_entries([e_id])
@@ -968,18 +981,23 @@ def delete_files_callback(self, origin_path: str | Path, origin_id: int | None =
self.preview_panel.update_widgets()
if len(self.selected) <= 1 and deleted_count == 0:
- self.main_window.statusbar.showMessage("No files deleted.")
+ self.main_window.statusbar.showMessage(Translations["status.deleted_none"])
elif len(self.selected) <= 1 and deleted_count == 1:
- self.main_window.statusbar.showMessage(f"Deleted {deleted_count} file!")
+ self.main_window.statusbar.showMessage(
+ Translations.translate_formatted("status.deleted_file_plural", count=deleted_count)
+ )
elif len(self.selected) > 1 and deleted_count == 0:
- self.main_window.statusbar.showMessage("No files deleted.")
+ self.main_window.statusbar.showMessage(Translations["status.deleted_none"])
elif len(self.selected) > 1 and deleted_count < len(self.selected):
self.main_window.statusbar.showMessage(
- f"Only deleted {deleted_count} file{'' if deleted_count == 1 else 's'}! "
- f"Check if any of the files are currently missing or in use."
+ Translations.translate_formatted(
+ "status.deleted_partial_warning", count=deleted_count
+ )
)
elif len(self.selected) > 1 and deleted_count == len(self.selected):
- self.main_window.statusbar.showMessage(f"Deleted {deleted_count} files!")
+ self.main_window.statusbar.showMessage(
+ Translations.translate_formatted("status.deleted_file_plural", count=deleted_count)
+ )
self.main_window.statusbar.repaint()
def delete_file_confirmation(self, count: int, filename: Path | None = None) -> int:
@@ -989,36 +1007,50 @@ def delete_file_confirmation(self, count: int, filename: Path | None = None) ->
count(int): The number of files to be deleted.
filename(Path | None): The filename to show if only one file is to be deleted.
"""
- trash_term: str = "Trash"
- if platform.system == "Windows":
- trash_term = "Recycle Bin"
+ trash_term: str = Translations["trash.name.trash"]
+ if platform.system() == "Windows":
+ trash_term = Translations["trash.name.recycle_bin"]
# NOTE: Windows + send2trash will PERMANENTLY delete files which cannot be moved to the
# Recycle Bin. This is done without any warning, so this message is currently the
# best way I've got to inform the user.
# https://github.com/arsenetar/send2trash/issues/28
# This warning is applied to all platforms until at least macOS and Linux can be verified
# to not exhibit this same behavior.
+ perm_warning_msg = Translations.translate_formatted(
+ "trash.dialog.permanent_delete_warning",
+ trash_term=trash_term,
+ )
perm_warning: str = (
f""
- f"WARNING! If this file can't be moved to the {trash_term}, "
- f"
it will be permanently deleted!"
+ f"{perm_warning_msg}"
)
msg = QMessageBox()
+ msg.setStyleSheet("font-weight:normal;")
msg.setTextFormat(Qt.TextFormat.RichText)
- msg.setWindowTitle("Delete File" if count == 1 else "Delete Files")
+ msg.setWindowTitle(
+ Translations["trash.title.singular"]
+ if count == 1
+ else Translations["trash.title.plural"]
+ )
msg.setIcon(QMessageBox.Icon.Warning)
if count <= 1:
+ msg_text = Translations.translate_formatted(
+ "trash.dialog.move.confirmation.singular", trash_term=trash_term
+ )
msg.setText(
- f"