ui: shortcut to add tags to selected entries; change click behavior of tags to edit (#749)

* ui: change on_click behavior of tags to edit

* fix: pass library to tag_widget

* feat: add `add_tag_to_selected` shortcut

* fix: only enable `add_tag_to_selected` shortcut when usable
This commit is contained in:
Travis Abendshien
2025-01-29 21:28:08 -08:00
committed by GitHub
parent d1b006a897
commit 82edbee276
3 changed files with 60 additions and 8 deletions

View File

@@ -183,6 +183,7 @@
"menu.view": "&View",
"menu.window": "Window",
"preview.no_selection": "No Items Selected",
"select.add_tag_to_selected": "Add Tag to Selected",
"select.all": "Select All",
"select.clear": "Clear Selection",
"settings.clear_thumb_cache.title": "Clear Thumbnail Cache",

View File

@@ -81,6 +81,7 @@ from src.qt.modals.fix_dupes import FixDupeFilesModal
from src.qt.modals.fix_unlinked import FixUnlinkedEntriesModal
from src.qt.modals.folders_to_tags import FoldersToTagsModal
from src.qt.modals.tag_database import TagDatabasePanel
from src.qt.modals.tag_search import TagSearchPanel
from src.qt.resource_manager import ResourceManager
from src.qt.splash import Splash
from src.qt.translations import Translations
@@ -132,6 +133,9 @@ class QtDriver(DriverMixin, QObject):
SIGTERM = Signal()
preview_panel: PreviewPanel
tag_search_panel: TagSearchPanel
add_tag_modal: PanelModal
lib: Library
def __init__(self, backend, args):
@@ -199,6 +203,8 @@ class QtDriver(DriverMixin, QObject):
f"[Config] Thumbnail cache size limit: {format_size(CacheManager.size_limit)}",
)
self.add_tag_to_selected_action: QAction | None = None
def init_workers(self):
"""Init workers for rendering thumbnails."""
if not self.thumb_threads:
@@ -270,6 +276,18 @@ class QtDriver(DriverMixin, QObject):
icon.addFile(str(icon_path))
app.setWindowIcon(icon)
# Initialize the main window's tag search panel
self.tag_search_panel = TagSearchPanel(self.lib, is_tag_chooser=True)
self.add_tag_modal = PanelModal(
self.tag_search_panel, Translations.translate_formatted("tag.add.plural")
)
self.tag_search_panel.tag_chosen.connect(
lambda t: (
self.add_tags_to_selected_callback(t),
self.preview_panel.update_widgets(),
)
)
menu_bar = QMenuBar(self.main_window)
self.main_window.setMenuBar(menu_bar)
menu_bar.setNativeMenuBar(True)
@@ -394,6 +412,24 @@ class QtDriver(DriverMixin, QObject):
clear_select_action.setToolTip("Esc")
edit_menu.addAction(clear_select_action)
self.add_tag_to_selected_action = QAction(menu_bar)
Translations.translate_qobject(
self.add_tag_to_selected_action, "select.add_tag_to_selected"
)
self.add_tag_to_selected_action.triggered.connect(self.add_tag_modal.show)
self.add_tag_to_selected_action.setShortcut(
QtCore.QKeyCombination(
QtCore.Qt.KeyboardModifier(
QtCore.Qt.KeyboardModifier.ControlModifier
^ QtCore.Qt.KeyboardModifier.ShiftModifier
),
QtCore.Qt.Key.Key_T,
)
)
self.add_tag_to_selected_action.setToolTip("Ctrl+Shift+T")
self.add_tag_to_selected_action.setEnabled(False)
edit_menu.addAction(self.add_tag_to_selected_action)
edit_menu.addSeparator()
manage_file_extensions_action = QAction(menu_bar)
@@ -551,6 +587,7 @@ class QtDriver(DriverMixin, QObject):
self.open_library(path_result.library_path)
# check ffmpeg and show warning if not
# NOTE: Does this need to use self?
self.ffmpeg_checker = FfmpegChecker()
if not self.ffmpeg_checker.installed():
self.ffmpeg_checker.show_warning()
@@ -705,9 +742,12 @@ class QtDriver(DriverMixin, QObject):
self.preview_panel.update_widgets()
self.main_window.toggle_landing_page(enabled=True)
self.main_window.pagination.setHidden(True)
# NOTE: Doesn't try to disable during tests
if self.add_tag_to_selected_action:
self.add_tag_to_selected_action.setEnabled(False)
end_time = time.time()
self.main_window.statusbar.showMessage(
Translations.translate_formatted(
@@ -760,16 +800,22 @@ class QtDriver(DriverMixin, QObject):
item.thumb_button.set_selected(True)
self.set_macro_menu_viability()
self.set_add_to_selected_visibility()
self.preview_panel.update_widgets(update_preview=False)
def clear_select_action_callback(self):
self.selected.clear()
self.set_add_to_selected_visibility()
for item in self.item_thumbs:
item.thumb_button.set_selected(False)
self.set_macro_menu_viability()
self.preview_panel.update_widgets()
def add_tags_to_selected_callback(self, tag_ids: list[int]):
for entry_id in self.selected:
self.lib.add_tags_to_entry(entry_id, tag_ids)
def show_tag_database(self):
self.modal = PanelModal(
widget=TagDatabasePanel(self.lib),
@@ -1110,11 +1156,21 @@ class QtDriver(DriverMixin, QObject):
it.thumb_button.set_selected(False)
self.set_macro_menu_viability()
self.set_add_to_selected_visibility()
self.preview_panel.update_widgets()
def set_macro_menu_viability(self):
self.autofill_action.setDisabled(not self.selected)
def set_add_to_selected_visibility(self):
if not self.add_tag_to_selected_action:
return
if self.selected:
self.add_tag_to_selected_action.setEnabled(True)
else:
self.add_tag_to_selected_action.setEnabled(False)
def update_completions_list(self, text: str) -> None:
matches = re.search(
r"((?:.* )?)(mediatype|filetype|path|tag|tag_id):(\"?[A-Za-z0-9\ \t]+\"?)?", text
@@ -1478,6 +1534,7 @@ class QtDriver(DriverMixin, QObject):
self.main_window.setAcceptDrops(True)
self.selected.clear()
self.set_add_to_selected_visibility()
self.preview_panel.update_widgets()
# page (re)rendering, extract eventually

View File

@@ -8,7 +8,6 @@ import typing
import structlog
from PySide6.QtCore import Signal
from src.core.library import Tag
from src.core.library.alchemy.enums import FilterState
from src.qt.flowlayout import FlowLayout
from src.qt.modals.build_tag import BuildTagPanel
from src.qt.widgets.fields import FieldWidget
@@ -53,12 +52,7 @@ class TagBoxWidget(FieldWidget):
for tag in tags_:
tag_widget = TagWidget(tag, library=self.driver.lib, has_edit=True, has_remove=True)
tag_widget.on_click.connect(
lambda tag_id=tag.id: (
self.driver.main_window.searchField.setText(f"tag_id:{tag_id}"),
self.driver.filter_items(FilterState.from_tag_id(tag_id)),
)
)
tag_widget.on_click.connect(lambda t=tag: self.edit_tag(t))
tag_widget.on_remove.connect(
lambda tag_id=tag.id: (