diff --git a/src/tagstudio/qt/controllers/tag_suggest_box.py b/src/tagstudio/qt/controllers/tag_suggest_box.py
index 0b4aac21..622771d0 100644
--- a/src/tagstudio/qt/controllers/tag_suggest_box.py
+++ b/src/tagstudio/qt/controllers/tag_suggest_box.py
@@ -7,6 +7,7 @@ from typing import override
from warnings import catch_warnings
import structlog
+from PySide6.QtGui import QAction, Qt
from PySide6.QtWidgets import QGraphicsOpacityEffect, QWidget
from tagstudio.core.library.alchemy.enums import BrowsingState
@@ -31,6 +32,29 @@ class TagSuggestBox(SuggestBox[Tag]):
self._driver = driver
self._lib = self._driver.lib
+ # Context Menu Actions
+ edit_tag_on_create_action = QAction(Translations["settings.edit_tag_on_create"], self)
+ edit_tag_on_create_action.setCheckable(True)
+ self.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu)
+ self.addAction(edit_tag_on_create_action)
+ self.layout().search_field.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu)
+ self.layout().search_field.addAction(edit_tag_on_create_action)
+ edit_tag_on_create_action.setChecked(self._driver.settings.edit_tag_on_create)
+ edit_tag_on_create_action.triggered.connect(
+ lambda checked: self.toggle_edit_on_tag_create(checked)
+ )
+
+ def search_for_tag(self, tag_id: int) -> None:
+ self._driver.main_window.search_field.setText(f"tag_id:{tag_id}")
+ self._driver.update_browsing_state(
+ BrowsingState.from_tag_id(tag_id, self._driver.browsing_history.current)
+ )
+
+ def toggle_edit_on_tag_create(self, checked: bool) -> None:
+ """Toggle the setting for opening the edit window after creating a tag.."""
+ self._driver.settings.edit_tag_on_create = checked
+ self._driver.settings.save()
+
@override
def on_item_create(self) -> None:
"""Opens panel to create a new tag and optionally add it to an entry.
@@ -143,12 +167,6 @@ class TagSuggestBox(SuggestBox[Tag]):
)
self.update_items(self._layout.search_field.text())
- def search_for_tag(self, tag_id: int) -> None:
- self._driver.main_window.search_field.setText(f"tag_id:{tag_id}")
- self._driver.update_browsing_state(
- BrowsingState.from_tag_id(tag_id, self._driver.browsing_history.current)
- )
-
@override
def get_item_widget(self, index: int, library: Library | None) -> TagWidget:
"""Gets the item widget at a specific index."""
diff --git a/src/tagstudio/qt/views/preview_panel_view.py b/src/tagstudio/qt/views/preview_panel_view.py
index 7e0dbd45..44885883 100644
--- a/src/tagstudio/qt/views/preview_panel_view.py
+++ b/src/tagstudio/qt/views/preview_panel_view.py
@@ -47,11 +47,11 @@ class PreviewPanelView(QWidget):
view=FieldTemplateSearchPanelView(is_field_template_chooser=True),
)
- tag_placeholder_text = (
- f"{Translations['home.search_tags']} {Translations['home.search.how_to_exit']}"
+ tag_placeholder = " ".join(
+ [Translations["home.search_or_create_tags"], Translations["home.search.how_to_exit"]]
)
self.tag_search_box = TagSuggestBox(
- driver, view=SuggestBoxView(placeholder=tag_placeholder_text)
+ driver, view=SuggestBoxView(placeholder_text=tag_placeholder)
)
self.tag_search_box.hide()
diff --git a/src/tagstudio/qt/views/suggest_box_view.py b/src/tagstudio/qt/views/suggest_box_view.py
index fc961a6d..da07a9c5 100644
--- a/src/tagstudio/qt/views/suggest_box_view.py
+++ b/src/tagstudio/qt/views/suggest_box_view.py
@@ -27,7 +27,7 @@ logger = structlog.get_logger(__name__)
class SuggestBoxView(QVBoxLayout):
- def __init__(self, placeholder: str = "") -> None:
+ def __init__(self, placeholder_text: str = "") -> None:
super().__init__()
# Init layout
self.setContentsMargins(0, 0, 0, 0)
@@ -79,7 +79,7 @@ class SuggestBoxView(QVBoxLayout):
self.search_field.setStyleSheet(autofill_line_edit_style())
self.search_field.setObjectName("search_field")
self.search_field.setMinimumHeight(28)
- self.search_field.setPlaceholderText(placeholder)
+ self.search_field.setPlaceholderText(placeholder_text)
self.scroll_area.setFocusProxy(self.search_field)
# Finalize layout
diff --git a/src/tagstudio/resources/translations/en.json b/src/tagstudio/resources/translations/en.json
index 1898b754..199aef6c 100644
--- a/src/tagstudio/resources/translations/en.json
+++ b/src/tagstudio/resources/translations/en.json
@@ -30,9 +30,9 @@
"drop_import.description": "The following files match file paths that already exist in the library",
"drop_import.duplicates_choice.plural": "The following {count} files match file paths that already exist in the library.",
"drop_import.duplicates_choice.singular": "The following file matches a file path that already exists in the library.",
- "drop_import.progress.label.initial": "Importing New Files...",
- "drop_import.progress.label.plural": "Importing New Files...\n{count} Files Imported.{suffix}",
- "drop_import.progress.label.singular": "Importing New Files...\n1 File imported.{suffix}",
+ "drop_import.progress.label.initial": "Importing New Files…",
+ "drop_import.progress.label.plural": "Importing New Files…\n{count} Files Imported.{suffix}",
+ "drop_import.progress.label.singular": "Importing New Files…\n1 File imported.{suffix}",
"drop_import.progress.window_title": "Import Files",
"drop_import.title": "Conflicting File(s)",
"edit.color_manager": "Manage Tag Colors",
@@ -40,26 +40,26 @@
"edit.paste_fields": "Paste Fields",
"edit.tag_manager": "Manage Tags",
"entries.duplicate.merge": "Merge Duplicate Entries",
- "entries.duplicate.merge.label": "Merging Duplicate Entries...",
+ "entries.duplicate.merge.label": "Merging 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.generic.refresh_alt": "&Refresh",
"entries.generic.remove.removing": "Removing Entries",
- "entries.generic.remove.removing_count": "Removing {count} Entries...",
+ "entries.generic.remove.removing_count": "Removing {count} Entries…",
"entries.ignored.description": "File entries are considered to be \"ignored\" if they were added to the library before the user's ignore rules (via the '.ts_ignore' file) were updated to exclude it. Ignored files are kept in the library by default in order to prevent accidental data loss when updating ignore rules.",
"entries.ignored.ignored_count": "Ignored Entries: {count}",
"entries.ignored.remove": "Remove Ignored Entries",
"entries.ignored.remove_alt": "Remo&ve Ignored Entries",
- "entries.ignored.scanning": "Scanning Library for Ignored Entries...",
+ "entries.ignored.scanning": "Scanning Library for Ignored Entries…",
"entries.ignored.title": "Fix Ignored Entries",
"entries.mirror": "&Mirror",
"entries.mirror.confirmation": "Are you sure you want to mirror the following {count} Entries?",
- "entries.mirror.label": "Mirroring {idx}/{total} Entries...",
+ "entries.mirror.label": "Mirroring {idx}/{total} Entries…",
"entries.mirror.title": "Mirroring Entries",
"entries.mirror.window_title": "Mirror Entries",
"entries.remove.plural.confirm": "Are you sure you want to remove these {count} entries from your library? No files on disk will be deleted.",
"entries.remove.singular.confirm": "Are you sure you want to remove this entry from your library? No files on disk will be deleted.",
- "entries.running.dialog.new_entries": "Adding {total} New File Entries...",
+ "entries.running.dialog.new_entries": "Adding {total} New File Entries…",
"entries.running.dialog.title": "Adding New File Entries",
"entries.tags": "Tags",
"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.",
@@ -68,7 +68,7 @@
"entries.unlinked.relink.title": "Relinking Entries",
"entries.unlinked.remove": "Remove Unlinked Entries",
"entries.unlinked.remove_alt": "Remo&ve Unlinked Entries",
- "entries.unlinked.scanning": "Scanning Library for Unlinked Entries...",
+ "entries.unlinked.scanning": "Scanning Library for Unlinked Entries…",
"entries.unlinked.search_and_relink": "&Search && Relink",
"entries.unlinked.title": "Fix Unlinked Entries",
"entries.unlinked.unlinked_count": "Unlinked Entries: {count}",
@@ -161,10 +161,11 @@
"generic.yes": "Yes",
"home.search": "Search",
"home.search_entries": "Search Entries",
- "home.search_field_templates": "Search Field Templates...",
+ "home.search_field_templates": "Search Field Templates…",
"home.search_library": "Search Library",
- "home.search_tags": "Search Tags...",
- "home.search.how_to_exit": "(Esc/Enter to Exit)",
+ "home.search_or_create_tags": "Search or Create Tags…",
+ "home.search_tags": "Search Tags…",
+ "home.search.how_to_exit": "(Esc to Exit)",
"home.search.view_limit": "View Limit:",
"home.show_hidden_entries": "Show Hidden Entries",
"home.thumbnail_size": "Thumbnail Size",
@@ -174,8 +175,8 @@
"home.thumbnail_size.mini": "Mini Thumbnails",
"home.thumbnail_size.small": "Small Thumbnails",
"ignore.open_file": "Show \"{ts_ignore}\" File on Disk",
- "json_migration.checking_for_parity": "Checking for Parity...",
- "json_migration.creating_database_tables": "Creating SQL Database Tables...",
+ "json_migration.checking_for_parity": "Checking for Parity…",
+ "json_migration.creating_database_tables": "Creating SQL Database Tables…",
"json_migration.description": "
Start and preview the results of the library migration process. The converted library will not be used unless you click \"Finish Migration\".
Library data should either have matching values or feature a \"Matched\" label. Values that do not match will be displayed in red and feature a \"(!)\" symbol next to them.