diff --git a/plugins/Marketplace/PackageModel.py b/plugins/Marketplace/PackageModel.py index ac2e2df2b2..2d9b013f72 100644 --- a/plugins/Marketplace/PackageModel.py +++ b/plugins/Marketplace/PackageModel.py @@ -6,6 +6,7 @@ from enum import Enum from typing import Any, cast, Dict, List, Optional from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal, pyqtSlot +from PyQt5.QtQml import QQmlEngine from cura.CuraApplication import CuraApplication from cura.CuraPackageManager import CuraPackageManager @@ -30,6 +31,7 @@ class PackageModel(QObject): :param parent: The parent QML object that controls the lifetime of this model (normally a PackageList). """ super().__init__(parent) + QQmlEngine.setObjectOwnership(self, QQmlEngine.CppOwnership) self._package_manager: CuraPackageManager = cast(CuraPackageManager, CuraApplication.getInstance().getPackageManager()) self._plugin_registry: PluginRegistry = CuraApplication.getInstance().getPluginRegistry() @@ -78,11 +80,10 @@ class PackageModel(QObject): self.updatePackageTriggered.connect(lambda pkg: self._setIsUpdating(True)) - self._plugin_registry.hasPluginsEnabledOrDisabledChanged.connect(self.stateManageButtonChanged) - self._package_manager.packageInstalled.connect(lambda pkg_id: self._packageInstalled(pkg_id, True)) - self._package_manager.packageUninstalled.connect(lambda pkg_id: self._packageInstalled(pkg_id, True)) - self._package_manager.packageInstallingFailed.connect(lambda pkg_id: self._packageInstalled(pkg_id, False)) + self._package_manager.packageInstalled.connect(lambda pkg_id: self._packageInstalled(pkg_id)) + self._package_manager.packageUninstalled.connect(lambda pkg_id: self._packageInstalled(pkg_id)) + self._package_manager.packageInstallingFailed.connect(lambda pkg_id: self._packageInstalled(pkg_id)) self._package_manager.packagesWithUpdateChanged.connect(lambda: self.setCanUpdate(self._package_id in self._package_manager.packagesWithUpdate)) self._is_busy = False @@ -328,16 +329,30 @@ class PackageModel(QObject): """ return self._is_busy + @pyqtSlot() + def enable(self): + self.enablePackageTriggered.emit(self.packageId) + + @pyqtSlot() + def disable(self): + self.disablePackageTriggered.emit(self.packageId) + def setBusy(self, value: bool): if self._is_busy != value: self._is_busy = value - self.busyChanged.emit() + try: + self.busyChanged.emit() + except RuntimeError: + pass - def _packageInstalled(self, package_id: str, success: bool) -> None: + def _packageInstalled(self, package_id: str) -> None: if self._package_id != package_id: return self.setBusy(not self._is_busy) - self.stateManageButtonChanged.emit() + try: + self.stateManageButtonChanged.emit() + except RuntimeError: + pass def _getRecentlyInstalled(self) -> bool: return (self._package_id in self._package_manager.getPackagesToInstall() or self._package_id in self._package_manager.getPackagesToRemove()) \ diff --git a/plugins/Marketplace/RemotePackageList.py b/plugins/Marketplace/RemotePackageList.py index 7cbd00ad76..e877cd9eb5 100644 --- a/plugins/Marketplace/RemotePackageList.py +++ b/plugins/Marketplace/RemotePackageList.py @@ -128,7 +128,7 @@ class RemotePackageList(PackageList): # Setting the ownership of this object to not qml can still result in a RuntimeError. Which can occur when quickly toggling # between de-/constructing RemotePackageLists. This try-except is here to prevent a hard crash when the wrapped C++ object # was deleted when it was still parsing the response - return + continue self._request_url = response_data["links"].get("next", "") # Use empty string to signify that there is no next page. self._ongoing_requests["get_packages"] = None diff --git a/plugins/Marketplace/resources/qml/ManageButton.qml b/plugins/Marketplace/resources/qml/ManageButton.qml index 87c72d8710..36022ffd54 100644 --- a/plugins/Marketplace/resources/qml/ManageButton.qml +++ b/plugins/Marketplace/resources/qml/ManageButton.qml @@ -11,7 +11,7 @@ import Cura 1.6 as Cura Item { id: manageButton - property bool button_style + property bool button_style: true property string text property bool busy: false property bool confirmed: false diff --git a/plugins/Marketplace/resources/qml/PackageCardHeader.qml b/plugins/Marketplace/resources/qml/PackageCardHeader.qml index fa45a4d0bb..5a661e32fb 100644 --- a/plugins/Marketplace/resources/qml/PackageCardHeader.qml +++ b/plugins/Marketplace/resources/qml/PackageCardHeader.qml @@ -181,7 +181,7 @@ Item ManageButton { id: enableManageButton - visible: showManageButtons && !(installManageButton.confirmed || updateManageButton.confirmed || packageData.packageType == "material") + visible: showManageButtons && packageData.packageType != "material" enabled: !(installManageButton.busy || updateManageButton.busy) button_style: !packageData.isActive @@ -189,23 +189,13 @@ Item text: button_style ? catalog.i18nc("@button", "Enable") : catalog.i18nc("@button", "Disable") - onClicked: - { - if(packageData.isActive) - { - packageData.disablePackageTriggered(packageData.packageId) - } - else - { - packageData.enablePackageTriggered(packageData.packageId) - } - } + onClicked: packageData.isActive ? packageData.disable(): packageData.enable() } ManageButton { id: installManageButton - visible: (showManageButtons || confirmed) && ((packageData.isBundled && packageData.canDowngrade) || !packageData.isBundled) && !updateManageButton.confirmed + visible: showManageButtons && (packageData.canDowngrade || !packageData.isBundled) enabled: !updateManageButton.busy busy: packageData.busy button_style: !packageData.isInstalled @@ -213,6 +203,11 @@ Item text: { + if (packageData.canDowngrade) + { + if (busy) { return catalog.i18nc("@button", "Downgrading..."); } + else { return catalog.i18nc("@button", "Downgrade"); } + } if (!packageData.isInstalled) { if (busy) { return catalog.i18nc("@button", "Installing..."); } @@ -220,56 +215,25 @@ Item } else { - if (packageData.canDowngrade) - { - if (busy) { return catalog.i18nc("@button", "Downgrading..."); } - else { return catalog.i18nc("@button", "Downgrade"); } - } - else - { - return catalog.i18nc("@button", "Uninstall"); - } + return catalog.i18nc("@button", "Uninstall"); } } onClicked: packageData.isInstalled ? packageData.uninstall(): packageData.install() - } ManageButton { id: updateManageButton - visible: (showManageButtons || confirmed) && (packageData.canUpdate || confirmed) && !installManageButton.confirmed + visible: showManageButtons && packageData.canUpdate enabled: !installManageButton.busy - confirmed: packageData.isRecentlyUpdatedChanged - - button_style: true + busy: packageData.busy Layout.alignment: Qt.AlignTop - text: - { - if (busy) { return catalog.i18nc("@button", "Updating..."); } - else if (confirmed) { return catalog.i18nc("@button", "Updated"); } - else { return catalog.i18nc("@button", "Update"); } - } + text: busy ? catalog.i18nc("@button", "Updating..."): catalog.i18nc("@button", "Update") - onClicked: - { - busy = true - packageData.updatePackageTriggered(packageData.packageId); - } - - Connections - { - target: packageData - - function updated(succes) - { - updateManageButton.busy = false; - updateManageButton.confirmed = succes; - } - } + onClicked: packageData.updatePackageTriggered(packageData.packageId); } } }