from copy import copy 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 PullRequest QML_IMPORT_NAME = "org.deprecated.kodereviewer" QML_IMPORT_MAJOR_VERSION = 1 @QmlElement class PullRequestModel(QAbstractListModel): _project: Optional[Project] _pull_requests: list[PullRequest] # This attribute holds a reference to a reference to a newly # copied PullRequest so Qt don't frees the memory of the pull # request on _pull_requests _current_pull_request: PullRequest NumberRole = Qt.ItemDataRole.UserRole + 1 TitleRole = NumberRole + 1 StateRole = TitleRole + 1 DraftRole = StateRole + 1 def __init__(self): super().__init__() def data(self, index: QModelIndex | QPersistentModelIndex, role: int = Qt.ItemDataRole.DisplayRole) -> object: if self._project is None: return None pull_request = self._project.pullRequests[index.row()] if role == self.NumberRole: return pull_request.number if role == self.TitleRole: return pull_request.title if role == self.StateRole: return pull_request.state if role == self.DraftRole: return pull_request.draft if role == Qt.ItemDataRole.DisplayRole: return f'{pull_request.number} - {pull_request.title}' return None def rowCount(self, parent: QModelIndex | QPersistentModelIndex = QModelIndex()) -> int: if self._project is not None: return len(self._project.pullRequests) return 0 def roleNames(self) -> dict[int, QByteArray]: return { self.NumberRole: QByteArray(b"number"), self.TitleRole: QByteArray(b"title"), self.StateRole: QByteArray(b"state"), self.DraftRole: QByteArray(b"draft"), } def get_project(self) -> Optional[Project]: return self._project def set_project(self, project: Optional[Project])-> None: if project is None: return self._project = project assert self._project is not None self._project.pullRequestsChanged.connect(self._reset_model) project = Property(Project, fget=get_project, fset=set_project) @Slot(int, result=PullRequest) def get(self, index: int) -> Optional[PullRequest]: self._current_pull_request = self._pull_requests[index].copy() return self._current_pull_request def _reset_model(self) -> None: print("Reseting pull request model") self.beginResetModel() if self._project is not None: self._pull_requests = self._project.pullRequests self.endResetModel()