diff --git a/tagstudio/resources/translations/en.json b/tagstudio/resources/translations/en.json index caeb7149..8b954278 100644 --- a/tagstudio/resources/translations/en.json +++ b/tagstudio/resources/translations/en.json @@ -205,6 +205,7 @@ "status.library_version_found": "Found:", "status.library_version_mismatch": "Library Version Mismatch!", "status.results_found": "{count} Results Found ({time_span})", + "status.results.invalid_syntax": "Invalid Search Syntax:", "status.results": "Results", "tag_manager.title": "Library Tags", "tag.add_to_search": "Add to Search", diff --git a/tagstudio/src/core/library/alchemy/enums.py b/tagstudio/src/core/library/alchemy/enums.py index 952b81cd..7ae865ed 100644 --- a/tagstudio/src/core/library/alchemy/enums.py +++ b/tagstudio/src/core/library/alchemy/enums.py @@ -2,11 +2,14 @@ import enum from dataclasses import dataclass, replace from pathlib import Path +import structlog from src.core.query_lang import AST as Query # noqa: N811 from src.core.query_lang import Constraint, ConstraintType, Parser MAX_SQL_VARIABLES = 32766 # 32766 is the max sql bind parameter count as defined here: https://github.com/sqlite/sqlite/blob/master/src/sqliteLimit.h#L140 +logger = structlog.get_logger(__name__) + class TagColorEnum(enum.IntEnum): DEFAULT = 1 diff --git a/tagstudio/src/core/library/alchemy/library.py b/tagstudio/src/core/library/alchemy/library.py index 83466280..8d6299df 100644 --- a/tagstudio/src/core/library/alchemy/library.py +++ b/tagstudio/src/core/library/alchemy/library.py @@ -640,10 +640,11 @@ class Library: return session.query(exists().where(Entry.path == path)).scalar() def get_paths(self, glob: str | None = None) -> list[str]: + path_strings: list[str] = [] with Session(self.engine) as session: paths = session.scalars(select(Entry.path)).unique() + path_strings = list(map(lambda x: x.as_posix(), paths)) - path_strings: list[str] = list(map(lambda x: x.as_posix(), paths)) return path_strings def search_library( diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index f04f4349..5b001290 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -66,6 +66,7 @@ from src.core.library.alchemy.enums import ( from src.core.library.alchemy.fields import _FieldID from src.core.library.alchemy.library import Entry, LibraryStatus from src.core.media_types import MediaCategories +from src.core.query_lang.util import ParsingError from src.core.ts_core import TagStudioCore from src.core.utils.refresh_dir import RefreshDirTracker from src.core.utils.web import strip_web_protocol @@ -659,24 +660,26 @@ class QtDriver(DriverMixin, QObject): # in a global dict for methods to access for different DPIs. # adj_font_size = math.floor(12 * self.main_window.devicePixelRatio()) + def _filter_items(): + try: + self.filter_items( + FilterState.from_search_query(self.main_window.searchField.text()) + .with_sorting_mode(self.sorting_mode) + .with_sorting_direction(self.sorting_direction) + ) + except ParsingError as e: + self.main_window.statusbar.showMessage( + f"{Translations["status.results.invalid_syntax"]} " + f"\"{self.main_window.searchField.text()}\"" + ) + logger.error("[QtDriver] Could not filter items", error=e) + # Search Button search_button: QPushButton = self.main_window.searchButton - search_button.clicked.connect( - lambda: self.filter_items( - FilterState.from_search_query(self.main_window.searchField.text()) - .with_sorting_mode(self.sorting_mode) - .with_sorting_direction(self.sorting_direction) - ) - ) + search_button.clicked.connect(_filter_items) # Search Field search_field: QLineEdit = self.main_window.searchField - search_field.returnPressed.connect( - lambda: self.filter_items( - FilterState.from_search_query(self.main_window.searchField.text()) - .with_sorting_mode(self.sorting_mode) - .with_sorting_direction(self.sorting_direction) - ) - ) + search_field.returnPressed.connect(_filter_items) # Sorting Dropdowns sort_mode_dropdown: QComboBox = self.main_window.sorting_mode_combobox for sort_mode in SortingModeEnum: