Skip to content

Type fixes to folders_to_tags.py, collage_icon.py and item_thumb.py #959

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions src/tagstudio/qt/modals/folders_to_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ def reverse_tag(library: Library, tag: Tag, items: list[Tag] | None) -> list[Tag
items.reverse()
return items

for subtag_id in tag.parent_ids:
subtag = library.get_tag(subtag_id)
return reverse_tag(library, subtag, items)
parent_tag = None # to avoid subtag unbound error
for parent_tag_id in tag.parent_ids:
parent_tag = library.get_tag(parent_tag_id)
assert parent_tag is not None
return reverse_tag(library, parent_tag, items)


# =========== UI ===========
Expand Down Expand Up @@ -132,7 +134,7 @@ def _add_folders_to_tree(items: Sequence[str]) -> BranchData:
if branch:
has_tag = False
for tag in entry.tags:
if tag.name == branch.tag.name:
if branch.tag and tag.name == branch.tag.name:
has_tag = True
break
if not has_tag:
Expand Down Expand Up @@ -216,20 +218,19 @@ def __init__(self, library: "Library", driver: "QtDriver"):
self.apply_button.setMinimumWidth(100)
self.apply_button.clicked.connect(self.on_apply)

self.showEvent = self.on_open # type: ignore

self.root_layout.addWidget(self.title_widget)
self.root_layout.addWidget(self.desc_widget)
self.root_layout.addWidget(self.open_close_button_w)
self.root_layout.addWidget(self.scroll_area)
self.root_layout.addWidget(self.apply_button, alignment=Qt.AlignmentFlag.AlignCenter)

def on_apply(self, event):
def on_apply(self):
folders_to_tags(self.library)
self.close()
self.driver.main_window.preview_panel.update_widgets(update_preview=False)

def on_open(self, event):
@override
def showEvent(self, event: QtGui.QShowEvent):
for i in reversed(range(self.scroll_layout.count())):
self.scroll_layout.itemAt(i).widget().setParent(None)

Expand Down Expand Up @@ -271,6 +272,7 @@ def __init__(self, data: BranchData, parent_tag: Tag | None = None):

self.label = QLabel()
self.tag_layout.addWidget(self.label)
assert data.tag is not None and parent_tag is not None
self.tag_widget = ModifiedTagWidget(data.tag, parent_tag)
self.tag_widget.bg_button.clicked.connect(lambda: self.hide_show())
self.tag_layout.addWidget(self.tag_widget)
Expand Down Expand Up @@ -323,10 +325,7 @@ def __init__(self, tag: Tag, parent_tag: Tag) -> None:

self.bg_button = QPushButton(self)
self.bg_button.setFlat(True)
if parent_tag is not None:
text = f"{tag.name} ({parent_tag.name})".replace("&", "&&")
else:
text = tag.name.replace("&", "&&")
text = f"{tag.name} ({parent_tag.name})".replace("&", "&&")
self.bg_button.setText(text)
self.bg_button.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu)

Expand Down
14 changes: 8 additions & 6 deletions src/tagstudio/qt/widgets/collage_icon.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,16 @@ def __init__(self, library: Library):

def render(
self,
entry_id,
entry_id: int,
size: tuple[int, int],
data_tint_mode,
data_only_mode,
keep_aspect,
data_tint_mode: bool,
data_only_mode: bool,
keep_aspect: bool,
):
entry = self.lib.get_entry(entry_id)
filepath = self.lib.library_dir / entry.path
lib_dir = self.lib.library_dir
assert lib_dir is not None and entry is not None
filepath = lib_dir / entry.path
color: str = ""

