From 7377dd551c6ac3f7fd21468a3b0cbe978c5d2f89 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Mon, 20 Apr 2020 15:04:53 +0200 Subject: [PATCH 1/9] Rearrange welcome pages in first run wizard Sign in to Ultimaker Cloud page will now appear before the add printer page. CURA-7019 --- cura/UI/WelcomePagesModel.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cura/UI/WelcomePagesModel.py b/cura/UI/WelcomePagesModel.py index c16ec3763e..429e8b2665 100644 --- a/cura/UI/WelcomePagesModel.py +++ b/cura/UI/WelcomePagesModel.py @@ -243,6 +243,9 @@ class WelcomePagesModel(ListModel): {"id": "data_collections", "page_url": self._getBuiltinWelcomePagePath("DataCollectionsContent.qml"), }, + {"id": "cloud", + "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"), + }, {"id": "add_network_or_local_printer", "page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"), "next_page_id": "machine_actions", @@ -253,12 +256,8 @@ class WelcomePagesModel(ListModel): }, {"id": "machine_actions", "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"), - "next_page_id": "cloud", "should_show_function": self.shouldShowMachineActions, }, - {"id": "cloud", - "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"), - }, ] pages_to_show = all_pages_list From 7b464e5550b08d3e88da417ae638f00ca38c4bb4 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Mon, 20 Apr 2020 15:06:31 +0200 Subject: [PATCH 2/9] Close welcome wizard when user has cloud printers If the user signs in during the welcome process, if he/she has cloud printers connected to his/her account, then the welcome wizard will close so that the user will not be asked to add local printers. CURA-7019 --- .../src/Cloud/CloudOutputDeviceManager.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index ccc64f8073..61506693a9 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -88,6 +88,14 @@ class CloudOutputDeviceManager: ## Callback for when the request for getting the clusters is finished. def _onGetRemoteClustersFinished(self, clusters: List[CloudClusterResponse]) -> None: online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudClusterResponse] + + # If the user signs in from the welcome dialog, then we will search for cloud printers and if any of them are + # found, the welcome screen will close. This way we avoid prompting the user to add printers if he/she already + # has cloud printers + welcome_pages_model = CuraApplication.getInstance().getWelcomePagesModel() + cloud_page_idx = welcome_pages_model.getPageIndexById("cloud") + if welcome_pages_model.currentPageIndex == cloud_page_idx and online_clusters: + CuraApplication.getWelcomePagesModel().atEnd() for device_id, cluster_data in online_clusters.items(): if device_id not in self._remote_clusters: self._onDeviceDiscovered(cluster_data) From cac834b101bd5d1e5e39c9c543884310f4130dc3 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Mon, 20 Apr 2020 15:12:40 +0200 Subject: [PATCH 3/9] Refactor "Ultimaker Cloud" page in welcome wizard The following changes have been done: - Text content changed - "Sign in" and "Create an account" buttons moved in the middle, under the main text - "Sign in" button changed to PrimaryButton format - "Finish" button changed to "Skip" - "Skip" button format changed CURA-7019 --- resources/qml/WelcomePages/CloudContent.qml | 72 ++++++++++++--------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/resources/qml/WelcomePages/CloudContent.qml b/resources/qml/WelcomePages/CloudContent.qml index b127dbfb3c..9f262c50ed 100644 --- a/resources/qml/WelcomePages/CloudContent.qml +++ b/resources/qml/WelcomePages/CloudContent.qml @@ -33,7 +33,7 @@ Item anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter horizontalAlignment: Text.AlignHCenter - text: catalog.i18nc("@label", "Ultimaker Account") + text: catalog.i18nc("@label", "Sign in to Ultimaker Cloud") color: UM.Theme.getColor("primary_button") font: UM.Theme.getFont("huge") renderType: Text.NativeRendering @@ -46,7 +46,7 @@ Item anchors { top: titleLabel.bottom - bottom: finishButton.top + bottom: nextButton.top left: parent.left right: parent.right topMargin: UM.Theme.getSize("default_margin").height @@ -74,7 +74,7 @@ Item id: highlightTextLabel anchors.horizontalCenter: parent.horizontalCenter horizontalAlignment: Text.AlignHCenter - text: catalog.i18nc("@text", "Your key to connected 3D printing") + text: catalog.i18nc("@text", "The next generation 3D printing workflow") textFormat: Text.RichText color: UM.Theme.getColor("primary") font: UM.Theme.getFont("medium") @@ -91,13 +91,13 @@ Item var full_text = "" var t = "" - t = catalog.i18nc("@text", "- Customize your experience with more print profiles and plugins") + t = catalog.i18nc("@text", "- Send print jobs to Ultimaker printers outside of your local network") full_text += "

