From 675c5064ed965f1f90d8b20f24737a1c186d3296 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 5 Jul 2018 11:47:06 +0200 Subject: [PATCH 01/11] Added checkPackageUsageAndUninstall and the package usage check. No confirmation dialog yet --- cura/CuraPackageManager.py | 23 +++++++++++++++++++ cura/Machines/QualityManager.py | 7 ++++++ cura/Settings/MachineManager.py | 15 ++++++++++-- .../qml/ToolboxInstalledTileActions.qml | 2 +- plugins/Toolbox/src/Toolbox.py | 23 +++++++++++++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index f65633ed66..0dfac6b84f 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -2,8 +2,12 @@ # Cura is released under the terms of the LGPLv3 or higher. from cura.CuraApplication import CuraApplication #To find some resource types. +from cura.Settings.GlobalStack import GlobalStack + +from UM.Logger import Logger from UM.PackageManager import PackageManager #The class we're extending. from UM.Resources import Resources #To find storage paths for some resource types. +from UM.Settings.ContainerRegistry import ContainerRegistry class CuraPackageManager(PackageManager): @@ -15,3 +19,22 @@ class CuraPackageManager(PackageManager): self._installation_dirs_dict["qualities"] = Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer) super().initialize() + + ## Returns a list of where the package is used + # empty if it is never used. + # It loops through all the package contents and see if some of the ids are used. + def packageUsed(self, package_id: str): + ids = self.packageContainerIds(package_id) + container_stacks = ContainerRegistry.getInstance().findContainerStacks() + global_stacks = [container_stack for container_stack in container_stacks if isinstance(container_stack, GlobalStack)] + machine_with_materials = [] + machine_with_qualities = [] + for container_id in ids: + for global_stack in global_stacks: + for extruder_nr, extruder_stack in global_stack.extruders.items(): + if container_id == extruder_stack.material.getId() or container_id == extruder_stack.material.getMetaData().get("base_file"): + machine_with_materials.append((global_stack, extruder_nr)) + if container_id == extruder_stack.quality.getId(): + machine_with_qualities.append((global_stack, extruder_nr)) + + return machine_with_materials, machine_with_qualities diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 8033057f77..d5d9c0e727 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -340,6 +340,13 @@ class QualityManager(QObject): return quality_group_dict + def getDefaultQualityType(self, machine: "GlobalStack") -> QualityGroup: + preferred_quality_type = machine.definition.getMetaDataEntry("preferred_quality_type") + quality_group_dict = self.getQualityGroups(machine) + quality_group = quality_group_dict.get(preferred_quality_type) + return quality_group + + # # Methods for GUI # diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 065dc84df1..10d32b0a70 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1392,8 +1392,13 @@ class MachineManager(QObject): material_node = self._material_manager.getMaterialNode(machine_definition_id, variant_name, material_diameter, root_material_id) self.setMaterial(position, material_node) + ## global_stack: if you want to provide your own global_stack instead of the current active one + # if you update an active machine, special measures have to be taken. @pyqtSlot(str, "QVariant") - def setMaterial(self, position: str, container_node) -> None: + def setMaterial(self, position: str, container_node, global_stack: Optional["GlobalStack"] = None) -> None: + if global_stack is not None and global_stack != self._global_container_stack: + global_stack.extruders[position].material = container_node.getContainer() + return position = str(position) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): @@ -1434,8 +1439,14 @@ class MachineManager(QObject): quality_group = quality_group_dict[quality_type] self.setQualityGroup(quality_group) + ## Optionally provide global_stack if you want to use your own + # The active global_stack is treated differently. @pyqtSlot(QObject) - def setQualityGroup(self, quality_group: QualityGroup, no_dialog: bool = False) -> None: + def setQualityGroup(self, quality_group: QualityGroup, no_dialog: bool = False, global_stack: Optional["GlobalStack"] = None) -> None: + if global_stack is not None and global_stack != self._global_container_stack: + global_stack.quality = quality_group.node_for_global.getContainer() + return + self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setQualityGroup(quality_group) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml index b0aecfc9a2..8fd88b1cfd 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml @@ -83,7 +83,7 @@ Column font: UM.Theme.getFont("default") } } - onClicked: toolbox.uninstall(model.id) + onClicked: toolbox.checkPackageUsageAndUninstall(model.id) Connections { target: toolbox diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 0d0060e48c..3e0749d612 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -294,6 +294,29 @@ class Toolbox(QObject, Extension): self._restart_required = True self.restartRequiredChanged.emit() + ## Check package usage and uninstall + # If the package is in use, you'll get a confirmation dialog to set everything to default + @pyqtSlot(str) + def checkPackageUsageAndUninstall(self, plugin_id: str) -> None: + print("checkPackageUsageAndUninstall...") + package_used_materials, package_used_qualities = self._package_manager.packageUsed(plugin_id) + if package_used_materials or package_used_qualities: + # Ask change to default material / profile + # Cancel: just return + # Confirm: change to default material / profile + material_manager = CuraApplication.getInstance().getMaterialManager() + quality_manager = CuraApplication.getInstance().getQualityManager() + machine_manager = CuraApplication.getInstance().getMachineManager() + for global_stack, extruder_nr in package_used_materials: + default_material_node = material_manager.getDefaultMaterial(global_stack, extruder_nr, global_stack.extruders[extruder_nr].variant.getName()) + machine_manager.setMaterial(extruder_nr, default_material_node, global_stack = global_stack) + for global_stack, extruder_nr in package_used_qualities: + default_quality_group = quality_manager.getDefaultQualityType(global_stack) + machine_manager.setQualityGroup(default_quality_group, global_stack = global_stack) + # Change to default material / profile + self.uninstall(plugin_id) + return + @pyqtSlot(str) def uninstall(self, plugin_id: str) -> None: self._package_manager.removePackage(plugin_id, force_add = True) From 5af5aa9e3550163937d56bc2b9d5f314b73097fe Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 9 Jul 2018 09:57:31 +0200 Subject: [PATCH 02/11] Added reset profiles/materials and uninstall functionality and dialog. CURA-5389 --- cura/CuraPackageManager.py | 5 +- cura/Settings/MachineManager.py | 2 + .../ToolboxConfirmUninstallResetDialog.qml | 91 +++++++++++++++++++ plugins/Toolbox/src/Toolbox.py | 74 +++++++++++---- 4 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 0dfac6b84f..2a4f62e5fe 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -23,6 +23,7 @@ class CuraPackageManager(PackageManager): ## Returns a list of where the package is used # empty if it is never used. # It loops through all the package contents and see if some of the ids are used. + # The list consists of 3-tuples: (global_stack, extruder_nr, container_id) def packageUsed(self, package_id: str): ids = self.packageContainerIds(package_id) container_stacks = ContainerRegistry.getInstance().findContainerStacks() @@ -33,8 +34,8 @@ class CuraPackageManager(PackageManager): for global_stack in global_stacks: for extruder_nr, extruder_stack in global_stack.extruders.items(): if container_id == extruder_stack.material.getId() or container_id == extruder_stack.material.getMetaData().get("base_file"): - machine_with_materials.append((global_stack, extruder_nr)) + machine_with_materials.append((global_stack, extruder_nr, container_id)) if container_id == extruder_stack.quality.getId(): - machine_with_qualities.append((global_stack, extruder_nr)) + machine_with_qualities.append((global_stack, extruder_nr, container_id)) return machine_with_materials, machine_with_qualities diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 10d32b0a70..4f6c7c179e 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1445,6 +1445,8 @@ class MachineManager(QObject): def setQualityGroup(self, quality_group: QualityGroup, no_dialog: bool = False, global_stack: Optional["GlobalStack"] = None) -> None: if global_stack is not None and global_stack != self._global_container_stack: global_stack.quality = quality_group.node_for_global.getContainer() + for extruder_nr, extruder_stack in global_stack.extruders.items(): + extruder_stack.quality = quality_group.nodes_for_extruders[extruder_nr].getContainer() return self.blurSettings.emit() diff --git a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml new file mode 100644 index 0000000000..487e2db894 --- /dev/null +++ b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml @@ -0,0 +1,91 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.1 + +import UM 1.3 as UM +import Cura 1.0 as Cura + + +UM.Dialog +{ + // This dialog asks the user whether he/she wants to open a project file as a project or import models. + id: base + + title: catalog.i18nc("@title:window", "Confirm uninstall ") + toolbox.pluginToUninstall + width: 450 * screenScaleFactor + height: 250 * screenScaleFactor + + maximumHeight: height + maximumWidth: width + minimumHeight: maximumHeight + minimumWidth: maximumWidth + + modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal + + Column + { + UM.I18nCatalog { id: catalog; name: "cura" } + + anchors.fill: parent + anchors.leftMargin: 20 * screenScaleFactor + anchors.rightMargin: 20 * screenScaleFactor + anchors.bottomMargin: 10 * screenScaleFactor + spacing: 10 * screenScaleFactor + + Label + { + id: dialogText + text: + { + var base_text = catalog.i18nc("@text:window", "You are uninstalling materials and/or profiles that are still in use. Confirming will reset the following materials/profiles to their defaults.") + var materials_text = catalog.i18nc("@text:window", "Materials") + var qualities_text = catalog.i18nc("@text:window", "Profiles") + var machines_with_materials = toolbox.uninstallUsedMaterials + var machines_with_qualities = toolbox.uninstallUsedQualities + if (machines_with_materials != "") + { + base_text += "\n\n" + materials_text +": \n" + machines_with_materials + } + if (machines_with_qualities != "") + { + base_text += "\n\n" + qualities_text + ": \n" + machines_with_qualities + } + return base_text + } + anchors.left: parent.left + anchors.right: parent.right + font: UM.Theme.getFont("default") + wrapMode: Text.WordWrap + } + + // Buttons + Item { + id: buttonBar + anchors.right: parent.right + anchors.left: parent.left + height: childrenRect.height + + Button { + id: cancelButton + text: catalog.i18nc("@action:button", "Cancel") + anchors.right: confirmButton.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + isDefault: true + onClicked: toolbox.closeConfirmResetDialog() + } + + Button { + id: confirmButton + text: catalog.i18nc("@action:button", "Confirm") + anchors.right: parent.right + onClicked: toolbox.resetMaterialsQualitiesAndUninstall() + } + } + } +} diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 3e0749d612..ad9481f892 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -102,6 +102,9 @@ class Toolbox(QObject, Extension): self._active_package = None # type: Optional[Dict[str, Any]] self._dialog = None #type: Optional[QObject] + self._confirm_reset_dialog = None #type: Optional[QObject] + self._resetUninstallVariables() + self._restart_required = False #type: bool # variables for the license agreement dialog @@ -130,6 +133,13 @@ class Toolbox(QObject, Extension): filterChanged = pyqtSignal() metadataChanged = pyqtSignal() showLicenseDialog = pyqtSignal() + uninstallVariablesChanged = pyqtSignal() + + def _resetUninstallVariables(self): + self._package_id_to_uninstall = None + self._package_name_to_uninstall = "" + self._package_used_materials = [] + self._package_used_qualities = [] @pyqtSlot(result = str) def getLicenseDialogPluginName(self) -> str: @@ -235,7 +245,6 @@ class Toolbox(QObject, Extension): dialog = self._application.createQmlComponent(path, {"toolbox": self}) return dialog - def _convertPluginMetadata(self, plugin: Dict[str, Any]) -> Dict[str, Any]: formatted = { "package_id": plugin["id"], @@ -298,24 +307,57 @@ class Toolbox(QObject, Extension): # If the package is in use, you'll get a confirmation dialog to set everything to default @pyqtSlot(str) def checkPackageUsageAndUninstall(self, plugin_id: str) -> None: - print("checkPackageUsageAndUninstall...") package_used_materials, package_used_qualities = self._package_manager.packageUsed(plugin_id) if package_used_materials or package_used_qualities: + # Set up "uninstall variables" for resetMaterialsQualitiesAndUninstall + self._package_id_to_uninstall = plugin_id + package_info = self._package_manager.getInstalledPackageInfo(plugin_id) + self._package_name_to_uninstall = package_info.get("display_name", package_info.get("package_id")) + self._package_used_materials = package_used_materials + self._package_used_qualities = package_used_qualities # Ask change to default material / profile - # Cancel: just return - # Confirm: change to default material / profile - material_manager = CuraApplication.getInstance().getMaterialManager() - quality_manager = CuraApplication.getInstance().getQualityManager() - machine_manager = CuraApplication.getInstance().getMachineManager() - for global_stack, extruder_nr in package_used_materials: - default_material_node = material_manager.getDefaultMaterial(global_stack, extruder_nr, global_stack.extruders[extruder_nr].variant.getName()) - machine_manager.setMaterial(extruder_nr, default_material_node, global_stack = global_stack) - for global_stack, extruder_nr in package_used_qualities: - default_quality_group = quality_manager.getDefaultQualityType(global_stack) - machine_manager.setQualityGroup(default_quality_group, global_stack = global_stack) - # Change to default material / profile - self.uninstall(plugin_id) - return + if self._confirm_reset_dialog is None: + self._confirm_reset_dialog = self._createDialog("ToolboxConfirmUninstallResetDialog.qml") + self.uninstallVariablesChanged.emit() + self._confirm_reset_dialog.show() + else: + # Plain uninstall + self.uninstall(plugin_id) + + @pyqtProperty(str, notify = uninstallVariablesChanged) + def pluginToUninstall(self): + return self._package_name_to_uninstall + + @pyqtProperty(str, notify = uninstallVariablesChanged) + def uninstallUsedMaterials(self): + return "\n".join(["%s (%s)" % (str(global_stack.getName()), material) for global_stack, extruder_nr, material in self._package_used_materials]) + + @pyqtProperty(str, notify = uninstallVariablesChanged) + def uninstallUsedQualities(self): + return "\n".join(["%s (%s)" % (str(global_stack.getName()), quality) for global_stack, extruder_nr, quality in self._package_used_qualities]) + + @pyqtSlot() + def closeConfirmResetDialog(self): + if self._confirm_reset_dialog is not None: + self._confirm_reset_dialog.close() + + ## Uses "uninstall variables" to reset qualities and materials, then uninstall + # It's used as an action on Confirm reset on Uninstall + @pyqtSlot() + def resetMaterialsQualitiesAndUninstall(self): + application = CuraApplication.getInstance() + material_manager = application.getMaterialManager() + quality_manager = application.getQualityManager() + machine_manager = application.getMachineManager() + for global_stack, extruder_nr, _ in self._package_used_materials: + default_material_node = material_manager.getDefaultMaterial(global_stack, extruder_nr, global_stack.extruders[extruder_nr].variant.getName()) + machine_manager.setMaterial(extruder_nr, default_material_node, global_stack = global_stack) + for global_stack, extruder_nr, _ in self._package_used_qualities: + default_quality_group = quality_manager.getDefaultQualityType(global_stack) + machine_manager.setQualityGroup(default_quality_group, global_stack = global_stack) + self.uninstall(self._package_id_to_uninstall) + self._resetUninstallVariables() + self.closeConfirmResetDialog() @pyqtSlot(str) def uninstall(self, plugin_id: str) -> None: From 111a3556d2ee9ff7f347be70dc7bfff785b3f277 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 9 Jul 2018 11:42:30 +0200 Subject: [PATCH 03/11] Fixed possible errors and typing error. CURA-5389 --- cura/Machines/QualityManager.py | 2 +- cura/Settings/MachineManager.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index d5d9c0e727..5e78c04900 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -340,7 +340,7 @@ class QualityManager(QObject): return quality_group_dict - def getDefaultQualityType(self, machine: "GlobalStack") -> QualityGroup: + def getDefaultQualityType(self, machine: "GlobalStack") -> Optional[QualityGroup]: preferred_quality_type = machine.definition.getMetaDataEntry("preferred_quality_type") quality_group_dict = self.getQualityGroups(machine) quality_group = quality_group_dict.get(preferred_quality_type) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 4f6c7c179e..772c01191c 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1444,6 +1444,12 @@ class MachineManager(QObject): @pyqtSlot(QObject) def setQualityGroup(self, quality_group: QualityGroup, no_dialog: bool = False, global_stack: Optional["GlobalStack"] = None) -> None: if global_stack is not None and global_stack != self._global_container_stack: + if quality_group is None: + Logger.log("e", "Could not set quality group because quality group is None") + return + if quality_group.node_for_global is None: + Logger.log("e", "Could not set quality group [%s] because it has no node_for_global", str(quality_group)) + return global_stack.quality = quality_group.node_for_global.getContainer() for extruder_nr, extruder_stack in global_stack.extruders.items(): extruder_stack.quality = quality_group.nodes_for_extruders[extruder_nr].getContainer() From aa0c7d5f0ae52828c7d1680b5d37a7a62a1cb064 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 9 Jul 2018 13:26:11 +0200 Subject: [PATCH 04/11] Confirm uninstall reset dialog now has proper sizing. CURA-5389 --- .../ToolboxConfirmUninstallResetDialog.qml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml index 487e2db894..a9d10eca2e 100644 --- a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml @@ -19,12 +19,12 @@ UM.Dialog title: catalog.i18nc("@title:window", "Confirm uninstall ") + toolbox.pluginToUninstall width: 450 * screenScaleFactor - height: 250 * screenScaleFactor + height: (30 + dialogText.height) * screenScaleFactor - maximumHeight: height - maximumWidth: width - minimumHeight: maximumHeight - minimumWidth: maximumWidth + maximumWidth: 450 * screenScaleFactor + maximumHeight: 450 * screenScaleFactor + minimumWidth: 450 * screenScaleFactor + minimumHeight: 150 * screenScaleFactor modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal @@ -33,10 +33,11 @@ UM.Dialog UM.I18nCatalog { id: catalog; name: "cura" } anchors.fill: parent - anchors.leftMargin: 20 * screenScaleFactor - anchors.rightMargin: 20 * screenScaleFactor - anchors.bottomMargin: 10 * screenScaleFactor - spacing: 10 * screenScaleFactor + anchors.leftMargin: Math.round(20 * screenScaleFactor) + anchors.rightMargin: Math.round(20 * screenScaleFactor) + anchors.topMargin: Math.round(10 * screenScaleFactor) + anchors.bottomMargin: Math.round(10 * screenScaleFactor) + spacing: Math.round(15 * screenScaleFactor) Label { From 513bd4f84ae7620bcb521c47f84be64d59c5c8a5 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 9 Jul 2018 14:36:38 +0200 Subject: [PATCH 05/11] Renamed packageContainerIds to getPackageContainerIds. CURA-5389 --- cura/CuraPackageManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 2a4f62e5fe..ff93c2b010 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -25,7 +25,7 @@ class CuraPackageManager(PackageManager): # It loops through all the package contents and see if some of the ids are used. # The list consists of 3-tuples: (global_stack, extruder_nr, container_id) def packageUsed(self, package_id: str): - ids = self.packageContainerIds(package_id) + ids = self.getPackageContainerIds(package_id) container_stacks = ContainerRegistry.getInstance().findContainerStacks() global_stacks = [container_stack for container_stack in container_stacks if isinstance(container_stack, GlobalStack)] machine_with_materials = [] From cc5f35dd9181d6a951deeb2e2b007314df3705e3 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 10 Jul 2018 14:57:01 +0200 Subject: [PATCH 06/11] Rename some functions and variables --- cura/CuraPackageManager.py | 3 +-- plugins/Toolbox/src/Toolbox.py | 14 +++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index ff93c2b010..95b381989f 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -4,7 +4,6 @@ from cura.CuraApplication import CuraApplication #To find some resource types. from cura.Settings.GlobalStack import GlobalStack -from UM.Logger import Logger from UM.PackageManager import PackageManager #The class we're extending. from UM.Resources import Resources #To find storage paths for some resource types. from UM.Settings.ContainerRegistry import ContainerRegistry @@ -24,7 +23,7 @@ class CuraPackageManager(PackageManager): # empty if it is never used. # It loops through all the package contents and see if some of the ids are used. # The list consists of 3-tuples: (global_stack, extruder_nr, container_id) - def packageUsed(self, package_id: str): + def getMachinesUsingPackage(self, package_id: str): ids = self.getPackageContainerIds(package_id) container_stacks = ContainerRegistry.getInstance().findContainerStacks() global_stacks = [container_stack for container_stack in container_stacks if isinstance(container_stack, GlobalStack)] diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 90d135c289..4e59fcd055 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -314,12 +314,12 @@ class Toolbox(QObject, Extension): ## Check package usage and uninstall # If the package is in use, you'll get a confirmation dialog to set everything to default @pyqtSlot(str) - def checkPackageUsageAndUninstall(self, plugin_id: str) -> None: - package_used_materials, package_used_qualities = self._package_manager.packageUsed(plugin_id) + def checkPackageUsageAndUninstall(self, package_id: str) -> None: + package_used_materials, package_used_qualities = self._package_manager.getMachinesUsingPackage(package_id) if package_used_materials or package_used_qualities: # Set up "uninstall variables" for resetMaterialsQualitiesAndUninstall - self._package_id_to_uninstall = plugin_id - package_info = self._package_manager.getInstalledPackageInfo(plugin_id) + self._package_id_to_uninstall = package_id + package_info = self._package_manager.getInstalledPackageInfo(package_id) self._package_name_to_uninstall = package_info.get("display_name", package_info.get("package_id")) self._package_used_materials = package_used_materials self._package_used_qualities = package_used_qualities @@ -330,7 +330,7 @@ class Toolbox(QObject, Extension): self._confirm_reset_dialog.show() else: # Plain uninstall - self.uninstall(plugin_id) + self.uninstall(package_id) @pyqtProperty(str, notify = uninstallVariablesChanged) def pluginToUninstall(self): @@ -368,8 +368,8 @@ class Toolbox(QObject, Extension): self.closeConfirmResetDialog() @pyqtSlot(str) - def uninstall(self, plugin_id: str) -> None: - self._package_manager.removePackage(plugin_id, force_add = True) + def uninstall(self, package_id: str) -> None: + self._package_manager.removePackage(package_id, force_add = True) self.installChanged.emit() self._updateInstalledModels() self.metadataChanged.emit() From 3a1d57a7251d3a80a713fe474f639a09c3d96d72 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 10 Jul 2018 15:32:39 +0200 Subject: [PATCH 07/11] Increase dialog height --- .../resources/qml/ToolboxConfirmUninstallResetDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml index a9d10eca2e..cefbe5218f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml @@ -19,7 +19,7 @@ UM.Dialog title: catalog.i18nc("@title:window", "Confirm uninstall ") + toolbox.pluginToUninstall width: 450 * screenScaleFactor - height: (30 + dialogText.height) * screenScaleFactor + height: (100 + dialogText.height) * screenScaleFactor maximumWidth: 450 * screenScaleFactor maximumHeight: 450 * screenScaleFactor From 5255d6ca2a162a6637fdeaef89e798a16d380968 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 10 Jul 2018 16:11:56 +0200 Subject: [PATCH 08/11] Better height for dialog --- .../resources/qml/ToolboxConfirmUninstallResetDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml index cefbe5218f..83ace5f80b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml @@ -19,7 +19,7 @@ UM.Dialog title: catalog.i18nc("@title:window", "Confirm uninstall ") + toolbox.pluginToUninstall width: 450 * screenScaleFactor - height: (100 + dialogText.height) * screenScaleFactor + height: 50 * screenScaleFactor + dialogText.height + buttonBar.height maximumWidth: 450 * screenScaleFactor maximumHeight: 450 * screenScaleFactor From 76417b7fb2069cca39f774c7fbf47c7120afa480 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 11 Jul 2018 10:57:55 +0200 Subject: [PATCH 09/11] Hide materials belong to a to-be-removed package --- cura/CuraPackageManager.py | 5 ++-- cura/Machines/MaterialGroup.py | 13 ++++++---- cura/Machines/Models/BrandMaterialsModel.py | 4 +++ cura/Machines/Models/GenericMaterialsModel.py | 5 ++++ plugins/Toolbox/src/Toolbox.py | 26 +++++++++++++++++-- .../XmlMaterialProfile/XmlMaterialProfile.py | 3 +++ 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 95b381989f..363b8034ec 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -6,7 +6,6 @@ from cura.Settings.GlobalStack import GlobalStack from UM.PackageManager import PackageManager #The class we're extending. from UM.Resources import Resources #To find storage paths for some resource types. -from UM.Settings.ContainerRegistry import ContainerRegistry class CuraPackageManager(PackageManager): @@ -25,14 +24,14 @@ class CuraPackageManager(PackageManager): # The list consists of 3-tuples: (global_stack, extruder_nr, container_id) def getMachinesUsingPackage(self, package_id: str): ids = self.getPackageContainerIds(package_id) - container_stacks = ContainerRegistry.getInstance().findContainerStacks() + container_stacks = self._application.getContainerRegistry().findContainerStacks() global_stacks = [container_stack for container_stack in container_stacks if isinstance(container_stack, GlobalStack)] machine_with_materials = [] machine_with_qualities = [] for container_id in ids: for global_stack in global_stacks: for extruder_nr, extruder_stack in global_stack.extruders.items(): - if container_id == extruder_stack.material.getId() or container_id == extruder_stack.material.getMetaData().get("base_file"): + if container_id in (extruder_stack.material.getId(), extruder_stack.material.getMetaData().get("base_file")): machine_with_materials.append((global_stack, extruder_nr, container_id)) if container_id == extruder_stack.quality.getId(): machine_with_qualities.append((global_stack, extruder_nr, container_id)) diff --git a/cura/Machines/MaterialGroup.py b/cura/Machines/MaterialGroup.py index b57e0e1808..e05647e674 100644 --- a/cura/Machines/MaterialGroup.py +++ b/cura/Machines/MaterialGroup.py @@ -1,8 +1,11 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import List -from cura.Machines.MaterialNode import MaterialNode #For type checking. +from typing import List, TYPE_CHECKING + +if TYPE_CHECKING: + from cura.Machines.MaterialNode import MaterialNode + ## A MaterialGroup represents a group of material InstanceContainers that are derived from a single material profile. # The main InstanceContainer which has the ID of the material profile file name is called the "root_material". For @@ -18,11 +21,11 @@ from cura.Machines.MaterialNode import MaterialNode #For type checking. class MaterialGroup: __slots__ = ("name", "is_read_only", "root_material_node", "derived_material_node_list") - def __init__(self, name: str, root_material_node: MaterialNode) -> None: + def __init__(self, name: str, root_material_node: "MaterialNode") -> None: self.name = name self.is_read_only = False - self.root_material_node = root_material_node # type: MaterialNode - self.derived_material_node_list = [] #type: List[MaterialNode] + self.root_material_node = root_material_node # type: MaterialNode + self.derived_material_node_list = [] # type: List[MaterialNode] def __str__(self) -> str: return "%s[%s]" % (self.__class__.__name__, self.name) diff --git a/cura/Machines/Models/BrandMaterialsModel.py b/cura/Machines/Models/BrandMaterialsModel.py index 236f105d12..ad48b3ea21 100644 --- a/cura/Machines/Models/BrandMaterialsModel.py +++ b/cura/Machines/Models/BrandMaterialsModel.py @@ -109,6 +109,10 @@ class BrandMaterialsModel(ListModel): if brand.lower() == "generic": continue + # Do not include the materials from a to-be-removed package + if bool(metadata.get("removed", False)): + continue + if brand not in brand_group_dict: brand_group_dict[brand] = {} diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py index 2fac919f3e..f14b039c91 100644 --- a/cura/Machines/Models/GenericMaterialsModel.py +++ b/cura/Machines/Models/GenericMaterialsModel.py @@ -41,10 +41,15 @@ class GenericMaterialsModel(BaseMaterialsModel): item_list = [] for root_material_id, container_node in available_material_dict.items(): metadata = container_node.metadata + # Only add results for generic materials if metadata["brand"].lower() != "generic": continue + # Do not include the materials from a to-be-removed package + if bool(metadata.get("removed", False)): + continue + item = {"root_material_id": root_material_id, "id": metadata["id"], "name": metadata["name"], diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 3fec67c96e..31b9dda9f4 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -360,16 +360,38 @@ class Toolbox(QObject, Extension): material_manager = application.getMaterialManager() quality_manager = application.getQualityManager() machine_manager = application.getMachineManager() - for global_stack, extruder_nr, _ in self._package_used_materials: + + for global_stack, extruder_nr, container_id in self._package_used_materials: default_material_node = material_manager.getDefaultMaterial(global_stack, extruder_nr, global_stack.extruders[extruder_nr].variant.getName()) machine_manager.setMaterial(extruder_nr, default_material_node, global_stack = global_stack) - for global_stack, extruder_nr, _ in self._package_used_qualities: + for global_stack, extruder_nr, container_id in self._package_used_qualities: default_quality_group = quality_manager.getDefaultQualityType(global_stack) machine_manager.setQualityGroup(default_quality_group, global_stack = global_stack) + + self._markPackageMaterialsAsRemove(self._package_id_to_uninstall) + self.uninstall(self._package_id_to_uninstall) self._resetUninstallVariables() self.closeConfirmResetDialog() + def _markPackageMaterialsAsRemove(self, package_id: str) -> None: + container_registry = self._application.getContainerRegistry() + + all_containers = self._package_manager.getPackageContainerIds(package_id) + for container_id in all_containers: + containers = container_registry.findInstanceContainers(id = container_id) + if not containers: + continue + container = containers[0] + if container.getMetaDataEntry("type") != "material": + continue + root_material_id = container.getMetaDataEntry("base_file") + root_material_containers = container_registry.findInstanceContainers(id = root_material_id) + if not root_material_containers: + continue + root_material_container = root_material_containers[0] + root_material_container.setMetaDataEntry("removed", True) + @pyqtSlot(str) def uninstall(self, package_id: str) -> None: self._package_manager.removePackage(package_id, force_add = True) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index eac6646197..ca6271391e 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -63,6 +63,7 @@ class XmlMaterialProfile(InstanceContainer): # Prevent recursion if not apply_to_all: + super().addMetaDataEntry(key, value) super().setMetaDataEntry(key, value) return @@ -74,12 +75,14 @@ class XmlMaterialProfile(InstanceContainer): # Update the root material container root_material_container = material_group.root_material_node.getContainer() if root_material_container is not None: + root_material_container.addMetaDataEntry(key, value) root_material_container.setMetaDataEntry(key, value, apply_to_all = False) # Update all containers derived from it for node in material_group.derived_material_node_list: container = node.getContainer() if container is not None: + container.addMetaDataEntry(key, value) container.setMetaDataEntry(key, value, apply_to_all = False) ## Overridden from InstanceContainer, similar to setMetaDataEntry. From af02dc2758b8eec1f3c3ccc2b96c5cb9bdc5276a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 11 Jul 2018 11:14:57 +0200 Subject: [PATCH 10/11] Only use setMetaDataEntry() --- cura/CuraApplication.py | 16 ++++---- cura/Machines/QualityManager.py | 8 ++-- cura/Settings/CuraContainerRegistry.py | 38 +++++++++---------- cura/Settings/CuraContainerStack.py | 2 +- cura/Settings/CuraStackBuilder.py | 12 +++--- cura/Settings/ExtruderStack.py | 8 ++-- cura/Settings/GlobalStack.py | 2 +- cura/Settings/MachineManager.py | 6 +-- cura/Settings/SettingOverrideDecorator.py | 2 +- plugins/3MFReader/ThreeMFWorkspaceReader.py | 2 +- .../CuraProfileReader/CuraProfileReader.py | 2 +- plugins/GCodeWriter/GCodeWriter.py | 10 ++--- .../LegacyProfileReader.py | 4 +- .../MachineSettingsAction.py | 5 +-- .../PostProcessingPlugin.py | 2 +- plugins/PostProcessingPlugin/Script.py | 2 +- .../UM3NetworkPrinting/DiscoverUM3Action.py | 6 +-- .../LegacyUM3OutputDevice.py | 10 +---- .../UM2UpgradeSelection.py | 5 +-- .../XmlMaterialProfile/XmlMaterialProfile.py | 3 -- tests/Settings/TestCuraContainerRegistry.py | 20 +++++----- tests/Settings/TestExtruderStack.py | 16 ++++---- tests/Settings/TestGlobalStack.py | 16 ++++---- 23 files changed, 91 insertions(+), 106 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index e5c0c5688c..f6a932546a 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -362,35 +362,35 @@ class CuraApplication(QtApplication): empty_definition_changes_container = copy.deepcopy(empty_container) empty_definition_changes_container.setMetaDataEntry("id", "empty_definition_changes") - empty_definition_changes_container.addMetaDataEntry("type", "definition_changes") + empty_definition_changes_container.setMetaDataEntry("type", "definition_changes") self._container_registry.addContainer(empty_definition_changes_container) self.empty_definition_changes_container = empty_definition_changes_container empty_variant_container = copy.deepcopy(empty_container) empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.addMetaDataEntry("type", "variant") + empty_variant_container.setMetaDataEntry("type", "variant") self._container_registry.addContainer(empty_variant_container) self.empty_variant_container = empty_variant_container empty_material_container = copy.deepcopy(empty_container) empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.addMetaDataEntry("type", "material") + empty_material_container.setMetaDataEntry("type", "material") self._container_registry.addContainer(empty_material_container) self.empty_material_container = empty_material_container empty_quality_container = copy.deepcopy(empty_container) empty_quality_container.setMetaDataEntry("id", "empty_quality") empty_quality_container.setName("Not Supported") - empty_quality_container.addMetaDataEntry("quality_type", "not_supported") - empty_quality_container.addMetaDataEntry("type", "quality") - empty_quality_container.addMetaDataEntry("supported", False) + empty_quality_container.setMetaDataEntry("quality_type", "not_supported") + empty_quality_container.setMetaDataEntry("type", "quality") + empty_quality_container.setMetaDataEntry("supported", False) self._container_registry.addContainer(empty_quality_container) self.empty_quality_container = empty_quality_container empty_quality_changes_container = copy.deepcopy(empty_container) empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.addMetaDataEntry("type", "quality_changes") - empty_quality_changes_container.addMetaDataEntry("quality_type", "not_supported") + empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") + empty_quality_changes_container.setMetaDataEntry("quality_type", "not_supported") self._container_registry.addContainer(empty_quality_changes_container) self.empty_quality_changes_container = empty_quality_changes_container diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 5e78c04900..82a11f9960 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -466,18 +466,18 @@ class QualityManager(QObject): # Create a new quality_changes container for the quality. quality_changes = InstanceContainer(new_id) quality_changes.setName(new_name) - quality_changes.addMetaDataEntry("type", "quality_changes") - quality_changes.addMetaDataEntry("quality_type", quality_type) + quality_changes.setMetaDataEntry("type", "quality_changes") + quality_changes.setMetaDataEntry("quality_type", quality_type) # If we are creating a container for an extruder, ensure we add that to the container if extruder_stack is not None: - quality_changes.addMetaDataEntry("position", extruder_stack.getMetaDataEntry("position")) + quality_changes.setMetaDataEntry("position", extruder_stack.getMetaDataEntry("position")) # If the machine specifies qualities should be filtered, ensure we match the current criteria. machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition) quality_changes.setDefinition(machine_definition_id) - quality_changes.addMetaDataEntry("setting_version", self._application.SettingVersion) + quality_changes.setMetaDataEntry("setting_version", self._application.SettingVersion) return quality_changes diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 6cbb3036f8..e1f50a157d 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -260,11 +260,11 @@ class CuraContainerRegistry(ContainerRegistry): profile_id = ContainerRegistry.getInstance().uniqueName(global_stack.getId() + "_extruder_" + str(idx + 1)) profile = InstanceContainer(profile_id) profile.setName(quality_name) - profile.addMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.SettingVersion) - profile.addMetaDataEntry("type", "quality_changes") - profile.addMetaDataEntry("definition", expected_machine_definition) - profile.addMetaDataEntry("quality_type", quality_type) - profile.addMetaDataEntry("position", "0") + profile.setMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.SettingVersion) + profile.setMetaDataEntry("type", "quality_changes") + profile.setMetaDataEntry("definition", expected_machine_definition) + profile.setMetaDataEntry("quality_type", quality_type) + profile.setMetaDataEntry("position", "0") profile.setDirty(True) if idx == 0: # move all per-extruder settings to the first extruder's quality_changes @@ -298,7 +298,7 @@ class CuraContainerRegistry(ContainerRegistry): extruder_id = machine_extruders[profile_index - 1].definition.getId() extruder_position = str(profile_index - 1) if not profile.getMetaDataEntry("position"): - profile.addMetaDataEntry("position", extruder_position) + profile.setMetaDataEntry("position", extruder_position) else: profile.setMetaDataEntry("position", extruder_position) profile_id = (extruder_id + "_" + name_seed).lower().replace(" ", "_") @@ -349,7 +349,7 @@ class CuraContainerRegistry(ContainerRegistry): if "type" in profile.getMetaData(): profile.setMetaDataEntry("type", "quality_changes") else: - profile.addMetaDataEntry("type", "quality_changes") + profile.setMetaDataEntry("type", "quality_changes") quality_type = profile.getMetaDataEntry("quality_type") if not quality_type: @@ -480,16 +480,16 @@ class CuraContainerRegistry(ContainerRegistry): extruder_stack = ExtruderStack.ExtruderStack(unique_name) extruder_stack.setName(extruder_definition.getName()) extruder_stack.setDefinition(extruder_definition) - extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) + extruder_stack.setMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) # create a new definition_changes container for the extruder stack definition_changes_id = self.uniqueName(extruder_stack.getId() + "_settings") if create_new_ids else extruder_stack.getId() + "_settings" definition_changes_name = definition_changes_id definition_changes = InstanceContainer(definition_changes_id, parent = application) definition_changes.setName(definition_changes_name) - definition_changes.addMetaDataEntry("setting_version", application.SettingVersion) - definition_changes.addMetaDataEntry("type", "definition_changes") - definition_changes.addMetaDataEntry("definition", extruder_definition.getId()) + definition_changes.setMetaDataEntry("setting_version", application.SettingVersion) + definition_changes.setMetaDataEntry("type", "definition_changes") + definition_changes.setMetaDataEntry("definition", extruder_definition.getId()) # move definition_changes settings if exist for setting_key in definition_changes.getAllKeys(): @@ -514,9 +514,9 @@ class CuraContainerRegistry(ContainerRegistry): user_container_name = user_container_id user_container = InstanceContainer(user_container_id, parent = application) user_container.setName(user_container_name) - user_container.addMetaDataEntry("type", "user") - user_container.addMetaDataEntry("machine", machine.getId()) - user_container.addMetaDataEntry("setting_version", application.SettingVersion) + user_container.setMetaDataEntry("type", "user") + user_container.setMetaDataEntry("machine", machine.getId()) + user_container.setMetaDataEntry("setting_version", application.SettingVersion) user_container.setDefinition(machine.definition.getId()) user_container.setMetaDataEntry("position", extruder_stack.getMetaDataEntry("position")) @@ -580,7 +580,7 @@ class CuraContainerRegistry(ContainerRegistry): extruder_quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine_quality_changes.getName()) if extruder_quality_changes_container: quality_changes_id = extruder_quality_changes_container.getId() - extruder_quality_changes_container.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) + extruder_quality_changes_container.setMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) extruder_stack.qualityChanges = self.findInstanceContainers(id = quality_changes_id)[0] else: # if we still cannot find a quality changes container for the extruder, create a new one @@ -588,10 +588,10 @@ class CuraContainerRegistry(ContainerRegistry): container_id = self.uniqueName(extruder_stack.getId() + "_qc_" + container_name) extruder_quality_changes_container = InstanceContainer(container_id, parent = application) extruder_quality_changes_container.setName(container_name) - extruder_quality_changes_container.addMetaDataEntry("type", "quality_changes") - extruder_quality_changes_container.addMetaDataEntry("setting_version", application.SettingVersion) - extruder_quality_changes_container.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) - extruder_quality_changes_container.addMetaDataEntry("quality_type", machine_quality_changes.getMetaDataEntry("quality_type")) + extruder_quality_changes_container.setMetaDataEntry("type", "quality_changes") + extruder_quality_changes_container.setMetaDataEntry("setting_version", application.SettingVersion) + extruder_quality_changes_container.setMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) + extruder_quality_changes_container.setMetaDataEntry("quality_type", machine_quality_changes.getMetaDataEntry("quality_type")) extruder_quality_changes_container.setDefinition(machine_quality_changes.getDefinition().getId()) self.addContainer(extruder_quality_changes_container) diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index 667b468bc0..bd3380dfb2 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -57,7 +57,7 @@ class CuraContainerStack(ContainerStack): self.containersChanged.connect(self._onContainersChanged) import cura.CuraApplication #Here to prevent circular imports. - self.addMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.SettingVersion) + self.setMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.SettingVersion) # This is emitted whenever the containersChanged signal from the ContainerStack base class is emitted. pyqtContainersChanged = pyqtSignal() diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index e593c3d349..841d45ed31 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -146,7 +146,7 @@ class CuraStackBuilder: stack.setName(extruder_definition.getName()) stack.setDefinition(extruder_definition) - stack.addMetaDataEntry("position", position) + stack.setMetaDataEntry("position", position) user_container = cls.createUserChangesContainer(new_stack_id + "_user", machine_definition_id, new_stack_id, is_global_stack = False) @@ -208,11 +208,11 @@ class CuraStackBuilder: container = InstanceContainer(unique_container_name) container.setDefinition(definition_id) - container.addMetaDataEntry("type", "user") - container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) + container.setMetaDataEntry("type", "user") + container.setMetaDataEntry("setting_version", CuraApplication.SettingVersion) metadata_key_to_add = "machine" if is_global_stack else "extruder" - container.addMetaDataEntry(metadata_key_to_add, stack_id) + container.setMetaDataEntry(metadata_key_to_add, stack_id) return container @@ -226,8 +226,8 @@ class CuraStackBuilder: definition_changes_container = InstanceContainer(unique_container_name) definition_changes_container.setDefinition(container_stack.getBottom().getId()) - definition_changes_container.addMetaDataEntry("type", "definition_changes") - definition_changes_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) + definition_changes_container.setMetaDataEntry("type", "definition_changes") + definition_changes_container.setMetaDataEntry("setting_version", CuraApplication.SettingVersion) registry.addContainer(definition_changes_container) container_stack.definitionChanges = definition_changes_container diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index 4445563e00..47846fc1dd 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -29,7 +29,7 @@ class ExtruderStack(CuraContainerStack): def __init__(self, container_id: str) -> None: super().__init__(container_id) - self.addMetaDataEntry("type", "extruder_train") # For backward compatibility + self.setMetaDataEntry("type", "extruder_train") # For backward compatibility self.propertiesChanged.connect(self._onPropertiesChanged) @@ -42,7 +42,7 @@ class ExtruderStack(CuraContainerStack): def setNextStack(self, stack: CuraContainerStack, connect_signals: bool = True) -> None: super().setNextStack(stack) stack.addExtruder(self) - self.addMetaDataEntry("machine", stack.id) + self.setMetaDataEntry("machine", stack.id) # For backward compatibility: Register the extruder with the Extruder Manager ExtruderManager.getInstance().registerExtruder(self, stack.id) @@ -53,7 +53,7 @@ class ExtruderStack(CuraContainerStack): def setEnabled(self, enabled: bool) -> None: if "enabled" not in self._metadata: - self.addMetaDataEntry("enabled", "True") + self.setMetaDataEntry("enabled", "True") self.setMetaDataEntry("enabled", str(enabled)) self.enabledChanged.emit() @@ -138,7 +138,7 @@ class ExtruderStack(CuraContainerStack): def deserialize(self, contents: str, file_name: Optional[str] = None) -> None: super().deserialize(contents, file_name) if "enabled" not in self.getMetaData(): - self.addMetaDataEntry("enabled", "True") + self.setMetaDataEntry("enabled", "True") stacks = ContainerRegistry.getInstance().findContainerStacks(id=self.getMetaDataEntry("machine", "")) if stacks: self.setNextStack(stacks[0]) diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index 6552e43073..66f3290b85 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -27,7 +27,7 @@ class GlobalStack(CuraContainerStack): def __init__(self, container_id: str) -> None: super().__init__(container_id) - self.addMetaDataEntry("type", "machine") # For backward compatibility + self.setMetaDataEntry("type", "machine") # For backward compatibility self._extruders = {} # type: Dict[str, "ExtruderStack"] diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 772c01191c..26f5a490dd 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1299,9 +1299,9 @@ class MachineManager(QObject): new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_sync", machine_definition_id) if not new_machine: return - new_machine.addMetaDataEntry("um_network_key", self.activeMachineNetworkKey) - new_machine.addMetaDataEntry("connect_group_name", self.activeMachineNetworkGroupName) - new_machine.addMetaDataEntry("hidden", False) + new_machine.setMetaDataEntry("um_network_key", self.activeMachineNetworkKey) + new_machine.setMetaDataEntry("connect_group_name", self.activeMachineNetworkGroupName) + new_machine.setMetaDataEntry("hidden", False) else: Logger.log("i", "Found a %s with the key %s. Let's use it!", machine_name, self.activeMachineNetworkKey) new_machine.setMetaDataEntry("hidden", False) diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index 27ae1d69f0..429e6d16ec 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -37,7 +37,7 @@ class SettingOverrideDecorator(SceneNodeDecorator): self._stack = PerObjectContainerStack(container_id = "per_object_stack_" + str(id(self))) self._stack.setDirty(False) # This stack does not need to be saved. user_container = InstanceContainer(container_id = self._generateUniqueName()) - user_container.addMetaDataEntry("type", "user") + user_container.setMetaDataEntry("type", "user") self._stack.userChanges = user_container self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId() diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 008bf24cda..f72029524e 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -963,7 +963,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): if not extruder_info: continue if "enabled" not in extruder_stack.getMetaData(): - extruder_stack.addMetaDataEntry("enabled", "True") + extruder_stack.setMetaDataEntry("enabled", "True") extruder_stack.setMetaDataEntry("enabled", str(extruder_info.enabled)) def _updateActiveMachine(self, global_stack): diff --git a/plugins/CuraProfileReader/CuraProfileReader.py b/plugins/CuraProfileReader/CuraProfileReader.py index d7370326e4..5957b2cecf 100644 --- a/plugins/CuraProfileReader/CuraProfileReader.py +++ b/plugins/CuraProfileReader/CuraProfileReader.py @@ -75,7 +75,7 @@ class CuraProfileReader(ProfileReader): def _loadProfile(self, serialized, profile_id): # Create an empty profile. profile = InstanceContainer(profile_id) - profile.addMetaDataEntry("type", "quality_changes") + profile.setMetaDataEntry("type", "quality_changes") try: profile.deserialize(serialized) except ContainerFormatError as e: diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index d334c66dbe..aea0698d19 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -127,11 +127,11 @@ class GCodeWriter(MeshWriter): flat_global_container = self._createFlattenedContainerInstance(stack.userChanges, container_with_profile) # If the quality changes is not set, we need to set type manually if flat_global_container.getMetaDataEntry("type", None) is None: - flat_global_container.addMetaDataEntry("type", "quality_changes") + flat_global_container.setMetaDataEntry("type", "quality_changes") # Ensure that quality_type is set. (Can happen if we have empty quality changes). if flat_global_container.getMetaDataEntry("quality_type", None) is None: - flat_global_container.addMetaDataEntry("quality_type", stack.quality.getMetaDataEntry("quality_type", "normal")) + flat_global_container.setMetaDataEntry("quality_type", stack.quality.getMetaDataEntry("quality_type", "normal")) # Get the machine definition ID for quality profiles machine_definition_id_for_quality = getMachineDefinitionIDForQualitySearch(stack.definition) @@ -151,15 +151,15 @@ class GCodeWriter(MeshWriter): flat_extruder_quality = self._createFlattenedContainerInstance(extruder.userChanges, extruder_quality) # If the quality changes is not set, we need to set type manually if flat_extruder_quality.getMetaDataEntry("type", None) is None: - flat_extruder_quality.addMetaDataEntry("type", "quality_changes") + flat_extruder_quality.setMetaDataEntry("type", "quality_changes") # Ensure that extruder is set. (Can happen if we have empty quality changes). if flat_extruder_quality.getMetaDataEntry("position", None) is None: - flat_extruder_quality.addMetaDataEntry("position", extruder.getMetaDataEntry("position")) + flat_extruder_quality.setMetaDataEntry("position", extruder.getMetaDataEntry("position")) # Ensure that quality_type is set. (Can happen if we have empty quality changes). if flat_extruder_quality.getMetaDataEntry("quality_type", None) is None: - flat_extruder_quality.addMetaDataEntry("quality_type", extruder.quality.getMetaDataEntry("quality_type", "normal")) + flat_extruder_quality.setMetaDataEntry("quality_type", extruder.quality.getMetaDataEntry("quality_type", "normal")) # Change the default definition flat_extruder_quality.setMetaDataEntry("definition", machine_definition_id_for_quality) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 40a843e6c4..93c15ca8e0 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -145,9 +145,9 @@ class LegacyProfileReader(ProfileReader): if len(profile.getAllKeys()) == 0: Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.") - profile.addMetaDataEntry("type", "profile") + profile.setMetaDataEntry("type", "profile") # don't know what quality_type it is based on, so use "normal" by default - profile.addMetaDataEntry("quality_type", "normal") + profile.setMetaDataEntry("quality_type", "normal") profile.setName(profile_id) profile.setDirty(True) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index acfec7938d..afd7aac86d 100755 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -135,10 +135,7 @@ class MachineSettingsAction(MachineAction): material_node = None if has_materials: - if "has_materials" in self._global_container_stack.getMetaData(): - self._global_container_stack.setMetaDataEntry("has_materials", True) - else: - self._global_container_stack.addMetaDataEntry("has_materials", True) + self._global_container_stack.setMetaDataEntry("has_materials", True) else: # The metadata entry is stored in an ini, and ini files are parsed as strings only. # Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False. diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py index 1bbe4bb66c..da971a8e61 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py @@ -248,7 +248,7 @@ class PostProcessingPlugin(QObject, Extension): global_stack = Application.getInstance().getGlobalContainerStack() if "post_processing_scripts" not in global_stack.getMetaData(): - global_stack.addMetaDataEntry("post_processing_scripts", "") + global_stack.setMetaDataEntry("post_processing_scripts", "") Application.getInstance().getGlobalContainerStack().setMetaDataEntry("post_processing_scripts", script_list_strs) ## Creates the view used by show popup. The view is saved because of the fairly aggressive garbage collection. diff --git a/plugins/PostProcessingPlugin/Script.py b/plugins/PostProcessingPlugin/Script.py index cc839ca485..7e430a5c78 100644 --- a/plugins/PostProcessingPlugin/Script.py +++ b/plugins/PostProcessingPlugin/Script.py @@ -48,7 +48,7 @@ class Script: self._stack.addContainer(self._definition) self._instance = InstanceContainer(container_id="ScriptInstanceContainer") self._instance.setDefinition(self._definition.getId()) - self._instance.addMetaDataEntry("setting_version", self._definition.getMetaDataEntry("setting_version", default = 0)) + self._instance.setMetaDataEntry("setting_version", self._definition.getMetaDataEntry("setting_version", default = 0)) self._stack.addContainer(self._instance) self._stack.propertyChanged.connect(self._onPropertyChanged) diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py index b48a57e0a2..135bc06d3a 100644 --- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py @@ -108,8 +108,8 @@ class DiscoverUM3Action(MachineAction): # Find all the places where there is the same group name and change it accordingly CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "connect_group_name", value = previous_connect_group_name, new_value = group_name) else: - global_container_stack.addMetaDataEntry("connect_group_name", group_name) - global_container_stack.addMetaDataEntry("hidden", False) + global_container_stack.setMetaDataEntry("connect_group_name", group_name) + global_container_stack.setMetaDataEntry("hidden", False) if self._network_plugin: # Ensure that the connection states are refreshed. @@ -130,7 +130,7 @@ class DiscoverUM3Action(MachineAction): global_container_stack.removeMetaDataEntry("network_authentication_key") CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "um_network_key", value = previous_network_key, new_value = key) else: - global_container_stack.addMetaDataEntry("um_network_key", key) + global_container_stack.setMetaDataEntry("um_network_key", key) if self._network_plugin: # Ensure that the connection states are refreshed. diff --git a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py index 9b90f8542d..4c5d56e0da 100644 --- a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py @@ -458,15 +458,9 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): def _saveAuthentication(self): global_container_stack = CuraApplication.getInstance().getGlobalContainerStack() if global_container_stack: - if "network_authentication_key" in global_container_stack.getMetaData(): - global_container_stack.setMetaDataEntry("network_authentication_key", self._authentication_key) - else: - global_container_stack.addMetaDataEntry("network_authentication_key", self._authentication_key) + global_container_stack.setMetaDataEntry("network_authentication_key", self._authentication_key) - if "network_authentication_id" in global_container_stack.getMetaData(): - global_container_stack.setMetaDataEntry("network_authentication_id", self._authentication_id) - else: - global_container_stack.addMetaDataEntry("network_authentication_id", self._authentication_id) + global_container_stack.setMetaDataEntry("network_authentication_id", self._authentication_id) # Force save so we are sure the data is not lost. CuraApplication.getInstance().saveStack(global_container_stack) diff --git a/plugins/UltimakerMachineActions/UM2UpgradeSelection.py b/plugins/UltimakerMachineActions/UM2UpgradeSelection.py index e21256f6bd..6ff3f0b629 100644 --- a/plugins/UltimakerMachineActions/UM2UpgradeSelection.py +++ b/plugins/UltimakerMachineActions/UM2UpgradeSelection.py @@ -47,10 +47,7 @@ class UM2UpgradeSelection(MachineAction): variant_container = global_container_stack.extruders["0"].variant if has_variants: - if "has_variants" in global_container_stack.getMetaData(): - global_container_stack.setMetaDataEntry("has_variants", True) - else: - global_container_stack.addMetaDataEntry("has_variants", True) + global_container_stack.setMetaDataEntry("has_variants", True) # Set the variant container to a sane default empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index ca6271391e..eac6646197 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -63,7 +63,6 @@ class XmlMaterialProfile(InstanceContainer): # Prevent recursion if not apply_to_all: - super().addMetaDataEntry(key, value) super().setMetaDataEntry(key, value) return @@ -75,14 +74,12 @@ class XmlMaterialProfile(InstanceContainer): # Update the root material container root_material_container = material_group.root_material_node.getContainer() if root_material_container is not None: - root_material_container.addMetaDataEntry(key, value) root_material_container.setMetaDataEntry(key, value, apply_to_all = False) # Update all containers derived from it for node in material_group.derived_material_node_list: container = node.getContainer() if container is not None: - container.addMetaDataEntry(key, value) container.setMetaDataEntry(key, value, apply_to_all = False) ## Overridden from InstanceContainer, similar to setMetaDataEntry. diff --git a/tests/Settings/TestCuraContainerRegistry.py b/tests/Settings/TestCuraContainerRegistry.py index b97f6b4faf..38b2e0f6ea 100644 --- a/tests/Settings/TestCuraContainerRegistry.py +++ b/tests/Settings/TestCuraContainerRegistry.py @@ -23,25 +23,25 @@ def creteEmptyContainers(): empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() empty_variant_container = copy.deepcopy(empty_container) empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.addMetaDataEntry("type", "variant") + empty_variant_container.setMetaDataEntry("type", "variant") ContainerRegistry.getInstance().addContainer(empty_variant_container) empty_material_container = copy.deepcopy(empty_container) empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.addMetaDataEntry("type", "material") + empty_material_container.setMetaDataEntry("type", "material") ContainerRegistry.getInstance().addContainer(empty_material_container) empty_quality_container = copy.deepcopy(empty_container) empty_quality_container.setMetaDataEntry("id", "empty_quality") empty_quality_container.setName("Not Supported") - empty_quality_container.addMetaDataEntry("quality_type", "not_supported") - empty_quality_container.addMetaDataEntry("type", "quality") - empty_quality_container.addMetaDataEntry("supported", False) + empty_quality_container.setMetaDataEntry("quality_type", "not_supported") + empty_quality_container.setMetaDataEntry("type", "quality") + empty_quality_container.setMetaDataEntry("supported", False) ContainerRegistry.getInstance().addContainer(empty_quality_container) empty_quality_changes_container = copy.deepcopy(empty_container) empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.addMetaDataEntry("type", "quality_changes") + empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) ## Gives a fresh CuraContainerRegistry instance. @@ -69,7 +69,7 @@ def test_addContainerExtruderStack(container_registry, definition_container): container_registry.addContainer(definition_container) container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Container Stack") #A container we're going to convert. - container_stack.addMetaDataEntry("type", "extruder_train") #This is now an extruder train. + container_stack.setMetaDataEntry("type", "extruder_train") #This is now an extruder train. container_stack.insertContainer(0, definition_container) #Add a definition to it so it doesn't complain. mock_super_add_container = unittest.mock.MagicMock() #Takes the role of the Uranium-ContainerRegistry where the resulting containers get registered. @@ -85,7 +85,7 @@ def test_addContainerGlobalStack(container_registry, definition_container): container_registry.addContainer(definition_container) container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Container Stack") #A container we're going to convert. - container_stack.addMetaDataEntry("type", "machine") #This is now a global stack. + container_stack.setMetaDataEntry("type", "machine") #This is now a global stack. container_stack.insertContainer(0, definition_container) #Must have a definition. mock_super_add_container = unittest.mock.MagicMock() #Takes the role of the Uranium-ContainerRegistry where the resulting containers get registered. @@ -102,7 +102,7 @@ def test_addContainerGoodSettingVersion(container_registry, definition_container container_registry.addContainer(definition_container) instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance") - instance.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) + instance.setMetaDataEntry("setting_version", CuraApplication.SettingVersion) instance.setDefinition(definition_container.getId()) mock_super_add_container = unittest.mock.MagicMock() #Take the role of the Uranium-ContainerRegistry where the resulting containers get registered. @@ -132,7 +132,7 @@ def test_addContainerBadSettingVersion(container_registry, definition_container) container_registry.addContainer(definition_container) instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance") - instance.addMetaDataEntry("setting_version", 9001) #Wrong version! + instance.setMetaDataEntry("setting_version", 9001) #Wrong version! instance.setDefinition(definition_container.getId()) mock_super_add_container = unittest.mock.MagicMock() #Take the role of the Uranium-ContainerRegistry where the resulting container should not get registered. diff --git a/tests/Settings/TestExtruderStack.py b/tests/Settings/TestExtruderStack.py index b418ae4306..7c463fb9be 100644 --- a/tests/Settings/TestExtruderStack.py +++ b/tests/Settings/TestExtruderStack.py @@ -45,32 +45,32 @@ def extruder_stack() -> cura.Settings.ExtruderStack.ExtruderStack: # \return An instance container instance. def getInstanceContainer(container_type) -> InstanceContainer: container = InstanceContainer(container_id = "InstanceContainer") - container.addMetaDataEntry("type", container_type) + container.setMetaDataEntry("type", container_type) return container def creteEmptyContainers(): empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() empty_variant_container = copy.deepcopy(empty_container) empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.addMetaDataEntry("type", "variant") + empty_variant_container.setMetaDataEntry("type", "variant") ContainerRegistry.getInstance().addContainer(empty_variant_container) empty_material_container = copy.deepcopy(empty_container) empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.addMetaDataEntry("type", "material") + empty_material_container.setMetaDataEntry("type", "material") ContainerRegistry.getInstance().addContainer(empty_material_container) empty_quality_container = copy.deepcopy(empty_container) empty_quality_container.setMetaDataEntry("id", "empty_quality") empty_quality_container.setName("Not Supported") - empty_quality_container.addMetaDataEntry("quality_type", "not_supported") - empty_quality_container.addMetaDataEntry("type", "quality") - empty_quality_container.addMetaDataEntry("supported", False) + empty_quality_container.setMetaDataEntry("quality_type", "not_supported") + empty_quality_container.setMetaDataEntry("type", "quality") + empty_quality_container.setMetaDataEntry("supported", False) ContainerRegistry.getInstance().addContainer(empty_quality_container) empty_quality_changes_container = copy.deepcopy(empty_container) empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.addMetaDataEntry("type", "quality_changes") + empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) class DefinitionContainerSubClass(DefinitionContainer): @@ -80,7 +80,7 @@ class DefinitionContainerSubClass(DefinitionContainer): class InstanceContainerSubClass(InstanceContainer): def __init__(self, container_type): super().__init__(container_id = "SubInstanceContainer") - self.addMetaDataEntry("type", container_type) + self.setMetaDataEntry("type", container_type) #############################START OF TEST CASES################################ diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py index 05c7cf1677..3e74e3e575 100755 --- a/tests/Settings/TestGlobalStack.py +++ b/tests/Settings/TestGlobalStack.py @@ -45,32 +45,32 @@ def global_stack() -> cura.Settings.GlobalStack.GlobalStack: # \return An instance container instance. def getInstanceContainer(container_type) -> InstanceContainer: container = InstanceContainer(container_id = "InstanceContainer") - container.addMetaDataEntry("type", container_type) + container.setMetaDataEntry("type", container_type) return container def creteEmptyContainers(): empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() empty_variant_container = copy.deepcopy(empty_container) empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.addMetaDataEntry("type", "variant") + empty_variant_container.setMetaDataEntry("type", "variant") ContainerRegistry.getInstance().addContainer(empty_variant_container) empty_material_container = copy.deepcopy(empty_container) empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.addMetaDataEntry("type", "material") + empty_material_container.setMetaDataEntry("type", "material") ContainerRegistry.getInstance().addContainer(empty_material_container) empty_quality_container = copy.deepcopy(empty_container) empty_quality_container.setMetaDataEntry("id", "empty_quality") empty_quality_container.setName("Not Supported") - empty_quality_container.addMetaDataEntry("quality_type", "not_supported") - empty_quality_container.addMetaDataEntry("type", "quality") - empty_quality_container.addMetaDataEntry("supported", False) + empty_quality_container.setMetaDataEntry("quality_type", "not_supported") + empty_quality_container.setMetaDataEntry("type", "quality") + empty_quality_container.setMetaDataEntry("supported", False) ContainerRegistry.getInstance().addContainer(empty_quality_container) empty_quality_changes_container = copy.deepcopy(empty_container) empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.addMetaDataEntry("type", "quality_changes") + empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) class DefinitionContainerSubClass(DefinitionContainer): @@ -80,7 +80,7 @@ class DefinitionContainerSubClass(DefinitionContainer): class InstanceContainerSubClass(InstanceContainer): def __init__(self, container_type): super().__init__(container_id = "SubInstanceContainer") - self.addMetaDataEntry("type", container_type) + self.setMetaDataEntry("type", container_type) #############################START OF TEST CASES################################ From 2bd8350141439814d92827ef67243c93f3d70872 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 12 Jul 2018 14:06:34 +0200 Subject: [PATCH 11/11] Added error checking, added typing, renamed function. CURA-5389 --- cura/CuraPackageManager.py | 4 +++- cura/Machines/MaterialGroup.py | 4 ++-- .../qml/ToolboxConfirmUninstallResetDialog.qml | 13 ++++++++----- plugins/Toolbox/src/Toolbox.py | 9 ++++++--- plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py | 10 ++++++++-- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 363b8034ec..6422469bdf 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -1,6 +1,8 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import List, Tuple + from cura.CuraApplication import CuraApplication #To find some resource types. from cura.Settings.GlobalStack import GlobalStack @@ -22,7 +24,7 @@ class CuraPackageManager(PackageManager): # empty if it is never used. # It loops through all the package contents and see if some of the ids are used. # The list consists of 3-tuples: (global_stack, extruder_nr, container_id) - def getMachinesUsingPackage(self, package_id: str): + def getMachinesUsingPackage(self, package_id: str) -> Tuple[List[Tuple[GlobalStack, str, str]], List[Tuple[GlobalStack, str, str]]]: ids = self.getPackageContainerIds(package_id) container_stacks = self._application.getContainerRegistry().findContainerStacks() global_stacks = [container_stack for container_stack in container_stacks if isinstance(container_stack, GlobalStack)] diff --git a/cura/Machines/MaterialGroup.py b/cura/Machines/MaterialGroup.py index e05647e674..8a73796a7a 100644 --- a/cura/Machines/MaterialGroup.py +++ b/cura/Machines/MaterialGroup.py @@ -24,8 +24,8 @@ class MaterialGroup: def __init__(self, name: str, root_material_node: "MaterialNode") -> None: self.name = name self.is_read_only = False - self.root_material_node = root_material_node # type: MaterialNode - self.derived_material_node_list = [] # type: List[MaterialNode] + self.root_material_node = root_material_node # type: MaterialNode + self.derived_material_node_list = [] # type: List[MaterialNode] def __str__(self) -> str: return "%s[%s]" % (self.__class__.__name__, self.name) diff --git a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml index 83ace5f80b..4aa8b883b7 100644 --- a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml @@ -32,11 +32,14 @@ UM.Dialog { UM.I18nCatalog { id: catalog; name: "cura" } - anchors.fill: parent - anchors.leftMargin: Math.round(20 * screenScaleFactor) - anchors.rightMargin: Math.round(20 * screenScaleFactor) - anchors.topMargin: Math.round(10 * screenScaleFactor) - anchors.bottomMargin: Math.round(10 * screenScaleFactor) + anchors + { + fill: parent + leftMargin: Math.round(20 * screenScaleFactor) + rightMargin: Math.round(20 * screenScaleFactor) + topMargin: Math.round(10 * screenScaleFactor) + bottomMargin: Math.round(10 * screenScaleFactor) + } spacing: Math.round(15 * screenScaleFactor) Label diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 31b9dda9f4..b1128722e9 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -330,7 +330,10 @@ class Toolbox(QObject, Extension): if self._confirm_reset_dialog is None: self._confirm_reset_dialog = self._createDialog("ToolboxConfirmUninstallResetDialog.qml") self.uninstallVariablesChanged.emit() - self._confirm_reset_dialog.show() + if self._confirm_reset_dialog is None: + Logger.log("e", "ToolboxConfirmUninstallResetDialog should have been initialized, but it is not. Not showing dialog and not uninstalling package.") + else: + self._confirm_reset_dialog.show() else: # Plain uninstall self.uninstall(package_id) @@ -368,13 +371,13 @@ class Toolbox(QObject, Extension): default_quality_group = quality_manager.getDefaultQualityType(global_stack) machine_manager.setQualityGroup(default_quality_group, global_stack = global_stack) - self._markPackageMaterialsAsRemove(self._package_id_to_uninstall) + self._markPackageMaterialsAsToBeUninstalled(self._package_id_to_uninstall) self.uninstall(self._package_id_to_uninstall) self._resetUninstallVariables() self.closeConfirmResetDialog() - def _markPackageMaterialsAsRemove(self, package_id: str) -> None: + def _markPackageMaterialsAsToBeUninstalled(self, package_id: str) -> None: container_registry = self._application.getContainerRegistry() all_containers = self._package_manager.getPackageContainerIds(package_id) diff --git a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py index 4c5d56e0da..f38c1a1c7a 100644 --- a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py @@ -455,8 +455,14 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self.setAuthenticationState(AuthState.AuthenticationDenied) self._authentication_failed_message.show() - def _saveAuthentication(self): + def _saveAuthentication(self) -> None: global_container_stack = CuraApplication.getInstance().getGlobalContainerStack() + if self._authentication_key is None: + Logger.log("e", "Authentication key is None, nothing to save.") + return + if self._authentication_id is None: + Logger.log("e", "Authentication id is None, nothing to save.") + return if global_container_stack: global_container_stack.setMetaDataEntry("network_authentication_key", self._authentication_key) @@ -631,4 +637,4 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): result = "********" + result return result - return self._authentication_key \ No newline at end of file + return self._authentication_key