mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-06-30 04:05:25 +08:00

The server is queried using the local packages_id and version to determine if they can be updated. The Manage button state is set accordingly. This is done in an async way to keep the UI responsive A.t.m I'm not sure if I might need to move this logic out, since we also need to make this query when check periodically for updates. when the list is not shown. But that would also entail creating the installed packages list before the Manage Packages tab is ever created in the Marketplace. Contributes to: CURA-8587
102 lines
3.8 KiB
Python
102 lines
3.8 KiB
Python
# 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
|
|
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope # To request JSON responses from the API.
|
|
from UM.TaskManagement.HttpRequestManager import HttpRequestData # To request the package list from the API.
|
|
|
|
from cura.CuraApplication import CuraApplication
|
|
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope # To make requests to the Ultimaker API with correct authorization.
|
|
|
|
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
|
|
|
|
self._ongoing_request: Optional[HttpRequestData] = None
|
|
self._scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance()))
|
|
|
|
@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
|