Merge branch 'CURA-8587_disable_update_install_and_uninstall' into cura-8587_disable_update_install_and_update/licence_agreement

# Conflicts:
#	plugins/Marketplace/PackageList.py
This commit is contained in:
casper 2021-12-06 15:49:21 +01:00
commit ec58cd2d0e
8 changed files with 144 additions and 156 deletions

View file

@ -58,17 +58,18 @@ class LocalPackageList(PackageList):
def _makePackageModel(self, package_info: Dict[str, Any]) -> PackageModel: def _makePackageModel(self, package_info: Dict[str, Any]) -> PackageModel:
""" Create a PackageModel from the package_info and determine its section_title""" """ Create a PackageModel from the package_info and determine its section_title"""
bundled_or_installed = "bundled" if self._manager.isBundledPackage(package_info["package_id"]) else "installed" package_id = package_info["package_id"]
bundled_or_installed = "bundled" if self._manager.isBundledPackage(package_id) else "installed"
package_type = package_info["package_type"] package_type = package_info["package_type"]
section_title = self.PACKAGE_CATEGORIES[bundled_or_installed][package_type] section_title = self.PACKAGE_CATEGORIES[bundled_or_installed][package_type]
package = PackageModel(package_info, section_title = section_title, parent = self) package = PackageModel(package_info, section_title = section_title, parent = self)
if package_info["package_id"] in self._manager.getPackagesToRemove() or package_info["package_id"] in self._manager.getPackagesToInstall(): if package_id in self._manager.getPackagesToRemove() or package_id in self._manager.getPackagesToInstall():
package.is_recently_managed = True package.is_recently_managed = True
package.can_downgrade = self._manager.canDowngrade(package_id)
self._connectManageButtonSignals(package) self._connectManageButtonSignals(package)
return package return package
def checkForUpdates(self, packages: List[Dict[str, Any]]): def checkForUpdates(self, packages: List[Dict[str, Any]]):
if self._account.isLoggedIn:
installed_packages = "installed_packages=".join([f"{package['package_id']}:{package['package_version']}&" for package in packages]) installed_packages = "installed_packages=".join([f"{package['package_id']}:{package['package_version']}&" for package in packages])
request_url = f"{PACKAGE_UPDATES_URL}?installed_packages={installed_packages[:-1]}" request_url = f"{PACKAGE_UPDATES_URL}?installed_packages={installed_packages[:-1]}"
@ -95,6 +96,6 @@ class LocalPackageList(PackageList):
for package_data in response_data["data"]: for package_data in response_data["data"]:
package = self.getPackageModel(package_data["package_id"]) package = self.getPackageModel(package_data["package_id"])
package.download_url = package_data.get("download_url", "") package.download_url = package_data.get("download_url", "")
package.canUpdate = True package.can_update = True
self.sort(attrgetter("sectionTitle", "can_update", "displayName"), key = "package", reverse = True) self.sort(attrgetter("sectionTitle", "can_update", "displayName"), key = "package", reverse = True)

View file

