Merge pull request #7904 from Ultimaker/CURA-7454_Add_remove_printers_button_in_removed_printers_from_account_message

CURA-7454: Add "remove printers" button in removed printers from account message
This commit is contained in:
Nino van Hooff 2020-06-12 17:35:09 +02:00 committed by GitHub
commit e5a7ad2eca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 100 additions and 27 deletions

View file

@ -207,6 +207,7 @@ class CuraApplication(QtApplication):
self._first_start_machine_actions_model = None self._first_start_machine_actions_model = None
self._welcome_pages_model = WelcomePagesModel(self, parent = self) self._welcome_pages_model = WelcomePagesModel(self, parent = self)
self._add_printer_pages_model = AddPrinterPagesModel(self, parent = self) self._add_printer_pages_model = AddPrinterPagesModel(self, parent = self)
self._add_printer_pages_model_without_cancel = AddPrinterPagesModel(self, parent = self)
self._whats_new_pages_model = WhatsNewPagesModel(self, parent = self) self._whats_new_pages_model = WhatsNewPagesModel(self, parent = self)
self._text_manager = TextManager(parent = self) self._text_manager = TextManager(parent = self)
@ -647,7 +648,7 @@ class CuraApplication(QtApplication):
return self._global_container_stack return self._global_container_stack
@override(Application) @override(Application)
def setGlobalContainerStack(self, stack: "GlobalStack") -> None: def setGlobalContainerStack(self, stack: Optional["GlobalStack"]) -> None:
self._setLoadingHint(self._i18n_catalog.i18nc("@info:progress", "Initializing Active Machine...")) self._setLoadingHint(self._i18n_catalog.i18nc("@info:progress", "Initializing Active Machine..."))
super().setGlobalContainerStack(stack) super().setGlobalContainerStack(stack)
@ -812,6 +813,7 @@ class CuraApplication(QtApplication):
self._output_device_manager.start() self._output_device_manager.start()
self._welcome_pages_model.initialize() self._welcome_pages_model.initialize()
self._add_printer_pages_model.initialize() self._add_printer_pages_model.initialize()
self._add_printer_pages_model_without_cancel.initialize(cancellable = False)
self._whats_new_pages_model.initialize() self._whats_new_pages_model.initialize()
# Detect in which mode to run and execute that mode # Detect in which mode to run and execute that mode
@ -849,6 +851,7 @@ class CuraApplication(QtApplication):
self.callLater(self._openFile, file_name) self.callLater(self._openFile, file_name)
initializationFinished = pyqtSignal() initializationFinished = pyqtSignal()
showAddPrintersUncancellableDialog = pyqtSignal() # Used to show the add printers dialog with a greyed background
def runWithoutGUI(self): def runWithoutGUI(self):
"""Run Cura without GUI elements and interaction (server mode).""" """Run Cura without GUI elements and interaction (server mode)."""
@ -939,6 +942,10 @@ class CuraApplication(QtApplication):
def getAddPrinterPagesModel(self, *args) -> "AddPrinterPagesModel": def getAddPrinterPagesModel(self, *args) -> "AddPrinterPagesModel":
return self._add_printer_pages_model return self._add_printer_pages_model
@pyqtSlot(result = QObject)
def getAddPrinterPagesModelWithoutCancel(self, *args) -> "AddPrinterPagesModel":
return self._add_printer_pages_model_without_cancel
@pyqtSlot(result = QObject) @pyqtSlot(result = QObject)
def getWhatsNewPagesModel(self, *args) -> "WhatsNewPagesModel": def getWhatsNewPagesModel(self, *args) -> "WhatsNewPagesModel":
return self._whats_new_pages_model return self._whats_new_pages_model

View file

@ -154,7 +154,7 @@ class BaseMaterialsModel(ListModel):
# Update the available materials (ContainerNode) for the current active machine and extruder setup. # Update the available materials (ContainerNode) for the current active machine and extruder setup.
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack() global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
if not global_stack.hasMaterials: if not global_stack or not global_stack.hasMaterials:
return # There are no materials for this machine, so nothing to do. return # There are no materials for this machine, so nothing to do.
extruder_list = global_stack.extruderList extruder_list = global_stack.extruderList
if self._extruder_position > len(extruder_list): if self._extruder_position > len(extruder_list):

View file

