diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index a97b588e68..550308f1dc 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -69,8 +69,7 @@ class MaterialManager(QObject): # Find all materials and put them in a matrix for quick search. material_metadata_list = self._container_registry.findContainersMetadata(type = "material") - self._material_group_map = OrderedDict() - self._diameter_machine_variant_material_map = {} + self._material_group_map = dict() # Map #1 # root_material_id -> MaterialGroup @@ -155,6 +154,7 @@ class MaterialManager(QObject): # Map #4 # "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer # Construct the "machine" -> "variant" -> "root material ID" -> specific material InstanceContainer + self._diameter_machine_variant_material_map = dict() for material_metadata in material_metadata_list: # We don't store empty material in the lookup tables if material_metadata["id"] == "empty_material": diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 7d4c702cf4..737810ee9d 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -42,8 +42,10 @@ class ContainerManager(QObject): def __init__(self, parent = None): super().__init__(parent) + self._application = Application.getInstance() self._container_registry = ContainerRegistry.getInstance() - self._machine_manager = Application.getInstance().getMachineManager() + self._machine_manager = self._application.getMachineManager() + self._material_manager = self._application._material_manager self._container_name_filters = {} ## Create a duplicate of the specified container @@ -211,18 +213,15 @@ class ContainerManager(QObject): # \param entry_value The new value of the entry. # # \return True if successful, False if not. - @pyqtSlot(str, str, str, result = bool) - def setContainerMetaDataEntry(self, container_id, entry_name, entry_value): - if self._container_registry.isReadOnly(container_id): - Logger.log("w", "Cannot set metadata of read-only container %s.", container_id) + # TODO: This is ONLY used by MaterialView for material containers. Maybe refactor this. + @pyqtSlot("QVariant", str, str) + def setContainerMetaDataEntry(self, container_node, entry_name, entry_value): + root_material_id = container_node.metadata["base_file"] + if self._container_registry.isReadOnly(root_material_id): + Logger.log("w", "Cannot set metadata of read-only container %s.", root_material_id) return False - containers = self._container_registry.findContainers(id = container_id) #We need the complete container, since we need to know whether the container is read-only or not. - if not containers: - Logger.log("w", "Could not set metadata of container %s because it was not found.", container_id) - return False - - container = containers[0] + material_group = self._material_manager.getMaterialGroup(root_material_id) entries = entry_name.split("/") entry_name = entries.pop() @@ -230,7 +229,7 @@ class ContainerManager(QObject): sub_item_changed = False if entries: root_name = entries.pop(0) - root = container.getMetaDataEntry(root_name) + root = material_group.root_material_node.metadata.get(root_name) item = root for _ in range(len(entries)): @@ -243,12 +242,11 @@ class ContainerManager(QObject): entry_name = root_name entry_value = root + container = material_group.root_material_node.getContainer() container.setMetaDataEntry(entry_name, entry_value) if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed. container.metaDataChanged.emit(container) - return True - ## Set a setting property of the specified container. # # This will set the specified property of the specified setting of the container @@ -768,10 +766,7 @@ class ContainerManager(QObject): def duplicateMaterial(self, material_node): root_material_id = material_node.metadata["base_file"] - from cura.CuraApplication import CuraApplication - material_manager = CuraApplication.getInstance()._material_manager - - material_group = material_manager.getMaterialGroup(root_material_id) + material_group = self._material_manager.getMaterialGroup(root_material_id) if not material_group: Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id) return "" @@ -867,10 +862,7 @@ class ContainerManager(QObject): def getLinkedMaterials(self, material_node): guid = material_node.metadata["GUID"] - from cura.CuraApplication import CuraApplication - material_manager = CuraApplication.getInstance()._material_manager - - material_group_list = material_manager.getMaterialGroupListByGUID(guid) + material_group_list = self._material_manager.getMaterialGroupListByGUID(guid) linked_material_names = [] if material_group_list: @@ -883,9 +875,7 @@ class ContainerManager(QObject): @pyqtSlot("QVariant") def unlinkMaterial(self, material_node): # Get the material group - from cura.CuraApplication import CuraApplication - material_manager = CuraApplication.getInstance()._material_manager - material_group = material_manager.getMaterialGroup(material_node.metadata["base_file"]) + material_group = self._material_manager.getMaterialGroup(material_node.metadata["base_file"]) # Generate a new GUID new_guid = str(uuid.uuid4()) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 338a72434f..80e3e3b721 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -48,14 +48,15 @@ class XmlMaterialProfile(InstanceContainer): ## Overridden from InstanceContainer # set the meta data for all machine / variant combinations - def setMetaDataEntry(self, key, value, is_first_call = True): + def setMetaDataEntry(self, key, value, apply_to_all = True): registry = ContainerRegistry.getInstance() if registry.isReadOnly(self.getId()): return # Prevent recursion - if is_first_call: + if not apply_to_all: super().setMetaDataEntry(key, value) + return # Get the MaterialGroup material_manager = CuraApplication.getInstance()._material_manager @@ -64,12 +65,12 @@ class XmlMaterialProfile(InstanceContainer): # Update the root material container root_material_container = material_group.root_material_node.getContainer() - root_material_container.setMetaDataEntry(key, value, is_first_call = False) + 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() - container.setMetaDataEntry(key, value, is_first_call = False) + container.setMetaDataEntry(key, value, apply_to_all = False) ## Overridden from InstanceContainer, similar to setMetaDataEntry. # without this function the setName would only set the name of the specific nozzle / material / machine combination container diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index f07564f7a5..0c3063ff41 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -417,7 +417,7 @@ TabView // Tiny convenience function to check if a value really changed before trying to set it. function setMetaDataEntry(entry_name, old_value, new_value) { if (old_value != new_value) { - Cura.ContainerManager.setContainerMetaDataEntry(base.containerId, entry_name, new_value) + Cura.ContainerManager.setContainerMetaDataEntry(base.currentMaterialNode, entry_name, new_value) // make sure the UI properties are updated as well since we don't re-fetch the entire model here // When the entry_name is something like properties/diameter, we take the last part of the entry_name var list = entry_name.split("/")