From 7adc1f4870fe65bc156b453ed64a1a23d09d2b0b Mon Sep 17 00:00:00 2001 From: Victor Larchenko Date: Mon, 14 Nov 2016 14:20:39 +0600 Subject: [PATCH 01/49] T576: Added aliases --- plugins/CuraEngineBackend/StartSliceJob.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index ade86e231d..bbf55a4803 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -251,6 +251,9 @@ class StartSliceJob(Job): settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode #Pre-compute material material_bed_temp_prepend and material_print_temp_prepend settings["material_print_temp_prepend"] = "{material_print_temperature}" not in start_gcode + settings["print_bed_temperature"] = settings["material_bed_temperature"] + settings["print_temperature"] = settings["material_print_temperature"] + for key, value in settings.items(): #Add all submessages for each individual setting. setting_message = self._slice_message.getMessage("global_settings").addRepeatedMessage("settings") setting_message.name = key @@ -260,6 +263,8 @@ class StartSliceJob(Job): setting_message.value = str(value).encode("utf-8") Job.yieldThread() + + ## Sends for some settings which extruder they should fallback to if not # set. # From dbb971fef5f1169e8fbfe060602b70c871d982ca Mon Sep 17 00:00:00 2001 From: Victor Larchenko Date: Mon, 14 Nov 2016 14:51:25 +0600 Subject: [PATCH 02/49] T576: Added date and time keywords --- plugins/CuraEngineBackend/StartSliceJob.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index bbf55a4803..4b0ec77ca0 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -4,6 +4,7 @@ import numpy from string import Formatter from enum import IntEnum +import time from UM.Job import Job from UM.Application import Application @@ -254,6 +255,16 @@ class StartSliceJob(Job): settings["print_bed_temperature"] = settings["material_bed_temperature"] settings["print_temperature"] = settings["material_print_temperature"] + settings["time"] = time.strftime('%H:%M:%S') + settings["date"] = time.strftime('%d-%m-%Y') + settings["day"] = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][int(time.strftime('%w'))] + + settings["print_time"] = Application.getInstance().getPrintInformation().currentPrintTime + settings["filament_amount"] = Application.getInstance().getPrintInformation().materialLengths + settings["filament_weight"] = Application.getInstance().getPrintInformation().materialWeights + settings["filament_cost"] = None + settings["profile_string"] = None + for key, value in settings.items(): #Add all submessages for each individual setting. setting_message = self._slice_message.getMessage("global_settings").addRepeatedMessage("settings") setting_message.name = key @@ -263,8 +274,6 @@ class StartSliceJob(Job): setting_message.value = str(value).encode("utf-8") Job.yieldThread() - - ## Sends for some settings which extruder they should fallback to if not # set. # From 67aae55640052e669cd3288915ad58d64bbc759e Mon Sep 17 00:00:00 2001 From: Victor Larchenko Date: Wed, 23 Nov 2016 12:38:02 +0600 Subject: [PATCH 03/49] T576: Added print statistics --- plugins/CuraEngineBackend/CuraEngineBackend.py | 10 +++++++++- plugins/CuraEngineBackend/StartSliceJob.py | 6 ------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index cf53475fb4..0e7f938804 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -13,7 +13,7 @@ from UM.Resources import Resources from UM.Settings.Validator import ValidatorState #To find if a setting is in an error state. We can't slice then. from UM.Platform import Platform from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator - +from UM.Qt.Duration import DurationFormat import cura.Settings @@ -386,6 +386,14 @@ class CuraEngineBackend(Backend): self.backendStateChange.emit(BackendState.Done) self.processingProgress.emit(1.0) + for line in self._scene.gcode_list: + replaced = line.replace("{print_time}", str(Application.getInstance().getPrintInformation().currentPrintTime.getDisplayString(DurationFormat.Format.ISO8601))) + replaced = replaced.replace("{filament_amount}", str(Application.getInstance().getPrintInformation().materialLengths)) + replaced = replaced.replace("{filament_weight}", str(Application.getInstance().getPrintInformation().materialWeights)) + replaced = replaced.replace("{filament_cost}", "Not yet implemented") + + self._scene.gcode_list[self._scene.gcode_list.index(line)] = replaced + self._slicing = False Logger.log("d", "Slicing took %s seconds", time() - self._slice_start_time ) if self._layer_view_active and (self._process_layers_job is None or not self._process_layers_job.isRunning()): diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 4b0ec77ca0..ea5bb1f57c 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -259,12 +259,6 @@ class StartSliceJob(Job): settings["date"] = time.strftime('%d-%m-%Y') settings["day"] = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][int(time.strftime('%w'))] - settings["print_time"] = Application.getInstance().getPrintInformation().currentPrintTime - settings["filament_amount"] = Application.getInstance().getPrintInformation().materialLengths - settings["filament_weight"] = Application.getInstance().getPrintInformation().materialWeights - settings["filament_cost"] = None - settings["profile_string"] = None - for key, value in settings.items(): #Add all submessages for each individual setting. setting_message = self._slice_message.getMessage("global_settings").addRepeatedMessage("settings") setting_message.name = key From 7c3728632ff4d237af32ba3d945e06d437954a97 Mon Sep 17 00:00:00 2001 From: Victor Larchenko Date: Thu, 24 Nov 2016 14:03:53 +0600 Subject: [PATCH 04/49] T576: Added {jobname} keyword --- plugins/CuraEngineBackend/CuraEngineBackend.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 0e7f938804..91bd13c9b6 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -390,7 +390,9 @@ class CuraEngineBackend(Backend): replaced = line.replace("{print_time}", str(Application.getInstance().getPrintInformation().currentPrintTime.getDisplayString(DurationFormat.Format.ISO8601))) replaced = replaced.replace("{filament_amount}", str(Application.getInstance().getPrintInformation().materialLengths)) replaced = replaced.replace("{filament_weight}", str(Application.getInstance().getPrintInformation().materialWeights)) + # TODO: calculate filament cost replaced = replaced.replace("{filament_cost}", "Not yet implemented") + replaced = replaced.replace("{jobname}", str(Application.getInstance().getPrintInformation().jobName)) self._scene.gcode_list[self._scene.gcode_list.index(line)] = replaced From 9302f4e9c60d2c3028076cf87e7e98cfe5c77cfe Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 16 Mar 2017 11:14:53 +0100 Subject: [PATCH 05/49] JSON feat: support_bottom_stair_step_width (CURA-3380) --- resources/definitions/fdmprinter.def.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index a951d6aca6..46055ba0c2 100755 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3025,6 +3025,19 @@ "enabled": "support_enable", "settable_per_mesh": true }, + "support_bottom_stair_step_width": + { + "label": "Support Stair Step Maximum Width", + "description": "The maximum width of the steps of the stair-like bottom of support resting on the model. A low value makes the support harder to remove, but too high values can lead to unstable support structures.", + "unit": "mm", + "type": "float", + "default_value": 5.0, + "limit_to_extruder": "support_interface_extruder_nr if support_interface_enable else support_infill_extruder_nr", + "minimum_value": "0", + "maximum_value_warning": "10.0", + "enabled": "support_enable", + "settable_per_mesh": true + }, "support_join_distance": { "label": "Support Join Distance", From 36420070fa5f25f30ec05045983da4f11044f826 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 16 Mar 2017 13:02:50 +0100 Subject: [PATCH 06/49] JSOn fix: more description on support_bottom_stair_step_height (CURA-3380) --- resources/definitions/fdmprinter.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 46055ba0c2..971ee91372 100755 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3015,7 +3015,7 @@ "support_bottom_stair_step_height": { "label": "Support Stair Step Height", - "description": "The height of the steps of the stair-like bottom of support resting on the model. A low value makes the support harder to remove, but too high values can lead to unstable support structures.", + "description": "The height of the steps of the stair-like bottom of support resting on the model. A low value makes the support harder to remove, but too high values can lead to unstable support structures. Set to zero to turn off the stair-like behaviour.", "unit": "mm", "type": "float", "default_value": 0.3, From e6121039d9dc0800f0170d684e4778d9b50b1a65 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 10 Mar 2017 23:14:11 +0100 Subject: [PATCH 07/49] Add extruders to Custom FDM Printer definition --- resources/definitions/custom.def.json | 11 +++++++++++ resources/extruders/custom_extruder_1.def.json | 17 +++++++++++++++++ resources/extruders/custom_extruder_2.def.json | 17 +++++++++++++++++ resources/extruders/custom_extruder_3.def.json | 17 +++++++++++++++++ resources/extruders/custom_extruder_4.def.json | 17 +++++++++++++++++ resources/extruders/custom_extruder_5.def.json | 17 +++++++++++++++++ resources/extruders/custom_extruder_6.def.json | 17 +++++++++++++++++ resources/extruders/custom_extruder_7.def.json | 17 +++++++++++++++++ resources/extruders/custom_extruder_8.def.json | 17 +++++++++++++++++ 9 files changed, 147 insertions(+) create mode 100644 resources/extruders/custom_extruder_1.def.json create mode 100644 resources/extruders/custom_extruder_2.def.json create mode 100644 resources/extruders/custom_extruder_3.def.json create mode 100644 resources/extruders/custom_extruder_4.def.json create mode 100644 resources/extruders/custom_extruder_5.def.json create mode 100644 resources/extruders/custom_extruder_6.def.json create mode 100644 resources/extruders/custom_extruder_7.def.json create mode 100644 resources/extruders/custom_extruder_8.def.json diff --git a/resources/definitions/custom.def.json b/resources/definitions/custom.def.json index 7ae1d1bd28..8f15f00a0f 100644 --- a/resources/definitions/custom.def.json +++ b/resources/definitions/custom.def.json @@ -10,6 +10,17 @@ "category": "Custom", "file_formats": "text/x-gcode", "has_materials": true, + "machine_extruder_trains": + { + "0": "custom_extruder_1", + "1": "custom_extruder_2", + "2": "custom_extruder_3", + "3": "custom_extruder_4", + "4": "custom_extruder_5", + "5": "custom_extruder_6", + "6": "custom_extruder_7", + "7": "custom_extruder_8" + }, "first_start_actions": ["MachineSettingsAction"] } } diff --git a/resources/extruders/custom_extruder_1.def.json b/resources/extruders/custom_extruder_1.def.json new file mode 100644 index 0000000000..859c6a2f22 --- /dev/null +++ b/resources/extruders/custom_extruder_1.def.json @@ -0,0 +1,17 @@ +{ + "id": "custom_extruder_1", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "custom", + "position": "0" + }, + + "overrides": { + "extruder_nr": { + "default_value": 0, + "maximum_value": "7" + } + } +} diff --git a/resources/extruders/custom_extruder_2.def.json b/resources/extruders/custom_extruder_2.def.json new file mode 100644 index 0000000000..eecda5dfcd --- /dev/null +++ b/resources/extruders/custom_extruder_2.def.json @@ -0,0 +1,17 @@ +{ + "id": "custom_extruder_2", + "version": 2, + "name": "Extruder 2", + "inherits": "fdmextruder", + "metadata": { + "machine": "custom", + "position": "1" + }, + + "overrides": { + "extruder_nr": { + "default_value": 1, + "maximum_value": "7" + } + } +} diff --git a/resources/extruders/custom_extruder_3.def.json b/resources/extruders/custom_extruder_3.def.json new file mode 100644 index 0000000000..77909ec05d --- /dev/null +++ b/resources/extruders/custom_extruder_3.def.json @@ -0,0 +1,17 @@ +{ + "id": "custom_extruder_3", + "version": 2, + "name": "Extruder 3", + "inherits": "fdmextruder", + "metadata": { + "machine": "custom", + "position": "2" + }, + + "overrides": { + "extruder_nr": { + "default_value": 2, + "maximum_value": "7" + } + } +} diff --git a/resources/extruders/custom_extruder_4.def.json b/resources/extruders/custom_extruder_4.def.json new file mode 100644 index 0000000000..be792c3a8e --- /dev/null +++ b/resources/extruders/custom_extruder_4.def.json @@ -0,0 +1,17 @@ +{ + "id": "custom_extruder_4", + "version": 2, + "name": "Extruder 4", + "inherits": "fdmextruder", + "metadata": { + "machine": "custom", + "position": "3" + }, + + "overrides": { + "extruder_nr": { + "default_value": 3, + "maximum_value": "7" + } + } +} diff --git a/resources/extruders/custom_extruder_5.def.json b/resources/extruders/custom_extruder_5.def.json new file mode 100644 index 0000000000..ea64605041 --- /dev/null +++ b/resources/extruders/custom_extruder_5.def.json @@ -0,0 +1,17 @@ +{ + "id": "custom_extruder_5", + "version": 2, + "name": "Extruder 5", + "inherits": "fdmextruder", + "metadata": { + "machine": "custom", + "position": "4" + }, + + "overrides": { + "extruder_nr": { + "default_value": 4, + "maximum_value": "7" + } + } +} diff --git a/resources/extruders/custom_extruder_6.def.json b/resources/extruders/custom_extruder_6.def.json new file mode 100644 index 0000000000..fd27fadace --- /dev/null +++ b/resources/extruders/custom_extruder_6.def.json @@ -0,0 +1,17 @@ +{ + "id": "custom_extruder_6", + "version": 2, + "name": "Extruder 6", + "inherits": "fdmextruder", + "metadata": { + "machine": "custom", + "position": "5" + }, + + "overrides": { + "extruder_nr": { + "default_value": 5, + "maximum_value": "7" + } + } +} diff --git a/resources/extruders/custom_extruder_7.def.json b/resources/extruders/custom_extruder_7.def.json new file mode 100644 index 0000000000..cf003d1a6b --- /dev/null +++ b/resources/extruders/custom_extruder_7.def.json @@ -0,0 +1,17 @@ +{ + "id": "custom_extruder_7", + "version": 2, + "name": "Extruder 7", + "inherits": "fdmextruder", + "metadata": { + "machine": "custom", + "position": "6" + }, + + "overrides": { + "extruder_nr": { + "default_value": 6, + "maximum_value": "7" + } + } +} diff --git a/resources/extruders/custom_extruder_8.def.json b/resources/extruders/custom_extruder_8.def.json new file mode 100644 index 0000000000..f418a55186 --- /dev/null +++ b/resources/extruders/custom_extruder_8.def.json @@ -0,0 +1,17 @@ +{ + "id": "custom_extruder_8", + "version": 2, + "name": "Extruder 8", + "inherits": "fdmextruder", + "metadata": { + "machine": "custom", + "position": "7" + }, + + "overrides": { + "extruder_nr": { + "default_value": 7, + "maximum_value": "7" + } + } +} From 0c74b4d1089bf38c107f939678ee3bacc46a8cf0 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 10 Mar 2017 23:16:07 +0100 Subject: [PATCH 08/49] Don't create extruder tabs for "inactive" extruders If a printer definition defines more extruders than machine_extruder_count, these are no longer shown as tabs in the sidebar. --- cura/Settings/ExtrudersModel.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 7f4a77eb5f..5632a83a27 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -136,6 +136,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): items.append(item) changed = True + machine_extruder_count = global_container_stack.getProperty("machine_extruder_count", "value") manager = ExtruderManager.getInstance() for extruder in manager.getMachineExtruders(global_container_stack.getId()): extruder_name = extruder.getName() @@ -145,6 +146,9 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): position = int(position) except ValueError: #Not a proper int. position = -1 + if position >= machine_extruder_count: + continue + default_color = self.defaultColors[position] if position >= 0 and position < len(self.defaultColors) else self.defaultColors[0] color = material.getMetaDataEntry("color_code", default = default_color) if material else default_color item = { #Construct an item with only the relevant information. From e853d87779d4e730dfb16ce4c777ce96f2d886e7 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 10 Mar 2017 23:17:03 +0100 Subject: [PATCH 09/49] Add control to set the number of extruders in Machine Settings --- .../MachineSettingsAction.py | 19 ++++++--- .../MachineSettingsAction.qml | 39 +++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index c27f8db4a6..1feb748006 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -29,6 +29,7 @@ class MachineSettingsAction(MachineAction): self._container_registry = ContainerRegistry.getInstance() self._container_registry.containerAdded.connect(self._onContainerAdded) + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) def _reset(self): global_container_stack = Application.getInstance().getGlobalContainerStack() @@ -67,13 +68,21 @@ class MachineSettingsAction(MachineAction): def _onContainerAdded(self, container): # Add this action as a supported action to all machine definitions if isinstance(container, DefinitionContainer) and container.getMetaDataEntry("type") == "machine": - if container.getProperty("machine_extruder_count", "value") > 1: - # Multiextruder printers are not currently supported - Logger.log("d", "Not attaching MachineSettingsAction to %s; Multi-extrusion printers are not supported", container.getId()) - return - Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey()) + def _onGlobalContainerChanged(self): + self.globalContainerChanged.emit() + + globalContainerChanged = pyqtSignal() + + @pyqtProperty(int, notify = globalContainerChanged) + def definedExtruderCount(self): + global_container_stack = Application.getInstance().getGlobalContainerStack() + if not global_container_stack: + return 0 + + return len(global_container_stack.getMetaDataEntry("machine_extruder_trains")) + @pyqtSlot() def forceUpdate(self): # Force rebuilding the build volume by reloading the global container stack. diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 26bbccd44a..4dfb7548d6 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -345,6 +345,35 @@ Cura.MachineAction Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + Label + { + text: catalog.i18nc("@label", "Number of Extruders") + } + + ComboBox + { + id: extruderCountComboBox + model: ListModel + { + id: extruderCountModel + Component.onCompleted: + { + for(var i = 0; i < manager.definedExtruderCount; i++) + { + extruderCountModel.append({text: String(i + 1), value: i}); + } + } + } + currentIndex: machineExtruderCountProvider.properties.value - 1 + onActivated: + { + machineExtruderCountProvider.setPropertyValue("value", index + 1); + manager.forceUpdate(); + } + } + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + + Label { text: catalog.i18nc("@label", "Nozzle size") @@ -532,6 +561,16 @@ Cura.MachineAction storeIndex: manager.containerIndex } + UM.SettingPropertyProvider + { + id: machineExtruderCountProvider + + containerStackId: Cura.MachineManager.activeMachineId + key: "machine_extruder_count" + watchedProperties: [ "value" ] + storeIndex: manager.containerIndex + } + UM.SettingPropertyProvider { id: gantryHeightProvider From a41bc77e5a9521ca7a624aa334ea39431e6c8207 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sat, 11 Mar 2017 11:10:55 +0100 Subject: [PATCH 10/49] Hide nozzlesize field for multiextrusion printers... and hide extruder count combobox when no extruders are defined --- .../MachineSettingsAction.qml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 4dfb7548d6..0d2165ddb4 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -348,11 +348,13 @@ Cura.MachineAction Label { text: catalog.i18nc("@label", "Number of Extruders") + visible: extruderCountComboBox.visible } ComboBox { id: extruderCountComboBox + visible: manager.definedExtruderCount > 1 model: ListModel { id: extruderCountModel @@ -364,34 +366,34 @@ Cura.MachineAction } } } - currentIndex: machineExtruderCountProvider.properties.value - 1 + currentIndex: machineExtruderCountProvider.properties.value - 1 onActivated: { machineExtruderCountProvider.setPropertyValue("value", index + 1); manager.forceUpdate(); } } - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height; visible: extruderCountComboBox.visible } Label { text: catalog.i18nc("@label", "Nozzle size") - visible: !Cura.MachineManager.hasVariants + visible: nozzleSizeField.visible } TextField { id: nozzleSizeField text: machineNozzleSizeProvider.properties.value - visible: !Cura.MachineManager.hasVariants + visible: !Cura.MachineManager.hasVariants && machineExtruderCountProvider.properties.value == 1 validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } onEditingFinished: { machineNozzleSizeProvider.setPropertyValue("value", text) } } Label { text: catalog.i18nc("@label", "mm") - visible: !Cura.MachineManager.hasVariants - } + visible: nozzleSizeField.visible + } } } } From 940a60a4cb773f642e5c333cb8f9c131f246a6cc Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 22 Mar 2017 18:50:31 +0100 Subject: [PATCH 11/49] Fix font rendering on second column --- plugins/MachineSettingsAction/MachineSettingsAction.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 0d2165ddb4..cbc7325d5c 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -55,7 +55,7 @@ Cura.MachineAction Column { - width: parent.width / 2 + width: Math.floor(parent.width / 2) spacing: UM.Theme.getSize("default_margin").height Label @@ -243,7 +243,7 @@ Cura.MachineAction Column { - width: parent.width / 2 + width: Math.floor(parent.width / 2) spacing: UM.Theme.getSize("default_margin").height Label @@ -407,7 +407,7 @@ Cura.MachineAction Column { height: parent.height - width: parent.width / 2 + width: Math.floor(parent.width / 2) Label { text: catalog.i18nc("@label", "Start Gcode") @@ -431,7 +431,7 @@ Cura.MachineAction } Column { height: parent.height - width: parent.width / 2 + width: Math.floor(parent.width / 2) Label { text: catalog.i18nc("@label", "End Gcode") From 91bc023d2a9020c90d5234bae349c440a126ab97 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 26 Mar 2017 19:39:36 +0200 Subject: [PATCH 12/49] Add tabs for extruder settings --- .../MachineSettingsAction.qml | 728 +++++++++--------- 1 file changed, 377 insertions(+), 351 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index cbc7325d5c..5bbcafb945 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -12,6 +12,9 @@ import Cura 1.0 as Cura Cura.MachineAction { + id: base + property var extrudersModel: Cura.ExtrudersModel{} + anchors.fill: parent; Item { @@ -38,420 +41,443 @@ Cura.MachineAction text: catalog.i18nc("@label", "Please enter the correct settings for your printer below:") } - Column + TabView { + id: settingsTabs height: parent.height - y - width: parent.width - UM.Theme.getSize("default_margin").width - spacing: UM.Theme.getSize("default_margin").height - + width: parent.width anchors.left: parent.left anchors.top: pageDescription.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - Row + property real columnWidth: Math.floor((width - 3 * UM.Theme.getSize("default_margin").width) / 2) + + Tab { - width: parent.width - spacing: UM.Theme.getSize("default_margin").height + title: catalog.i18nc("@title:tab", "Printer"); + anchors.margins: UM.Theme.getSize("default_margin").width Column { - width: Math.floor(parent.width / 2) spacing: UM.Theme.getSize("default_margin").height - Label + Row { - text: catalog.i18nc("@label", "Printer Settings") - font.bold: true - } + width: parent.width + spacing: UM.Theme.getSize("default_margin").height - Grid - { - columns: 3 - columnSpacing: UM.Theme.getSize("default_margin").width - - Label + Column { - text: catalog.i18nc("@label", "X (Width)") - } - TextField - { - id: buildAreaWidthField - text: machineWidthProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { machineWidthProvider.setPropertyValue("value", text); manager.forceUpdate() } - } - Label - { - text: catalog.i18nc("@label", "mm") - } - - Label - { - text: catalog.i18nc("@label", "Y (Depth)") - } - TextField - { - id: buildAreaDepthField - text: machineDepthProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { machineDepthProvider.setPropertyValue("value", text); manager.forceUpdate() } - } - Label - { - text: catalog.i18nc("@label", "mm") - } - - Label - { - text: catalog.i18nc("@label", "Z (Height)") - } - TextField - { - id: buildAreaHeightField - text: machineHeightProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { machineHeightProvider.setPropertyValue("value", text); manager.forceUpdate() } - } - Label - { - text: catalog.i18nc("@label", "mm") - } - } - - Column - { - Row - { - spacing: UM.Theme.getSize("default_margin").width + width: settingsTabs.columnWidth + spacing: UM.Theme.getSize("default_margin").height Label { - text: catalog.i18nc("@label", "Build Plate Shape") + text: catalog.i18nc("@label", "Printer Settings") + font.bold: true } - ComboBox + Grid { - id: shapeComboBox - model: ListModel + columns: 3 + columnSpacing: UM.Theme.getSize("default_margin").width + + Label { - id: shapesModel - Component.onCompleted: + text: catalog.i18nc("@label", "X (Width)") + } + TextField + { + id: buildAreaWidthField + text: machineWidthProvider.properties.value + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: { machineWidthProvider.setPropertyValue("value", text); manager.forceUpdate() } + } + Label + { + text: catalog.i18nc("@label", "mm") + } + + Label + { + text: catalog.i18nc("@label", "Y (Depth)") + } + TextField + { + id: buildAreaDepthField + text: machineDepthProvider.properties.value + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: { machineDepthProvider.setPropertyValue("value", text); manager.forceUpdate() } + } + Label + { + text: catalog.i18nc("@label", "mm") + } + + Label + { + text: catalog.i18nc("@label", "Z (Height)") + } + TextField + { + id: buildAreaHeightField + text: machineHeightProvider.properties.value + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: { machineHeightProvider.setPropertyValue("value", text); manager.forceUpdate() } + } + Label + { + text: catalog.i18nc("@label", "mm") + } + } + + Column + { + Row + { + spacing: UM.Theme.getSize("default_margin").width + + Label { - // Options come in as a string-representation of an OrderedDict - var options = machineShapeProvider.properties.options.match(/^OrderedDict\(\[\((.*)\)\]\)$/); - if(options) + text: catalog.i18nc("@label", "Build Plate Shape") + } + + ComboBox + { + id: shapeComboBox + model: ListModel { - options = options[1].split("), (") - for(var i = 0; i < options.length; i++) + id: shapesModel + Component.onCompleted: { - var option = options[i].substring(1, options[i].length - 1).split("', '") - shapesModel.append({text: option[1], value: option[0]}); + // Options come in as a string-representation of an OrderedDict + var options = machineShapeProvider.properties.options.match(/^OrderedDict\(\[\((.*)\)\]\)$/); + if(options) + { + options = options[1].split("), (") + for(var i = 0; i < options.length; i++) + { + var option = options[i].substring(1, options[i].length - 1).split("', '") + shapesModel.append({text: option[1], value: option[0]}); + } + } + } + } + currentIndex: + { + var currentValue = machineShapeProvider.properties.value; + var index = 0; + for(var i = 0; i < shapesModel.count; i++) + { + if(shapesModel.get(i).value == currentValue) { + index = i; + break; + } + } + return index + } + onActivated: + { + machineShapeProvider.setPropertyValue("value", shapesModel.get(index).value); + manager.forceUpdate(); + } + } + } + CheckBox + { + id: centerIsZeroCheckBox + text: catalog.i18nc("@option:check", "Machine Center is Zero") + checked: String(machineCenterIsZeroProvider.properties.value).toLowerCase() != 'false' + onClicked: + { + machineCenterIsZeroProvider.setPropertyValue("value", checked); + manager.forceUpdate(); + } + } + CheckBox + { + id: heatedBedCheckBox + text: catalog.i18nc("@option:check", "Heated Bed") + checked: String(machineHeatedBedProvider.properties.value).toLowerCase() != 'false' + onClicked: machineHeatedBedProvider.setPropertyValue("value", checked) + } + } + + Row + { + spacing: UM.Theme.getSize("default_margin").width + + Label + { + text: catalog.i18nc("@label", "GCode Flavor") + } + + ComboBox + { + model: ListModel + { + id: flavorModel + Component.onCompleted: + { + // Options come in as a string-representation of an OrderedDict + var options = machineGCodeFlavorProvider.properties.options.match(/^OrderedDict\(\[\((.*)\)\]\)$/); + if(options) + { + options = options[1].split("), (") + for(var i = 0; i < options.length; i++) + { + var option = options[i].substring(1, options[i].length - 1).split("', '") + flavorModel.append({text: option[1], value: option[0]}); + } } } } - } - currentIndex: - { - var currentValue = machineShapeProvider.properties.value; - var index = 0; - for(var i = 0; i < shapesModel.count; i++) + currentIndex: { - if(shapesModel.get(i).value == currentValue) { - index = i; - break; + var currentValue = machineGCodeFlavorProvider.properties.value; + var index = 0; + for(var i = 0; i < flavorModel.count; i++) + { + if(flavorModel.get(i).value == currentValue) { + index = i; + break; + } + } + return index + } + onActivated: + { + machineGCodeFlavorProvider.setPropertyValue("value", flavorModel.get(index).value); + manager.updateHasMaterialsMetadata(); + } + } + } + } + + Column + { + width: settingsTabs.columnWidth + spacing: UM.Theme.getSize("default_margin").height + + Label + { + text: catalog.i18nc("@label", "Printhead Settings") + font.bold: true + } + + Grid + { + columns: 3 + columnSpacing: UM.Theme.getSize("default_margin").width + + Label + { + text: catalog.i18nc("@label", "X min") + } + TextField + { + id: printheadXMinField + text: getHeadPolygonCoord("x", "min") + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: setHeadPolygon() + } + Label + { + text: catalog.i18nc("@label", "mm") + } + + Label + { + text: catalog.i18nc("@label", "Y min") + } + TextField + { + id: printheadYMinField + text: getHeadPolygonCoord("y", "min") + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: setHeadPolygon() + } + Label + { + text: catalog.i18nc("@label", "mm") + } + + Label + { + text: catalog.i18nc("@label", "X max") + } + TextField + { + id: printheadXMaxField + text: getHeadPolygonCoord("x", "max") + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: setHeadPolygon() + } + Label + { + text: catalog.i18nc("@label", "mm") + } + + Label + { + text: catalog.i18nc("@label", "Y max") + } + TextField + { + id: printheadYMaxField + text: getHeadPolygonCoord("y", "max") + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: setHeadPolygon() + } + Label + { + text: catalog.i18nc("@label", "mm") + } + + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + + Label + { + text: catalog.i18nc("@label", "Gantry height") + } + TextField + { + id: gantryHeightField + text: gantryHeightProvider.properties.value + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: { gantryHeightProvider.setPropertyValue("value", text) } + } + Label + { + text: catalog.i18nc("@label", "mm") + } + + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + + Label + { + text: catalog.i18nc("@label", "Number of Extruders") + visible: extruderCountComboBox.visible + } + + ComboBox + { + id: extruderCountComboBox + visible: manager.definedExtruderCount > 1 + model: ListModel + { + id: extruderCountModel + Component.onCompleted: + { + for(var i = 0; i < manager.definedExtruderCount; i++) + { + extruderCountModel.append({text: String(i + 1), value: i}); + } } } - return index + currentIndex: machineExtruderCountProvider.properties.value - 1 + onActivated: + { + machineExtruderCountProvider.setPropertyValue("value", index + 1); + manager.forceUpdate(); + } } - onActivated: + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height; visible: extruderCountComboBox.visible } + + + Label { - machineShapeProvider.setPropertyValue("value", shapesModel.get(index).value); - manager.forceUpdate(); + text: catalog.i18nc("@label", "Nozzle size") + visible: nozzleSizeField.visible } + TextField + { + id: nozzleSizeField + text: machineNozzleSizeProvider.properties.value + visible: !Cura.MachineManager.hasVariants && machineExtruderCountProvider.properties.value == 1 + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: { machineNozzleSizeProvider.setPropertyValue("value", text) } + } + Label + { + text: catalog.i18nc("@label", "mm") + visible: nozzleSizeField.visible + } } } - CheckBox - { - id: centerIsZeroCheckBox - text: catalog.i18nc("@option:check", "Machine Center is Zero") - checked: String(machineCenterIsZeroProvider.properties.value).toLowerCase() != 'false' - onClicked: - { - machineCenterIsZeroProvider.setPropertyValue("value", checked); - manager.forceUpdate(); - } - } - CheckBox - { - id: heatedBedCheckBox - text: catalog.i18nc("@option:check", "Heated Bed") - checked: String(machineHeatedBedProvider.properties.value).toLowerCase() != 'false' - onClicked: machineHeatedBedProvider.setPropertyValue("value", checked) - } } Row { spacing: UM.Theme.getSize("default_margin").width - - Label + anchors.left: parent.left + anchors.right: parent.right + height: parent.height - y + Column { - text: catalog.i18nc("@label", "GCode Flavor") - } - - ComboBox - { - model: ListModel + height: parent.height + width: settingsTabs.columnWidth + Label { - id: flavorModel - Component.onCompleted: + text: catalog.i18nc("@label", "Start Gcode") + } + TextArea + { + id: machineStartGcodeField + width: parent.width + height: parent.height - y + font: UM.Theme.getFont("fixed") + wrapMode: TextEdit.NoWrap + text: machineStartGcodeProvider.properties.value + onActiveFocusChanged: { - // Options come in as a string-representation of an OrderedDict - var options = machineGCodeFlavorProvider.properties.options.match(/^OrderedDict\(\[\((.*)\)\]\)$/); - if(options) + if(!activeFocus) { - options = options[1].split("), (") - for(var i = 0; i < options.length; i++) - { - var option = options[i].substring(1, options[i].length - 1).split("', '") - flavorModel.append({text: option[1], value: option[0]}); - } + machineStartGcodeProvider.setPropertyValue("value", machineStartGcodeField.text) } } } - currentIndex: + } + Column { + height: parent.height + width: settingsTabs.columnWidth + Label { - var currentValue = machineGCodeFlavorProvider.properties.value; - var index = 0; - for(var i = 0; i < flavorModel.count; i++) - { - if(flavorModel.get(i).value == currentValue) { - index = i; - break; - } - } - return index + text: catalog.i18nc("@label", "End Gcode") } - onActivated: + TextArea { - machineGCodeFlavorProvider.setPropertyValue("value", flavorModel.get(index).value); - manager.updateHasMaterialsMetadata(); - } - } - } - } - - Column - { - width: Math.floor(parent.width / 2) - spacing: UM.Theme.getSize("default_margin").height - - Label - { - text: catalog.i18nc("@label", "Printhead Settings") - font.bold: true - } - - Grid - { - columns: 3 - columnSpacing: UM.Theme.getSize("default_margin").width - - Label - { - text: catalog.i18nc("@label", "X min") - } - TextField - { - id: printheadXMinField - text: getHeadPolygonCoord("x", "min") - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: setHeadPolygon() - } - Label - { - text: catalog.i18nc("@label", "mm") - } - - Label - { - text: catalog.i18nc("@label", "Y min") - } - TextField - { - id: printheadYMinField - text: getHeadPolygonCoord("y", "min") - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: setHeadPolygon() - } - Label - { - text: catalog.i18nc("@label", "mm") - } - - Label - { - text: catalog.i18nc("@label", "X max") - } - TextField - { - id: printheadXMaxField - text: getHeadPolygonCoord("x", "max") - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: setHeadPolygon() - } - Label - { - text: catalog.i18nc("@label", "mm") - } - - Label - { - text: catalog.i18nc("@label", "Y max") - } - TextField - { - id: printheadYMaxField - text: getHeadPolygonCoord("y", "max") - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: setHeadPolygon() - } - Label - { - text: catalog.i18nc("@label", "mm") - } - - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } - - Label - { - text: catalog.i18nc("@label", "Gantry height") - } - TextField - { - id: gantryHeightField - text: gantryHeightProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { gantryHeightProvider.setPropertyValue("value", text) } - } - Label - { - text: catalog.i18nc("@label", "mm") - } - - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } - - Label - { - text: catalog.i18nc("@label", "Number of Extruders") - visible: extruderCountComboBox.visible - } - - ComboBox - { - id: extruderCountComboBox - visible: manager.definedExtruderCount > 1 - model: ListModel - { - id: extruderCountModel - Component.onCompleted: + id: machineEndGcodeField + width: parent.width + height: parent.height - y + font: UM.Theme.getFont("fixed") + wrapMode: TextEdit.NoWrap + text: machineEndGcodeProvider.properties.value + onActiveFocusChanged: { - for(var i = 0; i < manager.definedExtruderCount; i++) + if(!activeFocus) { - extruderCountModel.append({text: String(i + 1), value: i}); + machineEndGcodeProvider.setPropertyValue("value", machineEndGcodeField.text) } } } - currentIndex: machineExtruderCountProvider.properties.value - 1 - onActivated: - { - machineExtruderCountProvider.setPropertyValue("value", index + 1); - manager.forceUpdate(); - } } - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height; visible: extruderCountComboBox.visible } - - - Label - { - text: catalog.i18nc("@label", "Nozzle size") - visible: nozzleSizeField.visible - } - TextField - { - id: nozzleSizeField - text: machineNozzleSizeProvider.properties.value - visible: !Cura.MachineManager.hasVariants && machineExtruderCountProvider.properties.value == 1 - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { machineNozzleSizeProvider.setPropertyValue("value", text) } - } - Label - { - text: catalog.i18nc("@label", "mm") - visible: nozzleSizeField.visible - } } } } - Row + Repeater { - spacing: UM.Theme.getSize("default_margin").width - anchors.left: parent.left - anchors.right: parent.right - height: parent.height - y - Column + model: (machineExtruderCountProvider.properties.value > 1) ? base.extrudersModel : 0 + + Tab { - height: parent.height - width: Math.floor(parent.width / 2) - Label - { - text: catalog.i18nc("@label", "Start Gcode") - } - TextArea - { - id: machineStartGcodeField - width: parent.width - height: parent.height - y - font: UM.Theme.getFont("fixed") - wrapMode: TextEdit.NoWrap - text: machineStartGcodeProvider.properties.value - onActiveFocusChanged: - { - if(!activeFocus) - { - machineStartGcodeProvider.setPropertyValue("value", machineStartGcodeField.text) - } - } - } - } - Column { - height: parent.height - width: Math.floor(parent.width / 2) - Label - { - text: catalog.i18nc("@label", "End Gcode") - } - TextArea - { - id: machineEndGcodeField - width: parent.width - height: parent.height - y - font: UM.Theme.getFont("fixed") - wrapMode: TextEdit.NoWrap - text: machineEndGcodeProvider.properties.value - onActiveFocusChanged: - { - if(!activeFocus) - { - machineEndGcodeProvider.setPropertyValue("value", machineEndGcodeField.text) - } - } - } + title: model.name + anchors.margins: UM.Theme.getSize("default_margin").width } } } From af280047d1eebc77fc35c215412e2cd30cc54986 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 6 Apr 2017 11:35:56 +0200 Subject: [PATCH 13/49] Add extruder fields for start/end gcode, offset, nozzle size (non-functional) --- .../MachineSettingsAction.qml | 195 ++++++++++++++++-- 1 file changed, 181 insertions(+), 14 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 5bbcafb945..8744f6fffc 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -31,15 +31,6 @@ Cura.MachineAction wrapMode: Text.WordWrap font.pointSize: 18; } - Label - { - id: pageDescription - anchors.top: pageTitle.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width - wrapMode: Text.WordWrap - text: catalog.i18nc("@label", "Please enter the correct settings for your printer below:") - } TabView { @@ -47,7 +38,7 @@ Cura.MachineAction height: parent.height - y width: parent.width anchors.left: parent.left - anchors.top: pageDescription.bottom + anchors.top: pageTitle.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height property real columnWidth: Math.floor((width - 3 * UM.Theme.getSize("default_margin").width) / 2) @@ -81,6 +72,7 @@ Cura.MachineAction { columns: 3 columnSpacing: UM.Theme.getSize("default_margin").width + rowSpacing: UM.Theme.getSize("default_lining").width Label { @@ -269,6 +261,7 @@ Cura.MachineAction { columns: 3 columnSpacing: UM.Theme.getSize("default_margin").width + rowSpacing: UM.Theme.getSize("default_lining").width Label { @@ -405,8 +398,8 @@ Cura.MachineAction Label { text: catalog.i18nc("@label", "mm") - visible: nozzleSizeField.visible - } + visible: nozzleSizeField.visible + } } } } @@ -472,12 +465,135 @@ Cura.MachineAction Repeater { - model: (machineExtruderCountProvider.properties.value > 1) ? base.extrudersModel : 0 + model: (machineExtruderCountProvider.properties.value > 1) ? parseInt(machineExtruderCountProvider.properties.value) : 0 Tab { - title: model.name + title: base.extrudersModel.getItem(index).name anchors.margins: UM.Theme.getSize("default_margin").width + + Column + { + spacing: UM.Theme.getSize("default_margin").width + + Label + { + text: catalog.i18nc("@label", "Printer Settings") + font.bold: true + } + + Grid + { + columns: 3 + columnSpacing: UM.Theme.getSize("default_margin").width + rowSpacing: UM.Theme.getSize("default_lining").width + + Label + { + text: catalog.i18nc("@label", "Nozzle size") + } + TextField + { + id: extruderNozzleSizeField + text: extruderNozzleSizeProvider.properties.value + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: { extruderNozzleSizeProvider.setPropertyValue("value", text) } + } + Label + { + text: catalog.i18nc("@label", "mm") + } + + Label + { + text: catalog.i18nc("@label", "Nozzle offset X") + } + TextField + { + id: extruderOffsetXField + text: extruderOffsetXProvider.properties.value + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: { extruderOffsetXProvider.setPropertyValue("value", text) } + } + Label + { + text: catalog.i18nc("@label", "mm") + } + Label + { + text: catalog.i18nc("@label", "Nozzle offset Y") + } + TextField + { + id: extruderOffsetYField + text: extruderOffsetYProvider.properties.value + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: { extruderOffsetYProvider.setPropertyValue("value", text) } + } + Label + { + text: catalog.i18nc("@label", "mm") + } + + } + + Row + { + spacing: UM.Theme.getSize("default_margin").width + anchors.left: parent.left + anchors.right: parent.right + height: parent.height - y + Column + { + height: parent.height + width: settingsTabs.columnWidth + Label + { + text: catalog.i18nc("@label", "Extruder Start Gcode") + } + TextArea + { + id: extruderStartGcodeField + width: parent.width + height: parent.height - y + font: UM.Theme.getFont("fixed") + wrapMode: TextEdit.NoWrap + text: extruderStartGcodeProvider.properties.value + onActiveFocusChanged: + { + if(!activeFocus) + { + extruderStartGcodeProvider.setPropertyValue("value", extruderStartGcodeField.text) + } + } + } + } + Column { + height: parent.height + width: settingsTabs.columnWidth + Label + { + text: catalog.i18nc("@label", "Extruder End Gcode") + } + TextArea + { + id: extruderEndGcodeField + width: parent.width + height: parent.height - y + font: UM.Theme.getFont("fixed") + wrapMode: TextEdit.NoWrap + text: extruderEndGcodeProvider.properties.value + onActiveFocusChanged: + { + if(!activeFocus) + { + extruderEndGcodeProvider.setPropertyValue("value", extruderEndGcodeField.text) + } + } + } + } + } + } } } } @@ -640,4 +756,55 @@ Cura.MachineAction storeIndex: manager.containerIndex } + UM.SettingPropertyProvider + { + id: extruderNozzleSizeProvider + + containerStackId: Cura.MachineManager.activeStackId + key: "machine_nozzle_size" + watchedProperties: [ "value" ] + storeIndex: manager.containerIndex + } + + UM.SettingPropertyProvider + { + id: extruderOffsetXProvider + + containerStackId: Cura.MachineManager.activeStackId + key: "machine_nozzle_offset_x" + watchedProperties: [ "value" ] + storeIndex: manager.containerIndex + } + + UM.SettingPropertyProvider + { + id: extruderOffsetYProvider + + containerStackId: Cura.MachineManager.activeStackId + key: "machine_nozzle_offset_y" + watchedProperties: [ "value" ] + storeIndex: manager.containerIndex + } + + UM.SettingPropertyProvider + { + id: extruderStartGcodeProvider + + containerStackId: Cura.MachineManager.activeStackId + key: "machine_extruder_start_code" + watchedProperties: [ "value" ] + storeIndex: manager.containerIndex + } + + UM.SettingPropertyProvider + { + id: extruderEndGcodeProvider + + containerStackId: Cura.MachineManager.activeStackId + key: "machine_extruder_end_code" + watchedProperties: [ "value" ] + storeIndex: manager.containerIndex + } + + } \ No newline at end of file From 818043854db4c56e799391e86dbc2966b64725b7 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 6 Apr 2017 11:44:09 +0200 Subject: [PATCH 14/49] Set active extruder when switching extruder tabs in Machine Settings We can only get/set profiles for the active extruder. --- plugins/MachineSettingsAction/MachineSettingsAction.qml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 8744f6fffc..c8027d75bf 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -463,6 +463,14 @@ Cura.MachineAction } } + onCurrentIndexChanged: + { + if(currentIndex > 0) + { + ExtruderManager.setActiveExtruderIndex(currentIndex - 1); + } + } + Repeater { model: (machineExtruderCountProvider.properties.value > 1) ? parseInt(machineExtruderCountProvider.properties.value) : 0 From 7bc28a7e489c105956affd10810b46db68119668 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 6 Apr 2017 21:02:33 +0200 Subject: [PATCH 15/49] Make sure a valid stack is activated after changing the number of extruders --- .../MachineSettingsAction.qml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index c8027d75bf..2801f25aed 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -377,6 +377,26 @@ Cura.MachineAction { machineExtruderCountProvider.setPropertyValue("value", index + 1); manager.forceUpdate(); + if(index > 0) + { + // multiextrusion; make sure one of these extruder stacks is active + if(ExtruderManager.activeExtruderIndex == -1) + { + ExtruderManager.setActiveExtruderIndex(0); + } + else if(ExtruderManager.activeExtruderIndex > index) + { + ExtruderManager.setActiveExtruderIndex(index); + } + } + else + { + // single extrusion; make sure the machine stack is active + if(ExtruderManager.activeExtruderIndex != -1) + { + ExtruderManager.setActiveExtruderIndex(-1); + } + } } } Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height; visible: extruderCountComboBox.visible } @@ -435,6 +455,7 @@ Cura.MachineAction } } } + Column { height: parent.height width: settingsTabs.columnWidth From 5b37353b087b3ff5b3968d89b0f2c0b737c5c9b9 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 7 Apr 2017 11:55:07 +0200 Subject: [PATCH 16/49] Fix stuck extruder tabs when switching number of extruders --- .../MachineSettingsAction.qml | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 2801f25aed..e8a255c483 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -14,6 +14,23 @@ Cura.MachineAction { id: base property var extrudersModel: Cura.ExtrudersModel{} + property int extruderTabsCount: 0 + + Component.onCompleted: + { + // Populate extruder tabs after a short delay, because otherwise the tabs that are added when + // the dialog is created are stuck. + extruderTabsCountDelay.start(); + } + + Timer + { + id: extruderTabsCountDelay + repeat: false + interval: 1 + + onTriggered: base.extruderTabsCount = (machineExtruderCountProvider.properties.value > 1) ? parseInt(machineExtruderCountProvider.properties.value) : 0 + } anchors.fill: parent; Item @@ -377,6 +394,8 @@ Cura.MachineAction { machineExtruderCountProvider.setPropertyValue("value", index + 1); manager.forceUpdate(); + base.extruderTabsCount = (index > 0) ? index + 1 : 0; + if(index > 0) { // multiextrusion; make sure one of these extruder stacks is active @@ -384,10 +403,6 @@ Cura.MachineAction { ExtruderManager.setActiveExtruderIndex(0); } - else if(ExtruderManager.activeExtruderIndex > index) - { - ExtruderManager.setActiveExtruderIndex(index); - } } else { @@ -488,19 +503,22 @@ Cura.MachineAction { if(currentIndex > 0) { - ExtruderManager.setActiveExtruderIndex(currentIndex - 1); + ExtruderManager.setActiveExtruderIndex(settingsTabs.getTab(currentIndex).extruderIndex); } } Repeater { - model: (machineExtruderCountProvider.properties.value > 1) ? parseInt(machineExtruderCountProvider.properties.value) : 0 + id: extruderTabsRepeater + model: base.extruderTabsCount Tab { title: base.extrudersModel.getItem(index).name anchors.margins: UM.Theme.getSize("default_margin").width + property int extruderIndex: index + Column { spacing: UM.Theme.getSize("default_margin").width From 064f744bc042f57f5ecf72e3edc1e45dde63322d Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 9 Apr 2017 15:47:35 +0200 Subject: [PATCH 17/49] Make sure we're not trying to get/set extruder values on machine stacks --- .../MachineSettingsAction/MachineSettingsAction.qml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index e8a255c483..20ec99edf3 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -807,7 +807,7 @@ Cura.MachineAction { id: extruderNozzleSizeProvider - containerStackId: Cura.MachineManager.activeStackId + containerStackId: Cura.ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_nozzle_size" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -817,7 +817,7 @@ Cura.MachineAction { id: extruderOffsetXProvider - containerStackId: Cura.MachineManager.activeStackId + containerStackId: Cura.ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_nozzle_offset_x" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -827,7 +827,7 @@ Cura.MachineAction { id: extruderOffsetYProvider - containerStackId: Cura.MachineManager.activeStackId + containerStackId: Cura.ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_nozzle_offset_y" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -837,7 +837,7 @@ Cura.MachineAction { id: extruderStartGcodeProvider - containerStackId: Cura.MachineManager.activeStackId + containerStackId: Cura.ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_extruder_start_code" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -847,11 +847,9 @@ Cura.MachineAction { id: extruderEndGcodeProvider - containerStackId: Cura.MachineManager.activeStackId + containerStackId: Cura.ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_extruder_end_code" watchedProperties: [ "value" ] storeIndex: manager.containerIndex } - - } \ No newline at end of file From 7bad71882389f168e0cc739d0b47cfd9da9b709f Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 10 Apr 2017 13:36:16 +0200 Subject: [PATCH 18/49] Don't update the global container stack unnecessarily --- .../MachineSettingsAction.qml | 59 ++++++++++++++----- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 20ec99edf3..86b834c67c 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -100,7 +100,14 @@ Cura.MachineAction id: buildAreaWidthField text: machineWidthProvider.properties.value validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { machineWidthProvider.setPropertyValue("value", text); manager.forceUpdate() } + onEditingFinished: + { + if (text != machineWidthProvider.properties.value) + { + machineWidthProvider.setPropertyValue("value", text); + manager.forceUpdate(); + } + } } Label { @@ -116,7 +123,13 @@ Cura.MachineAction id: buildAreaDepthField text: machineDepthProvider.properties.value validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { machineDepthProvider.setPropertyValue("value", text); manager.forceUpdate() } + onEditingFinished: { + if (text != machineDepthProvider.properties.value) + { + machineDepthProvider.setPropertyValue("value", text); + manager.forceUpdate(); + } + } } Label { @@ -132,7 +145,13 @@ Cura.MachineAction id: buildAreaHeightField text: machineHeightProvider.properties.value validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { machineHeightProvider.setPropertyValue("value", text); manager.forceUpdate() } + onEditingFinished: { + if (text != machineHeightProvider.properties.value) + { + machineHeightProvider.setPropertyValue("value", text); + manager.forceUpdate(); + } + } } Label { @@ -187,8 +206,11 @@ Cura.MachineAction } onActivated: { - machineShapeProvider.setPropertyValue("value", shapesModel.get(index).value); - manager.forceUpdate(); + if(machineShapeProvider.properties.value != shapesModel.get(index).value) + { + machineShapeProvider.setPropertyValue("value", shapesModel.get(index).value); + manager.forceUpdate(); + } } } } @@ -392,6 +414,11 @@ Cura.MachineAction currentIndex: machineExtruderCountProvider.properties.value - 1 onActivated: { + if(machineExtruderCountProvider.properties.value == index + 1) + { + return; + } + machineExtruderCountProvider.setPropertyValue("value", index + 1); manager.forceUpdate(); base.extruderTabsCount = (index > 0) ? index + 1 : 0; @@ -503,7 +530,7 @@ Cura.MachineAction { if(currentIndex > 0) { - ExtruderManager.setActiveExtruderIndex(settingsTabs.getTab(currentIndex).extruderIndex); + ExtruderManager.setActiveExtruderIndex(currentIndex - 1); } } @@ -517,8 +544,6 @@ Cura.MachineAction title: base.extrudersModel.getItem(index).name anchors.margins: UM.Theme.getSize("default_margin").width - property int extruderIndex: index - Column { spacing: UM.Theme.getSize("default_margin").width @@ -668,8 +693,12 @@ Cura.MachineAction polygon.push([-parseFloat(printheadXMinField.text),-parseFloat(printheadYMinField.text)]); polygon.push([ parseFloat(printheadXMaxField.text), parseFloat(printheadYMaxField.text)]); polygon.push([ parseFloat(printheadXMaxField.text),-parseFloat(printheadYMinField.text)]); - machineHeadPolygonProvider.setPropertyValue("value", JSON.stringify(polygon)); - manager.forceUpdate(); + var polygon_string = JSON.stringify(polygon); + if(polygon != machineHeadPolygonProvider.properties.value) + { + machineHeadPolygonProvider.setPropertyValue("value", polygon_string); + manager.forceUpdate(); + } } UM.SettingPropertyProvider @@ -807,7 +836,7 @@ Cura.MachineAction { id: extruderNozzleSizeProvider - containerStackId: Cura.ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" + containerStackId: ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_nozzle_size" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -817,7 +846,7 @@ Cura.MachineAction { id: extruderOffsetXProvider - containerStackId: Cura.ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" + containerStackId: ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_nozzle_offset_x" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -827,7 +856,7 @@ Cura.MachineAction { id: extruderOffsetYProvider - containerStackId: Cura.ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" + containerStackId: ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_nozzle_offset_y" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -837,7 +866,7 @@ Cura.MachineAction { id: extruderStartGcodeProvider - containerStackId: Cura.ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" + containerStackId: ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_extruder_start_code" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -847,7 +876,7 @@ Cura.MachineAction { id: extruderEndGcodeProvider - containerStackId: Cura.ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" + containerStackId: ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_extruder_end_code" watchedProperties: [ "value" ] storeIndex: manager.containerIndex From c89669e73e1df69637b1d48f7f4da150f656ebbf Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 10 Apr 2017 16:22:20 +0200 Subject: [PATCH 19/49] Layout & code style: move unit into numeric textfield component --- .../MachineSettingsAction.qml | 186 ++++++++---------- 1 file changed, 79 insertions(+), 107 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 86b834c67c..babb9a6abb 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -87,7 +87,7 @@ Cura.MachineAction Grid { - columns: 3 + columns: 2 columnSpacing: UM.Theme.getSize("default_margin").width rowSpacing: UM.Theme.getSize("default_lining").width @@ -95,67 +95,39 @@ Cura.MachineAction { text: catalog.i18nc("@label", "X (Width)") } - TextField + Loader { id: buildAreaWidthField - text: machineWidthProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: - { - if (text != machineWidthProvider.properties.value) - { - machineWidthProvider.setPropertyValue("value", text); - manager.forceUpdate(); - } - } - } - Label - { - text: catalog.i18nc("@label", "mm") + sourceComponent: numericTextFieldWithUnit + property var propertyProvider: machineWidthProvider + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: true } Label { text: catalog.i18nc("@label", "Y (Depth)") } - TextField + Loader { id: buildAreaDepthField - text: machineDepthProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { - if (text != machineDepthProvider.properties.value) - { - machineDepthProvider.setPropertyValue("value", text); - manager.forceUpdate(); - } - } - } - Label - { - text: catalog.i18nc("@label", "mm") + sourceComponent: numericTextFieldWithUnit + property var propertyProvider: machineDepthProvider + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: true } Label { text: catalog.i18nc("@label", "Z (Height)") } - TextField + Loader { id: buildAreaHeightField - text: machineHeightProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { - if (text != machineHeightProvider.properties.value) - { - machineHeightProvider.setPropertyValue("value", text); - manager.forceUpdate(); - } - } - } - Label - { - text: catalog.i18nc("@label", "mm") + sourceComponent: numericTextFieldWithUnit + property var propertyProvider: machineHeightProvider + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: true } } @@ -298,7 +270,7 @@ Cura.MachineAction Grid { - columns: 3 + columns: 2 columnSpacing: UM.Theme.getSize("default_margin").width rowSpacing: UM.Theme.getSize("default_lining").width @@ -313,10 +285,6 @@ Cura.MachineAction validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } onEditingFinished: setHeadPolygon() } - Label - { - text: catalog.i18nc("@label", "mm") - } Label { @@ -329,10 +297,6 @@ Cura.MachineAction validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } onEditingFinished: setHeadPolygon() } - Label - { - text: catalog.i18nc("@label", "mm") - } Label { @@ -345,10 +309,6 @@ Cura.MachineAction validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } onEditingFinished: setHeadPolygon() } - Label - { - text: catalog.i18nc("@label", "mm") - } Label { @@ -361,12 +321,7 @@ Cura.MachineAction validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } onEditingFinished: setHeadPolygon() } - Label - { - text: catalog.i18nc("@label", "mm") - } - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } @@ -374,19 +329,15 @@ Cura.MachineAction { text: catalog.i18nc("@label", "Gantry height") } - TextField + Loader { id: gantryHeightField - text: gantryHeightProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { gantryHeightProvider.setPropertyValue("value", text) } - } - Label - { - text: catalog.i18nc("@label", "mm") + sourceComponent: numericTextFieldWithUnit + property var propertyProvider: gantryHeightProvider + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: false } - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } @@ -441,7 +392,6 @@ Cura.MachineAction } } } - Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height; visible: extruderCountComboBox.visible } Label @@ -449,18 +399,14 @@ Cura.MachineAction text: catalog.i18nc("@label", "Nozzle size") visible: nozzleSizeField.visible } - TextField + Loader { id: nozzleSizeField - text: machineNozzleSizeProvider.properties.value visible: !Cura.MachineManager.hasVariants && machineExtruderCountProvider.properties.value == 1 - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { machineNozzleSizeProvider.setPropertyValue("value", text) } - } - Label - { - text: catalog.i18nc("@label", "mm") - visible: nozzleSizeField.visible + sourceComponent: numericTextFieldWithUnit + property var propertyProvider: machineNozzleSizeProvider + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: false } } } @@ -556,57 +502,49 @@ Cura.MachineAction Grid { - columns: 3 + columns: 2 columnSpacing: UM.Theme.getSize("default_margin").width rowSpacing: UM.Theme.getSize("default_lining").width Label { text: catalog.i18nc("@label", "Nozzle size") + visible: extruderNozzleSizeField.visible } - TextField + Loader { id: extruderNozzleSizeField - text: extruderNozzleSizeProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { extruderNozzleSizeProvider.setPropertyValue("value", text) } - } - Label - { - text: catalog.i18nc("@label", "mm") + visible: !Cura.MachineManager.hasVariants + sourceComponent: numericTextFieldWithUnit + property var propertyProvider: extruderNozzleSizeProvider + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: false } Label { text: catalog.i18nc("@label", "Nozzle offset X") } - TextField + Loader { id: extruderOffsetXField - text: extruderOffsetXProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { extruderOffsetXProvider.setPropertyValue("value", text) } - } - Label - { - text: catalog.i18nc("@label", "mm") + sourceComponent: numericTextFieldWithUnit + property var propertyProvider: extruderOffsetXProvider + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: false } Label { text: catalog.i18nc("@label", "Nozzle offset Y") } - TextField + Loader { id: extruderOffsetYField - text: extruderOffsetYProvider.properties.value - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: { extruderOffsetYProvider.setPropertyValue("value", text) } + sourceComponent: numericTextFieldWithUnit + property var propertyProvider: extruderOffsetYProvider + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: false } - Label - { - text: catalog.i18nc("@label", "mm") - } - } Row @@ -701,6 +639,40 @@ Cura.MachineAction } } + Component + { + id: numericTextFieldWithUnit + Item { + height: textField.height + width: textField.width + TextField + { + id: textField + text: propertyProvider.properties.value + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: + { + if (propertyProvider && text != propertyProvider.properties.value) + { + propertyProvider.setPropertyValue("value", text); + if(forceUpdateOnChange) + { + manager.forceUpdate(); + } + } + } + } + + Label + { + text: unit + anchors.right: textField.right + anchors.rightMargin: y - textField.y + anchors.verticalCenter: textField.verticalCenter + } + } + } + UM.SettingPropertyProvider { id: machineWidthProvider From 499971d55cbad20bc8805bb24f763b4f7f4f183a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 10 Apr 2017 17:24:02 +0200 Subject: [PATCH 20/49] Fix loading values on 1st extruder tab --- .../MachineSettingsAction/MachineSettingsAction.qml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index babb9a6abb..fa4d62b5e1 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -808,7 +808,7 @@ Cura.MachineAction { id: extruderNozzleSizeProvider - containerStackId: ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" + containerStackId: settingsTabs.currentIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_nozzle_size" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -818,7 +818,7 @@ Cura.MachineAction { id: extruderOffsetXProvider - containerStackId: ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" + containerStackId: settingsTabs.currentIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_nozzle_offset_x" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -828,7 +828,7 @@ Cura.MachineAction { id: extruderOffsetYProvider - containerStackId: ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" + containerStackId: settingsTabs.currentIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_nozzle_offset_y" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -838,7 +838,7 @@ Cura.MachineAction { id: extruderStartGcodeProvider - containerStackId: ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" + containerStackId: settingsTabs.currentIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_extruder_start_code" watchedProperties: [ "value" ] storeIndex: manager.containerIndex @@ -848,7 +848,7 @@ Cura.MachineAction { id: extruderEndGcodeProvider - containerStackId: ExtruderManager.activeExtruderIndex > 0 ? Cura.MachineManager.activeStackId : "" + containerStackId: settingsTabs.currentIndex > 0 ? Cura.MachineManager.activeStackId : "" key: "machine_extruder_end_code" watchedProperties: [ "value" ] storeIndex: manager.containerIndex From df7f039826349c4592e07fedc5773dda4c2a2452 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 10 Apr 2017 18:16:00 +0200 Subject: [PATCH 21/49] Store extruder settings in definition_changes containers --- .../MachineSettingsAction.py | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 1feb748006..ec8ce7102e 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -13,6 +13,7 @@ from UM.Settings.DefinitionContainer import DefinitionContainer from UM.Logger import Logger from cura.Settings.CuraContainerRegistry import CuraContainerRegistry +from cura.Settings.ExtruderManager import ExtruderManager import UM.i18n catalog = UM.i18n.i18nCatalog("cura") @@ -26,10 +27,12 @@ class MachineSettingsAction(MachineAction): self._qml_url = "MachineSettingsAction.qml" self._container_index = 0 + self._extruder_container_index = 0 self._container_registry = ContainerRegistry.getInstance() self._container_registry.containerAdded.connect(self._onContainerAdded) Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) + ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) def _reset(self): global_container_stack = Application.getInstance().getGlobalContainerStack() @@ -39,7 +42,7 @@ class MachineSettingsAction(MachineAction): # Make sure there is a definition_changes container to store the machine settings definition_changes_container = global_container_stack.findContainer({"type": "definition_changes"}) if not definition_changes_container: - definition_changes_container = self._createDefinitionChangesContainer(global_container_stack) + definition_changes_container = self._createDefinitionChangesContainer(global_container_stack, global_container_stack.getName() + "_settings") # Notify the UI in which container to store the machine settings data container_index = global_container_stack.getContainerIndex(definition_changes_container) @@ -47,15 +50,32 @@ class MachineSettingsAction(MachineAction): self._container_index = container_index self.containerIndexChanged.emit() - def _createDefinitionChangesContainer(self, global_container_stack, container_index = None): - definition_changes_container = InstanceContainer(global_container_stack.getName() + "_settings") - definition = global_container_stack.getBottom() + def _onActiveExtruderStackChanged(self): + global_container_stack = Application.getInstance().getGlobalContainerStack() + extruder_container_stack = ExtruderManager.getInstance().getActiveExtruderStack() + if not global_container_stack or not extruder_container_stack: + return + + # Make sure there is a definition_changes container to store the machine settings + definition_changes_container = extruder_container_stack.findContainer({"type": "definition_changes"}) + if not definition_changes_container: + definition_changes_container = self._createDefinitionChangesContainer(extruder_container_stack, global_container_stack.getName() + "_" + extruder_container_stack.getId() + "_settings") + + # Notify the UI in which container to store the machine settings data + container_index = extruder_container_stack.getContainerIndex(definition_changes_container) + if container_index != self._extruder_container_index: + self._extruder_container_index = container_index + self.extruderContainerIndexChanged.emit() + + def _createDefinitionChangesContainer(self, container_stack, container_name, container_index = None): + definition_changes_container = InstanceContainer(container_name) + definition = container_stack.getBottom() definition_changes_container.setDefinition(definition) definition_changes_container.addMetaDataEntry("type", "definition_changes") self._container_registry.addContainer(definition_changes_container) # Insert definition_changes between the definition and the variant - global_container_stack.insertContainer(-1, definition_changes_container) + container_stack.insertContainer(-1, definition_changes_container) return definition_changes_container @@ -65,6 +85,13 @@ class MachineSettingsAction(MachineAction): def containerIndex(self): return self._container_index + extruderContainerIndexChanged = pyqtSignal() + + @pyqtProperty(int, notify = extruderContainerIndexChanged) + def extruderContainerIndex(self): + return self._extruder_container_index + + def _onContainerAdded(self, container): # Add this action as a supported action to all machine definitions if isinstance(container, DefinitionContainer) and container.getMetaDataEntry("type") == "machine": From 6dd642469ad98d0eb28e84c3bc1a349d73d4d709 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 10 Apr 2017 20:37:41 +0200 Subject: [PATCH 22/49] Set value before activating another extruder Because all extruder tabs share the same SettingPropertyProvider, we want the property provider value to update before its container stack is changed, or the value carries over to the other containerstack, leaving the value for the initial containerstack unchanged --- plugins/MachineSettingsAction/MachineSettingsAction.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index fa4d62b5e1..e7f17f3b26 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -476,6 +476,7 @@ Cura.MachineAction { if(currentIndex > 0) { + contentItem.forceActiveFocus(); ExtruderManager.setActiveExtruderIndex(currentIndex - 1); } } From 31ecb30c037dd05f84d2325af4750653453b6986 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 10 Apr 2017 22:30:43 +0200 Subject: [PATCH 23/49] Allow setting the nozzle size through the extruder definition --- resources/definitions/fdmextruder.def.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index 7c594e3eda..48cf750468 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -29,6 +29,18 @@ "settable_per_meshgroup": false, "settable_globally": false }, + "machine_nozzle_size": + { + "label": "Nozzle Diameter", + "description": "The inner diameter of the nozzle. Change this setting when using a non-standard nozzle size.", + "unit": "mm", + "type": "float", + "default_value": 0.4, + "minimum_value": "0.001", + "maximum_value_warning": "10", + "settable_per_mesh": false, + "settable_per_extruder": true + }, "machine_nozzle_offset_x": { "label": "Nozzle X Offset", From f15345a0cbcec60820292651e6f9bcc083bc5a32 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Apr 2017 12:18:33 +0200 Subject: [PATCH 24/49] Restore material on global stack when switching back to single extrusion MachineManager._onGlobalContainerChanged removes the global material of multiextruder machines --- .../MachineSettingsAction/MachineSettingsAction.qml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index e7f17f3b26..2456b62ddc 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -370,6 +370,13 @@ Cura.MachineAction return; } + var extruder_material; + if(index == 0 && Cura.MachineManager.hasMaterials) + { + // setting back to single extrusion + extruder_material = Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeStackId]; + } + machineExtruderCountProvider.setPropertyValue("value", index + 1); manager.forceUpdate(); base.extruderTabsCount = (index > 0) ? index + 1 : 0; @@ -389,6 +396,12 @@ Cura.MachineAction { ExtruderManager.setActiveExtruderIndex(-1); } + if(extruder_material) + { + // restore material on global stack + // MachineManager._onGlobalContainerChanged removes the global material of multiextruder machines + Cura.MachineManager.setActiveMaterial(extruder_material); + } } } } From 12079fc9daeb8cda016f0300e787878a2c1ef4eb Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sat, 15 Apr 2017 18:55:59 +0200 Subject: [PATCH 25/49] Add documentation --- plugins/MachineSettingsAction/MachineSettingsAction.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index ec8ce7102e..f9504f866f 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -98,6 +98,7 @@ class MachineSettingsAction(MachineAction): Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey()) def _onGlobalContainerChanged(self): + # This stub is needed because we cannot connect a UM.Signal directly to a pyqtSignal self.globalContainerChanged.emit() globalContainerChanged = pyqtSignal() From 813ee65849cc889109db9bea8aa72843d5516b0f Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sat, 15 Apr 2017 18:58:25 +0200 Subject: [PATCH 26/49] Update printer (& disallowed areas) when setting nozzle offsets --- plugins/MachineSettingsAction/MachineSettingsAction.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 2456b62ddc..41e8e79421 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -545,7 +545,7 @@ Cura.MachineAction sourceComponent: numericTextFieldWithUnit property var propertyProvider: extruderOffsetXProvider property string unit: catalog.i18nc("@label", "mm") - property bool forceUpdateOnChange: false + property bool forceUpdateOnChange: true } Label { @@ -557,7 +557,7 @@ Cura.MachineAction sourceComponent: numericTextFieldWithUnit property var propertyProvider: extruderOffsetYProvider property string unit: catalog.i18nc("@label", "mm") - property bool forceUpdateOnChange: false + property bool forceUpdateOnChange: true } } From 6e0221636dad0a4493e1047f774a167541237b8b Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sat, 15 Apr 2017 19:08:05 +0200 Subject: [PATCH 27/49] Save definition_changes in their own folder --- cura/CuraApplication.py | 5 ++++- plugins/MachineSettingsAction/MachineSettingsAction.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index d407ae1b85..bc7185083d 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -104,6 +104,7 @@ class CuraApplication(QtApplication): UserInstanceContainer = Resources.UserType + 6 MachineStack = Resources.UserType + 7 ExtruderStack = Resources.UserType + 8 + DefinitionChangesContainer = Resources.UserType + 9 Q_ENUMS(ResourceTypes) @@ -145,6 +146,7 @@ class CuraApplication(QtApplication): Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders") Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") + Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "machine_settings") ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer) @@ -152,6 +154,7 @@ class CuraApplication(QtApplication): ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.ExtruderStack) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.DefinitionChangesContainer) ## Initialise the version upgrade manager with Cura's storage paths. import UM.VersionUpgradeManager #Needs to be here to prevent circular dependencies. @@ -408,7 +411,7 @@ class CuraApplication(QtApplication): elif instance_type == "variant": path = Resources.getStoragePath(self.ResourceTypes.VariantInstanceContainer, file_name) elif instance_type == "definition_changes": - path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) + path = Resources.getStoragePath(self.ResourceTypes.DefinitionChangesContainer, file_name) if path: instance.setPath(path) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index f9504f866f..6e37ae9ae0 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -59,7 +59,7 @@ class MachineSettingsAction(MachineAction): # Make sure there is a definition_changes container to store the machine settings definition_changes_container = extruder_container_stack.findContainer({"type": "definition_changes"}) if not definition_changes_container: - definition_changes_container = self._createDefinitionChangesContainer(extruder_container_stack, global_container_stack.getName() + "_" + extruder_container_stack.getId() + "_settings") + definition_changes_container = self._createDefinitionChangesContainer(extruder_container_stack, extruder_container_stack.getId() + "_settings") # Notify the UI in which container to store the machine settings data container_index = extruder_container_stack.getContainerIndex(definition_changes_container) From 94545ec4eec9daf1d7406f3de1e3d3a9dc95c1ef Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sat, 15 Apr 2017 20:09:20 +0200 Subject: [PATCH 28/49] Restore active extruder after forcing an update of the global extruder stack --- plugins/MachineSettingsAction/MachineSettingsAction.qml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 41e8e79421..314265e1c1 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -671,7 +671,12 @@ Cura.MachineAction propertyProvider.setPropertyValue("value", text); if(forceUpdateOnChange) { + var extruderIndex = ExtruderManager.activeExtruderIndex; manager.forceUpdate(); + if(ExtruderManager.activeExtruderIndex != extruderIndex) + { + ExtruderManager.setActiveExtruderIndex(extruderIndex) + } } } } From 4d96e6931d70b0e240396cf547c44422979ba84a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 18 Apr 2017 15:08:46 +0200 Subject: [PATCH 29/49] Store definition changes containers in a folder named definition_changes --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index bc7185083d..9cd05bb135 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -146,7 +146,7 @@ class CuraApplication(QtApplication): Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders") Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") - Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "machine_settings") + Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes") ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer) From 62f2fe062beef3792f8503f225bc83650d884e8d Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 18 Apr 2017 17:05:45 +0200 Subject: [PATCH 30/49] Enable settings when machine_extruder_count is set to 1 but multiple extruders are defined --- resources/qml/Settings/SettingView.qml | 2 +- resources/qml/SidebarSimple.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 66f1c19a08..a98775fead 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -179,7 +179,7 @@ Item Behavior on opacity { NumberAnimation { duration: 100 } } enabled: { - if(!ExtruderManager.activeExtruderStackId && ExtruderManager.extruderCount > 0) + if(!ExtruderManager.activeExtruderStackId && machineExtruderCount.properties.value > 1) { // disable all controls on the global tab, except categories return model.type == "category" diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 424c1239af..2234255478 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -19,7 +19,7 @@ Item property Action configureSettings; property variant minimumPrintTime: PrintInformation.minimumPrintTime; property variant maximumPrintTime: PrintInformation.maximumPrintTime; - property bool settingsEnabled: ExtruderManager.activeExtruderStackId || ExtruderManager.extruderCount == 0 + property bool settingsEnabled: ExtruderManager.activeExtruderStackId || machineExtruderCount.properties.value == 1 Component.onCompleted: PrintInformation.enabled = true Component.onDestruction: PrintInformation.enabled = false From ba229444b77c4da08aa6a2a65b3a502edfd35f20 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 21 Apr 2017 21:05:28 +0200 Subject: [PATCH 31/49] Pause autoslicing while the MachineSettingsAction is open Each setting-change would cause a reslice, which is unnecessary. --- .../MachineSettingsAction/MachineSettingsAction.py | 11 +++++++++++ .../MachineSettingsAction/MachineSettingsAction.qml | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 6e37ae9ae0..0bdf0006ed 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -34,6 +34,8 @@ class MachineSettingsAction(MachineAction): Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) + self._backend = Application.getInstance().getBackend() + def _reset(self): global_container_stack = Application.getInstance().getGlobalContainerStack() if not global_container_stack: @@ -50,6 +52,15 @@ class MachineSettingsAction(MachineAction): self._container_index = container_index self.containerIndexChanged.emit() + # Disable autoslicing while the machineaction is showing + self._backend.disableTimer() + + @pyqtSlot() + def onFinishAction(self): + # Restore autoslicing when the machineaction is dismissed + if self._backend.determineAutoSlicing(): + self._backend.tickle() + def _onActiveExtruderStackChanged(self): global_container_stack = Application.getInstance().getGlobalContainerStack() extruder_container_stack = ExtruderManager.getInstance().getActiveExtruderStack() diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 314265e1c1..626f62dbd9 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -32,6 +32,18 @@ Cura.MachineAction onTriggered: base.extruderTabsCount = (machineExtruderCountProvider.properties.value > 1) ? parseInt(machineExtruderCountProvider.properties.value) : 0 } + Connections + { + target: dialog ? dialog : null + ignoreUnknownSignals: true + // Any which way this action dialog is dismissed, make sure it is properly finished + onNextClicked: manager.onFinishAction() + onBackClicked: manager.onFinishAction() + onAccepted: manager.onFinishAction() + onRejected: manager.onFinishAction() + onClosing: manager.onFinishAction() + } + anchors.fill: parent; Item { From 656e7a804680a297a4676a127919b2b6f236c3bc Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 21 Apr 2017 21:27:15 +0200 Subject: [PATCH 32/49] Change the scope of the head polygon functions to be inside the main tab --- .../MachineSettingsAction.qml | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 626f62dbd9..c63391f624 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -494,6 +494,36 @@ Cura.MachineAction } } } + + function getHeadPolygonCoord(axis, minMax) + { + var polygon = JSON.parse(machineHeadPolygonProvider.properties.value); + var item = (axis == "x") ? 0 : 1 + var result = polygon[0][item]; + for(var i = 1; i < polygon.length; i++) { + if (minMax == "min") { + result = Math.min(result, polygon[i][item]); + } else { + result = Math.max(result, polygon[i][item]); + } + } + return Math.abs(result); + } + + function setHeadPolygon() + { + var polygon = []; + polygon.push([-parseFloat(printheadXMinField.text), parseFloat(printheadYMaxField.text)]); + polygon.push([-parseFloat(printheadXMinField.text),-parseFloat(printheadYMinField.text)]); + polygon.push([ parseFloat(printheadXMaxField.text), parseFloat(printheadYMaxField.text)]); + polygon.push([ parseFloat(printheadXMaxField.text),-parseFloat(printheadYMinField.text)]); + var polygon_string = JSON.stringify(polygon); + if(polygon != machineHeadPolygonProvider.properties.value) + { + machineHeadPolygonProvider.setPropertyValue("value", polygon_string); + manager.forceUpdate(); + } + } } } @@ -635,36 +665,6 @@ Cura.MachineAction } } - function getHeadPolygonCoord(axis, minMax) - { - var polygon = JSON.parse(machineHeadPolygonProvider.properties.value); - var item = (axis == "x") ? 0 : 1 - var result = polygon[0][item]; - for(var i = 1; i < polygon.length; i++) { - if (minMax == "min") { - result = Math.min(result, polygon[i][item]); - } else { - result = Math.max(result, polygon[i][item]); - } - } - return Math.abs(result); - } - - function setHeadPolygon() - { - var polygon = []; - polygon.push([-parseFloat(printheadXMinField.text), parseFloat(printheadYMaxField.text)]); - polygon.push([-parseFloat(printheadXMinField.text),-parseFloat(printheadYMinField.text)]); - polygon.push([ parseFloat(printheadXMaxField.text), parseFloat(printheadYMaxField.text)]); - polygon.push([ parseFloat(printheadXMaxField.text),-parseFloat(printheadYMinField.text)]); - var polygon_string = JSON.stringify(polygon); - if(polygon != machineHeadPolygonProvider.properties.value) - { - machineHeadPolygonProvider.setPropertyValue("value", polygon_string); - manager.forceUpdate(); - } - } - Component { id: numericTextFieldWithUnit From 0966ef5338ccdb6fd9c9916090bb8e893312509c Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 21 Apr 2017 21:48:20 +0200 Subject: [PATCH 33/49] Fix QML warnings when switching to an extruder tab --- .../MachineSettingsAction.qml | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index c63391f624..c02971d8dd 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -450,6 +450,7 @@ Cura.MachineAction Label { text: catalog.i18nc("@label", "Start Gcode") + font.bold: true } TextArea { @@ -457,7 +458,6 @@ Cura.MachineAction width: parent.width height: parent.height - y font: UM.Theme.getFont("fixed") - wrapMode: TextEdit.NoWrap text: machineStartGcodeProvider.properties.value onActiveFocusChanged: { @@ -466,6 +466,10 @@ Cura.MachineAction machineStartGcodeProvider.setPropertyValue("value", machineStartGcodeField.text) } } + Component.onCompleted: + { + wrapMode = TextEdit.NoWrap; + } } } @@ -475,6 +479,7 @@ Cura.MachineAction Label { text: catalog.i18nc("@label", "End Gcode") + font.bold: true } TextArea { @@ -482,7 +487,6 @@ Cura.MachineAction width: parent.width height: parent.height - y font: UM.Theme.getFont("fixed") - wrapMode: TextEdit.NoWrap text: machineEndGcodeProvider.properties.value onActiveFocusChanged: { @@ -491,6 +495,10 @@ Cura.MachineAction machineEndGcodeProvider.setPropertyValue("value", machineEndGcodeField.text) } } + Component.onCompleted: + { + wrapMode = TextEdit.NoWrap; + } } } } @@ -552,7 +560,7 @@ Cura.MachineAction Label { - text: catalog.i18nc("@label", "Printer Settings") + text: catalog.i18nc("@label", "Nozzle Settings") font.bold: true } @@ -616,6 +624,7 @@ Cura.MachineAction Label { text: catalog.i18nc("@label", "Extruder Start Gcode") + font.bold: true } TextArea { @@ -623,8 +632,7 @@ Cura.MachineAction width: parent.width height: parent.height - y font: UM.Theme.getFont("fixed") - wrapMode: TextEdit.NoWrap - text: extruderStartGcodeProvider.properties.value + text: (extruderStartGcodeProvider.properties.value) ? extruderStartGcodeProvider.properties.value : "" onActiveFocusChanged: { if(!activeFocus) @@ -632,6 +640,10 @@ Cura.MachineAction extruderStartGcodeProvider.setPropertyValue("value", extruderStartGcodeField.text) } } + Component.onCompleted: + { + wrapMode = TextEdit.NoWrap; + } } } Column { @@ -640,6 +652,7 @@ Cura.MachineAction Label { text: catalog.i18nc("@label", "Extruder End Gcode") + font.bold: true } TextArea { @@ -647,8 +660,7 @@ Cura.MachineAction width: parent.width height: parent.height - y font: UM.Theme.getFont("fixed") - wrapMode: TextEdit.NoWrap - text: extruderEndGcodeProvider.properties.value + text: (extruderEndGcodeProvider.properties.value) ? extruderEndGcodeProvider.properties.value : "" onActiveFocusChanged: { if(!activeFocus) @@ -656,6 +668,10 @@ Cura.MachineAction extruderEndGcodeProvider.setPropertyValue("value", extruderEndGcodeField.text) } } + Component.onCompleted: + { + wrapMode = TextEdit.NoWrap; + } } } } @@ -674,7 +690,7 @@ Cura.MachineAction TextField { id: textField - text: propertyProvider.properties.value + text: (propertyProvider.properties.value) ? propertyProvider.properties.value : "" validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } onEditingFinished: { From 933ee408e457c727d47f92ad01f14a51c1223471 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sat, 22 Apr 2017 09:47:00 +0200 Subject: [PATCH 34/49] Code style --- .../MachineSettingsAction.py | 73 ++++++++++--------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 0bdf0006ed..4c66773d05 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -26,6 +26,7 @@ class MachineSettingsAction(MachineAction): super().__init__("MachineSettingsAction", catalog.i18nc("@action", "Machine Settings")) self._qml_url = "MachineSettingsAction.qml" + self._global_container_stack = None self._container_index = 0 self._extruder_container_index = 0 @@ -37,17 +38,16 @@ class MachineSettingsAction(MachineAction): self._backend = Application.getInstance().getBackend() def _reset(self): - global_container_stack = Application.getInstance().getGlobalContainerStack() - if not global_container_stack: + if not self._global_container_stack: return # Make sure there is a definition_changes container to store the machine settings - definition_changes_container = global_container_stack.findContainer({"type": "definition_changes"}) + definition_changes_container = self._global_container_stack.findContainer({"type": "definition_changes"}) if not definition_changes_container: - definition_changes_container = self._createDefinitionChangesContainer(global_container_stack, global_container_stack.getName() + "_settings") + definition_changes_container = self._createDefinitionChangesContainer(self._global_container_stack, self._global_container_stack.getName() + "_settings") # Notify the UI in which container to store the machine settings data - container_index = global_container_stack.getContainerIndex(definition_changes_container) + container_index = self._global_container_stack.getContainerIndex(definition_changes_container) if container_index != self._container_index: self._container_index = container_index self.containerIndexChanged.emit() @@ -62,9 +62,8 @@ class MachineSettingsAction(MachineAction): self._backend.tickle() def _onActiveExtruderStackChanged(self): - global_container_stack = Application.getInstance().getGlobalContainerStack() extruder_container_stack = ExtruderManager.getInstance().getActiveExtruderStack() - if not global_container_stack or not extruder_container_stack: + if not self._global_container_stack or not extruder_container_stack: return # Make sure there is a definition_changes container to store the machine settings @@ -109,18 +108,19 @@ class MachineSettingsAction(MachineAction): Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey()) def _onGlobalContainerChanged(self): - # This stub is needed because we cannot connect a UM.Signal directly to a pyqtSignal + self._global_container_stack = Application.getInstance().getGlobalContainerStack() + + # This additional emit is needed because we cannot connect a UM.Signal directly to a pyqtSignal self.globalContainerChanged.emit() globalContainerChanged = pyqtSignal() @pyqtProperty(int, notify = globalContainerChanged) def definedExtruderCount(self): - global_container_stack = Application.getInstance().getGlobalContainerStack() - if not global_container_stack: + if not self._global_container_stack: return 0 - return len(global_container_stack.getMetaDataEntry("machine_extruder_trains")) + return len(self._global_container_stack.getMetaDataEntry("machine_extruder_trains")) @pyqtSlot() def forceUpdate(self): @@ -131,34 +131,35 @@ class MachineSettingsAction(MachineAction): @pyqtSlot() def updateHasMaterialsMetadata(self): # Updates the has_materials metadata flag after switching gcode flavor - global_container_stack = Application.getInstance().getGlobalContainerStack() - if global_container_stack: - definition = global_container_stack.getBottom() - if definition.getProperty("machine_gcode_flavor", "value") == "UltiGCode" and not definition.getMetaDataEntry("has_materials", False): - has_materials = global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode" + if not self._global_container_stack: + return - material_container = global_container_stack.findContainer({"type": "material"}) - material_index = global_container_stack.getContainerIndex(material_container) + definition = self._global_container_stack.getBottom() + if definition.getProperty("machine_gcode_flavor", "value") == "UltiGCode" and not definition.getMetaDataEntry("has_materials", False): + has_materials = self._global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode" - if has_materials: - if "has_materials" in global_container_stack.getMetaData(): - global_container_stack.setMetaDataEntry("has_materials", True) - else: - global_container_stack.addMetaDataEntry("has_materials", True) + material_container = self._global_container_stack.findContainer({"type": "material"}) + material_index = self._global_container_stack.getContainerIndex(material_container) - # Set the material container to a sane default - if material_container.getId() == "empty_material": - search_criteria = { "type": "material", "definition": "fdmprinter", "id": "*pla*" } - containers = self._container_registry.findInstanceContainers(**search_criteria) - if containers: - global_container_stack.replaceContainer(material_index, containers[0]) + if has_materials: + if "has_materials" in self._global_container_stack.getMetaData(): + self._global_container_stack.setMetaDataEntry("has_materials", True) else: - # The metadata entry is stored in an ini, and ini files are parsed as strings only. - # Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False. - if "has_materials" in global_container_stack.getMetaData(): - global_container_stack.removeMetaDataEntry("has_materials") + self._global_container_stack.addMetaDataEntry("has_materials", True) - empty_material = self._container_registry.findInstanceContainers(id = "empty_material")[0] - global_container_stack.replaceContainer(material_index, empty_material) + # Set the material container to a sane default + if material_container.getId() == "empty_material": + search_criteria = { "type": "material", "definition": "fdmprinter", "id": "*pla*" } + containers = self._container_registry.findInstanceContainers(**search_criteria) + if containers: + self._global_container_stack.replaceContainer(material_index, containers[0]) + else: + # The metadata entry is stored in an ini, and ini files are parsed as strings only. + # Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False. + if "has_materials" in self._global_container_stack.getMetaData(): + self._global_container_stack.removeMetaDataEntry("has_materials") - Application.getInstance().globalContainerStackChanged.emit() + empty_material = self._container_registry.findInstanceContainers(id = "empty_material")[0] + self._global_container_stack.replaceContainer(material_index, empty_material) + + Application.getInstance().globalContainerStackChanged.emit() From 8d42f9c187875a517d1520fe4c457e4c11397321 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sat, 22 Apr 2017 10:13:58 +0200 Subject: [PATCH 35/49] Move some convoluted logic from QML into Python --- .../MachineSettingsAction.py | 34 ++++++++++++++++ .../MachineSettingsAction.qml | 39 +------------------ 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 4c66773d05..e8aec896c1 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -122,6 +122,40 @@ class MachineSettingsAction(MachineAction): return len(self._global_container_stack.getMetaDataEntry("machine_extruder_trains")) + @pyqtSlot(int) + def setMachineExtruderCount(self, extruder_count): + machine_manager = Application.getInstance().getMachineManager() + extruder_manager = ExtruderManager.getInstance() + + definition_changes_container = self._global_container_stack.findContainer({"type": "definition_changes"}) + if not self._global_container_stack or not definition_changes_container: + return + + if extruder_count == self._global_container_stack.getProperty("machine_extruder_count", "value"): + return + + extruder_material = None + if extruder_count == 1 and machine_manager.hasMaterials: + extruder_material = machine_manager.allActiveMaterialIds[machine_manager.activeStackId] + + definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count) + self.forceUpdate() + + if extruder_count > 1: + # multiextrusion; make sure one of these extruder stacks is active + if extruder_manager.activeExtruderIndex == -1: + extruder_manager.setActiveExtruderIndex(0) + else: + # single extrusion; make sure the machine stack is active + if extruder_manager.activeExtruderIndex > -1: + extruder_manager.setActiveExtruderIndex(-1); + + if extruder_material: + # restore material on global stack + # MachineManager._onGlobalContainerChanged removes the global material of multiextruder machines + machine_manager.setActiveMaterial(extruder_material); + + @pyqtSlot() def forceUpdate(self): # Force rebuilding the build volume by reloading the global container stack. diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index c02971d8dd..abe05d5654 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -377,48 +377,11 @@ Cura.MachineAction currentIndex: machineExtruderCountProvider.properties.value - 1 onActivated: { - if(machineExtruderCountProvider.properties.value == index + 1) - { - return; - } - - var extruder_material; - if(index == 0 && Cura.MachineManager.hasMaterials) - { - // setting back to single extrusion - extruder_material = Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeStackId]; - } - - machineExtruderCountProvider.setPropertyValue("value", index + 1); - manager.forceUpdate(); + manager.setMachineExtruderCount(index + 1); base.extruderTabsCount = (index > 0) ? index + 1 : 0; - - if(index > 0) - { - // multiextrusion; make sure one of these extruder stacks is active - if(ExtruderManager.activeExtruderIndex == -1) - { - ExtruderManager.setActiveExtruderIndex(0); - } - } - else - { - // single extrusion; make sure the machine stack is active - if(ExtruderManager.activeExtruderIndex != -1) - { - ExtruderManager.setActiveExtruderIndex(-1); - } - if(extruder_material) - { - // restore material on global stack - // MachineManager._onGlobalContainerChanged removes the global material of multiextruder machines - Cura.MachineManager.setActiveMaterial(extruder_material); - } - } } } - Label { text: catalog.i18nc("@label", "Nozzle size") From 2ca24ba7e6094b6304a07545d8f672c3c98bb588 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sat, 22 Apr 2017 11:20:55 +0200 Subject: [PATCH 36/49] Restore both material and variant to match 1st extruder when switching to single extrusion --- cura/Settings/MachineManager.py | 11 ++++++++++ .../MachineSettingsAction.py | 21 ++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 493f8fcf07..8deaca3b5e 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -505,6 +505,17 @@ class MachineManager(QObject): return result + @pyqtProperty("QVariantList", notify = activeVariantChanged) + def activeMaterialIds(self): + result = [] + if ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() is not None: + for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + variant_container = stack.findContainer({"type": "variant"}) + if variant_container and variant_container != self._empty_variant_container: + result.append(variant_container.getId()) + + return result + @pyqtProperty("QVariantList", notify = activeMaterialChanged) def activeMaterialNames(self): result = [] diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index e8aec896c1..17e4362f2c 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -134,9 +134,14 @@ class MachineSettingsAction(MachineAction): if extruder_count == self._global_container_stack.getProperty("machine_extruder_count", "value"): return - extruder_material = None - if extruder_count == 1 and machine_manager.hasMaterials: - extruder_material = machine_manager.allActiveMaterialIds[machine_manager.activeStackId] + extruder_material_id = None + extruder_variant_id = None + if extruder_count == 1: + # Get the material and variant of the first extruder before setting the number extruders to 1 + if machine_manager.hasMaterials: + extruder_material_id = machine_manager.allActiveMaterialIds[extruder_manager.extruderIds["0"]] + if machine_manager.hasVariants: + extruder_variant_id = machine_manager.activeVariantIds[0] definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count) self.forceUpdate() @@ -150,10 +155,12 @@ class MachineSettingsAction(MachineAction): if extruder_manager.activeExtruderIndex > -1: extruder_manager.setActiveExtruderIndex(-1); - if extruder_material: - # restore material on global stack - # MachineManager._onGlobalContainerChanged removes the global material of multiextruder machines - machine_manager.setActiveMaterial(extruder_material); + # Restore material and variant on global stack + # MachineManager._onGlobalContainerChanged removes the global material and vaiant of multiextruder machines + if extruder_material_id: + machine_manager.setActiveMaterial(extruder_material_id); + if extruder_variant_id: + machine_manager.setActiveVariant(extruder_variant_id); @pyqtSlot() From d2d36b8c98f167c98ab33342a3343845973730ea Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sat, 22 Apr 2017 12:13:23 +0200 Subject: [PATCH 37/49] Lower extruder_nr settings when they exceed the number of extruders --- .../MachineSettingsAction.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 17e4362f2c..7f5dabe8d1 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -10,6 +10,7 @@ from UM.Application import Application from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.DefinitionContainer import DefinitionContainer +from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Logger import Logger from cura.Settings.CuraContainerRegistry import CuraContainerRegistry @@ -143,6 +144,21 @@ class MachineSettingsAction(MachineAction): if machine_manager.hasVariants: extruder_variant_id = machine_manager.activeVariantIds[0] + # Check to see if any features are set to print with an extruder that will no longer exist + for setting_name in ["adhesion_extruder_nr", "support_extruder_nr", "support_extruder_nr_layer_0", "support_infill_extruder_nr", "support_interface_extruder_nr"]: + if int(self._global_container_stack.getProperty(setting_name, "value")) > extruder_count -1: + Logger.log("i", "Lowering %s setting to match number of extruders", setting_name) + self._global_container_stack.getTop().setProperty(setting_name, "value", extruder_count -1) + + # Check to see if any objects are set to print with an extruder that will no longer exist + root_node = Application.getInstance().getController().getScene().getRoot() + for node in DepthFirstIterator(root_node): + if node.getMeshData(): + extruder_nr = node.callDecoration("getActiveExtruderPosition") + + if extruder_nr is not None and extruder_nr > extruder_count - 1: + node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count -1).getId()) + definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count) self.forceUpdate() From fab0fa1dde9a6cb073fc3ceed305f23864c61d03 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 24 Apr 2017 12:58:20 +0200 Subject: [PATCH 38/49] Move setting values that are settable per extruder from/to global stack when setting extruder count --- .../MachineSettingsAction.py | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 7f5dabe8d1..f2194e356b 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -132,7 +132,8 @@ class MachineSettingsAction(MachineAction): if not self._global_container_stack or not definition_changes_container: return - if extruder_count == self._global_container_stack.getProperty("machine_extruder_count", "value"): + previous_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value") + if extruder_count == previous_extruder_count: return extruder_material_id = None @@ -144,11 +145,29 @@ class MachineSettingsAction(MachineAction): if machine_manager.hasVariants: extruder_variant_id = machine_manager.activeVariantIds[0] + # Copy any settable_per_extruder setting value from the extruders to the global stack + extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) + extruder_stacks.reverse() # make sure the first extruder is done last, so its settings override any higher extruder settings + + global_user_container = self._global_container_stack.getTop() + for extruder_stack in extruder_stacks: + extruder_index = extruder_stack.getMetaDataEntry("position") + extruder_user_container = extruder_stack.getTop() + for setting_instance in extruder_user_container.findInstances(): + setting_key = setting_instance.definition.key + settable_per_extruder = self._global_container_stack.getProperty(setting_key, "settable_per_extruder") + if settable_per_extruder: + limit_to_extruder = self._global_container_stack.getProperty(setting_key, "limit_to_extruder") + + if limit_to_extruder == "-1" or limit_to_extruder == extruder_index: + global_user_container.setProperty(setting_key, "value", extruder_user_container.getProperty(setting_key, "value")) + extruder_user_container.removeInstance(setting_key) + # Check to see if any features are set to print with an extruder that will no longer exist - for setting_name in ["adhesion_extruder_nr", "support_extruder_nr", "support_extruder_nr_layer_0", "support_infill_extruder_nr", "support_interface_extruder_nr"]: - if int(self._global_container_stack.getProperty(setting_name, "value")) > extruder_count -1: - Logger.log("i", "Lowering %s setting to match number of extruders", setting_name) - self._global_container_stack.getTop().setProperty(setting_name, "value", extruder_count -1) + for setting_key in ["adhesion_extruder_nr", "support_extruder_nr", "support_extruder_nr_layer_0", "support_infill_extruder_nr", "support_interface_extruder_nr"]: + if int(self._global_container_stack.getProperty(setting_key, "value")) > extruder_count -1: + Logger.log("i", "Lowering %s setting to match number of extruders", setting_key) + self._global_container_stack.getTop().setProperty(setting_key, "value", extruder_count -1) # Check to see if any objects are set to print with an extruder that will no longer exist root_node = Application.getInstance().getController().getScene().getRoot() @@ -163,11 +182,29 @@ class MachineSettingsAction(MachineAction): self.forceUpdate() if extruder_count > 1: - # multiextrusion; make sure one of these extruder stacks is active + # Multiextrusion + + # Make sure one of the extruder stacks is active if extruder_manager.activeExtruderIndex == -1: extruder_manager.setActiveExtruderIndex(0) + + # Move settable_per_extruder values out of the global container + if previous_extruder_count == 1: + extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) + global_user_container = self._global_container_stack.getTop() + + for setting_instance in global_user_container.findInstances(): + setting_key = setting_instance.definition.key + settable_per_extruder = self._global_container_stack.getProperty(setting_key, "settable_per_extruder") + if settable_per_extruder: + limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder")) + extruder_stack = extruder_stacks[max(0, limit_to_extruder)] + extruder_stack.getTop().setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value")) + global_user_container.removeInstance(setting_key) else: - # single extrusion; make sure the machine stack is active + # Single extrusion + + # Make sure the machine stack is active if extruder_manager.activeExtruderIndex > -1: extruder_manager.setActiveExtruderIndex(-1); From 3e9fdb5db1e68928da676e5752f7b7421fe5ef3f Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 24 Apr 2017 13:11:10 +0200 Subject: [PATCH 39/49] Prevent the DiscardOrKeepProfileChangesDialog from popping up (twice) if there are user changes --- .../MachineSettingsAction.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index f2194e356b..33854302a9 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -7,6 +7,7 @@ from UM.FlameProfiler import pyqtSlot from cura.MachineAction import MachineAction from UM.Application import Application +from UM.Preferences import Preferences from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.DefinitionContainer import DefinitionContainer @@ -209,11 +210,20 @@ class MachineSettingsAction(MachineAction): extruder_manager.setActiveExtruderIndex(-1); # Restore material and variant on global stack - # MachineManager._onGlobalContainerChanged removes the global material and vaiant of multiextruder machines - if extruder_material_id: - machine_manager.setActiveMaterial(extruder_material_id); - if extruder_variant_id: - machine_manager.setActiveVariant(extruder_variant_id); + # MachineManager._onGlobalContainerChanged removes the global material and variant of multiextruder machines + if extruder_material_id or extruder_variant_id: + # Prevent the DiscardOrKeepProfileChangesDialog from popping up (twice) if there are user changes + # The dialog is not relevant here, since we're restoring the previous situation as good as possible + preferences = Preferences.getInstance() + choice_on_profile_override = preferences.getValue("cura/choice_on_profile_override") + preferences.setValue("cura/choice_on_profile_override", "always_keep") + + if extruder_material_id: + machine_manager.setActiveMaterial(extruder_material_id); + if extruder_variant_id: + machine_manager.setActiveVariant(extruder_variant_id); + + preferences.setValue("cura/choice_on_profile_override", choice_on_profile_override) @pyqtSlot() From 8b5ac81404186321493d659d88458a487e010f92 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 24 Apr 2017 13:20:20 +0200 Subject: [PATCH 40/49] Fix extruder_stack global values are moved to ExtruderManager.getMachineExtruders() result is not sorted, the result of getActiveExtruderStacks() is --- plugins/MachineSettingsAction/MachineSettingsAction.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 33854302a9..f25d454dac 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -147,7 +147,7 @@ class MachineSettingsAction(MachineAction): extruder_variant_id = machine_manager.activeVariantIds[0] # Copy any settable_per_extruder setting value from the extruders to the global stack - extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) + extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() extruder_stacks.reverse() # make sure the first extruder is done last, so its settings override any higher extruder settings global_user_container = self._global_container_stack.getTop() @@ -191,7 +191,7 @@ class MachineSettingsAction(MachineAction): # Move settable_per_extruder values out of the global container if previous_extruder_count == 1: - extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) + extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() global_user_container = self._global_container_stack.getTop() for setting_instance in global_user_container.findInstances(): From 57f936e5fffb54b14df5415137b519ee14fb4e8a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 24 Apr 2017 13:56:37 +0200 Subject: [PATCH 41/49] Remove definition_changes containers when a stack is removed --- .../MachineSettingsAction.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index f25d454dac..995a07eac4 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -34,11 +34,26 @@ class MachineSettingsAction(MachineAction): self._container_registry = ContainerRegistry.getInstance() self._container_registry.containerAdded.connect(self._onContainerAdded) + self._container_registry.containerRemoved.connect(self._onContainerRemoved) Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) self._backend = Application.getInstance().getBackend() + def _onContainerAdded(self, container): + # Add this action as a supported action to all machine definitions + if isinstance(container, DefinitionContainer) and container.getMetaDataEntry("type") == "machine": + Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey()) + + def _onContainerRemoved(self, container): + # Remove definition_changes containers when a stack is removed + if container.getMetaDataEntry("type") in ["machine", "extruder_train"]: + definition_changes_container = container.findContainer({"type": "definition_changes"}) + if not definition_changes_container: + return + + self._container_registry.removeContainer(definition_changes_container.getId()) + def _reset(self): if not self._global_container_stack: return @@ -104,11 +119,6 @@ class MachineSettingsAction(MachineAction): return self._extruder_container_index - def _onContainerAdded(self, container): - # Add this action as a supported action to all machine definitions - if isinstance(container, DefinitionContainer) and container.getMetaDataEntry("type") == "machine": - Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey()) - def _onGlobalContainerChanged(self): self._global_container_stack = Application.getInstance().getGlobalContainerStack() From 4f446bfcbc95c510a29b1c103bdc606c968c76fd Mon Sep 17 00:00:00 2001 From: Victor Larchenko Date: Thu, 27 Apr 2017 16:44:43 +0600 Subject: [PATCH 42/49] Added filament cost keyword replacement --- plugins/CuraEngineBackend/CuraEngineBackend.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 4a1d280aeb..f32993fd20 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -446,8 +446,7 @@ class CuraEngineBackend(QObject, Backend): replaced = line.replace("{print_time}", str(Application.getInstance().getPrintInformation().currentPrintTime.getDisplayString(DurationFormat.Format.ISO8601))) replaced = replaced.replace("{filament_amount}", str(Application.getInstance().getPrintInformation().materialLengths)) replaced = replaced.replace("{filament_weight}", str(Application.getInstance().getPrintInformation().materialWeights)) - # TODO: calculate filament cost - replaced = replaced.replace("{filament_cost}", "Not yet implemented") + replaced = replaced.replace("{filament_cost}", str(Application.getInstance().getPrintInformation().materialCosts)) replaced = replaced.replace("{jobname}", str(Application.getInstance().getPrintInformation().jobName)) self._scene.gcode_list[self._scene.gcode_list.index(line)] = replaced From c9039bb6fc609859f4a371e77e292db71bf51a42 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 30 Apr 2017 11:08:24 +0200 Subject: [PATCH 43/49] Add a field to set the material diameter for the printer This is used to filter the list of available materials, see https://github.com/Ultimaker/Cura/pull/1685 --- .../MachineSettingsAction.qml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index abe05d5654..b7cf86ef58 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -382,6 +382,18 @@ Cura.MachineAction } } + Label + { + text: catalog.i18nc("@label", "Material Diameter") + } + Loader + { + id: materialDiameterField + sourceComponent: numericTextFieldWithUnit + property var propertyProvider: materialDiameterProvider + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: false + } Label { text: catalog.i18nc("@label", "Nozzle size") @@ -753,6 +765,16 @@ Cura.MachineAction storeIndex: manager.containerIndex } + UM.SettingPropertyProvider + { + id: materialDiameterProvider + + containerStackId: Cura.MachineManager.activeMachineId + key: "material_diameter" + watchedProperties: [ "value" ] + storeIndex: manager.containerIndex + } + UM.SettingPropertyProvider { id: machineNozzleSizeProvider From bb0e9c3fdc7c1ee98313d0cc60d1f81970d1c539 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 2 May 2017 12:36:25 +0200 Subject: [PATCH 44/49] Split interface line distance into two in user's profiles This hasn't been deep-tested yet, but I assume that'll happen when the plug-in is reactivated in the source code. Contributes to issue CURA-3491. --- .../VersionUpgrade24to25.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py b/plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py index 99a0f95a77..9e27759285 100644 --- a/plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py +++ b/plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py @@ -10,6 +10,10 @@ _removed_settings = { #Settings that were removed in 2.5. "start_layers_at_same_position" } +_split_settings = { #These settings should be copied to all settings it was split into. + "support_interface_line_distance": {"support_roof_line_distance", "support_bottom_line_distance"} +} + ## A collection of functions that convert the configuration of the user in Cura # 2.4 to a configuration for Cura 2.5. # @@ -42,7 +46,15 @@ class VersionUpgrade24to25(VersionUpgrade): #Remove settings from the visible_settings. if parser.has_section("general") and "visible_settings" in parser["general"]: visible_settings = parser["general"]["visible_settings"].split(";") - visible_settings = filter(lambda setting: setting not in _removed_settings, visible_settings) + new_visible_settings = [] + for setting in visible_settings: + if setting in _removed_settings: + continue #Skip. + if setting in _split_settings: + for replaced_setting in _split_settings[setting]: + new_visible_settings.append(replaced_setting) + continue #Don't add the original. + new_visible_settings.append(setting) #No special handling, so just add the original visible setting back. parser["general"]["visible_settings"] = ";".join(visible_settings) #Change the version number in the file. @@ -66,6 +78,10 @@ class VersionUpgrade24to25(VersionUpgrade): if parser.has_section("values"): for removed_setting in (_removed_settings & parser["values"].keys()): #Both in keys that need to be removed and in keys present in the file. del parser["values"][removed_setting] + for replaced_setting in (_split_settings.keys() & parser["values"].keys()): + for replacement in _split_settings[replaced_setting]: + parser["values"][replacement] = parser["values"][replaced_setting] #Copy to replacement before removing the original! + del replaced_setting #Change the version number in the file. if parser.has_section("general"): From 0e1748b705709e5940babae9abdf5065535797da Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 2 May 2017 12:55:37 +0200 Subject: [PATCH 45/49] Small layout fix so the comboboxes are aligned --- resources/qml/Preferences/GeneralPage.qml | 133 ++++++++++------------ 1 file changed, 60 insertions(+), 73 deletions(-) diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index 85039b3c32..689f7aafa9 100755 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -126,9 +126,11 @@ UM.PreferencesPage text: catalog.i18nc("@label","Interface") } - Row + GridLayout { - spacing: UM.Theme.getSize("default_margin").width + id: interfaceGrid + columns: 4 + Label { id: languageLabel @@ -189,94 +191,79 @@ UM.PreferencesPage { id: currencyLabel text: catalog.i18nc("@label","Currency:") - anchors.verticalCenter: languageComboBox.verticalCenter + anchors.verticalCenter: currencyField.verticalCenter } + TextField { id: currencyField text: UM.Preferences.getValue("cura/currency") onTextChanged: UM.Preferences.setValue("cura/currency", text) } + + Label + { + id: themeLabel + text: catalog.i18nc("@label","Theme:") + anchors.verticalCenter: themeComboBox.verticalCenter + } + + ComboBox + { + id: themeComboBox + + model: ListModel + { + id: themeList + + Component.onCompleted: { + append({ text: catalog.i18nc("@item:inlistbox", "Ultimaker"), code: "cura" }) + } + } + + currentIndex: + { + var code = UM.Preferences.getValue("general/theme"); + for(var i = 0; i < themeList.count; ++i) + { + if(model.get(i).code == code) + { + return i + } + } + } + onActivated: UM.Preferences.setValue("general/theme", model.get(index).code) + + Component.onCompleted: + { + // Because ListModel is stupid and does not allow using qsTr() for values. + for(var i = 0; i < themeList.count; ++i) + { + themeList.setProperty(i, "text", catalog.i18n(themeList.get(i).text)); + } + + // Glorious hack time. ComboBox does not update the text properly after changing the + // model. So change the indices around to force it to update. + currentIndex += 1; + currentIndex -= 1; + } + + } } - Label + + + + Label { id: languageCaption //: Language change warning - text: catalog.i18nc("@label", "You will need to restart the application for language changes to have effect.") + text: catalog.i18nc("@label", "You will need to restart the application for these changes to have effect.") wrapMode: Text.WordWrap font.italic: true } - Item - { - //: Spacer - height: UM.Theme.getSize("default_margin").height - width: UM.Theme.getSize("default_margin").width - } - - Row - { - spacing: UM.Theme.getSize("default_margin").width - Label - { - id: themeLabel - text: catalog.i18nc("@label","Theme:") - anchors.verticalCenter: themeComboBox.verticalCenter - } - - ComboBox - { - id: themeComboBox - model: ListModel - { - id: themeList - - Component.onCompleted: { - append({ text: catalog.i18nc("@item:inlistbox", "Ultimaker"), code: "cura" }) - } - } - - currentIndex: - { - var code = UM.Preferences.getValue("general/theme"); - for(var i = 0; i < themeList.count; ++i) - { - if(model.get(i).code == code) - { - return i - } - } - } - onActivated: UM.Preferences.setValue("general/theme", model.get(index).code) - - Component.onCompleted: - { - // Because ListModel is stupid and does not allow using qsTr() for values. - for(var i = 0; i < themeList.count; ++i) - { - themeList.setProperty(i, "text", catalog.i18n(themeList.get(i).text)); - } - - // Glorious hack time. ComboBox does not update the text properly after changing the - // model. So change the indices around to force it to update. - currentIndex += 1; - currentIndex -= 1; - } - } - } - - Label - { - id: themeCaption - - //: Theme change warning - text: catalog.i18nc("@label", "You will need to restart the application for theme changes to have effect.") - wrapMode: Text.WordWrap - font.italic: true - } - Item { //: Spacer From 7a9a4ae290ac873f9fa33de640b5debab488b214 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 2 May 2017 12:57:44 +0200 Subject: [PATCH 46/49] Revert "Change Label to Text because of ugle font rendering" This reverts commit 8c9eccd1f4f49a0d0584b3f56985f4fa16e48915. This element is in a modal window, where the fonts should get the system themeing. --- resources/qml/AddMachineDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/AddMachineDialog.qml index ba3f40260d..756badc4d2 100644 --- a/resources/qml/AddMachineDialog.qml +++ b/resources/qml/AddMachineDialog.qml @@ -180,7 +180,7 @@ UM.Dialog anchors.bottom:parent.bottom spacing: UM.Theme.getSize("default_margin").width - Text + Label { text: catalog.i18nc("@label", "Printer Name:") anchors.verticalCenter: machineName.verticalCenter From d006db5b2c961bd2d517eb656163c255c62d1737 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 2 May 2017 13:38:28 +0200 Subject: [PATCH 47/49] Slightly reduce minimum window size This should make it possible to work with Cura on 1024x768 screens. I interpolated this from the 800p screens, since it seems to render smaller on my computer anyway. --- resources/themes/cura/theme.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/cura/theme.json b/resources/themes/cura/theme.json index da58af4c14..5f0b3656c8 100644 --- a/resources/themes/cura/theme.json +++ b/resources/themes/cura/theme.json @@ -247,7 +247,7 @@ }, "sizes": { - "window_minimum_size": [70, 54], + "window_minimum_size": [70, 50], "window_margin": [1.0, 1.0], "default_margin": [1.0, 1.0], "default_lining": [0.08, 0.08], From 5176b98f6e3a54ac31924307568c63245bfc21c7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 2 May 2017 13:58:11 +0200 Subject: [PATCH 48/49] Set the correct result in visible settings Oops. Contributes to issue CURA-3491. --- .../VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py b/plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py index 9e27759285..1af2e7405a 100644 --- a/plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py +++ b/plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py @@ -55,7 +55,7 @@ class VersionUpgrade24to25(VersionUpgrade): new_visible_settings.append(replaced_setting) continue #Don't add the original. new_visible_settings.append(setting) #No special handling, so just add the original visible setting back. - parser["general"]["visible_settings"] = ";".join(visible_settings) + parser["general"]["visible_settings"] = ";".join(new_visible_settings) #Change the version number in the file. if parser.has_section("general"): #It better have! From 0452cffff9e1504e832fc95bf81dc4b42b488feb Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 3 May 2017 09:37:12 +0200 Subject: [PATCH 49/49] Fix setting active extruder when changing Custom FDM printer extruders. CURA-3299 --- plugins/MachineSettingsAction/MachineSettingsAction.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 plugins/MachineSettingsAction/MachineSettingsAction.py diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py old mode 100644 new mode 100755 index 995a07eac4..32053d32ab --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -186,8 +186,8 @@ class MachineSettingsAction(MachineAction): if node.getMeshData(): extruder_nr = node.callDecoration("getActiveExtruderPosition") - if extruder_nr is not None and extruder_nr > extruder_count - 1: - node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count -1).getId()) + if extruder_nr is not None and int(extruder_nr) > extruder_count - 1: + node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count - 1).getId()) definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count) self.forceUpdate()