diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index c376bb496c..b828e16daf 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -150,8 +150,9 @@ class PrinterOutputDevice(QObject, OutputDevice): @pyqtSlot(int) def setTargetBedTemperature(self, temperature): self._setTargetBedTemperature(temperature) - self._target_bed_temperature = temperature - self.targetBedTemperatureChanged.emit() + if self._target_bed_temperature != temperature: + self._target_bed_temperature = temperature + self.targetBedTemperatureChanged.emit() ## Time the print has been printing. # Note that timeTotal - timeElapsed should give time remaining. @@ -212,8 +213,9 @@ class PrinterOutputDevice(QObject, OutputDevice): # This simply sets the bed temperature, but ensures that a signal is emitted. # /param temperature temperature of the bed. def _setBedTemperature(self, temperature): - self._bed_temperature = temperature - self.bedTemperatureChanged.emit() + if self._bed_temperature != temperature: + self._bed_temperature = temperature + self.bedTemperatureChanged.emit() ## Get the target bed temperature if connected printer (if any) @pyqtProperty(int, notify = targetBedTemperatureChanged) @@ -228,8 +230,10 @@ class PrinterOutputDevice(QObject, OutputDevice): @pyqtSlot(int, int) def setTargetHotendTemperature(self, index, temperature): self._setTargetHotendTemperature(index, temperature) - self._target_hotend_temperatures[index] = temperature - self.targetHotendTemperaturesChanged.emit() + + if self._target_hotend_temperatures[index] != temperature: + self._target_hotend_temperatures[index] = temperature + self.targetHotendTemperaturesChanged.emit() ## Implementation function of setTargetHotendTemperature. # /param index Index of the hotend to set the temperature of @@ -251,8 +255,9 @@ class PrinterOutputDevice(QObject, OutputDevice): # /param index Index of the hotend # /param temperature temperature of the hotend (in deg C) def _setHotendTemperature(self, index, temperature): - self._hotend_temperatures[index] = temperature - self.hotendTemperaturesChanged.emit() + if self._hotend_temperatures[index] != temperature: + self._hotend_temperatures[index] = temperature + self.hotendTemperaturesChanged.emit() @pyqtProperty("QVariantList", notify = materialIdChanged) def materialIds(self): @@ -267,7 +272,6 @@ class PrinterOutputDevice(QObject, OutputDevice): self._material_ids[index] = material_id self.materialIdChanged.emit(index, material_id) - @pyqtProperty("QVariantList", notify = hotendIdChanged) def hotendIds(self): return self._hotend_ids @@ -302,8 +306,9 @@ class PrinterOutputDevice(QObject, OutputDevice): ## Set the connection state of this output device. # /param connection_state ConnectionState enum. def setConnectionState(self, connection_state): - self._connection_state = connection_state - self.connectionStateChanged.emit(self._id) + if self._connection_state != connection_state: + self._connection_state = connection_state + self.connectionStateChanged.emit(self._id) @pyqtProperty(str, notify = connectionTextChanged) def connectionText(self): @@ -351,6 +356,7 @@ class PrinterOutputDevice(QObject, OutputDevice): if self._head_z != z: self._head_z = z position_changed = True + if position_changed: self.headPositionChanged.emit() diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 27a9bd90dd..5be134c74b 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -610,6 +610,7 @@ class ContainerManager(QObject): # are also correctly created. with open(containers[0].getPath(), encoding="utf-8") as f: duplicated_container.deserialize(f.read()) + duplicated_container.setDirty(True) self._container_registry.addContainer(duplicated_container) # Factory function, used by QML diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index cd10348f2f..be8f5146c9 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -22,35 +22,6 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): super().__init__(container_id, *args, **kwargs) self._inherited_files = [] - ## Overridden from InstanceContainer - def duplicate(self, new_id, new_name = None): - base_file = self.getMetaDataEntry("base_file", None) - - if base_file != self.id: - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = base_file) - if containers: - new_basefile = containers[0].duplicate(self.getMetaDataEntry("brand") + "_" + new_id, new_name) - base_file = new_basefile.id - UM.Settings.ContainerRegistry.getInstance().addContainer(new_basefile) - - new_id = self.getMetaDataEntry("brand") + "_" + new_id + "_" + self.getDefinition().getId() - variant = self.getMetaDataEntry("variant") - if variant: - variant_containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = variant) - if variant_containers: - new_id += "_" + variant_containers[0].getName().replace(" ", "_") - has_base_file = True - else: - has_base_file = False - - new_id = UM.Settings.ContainerRegistry.getInstance().createUniqueName("material", self._id, new_id, "") - result = super().duplicate(new_id, new_name) - if has_base_file: - result.setMetaDataEntry("base_file", base_file) - else: - result.setMetaDataEntry("base_file", result.id) - return result - def getInheritedFiles(self): return self._inherited_files @@ -63,6 +34,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): 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(): return @@ -103,10 +75,17 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): # # basefile = self.getMetaDataEntry("base_file", self._id) #if basefile is self.id, this is a basefile. # for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile): - # container._dirty = True + # if not container.isReadOnly(): + # container.setDirty(True) ## Overridden from InstanceContainer + # base file: global settings + supported machines + # machine / variant combination: only changes for itself. def serialize(self): + if self._read_only: + Logger.log("w", "Serializing read-only container [%s], probably a programming error." % self.id) + return + registry = UM.Settings.ContainerRegistry.getInstance() base_file = self.getMetaDataEntry("base_file", "") @@ -114,7 +93,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): # Since we create an instance of XmlMaterialProfile for each machine and nozzle in the profile, # we should only serialize the "base" material definition, since that can then take care of # serializing the machine/nozzle specific profiles. - raise NotImplementedError("Cannot serialize non-root XML materials") + raise NotImplementedError("Ignoring serializing non-root XML materials, the data is contained in the base material") builder = ET.TreeBuilder() diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index b1f0afe52f..ef57b5af58 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -129,8 +129,7 @@ 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 + Button { text: catalog.i18nc("@action:button", "Duplicate"); iconName: "list-add"; @@ -148,7 +147,6 @@ UM.ManagementPage Cura.MachineManager.setActiveMaterial(material_id) } }, - */ Button { text: catalog.i18nc("@action:button", "Remove"); @@ -156,15 +154,13 @@ UM.ManagementPage enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) onClicked: confirmDialog.open() }, - /* // apparently visible does not work on OS X Button { text: catalog.i18nc("@action:button", "Import"); iconName: "document-import"; onClicked: importDialog.open(); - visible: false; + visible: true; }, - */ Button { text: catalog.i18nc("@action:button", "Export")