Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Ultimaker/Cura.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelle Spijker <spijker.jelle@gmail.com>2021-12-10 19:38:20 +0300
committerJelle Spijker <spijker.jelle@gmail.com>2021-12-10 19:38:20 +0300
commite72655cc22b0bb8f27aae82afcf6c2ee1298114e (patch)
tree1a7d760824cadf2b7c15e32df1f5c7493d619809 /plugins/Marketplace
parentd876b85259a5346dbcadb9679a954be94dd81bed (diff)
Moved busy/confirmed logic to QML
COntributes to CURA-8587
Diffstat (limited to 'plugins/Marketplace')
-rw-r--r--plugins/Marketplace/PackageList.py14
-rw-r--r--plugins/Marketplace/PackageModel.py145
-rw-r--r--plugins/Marketplace/resources/qml/PackageCardHeader.qml74
3 files changed, 134 insertions, 99 deletions
diff --git a/plugins/Marketplace/PackageList.py b/plugins/Marketplace/PackageList.py
index ca3d4aff41..390bf841df 100644
--- a/plugins/Marketplace/PackageList.py
+++ b/plugins/Marketplace/PackageList.py
@@ -165,7 +165,7 @@ class PackageList(ListModel):
if dialog is not None:
dialog.deleteLater()
# reset package card
- package = self.getPackageModel(package_id)
+ self._manager.packageInstallingFailed.emit(package_id)
def _requestInstall(self, package_id: str, update: bool = False) -> None:
package_path = self._to_install[package_id]
@@ -182,8 +182,9 @@ class PackageList(ListModel):
def _install(self, package_id: str, update: bool = False) -> None:
package_path = self._to_install.pop(package_id)
to_be_installed = self._manager.installPackage(package_path) is not None
+ if not to_be_installed:
+ return
package = self.getPackageModel(package_id)
- # TODO handle failure
self.subscribeUserToPackage(package_id, str(package.sdk_version))
def download(self, package_id: str, url: str, update: bool = False) -> None:
@@ -231,14 +232,7 @@ class PackageList(ListModel):
if reply:
reply_string = bytes(reply.readAll()).decode()
Logger.error(f"Failed to download package: {package_id} due to {reply_string}")
- try:
- package = self.getPackageModel(package_id)
- # TODO: handle error
- except RuntimeError:
- # Setting the ownership of this object to not qml can still result in a RuntimeError. Which can occur when quickly toggling
- # between de-/constructing Remote or Local PackageLists. 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
+ self._manager.packageInstallingFailed.emit(package_id)
def subscribeUserToPackage(self, package_id: str, sdk_version: str) -> None:
"""Subscribe the user (if logged in) to the package for a given SDK
diff --git a/plugins/Marketplace/PackageModel.py b/plugins/Marketplace/PackageModel.py
index 6a7c943e2c..de2732f147 100644
--- a/plugins/Marketplace/PackageModel.py
+++ b/plugins/Marketplace/PackageModel.py
@@ -16,6 +16,7 @@ from UM.PluginRegistry import PluginRegistry
catalog = i18nCatalog("cura")
+
class PackageModel(QObject):
"""
Represents a package, containing all the relevant information to be displayed about a package.
@@ -38,7 +39,8 @@ class PackageModel(QObject):
self._icon_url = package_data.get("icon_url", "")
self._display_name = package_data.get("display_name", catalog.i18nc("@label:property", "Unknown Package"))
tags = package_data.get("tags", [])
- self._is_checked_by_ultimaker = (self._package_type == "plugin" and "verified" in tags) or (self._package_type == "material" and "certified" in tags)
+ self._is_checked_by_ultimaker = (self._package_type == "plugin" and "verified" in tags) or (
+ self._package_type == "material" and "certified" in tags)
self._package_version = package_data.get("package_version", "") # Display purpose, no need for 'UM.Version'.
self._package_info_url = package_data.get("website", "") # Not to be confused with 'download_url'.
self._download_count = package_data.get("download_count", 0)
@@ -63,38 +65,32 @@ class PackageModel(QObject):
if not self._icon_url or self._icon_url == "":
self._icon_url = author_data.get("icon_url", "")
- self._is_installing = False
- self._recently_installed = False
- self._install_status_changing = False
-
self._can_update = False
- self._is_updating = False
- self._recently_updated = False
self._section_title = section_title
self.sdk_version = package_data.get("sdk_version_semver", "")
# Note that there's a lot more info in the package_data than just these specified here.
self.enablePackageTriggered.connect(self._plugin_registry.enablePlugin)
self.disablePackageTriggered.connect(self._plugin_registry.disablePlugin)
- self.installPackageTriggered.connect(lambda pkg_id, url: self.setIsInstalling(True))
- self.uninstallPackageTriggered.connect(lambda pkg_id: self.setIsInstalling(True))
- self.updatePackageTriggered.connect(lambda pkg_id: self.setIsUpdating(True))
-
- def finished_installed():
- if self.isInstalling:
- self._recently_installed = True
- self.setIsInstalling(False)
- if self.isUpdating:
- self._recently_updated = True
- self._can_update = not self._package_id in self._package_manager.getPackagesToInstall()
- self.setIsUpdating(False)
-
- self._package_manager.installedPackagesChanged.connect(finished_installed)
- self._plugin_registry.hasPluginsEnabledOrDisabledChanged.connect(self.stateManageButtonChanged)
- self._package_manager.packagesWithUpdateChanged.connect(lambda : self.setCanUpdate(self._package_id in self._package_manager.packagesWithUpdate))
+ self._is_updating = False
+ self._is_recently_updated = self._getRecentlyUpdated()
+
+ self._is_installing = False
+ self._is_uninstalling = False
+ self._is_recently_installed = self._getRecentlyInstalled()
- def __eq__(self, other: object):
+ self.updatePackageTriggered.connect(lambda pkg: self._setIsUpdating(True))
+ self.installPackageTriggered.connect(lambda pkg, url: self._setIsInstalling(True))
+ self.uninstallPackageTriggered.connect(lambda pkg: self._setIsUninstalling(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.packagesWithUpdateChanged.connect(lambda: self.setCanUpdate(self._package_id in self._package_manager.packagesWithUpdate))
+
+ def __eq__(self, other: object) -> bool:
if isinstance(other, PackageModel):
return other == self
elif isinstance(other, str):
@@ -102,7 +98,7 @@ class PackageModel(QObject):
else:
return False
- def __repr__(self):
+ def __repr__(self) -> str:
return f"<{self._package_id} : {self._package_version} : {self._section_title}>"
def _findLink(self, subdata: Dict[str, Any], link_type: str) -> str:
@@ -218,8 +214,8 @@ class PackageModel(QObject):
def packageType(self) -> str:
return self._package_type
- @pyqtProperty(str, constant=True)
- def iconUrl(self):
+ @pyqtProperty(str, constant = True)
+ def iconUrl(self) -> str:
return self._icon_url
@pyqtProperty(str, constant = True)
@@ -230,32 +226,32 @@ class PackageModel(QObject):
def isCheckedByUltimaker(self):
return self._is_checked_by_ultimaker
- @pyqtProperty(str, constant=True)
- def packageVersion(self):
+ @pyqtProperty(str, constant = True)
+ def packageVersion(self) -> str:
return self._package_version
- @pyqtProperty(str, constant=True)
- def packageInfoUrl(self):
+ @pyqtProperty(str, constant = True)
+ def packageInfoUrl(self) -> str:
return self._package_info_url
- @pyqtProperty(int, constant=True)
- def downloadCount(self):
+ @pyqtProperty(int, constant = True)
+ def downloadCount(self) -> str:
return self._download_count
- @pyqtProperty(str, constant=True)
- def description(self):
+ @pyqtProperty(str, constant = True)
+ def description(self) -> str:
return self._description
@pyqtProperty(str, constant = True)
def formattedDescription(self) -> str:
return self._formatted_description
- @pyqtProperty(str, constant=True)
- def authorName(self):
+ @pyqtProperty(str, constant = True)
+ def authorName(self) -> str:
return self._author_name
- @pyqtProperty(str, constant=True)
- def authorInfoUrl(self):
+ @pyqtProperty(str, constant = True)
+ def authorInfoUrl(self) -> str:
return self._author_info_url
@pyqtProperty(str, constant = True)
@@ -312,49 +308,62 @@ class PackageModel(QObject):
disablePackageTriggered = pyqtSignal(str)
- @pyqtProperty(bool, notify = stateManageButtonChanged)
- def isActive(self):
- return not self._package_id in self._plugin_registry.getDisabledPlugins()
+ installedPackagesChanged = pyqtSignal(bool)
- def setIsInstalling(self, value: bool) -> None:
- if value != self._is_installing:
- self._is_installing = value
- self.stateManageButtonChanged.emit()
+ uninstalledPackagesChanged = pyqtSignal(bool)
+
+ updatePackagesChanged = pyqtSignal(bool)
+
+ def _setIsUpdating(self, value: bool) -> None:
+ self._is_updating = value
+
+ def _setIsInstalling(self, value: bool) -> None:
+ self._is_installing = value
+
+ def _setIsUninstalling(self, value: bool) -> None:
+ self._is_uninstalling = value
- @pyqtProperty(bool, fset = setIsInstalling, notify = stateManageButtonChanged)
- def isInstalling(self) -> bool:
- return self._is_installing
+ def _packageInstalled(self, package_id: str, success: bool) -> None:
+ if self._package_id != package_id:
+ return
+ if self._is_updating:
+ self.updatePackagesChanged.emit(success)
+ self._is_updating = False
+ if self._is_installing:
+ self.installedPackagesChanged.emit(success)
+ self._is_installing = False
+ if self._is_uninstalling:
+ self.uninstalledPackagesChanged.emit(success)
+ self._is_uninstalling = False
+
+ def _getRecentlyInstalled(self) -> bool:
+ return (self._package_id in self._package_manager.getPackagesToInstall() or self._package_id in self._package_manager.getPackagesToRemove()) \
+ and self._package_id not in self._package_manager.package_infosWithUpdate
+
+ @pyqtProperty(bool, constant = True)
+ def isRecentlyInstalledChanged(self) -> bool:
+ return self._is_recently_installed
+
+ def _getRecentlyUpdated(self) -> bool:
+ return self._package_id in self._package_manager.package_infosWithUpdate and self._package_id in self._package_manager.getPackagesToInstall()
+
+ @pyqtProperty(bool, constant = True)
+ def isRecentlyUpdatedChanged(self) -> bool:
+ return self._is_recently_updated
@pyqtProperty(bool, notify = stateManageButtonChanged)
def isInstalled(self) -> bool:
return self._package_id in self._package_manager.local_packages_id
@pyqtProperty(bool, notify = stateManageButtonChanged)
- def isRecentlyInstalled(self) -> bool:
- return self._recently_installed and self._package_id in self._package_manager.getPackagesToInstall()
-
- @pyqtProperty(bool, notify = stateManageButtonChanged)
- def isRecentlyUninstalled(self) -> bool:
- return self._package_id in self._package_manager.getPackagesToRemove()
+ def isActive(self) -> bool:
+ return not self._package_id in self._plugin_registry.getDisabledPlugins()
@pyqtProperty(bool, notify = stateManageButtonChanged)
def canDowngrade(self) -> bool:
"""Flag if the installed package can be downgraded to a bundled version"""
return self._package_manager.canDowngrade(self._package_id)
- def setIsUpdating(self, value):
- if value != self._is_updating:
- self._is_updating = value
- self.stateManageButtonChanged.emit()
-
- @pyqtProperty(bool, fset = setIsUpdating, notify = stateManageButtonChanged)
- def isUpdating(self):
- return self._is_updating
-
- @pyqtProperty(bool, notify = stateManageButtonChanged)
- def isRecentlyUpdated(self):
- return self._recently_updated and self._package_id in self._package_manager.getPackagesToInstall()
-
def setCanUpdate(self, value: bool) -> None:
if value != self._can_update:
self._can_update = value
diff --git a/plugins/Marketplace/resources/qml/PackageCardHeader.qml b/plugins/Marketplace/resources/qml/PackageCardHeader.qml
index 56cfe4fa61..627fc27d46 100644
--- a/plugins/Marketplace/resources/qml/PackageCardHeader.qml
+++ b/plugins/Marketplace/resources/qml/PackageCardHeader.qml
@@ -209,45 +209,62 @@ Item
{
id: installManageButton
visible: (showManageButtons || confirmed) && ((packageData.isBundled && packageData.canDowngrade) || !packageData.isBundled) && !updateManageButton.confirmed
+ enabled: !updateManageButton.busy
- enabled: !packageData.isUpdating
-
- busy: packageData.isInstalling
- confirmed: packageData.isRecentlyInstalled || packageData.isRecentlyUninstalled
+ busy: false
+ confirmed: { packageData.isRecentlyInstalledChanged }
- button_style: !packageData.isInstalled
+ button_style: confirmed ? packageData.isInstalled : !packageData.isInstalled
Layout.alignment: Qt.AlignTop
text:
{
- if (packageData.canDowngrade) { return catalog.i18nc("@button", "Downgrade"); }
- if (packageData.isRecentlyInstalled) { return catalog.i18nc("@button", "Installed"); }
- if (packageData.isRecentlyUninstalled)
- {
- if (packageData.canDowngrade) { return catalog.i18nc("@button", "Downgraded") }
- else { return catalog.i18nc("@button", "Uninstalled"); } }
if (button_style)
{
- if (packageData.isInstalling) { return catalog.i18nc("@button", "Installing..."); }
+ if (busy) { return catalog.i18nc("@button", "Installing..."); }
+ else if (confirmed) { return catalog.i18nc("@button", "Installed"); }
else { return catalog.i18nc("@button", "Install"); }
}
else
{
- if (packageData.isInstalling) { return catalog.i18nc("@button", "Uninstalling..."); }
- else { return catalog.i18nc("@button", "Uninstall"); }
+ if (packageData.canDowngrade)
+ {
+ if (busy) { return catalog.i18nc("@button", "Downgrading..."); }
+ else if (confirmed) { return catalog.i18nc("@button", "Downgraded"); }
+ else { return catalog.i18nc("@button", "Downgrade"); }
+ }
+ else
+ {
+ if (busy) { return catalog.i18nc("@button", "Uninstalling..."); }
+ else if (confirmed) { return catalog.i18nc("@button", "Uninstalled"); }
+ else { return catalog.i18nc("@button", "Uninstall"); }
+ }
}
}
onClicked:
{
- if (primary_action)
+ busy = true
+ if (primary_action){ packageData.installPackageTriggered(packageData.packageId, packageData.downloadURL); }
+ else { packageData.uninstallPackageTriggered(packageData.packageId); }
+ }
+
+ Connections
+ {
+ target: packageData
+
+ function onInstalledPackagesChanged(success)
{
- packageData.installPackageTriggered(packageData.packageId, packageData.downloadURL)
+ installManageButton.busy = false;
+ installManageButton.confirmed = success;
}
- else
+ function onUninstalledPackagesChanged(success)
{
- packageData.uninstallPackageTriggered(packageData.packageId)
+ installManageButton.busy = false;
+ installManageButton.confirmed = success;
+ installManageButton.button_style = !installManageButton.button_style;
}
+
}
}
@@ -257,8 +274,8 @@ Item
visible: (showManageButtons || confirmed) && (packageData.canUpdate || confirmed) && !installManageButton.confirmed
enabled: !installManageButton.busy
- busy: packageData.isUpdating
- confirmed: packageData.isRecentlyUpdated
+ busy: false
+ confirmed: { packageData.isRecentlyUpdatedChanged }
button_style: true
Layout.alignment: Qt.AlignTop
@@ -270,7 +287,22 @@ Item
else { return catalog.i18nc("@button", "Update"); }
}
- onClicked: packageData.updatePackageTriggered(packageData.packageId)
+ onClicked:
+ {
+ busy = true;
+ packageData.updatePackageTriggered(packageData.packageId);
+ }
+
+ Connections
+ {
+ target: packageData
+
+ function onUpdatePackagesChanged(succes)
+ {
+ updateManageButton.busy = false;
+ updateManageButton.confirmed = succes;
+ }
+ }
}
}
}