" + t + "

" - t = catalog.i18nc("@text", "- Stay flexible by syncing your setup and loading it anywhere") + t = catalog.i18nc("@text", "- Store your Ultimaker Cura settings in the cloud to use anywhere") full_text += "

" + t + "

" - t = catalog.i18nc("@text", "- Increase efficiency with a remote workflow on Ultimaker printers") + t = catalog.i18nc("@text", "- Get exclusive access to material profiles from leading brands") full_text += "

" + t + "

" return full_text @@ -107,35 +107,47 @@ Item color: UM.Theme.getColor("text") renderType: Text.NativeRendering } + + // "Sign in" and "Create an account" exist inside the column + Cura.PrimaryButton + { + id: signInButton + height: createAccountButton.height + width: createAccountButton.width + anchors.horizontalCenter: parent.horizontalCenter + text: catalog.i18nc("@button", "Sign in") + onClicked: Cura.API.account.login() + // Content Item is used in order to align the text inside the button. Without it, when resizing the + // button, the text will be aligned on the left + contentItem: Text { + text: signInButton.text + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("primary_text") + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + Cura.SecondaryButton + { + id: createAccountButton + anchors.horizontalCenter: parent.horizontalCenter + text: catalog.i18nc("@button","Create an account") + onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create") + } } + + } - // Bottom buttons go here - Cura.PrimaryButton - { - id: finishButton - anchors.right: parent.right - anchors.bottom: parent.bottom - text: catalog.i18nc("@button", "Finish") - onClicked: base.showNextPage() - } - - Cura.SecondaryButton - { - id: createAccountButton - anchors.left: parent.left - anchors.verticalCenter: finishButton.verticalCenter - text: catalog.i18nc("@button", "Create an account") - onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create") - } - + // The "Next" button exists on the bottom right Label { - id: signInButton - anchors.left: createAccountButton.right - anchors.verticalCenter: finishButton.verticalCenter + id: nextButton + anchors.right: parent.right + anchors.bottom: parent.bottom anchors.leftMargin: UM.Theme.getSize("default_margin").width - text: catalog.i18nc("@button", "Sign in") + text: catalog.i18nc("@button", "Skip") color: UM.Theme.getColor("secondary_button_text") font: UM.Theme.getFont("medium") renderType: Text.NativeRendering @@ -144,7 +156,7 @@ Item { anchors.fill: parent hoverEnabled: true - onClicked: Cura.API.account.login() + onClicked: base.showNextPage() onEntered: parent.font.underline = true onExited: parent.font.underline = false } From ca2962aa123e554622396fe77a5c831ddfc701b5 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Tue, 21 Apr 2020 09:46:22 +0200 Subject: [PATCH 4/9] Revert text to the correct one CURA-7019 --- resources/qml/WelcomePages/CloudContent.qml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/qml/WelcomePages/CloudContent.qml b/resources/qml/WelcomePages/CloudContent.qml index 9f262c50ed..f0eadea9ff 100644 --- a/resources/qml/WelcomePages/CloudContent.qml +++ b/resources/qml/WelcomePages/CloudContent.qml @@ -33,7 +33,7 @@ Item anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter horizontalAlignment: Text.AlignHCenter - text: catalog.i18nc("@label", "Sign in to Ultimaker Cloud") + text: catalog.i18nc("@label", "Ultimaker Account") color: UM.Theme.getColor("primary_button") font: UM.Theme.getFont("huge") renderType: Text.NativeRendering @@ -74,7 +74,7 @@ Item id: highlightTextLabel anchors.horizontalCenter: parent.horizontalCenter horizontalAlignment: Text.AlignHCenter - text: catalog.i18nc("@text", "The next generation 3D printing workflow") + text: catalog.i18nc("@text", "Your key to connected 3D printing") textFormat: Text.RichText color: UM.Theme.getColor("primary") font: UM.Theme.getFont("medium") @@ -91,13 +91,13 @@ Item var full_text = "" var t = "" - t = catalog.i18nc("@text", "- Send print jobs to Ultimaker printers outside of your local network") + t = catalog.i18nc("@text", "- Customize your experience with more print profiles and plugins") full_text += "

" + t + "

" - t = catalog.i18nc("@text", "- Store your Ultimaker Cura settings in the cloud to use anywhere") + t = catalog.i18nc("@text", "- Stay flexible by syncing your setup and loading it anywhere") full_text += "

" + t + "

" - t = catalog.i18nc("@text", "- Get exclusive access to material profiles from leading brands") + t = catalog.i18nc("@text", "- Increase efficiency with a remote workflow on Ultimaker printers") full_text += "