@ -290,9 +290,15 @@ class MachineManager(QObject):
self.activeStackValueChanged.emit() self.activeStackValueChanged.emit()
@pyqtSlot(str) @pyqtSlot(str)
def setActiveMachine(self, stack_id: str) -> None: def setActiveMachine(self, stack_id: Optional[str]) -> None:
self.blurSettings.emit() # Ensure no-one has focus. self.blurSettings.emit() # Ensure no-one has focus.
if not stack_id:
self._application.setGlobalContainerStack(None)
self.globalContainerChanged.emit()
self._application.showAddPrintersUncancellableDialog.emit()
return
container_registry = CuraContainerRegistry.getInstance() container_registry = CuraContainerRegistry.getInstance()
containers = container_registry.findContainerStacks(id = stack_id) containers = container_registry.findContainerStacks(id = stack_id)
if not containers: if not containers:
@ -721,6 +727,8 @@ class MachineManager(QObject):
other_machine_stacks = [s for s in machine_stacks if s["id"] != machine_id] other_machine_stacks = [s for s in machine_stacks if s["id"] != machine_id]
if other_machine_stacks: if other_machine_stacks:
self.setActiveMachine(other_machine_stacks[0]["id"]) self.setActiveMachine(other_machine_stacks[0]["id"])
else:
self.setActiveMachine(None)
metadatas = CuraContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id) metadatas = CuraContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id)
if not metadatas: if not metadatas:

View file

@ -10,12 +10,11 @@ from .WelcomePagesModel import WelcomePagesModel
# #
class AddPrinterPagesModel(WelcomePagesModel): class AddPrinterPagesModel(WelcomePagesModel):
def initialize(self) -> None: def initialize(self, cancellable: bool = True) -> None:
self._pages.append({"id": "add_network_or_local_printer", self._pages.append({"id": "add_network_or_local_printer",
"page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"), "page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
"next_page_id": "machine_actions", "next_page_id": "machine_actions",
"next_page_button_text": self._catalog.i18nc("@action:button", "Add"), "next_page_button_text": self._catalog.i18nc("@action:button", "Add"),
"previous_page_button_text": self._catalog.i18nc("@action:button", "Cancel"),
}) })
self._pages.append({"id": "add_printer_by_ip", self._pages.append({"id": "add_printer_by_ip",
"page_url": self._getBuiltinWelcomePagePath("AddPrinterByIpContent.qml"), "page_url": self._getBuiltinWelcomePagePath("AddPrinterByIpContent.qml"),
@ -30,6 +29,9 @@ class AddPrinterPagesModel(WelcomePagesModel):
"page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"), "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
"should_show_function": self.shouldShowMachineActions, "should_show_function": self.shouldShowMachineActions,
}) })
if cancellable:
self._pages[0]["previous_page_button_text"] = self._catalog.i18nc("@action:button", "Cancel")
self.setItems(self._pages) self.setItems(self._pages)

View file