try:
Expand All @@ -57,7 +59,7 @@ def render(
ext: str = filepath.suffix.lower()
if MediaCategories.is_ext_in_category(ext, MediaCategories.IMAGE_TYPES):
try:
with Image.open(str(self.lib.library_dir / entry.path)) as pic:
with Image.open(filepath) as pic:
if keep_aspect:
pic.thumbnail(size)
else:
Expand Down
32 changes: 19 additions & 13 deletions src/tagstudio/qt/widgets/item_thumb.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
from enum import Enum
from functools import wraps
from pathlib import Path
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, override
from warnings import catch_warnings

import structlog
from PIL import Image, ImageQt
from PySide6.QtCore import QEvent, QMimeData, QSize, Qt, QUrl
from PySide6.QtGui import QAction, QDrag, QEnterEvent, QPixmap
from PySide6.QtGui import QAction, QDrag, QEnterEvent, QMouseEvent, QPixmap
from PySide6.QtWidgets import (
QBoxLayout,
QCheckBox,
Expand Down Expand Up @@ -403,7 +403,7 @@ def set_count(self, count: str) -> None:
self.ext_badge.setHidden(True)
self.count_badge.setHidden(True)

def set_filename_text(self, filename: Path | None):
def set_filename_text(self, filename: Path):
self.set_item_path(filename)
self.file_label.setText(str(filename.name))

Expand Down Expand Up @@ -437,22 +437,21 @@ def update_size(self, timestamp: float, size: QSize):
size (QSize): The new thumbnail size to set.
"""
if timestamp > ItemThumb.update_cutoff:
self.thumb_size = size.toTuple() # type: ignore
self.thumb_size = size.width(), size.height()
self.thumb_button.setIconSize(size)
self.thumb_button.setMinimumSize(size)
self.thumb_button.setMaximumSize(size)

def update_clickable(self, clickable: typing.Callable):
def update_clickable(self, clickable: typing.Callable[[], None]):
"""Updates attributes of a thumbnail element."""
if clickable:
with catch_warnings(record=True):
self.thumb_button.clicked.disconnect()
self.thumb_button.clicked.connect(clickable)
with catch_warnings(record=True):
self.thumb_button.clicked.disconnect()
self.thumb_button.clicked.connect(clickable)

def set_item_id(self, item_id: int):
self.item_id = item_id

def set_item_path(self, path: Path | str | None):
def set_item_path(self, path: Path | str):
"""Set the absolute filepath for the item. Used for locating on disk."""
self.opener.set_filepath(path)

Expand All @@ -474,11 +473,13 @@ def show_check_badges(self, show: bool):
is_hidden = not (show or self.badge_active[badge_type])
badge.setHidden(is_hidden)

def enterEvent(self, event: QEnterEvent) -> None: # noqa: N802
@override
def enterEvent(self, event: QEnterEvent) -> None: # type: ignore[misc]
self.show_check_badges(show=True)
return super().enterEvent(event)

def leaveEvent(self, event: QEvent) -> None: # noqa: N802
@override
def leaveEvent(self, event: QEvent) -> None: # type: ignore[misc]
self.show_check_badges(show=False)
return super().leaveEvent(event)

Expand All @@ -490,6 +491,9 @@ def on_badge_check(self, badge_type: BadgeType):
toggle_value = self.badges[badge_type].isChecked()
self.badge_active[badge_type] = toggle_value
badge_values: dict[BadgeType, bool] = {badge_type: toggle_value}
# TODO: Ensure that self.item_id is always an integer. During tests, it is currently None.
# This issue should be addressed by either fixing the test setup or modifying the
# self.driver.update_badges() method.
self.driver.update_badges(badge_values, self.item_id)

def toggle_item_tag(
Expand All @@ -506,7 +510,8 @@ def toggle_item_tag(
else:
pass

def mouseMoveEvent(self, event): # noqa: N802
@override
def mouseMoveEvent(self, event: QMouseEvent) -> None: # type: ignore[misc]
if event.buttons() is not Qt.MouseButton.LeftButton:
return

Expand All @@ -521,6 +526,7 @@ def mouseMoveEvent(self, event): # noqa: N802
if not entry:
continue

assert self.lib.library_dir is not None
url = QUrl.fromLocalFile(Path(self.lib.library_dir) / entry.path)
paths.append(url)

Expand Down