" + t + "

" return full_text @@ -132,7 +132,7 @@ Item { id: createAccountButton anchors.horizontalCenter: parent.horizontalCenter - text: catalog.i18nc("@button","Create an account") + text: catalog.i18nc("@button","Create account") onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create") } } From b4909e88ef6f06b2766a26619a82225353f26f81 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Tue, 21 Apr 2020 10:34:54 +0200 Subject: [PATCH 5/9] Rename "Next" button to "Skip" CURA-7019 --- resources/qml/WelcomePages/CloudContent.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/WelcomePages/CloudContent.qml b/resources/qml/WelcomePages/CloudContent.qml index f0eadea9ff..cc24fdd7b4 100644 --- a/resources/qml/WelcomePages/CloudContent.qml +++ b/resources/qml/WelcomePages/CloudContent.qml @@ -46,7 +46,7 @@ Item anchors { top: titleLabel.bottom - bottom: nextButton.top + bottom: skipButton.top left: parent.left right: parent.right topMargin: UM.Theme.getSize("default_margin").height @@ -140,10 +140,10 @@ Item } - // The "Next" button exists on the bottom right + // The "Skip" button exists on the bottom right Label { - id: nextButton + id: skipButton anchors.right: parent.right anchors.bottom: parent.bottom anchors.leftMargin: UM.Theme.getSize("default_margin").width From 1b1c00699876ce6d96359be4595bc98ac722152c Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Tue, 21 Apr 2020 11:23:42 +0200 Subject: [PATCH 6/9] Skip the Cloud page if the user is logged in If the user goes through the welcome wizard, arrives at the login page, logs in and then closes Cura, he/she will be logged in the next time. In this case, he/she will go through the welcome page again but will not see the sign in page at all. CURA-7019 --- cura/UI/WelcomePagesModel.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cura/UI/WelcomePagesModel.py b/cura/UI/WelcomePagesModel.py index 429e8b2665..611e62cfd6 100644 --- a/cura/UI/WelcomePagesModel.py +++ b/cura/UI/WelcomePagesModel.py @@ -245,6 +245,7 @@ class WelcomePagesModel(ListModel): }, {"id": "cloud", "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"), + "should_show_function": self.shouldShowCloudPage, }, {"id": "add_network_or_local_printer", "page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"), @@ -286,6 +287,17 @@ class WelcomePagesModel(ListModel): first_start_actions = self._application.getMachineActionManager().getFirstStartActions(definition_id) return len([action for action in first_start_actions if action.needsUserInteraction()]) > 0 + def shouldShowCloudPage(self) -> bool: + """ + The cloud page should be shown only if the user is not logged in + + :return: True if the user is not logged in, False if he/she is + """ + # Import CuraApplication locally or else it fails + from cura.CuraApplication import CuraApplication + api = CuraApplication.getInstance().getCuraAPI() + return not api.account.isLoggedIn + def addPage(self) -> None: pass From 3d26b6886fef2bfdf485cf5e6676728f0f30c8a3 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Wed, 22 Apr 2020 18:22:42 +0200 Subject: [PATCH 7/9] Fix the welcome dialog not closing when cloud printers detected The welcome dialog was not closing because when pressing the "Sign up" button in the cloud page, a signal is emitted that is forcing the welcome wizard to move to the next page. Therefore the currentPageIdx was detected as cloud_page_idx+1. This commit fixes the check by checking whether the welcome dialog is in the page after the Cloud page. CURA-7019 --- .../src/Cloud/CloudOutputDeviceManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index c5c583dcf7..60ec98acc0 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -104,9 +104,9 @@ class CloudOutputDeviceManager: # found, the welcome screen will close. This way we avoid prompting the user to add printers if he/she already # has cloud printers welcome_pages_model = CuraApplication.getInstance().getWelcomePagesModel() - cloud_page_idx = welcome_pages_model.getPageIndexById("cloud") - if welcome_pages_model.currentPageIndex == cloud_page_idx and online_clusters: - CuraApplication.getWelcomePagesModel().atEnd() + cloud_page_idx = welcome_pages_model.getPageIndexById("cloud") + 1 + if welcome_pages_model.currentPageIndex == cloud_page_idx and len(online_clusters) > 0: + welcome_pages_model.atEnd() for device_id, cluster_data in online_clusters.items(): if device_id not in self._remote_clusters: new_clusters.append(cluster_data) From 1262d1f641d02e26b424869b129f789bc5a62ac9 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Wed, 22 Apr 2020 18:31:04 +0200 Subject: [PATCH 8/9] Activate the first available Cloud printer if the activeMachine is empty CURA-7019 --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 60ec98acc0..d4355b2637 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -180,7 +180,10 @@ class CloudOutputDeviceManager: message.setProgress((idx / len(new_devices)) * 100) CuraApplication.getInstance().processEvents() self._remote_clusters[device.getId()] = device - self._createMachineFromDiscoveredDevice(device.getId(), activate = False) + + # If there is no active machine, activate the first available cloud printer + activate = not CuraApplication.getInstance().getMachineManager().activeMachine + self._createMachineFromDiscoveredDevice(device.getId(), activate = activate) message.setProgress(None) From 1602b71841723fb7c69b24447821a6e5b056080e Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Thu, 23 Apr 2020 09:59:32 +0200 Subject: [PATCH 9/9] Inform the Cloud page about new cloud printers Properly close the welcome screen if the user has signed in and has cloud printers linked to his/her account. If he doesn't have any, move to the next page of the welcome wizard. CURA-7019 --- cura/API/Account.py | 6 ++++++ .../src/Cloud/CloudOutputDeviceManager.py | 11 ++++------- resources/qml/WelcomePages/CloudContent.qml | 14 +++++++++----- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/cura/API/Account.py b/cura/API/Account.py index 4391f730e5..9864de1aaa 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -29,10 +29,12 @@ class Account(QObject): # Signal emitted when user logged in or out. loginStateChanged = pyqtSignal(bool) accessTokenChanged = pyqtSignal() + cloudPrintersDetectedChanged = pyqtSignal(bool) def __init__(self, application: "CuraApplication", parent = None) -> None: super().__init__(parent) self._application = application + self._new_cloud_printers_detected = False self._error_message = None # type: Optional[Message] self._logged_in = False @@ -74,6 +76,10 @@ class Account(QObject): def isLoggedIn(self) -> bool: return self._logged_in + @pyqtProperty(bool, notify=cloudPrintersDetectedChanged) + def newCloudPrintersDetected(self) -> bool: + return self._new_cloud_printers_detected + def _onLoginStateChanged(self, logged_in: bool = False, error_message: Optional[str] = None) -> None: if error_message: if self._error_message: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index d4355b2637..210f4ad13a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -100,13 +100,6 @@ class CloudOutputDeviceManager: new_clusters = [] online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudClusterResponse] - # If the user signs in from the welcome dialog, then we will search for cloud printers and if any of them are - # found, the welcome screen will close. This way we avoid prompting the user to add printers if he/she already - # has cloud printers - welcome_pages_model = CuraApplication.getInstance().getWelcomePagesModel() - cloud_page_idx = welcome_pages_model.getPageIndexById("cloud") + 1 - if welcome_pages_model.currentPageIndex == cloud_page_idx and len(online_clusters) > 0: - welcome_pages_model.atEnd() for device_id, cluster_data in online_clusters.items(): if device_id not in self._remote_clusters: new_clusters.append(cluster_data) @@ -115,6 +108,10 @@ class CloudOutputDeviceManager: self._onDevicesDiscovered(new_clusters) + # Inform whether new cloud printers have been detected. If they have, the welcome wizard can close. + self._account._new_cloud_printers_detected = len(new_clusters) > 0 + self._account.cloudPrintersDetectedChanged.emit(len(new_clusters) > 0) + removed_device_keys = set(self._remote_clusters.keys()) - set(online_clusters.keys()) for device_id in removed_device_keys: self._onDiscoveredDeviceRemoved(device_id) diff --git a/resources/qml/WelcomePages/CloudContent.qml b/resources/qml/WelcomePages/CloudContent.qml index cc24fdd7b4..a14c6600cd 100644 --- a/resources/qml/WelcomePages/CloudContent.qml +++ b/resources/qml/WelcomePages/CloudContent.qml @@ -15,14 +15,18 @@ Item { UM.I18nCatalog { id: catalog; name: "cura" } - property bool isLoggedIn: Cura.API.account.isLoggedIn + property bool newCloudPrintersDetected: Cura.API.account.newCloudPrintersDetected - onIsLoggedInChanged: + onNewCloudPrintersDetectedChanged: { - if(isLoggedIn) + // When the user signs in successfully, it will be checked whether he/she has cloud printers connected to + // the account. If he/she does, then the welcome wizard can close. If not, then proceed to the next page (if any) + if(newCloudPrintersDetected) + { + base.endWizard() + } + else { - // If the user created an account or logged in by pressing any button on this page, all the actions that - // need / can be done by this page are completed, so we can just go to the next (if any). base.showNextPage() } }