# Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, Qt from typing import Optional, TYPE_CHECKING from UM.i18n import i18nCatalog from UM.Qt.ListModel import ListModel if TYPE_CHECKING: from PyQt5.QtCore import QObject catalog = i18nCatalog("cura") class PackageList(ListModel): """ A List model for Packages, this class serves as parent class for more detailed implementations. such as Packages obtained from Remote or Local source """ PackageRole = Qt.UserRole + 1 def __init__(self, parent: Optional["QObject"] = None) -> None: super().__init__(parent) self._error_message = "" self.addRoleName(self.PackageRole, "package") self._is_loading = False self._has_more = False self._has_footer = True @pyqtSlot() def updatePackages(self) -> None: """ A Qt slot which will update the List from a source. Actual implementation should be done in the child class""" pass @pyqtSlot() def abortUpdating(self) -> None: """ A Qt slot which allows the update process to be aborted. Override this for child classes with async/callback updatePackges methods""" pass def reset(self) -> None: """ Resets and clears the list""" self.clear() isLoadingChanged = pyqtSignal() def setIsLoading(self, value: bool) -> None: if self._is_loading != value: self._is_loading = value self.isLoadingChanged.emit() @pyqtProperty(bool, fset = setIsLoading, notify = isLoadingChanged) def isLoading(self) -> bool: """ Indicating if the the packages are loading :return" ``True`` if the list is being obtained, otherwise ``False`` """ return self._is_loading hasMoreChanged = pyqtSignal() def setHasMore(self, value: bool) -> None: if self._has_more != value: self._has_more = value self.hasMoreChanged.emit() @pyqtProperty(bool, fset = setHasMore, notify = hasMoreChanged) def hasMore(self) -> bool: """ Indicating if there are more packages available to load. :return: ``True`` if there are more packages to load, or ``False``. """ return self._has_more errorMessageChanged = pyqtSignal() def setErrorMessage(self, error_message: str) -> None: if self._error_message != error_message: self._error_message = error_message self.errorMessageChanged.emit() @pyqtProperty(str, notify = errorMessageChanged, fset = setErrorMessage) def errorMessage(self) -> str: """ If an error occurred getting the list of packages, an error message will be held here. If no error occurred (yet), this will be an empty string. :return: An error message, if any, or an empty string if everything went okay. """ return self._error_message @pyqtProperty(bool, constant = True) def hasFooter(self) -> bool: """ Indicating if the PackageList should have a Footer visible. For paginated PackageLists :return: ``True`` if a Footer should be displayed in the ListView, e.q.: paginated lists, ``False`` Otherwise""" return self._has_footer