from copy import copy from enum import IntEnum, auto from typing import Any, Optional from PySide6.QtCore import QAbstractListModel, QByteArray, QModelIndex, QObject, QPersistentModelIndex, QStandardPaths, QUrl, Qt, Signal, Slot, Property from PySide6.QtQml import QmlElement from kodereviewer.project import Project from kodereviewer.data import Label, PullRequest QML_IMPORT_NAME = "org.deprecated.kodereviewer" QML_IMPORT_MAJOR_VERSION = 1 @QmlElement class LabelModel(QAbstractListModel): """Model to show pull request labels.""" _pull_request: Optional[PullRequest] class Roles(IntEnum): Name = Qt.ItemDataRole.UserRole + 1 LabelColor = auto() TextColor = auto() Description = auto() def __init__(self): super().__init__() self._pull_request = None pullRequestChanged = Signal() def get_pull_request(self) -> Optional[PullRequest]: return self._pull_request def set_pull_request(self, pull_request: Optional[PullRequest]) -> None: if pull_request is None: return if self._pull_request is not None and self._pull_request == pull_request: return self.beginResetModel() self._pull_request = pull_request self.endResetModel() self.pullRequestChanged.emit() pullRequest = Property(PullRequest, fget=get_pull_request, fset=set_pull_request, notify=pullRequestChanged) def data(self, index: QModelIndex | QPersistentModelIndex, role: int = Qt.ItemDataRole.DisplayRole) -> object: if self._pull_request is None: return None label: Label = self._pull_request.labels[index.row()] if role == self.Roles.Name: return label.name if role == self.Roles.LabelColor: return f'#{label.color}' if role == self.Roles.TextColor: return self.text_color(label.color) if role == self.Roles.Description: return label.description if role == Qt.ItemDataRole.DisplayRole: return label.name return None def rowCount(self, parent: QModelIndex | QPersistentModelIndex = QModelIndex()) -> int: if self._pull_request is None: return 0 return len(self._pull_request.labels) def roleNames(self) -> dict[int, QByteArray]: return { self.Roles.Name: QByteArray(b'name'), self.Roles.LabelColor: QByteArray(b'labelColor'), self.Roles.TextColor: QByteArray(b'textColor'), self.Roles.Description: QByteArray(b'description'), } def text_color(self, background_color: str) -> str: r = int(background_color[0:2], 16) g = int(background_color[2:4], 16) b = int(background_color[4:6], 16) def _t(value: float) -> float: if value <= 0.04045: return value / 12.92 return ((value + 0.055) / 1.055) ** 2.4 srgb = [_t(value/255) for value in [r, g, b]] L = 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2]; if L > 0.179: return '#000' return '#fff'