mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-02-01 15:49:09 +00:00
feat: translate modals
This commit is contained in:
@@ -3,27 +3,31 @@
|
||||
"app.pre_release": "Pre-Release",
|
||||
"app.title": "{base_title} - Library '{library_dir}'",
|
||||
"edit.tag_manager": "Manage Tags",
|
||||
"entries.duplicate.merge.label": "Merging Duplicate Entries",
|
||||
"entries.duplicate.merge.label": "Merging Duplicate Entries...",
|
||||
"entries.duplicate.merge": "Merge Duplicate Entries",
|
||||
"entries.duplicate.refresh": "Refresh Duplicate Entries",
|
||||
"entries.duplicates.description": "Duplicate entries are defined as multiple entries which point to the same file on disk. Merging these will combine the tags and metadata from all duplicates into a single consolidated entry. These are not to be confused with \"duplicate files\", which are duplicates of your files themselves outside of TagStudio.",
|
||||
"entries.mirror.confirmation": "Are you sure you want to mirror the following %{len(self.lib.dupe_files)} Entries?",
|
||||
"entries.mirror.label": "Mirroring 1/%{count} Entries...",
|
||||
"entries.mirror.confirmation": "Are you sure you want to mirror the following {count} Entries?",
|
||||
"entries.mirror.label": "Mirroring {idx}/{total} Entries...",
|
||||
"entries.mirror.title": "Mirroring Entries",
|
||||
"entries.mirror": "Mirror",
|
||||
"entries.mirror.window_title": "Mirror Entries",
|
||||
"entries.mirror": "&Mirror",
|
||||
"entries.tags": "Tags",
|
||||
"entries.unlinked.delete.confirm": "Are you sure you want to delete the following %{len(self.lib.missing_files)} entries?",
|
||||
"entries.unlinked.delete.deleting_count": "Deleting %{x[0]+1}/{len(self.lib.missing_files)} Unlinked Entries",
|
||||
"entries.unlinked.delete.confirm": "Are you sure you want to delete the following {count} entries?",
|
||||
"entries.unlinked.delete.deleting_count": "Deleting {idx}/{count} Unlinked Entries",
|
||||
"entries.unlinked.delete.deleting": "Deleting Entries",
|
||||
"entries.unlinked.delete": "Delete Unlinked Entries",
|
||||
"entries.unlinked.delete_alt": "De&lete Unlinked Entries",
|
||||
"entries.unlinked.description": "Each library entry is linked to a file in one of your directories. If a file linked to an entry is moved or deleted outside of TagStudio, it is then considered unlinked. Unlinked entries may be automatically relinked via searching your directories or deleted if desired.",
|
||||
"entries.unlinked.refresh_all": "Refresh All",
|
||||
"entries.unlinked.relink.attempting": "Attempting to Relink %{x[0]+1}/%{len(self.lib.missing_files)} Entries, %{self.fixed} Successfully Relinked",
|
||||
"entries.unlinked.relink.manual": "Manual Relink",
|
||||
"entries.unlinked.refresh_all": "&Refresh All",
|
||||
"entries.unlinked.relink.attempting": "Attempting to Relink {idx}/{missing_count} Entries, {fixed_count} Successfully Relinked",
|
||||
"entries.unlinked.relink.manual": "&Manual Relink",
|
||||
"entries.unlinked.relink.title": "Relinking Entries",
|
||||
"entries.unlinked.scanning": "Scanning Library for Unlinked Entries...",
|
||||
"entries.unlinked.search_and_relink": "Search && Relink",
|
||||
"entries.unlinked.search_and_relink": "&Search && Relink",
|
||||
"entries.unlinked.title": "Fix Unlinked Entries",
|
||||
"entries.unlinked.missing_count.none": "Unlinked Entries: N/A",
|
||||
"entries.unlinked.missing_count.some": "Unlinked Entries: {count}",
|
||||
"field.copy": "Copy Field",
|
||||
"field.edit": "Edit Field",
|
||||
"field.paste": "Paste Field",
|
||||
@@ -31,15 +35,16 @@
|
||||
"file.date_created": "Date Created",
|
||||
"file.date_modified": "Date Modified",
|
||||
"file.dimensions": "Dimensions",
|
||||
"file.duplicates.description": "TagStudio supports importing DupeGuru results to manage duplicate files.",
|
||||
"file.duplicates.dupeguru.advice": "After mirroring, you're free to use DupeGuru to delete the unwanted files. Afterwards, use TagStudio's \"Fix Unlinked Entries\" feature in the Tools menu in order to delete the unlinked Entries.",
|
||||
"file.duplicates.dupeguru.file_extension": "DupeGuru Files (*.dupeguru)",
|
||||
"file.duplicates.dupeguru.load_file": "Load DupeGuru File",
|
||||
"file.duplicates.dupeguru.load_file": "&Load DupeGuru File",
|
||||
"file.duplicates.dupeguru.no_file": "No DupeGuru File Selected",
|
||||
"file.duplicates.dupeguru.open_file": "Open DupeGuru Results File",
|
||||
"file.duplicates.fix": "Fix Duplicate Files",
|
||||
"file.duplicates.matches_uninitialized": "Duplicate File Matches: N/A",
|
||||
"file.duplicates.matches": "Duplicate File Matches: %{count}",
|
||||
"file.duplicates.mirror_entries": "Mirror Entries",
|
||||
"file.duplicates.matches": "Duplicate File Matches: {count}",
|
||||
"file.duplicates.mirror_entries": "&Mirror Entries",
|
||||
"file.duplicates.mirror.description": "Mirror the Entry data across each duplicate match set, combining all data while not removing or duplicating fields. This operation will not delete any files or data.",
|
||||
"file.duration": "Length",
|
||||
"file.not_found": "File Not Found",
|
||||
@@ -55,12 +60,23 @@
|
||||
"folders_to_tags.title": "Create Tags From Folders",
|
||||
"generic.add": "Add",
|
||||
"generic.apply": "Apply",
|
||||
"generic.apply_alt": "&Apply",
|
||||
"generic.cancel": "Cancel",
|
||||
"generic.cancel_alt": "&Cancel",
|
||||
"generic.close": "Close",
|
||||
"generic.copy": "Copy",
|
||||
"generic.cut": "Cut",
|
||||
"generic.delete": "Delete",
|
||||
"generic.delete_alt": "&Delete",
|
||||
"generic.done": "Done",
|
||||
"generic.done_alt": "&Done",
|
||||
"generic.edit": "Edit",
|
||||
"generic.rename": "Rename",
|
||||
"generic.rename_alt": "&Rename",
|
||||
"generic.overwrite": "Overwrite",
|
||||
"generic.overwrite_alt": "&Overwrite",
|
||||
"generic.skip": "Skip",
|
||||
"generic.skip_alt": "&Skip",
|
||||
"generic.navigation.back": "Back",
|
||||
"generic.navigation.next": "Next",
|
||||
"generic.paste": "Paste",
|
||||
@@ -76,10 +92,10 @@
|
||||
"home.thumbnail_size.small": "Small Thumbnails",
|
||||
"home.thumbnail_size.mini": "Mini Thumbnails",
|
||||
"home.thumbnail_size": "Thumbnail Size",
|
||||
"ignore_list.add_extension": "Add Extension",
|
||||
"ignore_list.add_extension": "&Add Extension",
|
||||
"ignore_list.mode.exclude": "Exclude",
|
||||
"ignore_list.mode.include": "Include",
|
||||
"ignore_list.mode.label": "List Mode",
|
||||
"ignore_list.mode.label": "List Mode:",
|
||||
"ignore_list.title": "File Extensions",
|
||||
"library.field.add": "Add Field",
|
||||
"library.field.confirm_remove": "Are you sure you want to remove this \"%{self.lib.get_field_attr(field, \"name\")}\" field?",
|
||||
@@ -134,7 +150,10 @@
|
||||
"status.results": "Results",
|
||||
"tag_manager.title": "Library Tags",
|
||||
"tag.add_to_search": "Add to Search",
|
||||
"tag.edit": "Edit Tag",
|
||||
"tag.add": "Add Tag",
|
||||
"tag.create": "Create Tag",
|
||||
"tag.remove": "Remove Tag",
|
||||
"tag.aliases": "Aliases",
|
||||
"tag.color": "Color",
|
||||
"tag.name": "Name",
|
||||
@@ -144,13 +163,23 @@
|
||||
"tag.parent_tags": "Parent Tags",
|
||||
"tag.search_for_tag": "Search for Tag",
|
||||
"tag.shorthand": "Shorthand",
|
||||
"tag.remove_alias": "Remove selected alias",
|
||||
"tag.tag_name_required": "Tag Name (Required)",
|
||||
"view.size.0": "Mini",
|
||||
"view.size.1": "Small",
|
||||
"view.size.2": "Medium",
|
||||
"view.size.3": "Large",
|
||||
"view.size.4": "Extra Large",
|
||||
"window.button.close": "Close",
|
||||
"window.title.error": "Error",
|
||||
"window.title.open_create_library": "Open/Create Library",
|
||||
"window.message.error_opening_library": "Error opening library."
|
||||
"window.message.error_opening_library": "Error opening library.",
|
||||
"tag_database.confirmation": "Are you sure you want to delete the tag \"{tag_name}\"?",
|
||||
"drop_import.title": "Conflicting File(s)",
|
||||
"drop_import.decription": "The following files have filenames already exist in the library",
|
||||
"drop_import.progress.label.initial": "Importing New Files...",
|
||||
"drop_import.progress.label.singular": "Importing New Files...\n1 File imported.{suffix}",
|
||||
"drop_import.progress.label.plural": "Importing New Files...\n{count} Files Imported.{suffix}",
|
||||
"drop_import.progress.window_title": "Import Files",
|
||||
"drop_import.duplicates_choice.singular": "The following file has a filename that already exists in the library.",
|
||||
"drop_import.duplicates_choice.plural": "The following {count} files have filenames that already exist in the library.",
|
||||
}
|
||||
@@ -15,6 +15,8 @@ from PySide6.QtWidgets import (
|
||||
)
|
||||
from src.core.library import Library
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
|
||||
class AddFieldModal(QWidget):
|
||||
done = Signal(list)
|
||||
@@ -26,7 +28,7 @@ class AddFieldModal(QWidget):
|
||||
super().__init__()
|
||||
self.is_connected = False
|
||||
self.lib = library
|
||||
self.setWindowTitle("Add Field") # TODO translate
|
||||
Translations.translate_with_setter(self.setWindowTitle, "library.field.add")
|
||||
self.setWindowModality(Qt.WindowModality.ApplicationModal)
|
||||
self.setMinimumSize(400, 300)
|
||||
self.root_layout = QVBoxLayout(self)
|
||||
@@ -40,7 +42,7 @@ class AddFieldModal(QWidget):
|
||||
# 'text-align:center;'
|
||||
"font-weight:bold;" "font-size:14px;" "padding-top: 6px" ""
|
||||
)
|
||||
self.title_widget.setText("Add Field") # TODO translate
|
||||
Translations.translate_qobject(self.title_widget, "library.field.add")
|
||||
self.title_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.list_widget = QListWidget()
|
||||
@@ -54,13 +56,13 @@ class AddFieldModal(QWidget):
|
||||
# self.cancel_button.setText('Cancel')
|
||||
|
||||
self.cancel_button = QPushButton()
|
||||
self.cancel_button.setText("Cancel") # TODO translate
|
||||
Translations.translate_qobject(self.cancel_button, "generic.cancel")
|
||||
self.cancel_button.clicked.connect(self.hide)
|
||||
# self.cancel_button.clicked.connect(widget.reset)
|
||||
self.button_layout.addWidget(self.cancel_button)
|
||||
|
||||
self.save_button = QPushButton()
|
||||
self.save_button.setText("Add") # TODO translate
|
||||
Translations.translate_qobject(self.save_button, "generic.add")
|
||||
# self.save_button.setAutoDefault(True)
|
||||
self.save_button.setDefault(True)
|
||||
self.save_button.clicked.connect(self.hide)
|
||||
|
||||
@@ -29,6 +29,8 @@ from src.qt.modals.tag_search import TagSearchPanel
|
||||
from src.qt.widgets.panel import PanelModal, PanelWidget
|
||||
from src.qt.widgets.tag import TagAliasWidget, TagWidget
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
@@ -54,12 +56,14 @@ class BuildTagPanel(PanelWidget):
|
||||
self.name_layout.setSpacing(0)
|
||||
self.name_layout.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
||||
self.name_title = QLabel()
|
||||
self.name_title.setText("Name")
|
||||
Translations.translate_qobject(self.name_title, "tag.name")
|
||||
self.name_layout.addWidget(self.name_title)
|
||||
self.name_field = QLineEdit()
|
||||
self.name_field.setFixedHeight(24)
|
||||
self.name_field.textChanged.connect(self.on_name_changed)
|
||||
self.name_field.setPlaceholderText("Tag Name (Required)") # TODO translate
|
||||
Translations.translate_with_setter(
|
||||
self.name_field.setPlaceholderText, "tag.tag_name_required"
|
||||
)
|
||||
self.name_layout.addWidget(self.name_field)
|
||||
|
||||
# Shorthand ------------------------------------------------------------
|
||||
@@ -70,7 +74,7 @@ class BuildTagPanel(PanelWidget):
|
||||
self.shorthand_layout.setSpacing(0)
|
||||
self.shorthand_layout.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
||||
self.shorthand_title = QLabel()
|
||||
self.shorthand_title.setText("Shorthand") # TODO translate
|
||||
Translations.translate_qobject(self.shorthand_title, "tag.shorthand")
|
||||
self.shorthand_layout.addWidget(self.shorthand_title)
|
||||
self.shorthand_field = QLineEdit()
|
||||
self.shorthand_layout.addWidget(self.shorthand_field)
|
||||
@@ -83,7 +87,7 @@ class BuildTagPanel(PanelWidget):
|
||||
self.aliases_layout.setSpacing(0)
|
||||
self.aliases_layout.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
||||
self.aliases_title = QLabel()
|
||||
self.aliases_title.setText("Aliases") # TODO translate
|
||||
Translations.translate_qobject(self.aliases_title, "tag.aliases")
|
||||
self.aliases_layout.addWidget(self.aliases_title)
|
||||
|
||||
self.aliases_flow_widget = QWidget()
|
||||
@@ -134,7 +138,7 @@ class BuildTagPanel(PanelWidget):
|
||||
self.subtags_layout.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
||||
|
||||
self.subtags_title = QLabel()
|
||||
self.subtags_title.setText("Parent Tags") # TODO translate
|
||||
Translations.translate_qobject(self.subtags_title, "tag.parent_tags")
|
||||
self.subtags_layout.addWidget(self.subtags_title)
|
||||
|
||||
self.subtag_flow_widget = QWidget()
|
||||
@@ -180,7 +184,9 @@ class BuildTagPanel(PanelWidget):
|
||||
|
||||
tsp = TagSearchPanel(self.lib, exclude_ids)
|
||||
tsp.tag_chosen.connect(lambda x: self.add_subtag_callback(x))
|
||||
self.add_tag_modal = PanelModal(tsp, "Add Parent Tags", "Add Parent Tags") # TODO translate
|
||||
self.add_tag_modal = PanelModal(tsp)
|
||||
Translations.translate_with_setter(self.add_tag_modal.setTitle, "tag.parent_tags.add")
|
||||
Translations.translate_with_setter(self.add_tag_modal.setWindowTitle, "tag.parent_tags.add")
|
||||
self.subtags_add_button.clicked.connect(self.add_tag_modal.show)
|
||||
# self.subtags_layout.addWidget(self.subtags_add_button)
|
||||
|
||||
@@ -196,7 +202,7 @@ class BuildTagPanel(PanelWidget):
|
||||
self.color_layout.setSpacing(0)
|
||||
self.color_layout.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
||||
self.color_title = QLabel()
|
||||
self.color_title.setText("Color") # TODO translate
|
||||
Translations.translate_qobject(self.color_title, "tag.color")
|
||||
self.color_layout.addWidget(self.color_title)
|
||||
self.color_field = QComboBox()
|
||||
self.color_field.setEditable(False)
|
||||
@@ -218,7 +224,8 @@ class BuildTagPanel(PanelWidget):
|
||||
)
|
||||
)
|
||||
self.color_layout.addWidget(self.color_field)
|
||||
remove_selected_alias_action = QAction("remove selected alias", self) # TODO translate
|
||||
remove_selected_alias_action = QAction(self)
|
||||
Translations.translate_qobject(remove_selected_alias_action, "tag.remove_alias")
|
||||
remove_selected_alias_action.triggered.connect(self.remove_selected_alias)
|
||||
remove_selected_alias_action.setShortcut(
|
||||
QtCore.QKeyCombination(
|
||||
@@ -243,7 +250,7 @@ class BuildTagPanel(PanelWidget):
|
||||
self.alias_names: set[str] = set()
|
||||
self.new_alias_names: dict = dict()
|
||||
|
||||
self.set_tag(tag or Tag(name="New Tag")) # TODO translate
|
||||
self.set_tag(tag or Tag(name=Translations["tag.new"]))
|
||||
if tag is None:
|
||||
self.name_field.selectAll()
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ from PySide6.QtWidgets import (
|
||||
from src.core.utils.missing_files import MissingRegistry
|
||||
from src.qt.widgets.progress import ProgressWidget
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
# Only import for type checking/autocompletion, will not be imported at runtime.
|
||||
if typing.TYPE_CHECKING:
|
||||
from src.qt.ts_qt import QtDriver
|
||||
@@ -29,7 +31,7 @@ class DeleteUnlinkedEntriesModal(QWidget):
|
||||
super().__init__()
|
||||
self.driver = driver
|
||||
self.tracker = tracker
|
||||
self.setWindowTitle("Delete Unlinked Entries") # TODO translate
|
||||
Translations.translate_with_setter(self.setWindowTitle, "entries.unlinked.delete")
|
||||
self.setWindowModality(Qt.WindowModality.ApplicationModal)
|
||||
self.setMinimumSize(500, 400)
|
||||
self.root_layout = QVBoxLayout(self)
|
||||
@@ -38,9 +40,11 @@ class DeleteUnlinkedEntriesModal(QWidget):
|
||||
self.desc_widget = QLabel()
|
||||
self.desc_widget.setObjectName("descriptionLabel")
|
||||
self.desc_widget.setWordWrap(True)
|
||||
self.desc_widget.setText(f"""
|
||||
Are you sure you want to delete the following {self.tracker.missing_files_count} entries?
|
||||
""") # TODO translate
|
||||
Translations.translate_qobject(
|
||||
self.desc_widget,
|
||||
"entries.unlinked.delete.confirm",
|
||||
count=self.tracker.missing_files_count,
|
||||
)
|
||||
self.desc_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.list_view = QListView()
|
||||
@@ -53,13 +57,13 @@ class DeleteUnlinkedEntriesModal(QWidget):
|
||||
self.button_layout.addStretch(1)
|
||||
|
||||
self.cancel_button = QPushButton()
|
||||
self.cancel_button.setText("&Cancel") # TODO translate
|
||||
Translations.translate_qobject(self.cancel_button, "generic.cancel_alt")
|
||||
self.cancel_button.setDefault(True)
|
||||
self.cancel_button.clicked.connect(self.hide)
|
||||
self.button_layout.addWidget(self.cancel_button)
|
||||
|
||||
self.delete_button = QPushButton()
|
||||
self.delete_button.setText("&Delete") # TODO translate
|
||||
Translations.translate_qobject(self.delete_button, "generic.delete_alt")
|
||||
self.delete_button.clicked.connect(self.hide)
|
||||
self.delete_button.clicked.connect(lambda: self.delete_entries())
|
||||
self.button_layout.addWidget(self.delete_button)
|
||||
@@ -69,9 +73,11 @@ class DeleteUnlinkedEntriesModal(QWidget):
|
||||
self.root_layout.addWidget(self.button_container)
|
||||
|
||||
def refresh_list(self):
|
||||
self.desc_widget.setText(f"""
|
||||
Are you sure you want to delete the following {self.tracker.missing_files_count} entries?
|
||||
""") # TODO translate
|
||||
self.desc_widget.setText(
|
||||
Translations.translate_formatted(
|
||||
"entries.unlinked.delete.confirm", count=self.tracker.missing_files_count
|
||||
)
|
||||
)
|
||||
|
||||
self.model.clear()
|
||||
for i in self.tracker.missing_files:
|
||||
@@ -81,14 +87,17 @@ class DeleteUnlinkedEntriesModal(QWidget):
|
||||
|
||||
def delete_entries(self):
|
||||
def displayed_text(x):
|
||||
return f"Deleting {x}/{self.tracker.missing_files_count} Unlinked Entries" # TODO translate
|
||||
return Translations.translate_formatted(
|
||||
"entries.unlinked.delete.deleting_count",
|
||||
idx=x,
|
||||
count=self.tracker.missing_files_count,
|
||||
)
|
||||
|
||||
pw = ProgressWidget(
|
||||
window_title="Deleting Entries", # TODO translate
|
||||
label_text="",
|
||||
cancel_button_text=None,
|
||||
minimum=0,
|
||||
maximum=self.tracker.missing_files_count,
|
||||
)
|
||||
Translations.translate_with_setter(pw.setWindowTitle, "entries.unlinked.delete.deleting")
|
||||
|
||||
pw.from_iterable_function(self.tracker.execute_deletion, displayed_text, self.done.emit)
|
||||
|
||||
@@ -19,6 +19,8 @@ from PySide6.QtWidgets import (
|
||||
)
|
||||
from src.qt.widgets.progress import ProgressWidget
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.qt.ts_qt import QtDriver
|
||||
|
||||
@@ -41,7 +43,7 @@ class DropImportModal(QWidget):
|
||||
self.driver: QtDriver = driver
|
||||
|
||||
# Widget ======================
|
||||
self.setWindowTitle("Conflicting File(s)") # TODO translate
|
||||
Translations.translate_with_setter(self.setWindowTitle, "drop_import.title")
|
||||
self.setWindowModality(Qt.WindowModality.ApplicationModal)
|
||||
self.setMinimumSize(500, 400)
|
||||
self.root_layout = QVBoxLayout(self)
|
||||
@@ -50,9 +52,7 @@ class DropImportModal(QWidget):
|
||||
self.desc_widget = QLabel()
|
||||
self.desc_widget.setObjectName("descriptionLabel")
|
||||
self.desc_widget.setWordWrap(True)
|
||||
self.desc_widget.setText(
|
||||
"The following files have filenames already exist in the library"
|
||||
) # TODO translate
|
||||
self.desc_widget.setText(Translations["drop_import.decription"])
|
||||
self.desc_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
# Duplicate File List ========
|
||||
@@ -67,25 +67,25 @@ class DropImportModal(QWidget):
|
||||
self.button_layout.addStretch(1)
|
||||
|
||||
self.skip_button = QPushButton()
|
||||
self.skip_button.setText("&Skip") # TODO translate
|
||||
Translations.translate_qobject(self.skip_button, "generic.skip_alt")
|
||||
self.skip_button.setDefault(True)
|
||||
self.skip_button.clicked.connect(lambda: self.begin_transfer(DuplicateChoice.SKIP))
|
||||
self.button_layout.addWidget(self.skip_button)
|
||||
|
||||
self.overwrite_button = QPushButton()
|
||||
self.overwrite_button.setText("&Overwrite") # TODO translate
|
||||
Translations.translate_qobject(self.overwrite_button, "generic.overwrite_alt")
|
||||
self.overwrite_button.clicked.connect(
|
||||
lambda: self.begin_transfer(DuplicateChoice.OVERWRITE)
|
||||
)
|
||||
self.button_layout.addWidget(self.overwrite_button)
|
||||
|
||||
self.rename_button = QPushButton()
|
||||
self.rename_button.setText("&Rename") # TODO translate
|
||||
Translations.translate_qobject(self.rename_button, "generic.rename_alt")
|
||||
self.rename_button.clicked.connect(lambda: self.begin_transfer(DuplicateChoice.RENAME))
|
||||
self.button_layout.addWidget(self.rename_button)
|
||||
|
||||
self.cancel_button = QPushButton()
|
||||
self.cancel_button.setText("&Cancel") # TODO translate
|
||||
Translations.translate_qobject(self.cancel_button, "generic.cancel_alt")
|
||||
self.cancel_button.clicked.connect(lambda: self.begin_transfer(DuplicateChoice.CANCEL))
|
||||
self.button_layout.addWidget(self.cancel_button)
|
||||
|
||||
@@ -139,8 +139,12 @@ class DropImportModal(QWidget):
|
||||
def ask_duplicates_choice(self):
|
||||
"""Display the message widgeth with a list of the duplicated files."""
|
||||
self.desc_widget.setText(
|
||||
f"The following {len(self.duplicate_files)} file(s) have filenames already exist in the library." # noqa: E501
|
||||
) # TODO translate
|
||||
Translations["drop_import.duplicates_choice.singular"]
|
||||
if len(self.duplicate_files) == 1
|
||||
else Translations.translate_formatted(
|
||||
"drop_import.duplicates_choice.plural", count=len(self.duplicate_files)
|
||||
)
|
||||
)
|
||||
|
||||
self.model.clear()
|
||||
for dupe in self.duplicate_files:
|
||||
@@ -160,19 +164,21 @@ class DropImportModal(QWidget):
|
||||
return
|
||||
|
||||
def displayed_text(x):
|
||||
text = f"Importing New Files...\n{x[0] + 1} File{'s' if x[0] + 1 != 1 else ''} Imported." # TODO translate
|
||||
if self.choice:
|
||||
text += f" {x[1]} {self.choice.value}"
|
||||
|
||||
return text
|
||||
return Translations.translate_formatted(
|
||||
"drop_import.progress.label.singular"
|
||||
if x[0] + 1 == 1
|
||||
else "drop_import.progress.label.plural",
|
||||
count=x[0] + 1,
|
||||
suffix=f" {x[1]} {self.choice.value}" if self.choice else "",
|
||||
)
|
||||
|
||||
pw = ProgressWidget(
|
||||
window_title="Import Files", # TODO translate
|
||||
label_text="Importing New Files...", # TODO translate
|
||||
cancel_button_text=None,
|
||||
minimum=0,
|
||||
maximum=len(self.files),
|
||||
)
|
||||
Translations.translate_with_setter(pw.setWindowTitle, "drop_import.progress.window_title")
|
||||
Translations.translate_with_setter(pw.update_label, "drop_import.progress.label.initial")
|
||||
|
||||
pw.from_iterable_function(
|
||||
self.copy_files,
|
||||
|
||||
@@ -20,6 +20,8 @@ from src.core.enums import LibraryPrefs
|
||||
from src.core.library import Library
|
||||
from src.qt.widgets.panel import PanelWidget
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
|
||||
class FileExtensionItemDelegate(QStyledItemDelegate):
|
||||
def setModelData(self, editor, model, index): # noqa: N802
|
||||
@@ -35,7 +37,7 @@ class FileExtensionModal(PanelWidget):
|
||||
super().__init__()
|
||||
# Initialize Modal =====================================================
|
||||
self.lib = library
|
||||
self.setWindowTitle("File Extensions") # TODO translate
|
||||
Translations.translate_with_setter(self.setWindowTitle, "ignore_list.title")
|
||||
self.setWindowModality(Qt.WindowModality.ApplicationModal)
|
||||
self.setMinimumSize(240, 400)
|
||||
self.root_layout = QVBoxLayout(self)
|
||||
@@ -50,7 +52,7 @@ class FileExtensionModal(PanelWidget):
|
||||
|
||||
# Create "Add Button" Widget -------------------------------------------
|
||||
self.add_button = QPushButton()
|
||||
self.add_button.setText("&Add Extension") # TODO translate
|
||||
Translations.translate_qobject(self.add_button, "ignore_list.add_extension")
|
||||
self.add_button.clicked.connect(self.add_item)
|
||||
self.add_button.setDefault(True)
|
||||
self.add_button.setMinimumWidth(100)
|
||||
@@ -61,11 +63,17 @@ class FileExtensionModal(PanelWidget):
|
||||
self.mode_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.mode_layout.setSpacing(12)
|
||||
self.mode_label = QLabel()
|
||||
self.mode_label.setText("List Mode:") # TODO translate
|
||||
Translations.translate_qobject(self.mode_label, "ignore_list.mode.label")
|
||||
self.mode_combobox = QComboBox()
|
||||
self.mode_combobox.setEditable(False)
|
||||
self.mode_combobox.addItem("Include") # TODO translate
|
||||
self.mode_combobox.addItem("Exclude") # TODO translate
|
||||
self.mode_combobox.addItem("")
|
||||
self.mode_combobox.addItem("")
|
||||
Translations.translate_with_setter(
|
||||
lambda text: self.mode_combobox.setItemText(0, text), "ignore_list.mode.include"
|
||||
)
|
||||
Translations.translate_with_setter(
|
||||
lambda text: self.mode_combobox.setItemText(0, text), "ignore_list.mode.exclude"
|
||||
)
|
||||
|
||||
is_exclude_list = int(bool(self.lib.prefs(LibraryPrefs.IS_EXCLUDE_LIST)))
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ from src.core.library import Library
|
||||
from src.core.utils.dupe_files import DupeRegistry
|
||||
from src.qt.modals.mirror_entities import MirrorEntriesModal
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
# Only import for type checking/autocompletion, will not be imported at runtime.
|
||||
if typing.TYPE_CHECKING:
|
||||
from src.qt.ts_qt import QtDriver
|
||||
@@ -30,7 +32,7 @@ class FixDupeFilesModal(QWidget):
|
||||
self.driver = driver
|
||||
self.count = -1
|
||||
self.filename = ""
|
||||
self.setWindowTitle("Fix Duplicate Files") # TODO translate
|
||||
Translations.translate_with_setter(self.setWindowTitle, "file.duplicates.fix")
|
||||
self.setWindowModality(Qt.WindowModality.ApplicationModal)
|
||||
self.setMinimumSize(400, 300)
|
||||
self.root_layout = QVBoxLayout(self)
|
||||
@@ -42,9 +44,7 @@ class FixDupeFilesModal(QWidget):
|
||||
self.desc_widget.setObjectName("descriptionLabel")
|
||||
self.desc_widget.setWordWrap(True)
|
||||
self.desc_widget.setStyleSheet("text-align:left;")
|
||||
self.desc_widget.setText(
|
||||
"TagStudio supports importing DupeGuru results to manage duplicate files."
|
||||
) # TODO translate
|
||||
Translations.translate_qobject(self.desc_widget, "file.duplicates.description")
|
||||
self.desc_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.dupe_count = QLabel()
|
||||
@@ -54,34 +54,25 @@ class FixDupeFilesModal(QWidget):
|
||||
|
||||
self.file_label = QLabel()
|
||||
self.file_label.setObjectName("fileLabel")
|
||||
self.file_label.setText("No DupeGuru File Selected") # TODO translate
|
||||
Translations.translate_qobject(self.file_label, "file.duplicates.dupeguru.no_file")
|
||||
|
||||
self.open_button = QPushButton()
|
||||
self.open_button.setText("&Load DupeGuru File") # TODO translate
|
||||
Translations.translate_qobject(self.open_button, "file.duplicates.dupeguru.load_file")
|
||||
self.open_button.clicked.connect(self.select_file)
|
||||
|
||||
self.mirror_modal = MirrorEntriesModal(self.driver, self.tracker)
|
||||
self.mirror_modal.done.connect(self.refresh_dupes)
|
||||
|
||||
self.mirror_button = QPushButton()
|
||||
self.mirror_button.setText("&Mirror Entries") # TODO translate
|
||||
Translations.translate_qobject(self.mirror_button, "file.duplicates.mirror_entries")
|
||||
self.mirror_button.clicked.connect(self.mirror_modal.show)
|
||||
self.mirror_desc = QLabel()
|
||||
self.mirror_desc.setWordWrap(True)
|
||||
self.mirror_desc.setText(
|
||||
"Mirror the Entry data across each duplicate match set, combining all data while not "
|
||||
"removing or duplicating fields. This operation will not delete any files or data."
|
||||
) # TODO translate
|
||||
Translations.translate_qobject(self.mirror_desc, "file.duplicates.mirror.description")
|
||||
|
||||
self.advice_label = QLabel()
|
||||
self.advice_label.setWordWrap(True)
|
||||
# fmt: off
|
||||
self.advice_label.setText(
|
||||
"After mirroring, you're free to use DupeGuru to delete the unwanted files. "
|
||||
"Afterwards, use TagStudio's \"Fix Unlinked Entries\" feature in the "
|
||||
"Tools menu in order to delete the unlinked Entries."
|
||||
)# TODO translate
|
||||
# fmt: on
|
||||
Translations.translate_qobject(self.advice_label, "file.duplicates.dupeguru.advice")
|
||||
|
||||
self.button_container = QWidget()
|
||||
self.button_layout = QHBoxLayout(self.button_container)
|
||||
@@ -89,7 +80,7 @@ class FixDupeFilesModal(QWidget):
|
||||
self.button_layout.addStretch(1)
|
||||
|
||||
self.done_button = QPushButton()
|
||||
self.done_button.setText("&Done") # TODO translate
|
||||
Translations.translate_qobject(self.done_button, "generic.done_alt")
|
||||
self.done_button.setDefault(True)
|
||||
self.done_button.clicked.connect(self.hide)
|
||||
self.button_layout.addWidget(self.done_button)
|
||||
@@ -109,10 +100,10 @@ class FixDupeFilesModal(QWidget):
|
||||
|
||||
def select_file(self):
|
||||
qfd = QFileDialog(
|
||||
self, "Open DupeGuru Results File", str(self.lib.library_dir)
|
||||
) # TODO translate
|
||||
self, Translations["file.duplicates.dupeguru.open_file"], str(self.lib.library_dir)
|
||||
)
|
||||
qfd.setFileMode(QFileDialog.FileMode.ExistingFile)
|
||||
qfd.setNameFilter("DupeGuru Files (*.dupeguru)") # TODO translate
|
||||
qfd.setNameFilter(Translations["file.duplicates.dupeguru.file_extension"])
|
||||
if qfd.exec_():
|
||||
filename = qfd.selectedFiles()
|
||||
if filename:
|
||||
@@ -122,7 +113,7 @@ class FixDupeFilesModal(QWidget):
|
||||
if filename:
|
||||
self.file_label.setText(filename)
|
||||
else:
|
||||
self.file_label.setText("No DupeGuru File Selected") # TODO translate
|
||||
self.file_label.setText(Translations["file.duplicates.dupeguru.no_file"])
|
||||
self.filename = filename
|
||||
self.refresh_dupes()
|
||||
self.mirror_modal.refresh_list()
|
||||
@@ -134,10 +125,14 @@ class FixDupeFilesModal(QWidget):
|
||||
def set_dupe_count(self, count: int):
|
||||
if count < 0:
|
||||
self.mirror_button.setDisabled(True)
|
||||
self.dupe_count.setText("Duplicate File Matches: N/A") # TODO translate
|
||||
self.dupe_count.setText(Translations["file.duplicates.matches_uninitialized"])
|
||||
elif count == 0:
|
||||
self.mirror_button.setDisabled(True)
|
||||
self.dupe_count.setText(f"Duplicate File Matches: {count}") # TODO translate
|
||||
self.dupe_count.setText(
|
||||
Translations.translate_formatted("file.duplicates.matches", count=count)
|
||||
)
|
||||
else:
|
||||
self.mirror_button.setDisabled(False)
|
||||
self.dupe_count.setText(f"Duplicate File Matches: {count}") # TODO translate
|
||||
self.dupe_count.setText(
|
||||
Translations.translate_formatted("file.duplicates.matches", count=count)
|
||||
)
|
||||
|
||||
@@ -14,6 +14,8 @@ from src.qt.modals.merge_dupe_entries import MergeDuplicateEntries
|
||||
from src.qt.modals.relink_unlinked import RelinkUnlinkedEntries
|
||||
from src.qt.widgets.progress import ProgressWidget
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
# Only import for type checking/autocompletion, will not be imported at runtime.
|
||||
if typing.TYPE_CHECKING:
|
||||
from src.qt.ts_qt import QtDriver
|
||||
@@ -29,7 +31,7 @@ class FixUnlinkedEntriesModal(QWidget):
|
||||
|
||||
self.missing_count = -1
|
||||
self.dupe_count = -1
|
||||
self.setWindowTitle("Fix Unlinked Entries") # TODO translate
|
||||
Translations.translate_with_setter(self.setWindowTitle, "entries.unlinked.title")
|
||||
self.setWindowModality(Qt.WindowModality.ApplicationModal)
|
||||
self.setMinimumSize(400, 300)
|
||||
self.root_layout = QVBoxLayout(self)
|
||||
@@ -39,13 +41,7 @@ class FixUnlinkedEntriesModal(QWidget):
|
||||
self.unlinked_desc_widget.setObjectName("unlinkedDescriptionLabel")
|
||||
self.unlinked_desc_widget.setWordWrap(True)
|
||||
self.unlinked_desc_widget.setStyleSheet("text-align:left;")
|
||||
self.unlinked_desc_widget.setText(
|
||||
"Each library entry is linked to a file in one of your directories. "
|
||||
"If a file linked to an entry is moved or deleted outside of TagStudio, "
|
||||
"it is then considered unlinked.\n\n"
|
||||
"Unlinked entries may be automatically relinked via searching your directories, "
|
||||
"manually relinked by the user, or deleted if desired."
|
||||
) # TODO translate
|
||||
Translations.translate_qobject(self.unlinked_desc_widget, "entries.unlinked.description")
|
||||
|
||||
self.missing_count_label = QLabel()
|
||||
self.missing_count_label.setObjectName("missingCountLabel")
|
||||
@@ -58,14 +54,14 @@ class FixUnlinkedEntriesModal(QWidget):
|
||||
self.dupe_count_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.refresh_unlinked_button = QPushButton()
|
||||
self.refresh_unlinked_button.setText("&Refresh All") # TODO translate
|
||||
Translations.translate_qobject(self.refresh_unlinked_button, "entries.unlinked.refresh_all")
|
||||
self.refresh_unlinked_button.clicked.connect(self.refresh_missing_files)
|
||||
|
||||
self.merge_class = MergeDuplicateEntries(self.lib, self.driver)
|
||||
self.relink_class = RelinkUnlinkedEntries(self.tracker)
|
||||
|
||||
self.search_button = QPushButton()
|
||||
self.search_button.setText("&Search && Relink") # TODO translate
|
||||
Translations.translate_qobject(self.search_button, "entries.unlinked.search_and_relink")
|
||||
self.relink_class.done.connect(
|
||||
# refresh the grid
|
||||
lambda: (
|
||||
@@ -76,7 +72,7 @@ class FixUnlinkedEntriesModal(QWidget):
|
||||
self.search_button.clicked.connect(self.relink_class.repair_entries)
|
||||
|
||||
self.manual_button = QPushButton()
|
||||
self.manual_button.setText("&Manual Relink") # TODO translate
|
||||
Translations.translate_qobject(self.manual_button, "entries.unlinked.relink.manual")
|
||||
self.manual_button.setHidden(True)
|
||||
|
||||
self.delete_button = QPushButton()
|
||||
@@ -88,7 +84,7 @@ class FixUnlinkedEntriesModal(QWidget):
|
||||
self.driver.filter_items(),
|
||||
)
|
||||
)
|
||||
self.delete_button.setText("De&lete Unlinked Entries") # TODO translate
|
||||
Translations.translate_qobject(self.delete_button, "entries.unlinked.delete_alt")
|
||||
self.delete_button.clicked.connect(self.delete_modal.show)
|
||||
|
||||
self.button_container = QWidget()
|
||||
@@ -97,7 +93,7 @@ class FixUnlinkedEntriesModal(QWidget):
|
||||
self.button_layout.addStretch(1)
|
||||
|
||||
self.done_button = QPushButton()
|
||||
self.done_button.setText("&Done") # TODO translate
|
||||
Translations.translate_qobject(self.done_button, "generic.done_alt")
|
||||
self.done_button.setDefault(True)
|
||||
self.done_button.clicked.connect(self.hide)
|
||||
self.button_layout.addWidget(self.done_button)
|
||||
@@ -116,12 +112,12 @@ class FixUnlinkedEntriesModal(QWidget):
|
||||
|
||||
def refresh_missing_files(self):
|
||||
pw = ProgressWidget(
|
||||
window_title="Scanning Library", # TODO translate
|
||||
label_text="Scanning Library for Unlinked Entries...", # TODO translate
|
||||
cancel_button_text=None,
|
||||
minimum=0,
|
||||
maximum=self.lib.entries_count,
|
||||
)
|
||||
Translations.translate_with_setter(pw.setWindowTitle, "library.scan_library.title")
|
||||
Translations.translate_with_setter(pw.update_label, "entries.unlinked.scanning")
|
||||
|
||||
pw.from_iterable_function(
|
||||
self.tracker.refresh_missing_files,
|
||||
@@ -139,11 +135,13 @@ class FixUnlinkedEntriesModal(QWidget):
|
||||
if self.missing_count < 0:
|
||||
self.search_button.setDisabled(True)
|
||||
self.delete_button.setDisabled(True)
|
||||
self.missing_count_label.setText("Unlinked Entries: N/A") # TODO translate
|
||||
self.missing_count_label.setText(Translations["entries.unlinked.missing_count.none"])
|
||||
else:
|
||||
# disable buttons if there are no files to fix
|
||||
self.search_button.setDisabled(self.missing_count == 0)
|
||||
self.delete_button.setDisabled(self.missing_count == 0)
|
||||
self.missing_count_label.setText(
|
||||
f"Unlinked Entries: {self.missing_count}"
|
||||
) # TODO translate
|
||||
Translations.translate_formatted(
|
||||
"entries.unlinked.missing_count.some", count=self.missing_count
|
||||
)
|
||||
)
|
||||
|
||||
@@ -24,6 +24,8 @@ from src.core.library.alchemy.fields import _FieldID
|
||||
from src.core.palette import ColorType, get_tag_color
|
||||
from src.qt.flowlayout import FlowLayout
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from src.qt.ts_qt import QtDriver
|
||||
|
||||
@@ -164,7 +166,7 @@ class FoldersToTagsModal(QWidget):
|
||||
self.count = -1
|
||||
self.filename = ""
|
||||
|
||||
self.setWindowTitle("Create Tags From Folders") # TODO translate
|
||||
Translations.translate_with_setter(self.setWindowTitle, "folders_to_tags.title")
|
||||
self.setWindowModality(Qt.WindowModality.ApplicationModal)
|
||||
self.setMinimumSize(640, 640)
|
||||
self.root_layout = QVBoxLayout(self)
|
||||
@@ -174,7 +176,7 @@ class FoldersToTagsModal(QWidget):
|
||||
self.title_widget.setObjectName("title")
|
||||
self.title_widget.setWordWrap(True)
|
||||
self.title_widget.setStyleSheet("font-weight:bold;" "font-size:14px;" "padding-top: 6px")
|
||||
self.title_widget.setText("Create Tags From Folders") # TODO translate
|
||||
Translations.translate_qobject(self.title_widget, "folders_to_tags.title")
|
||||
self.title_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.desc_widget = QLabel()
|
||||
@@ -190,10 +192,10 @@ class FoldersToTagsModal(QWidget):
|
||||
self.open_close_button_layout = QHBoxLayout(self.open_close_button_w)
|
||||
|
||||
self.open_all_button = QPushButton()
|
||||
self.open_all_button.setText("Open All") # TODO translate
|
||||
Translations.translate_qobject(self.open_all_button, "folders_to_tags.open_all")
|
||||
self.open_all_button.clicked.connect(lambda: self.set_all_branches(False))
|
||||
self.close_all_button = QPushButton()
|
||||
self.close_all_button.setText("Close All") # TODO translate
|
||||
Translations.translate_qobject(self.close_all_button, "folders_to_tags.close_all")
|
||||
self.close_all_button.clicked.connect(lambda: self.set_all_branches(True))
|
||||
|
||||
self.open_close_button_layout.addWidget(self.open_all_button)
|
||||
@@ -212,7 +214,7 @@ class FoldersToTagsModal(QWidget):
|
||||
self.scroll_area.setWidget(self.scroll_contents)
|
||||
|
||||
self.apply_button = QPushButton()
|
||||
self.apply_button.setText("&Apply") # TODO translate
|
||||
Translations.translate_qobject(self.apply_button, "generic.apply_alt")
|
||||
self.apply_button.setMinimumWidth(100)
|
||||
self.apply_button.clicked.connect(self.on_apply)
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ from src.core.library import Library
|
||||
from src.core.utils.dupe_files import DupeRegistry
|
||||
from src.qt.widgets.progress import ProgressWidget
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
# Only import for type checking/autocompletion, will not be imported at runtime.
|
||||
if typing.TYPE_CHECKING:
|
||||
from src.qt.ts_qt import QtDriver
|
||||
@@ -25,11 +27,11 @@ class MergeDuplicateEntries(QObject):
|
||||
|
||||
def merge_entries(self):
|
||||
pw = ProgressWidget(
|
||||
window_title="Merging Duplicate Entries", # TODO translate
|
||||
label_text="Merging Duplicate Entries...", # TODO translate
|
||||
cancel_button_text=None,
|
||||
minimum=0,
|
||||
maximum=self.tracker.groups_count,
|
||||
)
|
||||
Translations.translate_with_setter(pw.setWindowTitle, "entries.duplicate.merge.label")
|
||||
Translations.translate_with_setter(pw.update_label, "entries.duplicate.merge.label")
|
||||
|
||||
pw.from_iterable_function(self.tracker.merge_dupe_entries, None, self.done.emit)
|
||||
|
||||
@@ -19,6 +19,8 @@ from PySide6.QtWidgets import (
|
||||
from src.core.utils.dupe_files import DupeRegistry
|
||||
from src.qt.widgets.progress import ProgressWidget
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
# Only import for type checking/autocompletion, will not be imported at runtime.
|
||||
if typing.TYPE_CHECKING:
|
||||
from src.qt.ts_qt import QtDriver
|
||||
@@ -30,7 +32,7 @@ class MirrorEntriesModal(QWidget):
|
||||
def __init__(self, driver: "QtDriver", tracker: DupeRegistry):
|
||||
super().__init__()
|
||||
self.driver = driver
|
||||
self.setWindowTitle("Mirror Entries") # TODO translate
|
||||
Translations.translate_with_setter(self.setWindowTitle, "entries.mirror.window_title")
|
||||
self.setWindowModality(Qt.WindowModality.ApplicationModal)
|
||||
self.setMinimumSize(500, 400)
|
||||
self.root_layout = QVBoxLayout(self)
|
||||
@@ -40,10 +42,9 @@ class MirrorEntriesModal(QWidget):
|
||||
self.desc_widget = QLabel()
|
||||
self.desc_widget.setObjectName("descriptionLabel")
|
||||
self.desc_widget.setWordWrap(True)
|
||||
|
||||
self.desc_widget.setText(f"""
|
||||
Are you sure you want to mirror the following {self.tracker.groups_count} Entries?
|
||||
""") # TODO translate
|
||||
Translations.translate_qobject(
|
||||
self.desc_widget, "entries.mirror.confirmation", count=self.tracker.groups_count
|
||||
)
|
||||
self.desc_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.list_view = QListView()
|
||||
@@ -56,13 +57,13 @@ class MirrorEntriesModal(QWidget):
|
||||
self.button_layout.addStretch(1)
|
||||
|
||||
self.cancel_button = QPushButton()
|
||||
self.cancel_button.setText("&Cancel") # TODO translate
|
||||
Translations.translate_qobject(self.cancel_button, "generic.cancel_alt")
|
||||
self.cancel_button.setDefault(True)
|
||||
self.cancel_button.clicked.connect(self.hide)
|
||||
self.button_layout.addWidget(self.cancel_button)
|
||||
|
||||
self.mirror_button = QPushButton()
|
||||
self.mirror_button.setText("&Mirror") # TODO translate
|
||||
Translations.translate_qobject(self.mirror_button, "entries.mirror")
|
||||
self.mirror_button.clicked.connect(self.hide)
|
||||
self.mirror_button.clicked.connect(self.mirror_entries)
|
||||
self.button_layout.addWidget(self.mirror_button)
|
||||
@@ -72,9 +73,11 @@ class MirrorEntriesModal(QWidget):
|
||||
self.root_layout.addWidget(self.button_container)
|
||||
|
||||
def refresh_list(self):
|
||||
self.desc_widget.setText(f"""
|
||||
Are you sure you want to mirror the following {self.tracker.groups_count} Entries?
|
||||
""")
|
||||
self.desc_widget.setText(
|
||||
Translations.translate_formatted(
|
||||
"entries.mirror.confirmation", count=self.tracker.groups_count
|
||||
)
|
||||
)
|
||||
|
||||
self.model.clear()
|
||||
for i in self.tracker.groups:
|
||||
@@ -82,15 +85,16 @@ class MirrorEntriesModal(QWidget):
|
||||
|
||||
def mirror_entries(self):
|
||||
def displayed_text(x):
|
||||
return f"Mirroring {x + 1}/{self.tracker.groups_count} Entries..." # TODO translate
|
||||
return Translations.translate_formatted(
|
||||
"entries.mirror.label", idx=x + 1, count=self.tracker.groups_count
|
||||
)
|
||||
|
||||
pw = ProgressWidget(
|
||||
window_title="Mirroring Entries", # TODO translate
|
||||
label_text="",
|
||||
cancel_button_text=None,
|
||||
minimum=0,
|
||||
maximum=self.tracker.groups_count,
|
||||
)
|
||||
Translations.translate_with_setter(pw.setWindowTitle, "entries.mirror.title")
|
||||
|
||||
pw.from_iterable_function(
|
||||
self.mirror_entries_runnable,
|
||||
|
||||
@@ -7,6 +7,8 @@ from PySide6.QtCore import QObject, Signal
|
||||
from src.core.utils.missing_files import MissingRegistry
|
||||
from src.qt.widgets.progress import ProgressWidget
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
|
||||
class RelinkUnlinkedEntries(QObject):
|
||||
done = Signal()
|
||||
@@ -17,16 +19,19 @@ class RelinkUnlinkedEntries(QObject):
|
||||
|
||||
def repair_entries(self):
|
||||
def displayed_text(x):
|
||||
text = f"Attempting to Relink {x}/{self.tracker.missing_files_count} Entries. \n" # TODO translate
|
||||
text += f"{self.tracker.files_fixed_count} Successfully Relinked." # TODO translate
|
||||
return text
|
||||
return Translations.translate_formatted(
|
||||
"entries.unlinked.relink.attempting",
|
||||
idx=x,
|
||||
missing_count=self.tracker.missing_files_count,
|
||||
fixed_count=self.tracker.files_fixed_count,
|
||||
)
|
||||
|
||||
pw = ProgressWidget(
|
||||
window_title="Relinking Entries", # TODO translate
|
||||
label_text="",
|
||||
cancel_button_text=None,
|
||||
minimum=0,
|
||||
maximum=self.tracker.missing_files_count,
|
||||
)
|
||||
Translations.translate_with_setter(pw.setWindowTitle, "entries.unlinked.relink.title")
|
||||
|
||||
pw.from_iterable_function(self.tracker.fix_missing_files, displayed_text, self.done.emit)
|
||||
|
||||
@@ -21,6 +21,8 @@ from src.qt.modals.build_tag import BuildTagPanel
|
||||
from src.qt.widgets.panel import PanelModal, PanelWidget
|
||||
from src.qt.widgets.tag import TagWidget
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
# TODO: This class shares the majority of its code with tag_search.py.
|
||||
@@ -44,7 +46,7 @@ class TagDatabasePanel(PanelWidget):
|
||||
self.search_field = QLineEdit()
|
||||
self.search_field.setObjectName("searchField")
|
||||
self.search_field.setMinimumSize(QSize(0, 32))
|
||||
self.search_field.setPlaceholderText("Search Tags") # TODO translate
|
||||
Translations.translate_with_setter(self.search_field.setPlaceholderText, "home.search_tags")
|
||||
self.search_field.textEdited.connect(lambda: self.update_tags(self.search_field.text()))
|
||||
self.search_field.returnPressed.connect(
|
||||
lambda checked=False: self.on_return(self.search_field.text())
|
||||
@@ -63,7 +65,7 @@ class TagDatabasePanel(PanelWidget):
|
||||
self.scroll_area.setWidget(self.scroll_contents)
|
||||
|
||||
self.create_tag_button = QPushButton()
|
||||
self.create_tag_button.setText("Create Tag") # TODO translate
|
||||
Translations.translate_qobject(self.create_tag_button, "tag.create")
|
||||
self.create_tag_button.clicked.connect(self.build_tag)
|
||||
|
||||
self.root_layout.addWidget(self.search_field)
|
||||
@@ -72,14 +74,14 @@ class TagDatabasePanel(PanelWidget):
|
||||
self.update_tags()
|
||||
|
||||
def build_tag(self):
|
||||
panel = BuildTagPanel(self.lib)
|
||||
self.modal = PanelModal(
|
||||
BuildTagPanel(self.lib),
|
||||
"New Tag", # TODO translate
|
||||
"Add Tag", # TODO translate
|
||||
panel,
|
||||
has_save=True,
|
||||
)
|
||||
Translations.translate_with_setter(self.modal.setTitle, "tag.new")
|
||||
Translations.translate_with_setter(self.modal.setWindowTitle, "tag.add")
|
||||
|
||||
panel: BuildTagPanel = self.modal.widget
|
||||
self.modal.saved.connect(
|
||||
lambda: (
|
||||
self.lib.add_tag(
|
||||
@@ -134,10 +136,8 @@ class TagDatabasePanel(PanelWidget):
|
||||
return
|
||||
|
||||
message_box = QMessageBox()
|
||||
message_box.setWindowTitle("Remove Tag") # TODO translate
|
||||
message_box.setText(
|
||||
f'Are you sure you want to delete the tag "{tag.name}"?'
|
||||
) # TODO translate
|
||||
Translations.translate_with_setter(message_box.setWindowTitle, "tag.remove")
|
||||
Translations.translate_qobject(message_box, "tag_database.confirmation", tag_name=tag.name)
|
||||
message_box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) # type: ignore
|
||||
message_box.setIcon(QMessageBox.Question) # type: ignore
|
||||
|
||||
@@ -158,10 +158,10 @@ class TagDatabasePanel(PanelWidget):
|
||||
self.edit_modal = PanelModal(
|
||||
build_tag_panel,
|
||||
tag.name,
|
||||
"Edit Tag", # TODO translate
|
||||
done_callback=(self.update_tags(self.search_field.text())),
|
||||
has_save=True,
|
||||
)
|
||||
Translations.translate_with_setter(self.edit_modal.setWindowTitle, "tag.edit")
|
||||
# TODO Check Warning: Expected type 'BuildTagPanel', got 'PanelWidget' instead
|
||||
self.edit_modal.saved.connect(lambda: self.edit_tag_callback(build_tag_panel))
|
||||
self.edit_modal.show()
|
||||
|
||||
@@ -22,6 +22,8 @@ from src.core.palette import ColorType, get_tag_color
|
||||
from src.qt.widgets.panel import PanelWidget
|
||||
from src.qt.widgets.tag import TagWidget
|
||||
|
||||
from ..translations import Translations
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
@@ -41,7 +43,7 @@ class TagSearchPanel(PanelWidget):
|
||||
self.search_field = QLineEdit()
|
||||
self.search_field.setObjectName("searchField")
|
||||
self.search_field.setMinimumSize(QSize(0, 32))
|
||||
self.search_field.setPlaceholderText("Search Tags") # TODO translate
|
||||
Translations.translate_with_setter(self.search_field.setPlaceholderText, "home.search_tags")
|
||||
self.search_field.textEdited.connect(lambda: self.update_tags(self.search_field.text()))
|
||||
self.search_field.returnPressed.connect(
|
||||
lambda checked=False: self.on_return(self.search_field.text())
|
||||
|
||||
@@ -4,7 +4,7 @@ from typing import Callable
|
||||
import ujson
|
||||
from PySide6.QtCore import QObject, Signal
|
||||
from PySide6.QtGui import QAction
|
||||
from PySide6.QtWidgets import QLabel, QMenu, QPushButton
|
||||
from PySide6.QtWidgets import QLabel, QMenu, QMessageBox, QPushButton
|
||||
|
||||
DEFAULT_TRANSLATION = "de"
|
||||
|
||||
@@ -49,7 +49,7 @@ class Translator:
|
||||
|
||||
def translate_qobject(self, widget: QObject, key: str, **kwargs):
|
||||
"""Translates the text of the QObject using :func:`translate_with_setter`."""
|
||||
if isinstance(widget, (QLabel, QAction, QPushButton)):
|
||||
if isinstance(widget, (QLabel, QAction, QPushButton, QMessageBox)):
|
||||
self.translate_with_setter(widget.setText, key, **kwargs)
|
||||
elif isinstance(widget, (QMenu)):
|
||||
self.translate_with_setter(widget.setTitle, key, **kwargs)
|
||||
|
||||
@@ -522,7 +522,7 @@ class QtDriver(DriverMixin, QObject):
|
||||
msg_box.setIcon(QMessageBox.Icon.Critical)
|
||||
msg_box.setText(message)
|
||||
msg_box.setWindowTitle(Translations["window.title.error"])
|
||||
msg_box.addButton(Translations["window.button.close"], QMessageBox.ButtonRole.AcceptRole)
|
||||
msg_box.addButton(Translations["generic.close"], QMessageBox.ButtonRole.AcceptRole)
|
||||
|
||||
# Show the message box
|
||||
msg_box.exec()
|
||||
|
||||
Reference in New Issue
Block a user