mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-01-28 22:01:24 +00:00
feat(ui): new tag alias UI (#534)
* updated parents and aliases to use the flowLaout in the build tag panel added shortcuts for adding and removing aliases and updated the alias ui to always show remove button and not cover alias aliases use flowlayout wrote test for buildTagPanel removeSelectedAlias parent tags now use flowlayout in build tag panel moved buttons for adding aliases and parents to be at the end of the flowLayout * added aliases and subtags to search results * aliases now use a table, removed unnecessary keyboard shortcuts * reverted subtags to regular list from flowlayout * chor remove redundant lambda * feat: added display names for tags * fix: aliases table enter/return and backspace work as expected, display names work as expected, adding aliases outputs them in order * format * fix: add parent button on build tag panel * fix: empty aliases where not being removed all the time * fix: alias name changes would be discarded when a new alias was created or an alias was removed * fix: removed display names, as they didn't display properly and should be added in a different PR * fix: mypy * fix: added missing session.expunge_all session.expunge_all() on line 621 was removed, added it back. * fix: parent_tags relationship in Tag class parent_tags primaryJoin and secondaryJoin where in the wrong order. They have been switched back to the proper order. * fix: pillow_jxl import was missing * fix: ruff * fix: type hint fixes * fix: fix the type hint fixes --------- Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
This commit is contained in:
@@ -619,6 +619,7 @@ class Library:
|
||||
)
|
||||
|
||||
session.expunge_all()
|
||||
|
||||
return res
|
||||
|
||||
def get_all_child_tag_ids(self, tag_id: int) -> list[int]:
|
||||
@@ -901,9 +902,9 @@ class Library:
|
||||
def add_tag(
|
||||
self,
|
||||
tag: Tag,
|
||||
subtag_ids: set[int] | None = None,
|
||||
alias_names: set[str] | None = None,
|
||||
alias_ids: set[int] | None = None,
|
||||
subtag_ids: list[int] | set[int] | None = None,
|
||||
alias_names: list[str] | set[str] | None = None,
|
||||
alias_ids: list[int] | set[int] | None = None,
|
||||
) -> Tag | None:
|
||||
with Session(self.engine, expire_on_commit=False) as session:
|
||||
try:
|
||||
@@ -1077,9 +1078,9 @@ class Library:
|
||||
def update_tag(
|
||||
self,
|
||||
tag: Tag,
|
||||
subtag_ids: set[int] | None = None,
|
||||
alias_names: set[str] | None = None,
|
||||
alias_ids: set[int] | None = None,
|
||||
subtag_ids: list[int] | set[int] | None = None,
|
||||
alias_names: list[str] | set[str] | None = None,
|
||||
alias_ids: list[int] | set[int] | None = None,
|
||||
) -> None:
|
||||
"""Edit a Tag in the Library."""
|
||||
self.add_tag(tag, subtag_ids, alias_names, alias_ids)
|
||||
|
||||
@@ -3,43 +3,58 @@
|
||||
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
|
||||
|
||||
|
||||
import math
|
||||
import sys
|
||||
from typing import cast
|
||||
|
||||
import structlog
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtCore import Qt, Signal
|
||||
from PySide6.QtGui import (
|
||||
QAction,
|
||||
)
|
||||
from PySide6.QtWidgets import (
|
||||
QApplication,
|
||||
QComboBox,
|
||||
QFrame,
|
||||
QLabel,
|
||||
QLineEdit,
|
||||
QPushButton,
|
||||
QScrollArea,
|
||||
QTableWidget,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
)
|
||||
from src.core.library import Library, Tag
|
||||
from src.core.library.alchemy.enums import TagColor
|
||||
from src.core.palette import ColorType, UiColor, get_tag_color, get_ui_color
|
||||
from src.qt.flowlayout import FlowLayout
|
||||
from src.qt.modals.tag_search import TagSearchPanel
|
||||
from src.qt.widgets.panel import PanelModal, PanelWidget
|
||||
from src.qt.widgets.tag import TagAliasWidget, TagWidget
|
||||
from src.qt.widgets.tag import TagWidget
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
class CustomTableItem(QLineEdit):
|
||||
def __init__(self, text, on_return, on_backspace, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setText(text)
|
||||
self.on_return = on_return
|
||||
self.on_backspace = on_backspace
|
||||
|
||||
def set_id(self, id):
|
||||
self.id = id
|
||||
|
||||
def keyPressEvent(self, event): # noqa: N802
|
||||
if event.key() == Qt.Key.Key_Return or event.key() == Qt.Key.Key_Enter:
|
||||
self.on_return()
|
||||
elif event.key() == Qt.Key.Key_Backspace and self.text().strip() == "":
|
||||
self.on_backspace()
|
||||
else:
|
||||
super().keyPressEvent(event)
|
||||
|
||||
|
||||
class BuildTagPanel(PanelWidget):
|
||||
on_edit = Signal(Tag)
|
||||
|
||||
def __init__(self, library: Library, tag: Tag | None = None):
|
||||
super().__init__()
|
||||
self.lib = library
|
||||
# self.callback = callback
|
||||
# self.tag_id = tag_id
|
||||
|
||||
self.setMinimumSize(300, 400)
|
||||
self.root_layout = QVBoxLayout(self)
|
||||
@@ -86,43 +101,16 @@ class BuildTagPanel(PanelWidget):
|
||||
self.aliases_title.setText("Aliases")
|
||||
self.aliases_layout.addWidget(self.aliases_title)
|
||||
|
||||
self.aliases_flow_widget = QWidget()
|
||||
self.aliases_flow_layout = FlowLayout(self.aliases_flow_widget)
|
||||
self.aliases_flow_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.aliases_flow_layout.enable_grid_optimizations(value=False)
|
||||
self.aliases_table = QTableWidget(0, 2)
|
||||
self.aliases_table.horizontalHeader().setVisible(False)
|
||||
self.aliases_table.verticalHeader().setVisible(False)
|
||||
self.aliases_table.horizontalHeader().setStretchLastSection(True)
|
||||
self.aliases_table.setColumnWidth(0, 35)
|
||||
|
||||
self.alias_add_button = QPushButton()
|
||||
self.alias_add_button.setMinimumSize(23, 23)
|
||||
self.alias_add_button.setMaximumSize(23, 23)
|
||||
self.alias_add_button.setText("+")
|
||||
self.alias_add_button.setToolTip("CTRL + A")
|
||||
self.alias_add_button.setShortcut(
|
||||
QtCore.QKeyCombination(
|
||||
QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier),
|
||||
QtCore.Qt.Key.Key_A,
|
||||
)
|
||||
)
|
||||
self.alias_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"}}"
|
||||
)
|
||||
|
||||
self.alias_add_button.clicked.connect(lambda: self.add_alias_callback())
|
||||
self.aliases_flow_layout.addWidget(self.alias_add_button)
|
||||
self.alias_add_button.clicked.connect(self.add_alias_callback)
|
||||
|
||||
# Subtags ------------------------------------------------------------
|
||||
|
||||
@@ -137,42 +125,25 @@ class BuildTagPanel(PanelWidget):
|
||||
self.subtags_title.setText("Parent Tags")
|
||||
self.subtags_layout.addWidget(self.subtags_title)
|
||||
|
||||
self.subtag_flow_widget = QWidget()
|
||||
self.subtag_flow_layout = FlowLayout(self.subtag_flow_widget)
|
||||
self.subtag_flow_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.subtag_flow_layout.enable_grid_optimizations(value=False)
|
||||
self.scroll_contents = QWidget()
|
||||
self.subtags_scroll_layout = QVBoxLayout(self.scroll_contents)
|
||||
self.subtags_scroll_layout.setContentsMargins(6, 0, 6, 0)
|
||||
self.subtags_scroll_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
||||
|
||||
self.scroll_area = QScrollArea()
|
||||
# self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
|
||||
self.scroll_area.setWidgetResizable(True)
|
||||
self.scroll_area.setFrameShadow(QFrame.Shadow.Plain)
|
||||
self.scroll_area.setFrameShape(QFrame.Shape.NoFrame)
|
||||
self.scroll_area.setWidget(self.scroll_contents)
|
||||
# self.scroll_area.setMinimumHeight(60)
|
||||
|
||||
self.subtags_layout.addWidget(self.scroll_area)
|
||||
|
||||
self.subtags_add_button = QPushButton()
|
||||
self.subtags_add_button.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||
self.subtags_add_button.setText("+")
|
||||
self.subtags_add_button.setToolTip("CTRL + P")
|
||||
self.subtags_add_button.setMinimumSize(23, 23)
|
||||
self.subtags_add_button.setMaximumSize(23, 23)
|
||||
self.subtags_add_button.setShortcut(
|
||||
QtCore.QKeyCombination(
|
||||
QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier),
|
||||
QtCore.Qt.Key.Key_P,
|
||||
)
|
||||
)
|
||||
self.subtags_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"}}"
|
||||
)
|
||||
self.subtag_flow_layout.addWidget(self.subtags_add_button)
|
||||
self.subtags_layout.addWidget(self.subtags_add_button)
|
||||
|
||||
exclude_ids: list[int] = list()
|
||||
if tag is not None:
|
||||
@@ -182,11 +153,6 @@ class BuildTagPanel(PanelWidget):
|
||||
tsp.tag_chosen.connect(lambda x: self.add_subtag_callback(x))
|
||||
self.add_tag_modal = PanelModal(tsp, "Add Parent Tags", "Add Parent Tags")
|
||||
self.subtags_add_button.clicked.connect(self.add_tag_modal.show)
|
||||
# self.subtags_layout.addWidget(self.subtags_add_button)
|
||||
|
||||
# self.subtags_field = TagBoxWidget()
|
||||
# self.subtags_field.setMinimumHeight(60)
|
||||
# self.subtags_layout.addWidget(self.subtags_field)
|
||||
|
||||
# Shorthand ------------------------------------------------------------
|
||||
self.color_widget = QWidget()
|
||||
@@ -218,65 +184,59 @@ class BuildTagPanel(PanelWidget):
|
||||
)
|
||||
)
|
||||
self.color_layout.addWidget(self.color_field)
|
||||
remove_selected_alias_action = QAction("remove selected alias", self)
|
||||
remove_selected_alias_action.triggered.connect(self.remove_selected_alias)
|
||||
remove_selected_alias_action.setShortcut(
|
||||
QtCore.QKeyCombination(
|
||||
QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier),
|
||||
QtCore.Qt.Key.Key_D,
|
||||
)
|
||||
)
|
||||
self.addAction(remove_selected_alias_action)
|
||||
|
||||
# Add Widgets to Layout ================================================
|
||||
self.root_layout.addWidget(self.name_widget)
|
||||
self.root_layout.addWidget(self.shorthand_widget)
|
||||
self.root_layout.addWidget(self.aliases_widget)
|
||||
self.root_layout.addWidget(self.aliases_flow_widget)
|
||||
self.root_layout.addWidget(self.aliases_table)
|
||||
self.root_layout.addWidget(self.alias_add_button)
|
||||
self.root_layout.addWidget(self.subtags_widget)
|
||||
self.root_layout.addWidget(self.subtag_flow_widget)
|
||||
self.root_layout.addWidget(self.color_widget)
|
||||
# self.parent().done.connect(self.update_tag)
|
||||
|
||||
self.subtag_ids: set[int] = set()
|
||||
self.alias_ids: set[int] = set()
|
||||
self.alias_names: set[str] = set()
|
||||
self.new_alias_names: dict = dict()
|
||||
self.subtag_ids: list[int] = []
|
||||
self.alias_ids: list[int] = []
|
||||
self.alias_names: list[str] = []
|
||||
self.new_alias_names: dict = {}
|
||||
self.new_item_id = sys.maxsize
|
||||
|
||||
self.set_tag(tag or Tag(name="New Tag"))
|
||||
if tag is None:
|
||||
self.name_field.selectAll()
|
||||
|
||||
def keyPressEvent(self, event): # noqa: N802
|
||||
if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter: # type: ignore
|
||||
focused_widget = QApplication.focusWidget()
|
||||
if isinstance(focused_widget.parent(), TagAliasWidget):
|
||||
self.add_alias_callback()
|
||||
|
||||
def remove_selected_alias(self):
|
||||
count = self.aliases_flow_layout.count()
|
||||
if count <= 0:
|
||||
return
|
||||
|
||||
def backspace(self):
|
||||
focused_widget = QApplication.focusWidget()
|
||||
row = self.aliases_table.rowCount()
|
||||
|
||||
if focused_widget is None:
|
||||
if isinstance(focused_widget, CustomTableItem) is False:
|
||||
return
|
||||
remove_row = 0
|
||||
for i in range(0, row):
|
||||
item = self.aliases_table.cellWidget(i, 1)
|
||||
if (
|
||||
isinstance(item, CustomTableItem)
|
||||
and cast(CustomTableItem, item).id == cast(CustomTableItem, focused_widget).id
|
||||
):
|
||||
cast(QPushButton, self.aliases_table.cellWidget(i, 0)).click()
|
||||
remove_row = i
|
||||
break
|
||||
|
||||
if self.aliases_table.rowCount() <= 0:
|
||||
return
|
||||
|
||||
if isinstance(focused_widget.parent(), TagAliasWidget):
|
||||
cast(TagAliasWidget, focused_widget.parent()).on_remove.emit()
|
||||
if remove_row == 0:
|
||||
remove_row = 1
|
||||
|
||||
count = self.aliases_flow_layout.count()
|
||||
if count > 1:
|
||||
cast(
|
||||
TagAliasWidget, self.aliases_flow_layout.itemAt(count - 2).widget()
|
||||
).text_field.setFocus()
|
||||
else:
|
||||
self.alias_add_button.setFocus()
|
||||
self.aliases_table.cellWidget(remove_row - 1, 1).setFocus()
|
||||
|
||||
def enter(self):
|
||||
focused_widget = QApplication.focusWidget()
|
||||
if isinstance(focused_widget, CustomTableItem):
|
||||
self.add_alias_callback()
|
||||
|
||||
def add_subtag_callback(self, tag_id: int):
|
||||
logger.info("add_subtag_callback", tag_id=tag_id)
|
||||
self.subtag_ids.add(tag_id)
|
||||
self.subtag_ids.append(tag_id)
|
||||
self.set_subtags()
|
||||
|
||||
def remove_subtag_callback(self, tag_id: int):
|
||||
@@ -286,76 +246,71 @@ class BuildTagPanel(PanelWidget):
|
||||
|
||||
def add_alias_callback(self):
|
||||
logger.info("add_alias_callback")
|
||||
# bug passing in the text for a here means when the text changes
|
||||
# the remove callback uses what a whas initialy assigned
|
||||
new_field = TagAliasWidget()
|
||||
id = new_field.__hash__()
|
||||
new_field.id = id
|
||||
|
||||
new_field.on_remove.connect(lambda a="": self.remove_alias_callback(a, id))
|
||||
new_field.setMaximumHeight(25)
|
||||
new_field.setMinimumHeight(25)
|
||||
id = self.new_item_id
|
||||
|
||||
self.alias_ids.add(id)
|
||||
self.alias_ids.append(id)
|
||||
self.new_alias_names[id] = ""
|
||||
self.aliases_flow_layout.addWidget(new_field)
|
||||
new_field.text_field.setFocus()
|
||||
self.aliases_flow_layout.addWidget(self.alias_add_button)
|
||||
|
||||
self.new_item_id -= 1
|
||||
|
||||
self._set_aliases()
|
||||
|
||||
row = self.aliases_table.rowCount() - 1
|
||||
item = self.aliases_table.cellWidget(row, 1)
|
||||
item.setFocus()
|
||||
|
||||
def remove_alias_callback(self, alias_name: str, alias_id: int | None = None):
|
||||
logger.info("remove_alias_callback")
|
||||
|
||||
self.alias_ids.remove(alias_id)
|
||||
self._set_aliases()
|
||||
|
||||
def set_subtags(self):
|
||||
while self.subtag_flow_layout.itemAt(1):
|
||||
self.subtag_flow_layout.takeAt(0).widget().deleteLater()
|
||||
while self.subtags_scroll_layout.itemAt(0):
|
||||
self.subtags_scroll_layout.takeAt(0).widget().deleteLater()
|
||||
|
||||
c = QWidget()
|
||||
layout = QVBoxLayout(c)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setSpacing(3)
|
||||
for tag_id in self.subtag_ids:
|
||||
tag = self.lib.get_tag(tag_id)
|
||||
tw = TagWidget(tag, has_edit=False, has_remove=True)
|
||||
tw.on_remove.connect(lambda t=tag_id: self.remove_subtag_callback(t))
|
||||
self.subtag_flow_layout.addWidget(tw)
|
||||
|
||||
self.subtag_flow_layout.addWidget(self.subtags_add_button)
|
||||
layout.addWidget(tw)
|
||||
self.subtags_scroll_layout.addWidget(c)
|
||||
|
||||
def add_aliases(self):
|
||||
fields: set[TagAliasWidget] = set()
|
||||
for i in range(0, self.aliases_flow_layout.count() - 1):
|
||||
widget = self.aliases_flow_layout.itemAt(i).widget()
|
||||
names: set[str] = set()
|
||||
for i in range(0, self.aliases_table.rowCount()):
|
||||
widget = self.aliases_table.cellWidget(i, 1)
|
||||
|
||||
if not isinstance(widget, TagAliasWidget):
|
||||
return
|
||||
names.add(cast(CustomTableItem, widget).text())
|
||||
|
||||
field: TagAliasWidget = cast(TagAliasWidget, widget)
|
||||
fields.add(field)
|
||||
remove: set[str] = set(self.alias_names) - names
|
||||
|
||||
remove: set[str] = self.alias_names - set([a.text_field.text() for a in fields])
|
||||
self.alias_names = list(set(self.alias_names) - remove)
|
||||
|
||||
self.alias_names = self.alias_names - remove
|
||||
|
||||
for field in fields:
|
||||
for name in names:
|
||||
# add new aliases
|
||||
if field.text_field.text() != "":
|
||||
self.alias_names.add(field.text_field.text())
|
||||
if name.strip() != "" and name not in set(self.alias_names):
|
||||
self.alias_names.append(name)
|
||||
elif name.strip() == "" and name in set(self.alias_names):
|
||||
self.alias_names.remove(name)
|
||||
|
||||
def _update_new_alias_name_dict(self):
|
||||
for i in range(0, self.aliases_flow_layout.count() - 1):
|
||||
widget = self.aliases_flow_layout.itemAt(i).widget()
|
||||
|
||||
if not isinstance(widget, TagAliasWidget):
|
||||
return
|
||||
|
||||
field: TagAliasWidget = cast(TagAliasWidget, widget)
|
||||
text_field_text = field.text_field.text()
|
||||
|
||||
self.new_alias_names[field.id] = text_field_text
|
||||
row = self.aliases_table.rowCount()
|
||||
logger.info(row)
|
||||
for i in range(0, self.aliases_table.rowCount()):
|
||||
widget = self.aliases_table.cellWidget(i, 1)
|
||||
self.new_alias_names[widget.id] = widget.text() # type: ignore
|
||||
|
||||
def _set_aliases(self):
|
||||
self._update_new_alias_name_dict()
|
||||
|
||||
while self.aliases_flow_layout.itemAt(1):
|
||||
self.aliases_flow_layout.takeAt(0).widget().deleteLater()
|
||||
while self.aliases_table.rowCount() > 0:
|
||||
self.aliases_table.removeRow(0)
|
||||
|
||||
self.alias_names.clear()
|
||||
|
||||
@@ -364,43 +319,45 @@ class BuildTagPanel(PanelWidget):
|
||||
|
||||
alias_name = alias.name if alias else self.new_alias_names[alias_id]
|
||||
|
||||
new_field = TagAliasWidget(
|
||||
alias_id,
|
||||
alias_name,
|
||||
lambda a=alias_name, id=alias_id: self.remove_alias_callback(a, id),
|
||||
)
|
||||
new_field.setMaximumHeight(25)
|
||||
new_field.setMinimumHeight(25)
|
||||
self.aliases_flow_layout.addWidget(new_field)
|
||||
self.alias_names.add(alias_name)
|
||||
# handel when an alias name changes
|
||||
if alias_id in self.new_alias_names:
|
||||
alias_name = self.new_alias_names[alias_id]
|
||||
|
||||
self.aliases_flow_layout.addWidget(self.alias_add_button)
|
||||
self.alias_names.append(alias_name)
|
||||
|
||||
remove_btn = QPushButton("-")
|
||||
remove_btn.clicked.connect(
|
||||
lambda a=alias_name, id=alias_id: self.remove_alias_callback(a, id)
|
||||
)
|
||||
|
||||
row = self.aliases_table.rowCount()
|
||||
new_item = CustomTableItem(alias_name, self.enter, self.backspace)
|
||||
new_item.set_id(alias_id)
|
||||
|
||||
new_item.editingFinished.connect(lambda item=new_item: self._alias_name_change(item))
|
||||
|
||||
self.aliases_table.insertRow(row)
|
||||
self.aliases_table.setCellWidget(row, 1, new_item)
|
||||
self.aliases_table.setCellWidget(row, 0, remove_btn)
|
||||
|
||||
def _alias_name_change(self, item: CustomTableItem):
|
||||
self.new_alias_names[item.id] = item.text()
|
||||
|
||||
def set_tag(self, tag: Tag):
|
||||
self.tag = tag
|
||||
|
||||
self.tag = tag
|
||||
|
||||
logger.info("setting tag", tag=tag)
|
||||
|
||||
self.name_field.setText(tag.name)
|
||||
self.shorthand_field.setText(tag.shorthand or "")
|
||||
|
||||
for alias_id in tag.alias_ids:
|
||||
self.alias_ids.add(alias_id)
|
||||
self.alias_ids.append(alias_id)
|
||||
|
||||
self._set_aliases()
|
||||
|
||||
for subtag in tag.subtag_ids:
|
||||
self.subtag_ids.add(subtag)
|
||||
|
||||
for alias_id in tag.alias_ids:
|
||||
self.alias_ids.add(alias_id)
|
||||
|
||||
self._set_aliases()
|
||||
|
||||
for subtag in tag.subtag_ids:
|
||||
self.subtag_ids.add(subtag)
|
||||
self.subtag_ids.append(subtag)
|
||||
|
||||
self.set_subtags()
|
||||
|
||||
|
||||
@@ -165,7 +165,9 @@ class TagDatabasePanel(PanelWidget):
|
||||
self.edit_modal.show()
|
||||
|
||||
def edit_tag_callback(self, btp: BuildTagPanel):
|
||||
self.lib.update_tag(btp.build_tag(), btp.subtag_ids, btp.alias_names, btp.alias_ids)
|
||||
self.lib.update_tag(
|
||||
btp.build_tag(), set(btp.subtag_ids), set(btp.alias_names), set(btp.alias_ids)
|
||||
)
|
||||
self.update_tags(self.search_field.text())
|
||||
|
||||
def showEvent(self, event: QShowEvent) -> None: # noqa N802
|
||||
|
||||
@@ -635,7 +635,10 @@ class QtDriver(DriverMixin, QObject):
|
||||
self.modal.saved.connect(
|
||||
lambda: (
|
||||
self.lib.add_tag(
|
||||
panel.build_tag(), panel.subtag_ids, panel.alias_names, panel.alias_ids
|
||||
panel.build_tag(),
|
||||
set(panel.subtag_ids),
|
||||
set(panel.alias_names),
|
||||
set(panel.alias_ids),
|
||||
),
|
||||
self.modal.hide(),
|
||||
)
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
from typing import cast
|
||||
|
||||
from PySide6.QtWidgets import QApplication, QMainWindow
|
||||
from src.core.library.alchemy.models import Tag
|
||||
from src.qt.modals.build_tag import BuildTagPanel
|
||||
from src.qt.widgets.tag import TagAliasWidget
|
||||
|
||||
|
||||
def test_build_tag_panel_add_sub_tag_callback(library, generate_tag):
|
||||
@@ -43,29 +39,6 @@ import os
|
||||
os.environ["QT_QPA_PLATFORM"] = "offscreen"
|
||||
|
||||
|
||||
def test_build_tag_panel_remove_selected_alias(library, generate_tag):
|
||||
app = QApplication.instance() or QApplication([])
|
||||
|
||||
window = QMainWindow()
|
||||
parent_tag = library.add_tag(generate_tag("xxx", id=123))
|
||||
panel = BuildTagPanel(library, parent_tag)
|
||||
panel.setParent(window)
|
||||
|
||||
panel.add_alias_callback()
|
||||
window.show()
|
||||
|
||||
assert panel.aliases_flow_layout.count() == 2
|
||||
|
||||
alias_widget = panel.aliases_flow_layout.itemAt(0).widget()
|
||||
alias_widget.text_field.setFocus()
|
||||
|
||||
app.processEvents()
|
||||
|
||||
panel.remove_selected_alias()
|
||||
|
||||
assert panel.aliases_flow_layout.count() == 1
|
||||
|
||||
|
||||
def test_build_tag_panel_add_alias_callback(library, generate_tag):
|
||||
tag = library.add_tag(generate_tag("xxx", id=123))
|
||||
assert tag
|
||||
@@ -74,7 +47,7 @@ def test_build_tag_panel_add_alias_callback(library, generate_tag):
|
||||
|
||||
panel.add_alias_callback()
|
||||
|
||||
assert panel.aliases_flow_layout.count() == 2
|
||||
assert panel.aliases_table.rowCount() == 1
|
||||
|
||||
|
||||
def test_build_tag_panel_remove_alias_callback(library, generate_tag):
|
||||
@@ -112,7 +85,7 @@ def test_build_tag_panel_set_subtags(library, generate_tag):
|
||||
panel: BuildTagPanel = BuildTagPanel(library, child)
|
||||
|
||||
assert len(panel.subtag_ids) == 1
|
||||
assert panel.subtag_flow_layout.count() == 2
|
||||
assert panel.subtags_scroll_layout.count() == 1
|
||||
|
||||
|
||||
def test_build_tag_panel_add_aliases(library, generate_tag):
|
||||
@@ -128,19 +101,19 @@ def test_build_tag_panel_add_aliases(library, generate_tag):
|
||||
|
||||
panel: BuildTagPanel = BuildTagPanel(library, tag)
|
||||
|
||||
widget = panel.aliases_flow_layout.itemAt(0).widget()
|
||||
widget = panel.aliases_table.cellWidget(0, 1)
|
||||
|
||||
alias_names: set[str] = set()
|
||||
alias_names.add(cast(TagAliasWidget, widget).text_field.text())
|
||||
alias_names.add(widget.text())
|
||||
|
||||
widget = panel.aliases_flow_layout.itemAt(1).widget()
|
||||
alias_names.add(cast(TagAliasWidget, widget).text_field.text())
|
||||
widget = panel.aliases_table.cellWidget(1, 1)
|
||||
alias_names.add(widget.text())
|
||||
|
||||
assert "alias" in alias_names
|
||||
assert "alias_2" in alias_names
|
||||
|
||||
old_text = cast(TagAliasWidget, widget).text_field.text()
|
||||
cast(TagAliasWidget, widget).text_field.setText("alias_update")
|
||||
old_text = widget.text()
|
||||
widget.setText("alias_update")
|
||||
|
||||
panel.add_aliases()
|
||||
|
||||
@@ -161,7 +134,7 @@ def test_build_tag_panel_set_aliases(library, generate_tag):
|
||||
|
||||
panel: BuildTagPanel = BuildTagPanel(library, tag)
|
||||
|
||||
assert panel.aliases_flow_layout.count() == 2
|
||||
assert panel.aliases_table.rowCount() == 1
|
||||
assert len(panel.alias_names) == 1
|
||||
assert len(panel.alias_ids) == 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user