@ -12,7 +12,7 @@ from UM.Qt.ListModel import ListModel
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
from UM.TaskManagement.HttpRequestManager import HttpRequestData, HttpRequestManager from UM.TaskManagement.HttpRequestManager import HttpRequestData, HttpRequestManager
from UM.Logger import Logger from UM.Logger import Logger
from UM.PluginRegistry import PluginRegistry from UM import PluginRegistry
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
from cura import CuraPackageManager from cura import CuraPackageManager
@ -38,6 +38,7 @@ class PackageList(ListModel):
def __init__(self, parent: Optional["QObject"] = None) -> None: def __init__(self, parent: Optional["QObject"] = None) -> None:
super().__init__(parent) super().__init__(parent)
self._manager: CuraPackageManager = CuraApplication.getInstance().getPackageManager() self._manager: CuraPackageManager = CuraApplication.getInstance().getPackageManager()
self._plugin_registry: PluginRegistry = CuraApplication.getInstance().getPluginRegistry()
self._account = CuraApplication.getInstance().getCuraAPI().account self._account = CuraApplication.getInstance().getCuraAPI().account
self._error_message = "" self._error_message = ""
self.addRoleName(self.PackageRole, "package") self.addRoleName(self.PackageRole, "package")
@ -194,7 +195,6 @@ class PackageList(ListModel):
if update: if update:
package.is_updating = False package.is_updating = False
else: else:
Logger.debug(f"Setting recently installed for package: {package_id}")
package.is_recently_managed = True package.is_recently_managed = True
package.is_installing = False package.is_installing = False
self.subscribeUserToPackage(package_id, str(package.sdk_version)) self.subscribeUserToPackage(package_id, str(package.sdk_version))
@ -258,7 +258,7 @@ class PackageList(ListModel):
def _connectManageButtonSignals(self, package: PackageModel) -> None: def _connectManageButtonSignals(self, package: PackageModel) -> None:
package.installPackageTriggered.connect(self.installPackage) package.installPackageTriggered.connect(self.installPackage)
package.uninstallPackageTriggered.connect(self.uninstallPackage) package.uninstallPackageTriggered.connect(self.uninstallPackage)
package.updatePackageTriggered.connect(self.installPackage) package.updatePackageTriggered.connect(self.updatePackage)
package.enablePackageTriggered.connect(self.enablePackage) package.enablePackageTriggered.connect(self.enablePackage)
package.disablePackageTriggered.connect(self.disablePackage) package.disablePackageTriggered.connect(self.disablePackage)
@ -294,7 +294,8 @@ class PackageList(ListModel):
package = self.getPackageModel(package_id) package = self.getPackageModel(package_id)
package.is_enabling = True package.is_enabling = True
Logger.debug(f"Enabling {package_id}") Logger.debug(f"Enabling {package_id}")
# TODO: implement enabling functionality self._plugin_registry.enablePlugin(package_id)
package.is_active = True
package.is_enabling = False package.is_enabling = False
@pyqtSlot(str) @pyqtSlot(str)
@ -302,5 +303,6 @@ class PackageList(ListModel):
package = self.getPackageModel(package_id) package = self.getPackageModel(package_id)
package.is_enabling = True package.is_enabling = True
Logger.debug(f"Disabling {package_id}") Logger.debug(f"Disabling {package_id}")
# TODO: implement disabling functionality self._plugin_registry.disablePlugin(package_id)
package.is_active = False
package.is_enabling = False package.is_enabling = False

View file

