diff --git a/tagstudio/src/core/library.py b/tagstudio/src/core/library.py index c6c97bd2f..9d2e48f66 100644 --- a/tagstudio/src/core/library.py +++ b/tagstudio/src/core/library.py @@ -1349,10 +1349,18 @@ def search_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 @@ def search_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 @@ def search_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 @@ def search_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 @@ def add_entry(entry: Entry): 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 @@ def add_entry(entry: Entry): 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 @@ def get_tag(self, tag_id: int) -> Tag: 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 [] diff --git a/tagstudio/src/qt/modals/tag_database.py b/tagstudio/src/qt/modals/tag_database.py index 15c59c2ad..912562b2f 100644 --- a/tagstudio/src/qt/modals/tag_database.py +++ b/tagstudio/src/qt/modals/tag_database.py @@ -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 @@ def update_tags(self, query: str): 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) diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index f5b10cbd7..c298dd31b 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -809,7 +809,10 @@ def clear_select_action_callback(self): 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() diff --git a/tagstudio/src/qt/widgets/tag.py b/tagstudio/src/qt/widgets/tag.py index 739369dcf..f9d765b86 100644 --- a/tagstudio/src/qt/widgets/tag.py +++ b/tagstudio/src/qt/widgets/tag.py @@ -74,8 +74,6 @@ def __init__( # 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")