@ -4,6 +4,7 @@ import os
from typing import Dict, List, Optional, Set from typing import Dict, List, Optional, Set
from PyQt5.QtNetwork import QNetworkReply from PyQt5.QtNetwork import QNetworkReply
from PyQt5.QtWidgets import QMessageBox
from UM import i18nCatalog from UM import i18nCatalog
from UM.Logger import Logger # To log errors talking to the API. from UM.Logger import Logger # To log errors talking to the API.
@ -50,6 +51,7 @@ class CloudOutputDeviceManager:
self._account = CuraApplication.getInstance().getCuraAPI().account # type: Account self._account = CuraApplication.getInstance().getCuraAPI().account # type: Account
self._api = CloudApiClient(CuraApplication.getInstance(), on_error = lambda error: Logger.log("e", str(error))) self._api = CloudApiClient(CuraApplication.getInstance(), on_error = lambda error: Logger.log("e", str(error)))
self._account.loginStateChanged.connect(self._onLoginStateChanged) self._account.loginStateChanged.connect(self._onLoginStateChanged)
self._removed_printers_message = None # type: Optional[Message]
# Ensure we don't start twice. # Ensure we don't start twice.
self._running = False self._running = False
@ -120,6 +122,11 @@ class CloudOutputDeviceManager:
self._um_cloud_printers[device_id].setMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, True) self._um_cloud_printers[device_id].setMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, True)
self._onDevicesDiscovered(new_clusters) self._onDevicesDiscovered(new_clusters)
# Hide the current removed_printers_message, if there is any
if self._removed_printers_message:
self._removed_printers_message.actionTriggered.disconnect(self._onRemovedPrintersMessageActionTriggered)
self._removed_printers_message.hide()
# Remove the CloudOutput device for offline printers # Remove the CloudOutput device for offline printers
offline_device_keys = set(self._remote_clusters.keys()) - set(online_clusters.keys()) offline_device_keys = set(self._remote_clusters.keys()) - set(online_clusters.keys())
for device_id in offline_device_keys: for device_id in offline_device_keys:
@ -269,14 +276,13 @@ class CloudOutputDeviceManager:
return return
# Generate message # Generate message
removed_printers_message = Message( self._removed_printers_message = Message(
title = self.I18N_CATALOG.i18ncp( title = self.I18N_CATALOG.i18ncp(
"info:status", "info:status",
"Cloud connection is not available for a printer", "Cloud connection is not available for a printer",
"Cloud connection is not available for some printers", "Cloud connection is not available for some printers",
len(self.reported_device_ids) len(self.reported_device_ids)
), )
lifetime = 0
) )
device_names = "\n".join(["<li>{} ({})</li>".format(self._um_cloud_printers[device].name, self._um_cloud_printers[device].definition.name) for device in self.reported_device_ids]) device_names = "\n".join(["<li>{} ({})</li>".format(self._um_cloud_printers[device].name, self._um_cloud_printers[device].definition.name) for device in self.reported_device_ids])
message_text = self.I18N_CATALOG.i18ncp( message_text = self.I18N_CATALOG.i18ncp(
@ -291,13 +297,19 @@ class CloudOutputDeviceManager:
"<a href='https://mycloud.ultimaker.com/'>Ultimaker Digital Factory</a>.", "<a href='https://mycloud.ultimaker.com/'>Ultimaker Digital Factory</a>.",
device_names device_names
) )
removed_printers_message.setText(message_text) self._removed_printers_message.setText(message_text)
removed_printers_message.addAction("keep_printer_configurations_action", self._removed_printers_message.addAction("keep_printer_configurations_action",
name = self.I18N_CATALOG.i18nc("@action:button", "Keep printer configurations"), name = self.I18N_CATALOG.i18nc("@action:button", "Keep printer configurations"),
icon = "", icon = "",
description = "Keep the configuration of the cloud printer(s) synced with Cura which are not linked to your account.", description = "Keep the configuration of the cloud printer(s) synced with Cura which are not linked to your account.",
button_align = Message.ActionButtonAlignment.ALIGN_RIGHT) button_align = Message.ActionButtonAlignment.ALIGN_RIGHT)
removed_printers_message.actionTriggered.connect(self._onRemovedPrintersMessageActionTriggered) self._removed_printers_message.addAction("remove_printers_action",
name = self.I18N_CATALOG.i18nc("@action:button", "Remove printers"),
icon = "",
description = "Remove the cloud printer(s) which are not linked to your account.",
button_style = Message.ActionButtonStyle.SECONDARY,
button_align = Message.ActionButtonAlignment.ALIGN_LEFT)
self._removed_printers_message.actionTriggered.connect(self._onRemovedPrintersMessageActionTriggered)
output_device_manager = CuraApplication.getInstance().getOutputDeviceManager() output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
@ -314,7 +326,7 @@ class CloudOutputDeviceManager:
# Update the printer's metadata to mark it as not linked to the account # Update the printer's metadata to mark it as not linked to the account
device.setMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, False) device.setMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, False)
removed_printers_message.show() self._removed_printers_message.show()
def _onDiscoveredDeviceRemoved(self, device_id: str) -> None: def _onDiscoveredDeviceRemoved(self, device_id: str) -> None:
device = self._remote_clusters.pop(device_id, None) # type: Optional[CloudOutputDevice] device = self._remote_clusters.pop(device_id, None) # type: Optional[CloudOutputDevice]
@ -402,7 +414,23 @@ class CloudOutputDeviceManager:
if container_cluster_id in self._remote_clusters.keys(): if container_cluster_id in self._remote_clusters.keys():
del self._remote_clusters[container_cluster_id] del self._remote_clusters[container_cluster_id]
@staticmethod def _onRemovedPrintersMessageActionTriggered(self, removed_printers_message: Message, action: str) -> None:
def _onRemovedPrintersMessageActionTriggered(removed_printers_message: Message, action: str) -> None:
if action == "keep_printer_configurations_action": if action == "keep_printer_configurations_action":
removed_printers_message.hide() removed_printers_message.hide()
elif action == "remove_printers_action":
machine_manager = CuraApplication.getInstance().getMachineManager()
remove_printers_ids = {self._um_cloud_printers[i].getId() for i in self.reported_device_ids}
all_ids = {m.getId() for m in CuraApplication.getInstance().getContainerRegistry().findContainerStacks(type = "machine")}
question_title = self.I18N_CATALOG.i18nc("@title:window", "Remove printers?")
question_content = self.I18N_CATALOG.i18nc("@label", "You are about to remove {} printer(s) from Cura. This action cannot be undone. \nAre you sure you want to continue?".format(len(remove_printers_ids)))
if remove_printers_ids == all_ids:
question_content = self.I18N_CATALOG.i18nc("@label", "You are about to remove all printers from Cura. This action cannot be undone. \nAre you sure you want to continue?")
result = QMessageBox.question(None, question_title, question_content)
if result == QMessageBox.No:
return
for machine_cloud_id in self.reported_device_ids:
machine_manager.setActiveMachine(self._um_cloud_printers[machine_cloud_id].getId())
machine_manager.removeMachine(self._um_cloud_printers[machine_cloud_id].getId())
removed_printers_message.hide()