@ -66,6 +66,7 @@ class PackageModel(QObject):
self._can_update = False self._can_update = False
self._is_updating = False self._is_updating = False
self._is_enabling = False self._is_enabling = False
self._can_downgrade = False
self._section_title = section_title self._section_title = section_title
self.sdk_version = package_data.get("sdk_version_semver", "") 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. # Note that there's a lot more info in the package_data than just these specified here.
@ -287,8 +288,6 @@ class PackageModel(QObject):
if self._is_recently_managed: if self._is_recently_managed:
return "hidden" return "hidden"
if self._package_type == "material": if self._package_type == "material":
if self._is_bundled: # TODO: Check if a bundled material can/should be un-/install en-/disabled
return "secondary"
return "hidden" return "hidden"
if not self._is_installed: if not self._is_installed:
return "hidden" return "hidden"
@ -306,6 +305,16 @@ class PackageModel(QObject):
self._is_enabling = value self._is_enabling = value
self.stateManageButtonChanged.emit() self.stateManageButtonChanged.emit()
@property
def is_active(self) -> bool:
return self._is_active
@is_active.setter
def is_active(self, value: bool) -> None:
if value != self._is_active:
self._is_active = value
self.stateManageButtonChanged.emit()
# --- Installing --- # --- Installing ---
@pyqtProperty(str, notify = stateManageButtonChanged) @pyqtProperty(str, notify = stateManageButtonChanged)
@ -315,7 +324,7 @@ class PackageModel(QObject):
if self._is_recently_managed: if self._is_recently_managed:
return "hidden" return "hidden"
if self._is_installed: if self._is_installed:
if self._is_bundled: if self._is_bundled and not self._can_downgrade:
return "hidden" return "hidden"
else: else:
return "secondary" return "secondary"
@ -342,6 +351,16 @@ class PackageModel(QObject):
self._is_installing = value self._is_installing = value
self.stateManageButtonChanged.emit() self.stateManageButtonChanged.emit()
@property
def can_downgrade(self) -> bool:
return self._can_downgrade
@can_downgrade.setter
def can_downgrade(self, value: bool) -> None:
if value != self._can_downgrade:
self._can_downgrade = value
self.stateManageButtonChanged.emit()
# --- Updating --- # --- Updating ---
@pyqtProperty(str, notify = stateManageButtonChanged) @pyqtProperty(str, notify = stateManageButtonChanged)
@ -371,78 +390,3 @@ class PackageModel(QObject):
if value != self._can_update: if value != self._can_update:
self._can_update = value self._can_update = value
self.stateManageButtonChanged.emit() self.stateManageButtonChanged.emit()
# ----
# isInstalledChanged = pyqtSignal()
#
# @pyqtProperty(bool, notify = isInstalledChanged)
# def isInstalled(self):
# return self._is_installed
#
# isEnabledChanged = pyqtSignal()
#
#
#f
# @pyqtProperty(bool, notify = isEnabledChanged)
# def isEnabled(self) -> bool:
# return self._is_active
#
#
#
# isManageEnableStateChanged = pyqtSignalf()
#
# @pyqtProperty(str, notify = isManageEnableStateChanged)
# def isManageEnableState(self) -> str:
# if self.isEnabling:
# return "busy"
# if self.
#
# manageEnableStateChanged = pyqtSignal()
#
# @pyqtProperty(str, notify = manageEnableStateChanged)
# def manageEnableState(self) -> str:
# # TODO: Handle manual installed packages
# if self._is_installed:
# if self._is_active:
# return "secondary"
# else:
# return "primary"
# else:
# return "hidden"
#
# manageInstallStateChanged = pyqtSignal()
#
# def setManageInstallState(self, value: bool) -> None:
# if value != self._is_installed:
# self._is_installed = value
# self.manageInstallStateChanged.emit()
# self.manageEnableStateChanged.emit()
#
# @pyqtProperty(str, notify = manageInstallStateChanged)
# def manageInstallState(self) -> str:
# if self._is_installed:
# if self._is_bundled:
# return "hidden"
# else:
# return "secondary"
# else:
# return "primary"
#
# manageUpdateStateChanged = pyqtSignal()
#
# @pyqtProperty(str, notify = manageUpdateStateChanged)
# def manageUpdateState(self) -> str:
# if self._can_update:
# return "primary"
# return "hidden"
#

View file

