From 94a0b000075a7323fc6ca4cfa9b64ce4da607916 Mon Sep 17 00:00:00 2001 From: yedpodtrzitko Date: Fri, 10 May 2024 01:41:38 +0800 Subject: [PATCH 1/5] add list of libraries into sidebar --- tagstudio/src/core/enums.py | 16 +++ tagstudio/src/core/ts_core.py | 2 + tagstudio/src/qt/ts_qt.py | 125 +++++++++++++++------ tagstudio/src/qt/widgets/preview_panel.py | 127 ++++++++++++++++++---- 4 files changed, 215 insertions(+), 55 deletions(-) create mode 100644 tagstudio/src/core/enums.py diff --git a/tagstudio/src/core/enums.py b/tagstudio/src/core/enums.py new file mode 100644 index 00000000..c406a523 --- /dev/null +++ b/tagstudio/src/core/enums.py @@ -0,0 +1,16 @@ +import enum + + +class SettingItems(str, enum.Enum): + """List of setting item names.""" + + START_LOAD_LAST = "start_load_last" + LAST_LIBRARY = "last_library" + LIBS_LIST = "libs_list" + WINDOW_SHOW_LIBS = "window_show_libs" + + +class Theme(str, enum.Enum): + COLOR_BG = "#65000000" + COLOR_HOVER = "#65AAAAAA" + COLOR_PRESSED = "#65EEEEEE" diff --git a/tagstudio/src/core/ts_core.py b/tagstudio/src/core/ts_core.py index abbfdda8..02753f5f 100644 --- a/tagstudio/src/core/ts_core.py +++ b/tagstudio/src/core/ts_core.py @@ -4,6 +4,7 @@ """The core classes and methods of TagStudio.""" +import enum import json import os @@ -18,6 +19,7 @@ BACKUP_FOLDER_NAME: str = "backups" COLLAGE_FOLDER_NAME: str = "collages" LIBRARY_FILENAME: str = "ts_library.json" + # TODO: Turn this whitelist into a user-configurable blacklist. IMAGE_TYPES: list[str] = [ "png", diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index 8d626c52..8cac543c 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -16,7 +16,7 @@ import time import webbrowser from datetime import datetime as dt from pathlib import Path -from queue import Empty, Queue +from queue import Queue from typing import Optional from PIL import Image @@ -46,6 +46,7 @@ from PySide6.QtWidgets import ( ) from humanfriendly import format_timespan +from src.core.enums import SettingItems from src.core.library import ItemType from src.core.ts_core import ( PLAINTEXT_TYPES, @@ -88,7 +89,9 @@ from src.qt.modals.file_extension import FileExtensionModal from src.qt.modals.fix_unlinked import FixUnlinkedEntriesModal from src.qt.modals.fix_dupes import FixDupeFilesModal from src.qt.modals.folders_to_tags import FoldersToTagsModal -import src.qt.resources_rc + +# this import has side-effect of import PySide resources +import src.qt.resources_rc # pylint: disable=unused-import # SIGQUIT is not defined on Windows if sys.platform == "win32": @@ -282,6 +285,7 @@ class QtDriver(QObject): edit_menu = QMenu("&Edit", menu_bar) tools_menu = QMenu("&Tools", menu_bar) macros_menu = QMenu("&Macros", menu_bar) + window_menu = QMenu("&Window", menu_bar) help_menu = QMenu("&Help", menu_bar) # File Menu ============================================================ @@ -376,6 +380,18 @@ class QtDriver(QObject): tag_database_action.triggered.connect(lambda: self.show_tag_database()) edit_menu.addAction(tag_database_action) + check_action = QAction("Open library on start", self) + check_action.setCheckable(True) + check_action.setChecked( + self.settings.value(SettingItems.START_LOAD_LAST, True, type=bool) + ) + check_action.triggered.connect( + lambda checked: self.settings.setValue( + SettingItems.START_LOAD_LAST, checked + ) + ) + window_menu.addAction(check_action) + # Tools Menu =========================================================== fix_unlinked_entries_action = QAction("Fix &Unlinked Entries", menu_bar) fue_modal = FixUnlinkedEntriesModal(self.lib, self) @@ -423,6 +439,20 @@ class QtDriver(QObject): macros_menu.addAction(self.sort_fields_action) folders_to_tags_action = QAction("Create Tags From Folders", menu_bar) + show_libs_list_action = QAction("Show Recent Libraries", menu_bar) + show_libs_list_action.setCheckable(True) + show_libs_list_action.setChecked( + self.settings.value(SettingItems.WINDOW_SHOW_LIBS, True, type=bool) + ) + show_libs_list_action.triggered.connect( + lambda checked: ( + self.settings.setValue(SettingItems.WINDOW_SHOW_LIBS, checked), + self.toggle_libs_list(checked), + ) + ) + window_menu.addAction(show_libs_list_action) + + folders_to_tags_action = QAction("Folders to Tags", menu_bar) ftt_modal = FoldersToTagsModal(self.lib, self) folders_to_tags_action.triggered.connect(lambda: ftt_modal.show()) macros_menu.addAction(folders_to_tags_action) @@ -440,6 +470,7 @@ class QtDriver(QObject): menu_bar.addMenu(edit_menu) menu_bar.addMenu(tools_menu) menu_bar.addMenu(macros_menu) + menu_bar.addMenu(window_menu) menu_bar.addMenu(help_menu) self.preview_panel = PreviewPanel(self.lib, self) @@ -458,6 +489,27 @@ class QtDriver(QObject): self.thumb_renderers: list[ThumbRenderer] = [] self.collation_thumb_size = math.ceil(self.thumb_size * 2) + self.init_library_window() + + lib = None + if self.args.open: + lib = self.args.open + elif self.settings.value(SettingItems.START_LOAD_LAST, True, type=bool): + lib = self.settings.value(SettingItems.LAST_LIBRARY) + + if lib: + self.splash.showMessage( + f'Opening Library "{lib}"...', + int(Qt.AlignmentFlag.AlignBottom | Qt.AlignmentFlag.AlignHCenter), + QColor("#9782ff"), + ) + self.open_library(lib) + + app.exec_() + + self.shutdown() + + def init_library_window(self): self._init_thumb_grid() # TODO: Put this into its own method that copies the font file(s) into memory @@ -510,31 +562,12 @@ class QtDriver(QObject): self.splash.finish(self.main_window) self.preview_panel.update_widgets() - # Check if a library should be opened on startup, args should override last_library - # TODO: check for behavior (open last, open default, start empty) - if ( - self.args.open - or self.settings.contains("last_library") - and os.path.isdir(self.settings.value("last_library")) - ): - if self.args.open: - lib = self.args.open - elif self.settings.value("last_library"): - lib = self.settings.value("last_library") - self.splash.showMessage( - f'Opening Library "{lib}"...', - int(Qt.AlignmentFlag.AlignBottom | Qt.AlignmentFlag.AlignHCenter), - QColor("#9782ff"), - ) - self.open_library(lib) - - if self.args.ci: - # gracefully terminate the app in CI environment - self.thumb_job_queue.put((self.SIGTERM.emit, [])) - - app.exec() - - self.shutdown() + def toggle_libs_list(self, value: bool): + if value: + self.preview_panel.libs_flow_container.show() + else: + self.preview_panel.libs_flow_container.hide() + self.preview_panel.update() def callback_library_needed_check(self, func): """Check if loaded library has valid path before executing the button function""" @@ -548,7 +581,7 @@ class QtDriver(QObject): """Save Library on Application Exit""" if self.lib.library_dir: self.save_library() - self.settings.setValue("last_library", self.lib.library_dir) + self.settings.setValue(SettingItems.LAST_LIBRARY, self.lib.library_dir) self.settings.sync() logging.info("[SHUTDOWN] Ending Thumbnail Threads...") for _ in self.thumb_threads: @@ -597,7 +630,7 @@ class QtDriver(QObject): self.main_window.statusbar.showMessage(f"Closing & Saving Library...") start_time = time.time() self.save_library(show_status=False) - self.settings.setValue("last_library", self.lib.library_dir) + self.settings.setValue(SettingItems.LAST_LIBRARY, self.lib.library_dir) self.settings.sync() self.lib.clear_internal_vars() @@ -709,7 +742,7 @@ class QtDriver(QObject): iterator.value.connect(lambda x: pw.update_progress(x + 1)) iterator.value.connect( lambda x: pw.update_label( - f'Scanning Directories for New Files...\n{x+1} File{"s" if x+1 != 1 else ""} Searched, {len(self.lib.files_not_in_library)} New Files Found' + f'Scanning Directories for New Files...\n{x + 1} File{"s" if x + 1 != 1 else ""} Searched, {len(self.lib.files_not_in_library)} New Files Found' ) ) r = CustomRunnable(lambda: iterator.run()) @@ -760,7 +793,7 @@ class QtDriver(QObject): iterator.value.connect(lambda x: pw.update_progress(x + 1)) iterator.value.connect( lambda x: pw.update_label( - f"Running Configured Macros on {x+1}/{len(new_ids)} New Entries" + f"Running Configured Macros on {x + 1}/{len(new_ids)} New Entries" ) ) r = CustomRunnable(lambda: iterator.run()) @@ -1297,6 +1330,34 @@ class QtDriver(QObject): # self.update_thumbs() + def update_libs_list(self, path: str): + # add library to list in SettingItems.LIBS_LIST + ITEMS_LIMIT = 5 + + self.settings.beginGroup(SettingItems.LIBS_LIST) + + current_time = str(time.time()) + all_libs = {current_time: path} + + for item_key in self.settings.allKeys(): + item_path = self.settings.value(item_key) + if item_path != path: + all_libs[item_key] = item_path + + # sort items by the most recent first + all_libs = sorted(all_libs.items(), key=lambda item: item[0], reverse=True) + + # remove previously saved items + self.settings.clear() + + for idx, (item_key, item_value) in enumerate(all_libs, start=1): + if idx > ITEMS_LIMIT: + break + self.settings.setValue(item_key, item_value) + + self.settings.endGroup() + self.settings.sync() + def open_library(self, path): """Opens a TagStudio library.""" if self.lib.library_dir: @@ -1314,7 +1375,7 @@ class QtDriver(QObject): # self.lib.refresh_missing_files() # title_text = f'{self.base_title} - Library \'{self.lib.library_dir}\'' # self.main_window.setWindowTitle(title_text) - pass + self.update_libs_list(path) else: logging.info( diff --git a/tagstudio/src/qt/widgets/preview_panel.py b/tagstudio/src/qt/widgets/preview_panel.py index 81d8c97a..935775fc 100644 --- a/tagstudio/src/qt/widgets/preview_panel.py +++ b/tagstudio/src/qt/widgets/preview_panel.py @@ -28,6 +28,7 @@ from PySide6.QtWidgets import ( ) from humanfriendly import format_size +from src.core.enums import SettingItems, Theme from src.core.library import Entry, ItemType, Library from src.core.ts_core import VIDEO_TYPES, IMAGE_TYPES from src.qt.helpers.file_opener import FileOpenerLabel, FileOpenerHelper, open_file @@ -41,6 +42,7 @@ from src.qt.widgets.text_box_edit import EditTextBox from src.qt.widgets.text_line_edit import EditTextLine from src.qt.widgets.item_thumb import ItemThumb + # Only import for type checking/autocompletion, will not be imported at runtime. if typing.TYPE_CHECKING: from src.qt.ts_qt import QtDriver @@ -74,17 +76,10 @@ class PreviewPanel(QWidget): self.img_button_size: tuple[int, int] = (266, 266) self.image_ratio: float = 1.0 - root_layout = QHBoxLayout(self) - root_layout.setContentsMargins(0, 0, 0, 0) - self.image_container = QWidget() image_layout = QHBoxLayout(self.image_container) image_layout.setContentsMargins(0, 0, 0, 0) - splitter = QSplitter() - splitter.setOrientation(Qt.Orientation.Vertical) - splitter.setHandleWidth(12) - self.open_file_action = QAction("Open file", self) self.open_explorer_action = QAction("Open file in explorer", self) @@ -111,16 +106,6 @@ class PreviewPanel(QWidget): ) ) - splitter.splitterMoved.connect( - lambda: self.update_image_size( - ( - self.image_container.size().width(), - self.image_container.size().height(), - ) - ) - ) - splitter.addWidget(self.image_container) - image_layout.addWidget(self.preview_img) image_layout.setAlignment(self.preview_img, Qt.AlignmentFlag.AlignCenter) @@ -137,7 +122,7 @@ class PreviewPanel(QWidget): # Qt.TextInteractionFlag.TextSelectableByMouse) properties_style = ( - f"background-color:#65000000;" + f"background-color:{Theme.COLOR_BG};" f"font-family:Oxanium;" f"font-weight:bold;" f"font-size:12px;" @@ -177,19 +162,47 @@ class PreviewPanel(QWidget): # rounded corners are maintained when scrolling. I was unable to # find the right trick to only select that particular element. scroll_area.setStyleSheet( - f"QWidget#entryScrollContainer{{" - "background:#65000000;" + "QWidget#entryScrollContainer{" + f"background: {Theme.COLOR_BG};" "border-radius:6px;" - f"}}" + "}" ) scroll_area.setWidget(scroll_container) info_layout.addWidget(self.file_label) info_layout.addWidget(self.dimensions_label) info_layout.addWidget(scroll_area) - splitter.addWidget(info_section) - root_layout.addWidget(splitter) + # keep list of rendered libraries to avoid needles re-rendering + self.render_libs = set() + self.libs_layout = QVBoxLayout() + self.fill_libs_widget(self.libs_layout) + + self.libs_flow_container: QWidget = QWidget() + self.libs_flow_container.setObjectName("librariesList") + self.libs_flow_container.setLayout(self.libs_layout) + + # set initial visibility based on settings + if not self.driver.settings.value( + SettingItems.WINDOW_SHOW_LIBS, True, type=bool + ): + self.libs_flow_container.hide() + + splitter = QSplitter() + splitter.setOrientation(Qt.Orientation.Vertical) + splitter.setHandleWidth(12) + splitter.splitterMoved.connect( + lambda: self.update_image_size( + ( + self.image_container.size().width(), + self.image_container.size().height(), + ) + ) + ) + + splitter.addWidget(self.image_container) + splitter.addWidget(info_section) + splitter.addWidget(self.libs_flow_container) splitter.setStretchFactor(1, 2) self.afb_container = QWidget() @@ -208,6 +221,71 @@ class PreviewPanel(QWidget): (self.image_container.size().width(), self.image_container.size().height()) ) + root_layout = QHBoxLayout(self) + root_layout.setContentsMargins(0, 0, 0, 0) + root_layout.addWidget(splitter) + + def fill_libs_widget(self, layout: QVBoxLayout): + settings = self.driver.settings + settings.beginGroup(SettingItems.LIBS_LIST) + lib_items: dict[str, tuple[str, str]] = {} + for item_tstamp in settings.allKeys(): + val = settings.value(item_tstamp) + cut_val = val + if len(val) > 45: + cut_val = f"{val[0:10]} ... {val[-10:]}" + lib_items[item_tstamp] = (val, cut_val) + + settings.endGroup() + + new_keys = set(lib_items.keys()) + if new_keys == self.render_libs: + # no need to re-render + return + + # sort lib_items by the key + libs_sorted = sorted(lib_items.items(), key=lambda item: item[0], reverse=True) + + self.render_libs = new_keys + return self._fill_libs_widget(libs_sorted, layout) + + def _fill_libs_widget( + self, libraries: list[tuple[str, tuple[str, str]]], layout: QVBoxLayout + ): + # remove any potential previous items + for idx in reversed(range(layout.count())): + widget = layout.itemAt(idx).widget() + layout.removeWidget(widget) + # remove from GUI + widget.setParent(None) + + label = QLabel("Recent Libraries") + label.setAlignment(Qt.AlignCenter) + layout.addWidget(label) + + for tstamp, (full_val, cut_val) in libraries: + button = QPushButton(text=cut_val) + button.setObjectName(f"path{tstamp}") + + def open_library_button_clicked(path): + return lambda: self.driver.open_library(path) + + button.clicked.connect(open_library_button_clicked(full_val)) + button.setStyleSheet( + "QPushButton{" + f"background-color:{Theme.COLOR_BG};" + "border-radius:6px;" + "text-align: left;" + "padding-top: 3px;" + "padding-left: 6px;" + "padding-bottom: 4px;" + "}" + f"QPushButton::hover{{background-color:{Theme.COLOR_HOVER};}}" + f"QPushButton::pressed{{background-color:{Theme.COLOR_PRESSED};}}" + ) + button.setCursor(Qt.CursorShape.PointingHandCursor) + layout.addWidget(button) + def resizeEvent(self, event: QResizeEvent) -> None: self.update_image_size( (self.image_container.size().width(), self.image_container.size().height()) @@ -309,6 +387,9 @@ class PreviewPanel(QWidget): # self.tag_callback = tag_callback if tag_callback else None window_title = "" + # update list of libraries + self.fill_libs_widget(self.libs_layout) + # 0 Selected Items if not self.driver.selected: if self.selected or not self.initialized: From 06f528f8b5491f0483d043e4c220392389017c99 Mon Sep 17 00:00:00 2001 From: yedpodtrzitko Date: Tue, 14 May 2024 10:30:58 +0800 Subject: [PATCH 2/5] CR feedback --- tagstudio/src/qt/ts_qt.py | 16 +++++++--------- tagstudio/src/qt/widgets/preview_panel.py | 10 +++++----- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index 8cac543c..217b1364 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -1330,29 +1330,27 @@ class QtDriver(QObject): # self.update_thumbs() - def update_libs_list(self, path: str): - # add library to list in SettingItems.LIBS_LIST + def update_libs_list(self, path: str | Path): + """add library to list in SettingItems.LIBS_LIST""" ITEMS_LIMIT = 5 + path = Path(path) self.settings.beginGroup(SettingItems.LIBS_LIST) - current_time = str(time.time()) - all_libs = {current_time: path} + all_libs = {str(time.time()): str(path)} for item_key in self.settings.allKeys(): item_path = self.settings.value(item_key) - if item_path != path: + if Path(item_path) != path: all_libs[item_key] = item_path - # sort items by the most recent first + # sort items, most recent first all_libs = sorted(all_libs.items(), key=lambda item: item[0], reverse=True) # remove previously saved items self.settings.clear() - for idx, (item_key, item_value) in enumerate(all_libs, start=1): - if idx > ITEMS_LIMIT: - break + for item_key, item_value in all_libs[:ITEMS_LIMIT]: self.settings.setValue(item_key, item_value) self.settings.endGroup() diff --git a/tagstudio/src/qt/widgets/preview_panel.py b/tagstudio/src/qt/widgets/preview_panel.py index 935775fc..19fef2ac 100644 --- a/tagstudio/src/qt/widgets/preview_panel.py +++ b/tagstudio/src/qt/widgets/preview_panel.py @@ -122,7 +122,7 @@ class PreviewPanel(QWidget): # Qt.TextInteractionFlag.TextSelectableByMouse) properties_style = ( - f"background-color:{Theme.COLOR_BG};" + f"background-color:{Theme.COLOR_BG.value};" f"font-family:Oxanium;" f"font-weight:bold;" f"font-size:12px;" @@ -163,7 +163,7 @@ class PreviewPanel(QWidget): # find the right trick to only select that particular element. scroll_area.setStyleSheet( "QWidget#entryScrollContainer{" - f"background: {Theme.COLOR_BG};" + f"background: {Theme.COLOR_BG.value};" "border-radius:6px;" "}" ) @@ -273,15 +273,15 @@ class PreviewPanel(QWidget): button.clicked.connect(open_library_button_clicked(full_val)) button.setStyleSheet( "QPushButton{" - f"background-color:{Theme.COLOR_BG};" + f"background-color:{Theme.COLOR_BG.value};" "border-radius:6px;" "text-align: left;" "padding-top: 3px;" "padding-left: 6px;" "padding-bottom: 4px;" "}" - f"QPushButton::hover{{background-color:{Theme.COLOR_HOVER};}}" - f"QPushButton::pressed{{background-color:{Theme.COLOR_PRESSED};}}" + f"QPushButton::hover{{background-color:{Theme.COLOR_HOVER.value};}}" + f"QPushButton::pressed{{background-color:{Theme.COLOR_PRESSED.value};}}" ) button.setCursor(Qt.CursorShape.PointingHandCursor) layout.addWidget(button) From a71ed7c4265dacebbf819a4cd35130888448c4b6 Mon Sep 17 00:00:00 2001 From: yedpodtrzitko Date: Tue, 14 May 2024 12:24:47 +0800 Subject: [PATCH 3/5] add button for removing recent lib --- tagstudio/src/core/ts_core.py | 2 - tagstudio/src/qt/ts_qt.py | 12 +++- tagstudio/src/qt/widgets/preview_panel.py | 83 ++++++++++++++++------- 3 files changed, 70 insertions(+), 27 deletions(-) diff --git a/tagstudio/src/core/ts_core.py b/tagstudio/src/core/ts_core.py index 02753f5f..abbfdda8 100644 --- a/tagstudio/src/core/ts_core.py +++ b/tagstudio/src/core/ts_core.py @@ -4,7 +4,6 @@ """The core classes and methods of TagStudio.""" -import enum import json import os @@ -19,7 +18,6 @@ BACKUP_FOLDER_NAME: str = "backups" COLLAGE_FOLDER_NAME: str = "collages" LIBRARY_FILENAME: str = "ts_library.json" - # TODO: Turn this whitelist into a user-configurable blacklist. IMAGE_TYPES: list[str] = [ "png", diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index 217b1364..eb029248 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -505,7 +505,11 @@ class QtDriver(QObject): ) self.open_library(lib) - app.exec_() + if self.args.ci: + # gracefully terminate the app in CI environment + self.thumb_job_queue.put((self.SIGTERM.emit, [])) + + app.exec() self.shutdown() @@ -1330,6 +1334,12 @@ class QtDriver(QObject): # self.update_thumbs() + def remove_recent_library(self, item_key: str): + self.settings.beginGroup(SettingItems.LIBS_LIST) + self.settings.remove(item_key) + self.settings.endGroup() + self.settings.sync() + def update_libs_list(self, path: str | Path): """add library to list in SettingItems.LIBS_LIST""" ITEMS_LIMIT = 5 diff --git a/tagstudio/src/qt/widgets/preview_panel.py b/tagstudio/src/qt/widgets/preview_panel.py index 19fef2ac..b10fdd20 100644 --- a/tagstudio/src/qt/widgets/preview_panel.py +++ b/tagstudio/src/qt/widgets/preview_panel.py @@ -173,7 +173,7 @@ class PreviewPanel(QWidget): info_layout.addWidget(self.dimensions_label) info_layout.addWidget(scroll_area) - # keep list of rendered libraries to avoid needles re-rendering + # keep list of rendered libraries to avoid needless re-rendering self.render_libs = set() self.libs_layout = QVBoxLayout() self.fill_libs_widget(self.libs_layout) @@ -247,44 +247,79 @@ class PreviewPanel(QWidget): libs_sorted = sorted(lib_items.items(), key=lambda item: item[0], reverse=True) self.render_libs = new_keys - return self._fill_libs_widget(libs_sorted, layout) + self._fill_libs_widget(libs_sorted, layout) def _fill_libs_widget( self, libraries: list[tuple[str, tuple[str, str]]], layout: QVBoxLayout ): + def clear_layout(layout_item: QVBoxLayout): + for i in reversed(range(layout_item.count())): + child = layout_item.itemAt(i) + if child.widget() is not None: + child.widget().deleteLater() + elif child.layout() is not None: + clear_layout(child.layout()) + # remove any potential previous items - for idx in reversed(range(layout.count())): - widget = layout.itemAt(idx).widget() - layout.removeWidget(widget) - # remove from GUI - widget.setParent(None) + clear_layout(layout) label = QLabel("Recent Libraries") label.setAlignment(Qt.AlignCenter) - layout.addWidget(label) - for tstamp, (full_val, cut_val) in libraries: + row_layout = QHBoxLayout() + row_layout.addWidget(label) + layout.addLayout(row_layout) + + def set_button_style(btn: QPushButton, extras: list[str] | None = None): + base_style = [ + f"background-color:{Theme.COLOR_BG.value};", + "border-radius:6px;", + "text-align: left;", + "padding-top: 3px;", + "padding-left: 6px;", + "padding-bottom: 4px;", + ] + + full_style_rows = base_style + (extras or []) + + btn.setStyleSheet( + ( + "QPushButton{" + f"{''.join(full_style_rows)}" + "}" + f"QPushButton::hover{{background-color:{Theme.COLOR_HOVER.value};}}" + f"QPushButton::pressed{{background-color:{Theme.COLOR_PRESSED.value};}}" + ) + ) + btn.setCursor(Qt.CursorShape.PointingHandCursor) + + for item_key, (full_val, cut_val) in libraries: button = QPushButton(text=cut_val) - button.setObjectName(f"path{tstamp}") + button.setObjectName(f"path{item_key}") def open_library_button_clicked(path): return lambda: self.driver.open_library(path) button.clicked.connect(open_library_button_clicked(full_val)) - button.setStyleSheet( - "QPushButton{" - f"background-color:{Theme.COLOR_BG.value};" - "border-radius:6px;" - "text-align: left;" - "padding-top: 3px;" - "padding-left: 6px;" - "padding-bottom: 4px;" - "}" - f"QPushButton::hover{{background-color:{Theme.COLOR_HOVER.value};}}" - f"QPushButton::pressed{{background-color:{Theme.COLOR_PRESSED.value};}}" - ) - button.setCursor(Qt.CursorShape.PointingHandCursor) - layout.addWidget(button) + set_button_style(button) + + button_remove = QPushButton("➖") + button_remove.setCursor(Qt.CursorShape.PointingHandCursor) + set_button_style(button_remove) + + def remove_recent_library_clicked(key: str): + return lambda: ( + self.driver.remove_recent_library(key), + self.fill_libs_widget(self.libs_layout), + ) + + button_remove.clicked.connect(remove_recent_library_clicked(item_key)) + + row_layout = QHBoxLayout() + row_layout.addWidget(button) + row_layout.addWidget(button_remove) + + layout.addLayout(row_layout) def resizeEvent(self, event: QResizeEvent) -> None: self.update_image_size( From f60a93f35be2b5f697e54192086639c7dee504f3 Mon Sep 17 00:00:00 2001 From: yedpodtrzitko Date: Tue, 14 May 2024 14:58:42 +0800 Subject: [PATCH 4/5] keep remove button small --- tagstudio/src/qt/widgets/preview_panel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tagstudio/src/qt/widgets/preview_panel.py b/tagstudio/src/qt/widgets/preview_panel.py index b10fdd20..9d040b38 100644 --- a/tagstudio/src/qt/widgets/preview_panel.py +++ b/tagstudio/src/qt/widgets/preview_panel.py @@ -305,6 +305,7 @@ class PreviewPanel(QWidget): button_remove = QPushButton("➖") button_remove.setCursor(Qt.CursorShape.PointingHandCursor) + button_remove.setFixedWidth(30) set_button_style(button_remove) def remove_recent_library_clicked(key: str): From 5d21375e65551e0b0e447c79fbdb5e68f80bf0fd Mon Sep 17 00:00:00 2001 From: yedpodtrzitko Date: Tue, 14 May 2024 15:51:41 +0800 Subject: [PATCH 5/5] dont expand recent libs --- tagstudio/src/qt/widgets/preview_panel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tagstudio/src/qt/widgets/preview_panel.py b/tagstudio/src/qt/widgets/preview_panel.py index 9d040b38..a2491624 100644 --- a/tagstudio/src/qt/widgets/preview_panel.py +++ b/tagstudio/src/qt/widgets/preview_panel.py @@ -181,6 +181,7 @@ class PreviewPanel(QWidget): self.libs_flow_container: QWidget = QWidget() self.libs_flow_container.setObjectName("librariesList") self.libs_flow_container.setLayout(self.libs_layout) + self.libs_flow_container.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) # set initial visibility based on settings if not self.driver.settings.value(