diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 0e4b60495e..08f1bdcba5 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -289,74 +289,27 @@ class MaterialManager(QObject): if root_material_id is not None: self.removeMaterialByRootId(root_material_id) - def duplicateMaterialByRootId(self, root_material_id: str, new_base_id: Optional[str] = None, - new_metadata: Optional[Dict[str, Any]] = None) -> Optional[str]: - container_registry = CuraContainerRegistry.getInstance() - results = container_registry.findContainers(id=root_material_id) - - if not results: - Logger.log("i", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id) - return None - - base_container = results[0] - - # Ensure all settings are saved. - cura.CuraApplication.CuraApplication.getInstance().saveSettings() - - # Create a new ID & container to hold the data. - new_containers = [] - if new_base_id is None: - new_base_id = container_registry.uniqueName(base_container.getId()) - new_base_container = copy.deepcopy(base_container) - new_base_container.getMetaData()["id"] = new_base_id - new_base_container.getMetaData()["base_file"] = new_base_id - if new_metadata is not None: - for key, value in new_metadata.items(): - new_base_container.getMetaData()[key] = value - new_containers.append(new_base_container) - - # Clone all of them. - for container_to_copy in container_registry.findContainers(base_file=root_material_id): - if container_to_copy.getId() == root_material_id: - continue # We already have that one, skip it - new_id = new_base_id - if container_to_copy.getMetaDataEntry("definition") != "fdmprinter": - new_id += "_" + container_to_copy.getMetaDataEntry("definition") - if container_to_copy.getMetaDataEntry("variant_name"): - nozzle_name = container_to_copy.getMetaDataEntry("variant_name") - new_id += "_" + nozzle_name.replace(" ", "_") - - new_container = copy.deepcopy(container_to_copy) - new_container.getMetaData()["id"] = new_id - new_container.getMetaData()["base_file"] = new_base_id - if new_metadata is not None: - for key, value in new_metadata.items(): - new_container.getMetaData()[key] = value - new_containers.append(new_container) - - for container_to_add in new_containers: - container_to_add.setDirty(True) - container_registry.addContainer(container_to_add) - - # if the duplicated material was favorite then the new material should also be added to favorite. - if root_material_id in self.getFavorites(): - cura.CuraApplication.CuraApplication.getInstance().getMaterialManagementModel().addFavorite(new_base_id) - - return new_base_id - - # - # Creates a duplicate of a material, which has the same GUID and base_file metadata. - # Returns the root material ID of the duplicated material if successful. - # - @pyqtSlot("QVariant", result = str) - def duplicateMaterial(self, material_node: MaterialNode, new_base_id: Optional[str] = None, - new_metadata: Optional[Dict[str, Any]] = None) -> str: - if material_node.container is None: - Logger.log("e", "Material node {0} doesn't have container.".format(material_node.container_id)) + def duplicateMaterialByRootId(self, root_material_id: str, new_base_id: Optional[str] = None, new_metadata: Optional[Dict[str, Any]] = None) -> Optional[str]: + result = cura.CuraApplication.CuraApplication.getInstance().getMaterialManagementModel().duplicateMaterialByBaseFile(root_material_id, new_base_id, new_metadata) + if result is None: return "ERROR" - root_material_id = cast(str, material_node.container.getMetaDataEntry("base_file", "")) - new_material_id = self.duplicateMaterialByRootId(root_material_id, new_base_id, new_metadata) - return new_material_id if new_material_id is not None else "ERROR" + return result + + ## Creates a duplicate of a material with the same GUID and base_file + # metadata. + # \param material_node The node representing the material to duplicate. + # \param new_base_id A new material ID for the base material. The IDs of + # the submaterials will be based off this one. If not provided, a material + # ID will be generated automatically. + # \param new_metadata Metadata for the new material. If not provided, this + # will be duplicated from the original material. + # \return The root material ID of the duplicate material. + @pyqtSlot("QVariant", result = str) + def duplicateMaterial(self, material_node: MaterialNode, new_base_id: Optional[str] = None, new_metadata: Optional[Dict[str, Any]] = None) -> str: + result = cura.CuraApplication.CuraApplication.getInstance().getMaterialManagementModel().duplicateMaterial(material_node, new_base_id, new_metadata) + if result is None: + return "ERROR" + return result # Create a new material by cloning Generic PLA for the current material diameter and generate a new GUID. # Returns the ID of the newly created material. diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py index f9af587293..a0b61e0b9b 100644 --- a/cura/Machines/Models/MaterialManagementModel.py +++ b/cura/Machines/Models/MaterialManagementModel.py @@ -73,20 +73,19 @@ class MaterialManagementModel(QObject): ## Creates a duplicate of a material with the same GUID and base_file # metadata. - # \param material_node The node representing the material to duplicate. + # \param base_file: The base file of the material to duplicate. # \param new_base_id A new material ID for the base material. The IDs of # the submaterials will be based off this one. If not provided, a material # ID will be generated automatically. # \param new_metadata Metadata for the new material. If not provided, this # will be duplicated from the original material. # \return The root material ID of the duplicate material. - @pyqtSlot("QVariant", result = str) - def duplicateMaterial(self, material_node: "MaterialNode", new_base_id: Optional[str] = None, new_metadata: Dict[str, Any] = None) -> Optional[str]: + def duplicateMaterialByBaseFile(self, base_file: str, new_base_id: Optional[str] = None, new_metadata: Dict[str, Any] = None) -> Optional[str]: container_registry = CuraContainerRegistry.getInstance() - root_materials = container_registry.findContainers(id = material_node.base_file) + root_materials = container_registry.findContainers(id = base_file) if not root_materials: - Logger.log("i", "Unable to duplicate the root material with ID {root_id}, because it doesn't exist.".format(root_id = material_node.base_file)) + Logger.log("i", "Unable to duplicate the root material with ID {root_id}, because it doesn't exist.".format(root_id = base_file)) return None root_material = root_materials[0] @@ -105,8 +104,8 @@ class MaterialManagementModel(QObject): new_containers = [new_root_material] # Clone all submaterials. - for container_to_copy in container_registry.findInstanceContainers(base_file = material_node.base_file): - if container_to_copy.getId() == material_node.base_file: + for container_to_copy in container_registry.findInstanceContainers(base_file = base_file): + if container_to_copy.getId() == base_file: continue # We already have that one. Skip it. new_id = new_base_id definition = container_to_copy.getMetaDataEntry("definition") @@ -129,12 +128,25 @@ class MaterialManagementModel(QObject): # If the duplicated material was favorite then the new material should also be added to the favorites. favorites_set = set(application.getPreferences().getValue("cura/favorite_materials").split(";")) - if material_node.base_file in favorites_set: + if base_file in favorites_set: favorites_set.add(new_base_id) application.getPreferences().setValue("cura/favorite_materials", ";".join(favorites_set)) return new_base_id + ## Creates a duplicate of a material with the same GUID and base_file + # metadata. + # \param material_node The node representing the material to duplicate. + # \param new_base_id A new material ID for the base material. The IDs of + # the submaterials will be based off this one. If not provided, a material + # ID will be generated automatically. + # \param new_metadata Metadata for the new material. If not provided, this + # will be duplicated from the original material. + # \return The root material ID of the duplicate material. + @pyqtSlot("QVariant", result = str) + def duplicateMaterial(self, material_node: "MaterialNode", new_base_id: Optional[str] = None, new_metadata: Dict[str, Any] = None) -> Optional[str]: + return self.duplicateMaterialByBaseFile(material_node.base_file, new_base_id, new_metadata) + ## Create a new material by cloning the preferred material for the current # material diameter and generate a new GUID. #