@ -15,9 +15,8 @@ RowLayout
property alias secondaryText: secondaryButton.text property alias secondaryText: secondaryButton.text
property string busyPrimaryText: busyMessageText.text property string busyPrimaryText: busyMessageText.text
property string busySecondaryText: busyMessageText.text property string busySecondaryText: busyMessageText.text
property string mainState: "primary"
property bool enabled: true property bool enabled: true
property bool busy property bool busy: state == "busy"
signal clicked(bool primary_action) signal clicked(bool primary_action)
@ -77,7 +76,7 @@ RowLayout
{ {
id: busyMessageText id: busyMessageText
visible: parent.visible visible: parent.visible
text: manageButton.mainState == "primary" ? manageButton.busyPrimaryText : manageButton.busySecondaryText text: manageButton.state == "primary" ? manageButton.busyPrimaryText : manageButton.busySecondaryText
anchors.left: busyIndicator.right anchors.left: busyIndicator.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter

View file

@ -106,9 +106,8 @@ Window
height: UM.Theme.getSize("button_icon").height + UM.Theme.getSize("default_margin").height height: UM.Theme.getSize("button_icon").height + UM.Theme.getSize("default_margin").height
spacing: UM.Theme.getSize("thin_margin").width spacing: UM.Theme.getSize("thin_margin").width
Rectangle Item
{ {
color: "transparent"
Layout.preferredHeight: parent.height Layout.preferredHeight: parent.height
Layout.preferredWidth: searchBar.visible ? UM.Theme.getSize("thin_margin").width : 0 Layout.preferredWidth: searchBar.visible ? UM.Theme.getSize("thin_margin").width : 0
Layout.fillWidth: ! searchBar.visible Layout.fillWidth: ! searchBar.visible
@ -228,4 +227,51 @@ Window
} }
} }
} }
Rectangle
{
height: quitButton.height + 2 * UM.Theme.getSize("default_margin").width
color: UM.Theme.getColor("primary")
visible: false // TODO: enable this when restart is required
anchors
{
left: parent.left
right: parent.right
bottom: parent.bottom
}
RowLayout
{
anchors
{
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
margins: UM.Theme.getSize("default_margin").width
}
spacing: UM.Theme.getSize("default_margin").width
UM.RecolorImage
{
id: bannerIcon
source: UM.Theme.getIcon("Plugin")
color: UM.Theme.getColor("primary_button_text")
implicitWidth: UM.Theme.getSize("banner_icon_size").width
implicitHeight: UM.Theme.getSize("banner_icon_size").height
}
Text
{
color: UM.Theme.getColor("primary_button_text")
text: catalog.i18nc("@button", "In order to use the package you will need to restart Cura")
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
Layout.fillWidth: true
}
Cura.SecondaryButton
{
id: quitButton
text: catalog.i18nc("@button", "Quit Ultimaker Cura")
}
}
}
} }

View file

