diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 32c5191c7c..7651cad930 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -322,6 +322,7 @@ class CuraApplication(QtApplication): path = Resources.getStoragePath(self.ResourceTypes.VariantInstanceContainer, file_name) if path: + instance.setPath(path) with SaveFile(path, "wt", -1, "utf-8") as f: f.write(data) @@ -346,6 +347,7 @@ class CuraApplication(QtApplication): elif stack_type == "extruder_train": path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name) if path: + stack.setPath(path) with SaveFile(path, "wt", -1, "utf-8") as f: f.write(data) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index c082c64da1..27a9bd90dd 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -167,6 +167,19 @@ class ContainerManager(QObject): return True + @pyqtSlot(str, str, result=str) + def getContainerMetaDataEntry(self, container_id, entry_name): + containers = self._container_registry.findContainers(None, id=container_id) + if not containers: + UM.Logger.log("w", "Could not get metadata of container %s because it was not found.", container_id) + return False + + result = containers[0].getMetaDataEntry(entry_name) + if result: + return result + else: + return "" + ## Set a metadata entry of the specified container. # # This will set the specified entry of the container's metadata to the specified @@ -577,6 +590,28 @@ class ContainerManager(QObject): return new_name + @pyqtSlot(str, result = str) + def duplicateMaterial(self, material_id): + containers = self._container_registry.findInstanceContainers(id=material_id) + if not containers: + UM.Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", material_id) + return "" + + # Ensure all settings are saved. + UM.Application.getInstance().saveSettings() + + # Create a new ID & container to hold the data. + new_id = self._container_registry.uniqueName(material_id) + container_type = type(containers[0]) # Could be either a XMLMaterialProfile or a InstanceContainer + duplicated_container = container_type(new_id) + + # Instead of duplicating we load the data from the basefile again. + # This ensures that the inheritance goes well and all "cut up" subclasses of the xmlMaterial profile + # are also correctly created. + with open(containers[0].getPath(), encoding="utf-8") as f: + duplicated_container.deserialize(f.read()) + self._container_registry.addContainer(duplicated_container) + # Factory function, used by QML @staticmethod def createContainerManager(engine, js_engine): diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index d2d7c1b0a2..b1f0afe52f 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -129,30 +129,24 @@ UM.ManagementPage enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId onClicked: Cura.MachineManager.setActiveMaterial(base.currentItem.id) }, - /* // apparently visible does not work on OS X - Button + // apparently visible does not work on OS X + /*Button { text: catalog.i18nc("@action:button", "Duplicate"); iconName: "list-add"; enabled: base.currentItem != null onClicked: { - var material_id = Cura.ContainerManager.duplicateContainer(base.currentItem.id) + var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file") + // We need to copy the base container instead of the specific variant. + var material_id = base_file == "" ? Cura.ContainerManager.duplicateMaterial(base.currentItem.id): Cura.ContainerManager.duplicateMaterial(base_file) if(material_id == "") { return } - if(Cura.MachineManager.filterQualityByMachine) - { - var quality_id = Cura.ContainerManager.duplicateContainer(Cura.MachineManager.activeQualityId) - Cura.ContainerManager.setContainerMetaDataEntry(quality_id, "material", material_id) - Cura.MachineManager.setActiveQuality(quality_id) - } - Cura.MachineManager.setActiveMaterial(material_id) } - visible: false; }, */ Button