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/cura/UI/WelcomePagesModel.py b/cura/UI/WelcomePagesModel.py index c16ec3763e..611e62cfd6 100644 --- a/cura/UI/WelcomePagesModel.py +++ b/cura/UI/WelcomePagesModel.py @@ -243,6 +243,10 @@ class WelcomePagesModel(ListModel): {"id": "data_collections", "page_url": self._getBuiltinWelcomePagePath("DataCollectionsContent.qml"), }, + {"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"), "next_page_id": "machine_actions", @@ -253,12 +257,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 @@ -287,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 diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 1eebc46d64..65625df3bc 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -99,12 +99,17 @@ class CloudOutputDeviceManager: new_clusters = [] online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudClusterResponse] + for device_id, cluster_data in online_clusters.items(): if device_id not in self._remote_clusters: new_clusters.append(cluster_data) 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) @@ -176,7 +181,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) diff --git a/resources/qml/WelcomePages/CloudContent.qml b/resources/qml/WelcomePages/CloudContent.qml index b127dbfb3c..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() } } @@ -46,7 +50,7 @@ Item anchors { top: titleLabel.bottom - bottom: finishButton.top + bottom: skipButton.top left: parent.left right: parent.right topMargin: UM.Theme.getSize("default_margin").height @@ -107,35 +111,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 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 "Skip" button exists on the bottom right Label { - id: signInButton - anchors.left: createAccountButton.right - anchors.verticalCenter: finishButton.verticalCenter + id: skipButton + 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 +160,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 }