From feda1509f9b48619c7617713387481d034bcaab9 Mon Sep 17 00:00:00 2001 From: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com> Date: Fri, 3 Jan 2025 02:48:55 -0800 Subject: [PATCH] fix: badges now properly update --- tagstudio/src/qt/ts_qt.py | 16 ++-- tagstudio/src/qt/widgets/item_thumb.py | 2 +- .../qt/widgets/preview/field_containers.py | 10 +-- tagstudio/src/qt/widgets/preview_panel.py | 9 ++- tagstudio/src/qt/widgets/tag_box.py | 73 +------------------ 5 files changed, 20 insertions(+), 90 deletions(-) diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index f32e8793..a484e500 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -1011,14 +1011,14 @@ class QtDriver(DriverMixin, QObject): else: it.thumb_button.set_selected(False) - # # NOTE: By using the preview panel's "set_tags_updated_slot" method, - # # only the last of multiple identical item selections are connected. - # # If attaching the slot to multiple duplicate selections is needed, - # # just bypass the method and manually disconnect and connect the slots. - # if len(self.selected) == 1: - # for it in self.item_thumbs: - # if it.item_id == item_id: - # self.preview_panel.set_tags_updated_slot(it.refresh_badge) + # NOTE: By using the preview panel's "set_tags_updated_slot" method, + # only the last of multiple identical item selections are connected. + # If attaching the slot to multiple duplicate selections is needed, + # just bypass the method and manually disconnect and connect the slots. + if len(self.selected) == 1: + for it in self.item_thumbs: + if it.item_id == item_id: + self.preview_panel.fields.set_tags_updated_slot(it.refresh_badge) self.set_macro_menu_viability() self.preview_panel.update_widgets() diff --git a/tagstudio/src/qt/widgets/item_thumb.py b/tagstudio/src/qt/widgets/item_thumb.py index 20dacfc7..344035c2 100644 --- a/tagstudio/src/qt/widgets/item_thumb.py +++ b/tagstudio/src/qt/widgets/item_thumb.py @@ -322,7 +322,7 @@ class ItemThumb(FlowWidget): return self.badge_active[BadgeType.FAVORITE] @property - def is_archived(self): + def is_archived(self) -> bool: return self.badge_active[BadgeType.ARCHIVED] def set_mode(self, mode: ItemType | None) -> None: diff --git a/tagstudio/src/qt/widgets/preview/field_containers.py b/tagstudio/src/qt/widgets/preview/field_containers.py index 5ce97dcc..ec07281b 100644 --- a/tagstudio/src/qt/widgets/preview/field_containers.py +++ b/tagstudio/src/qt/widgets/preview/field_containers.py @@ -6,6 +6,7 @@ import sys import typing from collections.abc import Callable from datetime import datetime as dt +from warnings import catch_warnings import structlog from PySide6.QtCore import Qt, Signal @@ -53,7 +54,6 @@ class FieldContainers(QWidget): def __init__(self, library: Library, driver: "QtDriver"): super().__init__() - self.is_connected = False self.lib = library self.driver: QtDriver = driver self.initialized = False @@ -209,6 +209,7 @@ class FieldContainers(QWidget): entry.id, tag_ids=tags, ) + self.tags_updated.emit() def write_container(self, index: int, field: BaseField, is_mixed: bool = False): """Update/Create data for a FieldContainer. @@ -388,10 +389,8 @@ class FieldContainers(QWidget): if isinstance(inner_widget, TagBoxWidget): logger.warning("recycling") inner_widget.set_tags(tags) - try: + with catch_warnings(record=True): inner_widget.updated.disconnect() - except RuntimeError: - logger.error("[FieldContainers] Failed to disconnect inner_container.updated") else: logger.warning("creating new") @@ -466,9 +465,8 @@ class FieldContainers(QWidget): def set_tags_updated_slot(self, slot: object): """Replacement for tag_callback.""" - if self.is_connected: + with catch_warnings(record=True): self.tags_updated.disconnect() logger.info("[FieldContainers][set_tags_updated_slot] Setting tags updated slot") self.tags_updated.connect(slot) - self.is_connected = True diff --git a/tagstudio/src/qt/widgets/preview_panel.py b/tagstudio/src/qt/widgets/preview_panel.py index 3aa11ddd..009ce524 100644 --- a/tagstudio/src/qt/widgets/preview_panel.py +++ b/tagstudio/src/qt/widgets/preview_panel.py @@ -36,11 +36,10 @@ class PreviewPanel(QWidget): def __init__(self, library: Library, driver: "QtDriver"): super().__init__() - self.is_connected = False self.lib = library self.driver: QtDriver = driver self.initialized = False - self.is_open: bool = False + self.is_open: bool = True self.thumb = PreviewThumb(library, driver) self.file_attrs = FileAttributes(library, driver) @@ -147,10 +146,12 @@ class PreviewPanel(QWidget): return True def update_add_field_button(self, entry: Entry): - if self.add_field_modal.is_connected: + with catch_warnings(record=True): self.add_field_modal.done.disconnect() - if self.add_field_button.is_connected: self.add_field_button.clicked.disconnect() + # TODO: Remove all "is_connected" instances across the codebase + self.add_field_modal.is_connected = False + self.add_field_button.is_connected = False self.add_field_modal.done.connect( lambda f: ( diff --git a/tagstudio/src/qt/widgets/tag_box.py b/tagstudio/src/qt/widgets/tag_box.py index 42b034c2..8802dafa 100644 --- a/tagstudio/src/qt/widgets/tag_box.py +++ b/tagstudio/src/qt/widgets/tag_box.py @@ -44,48 +44,13 @@ class TagBoxWidget(FieldWidget): self.base_layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.base_layout) - # self.add_button = QPushButton() - # self.add_button.setCursor(Qt.CursorShape.PointingHandCursor) - # self.add_button.setMinimumSize(23, 23) - # self.add_button.setMaximumSize(23, 23) - # self.add_button.setText("+") - # self.add_button.setStyleSheet( - # f"QPushButton{{" - # f"background: #1e1e1e;" - # f"color: #FFFFFF;" - # f"font-weight: bold;" - # f"border-color: #333333;" - # f"border-radius: 6px;" - # f"border-style:solid;" - # f"border-width:{math.ceil(self.devicePixelRatio())}px;" - # f"padding-bottom: 5px;" - # f"font-size: 20px;" - # f"}}" - # f"QPushButton::hover" - # f"{{" - # f"border-color: #CCCCCC;" - # f"background: #555555;" - # f"}}" - # ) - # tsp = TagSearchPanel(self.driver.lib) - # tsp.tag_chosen.connect(lambda x: self.add_tag_callback(x)) - # self.add_modal = PanelModal(tsp, title, "Add Tags") - # self.add_button.clicked.connect( - # lambda: ( - # tsp.update_tags(), - # self.add_modal.show(), - # ) - # ) - self.set_tags(self.tags) def set_tags(self, tags: typing.Iterable[Tag]): tags_ = sorted(list(tags), key=lambda tag: tag.name) logger.info("[TagBoxWidget] Tags:", tags=tags) - # is_recycled = False while self.base_layout.itemAt(0): self.base_layout.takeAt(0).widget().deleteLater() - # is_recycled = True for tag in tags_: tag_widget = TagWidget(tag, has_edit=True, has_remove=True) @@ -105,17 +70,6 @@ class TagBoxWidget(FieldWidget): tag_widget.on_edit.connect(lambda t=tag: self.edit_tag(t)) self.base_layout.addWidget(tag_widget) - # # Move or add the '+' button. - # if is_recycled: - # self.base_layout.addWidget(self.base_layout.takeAt(0).widget()) - # else: - # self.base_layout.addWidget(self.add_button) - - # Handles an edge case where there are no more tags and the '+' button - # doesn't move all the way to the left. - if self.base_layout.itemAt(0) and not self.base_layout.itemAt(1): - self.base_layout.update() - def edit_tag(self, tag: Tag): assert isinstance(tag, Tag), f"tag is {type(tag)}" build_tag_panel = BuildTagPanel(self.driver.lib, tag=tag) @@ -138,39 +92,16 @@ class TagBoxWidget(FieldWidget): ) self.edit_modal.show() - def add_tag_callback(self, tag_id: int): - logger.info("[TagBoxWidget] add_tag_callback", tag_id=tag_id, selected=self.driver.selected) - - # tag = self.driver.lib.get_tag(tag_id=tag_id) - for entry_id in self.driver.selected: - # entry: Entry = self.driver.frame_content[entry.id] - self.driver.lib.add_tags_to_entry(entry_id, tag_id) - - if not self.driver.lib.add_tags_to_entry(entry_id, tag_id): - # TODO - add some visible error - self.error_occurred.emit(Exception("Failed to add tag")) - - self.updated.emit() - - if tag_id in (TAG_FAVORITE, TAG_ARCHIVED): - self.driver.update_badges() - - def edit_tag_callback(self, tag: Tag): - self.driver.lib.update_tag(tag) - def remove_tag(self, tag_id: int): logger.info( "[TagBoxWidget] remove_tag", selected=self.driver.selected, - # field_type=self.field.type, ) for entry_id in self.driver.selected: - # entry = self.driver.frame_content[entry_id] self.driver.lib.remove_tags_from_entry(entry_id, tag_id) - # self.driver.lib.remove_field_tag(entry, tag_id, self.field.type_key) - self.updated.emit() + self.updated.emit() if tag_id in (TAG_FAVORITE, TAG_ARCHIVED): - self.driver.update_badges() + self.driver.update_badges(self.driver.selected)