From 81f3422e36b22c9465780d099a6e73b6e407af5a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 02:02:14 +0200 Subject: [PATCH 01/61] Make settable_per_* properties read-only Contributes to CURA-2006 --- cura/CuraApplication.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5e78aeeed1..b08325b2dc 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -93,10 +93,10 @@ class CuraApplication(QtApplication): self._open_file_queue = [] # Files to open when plug-ins are loaded. # Need to do this before ContainerRegistry tries to load the machines - SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Any, default = True) - SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True) - SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True) - SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True) + SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Any, default = True, read_only = True) + SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True, read_only = True) + SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True, read_only = True) + SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True, read_only = True) SettingDefinition.addSupportedProperty("global_inherits_stack", DefinitionPropertyType.Function, default = "-1") SettingDefinition.addSettingType("extruder", None, str, Validator) From ab99100c5671a60b76ecf1d748db09dedf8af9b7 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 02:02:47 +0200 Subject: [PATCH 02/61] Introduce an empty quality_changes container Contributes to CURA-2006 --- cura/CuraApplication.py | 4 ++++ cura/Settings/MachineManager.py | 1 + 2 files changed, 5 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index b08325b2dc..fcd4eae829 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -190,6 +190,10 @@ class CuraApplication(QtApplication): empty_quality_container._id = "empty_quality" empty_quality_container.addMetaDataEntry("type", "quality") ContainerRegistry.getInstance().addContainer(empty_quality_container) + empty_quality_changes_container = copy.deepcopy(empty_container) + empty_quality_changes_container._id = "empty_quality_changes" + empty_quality_changes_container.addMetaDataEntry("type", "quality_changes") + ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) ContainerRegistry.getInstance().load() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 6a180593c5..de7b72bc84 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -47,6 +47,7 @@ class MachineManager(QObject): self._empty_variant_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_variant")[0] self._empty_material_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_material")[0] self._empty_quality_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality")[0] + self._empty_quality_changes_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality_changes")[0] Preferences.getInstance().addPreference("cura/active_machine", "") From d42f390ed6f93d3df77db1b7ae443d6eb404c980 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 02:03:57 +0200 Subject: [PATCH 03/61] Add the new empty quality_changes container to new machines Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index de7b72bc84..936e73b63d 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -383,7 +383,6 @@ class MachineManager(QObject): current_settings_instance_container.setDefinition(definitions[0]) container_registry.addContainer(current_settings_instance_container) - # If a definition is found, its a list. Should only have one item. new_global_stack.addContainer(definition) if variant_instance_container: new_global_stack.addContainer(variant_instance_container) @@ -391,6 +390,8 @@ class MachineManager(QObject): new_global_stack.addContainer(material_instance_container) if quality_instance_container: new_global_stack.addContainer(quality_instance_container) + + new_global_stack.addContainer(self._empty_quality_changes_container) new_global_stack.addContainer(current_settings_instance_container) ExtruderManager.getInstance().addMachineExtruders(definition, new_global_stack.getId()) From aa8561fec7aeb9a09b93c78ff8c2fb28b9686593 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 02:05:12 +0200 Subject: [PATCH 04/61] Remove globalPropertyChanged There should be no need for this if we properly store settings where they should be stored. Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 100 ++------------------------------ 1 file changed, 5 insertions(+), 95 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 936e73b63d..0b97ffe00c 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -26,6 +26,10 @@ class MachineManager(QObject): self._global_container_stack = None Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) + self.globalContainerChanged.connect(self.activeMaterialChanged) + self.globalContainerChanged.connect(self.activeVariantChanged) + self.globalContainerChanged.connect(self.activeQualityChanged) + self._active_stack_valid = None self._onGlobalContainerChanged() @@ -33,9 +37,7 @@ class MachineManager(QObject): self._onActiveExtruderStackChanged() ## When the global container is changed, active material probably needs to be updated. - self.globalContainerChanged.connect(self.activeMaterialChanged) - self.globalContainerChanged.connect(self.activeVariantChanged) - self.globalContainerChanged.connect(self.activeQualityChanged) + ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeMaterialChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeVariantChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeQualityChanged) @@ -197,107 +199,18 @@ class MachineManager(QObject): if old_index is not None: extruder_manager.setActiveExtruderIndex(old_index) - def _onGlobalPropertyChanged(self, key, property_name): - if property_name == "value": - ## We can get recursion issues. So we store a list of keys that we are still handling to prevent this. - if key in self._global_event_keys: - return - self._global_event_keys.add(key) - self.globalValueChanged.emit() - if self._active_container_stack and self._active_container_stack != self._global_container_stack: - # Make the global current settings mirror the stack values appropriate for this setting - if self._active_container_stack.getProperty("extruder_nr", "value") == int(self._active_container_stack.getProperty(key, "global_inherits_stack")): - new_value = self._active_container_stack.getProperty(key, "value") - self._global_container_stack.getTop().setProperty(key, "value", new_value) - # Global-only setting values should be set on all extruders and the global stack - if not self._global_container_stack.getProperty(key, "settable_per_extruder"): - extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) - target_stack_position = int(self._active_container_stack.getProperty(key, "global_inherits_stack")) - if target_stack_position == -1: # Prevent -1 from selecting wrong stack. - target_stack = self._active_container_stack - else: - target_stack = extruder_stacks[target_stack_position] - new_value = target_stack.getProperty(key, "value") - target_stack_has_user_value = target_stack.getTop().getInstance(key) != None - for extruder_stack in extruder_stacks: - if extruder_stack != target_stack: - if target_stack_has_user_value: - extruder_stack.getTop().setProperty(key, "value", new_value) - else: - # Remove from the value from the other stacks as well, unless the - # top value from the other stacklevels is different than the new value - for container in extruder_stack.getContainers(): - if container.__class__ == UM.Settings.InstanceContainer and container.getInstance(key) != None: - if container.getProperty(key, "value") != new_value: - # It could be that the setting needs to be removed instead of updated. - temp = extruder_stack - containers = extruder_stack.getContainers() - # Ensure we have the entire 'chain' - while temp.getNextStack(): - temp = temp.getNextStack() - containers.extend(temp.getContainers()) - instance_needs_removal = False - if len(containers) > 1: - for index in range(1, len(containers)): - deeper_container = containers[index] - if deeper_container.getProperty(key, "value") is None: - continue # Deeper container does not have the value, so continue. - if deeper_container.getProperty(key, "value") == new_value: - # Removal will result in correct value, so do that. - # We do this to prevent the reset from showing up unneeded. - instance_needs_removal = True - break - else: - # Container has the value, but it's not the same. Stop looking. - break - if instance_needs_removal: - extruder_stack.getTop().removeInstance(key) - else: - extruder_stack.getTop().setProperty(key, "value", new_value) - else: - # Check if we really need to remove something. - if extruder_stack.getProperty(key, "value") != new_value: - extruder_stack.getTop().removeInstance(key) - break - if self._global_container_stack.getProperty(key, "value") != new_value: - self._global_container_stack.getTop().setProperty(key, "value", new_value) - self._global_event_keys.remove(key) - if property_name == "global_inherits_stack": - if self._active_container_stack and self._active_container_stack != self._global_container_stack: - # Update the global user value when the "global_inherits_stack" function points to a different stack - extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) - target_stack_position = int(self._active_container_stack.getProperty(key, "global_inherits_stack")) - if target_stack_position == -1: # Prevent -1 from selecting wrong stack. - target_stack = self._active_container_stack - else: - target_stack = extruder_stacks[target_stack_position] - new_value = target_stack.getProperty(key, "value") - if self._global_container_stack.getProperty(key, "value") != new_value: - self._global_container_stack.getTop().setProperty(key, "value", new_value) - if property_name == "validationState": - if self._active_stack_valid: - changed_validation_state = self._active_container_stack.getProperty(key, property_name) - if changed_validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError): - self._active_stack_valid = False - self.activeValidationChanged.emit() - else: - has_errors = self._checkStackForErrors(self._active_container_stack) - if not has_errors: - self._active_stack_valid = True - self.activeValidationChanged.emit() def _onGlobalContainerChanged(self): if self._global_container_stack: self._global_container_stack.nameChanged.disconnect(self._onMachineNameChanged) self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) - self._global_container_stack.propertyChanged.disconnect(self._onGlobalPropertyChanged) material = self._global_container_stack.findContainer({"type": "material"}) material.nameChanged.disconnect(self._onMaterialNameChanged) @@ -314,7 +227,6 @@ class MachineManager(QObject): Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId()) self._global_container_stack.nameChanged.connect(self._onMachineNameChanged) self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) - self._global_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) material = self._global_container_stack.findContainer({"type": "material"}) material.nameChanged.connect(self._onMaterialNameChanged) @@ -325,11 +237,9 @@ class MachineManager(QObject): self.blurSettings.emit() # Ensure no-one has focus. if self._active_container_stack and self._active_container_stack != self._global_container_stack: self._active_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) - self._active_container_stack.propertyChanged.disconnect(self._onGlobalPropertyChanged) self._active_container_stack = ExtruderManager.getInstance().getActiveExtruderStack() if self._active_container_stack: self._active_container_stack.containersChanged.connect(self._onInstanceContainersChanged) - self._active_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) else: self._active_container_stack = self._global_container_stack self._active_stack_valid = not self._checkStackForErrors(self._active_container_stack) From 4de40534909efb0321d287414009226799604865 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 02:08:06 +0200 Subject: [PATCH 05/61] Properly implement "set as active extruder" menu entry Contributes to CURA-2006 --- resources/qml/Cura.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 5f45a062b8..7633b14239 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -150,7 +150,7 @@ UM.MainWindow MenuSeparator { } - MenuItem { text: "Set as Active Extruder" } + MenuItem { text: catalog.i18nc("@action:inmenu", "Set as Active Extruder"); onTriggered: Cura.ExtruderManager.setActiveExtruderIndex(model.index) } } onObjectAdded: settingsMenu.insertItem(index, object) onObjectRemoved: settingsMenu.removeItem(object) From 6eed25f145862c0e76fc07ff3cfa1e980ed46a72 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 02:09:02 +0200 Subject: [PATCH 06/61] Only write property changes to extruder stack if we actually should Now global settings are once again stored in the global stack Contributes to CURA-2006 --- resources/qml/Settings/SettingView.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 978e2dcaed..f79f074400 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -94,6 +94,7 @@ ScrollView { target: provider property: "containerStackId" + when: model.settable_per_extruder || (inheritStackProvider.properties.global_inherits_stack == -1 || inheritStackProvider.properties.global_inherits_stack == null) value: { if(inheritStackProvider.properties.global_inherits_stack == -1 || inheritStackProvider.properties.global_inherits_stack == null) @@ -127,7 +128,7 @@ ScrollView containerStackId: Cura.MachineManager.activeMachineId key: model.key ? model.key : "" - watchedProperties: [ "value", "enabled", "state", "validationState", "settable_per_extruder" ] + watchedProperties: [ "value", "enabled", "state", "validationState" ] storeIndex: 0 } From 95c3aa8251bbc6c166c1c87decbbb85111c25dce Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 02:10:28 +0200 Subject: [PATCH 07/61] Split ContainerManager::mergeContainer into a checking bit and a function that does the actual work Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 82be7c480f..a93c7ae96c 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -135,12 +135,11 @@ class ContainerManager(QObject): merge = containers[0] - if type(merge) != type(merge_into): + if not isinstance(merge, type(merge_into)): UM.Logger.log("w", "Cannot merge two containers of different types") return False - for key in merge.getAllKeys(): - merge_into.setProperty(key, "value", merge.getProperty(key, "value")) + self._performMerge(merge_into, merge) return True @@ -350,6 +349,22 @@ class ContainerManager(QObject): return { "status": "success", "message": "Successfully imported container {0}".format(container.getName()) } + # Factory function, used by QML + @staticmethod + def createContainerManager(engine, js_engine): + return ContainerManager() + + def _performMerge(self, merge_into, merge): + assert isinstance(merge, type(merge_into)) + + if merge == merge_into: + return + + for key in merge.getAllKeys(): + merge_into.setProperty(key, "value", merge.getProperty(key, "value")) + + merge.clear() + def _updateContainerNameFilters(self): self._container_name_filters = {} for plugin_id, container_type in UM.Settings.ContainerRegistry.getContainerTypes(): @@ -393,8 +408,3 @@ class ContainerManager(QObject): name_filter = "{0} ({1})".format(mime_type.comment, suffix_list) self._container_name_filters[name_filter] = entry - - # Factory function, used by QML - @staticmethod - def createContainerManager(engine, js_engine): - return ContainerManager() From 0934ae70a8533765b03e34b92b9cdec78a50117a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 02:11:35 +0200 Subject: [PATCH 08/61] Introduce clearUserContainers and updateQualityChanges methods in ContainerManager They are moved from MachineManager which is really getting too large and complicated. Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index a93c7ae96c..ad9c61366f 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -14,6 +14,8 @@ import UM.Platform import UM.MimeTypeDatabase import UM.Logger +from .ExtruderManager import ExtruderManager + from UM.MimeTypeDatabase import MimeTypeNotFoundError from UM.i18n import i18nCatalog @@ -349,6 +351,36 @@ class ContainerManager(QObject): return { "status": "success", "message": "Successfully imported container {0}".format(container.getName()) } + @pyqtSlot(result = bool) + def updateQualityChanges(self): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + + containers_to_merge = [] + + global_quality_changes = global_stack.findContainer(type = "quality_changes") + if not global_quality_changes or global_quality_changes.isReadOnly(): + return False + + containers_to_merge.append((global_quality_changes, global_stack.getTop())) + + for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): + quality_changes = extruder.findContainer(type = "quality_changes") + if not quality_changes or quality_changes.isReadOnly(): + return False + + containers_to_merge.append((quality_changes, extruder.getTop())) + + for merge_into, merge in containers_to_merge: + self._performMerge(merge_into, merge) + + @pyqtSlot() + def clearUserContainers(self): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + + for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): + extruder.getTop().clear() + + global_stack.getTop().clear() # Factory function, used by QML @staticmethod def createContainerManager(engine, js_engine): From 9ef709962ff3239261ca42bc26334d61f797cf83 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 02:12:32 +0200 Subject: [PATCH 09/61] Start implementing a createQualityChanges method in ContainerManager It will be used to create the quality change containers from the existing user containers. Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index ad9c61366f..7a6d5b8184 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -381,6 +381,28 @@ class ContainerManager(QObject): extruder.getTop().clear() global_stack.getTop().clear() + + @pyqtSlot() + def createQualityChanges(self): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + + user_container = global_stack.getTop() + quality_container = global_stack.findContainer(type = "quality") + if not quality_container: + return + + unique_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(quality_container.getName()) + unique_id = unique_name.lower() + unique_id.replace(" ", "_") + + quality_changes = user_container.duplicate() + quality_changes.setMetaDataEntry("type", "quality_changes") + quality_changes.setMetaDataEntry("quality_base", quality_container.getId()) + + UM.Settings.ContainerRegistry.getInstance().addContainer(quality_changes) + + + # Factory function, used by QML @staticmethod def createContainerManager(engine, js_engine): From 4eb4a90ded2d629b40f64b771924e13cfcd00a1d Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 02:13:24 +0200 Subject: [PATCH 10/61] Call the new clearUserContainers/updateQualityChanges from the relevant actions Contributes to CURA-2006 --- resources/qml/Actions.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index ed88433e33..3d08b133cc 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -122,7 +122,7 @@ Item id: updateProfileAction; enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings"); - onTriggered: Cura.MachineManager.updateQualityContainerFromUserContainer() + onTriggered: Cura.ContainerManager.updateQualityChanges(); } Action @@ -130,7 +130,7 @@ Item id: resetProfileAction; enabled: Cura.MachineManager.hasUserSettings text: catalog.i18nc("@action:inmenu menubar:profile","&Discard current settings"); - onTriggered: Cura.MachineManager.clearUserSettings(); + onTriggered: Cura.ContainerManager.clearUserContainers(); } Action From b6d0c40852a54bc11c5c829cca5319e39e173c9b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:32:38 +0200 Subject: [PATCH 11/61] Store "quality_changes" type containers in the quality directory Contributes to CURA-2006 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index fcd4eae829..091b8fe269 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -314,7 +314,7 @@ class CuraApplication(QtApplication): path = None if instance_type == "material": path = Resources.getStoragePath(self.ResourceTypes.MaterialInstanceContainer, file_name) - elif instance_type == "quality": + elif instance_type == "quality" or instance_type == "quality_changes": path = Resources.getStoragePath(self.ResourceTypes.QualityInstanceContainer, file_name) elif instance_type == "user": path = Resources.getStoragePath(self.ResourceTypes.UserInstanceContainer, file_name) From ec383b46b95ddee10b7b4b843395bb76255574f4 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:33:35 +0200 Subject: [PATCH 12/61] Emit blurSettings for ContainerManager::merge/clear user containers Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 7a6d5b8184..bec04af92e 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -15,6 +15,7 @@ import UM.MimeTypeDatabase import UM.Logger from .ExtruderManager import ExtruderManager +from .MachineManager import MachineManager from UM.MimeTypeDatabase import MimeTypeNotFoundError @@ -359,13 +360,17 @@ class ContainerManager(QObject): global_quality_changes = global_stack.findContainer(type = "quality_changes") if not global_quality_changes or global_quality_changes.isReadOnly(): + UM.Logger.log("e", "Could not update quality of a nonexistant or read only quality profile") return False + MachineManager.getInstance().blurSettings.emit() + containers_to_merge.append((global_quality_changes, global_stack.getTop())) for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): quality_changes = extruder.findContainer(type = "quality_changes") if not quality_changes or quality_changes.isReadOnly(): + UM.Logger.log("e", "Could not update quality of a nonexistant or read only quality profile") return False containers_to_merge.append((quality_changes, extruder.getTop())) @@ -377,6 +382,8 @@ class ContainerManager(QObject): def clearUserContainers(self): global_stack = UM.Application.getInstance().getGlobalContainerStack() + MachineManager.getInstance().blurSettings.emit() + for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): extruder.getTop().clear() From 7613274686adeff933db8d791bbf47c14f18306e Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:34:41 +0200 Subject: [PATCH 13/61] Properly hide link icon if setting is not settable per extruder Contributes to CURA-2006 --- resources/qml/Settings/SettingItem.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index dae9953690..a091b55c8b 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -27,7 +27,6 @@ Item { // Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise) property var state: propertyProvider.properties.state - property var settablePerExtruder: propertyProvider.properties.settable_per_extruder property var stackLevels: propertyProvider.stackLevels property var stackLevel: stackLevels[0] @@ -138,7 +137,7 @@ Item { { id: linkedSettingIcon; - visible: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId && base.settablePerExtruder != "True" && base.showLinkedSettingIcon + visible: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId && !definition.settable_per_extruder && base.showLinkedSettingIcon height: parent.height; width: height; From 9d0acf5b036ee4749af0034969c683e39cc547d3 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:35:01 +0200 Subject: [PATCH 14/61] Properly send global settings to the global stack Contributes to CURA-2006 --- resources/qml/Settings/SettingView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index f79f074400..79925e629f 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -94,7 +94,7 @@ ScrollView { target: provider property: "containerStackId" - when: model.settable_per_extruder || (inheritStackProvider.properties.global_inherits_stack == -1 || inheritStackProvider.properties.global_inherits_stack == null) + when: model.settable_per_extruder || (inheritStackProvider.properties.global_inherits_stack != -1 && inheritStackProvider.properties.global_inherits_stack != null) value: { if(inheritStackProvider.properties.global_inherits_stack == -1 || inheritStackProvider.properties.global_inherits_stack == null) From 70dee38c959db4a772f6ccf7277e02b33d1afe3d Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:35:33 +0200 Subject: [PATCH 15/61] Show quality_changes instance containers for custom containers in the profile menu Contributes to CURA-2006 --- resources/qml/Menus/ProfileMenu.qml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 68f83305d7..c99d6a181d 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -7,7 +7,7 @@ import QtQuick.Controls 1.1 import UM 1.2 as UM import Cura 1.0 as Cura - Menu +Menu { id: menu @@ -15,7 +15,7 @@ import Cura 1.0 as Cura { model: UM.InstanceContainersModel { - filter: menu.getFilter({ "read_only": true }); + filter: menu.getFilter({ "type": "quality" }); } MenuItem @@ -38,7 +38,7 @@ import Cura 1.0 as Cura id: customProfileInstantiator model: UM.InstanceContainersModel { - filter: menu.getFilter({ "read_only": false }); + filter: menu.getFilter({ "type": "quality_changes", "extruder": null }); onModelReset: customSeparator.visible = rowCount() > 0 } @@ -76,7 +76,6 @@ import Cura 1.0 as Cura function getFilter(initial_conditions) { var result = initial_conditions; - result.type = "quality" if(Cura.MachineManager.filterQualityByMachine) { From b76ebbb8508d58a5b8aa07917e3953c6ea21f4b5 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:36:39 +0200 Subject: [PATCH 16/61] Ensure we have an empty quality changes container in the extruder stack Contributes to CURA-2006 --- cura/Settings/ExtruderManager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 71bd58ded5..8861334237 100644 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -235,6 +235,9 @@ class ExtruderManager(QObject): container_stack.addContainer(quality) + empty_quality_changes = container_registry.findInstanceContainers(id = "empty_quality_changes")[0] + container_stack.addContainer(empty_quality_changes) + user_profile = container_registry.findInstanceContainers(type = "user", extruder = extruder_stack_id) if user_profile: # There was already a user profile, loaded from settings. user_profile = user_profile[0] From 2ee2bc734831eeefcec6c48da3f7ddc04d928be2 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:37:15 +0200 Subject: [PATCH 17/61] Properly implement ContainerManager::createQualityChanges Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 39 +++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index bec04af92e..d58b111be9 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -389,26 +389,51 @@ class ContainerManager(QObject): global_stack.getTop().clear() - @pyqtSlot() + @pyqtSlot(result = bool) def createQualityChanges(self): global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack: + return False - user_container = global_stack.getTop() quality_container = global_stack.findContainer(type = "quality") if not quality_container: - return + UM.Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId()) + return False + + MachineManager.getInstance().blurSettings.emit() unique_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(quality_container.getName()) unique_id = unique_name.lower() unique_id.replace(" ", "_") - quality_changes = user_container.duplicate() - quality_changes.setMetaDataEntry("type", "quality_changes") - quality_changes.setMetaDataEntry("quality_base", quality_container.getId()) + stacks = [ s for s in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()) ] + stacks.insert(0, global_stack) - UM.Settings.ContainerRegistry.getInstance().addContainer(quality_changes) + for stack in stacks: + user_container = stack.getTop() + quality_container = stack.findContainer(type = "quality") + quality_changes_container = stack.findContainer(type = "quality_changes") + if not quality_container or not quality_changes_container: + UM.Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId()) + return False + new_quality_changes = user_container.duplicate(stack.getId() + "_" + unique_id, unique_name) + new_quality_changes.setMetaDataEntry("type", "quality_changes") + new_quality_changes.addMetaDataEntry("quality", quality_container.getId()) + if not global_stack.getMetaDataEntry("has_machine_quality"): + new_quality_changes.setDefinition(UM.Settings.ContainerRegistry.getInstance().findContainers(id = "fdmprinter")[0]) + + if global_stack.getMetaDataEntry("has_materials"): + material = stack.findContainer(type = "material") + new_quality_changes.addMetaDataEntry("material", material.getId()) + + UM.Settings.ContainerRegistry.getInstance().addContainer(new_quality_changes) + + stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_quality_changes) + stack.getTop().clear() + + return True # Factory function, used by QML @staticmethod From 6d49fb87afe9420edb60b4fa79454705a627f381 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:38:19 +0200 Subject: [PATCH 18/61] Use ContainerManager::createQualityChanges when creating a quality from current settings Contributes to CURA-2006 --- resources/qml/Cura.qml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 7633b14239..02dcd10897 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -459,7 +459,8 @@ UM.MainWindow target: Cura.Actions.addProfile onTriggered: { - Cura.MachineManager.newQualityContainerFromQualityAndUser(); +// Cura.MachineManager.newQualityContainerFromQualityAndUser(); + Cura.ContainerManager.createQualityChanges(); preferences.setPage(4); preferences.show(); @@ -764,6 +765,10 @@ UM.MainWindow addMachineDialog.visible = true addMachineDialog.firstRun = false } + onClearAllFocus: + { + contentItem.focus = true + } } Timer From 10de07c08ec2494227dc56d2e00b96d9d82d91a8 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:39:09 +0200 Subject: [PATCH 19/61] Remove some code that was moved to ContainerManager Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0b97ffe00c..265e3d0bc1 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -438,16 +438,6 @@ class MachineManager(QObject): if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value: extruder_stack.getTop().setProperty(key, "value", new_value) - @pyqtSlot(result = str) - def newQualityContainerFromQualityAndUser(self): - new_container_id = self.duplicateContainer(self.activeQualityId) - if new_container_id == "": - return - self.blurSettings.emit() - self.updateQualityContainerFromUserContainer(new_container_id) - self.setActiveQuality(new_container_id) - return new_container_id - @pyqtSlot(str, result=str) def duplicateContainer(self, container_id): if not self._active_container_stack: @@ -513,29 +503,6 @@ class MachineManager(QObject): self.setActiveQuality(containers[0].getId()) self.activeQualityChanged.emit() - @pyqtSlot(str) - @pyqtSlot() - def updateQualityContainerFromUserContainer(self, quality_id = None): - if not self._active_container_stack: - return - - if quality_id: - quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id, type = "quality") - if quality: - quality = quality[0] - else: - quality = self._active_container_stack.findContainer({"type": "quality"}) - - if not quality: - return - - user_settings = self._active_container_stack.getTop() - - for key in user_settings.getAllKeys(): - quality.setProperty(key, "value", user_settings.getProperty(key, "value")) - self.clearUserSettings() # As all users settings are noq a quality, remove them. - - @pyqtSlot(str) def setActiveMaterial(self, material_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = material_id) From 5361efcf2c335791f9e5d403ec0a872e4ff0d114 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:39:52 +0200 Subject: [PATCH 20/61] Return the name/id of the quality changes container if it is set for activeQuality Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 265e3d0bc1..6a3c50b53b 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -404,6 +404,9 @@ class MachineManager(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityName(self): if self._active_container_stack: + quality = self._active_container_stack.findContainer({"type": "quality_changes"}) + if quality and quality != self._empty_quality_changes_container: + return quality.getName() quality = self._active_container_stack.findContainer({"type": "quality"}) if quality: return quality.getName() @@ -411,8 +414,11 @@ class MachineManager(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(self): - if self._active_container_stack: - quality = self._active_container_stack.findContainer({"type": "quality"}) + if self._global_container_stack: + quality = self._global_container_stack.findContainer({"type": "quality_changes"}) + if quality and quality != self._empty_quality_changes_container: + return quality.getId() + quality = self._global_container_stack.findContainer({"type": "quality"}) if quality: return quality.getId() return "" From e2045cdb7f7ec58730bf6f2b1ef2233847637dda Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:40:16 +0200 Subject: [PATCH 21/61] Remove obsolete container switcheroo Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 6a3c50b53b..38b4e80e80 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -248,16 +248,7 @@ class MachineManager(QObject): def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") - if self._active_container_stack and self._active_container_stack != self._global_container_stack: - if int(self._active_container_stack.getProperty("extruder_nr", "value")) == 0: - global_container = self._global_container_stack.findContainer({"type": container_type}) - if global_container and global_container != container: - container_index = self._global_container_stack.getContainerIndex(global_container) - self._global_container_stack.replaceContainer(container_index, container) - for key in container.getAllKeys(): - # Make sure the values in this profile are distributed to other stacks if necessary - self._onGlobalPropertyChanged(key, "value") if container_type == "material": self.activeMaterialChanged.emit() From d150acb79c95122384a197b847e11b34333db9b5 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:41:01 +0200 Subject: [PATCH 22/61] Change setActiveQuality to set quality of extruders & global and also set change containers Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 75 ++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 38b4e80e80..3b239ce770 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -545,32 +545,65 @@ class MachineManager(QObject): @pyqtSlot(str) def setActiveQuality(self, quality_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id) - if not containers or not self._active_container_stack: + if not containers or not self._global_container_stack: return - old_quality = self._active_container_stack.findContainer({"type": "quality"}) - if old_quality and old_quality != containers[0]: - old_quality.nameChanged.disconnect(self._onQualityNameChanged) + quality_container = None + quality_changes_container = self._empty_quality_changes_container - quality_index = self._active_container_stack.getContainerIndex(old_quality) + container_type = containers[0].getMetaDataEntry("type") - self._active_container_stack.replaceContainer(quality_index, containers[0]) - - containers[0].nameChanged.connect(self._onQualityNameChanged) - - if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: - # Ask the user if the user profile should be cleared or not (discarding the current settings) - # In Simple Mode we assume the user always wants to keep the (limited) current settings - details = catalog.i18nc("@label", "You made changes to the following setting(s):") - user_settings = self._active_container_stack.getTop().findInstances(**{}) - for setting in user_settings: - details = details + "\n " + setting.definition.label - - Application.getInstance().messageBox(catalog.i18nc("@window:title", "Switched profiles"), catalog.i18nc("@label", "Do you want to transfer your changed settings to this profile?"), - catalog.i18nc("@label", "If you transfer your settings they will override settings in the profile."), details, - buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._keepUserSettingsDialogCallback) + if container_type == "quality": + quality_container = containers[0] + elif container_type == "quality_changes": + quality_changes_container = containers[0] + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_changes_container.getMetaDataEntry("quality")) + if not containers: + Logger.log("e", "Could not find quality %s for changes %s, not changing quality", quality_changes_container.getMetaDataEntry("quality"), quality_changes_container.getId()) + return + quality_container = containers[0] else: - Logger.log("w", "While trying to set the active quality, no quality was found to replace.") + Logger.log("e", "Tried to set quality to a container that is not of the right type") + return + + stacks = [ s for s in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()) ] + stacks.insert(0, self._global_container_stack) + + for stack in stacks: + extruder_id = stack.getId() if stack != self._global_container_stack else None + stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = quality_container.getName(), extruder = extruder_id) + if not stack_quality: + stack_quality = quality_container + else: + stack_quality = stack_quality[0] + + if quality_changes_container != self._empty_quality_changes_container: + stack_quality_changes = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = quality_changes_container.getName(), extruder = extruder_id)[0] + else: + stack_quality_changes = self._empty_quality_changes_container + + old_quality = stack.findContainer(type = "quality") + old_quality.nameChanged.disconnect(self._onQualityNameChanged) + old_changes = stack.findContainer(type = "quality_changes") + old_changes.nameChanged.disconnect(self._onQualityNameChanged) + + stack.replaceContainer(stack.getContainerIndex(old_quality), stack_quality) + stack.replaceContainer(stack.getContainerIndex(old_changes), stack_quality_changes) + + stack_quality.nameChanged.connect(self._onQualityNameChanged) + stack_quality_changes.nameChanged.connect(self._onQualityNameChanged) + + if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: + # Ask the user if the user profile should be cleared or not (discarding the current settings) + # In Simple Mode we assume the user always wants to keep the (limited) current settings + details = catalog.i18nc("@label", "You made changes to the following setting(s):") + user_settings = self._active_container_stack.getTop().findInstances(**{}) + for setting in user_settings: + details = details + "\n " + setting.definition.label + + Application.getInstance().messageBox(catalog.i18nc("@window:title", "Switched profiles"), catalog.i18nc("@label", "Do you want to transfer your changed settings to this profile?"), + catalog.i18nc("@label", "If you transfer your settings they will override settings in the profile."), details, + buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._keepUserSettingsDialogCallback) def _keepUserSettingsDialogCallback(self, button): if button == QMessageBox.Yes: From 354a467d8ef0c948533b9da35e3b62a3bcc0700c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:51:43 +0200 Subject: [PATCH 23/61] Fix circular import bullcrap Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index d58b111be9..528248f7ae 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -14,8 +14,7 @@ import UM.Platform import UM.MimeTypeDatabase import UM.Logger -from .ExtruderManager import ExtruderManager -from .MachineManager import MachineManager +import cura.Settings from UM.MimeTypeDatabase import MimeTypeNotFoundError @@ -363,11 +362,11 @@ class ContainerManager(QObject): UM.Logger.log("e", "Could not update quality of a nonexistant or read only quality profile") return False - MachineManager.getInstance().blurSettings.emit() + cura.Settings.MachineManager.getInstance().blurSettings.emit() containers_to_merge.append((global_quality_changes, global_stack.getTop())) - for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): + for extruder in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): quality_changes = extruder.findContainer(type = "quality_changes") if not quality_changes or quality_changes.isReadOnly(): UM.Logger.log("e", "Could not update quality of a nonexistant or read only quality profile") @@ -382,9 +381,9 @@ class ContainerManager(QObject): def clearUserContainers(self): global_stack = UM.Application.getInstance().getGlobalContainerStack() - MachineManager.getInstance().blurSettings.emit() + cura.Settings.MachineManager.getInstance().blurSettings.emit() - for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): + for extruder in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): extruder.getTop().clear() global_stack.getTop().clear() @@ -400,13 +399,13 @@ class ContainerManager(QObject): UM.Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId()) return False - MachineManager.getInstance().blurSettings.emit() + cura.Settings.MachineManager.getInstance().blurSettings.emit() unique_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(quality_container.getName()) unique_id = unique_name.lower() unique_id.replace(" ", "_") - stacks = [ s for s in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()) ] + stacks = [ s for s in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()) ] stacks.insert(0, global_stack) for stack in stacks: From 324d1415d7fd12970c23b945599db11282e0aa8e Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 17:55:16 +0200 Subject: [PATCH 24/61] Fix updating active quality Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 3 +++ cura/Settings/MachineManager.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 528248f7ae..797b5d7cec 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -377,6 +377,8 @@ class ContainerManager(QObject): for merge_into, merge in containers_to_merge: self._performMerge(merge_into, merge) + cura.Settings.MachineManager.getInstance().activeQualityChanged.emit() + @pyqtSlot() def clearUserContainers(self): global_stack = UM.Application.getInstance().getGlobalContainerStack() @@ -432,6 +434,7 @@ class ContainerManager(QObject): stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_quality_changes) stack.getTop().clear() + cura.Settings.MachineManager.getInstance().activeQualityChanged.emit() return True # Factory function, used by QML diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 3b239ce770..e1cc784d9e 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -605,6 +605,8 @@ class MachineManager(QObject): catalog.i18nc("@label", "If you transfer your settings they will override settings in the profile."), details, buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._keepUserSettingsDialogCallback) + self.activeQualityChanged.emit() + def _keepUserSettingsDialogCallback(self, button): if button == QMessageBox.Yes: # Yes, keep the settings in the user profile with this profile From 7b9c982c62d4d54dc0ec15ea00505d4f7610504c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 18:04:32 +0200 Subject: [PATCH 25/61] Properly fix machinemanager access Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 797b5d7cec..c340815212 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -362,7 +362,7 @@ class ContainerManager(QObject): UM.Logger.log("e", "Could not update quality of a nonexistant or read only quality profile") return False - cura.Settings.MachineManager.getInstance().blurSettings.emit() + UM.Application.getInstance().getMachineManager().blurSettings.emit() containers_to_merge.append((global_quality_changes, global_stack.getTop())) @@ -377,13 +377,13 @@ class ContainerManager(QObject): for merge_into, merge in containers_to_merge: self._performMerge(merge_into, merge) - cura.Settings.MachineManager.getInstance().activeQualityChanged.emit() + UM.Application.getInstance().getMachineManager().activeQualityChanged.emit() @pyqtSlot() def clearUserContainers(self): global_stack = UM.Application.getInstance().getGlobalContainerStack() - cura.Settings.MachineManager.getInstance().blurSettings.emit() + UM.Application.getInstance().getMachineManager().blurSettings.emit() for extruder in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): extruder.getTop().clear() @@ -401,7 +401,7 @@ class ContainerManager(QObject): UM.Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId()) return False - cura.Settings.MachineManager.getInstance().blurSettings.emit() + UM.Application.getInstance().getMachineManager().blurSettings.emit() unique_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(quality_container.getName()) unique_id = unique_name.lower() @@ -434,7 +434,7 @@ class ContainerManager(QObject): stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_quality_changes) stack.getTop().clear() - cura.Settings.MachineManager.getInstance().activeQualityChanged.emit() + UM.Application.getInstance().getMachineManager().activeQualityChanged.emit() return True # Factory function, used by QML From bc8c55f8fbef4a30c4f32ee532ead5662dc5b2ad Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 18:05:45 +0200 Subject: [PATCH 26/61] Properly return True in updateQualityChanges Since it is declared as returning bool Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index c340815212..c23823d71f 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -379,6 +379,8 @@ class ContainerManager(QObject): UM.Application.getInstance().getMachineManager().activeQualityChanged.emit() + return True + @pyqtSlot() def clearUserContainers(self): global_stack = UM.Application.getInstance().getGlobalContainerStack() From 4a02a9d1e3b6e3e6dfa85ba76444fc4fd4e25ce5 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 4 Aug 2016 18:11:36 +0200 Subject: [PATCH 27/61] Fix updating changed state for all stacks Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index e1cc784d9e..03268fb457 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -211,6 +211,7 @@ class MachineManager(QObject): if self._global_container_stack: self._global_container_stack.nameChanged.disconnect(self._onMachineNameChanged) self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) + self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged) material = self._global_container_stack.findContainer({"type": "material"}) material.nameChanged.disconnect(self._onMaterialNameChanged) @@ -227,6 +228,7 @@ class MachineManager(QObject): Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId()) self._global_container_stack.nameChanged.connect(self._onMachineNameChanged) self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) + self._global_container_stack.propertyChanged.connect(self._onPropertyChanged) material = self._global_container_stack.findContainer({"type": "material"}) material.nameChanged.connect(self._onMaterialNameChanged) @@ -237,9 +239,11 @@ class MachineManager(QObject): self.blurSettings.emit() # Ensure no-one has focus. if self._active_container_stack and self._active_container_stack != self._global_container_stack: self._active_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) + self._active_container_stack.propertyChanged.disconnect(self._onPropertyChanged) self._active_container_stack = ExtruderManager.getInstance().getActiveExtruderStack() if self._active_container_stack: self._active_container_stack.containersChanged.connect(self._onInstanceContainersChanged) + self._active_container_stack.propertyChanged.connect(self._onPropertyChanged) else: self._active_container_stack = self._global_container_stack self._active_stack_valid = not self._checkStackForErrors(self._active_container_stack) @@ -248,8 +252,6 @@ class MachineManager(QObject): def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") - - if container_type == "material": self.activeMaterialChanged.emit() elif container_type == "variant": @@ -257,6 +259,9 @@ class MachineManager(QObject): elif container_type == "quality": self.activeQualityChanged.emit() + def _onPropertyChanged(self, key, property_name): + self.activeStackChanged.emit() + @pyqtSlot(str) def setActiveMachine(self, stack_id): containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = stack_id) @@ -333,11 +338,17 @@ class MachineManager(QObject): ## Check if the global_container has instances in the user container @pyqtProperty(bool, notify = activeStackChanged) def hasUserSettings(self): - if not self._active_container_stack: + if not self._global_container_stack: return False - user_settings = self._active_container_stack.getTop().findInstances(**{}) - return len(user_settings) != 0 + if self._global_container_stack.getTop().findInstances(): + return True + + for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()): + if stack.getTop().findInstances(): + return True + + return False ## Check if the global profile does not contain error states # Note that the _active_stack_valid is cached due to performance issues From b894e3888c40ba103ddbaf1039da14f0468bbef7 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 10:55:25 +0200 Subject: [PATCH 28/61] Introduce a quality_type metadata entry that can be used to distinguish qualities Since we want the profile to be selected based on material and we have profiles like "ABS Normal" and "PLA Normal" we need some way to make sure we select the same. Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 2 +- resources/quality/high.inst.cfg | 1 + resources/quality/low.inst.cfg | 1 + resources/quality/normal.inst.cfg | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index c23823d71f..b1cc060c23 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -422,7 +422,7 @@ class ContainerManager(QObject): new_quality_changes = user_container.duplicate(stack.getId() + "_" + unique_id, unique_name) new_quality_changes.setMetaDataEntry("type", "quality_changes") - new_quality_changes.addMetaDataEntry("quality", quality_container.getId()) + new_quality_changes.addMetaDataEntry("quality", quality_container.getMetaDataEntry("quality_type")) if not global_stack.getMetaDataEntry("has_machine_quality"): new_quality_changes.setDefinition(UM.Settings.ContainerRegistry.getInstance().findContainers(id = "fdmprinter")[0]) diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index b4498c6c8b..ec3ab18fd6 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +quality_type = high weight = -3 [values] diff --git a/resources/quality/low.inst.cfg b/resources/quality/low.inst.cfg index d34a7c6461..787325c27c 100644 --- a/resources/quality/low.inst.cfg +++ b/resources/quality/low.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +quality_type = low weight = -1 [values] diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index 417c7c700f..cfd70de49c 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +quality_type = normal weight = -2 [values] From e2a4aeb8ff316f0166778a00a4a3c8710a50bc1a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 10:57:12 +0200 Subject: [PATCH 29/61] Use the new quality_type when setting the active quality Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 03268fb457..209bae395a 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -199,14 +199,6 @@ class MachineManager(QObject): if old_index is not None: extruder_manager.setActiveExtruderIndex(old_index) - - - - - - - - def _onGlobalContainerChanged(self): if self._global_container_stack: self._global_container_stack.nameChanged.disconnect(self._onMachineNameChanged) @@ -577,14 +569,29 @@ class MachineManager(QObject): Logger.log("e", "Tried to set quality to a container that is not of the right type") return + quality_type = quality_container.getMetaDataEntry("quality_type") + if not quality_type: + quality_type = quality_changes_container.getName() + stacks = [ s for s in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()) ] stacks.insert(0, self._global_container_stack) for stack in stacks: extruder_id = stack.getId() if stack != self._global_container_stack else None - stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = quality_container.getName(), extruder = extruder_id) + + criteria = { "quality_type": quality_type, "extruder": extruder_id } + + if self._global_container_stack.getMetaDataEntry("has_machine_quality"): + material = stack.findContainer(type = "material") + criteria["material"] = material.getId() + + stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) if not stack_quality: - stack_quality = quality_container + criteria.pop("extruder") + stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) + if not stack_quality: + stack_quality = quality_container + stack_quality = stack_quality[0] else: stack_quality = stack_quality[0] From 450dcac394902f078184aa8f3c3ffa188db42163 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 10:57:42 +0200 Subject: [PATCH 30/61] Fix "keep current settings" dialog so it properly clears on "No" Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 209bae395a..bfedc189ba 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -631,7 +631,12 @@ class MachineManager(QObject): pass elif button == QMessageBox.No: # No, discard the settings in the user profile - self.clearUserSettings() + global_stack = Application.getInstance().getGlobalContainerStack() + + for extruder in ExtruderManager.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): + extruder.getTop().clear() + + global_stack.getTop().clear() @pyqtProperty(str, notify = activeVariantChanged) def activeVariantName(self): From 6de7d0170a584f4bc73ba20195ac8e6a80027a9d Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 10:58:44 +0200 Subject: [PATCH 31/61] Expose quality changes id and quality type and make the profile menu work correctly Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 16 ++++++++++++++++ resources/qml/Menus/ProfileMenu.qml | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index bfedc189ba..8c2466762c 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -417,6 +417,22 @@ class MachineManager(QObject): return quality.getId() return "" + @pyqtProperty(str, notify = activeQualityChanged) + def activeQualityType(self): + if self._global_container_stack: + quality = self._global_container_stack.findContainer(type = "quality") + if quality: + return quality.getMetaDataEntry("quality_type") + return "" + + @pyqtProperty(str, notify = activeQualityChanged) + def activeQualityChangesId(self): + if self._global_container_stack: + changes = self._global_container_stack.findContainer(type = "quality_changes") + if changes: + return changes.getId() + return "" + ## Check if a container is read_only @pyqtSlot(str, result = bool) def isReadOnly(self, container_id): diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index c99d6a181d..93cba6ab12 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -22,7 +22,7 @@ Menu { text: model.name checkable: true - checked: Cura.MachineManager.activeQualityId == model.id + checked: Cura.MachineManager.activeQualityChangesId == "empty_quality_changes" && Cura.MachineManager.activeQualityType == model.metadata.quality_type exclusiveGroup: group onTriggered: Cura.MachineManager.setActiveQuality(model.id) } @@ -38,7 +38,7 @@ Menu id: customProfileInstantiator model: UM.InstanceContainersModel { - filter: menu.getFilter({ "type": "quality_changes", "extruder": null }); + filter: { "type": "quality_changes", "extruder": null, "definition": Cura.MachineManager.filterQualityByMachine ? Cura.MachineManager.activeDefinitionId : "fdmprinter" }; onModelReset: customSeparator.visible = rowCount() > 0 } From 578191bb8a8b1b72f93c0180558ac9b6a4a0688f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 10:59:43 +0200 Subject: [PATCH 32/61] Expose a list of all active materials in MachineManager Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 8c2466762c..fb478f8f7c 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -395,6 +395,32 @@ class MachineManager(QObject): return "" + @pyqtProperty("QVariantMap", notify = activeMaterialChanged) + def allActiveMaterialIds(self): + if not self._global_container_stack: + return {} + + result = {} + + stacks = [ s for s in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()) ] + stacks.insert(0, self._global_container_stack) + + for stack in stacks: + material_container = stack.findContainer(type = "material") + if not material_container: + continue + + key = "" + if stack == self._global_container_stack: + key = "global" + else: + key = stack.getId() + + result[key] = material_container.getId() + + return result + + @pyqtProperty(str, notify=activeQualityChanged) def activeQualityName(self): if self._active_container_stack: From 1a6b16932a68a202648241dccd4c2eef34f9db8d Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 11:00:26 +0200 Subject: [PATCH 33/61] Add a QualitySettingsModel that lists all quality related settings and values Contributes to CURA-2006 --- cura/CuraApplication.py | 1 + cura/Settings/QualitySettingsModel.py | 155 ++++++++++++++++++++++++++ cura/Settings/__init__.py | 1 + 3 files changed, 157 insertions(+) create mode 100644 cura/Settings/QualitySettingsModel.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 091b8fe269..6914485a5d 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -482,6 +482,7 @@ class CuraApplication(QtApplication): qmlRegisterType(cura.Settings.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") qmlRegisterType(cura.Settings.MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") + qmlRegisterType(cura.Settings.QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel") qmlRegisterSingletonType(cura.Settings.ContainerManager, "Cura", 1, 0, "ContainerManager", cura.Settings.ContainerManager.createContainerManager) diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py new file mode 100644 index 0000000000..5eae16701f --- /dev/null +++ b/cura/Settings/QualitySettingsModel.py @@ -0,0 +1,155 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +import collections + +from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt + +import UM.Application +import UM.Logger +import UM.Qt +import UM.Settings + +class QualitySettingsModel(UM.Qt.ListModel.ListModel): + KeyRole = Qt.UserRole + 1 + LabelRole = Qt.UserRole + 2 + UnitRole = Qt.UserRole + 3 + ProfileValueRole = Qt.UserRole + 4 + UserValueRole = Qt.UserRole + 5 + CategoryRole = Qt.UserRole + 6 + + def __init__(self, parent = None): + super().__init__(parent = parent) + + self._extruder_id = None + self._quality = None + self._material = None + + self.addRoleName(self.KeyRole, "key") + self.addRoleName(self.LabelRole, "label") + self.addRoleName(self.UnitRole, "unit") + self.addRoleName(self.ProfileValueRole, "profile_value") + self.addRoleName(self.UserValueRole, "user_value") + self.addRoleName(self.CategoryRole, "category") + + def setExtruderId(self, extruder_id): + if extruder_id != self._extruder_id: + self._extruder_id = extruder_id + self._update() + self.extruderIdChanged.emit() + + extruderIdChanged = pyqtSignal() + @pyqtProperty(str, fset = setExtruderId, notify = extruderIdChanged) + def extruderId(self): + return self._extruder_id + + def setQuality(self, quality): + if quality != self._quality: + self._quality = quality + self._update() + self.qualityChanged.emit() + + qualityChanged = pyqtSignal() + @pyqtProperty(str, fset = setQuality, notify = qualityChanged) + def quality(self): + return self._quality + + def setMaterial(self, material): + if material != self._material: + self._material = material + self._update() + self.materialChanged.emit() + + materialChanged = pyqtSignal() + @pyqtProperty(str, fset = setMaterial, notify = materialChanged) + def material(self): + return self._material + + def _update(self): + if not self._quality: + return + + self.clear() + + settings = collections.OrderedDict() + definition_container = UM.Application.getInstance().getGlobalContainerStack().getBottom() + + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = self._quality) + if not containers: + UM.Logger.log("w", "Could not find a quality container with id %s", self._quality) + return + + quality_container = None + quality_changes_container = None + + if containers[0].getMetaDataEntry("type") == "quality": + quality_container = containers[0] + else: + quality_changes_container = containers[0] + + criteria = { "type": "quality", "quality_type": quality_changes_container.getMetaDataEntry("quality"), "definition": quality_changes_container.getDefinition().getId() } + + if self._material: + criteria["material"] = self._material + + quality_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) + if not quality_container: + UM.Logger.log("w", "Could not find a quality container matching quality changes %s", quality_changes_container.getId()) + return + quality_container = quality_container[0] + + quality_type = quality_container.getMetaDataEntry("quality_type") + + criteria = { "type": "quality", "quality_type": quality_type } + + if self._material: + criteria["material"] = self._material + + criteria["extruder"] = self._extruder_id + + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) + if not containers: + # Try again, this time without extruder + criteria.pop("extruder") + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) + + if not containers: + UM.Logger.log("Could not find any quality containers matching the search criteria %s", criteria) + return + + if quality_changes_container: + changes = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality_changes", quality = quality_type, extruder = self._extruder_id) + if changes: + containers.extend(changes) + + current_category = "" + for definition in definition_container.findDefinitions(): + if definition.type == "category": + current_category = definition.label + continue + + profile_value = None + for container in containers: + new_value = container.getProperty(definition.key, "value") + if new_value: + profile_value = new_value + + user_value = None + if not self._extruder_id: + user_value = UM.Application.getInstance().getGlobalContainerStack().getTop().getProperty(definition.key, "value") + else: + extruder_stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = self._extruder_id) + if extruder_stack: + user_value = extruder_stack[0].getTop().getProperty(definition.key, "value") + + if not profile_value and not user_value: + continue + + self.appendItem({ + "key": definition.key, + "label": definition.label, + "unit": definition.unit, + "profile_value": profile_value, + "user_value": user_value, + "category": current_category + }) diff --git a/cura/Settings/__init__.py b/cura/Settings/__init__.py index da8f36c040..5daa00c84f 100644 --- a/cura/Settings/__init__.py +++ b/cura/Settings/__init__.py @@ -10,3 +10,4 @@ from .ExtrudersModel import ExtrudersModel from .MachineManager import MachineManager from .MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler from .SettingOverrideDecorator import SettingOverrideDecorator +from .QualitySettingsModel import QualitySettingsModel From 03252c69dcfef5ce546a33e81e5d9da0389be425 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 11:01:50 +0200 Subject: [PATCH 34/61] List all the qualities and quality changes in the profiles page Contributes to CURA-2006 --- resources/qml/Preferences/ProfilesPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index c090a8468d..3c613d71c4 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -18,13 +18,13 @@ UM.ManagementPage { filter: { - var result = { "type": "quality" }; + var result = { "type": "quality*", "extruder": null }; if(Cura.MachineManager.filterQualityByMachine) { result.definition = Cura.MachineManager.activeDefinitionId; if(Cura.MachineManager.hasMaterials) { - result.material = Cura.MachineManager.activeMaterialId; + result.material = Cura.MachineManager.allActiveMaterialIds.global; } } else From 975a60bec32600b0c9cef5f75039405db1c573e9 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 11:03:00 +0200 Subject: [PATCH 35/61] Display all the extruder settings and global settings in profile manager Contributes to CURA-2006 --- resources/qml/Preferences/ProfileTab.qml | 33 +++++++++++ resources/qml/Preferences/ProfilesPage.qml | 67 +++------------------- 2 files changed, 42 insertions(+), 58 deletions(-) create mode 100644 resources/qml/Preferences/ProfileTab.qml diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml new file mode 100644 index 0000000000..1be1d82cb8 --- /dev/null +++ b/resources/qml/Preferences/ProfileTab.qml @@ -0,0 +1,33 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Tab +{ + id: base + + property string extruderId: ""; + property string quality: ""; + property string material: ""; + + TableView + { + anchors.fill: parent + anchors.margins: UM.Theme.getSize("default_margin").width + + TableViewColumn { role: "label"; title: catalog.i18nc("@title:column", "Setting") } + TableViewColumn { role: "profile_value"; title: catalog.i18nc("@title:column", "Profile Value"); } + TableViewColumn { role: "user_value"; title: catalog.i18nc("@title:column", "User Value"); visible: quality == Cura.MachineManager.activeQualityId } + TableViewColumn { role: "unit"; title: catalog.i18nc("@title:column", "Unit") } + + section.property: "category" + section.delegate: Label { text: section } + + model: Cura.QualitySettingsModel { extruderId: base.extruderId != "" ? base.extruderId : null; quality: base.quality; material: base.material } + } +} diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 3c613d71c4..b32590382b 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -187,70 +187,21 @@ UM.ManagementPage } } - ScrollView { - id: scrollView - + TabView + { anchors.left: parent.left anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.right: parent.right anchors.bottom: parent.bottom - ListView { - model: Cura.ContainerSettingsModel{ containers: - { - if (!currentItem) { - return [] - } else if (currentItem.id == Cura.MachineManager.activeQualityId) { - return [base.currentItem.id, Cura.MachineManager.activeUserProfileId] - } else { - return [base.currentItem.id] - } - } - } - delegate: Row { - property variant setting: model - spacing: UM.Theme.getSize("default_margin").width/2 - Label { - text: model.label - elide: Text.ElideMiddle - width: scrollView.width / 100 * 40 - } - Repeater { - model: setting.values.length - Label { - text: setting.values[index].toString() - width: scrollView.width / 100 * 15 - elide: Text.ElideRight - font.strikeout: index < setting.values.length - 1 && setting.values[index + 1] != "" - opacity: font.strikeout ? 0.5 : 1 - } - } - Label { - text: model.unit - } - } - header: Row { - visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId - spacing: UM.Theme.getSize("default_margin").width - Label { - text: catalog.i18nc("@action:label", "Profile:") - width: scrollView.width / 100 * 55 - horizontalAlignment: Text.AlignRight - font.bold: true - } - Label { - text: catalog.i18nc("@action:label", "Current:") - visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId - font.bold: true - } - } - section.property: "category" - section.criteria: ViewSection.FullString - section.delegate: Label { - text: section - font.bold: true - } + ProfileTab { title: catalog.i18nc("@title:tab", "Global Settings"); quality: base.currentItem != null ? base.currentItem.id : ""; material: Cura.MachineManager.allActiveMaterialIds.global } + + Repeater + { + model: Cura.ExtrudersModel { } + + ProfileTab { title: model.name; extruderId: model.id; quality: base.currentItem.id; material: Cura.MachineManager.allActiveMaterialIds[model.id] } } } } From ba2c60bb0d7aa22434a4d7de3188282e64fc6e4a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 11:03:33 +0200 Subject: [PATCH 36/61] Implement remove, rename, duplicate quality in containermanager Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 109 ++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index b1cc060c23..734a908a22 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -439,6 +439,83 @@ class ContainerManager(QObject): UM.Application.getInstance().getMachineManager().activeQualityChanged.emit() return True + @pyqtSlot(str, result = bool) + def removeQualityChanges(self, quality_name): + if not quality_name: + return False + + for container in self._getQualityContainers(quality_name): + UM.Settings.ContainerRegistry.getInstance().removeContainer(container.getId()) + + return True + + @pyqtSlot(str, str, result = bool) + def renameQualityChanges(self, quality_name, new_name): + if not quality_name or not new_name: + return False + + new_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(new_name) + + for container in self._getQualityContainers(quality_name): + UM.Settings.ContainerRegistry.getInstance().renameContainer(container.getId(), new_name, new_name) + + return True + + @pyqtSlot(str, result = str) + def duplicateQuality(self, quality_name): + if not quality_name: + return "" + + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack: + return "" + + new_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(quality_name) + + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = quality_name) + if not containers: + return "" + + container_type = containers[0].getMetaDataEntry("type") + if container_type == "quality": + for container in self._getQualityContainers(quality_name, "quality"): + stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) + new_id = new_name.lower() + new_id.replace(" ", "_") + new_id = stack_id + "_" + new_id + + quality_changes = UM.Settings.InstanceContainer(new_id) + quality_changes.setName(new_name) + quality_changes.addMetaDataEntry("type", "quality_changes") + quality_changes.addMetaDataEntry("quality", container.getMetaDataEntry("quality_type")) + + if not global_stack.getMetaDataEntry("has_machine_quality"): + quality_changes.setDefinition(UM.Settings.ContainerRegistry.getInstance().findContainers(id = "fdmprinter")[0]) + else: + quality_changes.setDefinition(global_stack.getBottom()) + + if global_stack.getMetaDataEntry("has_materials"): + material = container.getMetaDataEntry("material") + quality_changes.addMetaDataEntry("material", material) + + UM.Settings.ContainerRegistry.getInstance().addContainer(quality_changes) + + + elif container_type == "quality_changes": + for container in self._getQualityContainers(quality_name): + stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) + new_id = new_name.lower() + new_id.replace(" ", "_") + new_id = stack_id + "_" + new_id + + new_container = container.duplicate(new_id, new_name) + UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) + else: + return "" + + return new_name + + # Factory function, used by QML @staticmethod def createContainerManager(engine, js_engine): @@ -498,3 +575,35 @@ class ContainerManager(QObject): name_filter = "{0} ({1})".format(mime_type.comment, suffix_list) self._container_name_filters[name_filter] = entry + + def _getQualityContainers(self, quality_name, container_type = "quality_changes"): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack: + return False + + criteria = { "type": container_type, "name": quality_name } + + filter_by_material = False + + if global_stack.getMetaDataEntry("has_machine_quality"): + criteria["definition"] = global_stack.getBottom().getId() + + filter_by_material = global_stack.getMetaDataEntry("has_materials") + + material_ids = [] + if filter_by_material: + stacks = [ s for s in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()) ] + stacks.insert(0, global_stack) + + for stack in stacks: + material_ids.append(stack.findContainer(type = "material").getId()) + + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) + for container in containers: + if filter_by_material and container.getMetaDataEntry("material") not in material_ids: + continue + + if container.isReadOnly(): + continue + + yield container From 783d395fbc0fde5396d35ebb2325e5a99578a82d Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 11:04:15 +0200 Subject: [PATCH 37/61] Use containermanager for operations on Quality Contributes to CURA-2006 --- resources/qml/Preferences/ProfilesPage.qml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index b32590382b..c916c04685 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -76,9 +76,9 @@ UM.ManagementPage { var selectedContainer; if (base.currentItem.id == Cura.MachineManager.activeQualityId) { - selectedContainer = Cura.MachineManager.newQualityContainerFromQualityAndUser(); + selectedContainer = Cura.ContainerManager.createQualityChanges(); } else { - selectedContainer = Cura.MachineManager.duplicateContainer(base.currentItem.id); + selectedContainer = Cura.ContainerManager.duplicateQuality(base.currentItem.name); } base.selectContainer(selectedContainer); @@ -106,13 +106,15 @@ UM.ManagementPage text: catalog.i18nc("@action:button", "Import"); iconName: "document-import"; onClicked: importDialog.open(); + enabled: false }, Button { text: catalog.i18nc("@action:button", "Export") iconName: "document-export" onClicked: exportDialog.open() - enabled: currentItem != null +// enabled: currentItem != null + enabled: false } ] @@ -152,14 +154,14 @@ UM.ManagementPage return catalog.i18nc("@action:button", "Update profile with current settings"); } enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) - onClicked: Cura.MachineManager.updateQualityContainerFromUserContainer() + onClicked: Cura.ContainerManager.updateQualityChanges() } Button { text: catalog.i18nc("@action:button", "Discard current settings"); enabled: Cura.MachineManager.hasUserSettings - onClicked: Cura.MachineManager.clearUserSettings(); + onClicked: Cura.ContainerManager.clearUserContainers(); } } @@ -214,19 +216,19 @@ UM.ManagementPage { id: confirmDialog object: base.currentItem != null ? base.currentItem.name : "" - onYes: Cura.MachineManager.removeQualityContainer(base.currentItem.id) + onYes: Cura.ContainerManager.removeQualityChanges(base.currentItem.name) } UM.RenameDialog { id: renameDialog; object: base.currentItem != null ? base.currentItem.name : "" property bool removeWhenRejected: false - onAccepted: Cura.MachineManager.renameQualityContainer(base.currentItem.id, newName) onRejected: { if(removeWhenRejected) { Cura.MachineManager.removeQualityContainer(base.currentItem.id) } } + onAccepted: Cura.ContainerManager.renameQualityChanges(base.currentItem.name, newName) } MessageDialog { From 2a81d25bf96197c6e2ec2945029ac582c3605b04 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 11:05:56 +0200 Subject: [PATCH 38/61] Fix removing container after rejecting a rename Contributes to CURA-2006 --- resources/qml/Preferences/ProfilesPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index c916c04685..1454f558af 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -223,12 +223,12 @@ UM.ManagementPage id: renameDialog; object: base.currentItem != null ? base.currentItem.name : "" property bool removeWhenRejected: false + onAccepted: Cura.ContainerManager.renameQualityChanges(base.currentItem.name, newName) onRejected: { if(removeWhenRejected) { - Cura.MachineManager.removeQualityContainer(base.currentItem.id) + Cura.ContainerManager.removeQualityChanges(base.currentItem.name) } } - onAccepted: Cura.ContainerManager.renameQualityChanges(base.currentItem.name, newName) } MessageDialog { From 29c0cc3850ae490cb031d248ffe8d580927633b0 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 11:57:04 +0200 Subject: [PATCH 39/61] Fix ContainerManager::renameQuality to set a proper unique id Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 734a908a22..afabc68f4e 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -454,11 +454,25 @@ class ContainerManager(QObject): if not quality_name or not new_name: return False + if quality_name == new_name: + return True + + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack: + return False + + UM.Application.getInstance().getMachineManager().blurSettings.emit() + new_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(new_name) + new_id = new_name.lower() + new_id.replace(" ", "_") for container in self._getQualityContainers(quality_name): - UM.Settings.ContainerRegistry.getInstance().renameContainer(container.getId(), new_name, new_name) + stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) + UM.Settings.ContainerRegistry.getInstance().renameContainer(container.getId(), new_name, stack_id + "_" + new_id) + + UM.Application.getInstance().getMachineManager().activeQualityChanged.emit() return True @pyqtSlot(str, result = str) From 2c0f0e855907f8d4641909e7a5f436826364ca14 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 11:57:57 +0200 Subject: [PATCH 40/61] Move new_id in ContainerManager::duplicate into a general block Saves duplication Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index afabc68f4e..50394b218d 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -485,6 +485,8 @@ class ContainerManager(QObject): return "" new_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(quality_name) + new_id = new_name.lower() + new_id.replace(" ", "_") containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = quality_name) if not containers: @@ -494,11 +496,8 @@ class ContainerManager(QObject): if container_type == "quality": for container in self._getQualityContainers(quality_name, "quality"): stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) - new_id = new_name.lower() - new_id.replace(" ", "_") - new_id = stack_id + "_" + new_id - quality_changes = UM.Settings.InstanceContainer(new_id) + quality_changes = UM.Settings.InstanceContainer(stack_id + "_" + new_id) quality_changes.setName(new_name) quality_changes.addMetaDataEntry("type", "quality_changes") quality_changes.addMetaDataEntry("quality", container.getMetaDataEntry("quality_type")) @@ -514,22 +513,16 @@ class ContainerManager(QObject): UM.Settings.ContainerRegistry.getInstance().addContainer(quality_changes) - elif container_type == "quality_changes": for container in self._getQualityContainers(quality_name): stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) - new_id = new_name.lower() - new_id.replace(" ", "_") - new_id = stack_id + "_" + new_id - - new_container = container.duplicate(new_id, new_name) + new_container = container.duplicate(stack_id + "_" + new_id, new_name) UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) else: return "" return new_name - # Factory function, used by QML @staticmethod def createContainerManager(engine, js_engine): From 7ba49b4f886f2a51b145152ff10dc0771eac066b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 11:58:40 +0200 Subject: [PATCH 41/61] Remove code that is obsolete and moved to ContainerManager Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 65 --------------------------------- resources/qml/Cura.qml | 4 -- 2 files changed, 69 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index fb478f8f7c..3e8cbfd500 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -480,71 +480,6 @@ class MachineManager(QObject): if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value: extruder_stack.getTop().setProperty(key, "value", new_value) - @pyqtSlot(str, result=str) - def duplicateContainer(self, container_id): - if not self._active_container_stack: - return "" - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) - if containers: - new_name = self._createUniqueName("quality", "", containers[0].getName(), catalog.i18nc("@label", "Custom profile")) - - new_container = containers[0].duplicate(new_name, new_name) - - UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) - - return new_name - - return "" - - @pyqtSlot(str, str) - def renameQualityContainer(self, container_id, new_name): - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality") - if containers: - new_name = self._createUniqueName("quality", containers[0].getName(), new_name, - catalog.i18nc("@label", "Custom profile")) - - if containers[0].getName() == new_name: - # Nothing to do. - return - - # As we also want the id of the container to be changed (so that profile name is the name of the file - # on disk. We need to create a new instance and remove it (so the old file of the container is removed) - # If we don't do that, we might get duplicates & other weird issues. - new_container = UM.Settings.InstanceContainer("") - new_container.deserialize(containers[0].serialize()) - - # Actually set the name - new_container.setName(new_name) - new_container._id = new_name # Todo: Fix proper id change function for this. - - # Add the "new" container. - UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) - - # Ensure that the renamed profile is saved -before- we remove the old profile. - Application.getInstance().saveSettings() - - # Actually set & remove new / old quality. - self.setActiveQuality(new_name) - self.removeQualityContainer(containers[0].getId()) - - @pyqtSlot(str) - def removeQualityContainer(self, container_id): - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) - if not containers or not self._active_container_stack: - return - - # If the container that is being removed is the currently active container, set another machine as the active container - activate_new_container = container_id == self.activeQualityId - - UM.Settings.ContainerRegistry.getInstance().removeContainer(container_id) - - if activate_new_container: - definition_id = "fdmprinter" if not self.filterQualityByMachine else self.activeDefinitionId - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = definition_id) - if containers: - self.setActiveQuality(containers[0].getId()) - self.activeQualityChanged.emit() - @pyqtSlot(str) def setActiveMaterial(self, material_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = material_id) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 02dcd10897..612de89fe8 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -765,10 +765,6 @@ UM.MainWindow addMachineDialog.visible = true addMachineDialog.firstRun = false } - onClearAllFocus: - { - contentItem.focus = true - } } Timer From 5edeaa1c93d3b05a68929fe771ff946769b95b62 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 12:00:03 +0200 Subject: [PATCH 42/61] Reduce the amount of QML warning showing up Contributes to CURA-2006 --- resources/qml/Preferences/ProfileTab.qml | 7 ++++++- resources/qml/Preferences/ProfilesPage.qml | 17 ++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index 1be1d82cb8..7b1f99ebca 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -28,6 +28,11 @@ Tab section.property: "category" section.delegate: Label { text: section } - model: Cura.QualitySettingsModel { extruderId: base.extruderId != "" ? base.extruderId : null; quality: base.quality; material: base.material } + model: Cura.QualitySettingsModel + { + extruderId: base.extruderId != "" ? base.extruderId : null; + quality: base.quality != null ? base.quality : ""; + material: base.material + } } } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 1454f558af..ea129a62b0 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -175,7 +175,7 @@ UM.ManagementPage Label { id: defaultsMessage - visible: currentItem && !currentItem.metadata.has_settings + visible: false text: catalog.i18nc("@action:label", "This profile has no settings and uses the defaults specified by the printer.") wrapMode: Text.WordWrap width: parent.width @@ -197,13 +197,24 @@ UM.ManagementPage anchors.right: parent.right anchors.bottom: parent.bottom - ProfileTab { title: catalog.i18nc("@title:tab", "Global Settings"); quality: base.currentItem != null ? base.currentItem.id : ""; material: Cura.MachineManager.allActiveMaterialIds.global } + ProfileTab + { + title: catalog.i18nc("@title:tab", "Global Settings"); + quality: base.currentItem != null ? base.currentItem.id : ""; + material: Cura.MachineManager.allActiveMaterialIds.global + } Repeater { model: Cura.ExtrudersModel { } - ProfileTab { title: model.name; extruderId: model.id; quality: base.currentItem.id; material: Cura.MachineManager.allActiveMaterialIds[model.id] } + ProfileTab + { + title: model.name; + extruderId: model.id; + quality: base.currentItem != null ? base.currentItem.id : null; + material: Cura.MachineManager.allActiveMaterialIds[model.id] + } } } } From be4db899a644937c52123bb99ce9916051c0977c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 10 Aug 2016 12:02:11 +0200 Subject: [PATCH 43/61] Change the active quality if we remove the active quality Contributes to CURA-2006 --- resources/qml/Preferences/ProfilesPage.qml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index ea129a62b0..e9391b90f2 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -227,7 +227,15 @@ UM.ManagementPage { id: confirmDialog object: base.currentItem != null ? base.currentItem.name : "" - onYes: Cura.ContainerManager.removeQualityChanges(base.currentItem.name) + onYes: + { + var name = base.currentItem.name; + Cura.ContainerManager.removeQualityChanges(name) + if(Cura.MachineManager.activeQualityName == name) + { + Cura.MachineManager.setActiveQuality(base.model.getItem(0).name) + } + } } UM.RenameDialog { From e1ddb878adac54d868bb09025a6b1047a1e4668e Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 11 Aug 2016 17:47:15 +0200 Subject: [PATCH 44/61] Fix copyright header Contributes to CURA-2006 --- resources/qml/Preferences/ProfileTab.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index 7b1f99ebca..72c241babe 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2015 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Copyright (c) 2016 Ultimaker B.V. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 From 6778020d56f220a2e5bc37a5dd25bddc88a95077 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 11 Aug 2016 17:47:30 +0200 Subject: [PATCH 45/61] Remove duplicated code Contributes to CURA-2006 --- resources/qml/Cura.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 612de89fe8..fc808c1434 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -459,7 +459,6 @@ UM.MainWindow target: Cura.Actions.addProfile onTriggered: { -// Cura.MachineManager.newQualityContainerFromQualityAndUser(); Cura.ContainerManager.createQualityChanges(); preferences.setPage(4); preferences.show(); From c557cd1a7a5e8d0a35a8c2baa7fc92561ed85c68 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 11 Aug 2016 17:48:22 +0200 Subject: [PATCH 46/61] Move comment Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 3e8cbfd500..9f917471dd 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -26,6 +26,7 @@ class MachineManager(QObject): self._global_container_stack = None Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) + ## When the global container is changed, active material probably needs to be updated. self.globalContainerChanged.connect(self.activeMaterialChanged) self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) @@ -36,8 +37,6 @@ class MachineManager(QObject): ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) self._onActiveExtruderStackChanged() - ## When the global container is changed, active material probably needs to be updated. - ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeMaterialChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeVariantChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeQualityChanged) From 6049d6f3a53a09766d821fe7620c09d1d79cd101 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 11 Aug 2016 17:49:02 +0200 Subject: [PATCH 47/61] Introduce a getActiveGlobalAndExtruderStacks method to ExtruderManager It can be used to iterate over the active global and extruder stacks Contributes to CURA-2006 --- cura/Settings/ExtruderManager.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 8861334237..c784bce5a0 100644 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -277,6 +277,20 @@ class ExtruderManager(QObject): for name in self._extruder_trains[machine_id]: yield self._extruder_trains[machine_id][name] + ## Returns a generator that will iterate over the global stack and per-extruder stacks. + # + # The first generated element is the global container stack. After that any extruder stacks are generated. + def getActiveGlobalAndExtruderStacks(self): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack: + return + + yield global_stack + + global_id = global_stack.getId() + for name in self._extruder_trains[global_id]: + yield self._extruder_trains[global_id][name] + def __globalContainerStackChanged(self): self._addCurrentMachineExtruders() self.activeExtruderChanged.emit() From 9f33fef4ec7c2c9f935733cc07f825fe799d1c2e Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 11 Aug 2016 17:50:08 +0200 Subject: [PATCH 48/61] Use the new generator to simplify some extruder related code in MachineManager Contributes to CURA-2006 --- cura/Settings/MachineManager.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 9f917471dd..b57695b8f6 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -401,25 +401,15 @@ class MachineManager(QObject): result = {} - stacks = [ s for s in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()) ] - stacks.insert(0, self._global_container_stack) - - for stack in stacks: + for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): material_container = stack.findContainer(type = "material") if not material_container: continue - key = "" - if stack == self._global_container_stack: - key = "global" - else: - key = stack.getId() - - result[key] = material_container.getId() + result[stack.getId()] = material_container.getId() return result - @pyqtProperty(str, notify=activeQualityChanged) def activeQualityName(self): if self._active_container_stack: @@ -549,10 +539,7 @@ class MachineManager(QObject): if not quality_type: quality_type = quality_changes_container.getName() - stacks = [ s for s in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()) ] - stacks.insert(0, self._global_container_stack) - - for stack in stacks: + for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): extruder_id = stack.getId() if stack != self._global_container_stack else None criteria = { "quality_type": quality_type, "extruder": extruder_id } @@ -567,7 +554,8 @@ class MachineManager(QObject): stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) if not stack_quality: stack_quality = quality_container - stack_quality = stack_quality[0] + else: + stack_quality = stack_quality[0] else: stack_quality = stack_quality[0] From a14a80be56fdc44b298d3229bd6dfe96d3ab9c51 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 11 Aug 2016 17:50:54 +0200 Subject: [PATCH 49/61] Document and simplify the quality/quality changes code in ContainerManager Contributes to CURA-2006 --- cura/Settings/ContainerManager.py | 218 ++++++++++++++++++------------ 1 file changed, 130 insertions(+), 88 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 50394b218d..a86e3d922c 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -351,47 +351,49 @@ class ContainerManager(QObject): return { "status": "success", "message": "Successfully imported container {0}".format(container.getName()) } + ## Update the current active quality changes container with the settings from the user container. + # + # This will go through the active global stack and all active extruder stacks and merge the changes from the user + # container into the quality_changes container. After that, the user container is cleared. + # + # \return \type{bool} True if successful, False if not. @pyqtSlot(result = bool) def updateQualityChanges(self): global_stack = UM.Application.getInstance().getGlobalContainerStack() - - containers_to_merge = [] - - global_quality_changes = global_stack.findContainer(type = "quality_changes") - if not global_quality_changes or global_quality_changes.isReadOnly(): - UM.Logger.log("e", "Could not update quality of a nonexistant or read only quality profile") + if not global_stack: return False UM.Application.getInstance().getMachineManager().blurSettings.emit() - containers_to_merge.append((global_quality_changes, global_stack.getTop())) - - for extruder in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): - quality_changes = extruder.findContainer(type = "quality_changes") + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + # Find the quality_changes container for this stack and merge the contents of the top container into it. + quality_changes = stack.findContainer(type = "quality_changes") if not quality_changes or quality_changes.isReadOnly(): - UM.Logger.log("e", "Could not update quality of a nonexistant or read only quality profile") - return False + UM.Logger.log("e", "Could not update quality of a nonexistant or read only quality profile in stack %s", stack.getId()) + continue - containers_to_merge.append((quality_changes, extruder.getTop())) - - for merge_into, merge in containers_to_merge: - self._performMerge(merge_into, merge) + self._performMerge(quality_changes, stack.getTop()) UM.Application.getInstance().getMachineManager().activeQualityChanged.emit() return True + ## Clear the top-most (user) containers of the active stacks. @pyqtSlot() def clearUserContainers(self): - global_stack = UM.Application.getInstance().getGlobalContainerStack() - UM.Application.getInstance().getMachineManager().blurSettings.emit() - for extruder in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): - extruder.getTop().clear() - - global_stack.getTop().clear() + # Go through global and extruder stacks and clear their topmost container (the user settings). + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + stack.getTop().clear() + ## Create quality changes containers from the user containers in the active stacks. + # + # This will go through the global and extruder stacks and create quality_changes containers from + # the user containers in each stack. These then replace the quality_changes containers in the + # stack and clear the user settings. + # + # \return \type{bool} True if the operation was successfully, False if not. @pyqtSlot(result = bool) def createQualityChanges(self): global_stack = UM.Application.getInstance().getGlobalContainerStack() @@ -406,49 +408,54 @@ class ContainerManager(QObject): UM.Application.getInstance().getMachineManager().blurSettings.emit() unique_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(quality_container.getName()) - unique_id = unique_name.lower() - unique_id.replace(" ", "_") - stacks = [ s for s in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()) ] - stacks.insert(0, global_stack) - - for stack in stacks: + # Go through the active stacks and create quality_changes containers from the user containers. + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): user_container = stack.getTop() quality_container = stack.findContainer(type = "quality") quality_changes_container = stack.findContainer(type = "quality_changes") if not quality_container or not quality_changes_container: UM.Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId()) - return False + continue - new_quality_changes = user_container.duplicate(stack.getId() + "_" + unique_id, unique_name) - new_quality_changes.setMetaDataEntry("type", "quality_changes") - new_quality_changes.addMetaDataEntry("quality", quality_container.getMetaDataEntry("quality_type")) + new_changes = self._createQualityChanges(quality_container, unique_name, stack.getId()) + self._performMerge(new_changes, user_container) - if not global_stack.getMetaDataEntry("has_machine_quality"): - new_quality_changes.setDefinition(UM.Settings.ContainerRegistry.getInstance().findContainers(id = "fdmprinter")[0]) - - if global_stack.getMetaDataEntry("has_materials"): - material = stack.findContainer(type = "material") - new_quality_changes.addMetaDataEntry("material", material.getId()) - - UM.Settings.ContainerRegistry.getInstance().addContainer(new_quality_changes) - - stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_quality_changes) - stack.getTop().clear() + UM.Settings.ContainerRegistry.getInstance().addContainer(new_changes) + stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_changes) UM.Application.getInstance().getMachineManager().activeQualityChanged.emit() return True + ## Remove all quality changes containers matching a specified name. + # + # This will search for quality_changes containers matching the supplied name and remove them. + # Note that if the machine specifies that qualities should be filtered by machine and/or material + # only the containers related to the active machine/material are removed. + # + # \param quality_name The name of the quality changes to remove. + # + # \return \type{bool} True if successful, False if not. @pyqtSlot(str, result = bool) def removeQualityChanges(self, quality_name): if not quality_name: return False - for container in self._getQualityContainers(quality_name): + for container in self._getFilteredContainers(name = quality_name, type = "quality_changes"): UM.Settings.ContainerRegistry.getInstance().removeContainer(container.getId()) return True + ## Rename a set of quality changes containers. + # + # This will search for quality_changes containers matching the supplied name and rename them. + # Note that if the machine specifies that qualities should be filtered by machine and/or material + # only the containers related to the active machine/material are renamed. + # + # \param quality_name The name of the quality changes containers to rename. + # \param new_name The new name of the quality changes. + # + # \return True if successful, False if not. @pyqtSlot(str, str, result = bool) def renameQualityChanges(self, quality_name, new_name): if not quality_name or not new_name: @@ -464,59 +471,45 @@ class ContainerManager(QObject): UM.Application.getInstance().getMachineManager().blurSettings.emit() new_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(new_name) - new_id = new_name.lower() - new_id.replace(" ", "_") - for container in self._getQualityContainers(quality_name): + for container in self._getFilteredContainers(name = quality_name, type = "quality_changes"): stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) - - UM.Settings.ContainerRegistry.getInstance().renameContainer(container.getId(), new_name, stack_id + "_" + new_id) + UM.Settings.ContainerRegistry.getInstance().renameContainer(container.getId(), new_name, self._createUniqueId(stack_id, new_name)) UM.Application.getInstance().getMachineManager().activeQualityChanged.emit() return True + ## Duplicate a specified set of quality or quality_changes containers. + # + # This will search for containers matching the specified name. If the container is a "quality" type container, a new + # quality_changes container will be created with the specified quality as base. If the container is a "quality_changes" + # container, it is simply duplicated and renamed. + # + # \param quality_name The name of the quality to duplicate. + # + # \return A string containing the name of the duplicated containers, or an empty string if it failed. @pyqtSlot(str, result = str) - def duplicateQuality(self, quality_name): - if not quality_name: - return "" - + def duplicateQualityOrQualityChanges(self, quality_name): global_stack = UM.Application.getInstance().getGlobalContainerStack() - if not global_stack: + if not global_stack or not quality_name: return "" - new_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(quality_name) - new_id = new_name.lower() - new_id.replace(" ", "_") - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = quality_name) if not containers: return "" + new_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(quality_name) + container_type = containers[0].getMetaDataEntry("type") if container_type == "quality": - for container in self._getQualityContainers(quality_name, "quality"): - stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) - - quality_changes = UM.Settings.InstanceContainer(stack_id + "_" + new_id) - quality_changes.setName(new_name) - quality_changes.addMetaDataEntry("type", "quality_changes") - quality_changes.addMetaDataEntry("quality", container.getMetaDataEntry("quality_type")) - - if not global_stack.getMetaDataEntry("has_machine_quality"): - quality_changes.setDefinition(UM.Settings.ContainerRegistry.getInstance().findContainers(id = "fdmprinter")[0]) - else: - quality_changes.setDefinition(global_stack.getBottom()) - - if global_stack.getMetaDataEntry("has_materials"): - material = container.getMetaDataEntry("material") - quality_changes.addMetaDataEntry("material", material) - - UM.Settings.ContainerRegistry.getInstance().addContainer(quality_changes) - + for container in self._getFilteredContainers(name = quality_name, type = "quality"): + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + new_changes = self._createQualityChanges(container, new_name, stack.getId()) + UM.Settings.ContainerRegistry.getInstance().addContainer(new_changes) elif container_type == "quality_changes": - for container in self._getQualityContainers(quality_name): + for container in self._getFilteredContainers(name = quality_name, type = "quality_changes"): stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) - new_container = container.duplicate(stack_id + "_" + new_id, new_name) + new_container = container.duplicate(self._createUniqueId(stack_id, new_name), new_name) UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) else: return "" @@ -583,12 +576,17 @@ class ContainerManager(QObject): name_filter = "{0} ({1})".format(mime_type.comment, suffix_list) self._container_name_filters[name_filter] = entry - def _getQualityContainers(self, quality_name, container_type = "quality_changes"): + ## Return a generator that iterates over a set of containers that are filtered by machine and material when needed. + # + # \param kwargs Initial search criteria that the containers need to match. + # + # \return A generator that iterates over the list of containers matching the search criteria. + def _getFilteredContainers(self, **kwargs): global_stack = UM.Application.getInstance().getGlobalContainerStack() if not global_stack: return False - criteria = { "type": container_type, "name": quality_name } + criteria = kwargs filter_by_material = False @@ -599,18 +597,62 @@ class ContainerManager(QObject): material_ids = [] if filter_by_material: - stacks = [ s for s in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()) ] - stacks.insert(0, global_stack) - - for stack in stacks: + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): material_ids.append(stack.findContainer(type = "material").getId()) containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) for container in containers: + # If the machine specifies we should filter by material, exclude containers that do not match any active material. if filter_by_material and container.getMetaDataEntry("material") not in material_ids: continue - if container.isReadOnly(): - continue - yield container + + ## Creates a unique ID for a container by prefixing the name with the stack ID. + # + # This method creates a unique ID for a container by prefixing it with a specified stack ID. + # This is done to ensure we have an easily identified ID for quality changes, which have the + # same name across several stacks. + # + # \param stack_id The ID of the stack to prepend. + # \param container_name The name of the container that we are creating a unique ID for. + # + # \return Container name prefixed with stack ID, in lower case with spaces replaced by underscores. + def _createUniqueId(self, stack_id, container_name): + result = stack_id + "_" + container_name + result = result.lower() + result.replace(" ", "_") + return result + + ## Create a quality changes container for a specified quality container. + # + # \param quality_container The quality container to create a changes container for. + # \param new_name The name of the new quality_changes container. + # \param stack_id The ID of the container stack the new container "belongs to". It is used primarily to ensure a unique ID. + # + # \return A new quality_changes container with the specified container as base. + def _createQualityChanges(self, quality_container, new_name, stack_id): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + assert global_stack is not None + + # Create a new quality_changes container for the quality. + quality_changes = UM.Settings.InstanceContainer(self._createUniqueId(stack_id, new_name)) + quality_changes.setName(new_name) + quality_changes.addMetaDataEntry("type", "quality_changes") + quality_changes.addMetaDataEntry("quality", quality_container.getMetaDataEntry("quality_type")) + + # If we are creating a container for an extruder, ensure we add that to the container + if stack_id != global_stack.getId(): + quality_changes.addMetaDataEntry("extruder", stack_id) + + # If the machine specifies qualities should be filtered, ensure we match the current criteria. + if not global_stack.getMetaDataEntry("has_machine_quality"): + quality_changes.setDefinition(UM.Settings.ContainerRegistry.getInstance().findContainers(id = "fdmprinter")[0]) + else: + quality_changes.setDefinition(global_stack.getBottom()) + + if global_stack.getMetaDataEntry("has_materials"): + material = quality_container.getMetaDataEntry("material") + quality_changes.addMetaDataEntry("material", material) + + return quality_changes From 2969aafb6d2555ac72efe22a5e076e59ecc82251 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 11 Aug 2016 17:51:16 +0200 Subject: [PATCH 50/61] Update profile page with the renamed functions Contributes to CURA-2006 --- resources/qml/Preferences/ProfilesPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index e9391b90f2..e612cbc46c 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -24,7 +24,7 @@ UM.ManagementPage result.definition = Cura.MachineManager.activeDefinitionId; if(Cura.MachineManager.hasMaterials) { - result.material = Cura.MachineManager.allActiveMaterialIds.global; + result.material = Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeMachineId]; } } else @@ -78,7 +78,7 @@ UM.ManagementPage if (base.currentItem.id == Cura.MachineManager.activeQualityId) { selectedContainer = Cura.ContainerManager.createQualityChanges(); } else { - selectedContainer = Cura.ContainerManager.duplicateQuality(base.currentItem.name); + selectedContainer = Cura.ContainerManager.duplicateQualityOrQualityChanges(base.currentItem.name); } base.selectContainer(selectedContainer); From 759ef29b1db706c5cd961c48ecd5076be865d231 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 16 Aug 2016 13:12:34 +0200 Subject: [PATCH 51/61] Fix keep user settings dialog. --- cura/Settings/MachineManager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index b57695b8f6..1453437a12 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -596,8 +596,7 @@ class MachineManager(QObject): elif button == QMessageBox.No: # No, discard the settings in the user profile global_stack = Application.getInstance().getGlobalContainerStack() - - for extruder in ExtruderManager.ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): + for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): extruder.getTop().clear() global_stack.getTop().clear() From a27f2e87940b0325c1ebb07edf0200c696aa3973 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 16 Aug 2016 13:19:03 +0200 Subject: [PATCH 52/61] Added quality_type properties to printers. --- .../quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg | 1 + .../quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg | 1 + .../quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg | 1 + 19 files changed, 19 insertions(+) diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg index d658ee5bb5..5650353f7a 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.4_mm weight = -3 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg index f4d9264d3e..7774ba3534 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.25_mm weight = -2 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg index d6d10dbe1a..09e9ec2941 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.6_mm weight = -2 +quality_type = normal [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg index 53d5e0bc8c..e3d8d5462f 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.8_mm weight = -2 +quality_type = fast [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg index 5e54b3194a..346df10c44 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_pla_ultimaker2_extended_plus_0.25_mm weight = -2 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg index 893256bb33..7bba3a504d 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_pla_ultimaker2_extended_plus_0.4_mm weight = -1 +quality_type = fast [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg index 844e2b3eac..939d099d55 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_pla_ultimaker2_extended_plus_0.4_mm weight = -3 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg index 47d511446a..7e521e8fe8 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_pla_ultimaker2_extended_plus_0.4_mm weight = -2 +quality_type = normal [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg index a2b15b6f16..0745ed891f 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus material = generic_pla_ultimaker2_extended_plus_0.6_mm type = quality weight = -2 +quality_type = normal [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg index 08b5bec667..f5f66dce6c 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus material = generic_pla_ultimaker2_extended_plus_0.8_mm type = quality weight = -2 +quality_type = fast [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg index 05a9bce71c..8457d5cd2b 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.25_mm weight = -2 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg index 89e73dda38..4ef0f34484 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.6_mm weight = -2 +quality_type = normal [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg index 2171fd3837..ca2f736c01 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.8_mm weight = -2 +quality_type = fast [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg index 6a300ba27d..0f2a612619 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.25_mm weight = -2 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg index e76c5205f5..8f8fb9e01b 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.4_mm weight = -1 +quality_type = fast [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg index 60f171dc17..abc5e562f7 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.4_mm weight = -3 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg index 04116dbe21..5531f245f0 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.4_mm weight = -2 +quality_type = normal [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg index 35e666e6d9..3765f98709 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.6_mm weight = -2 +quality_type = normal [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg index c36d1714a0..179b554973 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.8_mm weight = -2 +quality_type = fast [values] layer_height = 0.2 From 83b89d09d872bd796b2702a62fbf2524f2dd5103 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 16 Aug 2016 13:34:47 +0200 Subject: [PATCH 53/61] Fix for could not find quality xxx --- cura/Settings/MachineManager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 1453437a12..67b86758cb 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -526,7 +526,8 @@ class MachineManager(QObject): quality_container = containers[0] elif container_type == "quality_changes": quality_changes_container = containers[0] - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_changes_container.getMetaDataEntry("quality")) + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers( + quality_type = quality_changes_container.getMetaDataEntry("quality")) if not containers: Logger.log("e", "Could not find quality %s for changes %s, not changing quality", quality_changes_container.getMetaDataEntry("quality"), quality_changes_container.getId()) return From 80214d07bc909f82a113cf4a6a8513d3f2bfc9ca Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 16 Aug 2016 15:03:01 +0200 Subject: [PATCH 54/61] Prettier number display in Profiles page. CURA-2006 --- cura/Settings/QualitySettingsModel.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py index 5eae16701f..da8eaeebaf 100644 --- a/cura/Settings/QualitySettingsModel.py +++ b/cura/Settings/QualitySettingsModel.py @@ -10,6 +10,7 @@ import UM.Logger import UM.Qt import UM.Settings + class QualitySettingsModel(UM.Qt.ListModel.ListModel): KeyRole = Qt.UserRole + 1 LabelRole = Qt.UserRole + 2 @@ -149,7 +150,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): "key": definition.key, "label": definition.label, "unit": definition.unit, - "profile_value": profile_value, - "user_value": user_value, + "profile_value": "" if profile_value is None else str(profile_value), # it is for display only + "user_value": "" if user_value is None else str(user_value), "category": current_category }) From 07f2b2be9581dccb9cc13971cc5a4acf2f34714d Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 16 Aug 2016 15:41:52 +0200 Subject: [PATCH 55/61] More quality_types for more material/qualities. CURA-2006 --- .../ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg | 1 + .../quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg | 1 + .../quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg | 1 + .../quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg | 1 + resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg | 1 + resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg | 1 + resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg | 1 + 17 files changed, 17 insertions(+) diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg index 11b926378d..2d0a81c8a4 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.25_mm weight = -2 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg index bdeeb935f4..a882429f2a 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.4_mm weight = -1 +quality_type = fast [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg index ff024ccc69..6b5901ad15 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.4_mm weight = -2 +quality_type = normal [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg index c2f4daa86f..bcc2f29656 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.6_mm weight = -2 +quality_type = normal [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg index 362e844214..3fea836f7a 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.8_mm weight = -2 +quality_type = fast [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg index f514f22294..256c304149 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.4_mm weight = -1 +quality_type = fast [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg index 0c68be2f5f..0c70fe615d 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.4_mm weight = -3 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg index 26ea8ce9bc..541ea1b468 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.4_mm weight = -2 +quality_type = normal [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg index 9a44582610..18d74386cf 100644 --- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.25_mm weight = -2 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg index 0df882e418..b17a1f2a6a 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -1 +quality_type = fast [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg index a8abdb081f..ff542c7c19 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -3 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg index c29b017bbe..79d868f25f 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -2 +quality_type = normal [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg index 5a0a840ae7..63beca8fbb 100644 --- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus material = generic_pla_ultimaker2_plus_0.6_mm type = quality weight = -2 +quality_type = normal [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg index bd90b8c059..f2b78846a8 100644 --- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus material = generic_pla_ultimaker2_plus_0.8_mm type = quality weight = -2 +quality_type = fast [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg index cd0a25981a..8bcb3efee4 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.4_mm weight = -1 +quality_type = fast [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg index 4b1ece31ef..f2235abd41 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.4_mm weight = -3 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg index f1b01fd408..1b8c1035db 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.4_mm weight = -2 +quality_type = normal [values] layer_height = 0.1 From 0c0871656b70c284fdee96cdf7df77d0505f6a21 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 18 Aug 2016 17:26:51 +0200 Subject: [PATCH 56/61] Cache container registry before for loop Slight performance increase. We should pay more attention to this kind of thing. Contributes to issue CURA-2006. --- cura/Settings/ContainerManager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index a86e3d922c..3dbd179700 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -472,9 +472,10 @@ class ContainerManager(QObject): new_name = UM.Settings.ContainerRegistry.getInstance().uniqueName(new_name) + container_registry = UM.Settings.ContainerRegistry.getInstance() for container in self._getFilteredContainers(name = quality_name, type = "quality_changes"): stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) - UM.Settings.ContainerRegistry.getInstance().renameContainer(container.getId(), new_name, self._createUniqueId(stack_id, new_name)) + container_registry.renameContainer(container.getId(), new_name, self._createUniqueId(stack_id, new_name)) UM.Application.getInstance().getMachineManager().activeQualityChanged.emit() return True From eaa7d716f57140953b27da3d6eb73aed25530a4f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 19 Aug 2016 15:48:35 +0200 Subject: [PATCH 57/61] Revert "Properly send global settings to the global stack" This reverts commit 9d0acf5b036ee4749af0034969c683e39cc547d3. It was not so proper after all. Contributes to issue CURA-2006. --- resources/qml/Settings/SettingView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 79925e629f..f79f074400 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -94,7 +94,7 @@ ScrollView { target: provider property: "containerStackId" - when: model.settable_per_extruder || (inheritStackProvider.properties.global_inherits_stack != -1 && inheritStackProvider.properties.global_inherits_stack != null) + when: model.settable_per_extruder || (inheritStackProvider.properties.global_inherits_stack == -1 || inheritStackProvider.properties.global_inherits_stack == null) value: { if(inheritStackProvider.properties.global_inherits_stack == -1 || inheritStackProvider.properties.global_inherits_stack == null) From 1c1bfbe11443184a9a8fdfd70db64805489e424b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 22 Aug 2016 11:34:17 +0200 Subject: [PATCH 58/61] Fix providing of global_inherits_stack settings I've rewritten this part and documented what each case catches. There is a base case which is not required any more since we removed the global tab, but I left it in for defense. Contributes to issue CURA-2006. --- resources/qml/Settings/SettingView.qml | 32 ++++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index f79f074400..d53cb9bb3c 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -94,21 +94,29 @@ ScrollView { target: provider property: "containerStackId" - when: model.settable_per_extruder || (inheritStackProvider.properties.global_inherits_stack == -1 || inheritStackProvider.properties.global_inherits_stack == null) + when: { + var now = model.settable_per_extruder || model.settable_per_mesh || (inheritStackProvider.properties.global_inherits_stack == null && inheritStackProvider.properties.global_inherits_stack < 0); + return now; + } value: { - if(inheritStackProvider.properties.global_inherits_stack == -1 || inheritStackProvider.properties.global_inherits_stack == null) + if(!model.settable_per_extruder && !model.settable_per_mesh) { - if( ExtruderManager.activeExtruderStackId) - { - return ExtruderManager.activeExtruderStackId - } - else - { - return Cura.MachineManager.activeMachineId - } + //Not settable per extruder, so we must pick global. + return Cura.MachineManager.activeMachineId; } - return ExtruderManager.extruderIds[String(inheritStackProvider.properties.global_inherits_stack)] + if(inheritStackProvider.properties.global_inherits_stack != null && inheritStackProvider.properties.global_inherits_stack >= 0) + { + //We have global_inherits_stack, so pick that stack. + return ExtruderManager.extruderIds[String(inheritStackProvider.properties.global_inherits_stack)]; + } + if(ExtruderManager.activeExtruderStackId) + { + //We're on an extruder tab. Pick the current extruder. + return ExtruderManager.activeExtruderStackId; + } + //No extruder tab is selected. Pick the global stack. Shouldn't happen any more since we removed the global tab. + return Cura.MachineManager.activeMachineId; } } @@ -119,7 +127,7 @@ ScrollView id: inheritStackProvider containerStackId: Cura.MachineManager.activeMachineId key: model.key - watchedProperties: [ "global_inherits_stack"] + watchedProperties: [ "global_inherits_stack" ] } UM.SettingPropertyProvider From 42399e82fb8089533d90234cc537cc942af4cbd9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 22 Aug 2016 11:36:33 +0200 Subject: [PATCH 59/61] ) Contributes to issue CURA-2006. --- resources/qml/Settings/SettingView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index d53cb9bb3c..c5fec8c8ce 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -121,7 +121,7 @@ ScrollView } // Specialty provider that only watches global_inherits (we cant filter on what property changed we get events - // so we bypass that to make a dedicated provider. + // so we bypass that to make a dedicated provider). UM.SettingPropertyProvider { id: inheritStackProvider From aefb36d1ec53bc9bd5e5d7b76f925de054d8efba Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 22 Aug 2016 13:42:14 +0200 Subject: [PATCH 60/61] Update activeValidationState if setting validation changed This was removed from onGlobalSettingChanged but never re-added anywhere. I've updated it to check for both the global and the active stack, since some settings modify only the global stack (such as layer height). Contributes to issue CURA-2006. --- cura/Settings/MachineManager.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index fb139164d9..23dcf8ba94 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -251,6 +251,20 @@ class MachineManager(QObject): self.activeQualityChanged.emit() def _onPropertyChanged(self, key, property_name): + if property_name == "validationState": + if self._active_stack_valid: + if self._active_container_stack.getProperty(key, "settable_per_extruder"): + changed_validation_state = self._active_container_stack.getProperty(key, property_name) + else: + changed_validation_state = self._global_container_stack.getProperty(key, property_name) + if changed_validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError): + self._active_stack_valid = False + self.activeValidationChanged.emit() + else: + if not self._checkStackForErrors(self._active_container_stack) and not self._checkStackForErrors(self._global_container_stack): + self._active_stack_valid = True + self.activeValidationChanged.emit() + self.activeStackChanged.emit() @pyqtSlot(str) From f296b77d2c579994b38ed2b4b601048734ac1c10 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 22 Aug 2016 14:17:47 +0200 Subject: [PATCH 61/61] Fix check for presence of global_inherits_stack My mistake. Contributes to issue CURA-2006. --- resources/qml/Settings/SettingView.qml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index c5fec8c8ce..57cf8f4add 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -94,10 +94,7 @@ ScrollView { target: provider property: "containerStackId" - when: { - var now = model.settable_per_extruder || model.settable_per_mesh || (inheritStackProvider.properties.global_inherits_stack == null && inheritStackProvider.properties.global_inherits_stack < 0); - return now; - } + when: model.settable_per_extruder || model.settable_per_mesh || (inheritStackProvider.properties.global_inherits_stack != null && inheritStackProvider.properties.global_inherits_stack >= 0); value: { if(!model.settable_per_extruder && !model.settable_per_mesh)