View file

@ -84,6 +84,21 @@ UM.MainWindow
CuraApplication.purgeWindows() CuraApplication.purgeWindows()
} }
Connections
{
// This connection is used when there is no ActiveMachine and the user is logged in
target: CuraApplication
onShowAddPrintersUncancellableDialog:
{
Cura.Actions.parent = backgroundItem
// Reuse the welcome dialog item to show "Add a printer" only.
welcomeDialogItem.model = CuraApplication.getAddPrinterPagesModelWithoutCancel()
welcomeDialogItem.progressBarVisible = false
welcomeDialogItem.visible = true
}
}
Connections Connections
{ {
target: CuraApplication target: CuraApplication
@ -117,6 +132,15 @@ UM.MainWindow
welcomeDialogItem.progressBarVisible = false welcomeDialogItem.progressBarVisible = false
welcomeDialogItem.visible = true welcomeDialogItem.visible = true
} }
// Reuse the welcome dialog item to show the "Add printers" dialog. Triggered when there is no active
// machine and the user is logged in.
if (!Cura.MachineManager.activeMachine && Cura.API.account.isLoggedIn)
{
welcomeDialogItem.model = CuraApplication.getAddPrinterPagesModelWithoutCancel()
welcomeDialogItem.progressBarVisible = false
welcomeDialogItem.visible = true
}
} }
} }

View file

@ -143,7 +143,7 @@ UM.Dialog
{ {
width: parent.width width: parent.width
height: childrenRect.height height: childrenRect.height
model: Cura.MachineManager.activeMachine.extruderList model: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.extruderList : null
delegate: Column delegate: Column
{ {
height: childrenRect.height height: childrenRect.height

View file

@ -33,7 +33,7 @@ Cura.ExpandablePopup
} }
contentPadding: UM.Theme.getSize("default_lining").width contentPadding: UM.Theme.getSize("default_lining").width
enabled: Cura.MachineManager.activeMachine.hasMaterials || Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates; //Only let it drop down if there is any configuration that you could change. enabled: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials || Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates : false; //Only let it drop down if there is any configuration that you could change.
headerItem: Item headerItem: Item
{ {
@ -84,7 +84,7 @@ Cura.ExpandablePopup
{ {
id: variantLabel id: variantLabel
visible: Cura.MachineManager.activeMachine.hasVariants visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasVariants : false
text: model.variant text: model.variant
elide: Text.ElideRight elide: Text.ElideRight
@ -114,7 +114,7 @@ Cura.ExpandablePopup
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")
renderType: Text.NativeRendering renderType: Text.NativeRendering
visible: !Cura.MachineManager.activeMachine.hasMaterials && (Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates) visible: Cura.MachineManager.activeMachine ? !Cura.MachineManager.activeMachine.hasMaterials && (Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates) : false
anchors anchors
{ {

View file

@ -244,7 +244,7 @@ Item
Row Row
{ {
height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0 height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0
visible: Cura.MachineManager.activeMachine.hasMaterials visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials : false
Label Label
{ {
@ -305,7 +305,7 @@ Item
Row Row
{ {
height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0 height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0
visible: Cura.MachineManager.activeMachine.hasVariants visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasVariants : false
Label Label
{ {

View file

@ -130,7 +130,11 @@ Item
target: extruderModel target: extruderModel
onModelChanged: onModelChanged:
{ {
supportExtruderCombobox.color = supportExtruderCombobox.model.getItem(supportExtruderCombobox.currentIndex).color var maybeColor = supportExtruderCombobox.model.getItem(supportExtruderCombobox.currentIndex).color
if (maybeColor)
{
supportExtruderCombobox.color = maybeColor
}
} }
} }
onCurrentIndexChanged: onCurrentIndexChanged:

View file

@ -28,11 +28,11 @@ ListView
delegate: MachineSelectorButton delegate: MachineSelectorButton
{ {
text: model.name text: model.name ? model.name : ""
width: listView.width width: listView.width
outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
checked: Cura.MachineManager.activeMachine.id == model.id checked: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.id == model.id : false
onClicked: onClicked:
{ {