diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index a93dd3c1b6..be302d2a6f 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -164,15 +164,15 @@ class ContainerManager(QObject): # \return True if successful, False if not. @pyqtSlot(str, result = bool) def clearContainer(self, container_id): + if self._container_registry.isReadOnly(container_id): + Logger.log("w", "Cannot clear read-only container %s", container_id) + return False + containers = self._container_registry.findContainers(id = container_id) if not containers: Logger.log("w", "Could clear container %s because it was not found.", container_id) return False - if containers[0].isReadOnly(): - Logger.log("w", "Cannot clear read-only container %s", container_id) - return False - containers[0].clear() return True @@ -200,6 +200,10 @@ class ContainerManager(QObject): # \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) + 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) @@ -207,10 +211,6 @@ class ContainerManager(QObject): container = containers[0] - if container.isReadOnly(): - Logger.log("w", "Cannot set metadata of read-only container %s.", container_id) - return False - entries = entry_name.split("/") entry_name = entries.pop() @@ -250,6 +250,10 @@ class ContainerManager(QObject): # \return True if successful, False if not. @pyqtSlot(str, str, str, str, result = bool) def setContainerProperty(self, container_id, setting_key, property_name, property_value): + if self._container_registry.isReadOnly(container_id): + Logger.log("w", "Cannot set properties of read-only container %s.", container_id) + return False + containers = self._container_registry.findContainers(id = container_id) if not containers: Logger.log("w", "Could not set properties of container %s because it was not found.", container_id) @@ -257,10 +261,6 @@ class ContainerManager(QObject): container = containers[0] - if container.isReadOnly(): - Logger.log("w", "Cannot set properties of read-only container %s.", container_id) - return False - container.setProperty(setting_key, property_name, property_value) basefile = container.getMetaDataEntry("base_file", container_id) @@ -296,18 +296,16 @@ class ContainerManager(QObject): ## Set the name of the specified container. @pyqtSlot(str, str, result = bool) def setContainerName(self, container_id, new_name): + if self._container_registry.isReadOnly(container_id): + Logger.log("w", "Cannot set name of read-only container %s.", container_id) + return False + containers = self._container_registry.findContainers(id = container_id) #We need to get the full container, not just metadata, since we need to know whether it's read-only. if not containers: Logger.log("w", "Could not set name of container %s because it was not found.", container_id) return False - container = containers[0] - - if container.isReadOnly(): - Logger.log("w", "Cannot set name of read-only container %s.", container_id) - return False - - container.setName(new_name) + containers[0].setName(new_name) return True diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index aa1f7617cb..b19bdca2cf 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -266,7 +266,6 @@ class CuraContainerRegistry(ContainerRegistry): # # \return None if configuring was successful or an error message if an error occurred. def _configureProfile(self, profile: InstanceContainer, id_seed: str, new_name: str) -> Optional[str]: - profile.setReadOnly(False) profile.setDirty(True) # Ensure the profiles are correctly saved new_id = self.createUniqueName("quality_changes", "", id_seed, catalog.i18nc("@label", "Custom profile")) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index e01561c5f4..03681d9e82 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -332,7 +332,7 @@ class ExtruderManager(QObject): preferred_materials = container_registry.findInstanceContainers(**search_criteria) if len(preferred_materials) >= 1: # In some cases we get multiple materials. In that case, prefer materials that are marked as read only. - read_only_preferred_materials = [preferred_material for preferred_material in preferred_materials if preferred_material.isReadOnly()] + read_only_preferred_materials = [preferred_material for preferred_material in preferred_materials if container_registry.isReadOnly(preferred_material.getId())] if len(read_only_preferred_materials) >= 1: material = read_only_preferred_materials[0] else: diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 285a329cae..e117efe289 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -704,10 +704,7 @@ class MachineManager(QObject): ## Check if a container is read_only @pyqtSlot(str, result = bool) def isReadOnly(self, container_id: str) -> bool: - containers = ContainerRegistry.getInstance().findInstanceContainers(id = container_id) - if not containers or not self._active_container_stack: - return True - return containers[0].isReadOnly() + return ContainerRegistry.getInstance().isReadOnly(container_id) ## Copy the value of the setting of the current extruder to all other extruders as well as the global container. @pyqtSlot(str) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 011bac022c..bfd31f2ebe 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -180,11 +180,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader): material_container_files = [name for name in cura_file_names if name.endswith(self._material_container_suffix)] for material_container_file in material_container_files: container_id = self._stripFileToId(material_container_file) - materials = self._container_registry.findInstanceContainers(id=container_id) material_labels.append(self._getMaterialLabelFromSerialized(archive.open(material_container_file).read().decode("utf-8"))) - if materials: + if self._container_registry.findContainersMetadata(id = container_id): #This material already exists. containers_found_dict["material"] = True - if not materials[0].isReadOnly(): # Only non readonly materials can be in conflict + if not self._container_registry.isReadOnly(container_id): # Only non readonly materials can be in conflict material_conflict = True Job.yieldThread() @@ -501,7 +500,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): containers_to_add.append(material_container) else: material_container = materials[0] - if not material_container.isReadOnly(): # Only create new materials if they are not read only. + if not self._container_registry.isReadOnly(container_id): # Only create new materials if they are not read only. if self._resolve_strategies["material"] == "override": material_container.deserialize(archive.open(material_container_file).read().decode("utf-8")) elif self._resolve_strategies["material"] == "new": diff --git a/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py b/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py index 07a8df985c..0193434b18 100755 --- a/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py +++ b/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py @@ -969,7 +969,8 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): ## Send all material profiles to the printer. def sendMaterialProfiles(self): - for container in UM.Settings.ContainerRegistry.ContainerRegistry.getInstance().findInstanceContainers(type = "material"): + registry = UM.Settings.ContainerRegistry.ContainerRegistry.getInstance() + for container in registry.findInstanceContainers(type = "material"): try: xml_data = container.serialize() if xml_data == "" or xml_data is None: @@ -978,7 +979,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): names = ContainerManager.getInstance().getLinkedMaterials(container.getId()) if names: # There are other materials that share this GUID. - if not container.isReadOnly(): + if not registry.isReadOnly(container.getId()): continue # If it's not readonly, it's created by user, so skip it. material_multi_part = QHttpMultiPart(QHttpMultiPart.FormDataType) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 23d4ed3860..47b0b4f2e9 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -45,25 +45,18 @@ class XmlMaterialProfile(InstanceContainer): def getInheritedFiles(self): return self._inherited_files - ## Overridden from InstanceContainer - def setReadOnly(self, read_only): - super().setReadOnly(read_only) - - basefile = self.getMetaDataEntry("base_file", self.getId()) # if basefile is self.getId, this is a basefile. - for container in ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile): - container._read_only = read_only # prevent loop instead of calling setReadOnly - ## Overridden from InstanceContainer # set the meta data for all machine / variant combinations def setMetaDataEntry(self, key, value): - if self.isReadOnly(): + registry = ContainerRegistry.getInstance() + if registry.isReadOnly(self.getId()): return super().setMetaDataEntry(key, value) basefile = self.getMetaDataEntry("base_file", self.getId()) #if basefile is self.getId, this is a basefile. # Update all containers that share basefile - for container in ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile): + for container in registry.findInstanceContainers(base_file = basefile): if container.getMetaDataEntry(key, None) != value: # Prevent recursion container.setMetaDataEntry(key, value) @@ -71,7 +64,8 @@ class XmlMaterialProfile(InstanceContainer): # without this function the setName would only set the name of the specific nozzle / material / machine combination container # The function is a bit tricky. It will not set the name of all containers if it has the correct name itself. def setName(self, new_name): - if self.isReadOnly(): + registry = ContainerRegistry.getInstance() + if registry.isReadOnly(self.getId()): return # Not only is this faster, it also prevents a major loop that causes a stack overflow. @@ -83,7 +77,7 @@ class XmlMaterialProfile(InstanceContainer): basefile = self.getMetaDataEntry("base_file", self.getId()) # if basefile is self.getId, this is a basefile. # Update the basefile as well, this is actually what we're trying to do # Update all containers that share GUID and basefile - containers = ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile) + containers = registry.findInstanceContainers(base_file = basefile) for container in containers: container.setName(new_name) @@ -91,12 +85,11 @@ class XmlMaterialProfile(InstanceContainer): def setDirty(self, dirty): super().setDirty(dirty) base_file = self.getMetaDataEntry("base_file", None) - if base_file is not None and base_file != self.getId(): - containers = ContainerRegistry.getInstance().findContainers(id=base_file) + registry = ContainerRegistry.getInstance() + if base_file is not None and base_file != self.getId() and not registry.isReadOnly(base_file): + containers = registry.findContainers(id = base_file) if containers: - base_container = containers[0] - if not base_container.isReadOnly(): - base_container.setDirty(dirty) + containers[0].setDirty(dirty) ## Overridden from InstanceContainer # base file: common settings + supported machines