|
11 | 11 | import dataclasses |
12 | 12 | import math |
13 | 13 | import os |
| 14 | +import re |
14 | 15 | import sys |
15 | 16 | import time |
16 | 17 | import webbrowser |
|
72 | 73 | ) |
73 | 74 | from src.core.library.alchemy.fields import _FieldID |
74 | 75 | from src.core.library.alchemy.library import LibraryStatus |
| 76 | +from src.core.media_types import MediaCategories |
75 | 77 | from src.core.ts_core import TagStudioCore |
76 | 78 | from src.core.utils.refresh_dir import RefreshDirTracker |
77 | 79 | from src.core.utils.web import strip_web_protocol |
@@ -445,6 +447,8 @@ def create_folders_tags_modal(): |
445 | 447 | menu_bar.addMenu(window_menu) |
446 | 448 | menu_bar.addMenu(help_menu) |
447 | 449 |
|
| 450 | + self.main_window.searchField.textChanged.connect(self.update_completions_list) |
| 451 | + |
448 | 452 | self.preview_panel = PreviewPanel(self.lib, self) |
449 | 453 | splitter = self.main_window.splitter |
450 | 454 | splitter.addWidget(self.preview_panel) |
@@ -949,6 +953,61 @@ def select_item(self, grid_index: int, append: bool, bridge: bool): |
949 | 953 | def set_macro_menu_viability(self): |
950 | 954 | self.autofill_action.setDisabled(not self.selected) |
951 | 955 |
|
| 956 | + def update_completions_list(self, text: str) -> None: |
| 957 | + matches = re.search(r"(mediatype|filetype|path|tag):(\"?[A-Za-z0-9\ \t]+\"?)?", text) |
| 958 | + |
| 959 | + completion_list: list[str] = [] |
| 960 | + if len(text) < 3: |
| 961 | + completion_list = ["mediatype:", "filetype:", "path:", "tag:"] |
| 962 | + self.main_window.searchFieldCompletionList.setStringList(completion_list) |
| 963 | + |
| 964 | + if not matches: |
| 965 | + return |
| 966 | + |
| 967 | + query_type: str |
| 968 | + query_value: str | None |
| 969 | + query_type, query_value = matches.groups() |
| 970 | + |
| 971 | + if not query_value: |
| 972 | + return |
| 973 | + |
| 974 | + if query_type == "tag": |
| 975 | + completion_list = list(map(lambda x: "tag:" + x.name, self.lib.tags)) |
| 976 | + elif query_type == "path": |
| 977 | + completion_list = list(map(lambda x: "path:" + x, self.lib.get_paths())) |
| 978 | + elif query_type == "mediatype": |
| 979 | + single_word_completions = map( |
| 980 | + lambda x: "mediatype:" + x.name, |
| 981 | + filter(lambda y: " " not in y.name, MediaCategories.ALL_CATEGORIES), |
| 982 | + ) |
| 983 | + single_word_completions_quoted = map( |
| 984 | + lambda x: 'mediatype:"' + x.name + '"', |
| 985 | + filter(lambda y: " " not in y.name, MediaCategories.ALL_CATEGORIES), |
| 986 | + ) |
| 987 | + multi_word_completions = map( |
| 988 | + lambda x: 'mediatype:"' + x.name + '"', |
| 989 | + filter(lambda y: " " in y.name, MediaCategories.ALL_CATEGORIES), |
| 990 | + ) |
| 991 | + |
| 992 | + all_completions = [ |
| 993 | + single_word_completions, |
| 994 | + single_word_completions_quoted, |
| 995 | + multi_word_completions, |
| 996 | + ] |
| 997 | + completion_list = [j for i in all_completions for j in i] |
| 998 | + elif query_type == "filetype": |
| 999 | + extensions_list: set[str] = set() |
| 1000 | + for media_cat in MediaCategories.ALL_CATEGORIES: |
| 1001 | + extensions_list = extensions_list | media_cat.extensions |
| 1002 | + completion_list = list(map(lambda x: "filetype:" + x.replace(".", ""), extensions_list)) |
| 1003 | + |
| 1004 | + update_completion_list: bool = ( |
| 1005 | + completion_list != self.main_window.searchFieldCompletionList.stringList() |
| 1006 | + or self.main_window.searchFieldCompletionList == [] |
| 1007 | + ) |
| 1008 | + if update_completion_list: |
| 1009 | + self.main_window.searchFieldCompletionList.setStringList(completion_list) |
| 1010 | + |
952 | 1011 | def update_thumbs(self): |
953 | 1012 | """Update search thumbnails.""" |
954 | 1013 | # start_time = time.time() |
|
0 commit comments