From 09e221d64a3954b515e86dccb786b0a9101804f6 Mon Sep 17 00:00:00 2001 From: casper Date: Mon, 6 Dec 2021 14:49:50 +0100 Subject: [PATCH 1/8] Add license dialog to the Marketplace cura 8587 --- plugins/Marketplace/LicenseModel.py | 66 +++++++++++ plugins/Marketplace/PackageList.py | 39 ++++++- .../resources/qml/LicenseDialog.qml | 110 ++++++++++++++++++ 3 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 plugins/Marketplace/LicenseModel.py create mode 100644 plugins/Marketplace/resources/qml/LicenseDialog.qml diff --git a/plugins/Marketplace/LicenseModel.py b/plugins/Marketplace/LicenseModel.py new file mode 100644 index 0000000000..cb85b33430 --- /dev/null +++ b/plugins/Marketplace/LicenseModel.py @@ -0,0 +1,66 @@ +from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal +from UM.i18n import i18nCatalog + +catalog = i18nCatalog("cura") + +# Model for the LicenseDialog +class LicenseModel(QObject): + DEFAULT_DECLINE_BUTTON_TEXT = catalog.i18nc("@button", "Decline") + ACCEPT_BUTTON_TEXT = catalog.i18nc("@button", "Agree") + + dialogTitleChanged = pyqtSignal() + packageNameChanged = pyqtSignal() + licenseTextChanged = pyqtSignal() + iconChanged = pyqtSignal() + + def __init__(self, decline_button_text: str = DEFAULT_DECLINE_BUTTON_TEXT) -> None: + super().__init__() + + self._dialogTitle = "" + self._license_text = "" + self._package_name = "" + self._icon_url = "" + self._decline_button_text = decline_button_text + + @pyqtProperty(str, constant = True) + def acceptButtonText(self): + return self.ACCEPT_BUTTON_TEXT + + @pyqtProperty(str, constant = True) + def declineButtonText(self): + return self._decline_button_text + + @pyqtProperty(str, notify=dialogTitleChanged) + def dialogTitle(self) -> str: + return self._dialogTitle + + @pyqtProperty(str, notify=packageNameChanged) + def packageName(self) -> str: + return self._package_name + + def setPackageName(self, name: str) -> None: + self._package_name = name + self.packageNameChanged.emit() + + @pyqtProperty(str, notify=iconChanged) + def iconUrl(self) -> str: + return self._icon_url + + def setIconUrl(self, url: str): + self._icon_url = url + self.iconChanged.emit() + + @pyqtProperty(str, notify=licenseTextChanged) + def licenseText(self) -> str: + return self._license_text + + def setLicenseText(self, license_text: str) -> None: + if self._license_text != license_text: + self._license_text = license_text + self.licenseTextChanged.emit() + + def _updateDialogTitle(self): + self._dialogTitle = catalog.i18nc("@title:window", "Plugin License Agreement") + if self._page_count > 1: + self._dialogTitle = self._dialogTitle + " ({}/{})".format(self._current_page_idx + 1, self._page_count) + self.dialogTitleChanged.emit() diff --git a/plugins/Marketplace/PackageList.py b/plugins/Marketplace/PackageList.py index 301f765dab..0c5895866c 100644 --- a/plugins/Marketplace/PackageList.py +++ b/plugins/Marketplace/PackageList.py @@ -2,6 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import tempfile import json +import os.path from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, Qt from typing import Dict, Optional, Set, TYPE_CHECKING @@ -11,6 +12,7 @@ from UM.Qt.ListModel import ListModel from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope from UM.TaskManagement.HttpRequestManager import HttpRequestData, HttpRequestManager from UM.Logger import Logger +from UM.PluginRegistry import PluginRegistry from cura.CuraApplication import CuraApplication from cura import CuraPackageManager @@ -18,6 +20,7 @@ from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope # To ma from .PackageModel import PackageModel from .Constants import USER_PACKAGES_URL +from .LicenseModel import LicenseModel if TYPE_CHECKING: from PyQt5.QtCore import QObject @@ -42,12 +45,24 @@ class PackageList(ListModel): self._has_more = False self._has_footer = True self._to_install: Dict[str, str] = {} - self.canInstallChanged.connect(self._install) + self.canInstallChanged.connect(self._requestInstall) self._local_packages: Set[str] = {p["package_id"] for p in self._manager.local_packages} self._ongoing_request: Optional[HttpRequestData] = None self._scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance())) + self._license_model = LicenseModel() + + plugin_path = PluginRegistry.getInstance().getPluginPath("Marketplace") + if plugin_path is None: + plugin_path = os.path.dirname(__file__) + + # create a QML component for the license dialog + license_dialog_component_path = os.path.join(plugin_path, "resources", "qml", "LicenseDialog.qml") + self._license_dialog = CuraApplication.getInstance().createQmlComponent(license_dialog_component_path, { + "licenseModel": self._license_model + }) + @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""" @@ -119,6 +134,28 @@ class PackageList(ListModel): canInstallChanged = pyqtSignal(str, bool) + def _openLicenseDialog(self, plugin_name: str, license_content: str, icon_url: str) -> None: + self._license_model.setIconUrl(icon_url) + self._license_model.setPackageName(plugin_name) + self._license_model.setLicenseText(license_content) + self._license_dialog.show() + + def _requestInstall(self, package_id: str, update: bool = False) -> None: + Logger.debug(f"Request installing {package_id}") + + package_path = self._to_install.pop(package_id) + license_content = self._manager.getPackageLicense(package_path) + + if not update and license_content is not None: + # open dialog, prompting the using to accept the plugin license + package = self.getPackageModel(package_id) + plugin_name = package.displayName + icon_url = package.iconUrl + self._openLicenseDialog(plugin_name, license_content, icon_url) + else: + # Otherwise continue the installation + self._install(package_id, update) + def _install(self, package_id: str, update: bool = False) -> None: package_path = self._to_install.pop(package_id) Logger.debug(f"Installing {package_id}") diff --git a/plugins/Marketplace/resources/qml/LicenseDialog.qml b/plugins/Marketplace/resources/qml/LicenseDialog.qml new file mode 100644 index 0000000000..9219f4ed32 --- /dev/null +++ b/plugins/Marketplace/resources/qml/LicenseDialog.qml @@ -0,0 +1,110 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Toolbox is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.10 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 +import QtQuick.Controls.Styles 1.4 + +import UM 1.1 as UM +import Cura 1.6 as Cura + +UM.Dialog +{ + id: licenseDialog + title: licenseModel.dialogTitle + minimumWidth: UM.Theme.getSize("license_window_minimum").width + minimumHeight: UM.Theme.getSize("license_window_minimum").height + width: minimumWidth + height: minimumHeight + backgroundColor: UM.Theme.getColor("main_background") + margin: screenScaleFactor * 10 + + ColumnLayout + { + anchors.fill: parent + spacing: UM.Theme.getSize("thick_margin").height + + UM.I18nCatalog{id: catalog; name: "cura"} + + Label + { + id: licenseHeader + Layout.fillWidth: true + text: catalog.i18nc("@label", "You need to accept the license to install the package") + color: UM.Theme.getColor("text") + wrapMode: Text.Wrap + renderType: Text.NativeRendering + } + + Row { + id: packageRow + + Layout.fillWidth: true + height: childrenRect.height + spacing: UM.Theme.getSize("default_margin").width + leftPadding: UM.Theme.getSize("narrow_margin").width + + Image + { + id: icon + width: 30 * screenScaleFactor + height: width + sourceSize.width: width + sourceSize.height: height + fillMode: Image.PreserveAspectFit + source: licenseModel.iconUrl || "../../images/placeholder.svg" + mipmap: true + } + + Label + { + id: packageName + text: licenseModel.packageName + color: UM.Theme.getColor("text") + font.bold: true + anchors.verticalCenter: icon.verticalCenter + height: contentHeight + wrapMode: Text.Wrap + renderType: Text.NativeRendering + } + + + } + + Cura.ScrollableTextArea + { + + Layout.fillWidth: true + Layout.fillHeight: true + anchors.topMargin: UM.Theme.getSize("default_margin").height + + textArea.text: licenseModel.licenseText + textArea.readOnly: true + } + + } + rightButtons: + [ + Cura.PrimaryButton + { + leftPadding: UM.Theme.getSize("dialog_primary_button_padding").width + rightPadding: UM.Theme.getSize("dialog_primary_button_padding").width + + text: licenseModel.acceptButtonText + onClicked: { handler.onLicenseAccepted() } + } + ] + + leftButtons: + [ + Cura.SecondaryButton + { + id: declineButton + text: licenseModel.declineButtonText + onClicked: { handler.onLicenseDeclined() } + } + ] +} From c3665d7440d1beaa1a826d1fc874cfe39b1f70aa Mon Sep 17 00:00:00 2001 From: casper Date: Mon, 6 Dec 2021 15:45:27 +0100 Subject: [PATCH 2/8] Correctly handle actions from marketplace license prompt Install package on accept And stop spinner on decline cura 8587 --- plugins/Marketplace/PackageList.py | 36 ++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/plugins/Marketplace/PackageList.py b/plugins/Marketplace/PackageList.py index 0c5895866c..7bb1076988 100644 --- a/plugins/Marketplace/PackageList.py +++ b/plugins/Marketplace/PackageList.py @@ -60,7 +60,8 @@ class PackageList(ListModel): # create a QML component for the license dialog license_dialog_component_path = os.path.join(plugin_path, "resources", "qml", "LicenseDialog.qml") self._license_dialog = CuraApplication.getInstance().createQmlComponent(license_dialog_component_path, { - "licenseModel": self._license_model + "licenseModel": self._license_model, + "handler": self }) @pyqtSlot() @@ -135,11 +136,32 @@ class PackageList(ListModel): canInstallChanged = pyqtSignal(str, bool) def _openLicenseDialog(self, plugin_name: str, license_content: str, icon_url: str) -> None: + Logger.debug(f"Prompting license for {plugin_name}") self._license_model.setIconUrl(icon_url) self._license_model.setPackageName(plugin_name) self._license_model.setLicenseText(license_content) self._license_dialog.show() + @pyqtSlot() + def onLicenseAccepted(self) -> None: + package_id = self._to_be_installed_package_id + package_path = self._to_be_installed_package_path + del self._to_be_installed_package_id + del self._to_be_installed_package_path + Logger.debug(f"Accepted license for {package_id}") + self._license_dialog.close() + self._install(package_id, package_path) + + @pyqtSlot() + def onLicenseDeclined(self) -> None: + package_id = self._to_be_installed_package_id + del self._to_be_installed_package_id + del self._to_be_installed_package_path + Logger.debug(f"Declined license for {package_id}") + self._license_dialog.close() + package = self.getPackageModel(package_id) + package.is_installing = False + def _requestInstall(self, package_id: str, update: bool = False) -> None: Logger.debug(f"Request installing {package_id}") @@ -147,17 +169,23 @@ class PackageList(ListModel): license_content = self._manager.getPackageLicense(package_path) if not update and license_content is not None: + # If installation is not and update, and the packages contains a license then # open dialog, prompting the using to accept the plugin license + + # Store some properties that are needed after the dialog is closed + self._to_be_installed_package_id = package_id + self._to_be_installed_package_path = package_path + + # Open actual dialog package = self.getPackageModel(package_id) plugin_name = package.displayName icon_url = package.iconUrl self._openLicenseDialog(plugin_name, license_content, icon_url) else: # Otherwise continue the installation - self._install(package_id, update) + self._install(package_id, package_path, update) - def _install(self, package_id: str, update: bool = False) -> None: - package_path = self._to_install.pop(package_id) + def _install(self, package_id: str, package_path: str, update: bool = False) -> None: Logger.debug(f"Installing {package_id}") to_be_installed = self._manager.installPackage(package_path) is not None package = self.getPackageModel(package_id) From 0cc9d8db6875b4c3bc3521fbf6ca2e8ad9e52c90 Mon Sep 17 00:00:00 2001 From: casper Date: Mon, 6 Dec 2021 15:51:19 +0100 Subject: [PATCH 3/8] Use existing plugin registry Fix after merge cura 8587 --- plugins/Marketplace/PackageList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Marketplace/PackageList.py b/plugins/Marketplace/PackageList.py index a9d4e698ed..d50e19d514 100644 --- a/plugins/Marketplace/PackageList.py +++ b/plugins/Marketplace/PackageList.py @@ -54,7 +54,7 @@ class PackageList(ListModel): self._license_model = LicenseModel() - plugin_path = PluginRegistry.getInstance().getPluginPath("Marketplace") + plugin_path = self._plugin_registry.getPluginPath("Marketplace") if plugin_path is None: plugin_path = os.path.dirname(__file__) From 4848c474e81bbe60a1e3a764c474d7a0efc821cb Mon Sep 17 00:00:00 2001 From: casper Date: Mon, 6 Dec 2021 17:10:13 +0100 Subject: [PATCH 4/8] Implement UX design for maketplace license dialog cura 8587 --- plugins/Marketplace/LicenseModel.py | 10 ----- plugins/Marketplace/PackageList.py | 6 +-- .../resources/qml/LicenseDialog.qml | 40 +++++-------------- .../cura-light/icons/high/Certificate.svg | 3 ++ resources/themes/cura-light/theme.json | 4 +- 5 files changed, 17 insertions(+), 46 deletions(-) create mode 100644 resources/themes/cura-light/icons/high/Certificate.svg diff --git a/plugins/Marketplace/LicenseModel.py b/plugins/Marketplace/LicenseModel.py index cb85b33430..199ddc9ee0 100644 --- a/plugins/Marketplace/LicenseModel.py +++ b/plugins/Marketplace/LicenseModel.py @@ -11,7 +11,6 @@ class LicenseModel(QObject): dialogTitleChanged = pyqtSignal() packageNameChanged = pyqtSignal() licenseTextChanged = pyqtSignal() - iconChanged = pyqtSignal() def __init__(self, decline_button_text: str = DEFAULT_DECLINE_BUTTON_TEXT) -> None: super().__init__() @@ -19,7 +18,6 @@ class LicenseModel(QObject): self._dialogTitle = "" self._license_text = "" self._package_name = "" - self._icon_url = "" self._decline_button_text = decline_button_text @pyqtProperty(str, constant = True) @@ -42,14 +40,6 @@ class LicenseModel(QObject): self._package_name = name self.packageNameChanged.emit() - @pyqtProperty(str, notify=iconChanged) - def iconUrl(self) -> str: - return self._icon_url - - def setIconUrl(self, url: str): - self._icon_url = url - self.iconChanged.emit() - @pyqtProperty(str, notify=licenseTextChanged) def licenseText(self) -> str: return self._license_text diff --git a/plugins/Marketplace/PackageList.py b/plugins/Marketplace/PackageList.py index d50e19d514..e41d28721c 100644 --- a/plugins/Marketplace/PackageList.py +++ b/plugins/Marketplace/PackageList.py @@ -136,9 +136,8 @@ class PackageList(ListModel): canInstallChanged = pyqtSignal(str, bool) - def _openLicenseDialog(self, plugin_name: str, license_content: str, icon_url: str) -> None: + def _openLicenseDialog(self, plugin_name: str, license_content: str) -> None: Logger.debug(f"Prompting license for {plugin_name}") - self._license_model.setIconUrl(icon_url) self._license_model.setPackageName(plugin_name) self._license_model.setLicenseText(license_content) self._license_dialog.show() @@ -180,8 +179,7 @@ class PackageList(ListModel): # Open actual dialog package = self.getPackageModel(package_id) plugin_name = package.displayName - icon_url = package.iconUrl - self._openLicenseDialog(plugin_name, license_content, icon_url) + self._openLicenseDialog(plugin_name, license_content) else: # Otherwise continue the installation self._install(package_id, package_path, update) diff --git a/plugins/Marketplace/resources/qml/LicenseDialog.qml b/plugins/Marketplace/resources/qml/LicenseDialog.qml index 9219f4ed32..0640379895 100644 --- a/plugins/Marketplace/resources/qml/LicenseDialog.qml +++ b/plugins/Marketplace/resources/qml/LicenseDialog.qml @@ -20,7 +20,6 @@ UM.Dialog width: minimumWidth height: minimumHeight backgroundColor: UM.Theme.getColor("main_background") - margin: screenScaleFactor * 10 ColumnLayout { @@ -29,49 +28,32 @@ UM.Dialog UM.I18nCatalog{id: catalog; name: "cura"} - Label - { - id: licenseHeader - Layout.fillWidth: true - text: catalog.i18nc("@label", "You need to accept the license to install the package") - color: UM.Theme.getColor("text") - wrapMode: Text.Wrap - renderType: Text.NativeRendering - } - Row { - id: packageRow - Layout.fillWidth: true height: childrenRect.height spacing: UM.Theme.getSize("default_margin").width leftPadding: UM.Theme.getSize("narrow_margin").width - Image + UM.RecolorImage { - id: icon - width: 30 * screenScaleFactor - height: width - sourceSize.width: width - sourceSize.height: height - fillMode: Image.PreserveAspectFit - source: licenseModel.iconUrl || "../../images/placeholder.svg" - mipmap: true + width: UM.Theme.getSize("marketplace_large_icon").width + height: UM.Theme.getSize("marketplace_large_icon").height + color: UM.Theme.getColor("text") + source: UM.Theme.getIcon("Certificate", "high") } Label { - id: packageName - text: licenseModel.packageName + text: catalog.i18nc("@text", "Please read and agree with the plugin licence.") color: UM.Theme.getColor("text") - font.bold: true + font: UM.Theme.getFont("large") anchors.verticalCenter: icon.verticalCenter - height: contentHeight + height: UM.Theme.getSize("marketplace_large_icon").height + verticalAlignment: Qt.AlignVCenter wrapMode: Text.Wrap renderType: Text.NativeRendering } - } Cura.ScrollableTextArea @@ -90,9 +72,6 @@ UM.Dialog [ Cura.PrimaryButton { - leftPadding: UM.Theme.getSize("dialog_primary_button_padding").width - rightPadding: UM.Theme.getSize("dialog_primary_button_padding").width - text: licenseModel.acceptButtonText onClicked: { handler.onLicenseAccepted() } } @@ -102,7 +81,6 @@ UM.Dialog [ Cura.SecondaryButton { - id: declineButton text: licenseModel.declineButtonText onClicked: { handler.onLicenseDeclined() } } diff --git a/resources/themes/cura-light/icons/high/Certificate.svg b/resources/themes/cura-light/icons/high/Certificate.svg new file mode 100644 index 0000000000..b588bddd8b --- /dev/null +++ b/resources/themes/cura-light/icons/high/Certificate.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 149bfab308..8e9db0e9fe 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -686,6 +686,8 @@ "welcome_wizard_content_image_big": [18, 15], "welcome_wizard_cloud_content_image": [4, 4], - "banner_icon_size": [2.0, 2.0] + "banner_icon_size": [2.0, 2.0], + + "marketplace_large_icon": [4.0, 4.0] } } From 119b86b9579910e31d2ef7063aca86242e9df2a7 Mon Sep 17 00:00:00 2001 From: casper Date: Mon, 6 Dec 2021 17:32:10 +0100 Subject: [PATCH 5/8] Remove page-count logic from LicenceModel title dialog cura 8587 --- plugins/Marketplace/LicenseModel.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/Marketplace/LicenseModel.py b/plugins/Marketplace/LicenseModel.py index 199ddc9ee0..1bedb02cad 100644 --- a/plugins/Marketplace/LicenseModel.py +++ b/plugins/Marketplace/LicenseModel.py @@ -51,6 +51,4 @@ class LicenseModel(QObject): def _updateDialogTitle(self): self._dialogTitle = catalog.i18nc("@title:window", "Plugin License Agreement") - if self._page_count > 1: - self._dialogTitle = self._dialogTitle + " ({}/{})".format(self._current_page_idx + 1, self._page_count) self.dialogTitleChanged.emit() From 49a6a83fe93e864c53865319444dc388c277c66e Mon Sep 17 00:00:00 2001 From: casper Date: Mon, 6 Dec 2021 17:50:18 +0100 Subject: [PATCH 6/8] Move button text inside QML element cura 8587 --- plugins/Marketplace/LicenseModel.py | 23 +------------------ .../resources/qml/LicenseDialog.qml | 6 ++--- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/plugins/Marketplace/LicenseModel.py b/plugins/Marketplace/LicenseModel.py index 1bedb02cad..64625185d7 100644 --- a/plugins/Marketplace/LicenseModel.py +++ b/plugins/Marketplace/LicenseModel.py @@ -5,32 +5,15 @@ catalog = i18nCatalog("cura") # Model for the LicenseDialog class LicenseModel(QObject): - DEFAULT_DECLINE_BUTTON_TEXT = catalog.i18nc("@button", "Decline") - ACCEPT_BUTTON_TEXT = catalog.i18nc("@button", "Agree") dialogTitleChanged = pyqtSignal() packageNameChanged = pyqtSignal() licenseTextChanged = pyqtSignal() - def __init__(self, decline_button_text: str = DEFAULT_DECLINE_BUTTON_TEXT) -> None: + def __init__(self, licence_text: str, package_name: str) -> None: super().__init__() - - self._dialogTitle = "" self._license_text = "" self._package_name = "" - self._decline_button_text = decline_button_text - - @pyqtProperty(str, constant = True) - def acceptButtonText(self): - return self.ACCEPT_BUTTON_TEXT - - @pyqtProperty(str, constant = True) - def declineButtonText(self): - return self._decline_button_text - - @pyqtProperty(str, notify=dialogTitleChanged) - def dialogTitle(self) -> str: - return self._dialogTitle @pyqtProperty(str, notify=packageNameChanged) def packageName(self) -> str: @@ -48,7 +31,3 @@ class LicenseModel(QObject): if self._license_text != license_text: self._license_text = license_text self.licenseTextChanged.emit() - - def _updateDialogTitle(self): - self._dialogTitle = catalog.i18nc("@title:window", "Plugin License Agreement") - self.dialogTitleChanged.emit() diff --git a/plugins/Marketplace/resources/qml/LicenseDialog.qml b/plugins/Marketplace/resources/qml/LicenseDialog.qml index 0640379895..6d863ecce5 100644 --- a/plugins/Marketplace/resources/qml/LicenseDialog.qml +++ b/plugins/Marketplace/resources/qml/LicenseDialog.qml @@ -14,7 +14,7 @@ import Cura 1.6 as Cura UM.Dialog { id: licenseDialog - title: licenseModel.dialogTitle + title: catalog.i18nc("@button", "Plugin license agreement") minimumWidth: UM.Theme.getSize("license_window_minimum").width minimumHeight: UM.Theme.getSize("license_window_minimum").height width: minimumWidth @@ -72,7 +72,7 @@ UM.Dialog [ Cura.PrimaryButton { - text: licenseModel.acceptButtonText + text: catalog.i18nc("@button", "Accept") onClicked: { handler.onLicenseAccepted() } } ] @@ -81,7 +81,7 @@ UM.Dialog [ Cura.SecondaryButton { - text: licenseModel.declineButtonText + text: catalog.i18nc("@button", "Decline") onClicked: { handler.onLicenseDeclined() } } ] From 28b21628b44748b0a8d52147e1b361a1f615a664 Mon Sep 17 00:00:00 2001 From: casper Date: Mon, 6 Dec 2021 18:07:44 +0100 Subject: [PATCH 7/8] Remove unused package_name property and add package_id in license model The `_to_be_installed_package_id` and `_to_be_installed_package_path` can now be removed from the class as they can requested from the model itself. This we make sure that the we alway install the package for which the license was recently accepted. cura 8587 --- plugins/Marketplace/LicenseModel.py | 20 +++++++++---------- plugins/Marketplace/PackageList.py | 30 +++++++++-------------------- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/plugins/Marketplace/LicenseModel.py b/plugins/Marketplace/LicenseModel.py index 64625185d7..8eb439d4d6 100644 --- a/plugins/Marketplace/LicenseModel.py +++ b/plugins/Marketplace/LicenseModel.py @@ -5,23 +5,21 @@ catalog = i18nCatalog("cura") # Model for the LicenseDialog class LicenseModel(QObject): - - dialogTitleChanged = pyqtSignal() - packageNameChanged = pyqtSignal() + packageIdChanged = pyqtSignal() licenseTextChanged = pyqtSignal() - def __init__(self, licence_text: str, package_name: str) -> None: + def __init__(self) -> None: super().__init__() self._license_text = "" - self._package_name = "" + self._package_id = "" - @pyqtProperty(str, notify=packageNameChanged) - def packageName(self) -> str: - return self._package_name + @pyqtProperty(str, notify=packageIdChanged) + def packageId(self) -> str: + return self._package_id - def setPackageName(self, name: str) -> None: - self._package_name = name - self.packageNameChanged.emit() + def setPackageId(self, name: str) -> None: + self._package_id = name + self.packageIdChanged.emit() @pyqtProperty(str, notify=licenseTextChanged) def licenseText(self) -> str: diff --git a/plugins/Marketplace/PackageList.py b/plugins/Marketplace/PackageList.py index 9414bb9b28..39d1d9fab6 100644 --- a/plugins/Marketplace/PackageList.py +++ b/plugins/Marketplace/PackageList.py @@ -139,25 +139,20 @@ class PackageList(ListModel): def _openLicenseDialog(self, plugin_name: str, license_content: str) -> None: Logger.debug(f"Prompting license for {plugin_name}") - self._license_model.setPackageName(plugin_name) + self._license_model.setPackageId(plugin_name) self._license_model.setLicenseText(license_content) self._license_dialog.show() @pyqtSlot() def onLicenseAccepted(self) -> None: - package_id = self._to_be_installed_package_id - package_path = self._to_be_installed_package_path - del self._to_be_installed_package_id - del self._to_be_installed_package_path + package_id = self._license_model.packageId Logger.debug(f"Accepted license for {package_id}") self._license_dialog.close() - self._install(package_id, package_path) + self._install(package_id) @pyqtSlot() def onLicenseDeclined(self) -> None: - package_id = self._to_be_installed_package_id - del self._to_be_installed_package_id - del self._to_be_installed_package_path + package_id = self._license_model.packageId Logger.debug(f"Declined license for {package_id}") self._license_dialog.close() package = self.getPackageModel(package_id) @@ -166,27 +161,20 @@ class PackageList(ListModel): def _requestInstall(self, package_id: str, update: bool = False) -> None: Logger.debug(f"Request installing {package_id}") - package_path = self._to_install.pop(package_id) + package_path = self._to_install[package_id] license_content = self._manager.getPackageLicense(package_path) if not update and license_content is not None: # If installation is not and update, and the packages contains a license then # open dialog, prompting the using to accept the plugin license - - # Store some properties that are needed after the dialog is closed - self._to_be_installed_package_id = package_id - self._to_be_installed_package_path = package_path - - # Open actual dialog - package = self.getPackageModel(package_id) - plugin_name = package.displayName - self._openLicenseDialog(plugin_name, license_content) + self._openLicenseDialog(package_id, license_content) else: # Otherwise continue the installation - self._install(package_id, package_path, update) + self._install(package_id, update) - def _install(self, package_id: str, package_path: str, update: bool = False) -> None: + def _install(self, package_id: str, update: bool = False) -> None: Logger.debug(f"Installing {package_id}") + package_path = self._to_install.pop(package_id) to_be_installed = self._manager.installPackage(package_path) is not None package = self.getPackageModel(package_id) if package.can_update and to_be_installed: From 455f6f17915485ac5e778f3d3b03cb720a839fe6 Mon Sep 17 00:00:00 2001 From: casper Date: Mon, 6 Dec 2021 18:12:58 +0100 Subject: [PATCH 8/8] Update licencing comment cura 8587 --- plugins/Marketplace/resources/qml/LicenseDialog.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Marketplace/resources/qml/LicenseDialog.qml b/plugins/Marketplace/resources/qml/LicenseDialog.qml index 6d863ecce5..7bee6f9108 100644 --- a/plugins/Marketplace/resources/qml/LicenseDialog.qml +++ b/plugins/Marketplace/resources/qml/LicenseDialog.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Toolbox is released under the terms of the LGPLv3 or higher. +//Copyright (c) 2021 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 import QtQuick.Dialogs 1.1