From 6eb502730c0530f7f7e8905d07272a54338c2a14 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 6 Jul 2016 16:30:34 +0200 Subject: [PATCH 1/7] Add reusable messagebox based on QML MessageDialog Contributes to CURA-1730 and CURA-1850 --- cura/CuraApplication.py | 16 ++++++++++++++++ resources/qml/Cura.qml | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index e34a537953..feaa700d48 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -47,6 +47,7 @@ import cura.Settings from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS from PyQt5.QtGui import QColor, QIcon +from PyQt5.QtWidgets import QMessageBox from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType import platform @@ -155,6 +156,8 @@ class CuraApplication(QtApplication): self._cura_actions = None self._started = False + self._message_box_callback = None + self._i18n_catalog = i18nCatalog("cura") self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity) @@ -251,6 +254,19 @@ class CuraApplication(QtApplication): def _onEngineCreated(self): self._engine.addImageProvider("camera", CameraImageProvider.CameraImageProvider()) + ## A reusable dialogbox + # + showMessageBox = pyqtSignal(str, str, str, str, int, int, arguments = ["title", "text", "informativeText", "detailedText", "buttons", "icon"]) + def messageBox(self, title, text, informativeText = "", detailedText = "", buttons = QMessageBox.Ok, icon = QMessageBox.NoIcon, callback = None): + self._message_box_callback = callback + self.showMessageBox.emit(title, text, informativeText, detailedText, buttons, icon) + + @pyqtSlot(int) + def messageBoxClosed(self, button): + if self._message_box_callback: + self._message_box_callback(button) + self._message_box_callback = None + showPrintMonitor = pyqtSignal(bool, arguments = ["show"]) ## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently. diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index e805991df4..f70dffa3cc 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -683,6 +683,35 @@ UM.MainWindow } } + MessageDialog + { + id: messageDialog + modality: Qt.ApplicationModal + onAccepted: Printer.messageBoxClosed(clickedButton) + onApply: Printer.messageBoxClosed(clickedButton) + onDiscard: Printer.messageBoxClosed(clickedButton) + onHelp: Printer.messageBoxClosed(clickedButton) + onNo: Printer.messageBoxClosed(clickedButton) + onRejected: Printer.messageBoxClosed(clickedButton) + onReset: Printer.messageBoxClosed(clickedButton) + onYes: Printer.messageBoxClosed(clickedButton) + } + + Connections + { + target: Printer + onShowMessageBox: + { + messageDialog.title = title + messageDialog.text = text + messageDialog.informativeText = informativeText + messageDialog.detailedText = detailedText + messageDialog.standardButtons = buttons + messageDialog.icon = icon + messageDialog.visible = true + } + } + Connections { target: Cura.Actions.addMachine From 4a9de156cb7ef5fb73c1aec48dcc50043e3f97e2 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 6 Jul 2016 16:31:27 +0200 Subject: [PATCH 2/7] Ask the user about keeping current settings when switching quality profiles CURA-1730 --- cura/Settings/MachineManager.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c217c7087a..773d65a7db 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -2,6 +2,7 @@ # Cura is released under the terms of the AGPLv3 or higher. from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal +from PyQt5.QtWidgets import QMessageBox from UM.Application import Application from UM.Preferences import Preferences @@ -461,10 +462,31 @@ class MachineManager(QObject): return old_quality = self._active_container_stack.findContainer({"type": "quality"}) - if old_quality: + if old_quality and old_quality != containers[0]: quality_index = self._active_container_stack.getContainerIndex(old_quality) + self._active_container_stack.replaceContainer(quality_index, containers[0]) + if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: + # Ask the user if the user profile should be cleared or not (discarding the current settings) + # In Simple Mode we assume the user always wants to keep the (limited) current settings + details = catalog.i18nc("@label", "You made changes to the following setting(s):") + user_settings = self._active_container_stack.getTop().findInstances(**{}) + for setting in user_settings: + details = details + "\n " + setting.definition.label + + Application.getInstance().messageBox(catalog.i18nc("@window:title", "Switched profiles"), catalog.i18nc("@label", "Do you want to transfer your changed settings to this profile?"), + catalog.i18nc("@label", "If you transfer your settings they will override settings in the profile."), details, + buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._keepUserSettingsDialogCallback) + + def _keepUserSettingsDialogCallback(self, button): + if button == QMessageBox.Yes: + # Yes, keep the settings in the user profile with this profile + pass + elif button == QMessageBox.No: + # No, discard the settings in the user profile + self.clearUserSettings() + @pyqtProperty(str, notify = activeVariantChanged) def activeVariantName(self): if self._active_container_stack: From 475277069f8facc8641b688feb52292d82fe4501 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 7 Jul 2016 08:14:49 +0200 Subject: [PATCH 3/7] Add optional arguments to reusable messagebox Contributes to CURA-1850 --- cura/CuraApplication.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index feaa700d48..0d31155590 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -157,6 +157,7 @@ class CuraApplication(QtApplication): self._started = False self._message_box_callback = None + self._message_box_callback_arguments = [] self._i18n_catalog = i18nCatalog("cura") @@ -257,15 +258,17 @@ class CuraApplication(QtApplication): ## A reusable dialogbox # showMessageBox = pyqtSignal(str, str, str, str, int, int, arguments = ["title", "text", "informativeText", "detailedText", "buttons", "icon"]) - def messageBox(self, title, text, informativeText = "", detailedText = "", buttons = QMessageBox.Ok, icon = QMessageBox.NoIcon, callback = None): + def messageBox(self, title, text, informativeText = "", detailedText = "", buttons = QMessageBox.Ok, icon = QMessageBox.NoIcon, callback = None, callback_arguments = []): self._message_box_callback = callback + self._message_box_callback_arguments = callback_arguments self.showMessageBox.emit(title, text, informativeText, detailedText, buttons, icon) @pyqtSlot(int) def messageBoxClosed(self, button): if self._message_box_callback: - self._message_box_callback(button) + self._message_box_callback(button, *self._message_box_callback_arguments) self._message_box_callback = None + self._message_box_callback_arguments = [] showPrintMonitor = pyqtSignal(bool, arguments = ["show"]) From c129b4b8b5e94f7f9f8aca1b1a926ec460d42edb Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 7 Jul 2016 08:16:02 +0200 Subject: [PATCH 4/7] Let the user opt out of changing to the material/nozzle reported by the printer CURA-1850 --- cura/Settings/MachineManager.py | 66 +++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 773d65a7db..15b5265850 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -98,12 +98,38 @@ class MachineManager(QObject): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = self._global_container_stack.getBottom().getId(), name = hotend_id) if containers: - Logger.log("d", "Setting hotend variant of hotend %d to %s" % (index, containers[0].getId())) - ExtruderManager.ExtruderManager.getInstance().setActiveExtruderIndex(index) - self.setActiveVariant(containers[0].getId()) + old_index = extruder_manager.activeExtruderIndex + if old_index != index: + extruder_manager.setActiveExtruderIndex(index) + else: + old_index = None + + if self.activeVariantId != containers[0].getId(): + Application.getInstance().messageBox(catalog.i18nc("@window:title", "Changes on the Printer"), catalog.i18nc("@label", "Do you want to change the hotend to match the hotend in your printer?"), + catalog.i18nc("@label", "The hotend on your printer was changed. For best results always slice for the hotend that is inserted in your printer."), + buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._hotendChangedDialogCallback, callback_arguments = [index, containers[0].getId()]) + if old_index is not None: + extruder_manager.setActiveExtruderIndex(old_index) + + else: + Logger.log("w", "No variant found for printer definition %s with id %s" % (definition_id, variant_id)) + + def _hotendChangedDialogCallback(self, button, index, hotend_id): + Logger.log("d", "Setting hotend variant of hotend %d to %s" % (index, containers[0].getId())) + + extruder_manager = ExtruderManager.ExtruderManager.getInstance() + old_index = extruder_manager.activeExtruderIndex + if old_index != index: + extruder_manager.setActiveExtruderIndex(index) + else: + old_index = None + + self.setActiveVariant(containers[0].getId()) + + if old_index is not None: + extruder_manager.setActiveExtruderIndex(old_index) def _onMaterialIdChanged(self, index, material_id): - # TODO: fix this if not self._global_container_stack: return @@ -113,12 +139,38 @@ class MachineManager(QObject): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition_id, GUID = material_id) if containers: - Logger.log("d", "Setting material of hotend %d to %s" % (index, containers[0].getId())) - ExtruderManager.ExtruderManager.getInstance().setActiveExtruderIndex(index) - self.setActiveMaterial(containers[0].getId()) + extruder_manager = ExtruderManager.ExtruderManager.getInstance() + old_index = extruder_manager.activeExtruderIndex + if old_index != index: + extruder_manager.setActiveExtruderIndex(index) + else: + old_index = None + + if self.activeMaterialId != containers[0].getId(): + Application.getInstance().messageBox(catalog.i18nc("@window:title", "Changes on the Printer"), catalog.i18nc("@label", "Do you want to change the material to match the material in your printer?"), + catalog.i18nc("@label", "The material on your printer was changed. For best results always slice for the material that is inserted in your printer."), + buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._materialIdChangedDialogCallback, callback_arguments = [index, containers[0].getId()]) + if old_index is not None: + extruder_manager.setActiveExtruderIndex(old_index) + else: Logger.log("w", "No material definition found for printer definition %s and GUID %s" % (definition_id, material_id)) + def _materialIdChangedDialogCallback(self, button, index, material_id): + Logger.log("d", "Setting material of hotend %d to %s" % (index, material_id)) + + extruder_manager = ExtruderManager.ExtruderManager.getInstance() + old_index = extruder_manager.activeExtruderIndex + if old_index != index: + extruder_manager.setActiveExtruderIndex(index) + else: + old_index = None + + self.setActiveMaterial(material_id) + + if old_index is not None: + extruder_manager.setActiveExtruderIndex(old_index) + def _onGlobalPropertyChanged(self, key, property_name): if property_name == "value": From bf529c642572e1965216f2ca707fd6242ffeec36 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 7 Jul 2016 11:46:07 +0200 Subject: [PATCH 5/7] Apply a flood control on messages about materials/hotends changed on the printer CURA-1850 --- cura/Settings/MachineManager.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 15b5265850..1c8734c80d 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -17,6 +17,8 @@ from . import ExtruderManager from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") +import time + class MachineManager(QObject): def __init__(self, parent = None): super().__init__(parent) @@ -60,6 +62,10 @@ class MachineManager(QObject): self.setActiveMachine(active_machine_id) pass + self._auto_change_material_hotend_flood_window = 10 + self._auto_change_material_hotend_flood_time = 0 + self._auto_change_material_hotend_flood_last_choice = None + globalContainerChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() activeVariantChanged = pyqtSignal() @@ -98,6 +104,7 @@ class MachineManager(QObject): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = self._global_container_stack.getBottom().getId(), name = hotend_id) if containers: + extruder_manager = ExtruderManager.ExtruderManager.getInstance() old_index = extruder_manager.activeExtruderIndex if old_index != index: extruder_manager.setActiveExtruderIndex(index) @@ -105,9 +112,12 @@ class MachineManager(QObject): old_index = None if self.activeVariantId != containers[0].getId(): - Application.getInstance().messageBox(catalog.i18nc("@window:title", "Changes on the Printer"), catalog.i18nc("@label", "Do you want to change the hotend to match the hotend in your printer?"), - catalog.i18nc("@label", "The hotend on your printer was changed. For best results always slice for the hotend that is inserted in your printer."), - buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._hotendChangedDialogCallback, callback_arguments = [index, containers[0].getId()]) + if time.time() - self._auto_change_material_hotend_flood_time > self._auto_change_material_hotend_flood_window: + Application.getInstance().messageBox(catalog.i18nc("@window:title", "Changes on the Printer"), catalog.i18nc("@label", "Do you want to change the hotend to match the hotend in your printer?"), + catalog.i18nc("@label", "The hotend on your printer was changed. For best results always slice for the hotend that is inserted in your printer."), + buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._hotendChangedDialogCallback, callback_arguments = [index, containers[0].getId()]) + else: + self._hotendChangedDialogCallback(self._auto_change_material_hotend_flood_last_choice, index, containers[0].getId()) if old_index is not None: extruder_manager.setActiveExtruderIndex(old_index) @@ -115,6 +125,9 @@ class MachineManager(QObject): Logger.log("w", "No variant found for printer definition %s with id %s" % (definition_id, variant_id)) def _hotendChangedDialogCallback(self, button, index, hotend_id): + self._auto_change_material_hotend_flood_time = time.time() + self._auto_change_material_hotend_flood_last_choice = button + Logger.log("d", "Setting hotend variant of hotend %d to %s" % (index, containers[0].getId())) extruder_manager = ExtruderManager.ExtruderManager.getInstance() @@ -147,9 +160,12 @@ class MachineManager(QObject): old_index = None if self.activeMaterialId != containers[0].getId(): - Application.getInstance().messageBox(catalog.i18nc("@window:title", "Changes on the Printer"), catalog.i18nc("@label", "Do you want to change the material to match the material in your printer?"), - catalog.i18nc("@label", "The material on your printer was changed. For best results always slice for the material that is inserted in your printer."), - buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._materialIdChangedDialogCallback, callback_arguments = [index, containers[0].getId()]) + if time.time() - self._auto_change_material_hotend_flood_time > self._auto_change_material_hotend_flood_window: + Application.getInstance().messageBox(catalog.i18nc("@window:title", "Changes on the Printer"), catalog.i18nc("@label", "Do you want to change the material to match the material in your printer?"), + catalog.i18nc("@label", "The material on your printer was changed. For best results always slice for the material that is inserted in your printer."), + buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._materialIdChangedDialogCallback, callback_arguments = [index, containers[0].getId()]) + else: + self._materialIdChangedDialogCallback(self._auto_change_material_hotend_flood_last_choice, index, containers[0].getId()) if old_index is not None: extruder_manager.setActiveExtruderIndex(old_index) @@ -157,6 +173,9 @@ class MachineManager(QObject): Logger.log("w", "No material definition found for printer definition %s and GUID %s" % (definition_id, material_id)) def _materialIdChangedDialogCallback(self, button, index, material_id): + self._auto_change_material_hotend_flood_time = time.time() + self._auto_change_material_hotend_flood_last_choice = button + Logger.log("d", "Setting material of hotend %d to %s" % (index, material_id)) extruder_manager = ExtruderManager.ExtruderManager.getInstance() From fc74b538771514fb0525031b110a88ca04c7fc28 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 8 Jul 2016 11:44:20 +0200 Subject: [PATCH 6/7] Add documentation CURA-1850 --- cura/Settings/MachineManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 1c8734c80d..c55baab055 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -62,9 +62,9 @@ class MachineManager(QObject): self.setActiveMachine(active_machine_id) pass - self._auto_change_material_hotend_flood_window = 10 - self._auto_change_material_hotend_flood_time = 0 - self._auto_change_material_hotend_flood_last_choice = None + self._auto_change_material_hotend_flood_window = 10 # The minimum number of seconds between asking if the material or hotend on the machine should be used + self._auto_change_material_hotend_flood_time = 0 # The last timestamp (in seconds) when the user was asked about changing the material or hotend to whatis loaded on the machine + self._auto_change_material_hotend_flood_last_choice = None # The last choice that was made, so we can apply that choice again globalContainerChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() From 27d47b5c9c5301e8db5569025634f57933b8a3bf Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 8 Jul 2016 13:22:40 +0200 Subject: [PATCH 7/7] Fixes some issues due to merge --- cura/Settings/MachineManager.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c55baab055..e0158f2ac4 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -104,7 +104,7 @@ class MachineManager(QObject): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = self._global_container_stack.getBottom().getId(), name = hotend_id) if containers: - extruder_manager = ExtruderManager.ExtruderManager.getInstance() + extruder_manager = ExtruderManager.getInstance() old_index = extruder_manager.activeExtruderIndex if old_index != index: extruder_manager.setActiveExtruderIndex(index) @@ -122,22 +122,22 @@ class MachineManager(QObject): extruder_manager.setActiveExtruderIndex(old_index) else: - Logger.log("w", "No variant found for printer definition %s with id %s" % (definition_id, variant_id)) + Logger.log("w", "No variant found for printer definition %s with id %s" % (self._global_container_stack.getBottom().getId(), hotend_id)) def _hotendChangedDialogCallback(self, button, index, hotend_id): self._auto_change_material_hotend_flood_time = time.time() self._auto_change_material_hotend_flood_last_choice = button - Logger.log("d", "Setting hotend variant of hotend %d to %s" % (index, containers[0].getId())) + Logger.log("d", "Setting hotend variant of hotend %d to %s" % (index, hotend_id)) - extruder_manager = ExtruderManager.ExtruderManager.getInstance() + extruder_manager = ExtruderManager.getInstance() old_index = extruder_manager.activeExtruderIndex if old_index != index: extruder_manager.setActiveExtruderIndex(index) else: old_index = None - self.setActiveVariant(containers[0].getId()) + self.setActiveVariant(hotend_id) if old_index is not None: extruder_manager.setActiveExtruderIndex(old_index) @@ -152,7 +152,7 @@ class MachineManager(QObject): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition_id, GUID = material_id) if containers: - extruder_manager = ExtruderManager.ExtruderManager.getInstance() + extruder_manager = ExtruderManager.getInstance() old_index = extruder_manager.activeExtruderIndex if old_index != index: extruder_manager.setActiveExtruderIndex(index) @@ -178,7 +178,7 @@ class MachineManager(QObject): Logger.log("d", "Setting material of hotend %d to %s" % (index, material_id)) - extruder_manager = ExtruderManager.ExtruderManager.getInstance() + extruder_manager = ExtruderManager.getInstance() old_index = extruder_manager.activeExtruderIndex if old_index != index: extruder_manager.setActiveExtruderIndex(index) @@ -513,7 +513,6 @@ class MachineManager(QObject): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = variant_id) if not containers or not self._active_container_stack: return - old_variant = self._active_container_stack.findContainer({"type": "variant"}) old_material = self._active_container_stack.findContainer({"type": "material"}) if old_variant: @@ -523,7 +522,6 @@ class MachineManager(QObject): preferred_material = None if old_material: preferred_material_name = old_material.getName() - self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), containers[0], preferred_material_name).id) @pyqtSlot(str)