mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-01-29 14:20:48 +00:00
fix: correct behavior for tag widget search options (#398)
* fix(tags): include cluster in tag_id search * fix(ui): remove unused tag context menu item Remove unused "Add to Search" context menu item for tag widgets. * fix(ui): add tag search from tag_database Add missing functionality for the "Search for Tag" context menu option + left click functionality inside `tag_database.py` aka the "Tag Manager" panel. * fix: verify `tag_id:` input in search * style: remove commented code * fix: change `Library` import to type check only
This commit is contained in:
committed by
GitHub
parent
4590226bca
commit
569390ea72
@@ -1349,10 +1349,18 @@ class Library:
|
||||
only_missing: bool = "missing" in query or "no file" in query
|
||||
allow_adv: bool = "filename:" in query_words
|
||||
tag_only: bool = "tag_id:" in query_words
|
||||
tag_only_ids: list[int] = []
|
||||
if allow_adv:
|
||||
query_words.remove("filename:")
|
||||
if tag_only:
|
||||
query_words.remove("tag_id:")
|
||||
if query_words and query_words[0].isdigit():
|
||||
tag_only_ids.append(int(query_words[0]))
|
||||
tag_only_ids.extend(self.get_tag_cluster(int(query_words[0])))
|
||||
else:
|
||||
logging.error(
|
||||
f"[Library][ERROR] Invalid Tag ID in query: {query_words}"
|
||||
)
|
||||
# TODO: Expand this to allow for dynamic fields to work.
|
||||
only_no_author: bool = "no author" in query or "no artist" in query
|
||||
|
||||
@@ -1379,15 +1387,9 @@ class Library:
|
||||
all_tag_terms.remove(all_tag_terms[i])
|
||||
break
|
||||
|
||||
# print(all_tag_terms)
|
||||
|
||||
# non_entry_count = 0
|
||||
# Iterate over all Entries =============================================================
|
||||
for entry in self.entries:
|
||||
allowed_ext: bool = entry.filename.suffix.lower() not in self.ext_list
|
||||
# try:
|
||||
# entry: Entry = self.entries[self.file_to_library_index_map[self._source_filenames[i]]]
|
||||
# print(f'{entry}')
|
||||
|
||||
if allowed_ext == self.is_exclude_list:
|
||||
# If the entry has tags of any kind, append them to this main tag list.
|
||||
@@ -1429,7 +1431,6 @@ class Library:
|
||||
# elif query in entry.path.lower():
|
||||
|
||||
# NOTE: This searches path and filenames.
|
||||
|
||||
if allow_adv:
|
||||
if [q for q in query_words if (q in str(entry.path).lower())]:
|
||||
results.append((ItemType.ENTRY, entry.id))
|
||||
@@ -1438,17 +1439,14 @@ class Library:
|
||||
]:
|
||||
results.append((ItemType.ENTRY, entry.id))
|
||||
elif tag_only:
|
||||
if entry.has_tag(self, int(query_words[0])):
|
||||
results.append((ItemType.ENTRY, entry.id))
|
||||
for id in tag_only_ids:
|
||||
if entry.has_tag(self, id) and entry.id not in results:
|
||||
results.append((ItemType.ENTRY, entry.id))
|
||||
break
|
||||
|
||||
# elif query in entry.filename.lower():
|
||||
# self.filtered_entries.append(index)
|
||||
elif entry_tags:
|
||||
# function to add entry to results
|
||||
def add_entry(entry: Entry):
|
||||
# self.filter_entries.append()
|
||||
# self.filtered_file_list.append(file)
|
||||
# results.append((SearchItemType.ENTRY, entry.id))
|
||||
added = False
|
||||
for f in entry.fields:
|
||||
if self.get_field_attr(f, "type") == "collation":
|
||||
@@ -1518,26 +1516,6 @@ class Library:
|
||||
add_entry(entry)
|
||||
break
|
||||
|
||||
# sys.stdout.write(
|
||||
# f'\r[INFO][FILTER]: {len(self.filtered_file_list)} matches found')
|
||||
# sys.stdout.flush()
|
||||
|
||||
# except:
|
||||
# # # Put this here to have new non-registered images show up
|
||||
# # if query == "untagged" or query == "no author" or query == "no artist":
|
||||
# # self.filtered_file_list.append(file)
|
||||
# # non_entry_count = non_entry_count + 1
|
||||
# pass
|
||||
|
||||
# end_time = time.time()
|
||||
# print(
|
||||
# f'[INFO][FILTER]: {len(self.filtered_entries)} matches found ({(end_time - start_time):.3f} seconds)')
|
||||
|
||||
# if non_entry_count:
|
||||
# print(
|
||||
# f'[INFO][FILTER]: There are {non_entry_count} new files in {self.source_dir} that do not have entries. These will not appear in most filtered results.')
|
||||
# if not self.filtered_entries:
|
||||
# print("[INFO][FILTER]: Filter returned no results.")
|
||||
else:
|
||||
for entry in self.entries:
|
||||
added = False
|
||||
@@ -1562,8 +1540,6 @@ class Library:
|
||||
|
||||
if not added:
|
||||
results.append((ItemType.ENTRY, entry.id))
|
||||
# for file in self._source_filenames:
|
||||
# self.filtered_file_list.append(file)
|
||||
results.reverse()
|
||||
return results
|
||||
|
||||
@@ -2306,7 +2282,7 @@ class Library:
|
||||
return self.tags[self._tag_id_to_index_map[int(tag_id)]]
|
||||
|
||||
def get_tag_cluster(self, tag_id: int) -> list[int]:
|
||||
"""Returns a list of Tag IDs that reference this Tag."""
|
||||
"""Returns a list of Tag IDs that reference this Tag as its parent."""
|
||||
if tag_id in self._tag_id_to_cluster_map:
|
||||
return self._tag_id_to_cluster_map[int(tag_id)]
|
||||
return []
|
||||
|
||||
@@ -2,33 +2,37 @@
|
||||
# Licensed under the GPL-3.0 License.
|
||||
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
|
||||
|
||||
from PySide6.QtCore import Signal, Qt, QSize
|
||||
import typing
|
||||
|
||||
from PySide6.QtCore import QSize, Qt, Signal
|
||||
from PySide6.QtWidgets import (
|
||||
QWidget,
|
||||
QVBoxLayout,
|
||||
QFrame,
|
||||
QHBoxLayout,
|
||||
QLineEdit,
|
||||
QScrollArea,
|
||||
QFrame,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
)
|
||||
|
||||
from src.core.constants import TAG_COLORS
|
||||
from src.core.library import Library
|
||||
from src.qt.widgets.panel import PanelWidget, PanelModal
|
||||
from src.qt.widgets.tag import TagWidget
|
||||
from src.qt.modals.build_tag import BuildTagPanel
|
||||
from src.qt.widgets.panel import PanelModal, PanelWidget
|
||||
from src.qt.widgets.tag import TagWidget
|
||||
|
||||
# Only import for type checking/autocompletion, will not be imported at runtime.
|
||||
if typing.TYPE_CHECKING:
|
||||
from src.core.library import Library, Tag
|
||||
from src.qt.ts_qt import QtDriver
|
||||
|
||||
|
||||
class TagDatabasePanel(PanelWidget):
|
||||
tag_chosen = Signal(int)
|
||||
|
||||
def __init__(self, library):
|
||||
def __init__(self, library: "Library", driver: "QtDriver"):
|
||||
super().__init__()
|
||||
self.lib: Library = library
|
||||
# self.callback = callback
|
||||
self.driver: QtDriver = driver
|
||||
self.first_tag_id = -1
|
||||
self.tag_limit = 30
|
||||
# self.selected_tag: int = 0
|
||||
|
||||
self.setMinimumSize(300, 400)
|
||||
self.root_layout = QVBoxLayout(self)
|
||||
@@ -133,9 +137,14 @@ class TagDatabasePanel(PanelWidget):
|
||||
row = QHBoxLayout(container)
|
||||
row.setContentsMargins(0, 0, 0, 0)
|
||||
row.setSpacing(3)
|
||||
tw = TagWidget(self.lib, self.lib.get_tag(tag_id), True, False)
|
||||
tw.on_edit.connect(
|
||||
lambda checked=False, t=self.lib.get_tag(tag_id): (self.edit_tag(t.id))
|
||||
tag: Tag = self.lib.get_tag(tag_id)
|
||||
tw = TagWidget(self.lib, tag, True, False)
|
||||
tw.on_edit.connect(lambda checked=False, t=tag: (self.edit_tag(t.id)))
|
||||
tw.on_click.connect(
|
||||
lambda checked=False, q=f"tag_id: {tag_id}": (
|
||||
self.driver.main_window.searchField.setText(q),
|
||||
self.driver.filter_items(q),
|
||||
)
|
||||
)
|
||||
row.addWidget(tw)
|
||||
self.scroll_layout.addWidget(container)
|
||||
|
||||
@@ -809,7 +809,10 @@ class QtDriver(QObject):
|
||||
|
||||
def show_tag_database(self):
|
||||
self.modal = PanelModal(
|
||||
TagDatabasePanel(self.lib), "Library Tags", "Library Tags", has_save=False
|
||||
TagDatabasePanel(self.lib, self),
|
||||
"Library Tags",
|
||||
"Library Tags",
|
||||
has_save=False,
|
||||
)
|
||||
self.modal.show()
|
||||
|
||||
|
||||
@@ -74,8 +74,6 @@ class TagWidget(QWidget):
|
||||
# search_for_tag_action.triggered.connect(on_click_callback)
|
||||
search_for_tag_action.triggered.connect(self.on_click.emit)
|
||||
self.bg_button.addAction(search_for_tag_action)
|
||||
add_to_search_action = QAction("Add to Search", self)
|
||||
self.bg_button.addAction(add_to_search_action)
|
||||
|
||||
self.inner_layout = QHBoxLayout()
|
||||
self.inner_layout.setObjectName("innerLayout")
|
||||
|
||||
Reference in New Issue
Block a user