From b36992324f972242d0c7c14cb33617224198b72a Mon Sep 17 00:00:00 2001 From: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com> Date: Fri, 11 Sep 2026 21:17:24 -0700 Subject: [PATCH] ui: tweak UI, full height inspector, floating pagination bar --- src/tagstudio/qt/controllers/main_window.py | 72 +++++++++---------- src/tagstudio/qt/mixed/pagination.py | 39 ++++++++-- src/tagstudio/qt/qt_driver.py | 64 ++--------------- src/tagstudio/qt/views/inspector_view.py | 2 +- .../qt/views/layouts/thumb_grid_layout.py | 11 ++- src/tagstudio/qt/views/preview_thumb_view.py | 17 +++-- src/tagstudio/qt/views/styles/stylesheets.py | 14 ++++ src/tagstudio/resources/translations/en.json | 10 --- 8 files changed, 107 insertions(+), 122 deletions(-) diff --git a/src/tagstudio/qt/controllers/main_window.py b/src/tagstudio/qt/controllers/main_window.py index 5632fd37..1f4dcc84 100644 --- a/src/tagstudio/qt/controllers/main_window.py +++ b/src/tagstudio/qt/controllers/main_window.py @@ -31,7 +31,6 @@ from PySide6.QtWidgets import ( QSizePolicy, QSpacerItem, QSplitter, - QStatusBar, QVBoxLayout, QWidget, ) @@ -475,6 +474,7 @@ class MainWindow(QMainWindow): # initialized in setup_extra_input_bar self.extra_input_layout: QHBoxLayout + self.results_label: QLabel self.sorting_mode_combobox: QComboBox self.sorting_direction_combobox: QComboBox self.thumb_size_combobox: QComboBox @@ -482,6 +482,8 @@ class MainWindow(QMainWindow): # initialized in setup_content self.content_layout: QHBoxLayout self.content_splitter: QSplitter + self.central_content: QWidget + self.central_content_layout: QVBoxLayout # initialized in setup_entry_list self.entry_list_container: QWidget @@ -499,14 +501,12 @@ class MainWindow(QMainWindow): if not self.objectName(): self.setObjectName("MainWindow") - self.resize(1316, 740) + self.resize(1280, 720) self.setup_menu_bar() self.setup_central_widget(driver) - self.setup_status_bar() - QMetaObject.connectSlotsByName(self) # NOTE: These are old attempts to allow for a translucent/acrylic @@ -536,6 +536,7 @@ class MainWindow(QMainWindow): self.central_widget.setObjectName("central_widget") self.central_layout = QGridLayout(self.central_widget) self.central_layout.setObjectName("central_layout") + self.central_layout.setContentsMargins(0, 9, 0, 0) self.setup_search_bar() self.setup_extra_input_bar() @@ -547,6 +548,7 @@ class MainWindow(QMainWindow): self.search_bar_layout = QHBoxLayout() self.search_bar_layout.setObjectName("search_bar_layout") self.search_bar_layout.setSizeConstraint(QLayout.SizeConstraint.SetMinimumSize) + self.search_bar_layout.setContentsMargins(9, 0, 0, 0) self.back_button = QPushButton(self.central_widget) back_icon: Image.Image = self.rm.bxs_left_arrow @@ -584,12 +586,19 @@ class MainWindow(QMainWindow): self.search_button.setMinimumSize(QSize(0, 32)) self.search_bar_layout.addWidget(self.search_button) - self.central_layout.addLayout(self.search_bar_layout, 3, 0, 1, 1) - def setup_extra_input_bar(self): """Sets up inputs for sorting settings and thumbnail size.""" self.extra_input_layout = QHBoxLayout() self.extra_input_layout.setObjectName("extra_input_layout") + self.extra_input_layout.setContentsMargins(9, 0, 0, 0) + + self.results_label = QLabel("") + self.results_label.setObjectName("results_label") + self.extra_input_layout.addWidget(self.results_label) + + self.extra_input_layout.addItem( + QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) + ) ## Show hidden entries checkbox self.show_hidden_entries_widget = QWidget() @@ -610,11 +619,6 @@ class MainWindow(QMainWindow): self.extra_input_layout.addWidget(self.show_hidden_entries_widget) - ## Spacer - self.extra_input_layout.addItem( - QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) - ) - ## Sorting Mode Dropdown self.sorting_mode_combobox = QComboBox(self.central_widget) self.sorting_mode_combobox.setObjectName("sorting_mode_combobox") @@ -651,28 +655,39 @@ class MainWindow(QMainWindow): self.thumb_size_combobox.addItem(size[0], size[1]) self.thumb_size_combobox.setCurrentIndex(2) # Default: Medium - self.central_layout.addLayout(self.extra_input_layout, 5, 0, 1, 1) - def setup_content(self, driver: QtDriver): self.content_layout = QHBoxLayout() self.content_layout.setObjectName("content_layout") + self.content_layout.setContentsMargins(0, 0, 0, 0) self.content_splitter = QSplitter() self.content_splitter.setObjectName("content_splitter") self.content_splitter.setHandleWidth(12) + self.central_content = QWidget() + self.central_content.setObjectName("central_content") + self.central_content_layout = QVBoxLayout(self.central_content) + self.central_content_layout.setObjectName("central_content_layout") + self.central_content_layout.setContentsMargins(0, 0, 0, 0) + self.central_content_layout.setSpacing(6) + self.central_content_layout.addLayout(self.search_bar_layout) + self.central_content_layout.addLayout(self.extra_input_layout) + self.setup_entry_list(driver) + self.content_splitter.addWidget(self.central_content) + self.setup_preview_panel(driver) self.content_splitter.setStretchFactor(0, 1) self.content_layout.addWidget(self.content_splitter) - self.central_layout.addLayout(self.content_layout, 10, 0, 1, 1) + self.central_layout.addLayout(self.content_layout, 0, 0, 1, 1) def setup_entry_list(self, driver: QtDriver): self.entry_list_container = QWidget() self.entry_list_layout = QVBoxLayout(self.entry_list_container) self.entry_list_layout.setSpacing(0) + self.entry_list_layout.setContentsMargins(9, 0, 0, 0) self.entry_scroll_area = QScrollArea() self.entry_scroll_area.setObjectName("entry_scroll_area") @@ -687,8 +702,10 @@ class MainWindow(QMainWindow): self.thumb_grid = QWidget() self.thumb_grid.setObjectName("thumb_grid") - self.thumb_layout = ThumbGridLayout(driver, self.entry_scroll_area) - self.thumb_layout.setSpacing(min(self.thumb_size // 10, 12)) + # Padding so floating pagination bar doesn't block bottom of scroll contents + self.thumb_layout = ThumbGridLayout( + driver, self.entry_scroll_area, bottom_padding=Pagination.HEIGHT + ) self.thumb_layout.setAlignment(Qt.AlignmentFlag.AlignCenter) self.thumb_grid.setLayout(self.thumb_layout) self.entry_scroll_area.setWidget(self.thumb_grid) @@ -697,34 +714,15 @@ class MainWindow(QMainWindow): self.entry_list_layout.addWidget(self.banner) self.entry_list_layout.addWidget(self.entry_scroll_area) - self.landing_widget = LandingWidget(driver, self.devicePixelRatio()) self.entry_list_layout.addWidget(self.landing_widget) - - self.pagination = Pagination() - self.entry_list_layout.addWidget(self.pagination) - - self.content_splitter.addWidget(self.entry_list_container) + self.pagination = Pagination(self.entry_list_container) + self.central_content_layout.addWidget(self.entry_list_container) def setup_preview_panel(self, driver: QtDriver): self.preview_panel = Inspector(driver) self.content_splitter.addWidget(self.preview_panel) - def setup_status_bar(self): - # BUG: Clicking the status bar does not count as losing focus on other widgets - # (for example, the "Add Tag" line edit). Can this be fixed? - self.status_bar = QStatusBar(self) - self.status_bar.setObjectName("status_bar") - status_bar_size_policy = QSizePolicy( - QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Maximum - ) - status_bar_size_policy.setHorizontalStretch(0) - status_bar_size_policy.setVerticalStretch(0) - status_bar_size_policy.setHeightForWidth(self.status_bar.sizePolicy().hasHeightForWidth()) - self.status_bar.setSizePolicy(status_bar_size_policy) - self.status_bar.setSizeGripEnabled(False) - self.setStatusBar(self.status_bar) - # endregion def toggle_landing_page(self, enabled: bool): diff --git a/src/tagstudio/qt/mixed/pagination.py b/src/tagstudio/qt/mixed/pagination.py index 78cf7316..d1a26bcd 100644 --- a/src/tagstudio/qt/mixed/pagination.py +++ b/src/tagstudio/qt/mixed/pagination.py @@ -7,18 +7,23 @@ from typing import cast, override from warnings import catch_warnings from PIL import Image, ImageQt -from PySide6.QtCore import QSize, Signal +from PySide6.QtCore import QEvent, QObject, QSize, Qt, Signal from PySide6.QtGui import QIntValidator, QPixmap -from PySide6.QtWidgets import QHBoxLayout, QLabel, QLineEdit, QPushButton, QSizePolicy, QWidget +from PySide6.QtWidgets import QHBoxLayout, QLabel, QLineEdit, QPushButton, QWidget from tagstudio.qt.resource_manager import ResourceManager from tagstudio.qt.views.styles.color_overlay import auto_theme_overlay +from tagstudio.qt.views.styles.stylesheets import pagination_style # TODO: Split to use MVC guidelines. class Pagination(QWidget): """Widget containing controls for navigating between pages of items.""" + HEIGHT = 36 # Button row height (24) plus 6px above and below. + RIGHT_MARGIN = 6 + SCROLLBAR_WIDTH = 14 + index = Signal(int) def __init__(self, parent: QWidget | None = None) -> None: @@ -37,11 +42,18 @@ class Pagination(QWidget): # [----------- ROOT LAYOUT ------------] self.setHidden(True) + self.setObjectName("pagination") + self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground) + self.setFixedHeight(self.HEIGHT) + self.setStyleSheet(pagination_style()) self.root_layout = QHBoxLayout(self) - self.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred) - self.root_layout.setContentsMargins(0, 6, 0, 0) + self.root_layout.setContentsMargins(0, 6, 0, 6) self.root_layout.setSpacing(3) + if parent is not None: + parent.installEventFilter(self) + self._sync_geometry() + # [<] ---------------------------------- self.prev_button = QPushButton() prev_icon: Image.Image = self.rm.bxs_left_arrow @@ -60,6 +72,7 @@ class Pagination(QWidget): self.start_ellipses = QLabel() self.start_ellipses.setMinimumSize(self.button_size) self.start_ellipses.setMaximumSize(self.button_size) + # self.start_ellipses.setAlignment(Qt.AlignmentFlag.AlignCenter) self.start_ellipses.setText(". . .") # --------- [3][4] --------------------- @@ -88,6 +101,7 @@ class Pagination(QWidget): self.end_ellipses = QLabel() self.end_ellipses.setMinimumSize(self.button_size) self.end_ellipses.setMaximumSize(self.button_size) + # self.end_ellipses.setAlignment(Qt.AlignmentFlag.AlignCenter) self.end_ellipses.setText(". . .") # ----------------------------- [42] --- @@ -258,6 +272,8 @@ class Pagination(QWidget): self.start_buffer_layout.itemAt(i - 1).widget().setHidden(True) self.setHidden(False) + self._sync_geometry() + self.raise_() self.validator.setTop(page_count) if emit: @@ -287,6 +303,21 @@ class Pagination(QWidget): end_button.setHidden(True) self.end_buffer_layout.addWidget(end_button) + @override + def eventFilter(self, watched: QObject, event: QEvent) -> bool: + if watched is self.parentWidget() and event.type() == QEvent.Type.Resize: + self._sync_geometry() + return super().eventFilter(watched, event) + + def _sync_geometry(self): + parent = self.parentWidget() + if parent is None: + return + # Stays out of the way of the entry view scrollbar + right_inset = max(self.RIGHT_MARGIN, self.SCROLLBAR_WIDTH) + width = max(0, parent.width() - right_inset) + self.setGeometry(0, parent.height() - self.HEIGHT, width, self.HEIGHT) + class Validator(QIntValidator): def __init__(self, bottom: int, top: int) -> None: diff --git a/src/tagstudio/qt/qt_driver.py b/src/tagstudio/qt/qt_driver.py index bcc0907a..fce01efa 100644 --- a/src/tagstudio/qt/qt_driver.py +++ b/src/tagstudio/qt/qt_driver.py @@ -654,7 +654,6 @@ class QtDriver(DriverMixin, QObject): self.shutdown() def show_error_message(self, error_name: str, error_desc: str | None = None): - self.main_window.status_bar.showMessage(error_name, Qt.AlignmentFlag.AlignLeft) self.main_window.landing_widget.set_status_label(error_name) self.main_window.setWindowTitle(f"{self.base_title} - {error_name}") @@ -689,7 +688,7 @@ class QtDriver(DriverMixin, QObject): .with_show_hidden_entries(self.main_window.show_hidden_entries) ) except ParsingError as e: - self.main_window.status_bar.showMessage( + self.main_window.results_label.setText( f"{Translations['status.results.invalid_syntax']} " f'"{self.main_window.search_field.text()}"' ) @@ -797,15 +796,13 @@ class QtDriver(DriverMixin, QObject): self._banner_context = None self.main_window.banner.hide_banner(force=True) - self.main_window.status_bar.showMessage(Translations["status.library_closing"]) - start_time = time.time() - self.cached_values.setValue(AppCacheItems.LAST_LIBRARY, str(self.lib.library_dir)) self.cached_values.sync() # Reset library state self.main_window.preview_panel.set_selection(self.selected) self.main_window.search_field.setText("") + self.main_window.results_label.setText("") scrollbar: QScrollArea = self.main_window.entry_scroll_area scrollbar.verticalScrollBar().setValue(0) self.__reset_navigation() @@ -860,26 +857,9 @@ class QtDriver(DriverMixin, QObject): if self.main_window.menu_bar.add_tag_to_selected_action: self.main_window.menu_bar.add_tag_to_selected_action.setEnabled(False) - end_time = time.time() - self.main_window.status_bar.showMessage( - Translations.format( - "status.library_closed", time_span=format_timespan(end_time - start_time) - ) - ) - def backup_library(self): logger.info("Backing Up Library...") - self.main_window.status_bar.showMessage(Translations["status.library_backup_in_progress"]) - start_time = time.time() - target_path = Library.save_library_backup_to_disk(unwrap(self.lib.library_dir)) - end_time = time.time() - self.main_window.status_bar.showMessage( - Translations.format( - "status.library_backup_success", - path=target_path, - time_span=format_timespan(end_time - start_time), - ) - ) + Library.save_library_backup_to_disk(unwrap(self.lib.library_dir)) def emit_badge_signals(self, tag_ids: list[int] | set[int], emit_on_absent: bool = True): """Emit any connected signals for updating badge icons.""" @@ -967,7 +947,6 @@ class QtDriver(DriverMixin, QObject): """ entry: Entry | None = None pending: list[tuple[int | None, Path]] = [] - deleted_count: int = 0 selected = self.selected library_dir = unwrap(self.lib.library_dir) @@ -991,37 +970,17 @@ class QtDriver(DriverMixin, QObject): return_code == QMessageBox.ButtonRole.DestructiveRole.value and return_code != QMessageBox.ButtonRole.ActionRole.value ): - for i, tup in enumerate(pending): - e_id, f = tup + for e_id, f in pending: if (origin_path == f) or (not origin_path): self.main_window.preview_panel.stop_media_playback() - msg = Translations.format( - "status.deleting_file", i=i, count=len(pending), path=f - ) - self.main_window.status_bar.showMessage(msg) - self.main_window.status_bar.repaint() - if e_id is not None: self.lib.remove_entries([e_id]) - if delete_file(library_dir / f): - deleted_count += 1 + delete_file(library_dir / f) self.clear_select_action_callback() self.update_browsing_state() - if deleted_count > 0 and deleted_count != len(pending): - msg = Translations.format("status.deleted_partial_warning", count=deleted_count) - else: - index = min(deleted_count, 2) - msg = ( - Translations["status.deleted_none"], - Translations["status.deleted_file_singular"], - Translations.format("status.deleted_file_plural", count=deleted_count), - )[index] - self.main_window.status_bar.showMessage(msg) - self.main_window.status_bar.repaint() - def delete_file_confirmation(self, count: int, filename: Path | None = None) -> int: """A confirmation dialogue box for deleting files. @@ -1398,9 +1357,6 @@ class QtDriver(DriverMixin, QObject): def thumb_size_callback(self, size: int): """Perform actions needed when the thumbnail size selection is changed.""" - spacing_divisor: int = 10 - min_spacing: int = 12 - self.update_thumbs() blank_icon: QIcon = QIcon() for it in self.main_window.thumb_layout._item_thumbs: @@ -1410,9 +1366,6 @@ class QtDriver(DriverMixin, QObject): it.setFixedSize(self.main_window.thumb_size, self.main_window.thumb_size) it.thumb_button.thumb_size = (self.main_window.thumb_size, self.main_window.thumb_size) it.set_filename_visibility(it.show_filename_label) - self.main_window.thumb_layout.setSpacing( - min(self.main_window.thumb_size // spacing_divisor, min_spacing) - ) def show_hidden_entries_callback(self): logger.info("Show Hidden Entries Changed", exclude=self.main_window.show_hidden_entries) @@ -1680,10 +1633,6 @@ class QtDriver(DriverMixin, QObject): self.main_window.search_field.setText(self.browsing_history.current.query or "") - # inform user about running search - self.main_window.status_bar.showMessage(Translations["status.library_search_query"]) - self.main_window.status_bar.repaint() - # search the library start_time = time.time() Ignore.get_patterns(self.lib.library_dir, include_global=True) @@ -1692,7 +1641,7 @@ class QtDriver(DriverMixin, QObject): end_time = time.time() # inform user about completed search - self.main_window.status_bar.showMessage( + self.main_window.results_label.setText( Translations.format( "status.results_found", count=results.total_count, @@ -1814,7 +1763,6 @@ class QtDriver(DriverMixin, QObject): ) message = Translations.format("splash.opening_library", library_path=library_dir_display) self.main_window.landing_widget.set_status_label(message) - self.main_window.status_bar.showMessage(message, 3) self.main_window.repaint() if self.lib.library_dir: diff --git a/src/tagstudio/qt/views/inspector_view.py b/src/tagstudio/qt/views/inspector_view.py index 3195d0e2..de30b381 100644 --- a/src/tagstudio/qt/views/inspector_view.py +++ b/src/tagstudio/qt/views/inspector_view.py @@ -30,7 +30,7 @@ logger = structlog.get_logger(__name__) class InspectorView(QVBoxLayout): def __init__(self, driver: QtDriver, pixel_ratio: float) -> None: super().__init__() - self.setContentsMargins(0, 0, 0, 0) + self.setContentsMargins(0, 0, 9, 9) self.setSpacing(6) rm = ResourceManager() diff --git a/src/tagstudio/qt/views/layouts/thumb_grid_layout.py b/src/tagstudio/qt/views/layouts/thumb_grid_layout.py index dc1f6919..9754bdac 100644 --- a/src/tagstudio/qt/views/layouts/thumb_grid_layout.py +++ b/src/tagstudio/qt/views/layouts/thumb_grid_layout.py @@ -24,13 +24,18 @@ if TYPE_CHECKING: class ThumbGridLayout(QLayout): + SPACING = 9 + # Id of first visible entry visible_changed = Signal(int) - def __init__(self, driver: QtDriver, scroll_area: QScrollArea) -> None: + def __init__(self, driver: QtDriver, scroll_area: QScrollArea, bottom_padding: int = 0) -> None: super().__init__(None) + self.setContentsMargins(0, 0, 0, 0) + self.setSpacing(self.SPACING) self.driver: QtDriver = driver self.scroll_area: QScrollArea = scroll_area + self._bottom_padding: int = bottom_padding self._item_thumbs: list[ItemThumb] = [] self._items: list[QLayoutItem] = [] @@ -183,8 +188,8 @@ class ThumbGridLayout(QLayout): width = arg__1 per_row, _, height_offset = self._size(width) if per_row == 0: - return height_offset - return math.ceil(len(self._entry_ids) / per_row) * height_offset + return height_offset + self._bottom_padding + return math.ceil(len(self._entry_ids) / per_row) * height_offset + self._bottom_padding @override def setGeometry(self, arg__1: QRect) -> None: diff --git a/src/tagstudio/qt/views/preview_thumb_view.py b/src/tagstudio/qt/views/preview_thumb_view.py index 13f6c9c3..5fdb5f3b 100644 --- a/src/tagstudio/qt/views/preview_thumb_view.py +++ b/src/tagstudio/qt/views/preview_thumb_view.py @@ -47,7 +47,6 @@ class PreviewThumbView(QWidget): check_ffmpeg = Signal(bool) stats_updated = Signal(Path, FileAttributeData) - __img_button_size: tuple[int, int] __image_ratio: float _current_file: Path | None @@ -58,7 +57,7 @@ class PreviewThumbView(QWidget): super().__init__() self._driver = driver - self.__img_button_size = (266, 266) + self._preview_size: tuple[int, int] = (272, 272) self.__image_ratio = 1.0 self.__should_render_on_resize = False @@ -79,7 +78,7 @@ class PreviewThumbView(QWidget): delete_action.triggered.connect(self._delete_action_callback) self.__button_wrapper = QPushButton() - self.__button_wrapper.setMinimumSize(*self.__img_button_size) + self.__button_wrapper.setMinimumSize(*self._preview_size) self.__button_wrapper.setFlat(True) self.__button_wrapper.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu) self.__button_wrapper.addAction(open_file_action) @@ -93,7 +92,7 @@ class PreviewThumbView(QWidget): self.__stacked_page_setup(self.__preview_img_page, self.__button_wrapper) self.__preview_gif = QLabel() - self.__preview_gif.setMinimumSize(*self.__img_button_size) + self.__preview_gif.setMinimumSize(*self._preview_size) self.__preview_gif.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu) self.__preview_gif.setCursor(Qt.CursorShape.ArrowCursor) self.__preview_gif.addAction(open_file_action) @@ -129,7 +128,7 @@ class PreviewThumbView(QWidget): self.__image_layout.addWidget(self.__preview_gif_page) self.__image_layout.addWidget(self.__media_player_page) - self.setMinimumSize(*self.__img_button_size) + self.setMinimumSize(*self._preview_size) self.hide_preview() @@ -194,7 +193,7 @@ class PreviewThumbView(QWidget): adj_size = QSize(int(adj_width), int(adj_height)) - self.__img_button_size = (int(adj_width), int(adj_height)) + self._preview_size = (int(adj_width), int(adj_height)) self.__button_wrapper.setMaximumSize(adj_size) self.__button_wrapper.setIconSize(adj_size) self.__preview_gif.setMaximumSize(adj_size) @@ -243,8 +242,8 @@ class PreviewThumbView(QWidget): self.__should_render_on_resize = True self.__rendered_res = ( - math.ceil(self.__img_button_size[0] * THUMB_SIZE_FACTOR), - math.ceil(self.__img_button_size[1] * THUMB_SIZE_FACTOR), + math.ceil(self._preview_size[0] * THUMB_SIZE_FACTOR), + math.ceil(self._preview_size[1] * THUMB_SIZE_FACTOR), ) # TODO: Make driver update the cache manager reference here instead of passing the driver. @@ -343,7 +342,7 @@ class PreviewThumbView(QWidget): if ( self._current_file is not None and self.__should_render_on_resize - and self.__rendered_res < self.__img_button_size + and self.__rendered_res < self._preview_size ): self.__render_thumb(self._current_file) diff --git a/src/tagstudio/qt/views/styles/stylesheets.py b/src/tagstudio/qt/views/styles/stylesheets.py index 417b795b..4cc7d12b 100644 --- a/src/tagstudio/qt/views/styles/stylesheets.py +++ b/src/tagstudio/qt/views/styles/stylesheets.py @@ -688,6 +688,20 @@ def banner_progress_style() -> str: """ +def pagination_style() -> str: + """Style for the pagination bar.""" + bg = QColor(banner_progress_bg_color()) + bg.setAlpha(200) + border = "rgba(200, 200, 200, 30)" + + return f""" + QWidget#pagination {{ + background-color: rgba{bg.toTuple()}; + border-top: 1px solid {border}; + }} + """ + + def banner_progress_chunk_color() -> QColor: """Fill color for the banner's custom-painted progress bar chunk.""" is_dark = _is_dark_theme() diff --git a/src/tagstudio/resources/translations/en.json b/src/tagstudio/resources/translations/en.json index 6344844e..6a612f85 100644 --- a/src/tagstudio/resources/translations/en.json +++ b/src/tagstudio/resources/translations/en.json @@ -373,17 +373,7 @@ "sorting.direction.descending": "Descending", "sorting.mode.random": "Random", "splash.opening_library": "Opening Library \"{library_path}\"…", - "status.deleted_file_plural": "Deleted {count} files!", - "status.deleted_file_singular": "Deleted 1 file!", - "status.deleted_none": "No files deleted.", - "status.deleted_partial_warning": "Only deleted {count} file(s)! Check if any of the files are currently missing or in use.", - "status.deleting_file": "Deleting file [{i}/{count}]: \"{path}\"…", - "status.library_backup_in_progress": "Saving Library Backup…", - "status.library_backup_success": "Library Backup Saved at: \"{path}\" ({time_span})", - "status.library_closed": "Library Closed ({time_span})", - "status.library_closing": "Closing Library…", "status.library_save_success": "Library Saved and Closed!", - "status.library_search_query": "Searching Library…", "status.library_version_expected": "Expected:", "status.library_version_found": "Found:", "status.library_version_mismatch": "Library Version Mismatch!",