@ -94,7 +94,7 @@ Rectangle
left: packageItem.right left: packageItem.right
leftMargin: UM.Theme.getSize("default_margin").width leftMargin: UM.Theme.getSize("default_margin").width
right: parent.right right: parent.right
rightMargin: UM.Theme.getSize("thick_margin").width rightMargin: UM.Theme.getSize("default_margin").width
top: parent.top top: parent.top
topMargin: UM.Theme.getSize("narrow_margin").height topMargin: UM.Theme.getSize("narrow_margin").height
} }
@ -114,46 +114,12 @@ Rectangle
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")
verticalAlignment: Text.AlignTop verticalAlignment: Text.AlignTop
} }
VerifiedIcon
Control
{ {
Layout.preferredWidth: UM.Theme.getSize("card_tiny_icon").width
Layout.preferredHeight: UM.Theme.getSize("card_tiny_icon").height
enabled: packageData.isCheckedByUltimaker enabled: packageData.isCheckedByUltimaker
visible: packageData.isCheckedByUltimaker visible: packageData.isCheckedByUltimaker
Cura.ToolTip
{
tooltipText:
{
switch(packageData.packageType)
{
case "plugin": return catalog.i18nc("@info", "Ultimaker Verified Plug-in");
case "material": return catalog.i18nc("@info", "Ultimaker Certified Material");
default: return catalog.i18nc("@info", "Ultimaker Verified Package");
}
}
visible: parent.hovered
targetPoint: Qt.point(0, Math.round(parent.y + parent.height / 4))
} }
Rectangle
{
anchors.fill: parent
color: UM.Theme.getColor("action_button_hovered")
radius: width
UM.RecolorImage
{
anchors.fill: parent
color: UM.Theme.getColor("primary")
source: packageData.packageType == "plugin" ? UM.Theme.getIcon("CheckCircle") : UM.Theme.getIcon("Certified")
}
}
//NOTE: Can we link to something here? (Probably a static link explaining what verified is):
// onClicked: Qt.openUrlExternally( XXXXXX )
}
Control Control
{ {
@ -362,12 +328,8 @@ Rectangle
secondaryText: catalog.i18nc("@button", "Disable") secondaryText: catalog.i18nc("@button", "Disable")
busySecondaryText: catalog.i18nc("@button", "disabling...") busySecondaryText: catalog.i18nc("@button", "disabling...")
enabled: !(installManageButton.busy || updateManageButton.busy) enabled: !(installManageButton.busy || updateManageButton.busy)
}
Connections onClicked: {
{
target: enableManageButton
function onClicked(primary_action)
{
if (primary_action) if (primary_action)
{ {
packageData.enablePackageTriggered(packageData.packageId) packageData.enablePackageTriggered(packageData.packageId)
@ -389,11 +351,7 @@ Rectangle
secondaryText: catalog.i18nc("@button", "Uninstall") secondaryText: catalog.i18nc("@button", "Uninstall")
busySecondaryText: catalog.i18nc("@button", "uninstalling...") busySecondaryText: catalog.i18nc("@button", "uninstalling...")
enabled: !(enableManageButton.busy || updateManageButton.busy) enabled: !(enableManageButton.busy || updateManageButton.busy)
} onClicked:
Connections
{
target: installManageButton
function onClicked(primary_action)
{ {
if (primary_action) if (primary_action)
{ {
@ -414,14 +372,7 @@ Rectangle
primaryText: catalog.i18nc("@button", "Update") primaryText: catalog.i18nc("@button", "Update")
busyPrimaryText: catalog.i18nc("@button", "updating...") busyPrimaryText: catalog.i18nc("@button", "updating...")
enabled: !(installManageButton.busy || enableManageButton.busy) enabled: !(installManageButton.busy || enableManageButton.busy)
} onClicked: packageData.updatePackageTriggered(packageData.packageId)
Connections
{
target: updateManageButton
function onClicked(primary_action)
{
packageData.updatePackageTriggered(packageData.packageId)
}
} }
} }
} }

View file

@ -0,0 +1,45 @@
// Copyright (c) 2021 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.1
import UM 1.6 as UM
import Cura 1.6 as Cura
Control
{
implicitWidth: UM.Theme.getSize("card_tiny_icon").width
implicitHeight: UM.Theme.getSize("card_tiny_icon").height
Cura.ToolTip
{
tooltipText:
{
switch(packageData.packageType)
{
case "plugin": return catalog.i18nc("@info", "Ultimaker Verified Plug-in");
case "material": return catalog.i18nc("@info", "Ultimaker Certified Material");
default: return catalog.i18nc("@info", "Ultimaker Verified Package");
}
}
visible: parent.hovered
targetPoint: Qt.point(0, Math.round(parent.y + parent.height / 4))
}
Rectangle
{
anchors.fill: parent
color: UM.Theme.getColor("action_button_hovered")
radius: width
UM.RecolorImage
{
anchors.fill: parent
color: UM.Theme.getColor("primary")
source: packageData.packageType == "plugin" ? UM.Theme.getIcon("CheckCircle") : UM.Theme.getIcon("Certified")
}
}
//NOTE: Can we link to something here? (Probably a static link explaining what verified is):
// onClicked: Qt.openUrlExternally( XXXXXX )
}

View file

@ -179,7 +179,7 @@
"lining": [192, 193, 194, 255], "lining": [192, 193, 194, 255],
"viewport_overlay": [246, 246, 246, 255], "viewport_overlay": [246, 246, 246, 255],
"primary": [50, 130, 255, 255], "primary": [25, 110, 240, 255],
"primary_shadow": [64, 47, 205, 255], "primary_shadow": [64, 47, 205, 255],
"primary_hover": [48, 182, 231, 255], "primary_hover": [48, 182, 231, 255],
"primary_text": [255, 255, 255, 255], "primary_text": [255, 255, 255, 255],