diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 950c97a4e2..5c6df6defe 100755 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -30,7 +30,6 @@ class MachineSettingsAction(MachineAction): self._global_container_stack = None self._container_index = 0 - self._extruder_container_index = 0 self._container_registry = ContainerRegistry.getInstance() self._container_registry.containerAdded.connect(self._onContainerAdded) @@ -38,6 +37,8 @@ class MachineSettingsAction(MachineAction): Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) + self._empty_container = self._container_registry.getEmptyInstanceContainer() + self._backend = Application.getInstance().getBackend() def _onContainerAdded(self, container): @@ -48,8 +49,8 @@ class MachineSettingsAction(MachineAction): 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: + definition_changes_container = container.definitionChanges + if definition_changes_container == self._empty_container: return self._container_registry.removeContainer(definition_changes_container.getId()) @@ -59,8 +60,8 @@ class MachineSettingsAction(MachineAction): return # Make sure there is a definition_changes container to store the machine settings - definition_changes_container = self._global_container_stack.findContainer({"type": "definition_changes"}) - if not definition_changes_container: + definition_changes_container = self._global_container_stack.definitionChanges + if definition_changes_container == self._empty_container: 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 @@ -85,16 +86,10 @@ class MachineSettingsAction(MachineAction): 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 = extruder_container_stack.definitionChanges + if definition_changes_container == self._empty_container: 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) - 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() @@ -113,13 +108,6 @@ 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 _onGlobalContainerChanged(self): self._global_container_stack = Application.getInstance().getGlobalContainerStack() @@ -140,8 +128,8 @@ class MachineSettingsAction(MachineAction): 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: + definition_changes_container = self._global_container_stack.definitionChanges + if not self._global_container_stack or definition_changes_container == self._empty_container: return previous_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value") @@ -250,30 +238,115 @@ class MachineSettingsAction(MachineAction): return 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 definition.getProperty("machine_gcode_flavor", "value") != "UltiGCode" or definition.getMetaDataEntry("has_materials", False): + # In other words: only continue for the UM2 (extended), but not for the UM2+ + return - material_container = self._global_container_stack.material - material_index = self._global_container_stack.getContainerIndex(material_container) + has_materials = self._global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode" - if has_materials: - if "has_materials" in self._global_container_stack.getMetaData(): - self._global_container_stack.setMetaDataEntry("has_materials", True) - else: - self._global_container_stack.addMetaDataEntry("has_materials", True) + material_container = self._global_container_stack.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]) + 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 self._global_container_stack.getMetaData(): - self._global_container_stack.removeMetaDataEntry("has_materials") + self._global_container_stack.addMetaDataEntry("has_materials", True) - self._global_container_stack.material = ContainerRegistry.getInstance().getEmptyInstanceContainer() + # Set the material container to a sane default + if material_container == self._empty_container: + search_criteria = { "type": "material", "definition": "fdmprinter", "id": self._global_container_stack.getMetaDataEntry("preferred_material")} + materials = self._container_registry.findInstanceContainers(**search_criteria) + if materials: + self._global_container_stack.material = materials[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() + self._global_container_stack.material = ContainerRegistry.getInstance().getEmptyInstanceContainer() + + Application.getInstance().globalContainerStackChanged.emit() + + @pyqtSlot() + def updateMaterialForDiameter(self): + # Updates the material container to a material that matches the material diameter set for the printer + if not self._global_container_stack: + return + + if not self._global_container_stack.getMetaDataEntry("has_materials", False): + return + + machine_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value") + if machine_extruder_count > 1: + material = ExtruderManager.getInstance().getActiveExtruderStack().material + else: + material = self._global_container_stack.material + material_diameter = material.getProperty("material_diameter", "value") + if not material_diameter: # in case of "empty" material + material_diameter = 0 + material_approximate_diameter = str(round(material_diameter)) + + definition_changes = self._global_container_stack.definitionChanges + machine_diameter = definition_changes.getProperty("material_diameter", "value") + if not machine_diameter: + machine_diameter = self._global_container_stack.definition.getProperty("material_diameter", "value") + machine_approximate_diameter = str(round(machine_diameter)) + + if material_approximate_diameter != machine_approximate_diameter: + Logger.log("i", "The the currently active material(s) do not match the diameter set for the printer. Finding alternatives.") + + if machine_extruder_count > 1: + stacks = ExtruderManager.getInstance().getExtruderStacks() + else: + stacks = [self._global_container_stack] + + if self._global_container_stack.getMetaDataEntry("has_machine_materials", False): + materials_definition = self._global_container_stack.definition.getId() + has_material_variants = self._global_container_stack.getMetaDataEntry("has_variants", False) + else: + materials_definition = "fdmprinter" + has_material_variants = False + + for stack in stacks: + old_material = stack.material + search_criteria = { + "type": "material", + "approximate_diameter": machine_approximate_diameter, + "material": old_material.getMetaDataEntry("material", "value"), + "supplier": old_material.getMetaDataEntry("supplier", "value"), + "color_name": old_material.getMetaDataEntry("color_name", "value"), + "definition": materials_definition + } + if has_material_variants: + search_criteria["variant"] = stack.variant.getId() + + if old_material == self._empty_container: + search_criteria.pop("material", None) + search_criteria.pop("supplier", None) + search_criteria.pop("definition", None) + search_criteria["id"] = stack.getMetaDataEntry("preferred_material") + + materials = self._container_registry.findInstanceContainers(**search_criteria) + if not materials: + # Same material with new diameter is not found, search for generic version of the same material type + search_criteria.pop("supplier", None) + search_criteria["color_name"] = "Generic" + materials = self._container_registry.findInstanceContainers(**search_criteria) + if not materials: + # Generic material with new diameter is not found, search for preferred material + search_criteria.pop("color_name", None) + search_criteria.pop("material", None) + search_criteria["id"] = stack.getMetaDataEntry("preferred_material") + materials = self._container_registry.findInstanceContainers(**search_criteria) + if not materials: + # Preferrd material with new diameter is not found, search for any material + search_criteria.pop("id", None) + materials = self._container_registry.findInstanceContainers(**search_criteria) + if not materials: + # Just use empty material as a final fallback + materials = [self._empty_container] + + Logger.log("i", "Selecting new material: %s" % materials[0].getId()) + + stack.material = materials[0] diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 23dc7f073f..897fb2a051 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -31,17 +31,23 @@ Cura.MachineAction 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() + onNextClicked: finishAction() + onBackClicked: finishAction() + onAccepted: finishAction() + onRejected: finishAction() + onClosing: finishAction() + } + + function finishAction() + { + forceActiveFocus(); + manager.onFinishAction(); } anchors.fill: parent; Item { - id: bedLevelMachineAction + id: machineSettingsAction anchors.fill: parent; UM.I18nCatalog { id: catalog; name: "cura"; } @@ -83,7 +89,7 @@ Cura.MachineAction Column { width: settingsTabs.columnWidth - spacing: UM.Theme.getSize("default_margin").height + spacing: UM.Theme.getSize("default_lining").height Label { @@ -91,182 +97,83 @@ Cura.MachineAction font.bold: true } - Grid + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + + Loader { - columns: 2 - columnSpacing: UM.Theme.getSize("default_margin").width - rowSpacing: UM.Theme.getSize("default_lining").width - - Label - { - text: catalog.i18nc("@label", "X (Width)") - } - Loader - { - id: buildAreaWidthField - sourceComponent: numericTextFieldWithUnit - property var propertyProvider: machineWidthProvider - property string unit: catalog.i18nc("@label", "mm") - property bool forceUpdateOnChange: true - } - - Label - { - text: catalog.i18nc("@label", "Y (Depth)") - } - Loader - { - id: buildAreaDepthField - sourceComponent: numericTextFieldWithUnit - property var propertyProvider: machineDepthProvider - property string unit: catalog.i18nc("@label", "mm") - property bool forceUpdateOnChange: true - } - - Label - { - text: catalog.i18nc("@label", "Z (Height)") - } - Loader - { - id: buildAreaHeightField - sourceComponent: numericTextFieldWithUnit - property var propertyProvider: machineHeightProvider - property string unit: catalog.i18nc("@label", "mm") - property bool forceUpdateOnChange: true - } + id: buildAreaWidthField + sourceComponent: numericTextFieldWithUnit + property string settingKey: "machine_width" + property string label: catalog.i18nc("@label", "X (Width)") + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: true } - Column + Loader { - Row - { - spacing: UM.Theme.getSize("default_margin").width - - Label - { - text: catalog.i18nc("@label", "Build Plate Shape") - } - - ComboBox - { - id: shapeComboBox - model: ListModel - { - id: shapesModel - Component.onCompleted: - { - // 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: - { - if(machineShapeProvider.properties.value != shapesModel.get(index).value) - { - 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) - } + id: buildAreaDepthField + sourceComponent: numericTextFieldWithUnit + property string settingKey: "machine_depth" + property string label: catalog.i18nc("@label", "Y (Depth)") + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: true } - Row + Loader { - spacing: UM.Theme.getSize("default_margin").width + id: buildAreaHeightField + sourceComponent: numericTextFieldWithUnit + property string settingKey: "machine_height" + property string label: catalog.i18nc("@label", "Z (Height)") + property string unit: catalog.i18nc("@label", "mm") + property bool forceUpdateOnChange: true + } - Label - { - text: catalog.i18nc("@label", "GCode Flavor") - } + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } - 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 = 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(); - } - } + Loader + { + id: shapeComboBox + sourceComponent: comboBoxWithOptions + property string settingKey: "machine_shape" + property string label: catalog.i18nc("@label", "Build plate shape") + property bool forceUpdateOnChange: true + } + + Loader + { + id: centerIsZeroCheckBox + sourceComponent: simpleCheckBox + property string settingKey: "machine_center_is_zero" + property string label: catalog.i18nc("@option:check", "Origin at center") + property bool forceUpdateOnChange: true + } + Loader + { + id: heatedBedCheckBox + sourceComponent: simpleCheckBox + property var settingKey: "machine_heated_bed" + property string label: catalog.i18nc("@option:check", "Heated bed") + property bool forceUpdateOnChange: true + } + + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + + Loader + { + id: gcodeFlavorComboBox + sourceComponent: comboBoxWithOptions + property string settingKey: "machine_gcode_flavor" + property string label: catalog.i18nc("@label", "Gcode flavor") + property bool forceUpdateOnChange: true + property var afterOnActivate: manager.updateHasMaterialsMetadata } } Column { width: settingsTabs.columnWidth - spacing: UM.Theme.getSize("default_margin").height + spacing: UM.Theme.getSize("default_lining").height Label { @@ -274,130 +181,121 @@ Cura.MachineAction font.bold: true } - Grid + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + + Loader { - columns: 2 - columnSpacing: UM.Theme.getSize("default_margin").width - rowSpacing: UM.Theme.getSize("default_lining").width + id: printheadXMinField + sourceComponent: headPolygonTextField + property string label: catalog.i18nc("@label", "X min") + property string tooltip: catalog.i18nc("@tooltip", "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\".") + property string axis: "x" + property string side: "min" + } - Label - { - text: catalog.i18nc("@label", "X min") - } - TextField - { - id: printheadXMinField - text: getHeadPolygonCoord("x", "min") - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: setHeadPolygon() - } + Loader + { + id: printheadYMinField + sourceComponent: headPolygonTextField + property string label: catalog.i18nc("@label", "Y min") + property string tooltip: catalog.i18nc("@tooltip", "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\".") + property string axis: "y" + property string side: "min" + } - Label - { - text: catalog.i18nc("@label", "Y min") - } - TextField - { - id: printheadYMinField - text: getHeadPolygonCoord("y", "min") - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: setHeadPolygon() - } + Loader + { + id: printheadXMaxField + sourceComponent: headPolygonTextField + property string label: catalog.i18nc("@label", "X max") + property string tooltip: catalog.i18nc("@tooltip", "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\".") + property string axis: "x" + property string side: "max" + } - Label - { - text: catalog.i18nc("@label", "X max") - } - TextField - { - id: printheadXMaxField - text: getHeadPolygonCoord("x", "max") - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: setHeadPolygon() - } + Loader + { + id: printheadYMaxField + sourceComponent: headPolygonTextField + property string label: catalog.i18nc("@label", "Y max") + property string tooltip: catalog.i18nc("@tooltip", "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\".") + property string axis: "y" + property string side: "max" + } - Label - { - text: catalog.i18nc("@label", "Y max") - } - TextField - { - id: printheadYMaxField - text: getHeadPolygonCoord("y", "max") - validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } - onEditingFinished: setHeadPolygon() - } + 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 } + Loader + { + id: gantryHeightField + sourceComponent: numericTextFieldWithUnit + property string settingKey: "gantry_height" + property string label: catalog.i18nc("@label", "Gantry height") + property string unit: catalog.i18nc("@label", "mm") + property string tooltip: catalog.i18nc("@tooltip", "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\".") + } - Label - { - text: catalog.i18nc("@label", "Gantry height") - } - Loader - { - id: gantryHeightField - sourceComponent: numericTextFieldWithUnit - property var propertyProvider: gantryHeightProvider - property string unit: 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 } + UM.TooltipArea + { + visible: manager.definedExtruderCount > 1 + height: childrenRect.height + width: childrenRect.width + text: machineExtruderCountProvider.properties.description - Label + Row { - text: catalog.i18nc("@label", "Number of Extruders") - visible: extruderCountComboBox.visible - } + spacing: UM.Theme.getSize("default_margin").width - ComboBox - { - id: extruderCountComboBox - visible: manager.definedExtruderCount > 1 - model: ListModel + Label { - id: extruderCountModel - Component.onCompleted: + text: catalog.i18nc("@label", "Number of Extruders") + elide: Text.ElideRight + width: Math.max(0, settingsTabs.columnWidth - 2 * UM.Theme.getSize("default_margin").width - extruderCountComboBox.width) + anchors.verticalCenter: extruderCountComboBox.verticalCenter + } + ComboBox + { + id: extruderCountComboBox + model: ListModel { - for(var i = 0; i < manager.definedExtruderCount; i++) + id: extruderCountModel + Component.onCompleted: { - extruderCountModel.append({text: String(i + 1), value: i}); + for(var i = 0; i < manager.definedExtruderCount; i++) + { + extruderCountModel.append({text: String(i + 1), value: i}); + } } } - } - currentIndex: machineExtruderCountProvider.properties.value - 1 - onActivated: - { - manager.setMachineExtruderCount(index + 1); + currentIndex: machineExtruderCountProvider.properties.value - 1 + onActivated: + { + manager.setMachineExtruderCount(index + 1); + } } } + } - Label - { - text: catalog.i18nc("@label", "Material Diameter") - } - Loader - { - id: materialDiameterField - sourceComponent: numericTextFieldWithUnit - property var propertyProvider: materialDiameterProvider - property string unit: catalog.i18nc("@label", "mm") - } - Label - { - text: catalog.i18nc("@label", "Nozzle size") - visible: nozzleSizeField.visible - } - Loader - { - id: nozzleSizeField - visible: !Cura.MachineManager.hasVariants && machineExtruderCountProvider.properties.value == 1 - sourceComponent: numericTextFieldWithUnit - property var propertyProvider: machineNozzleSizeProvider - property string unit: catalog.i18nc("@label", "mm") - } + Loader + { + id: materialDiameterField + sourceComponent: numericTextFieldWithUnit + property string settingKey: "material_diameter" + property string unit: catalog.i18nc("@label", "mm") + property string tooltip: catalog.i18nc("@tooltip", "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile.") + property var afterOnEditingFinished: manager.updateMaterialForDiameter + property string label: catalog.i18nc("@label", "Material diameter") + } + Loader + { + id: nozzleSizeField + visible: !Cura.MachineManager.hasVariants && machineExtruderCountProvider.properties.value == 1 + sourceComponent: numericTextFieldWithUnit + property string settingKey: "machine_nozzle_size" + property string label: catalog.i18nc("@label", "Nozzle size") + property string unit: catalog.i18nc("@label", "mm") } } } @@ -417,24 +315,14 @@ Cura.MachineAction text: catalog.i18nc("@label", "Start Gcode") font.bold: true } - TextArea + Loader { id: machineStartGcodeField - width: parent.width - height: parent.height - y - font: UM.Theme.getFont("fixed") - text: machineStartGcodeProvider.properties.value - onActiveFocusChanged: - { - if(!activeFocus) - { - machineStartGcodeProvider.setPropertyValue("value", machineStartGcodeField.text) - } - } - Component.onCompleted: - { - wrapMode = TextEdit.NoWrap; - } + sourceComponent: gcodeTextArea + property int areaWidth: parent.width + property int areaHeight: parent.height - y + property string settingKey: "machine_start_gcode" + property string tooltip: catalog.i18nc("@tooltip", "Gcode commands to be executed at the very start.") } } @@ -446,57 +334,17 @@ Cura.MachineAction text: catalog.i18nc("@label", "End Gcode") font.bold: true } - TextArea + Loader { id: machineEndGcodeField - width: parent.width - height: parent.height - y - font: UM.Theme.getFont("fixed") - text: machineEndGcodeProvider.properties.value - onActiveFocusChanged: - { - if(!activeFocus) - { - machineEndGcodeProvider.setPropertyValue("value", machineEndGcodeField.text) - } - } - Component.onCompleted: - { - wrapMode = TextEdit.NoWrap; - } + sourceComponent: gcodeTextArea + property int areaWidth: parent.width + property int areaHeight: parent.height - y + property string settingKey: "machine_end_gcode" + property string tooltip: catalog.i18nc("@tooltip", "Gcode commands to be executed at the very end.") } } } - - 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(); - } - } } } @@ -521,7 +369,7 @@ Cura.MachineAction Column { - spacing: UM.Theme.getSize("default_margin").width + spacing: UM.Theme.getSize("default_lining").width Label { @@ -529,54 +377,45 @@ Cura.MachineAction font.bold: true } - Grid + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + + Loader { - 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 - } - Loader - { - id: extruderNozzleSizeField - visible: !Cura.MachineManager.hasVariants - sourceComponent: numericTextFieldWithUnit - property var propertyProvider: extruderNozzleSizeProvider - property string unit: catalog.i18nc("@label", "mm") - } - - Label - { - text: catalog.i18nc("@label", "Nozzle offset X") - } - Loader - { - id: extruderOffsetXField - sourceComponent: numericTextFieldWithUnit - property var propertyProvider: extruderOffsetXProvider - property string unit: catalog.i18nc("@label", "mm") - property bool forceUpdateOnChange: true - property bool allowNegative: true - } - Label - { - text: catalog.i18nc("@label", "Nozzle offset Y") - } - Loader - { - id: extruderOffsetYField - sourceComponent: numericTextFieldWithUnit - property var propertyProvider: extruderOffsetYProvider - property string unit: catalog.i18nc("@label", "mm") - property bool forceUpdateOnChange: true - property bool allowNegative: true - } + id: extruderNozzleSizeField + visible: !Cura.MachineManager.hasVariants + sourceComponent: numericTextFieldWithUnit + property string settingKey: "machine_nozzle_size" + property string label: catalog.i18nc("@label", "Nozzle size") + property string unit: catalog.i18nc("@label", "mm") + property bool isExtruderSetting: true } + Loader + { + id: extruderOffsetXField + sourceComponent: numericTextFieldWithUnit + property string settingKey: "machine_nozzle_offset_x" + property string label: catalog.i18nc("@label", "Nozzle offset X") + property string unit: catalog.i18nc("@label", "mm") + property bool isExtruderSetting: true + property bool forceUpdateOnChange: true + property bool allowNegative: true + } + + Loader + { + id: extruderOffsetYField + sourceComponent: numericTextFieldWithUnit + property string settingKey: "machine_nozzle_offset_y" + property string label: catalog.i18nc("@label", "Nozzle offset Y") + property string unit: catalog.i18nc("@label", "mm") + property bool isExtruderSetting: true + property bool forceUpdateOnChange: true + property bool allowNegative: true + } + + Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height } + Row { spacing: UM.Theme.getSize("default_margin").width @@ -592,25 +431,15 @@ Cura.MachineAction text: catalog.i18nc("@label", "Extruder Start Gcode") font.bold: true } - TextArea + Loader { id: extruderStartGcodeField - width: parent.width - height: parent.height - y - font: UM.Theme.getFont("fixed") - text: (extruderStartGcodeProvider.properties.value) ? extruderStartGcodeProvider.properties.value : "" - onActiveFocusChanged: - { - if(!activeFocus) - { - extruderStartGcodeProvider.setPropertyValue("value", extruderStartGcodeField.text) - } - } - Component.onCompleted: - { - wrapMode = TextEdit.NoWrap; - } - } + sourceComponent: gcodeTextArea + property int areaWidth: parent.width + property int areaHeight: parent.height - y + property string settingKey: "machine_extruder_start_code" + property bool isExtruderSetting: true + } } Column { height: parent.height @@ -620,24 +449,14 @@ Cura.MachineAction text: catalog.i18nc("@label", "Extruder End Gcode") font.bold: true } - TextArea + Loader { id: extruderEndGcodeField - width: parent.width - height: parent.height - y - font: UM.Theme.getFont("fixed") - text: (extruderEndGcodeProvider.properties.value) ? extruderEndGcodeProvider.properties.value : "" - onActiveFocusChanged: - { - if(!activeFocus) - { - extruderEndGcodeProvider.setPropertyValue("value", extruderEndGcodeField.text) - } - } - Component.onCompleted: - { - wrapMode = TextEdit.NoWrap; - } + sourceComponent: gcodeTextArea + property int areaWidth: parent.width + property int areaHeight: parent.height - y + property string settingKey: "machine_extruder_end_code" + property bool isExtruderSetting: true } } } @@ -649,136 +468,395 @@ Cura.MachineAction Component { - id: numericTextFieldWithUnit - Item { - height: textField.height - width: textField.width + id: simpleCheckBox + UM.TooltipArea + { + height: checkBox.height + width: checkBox.width + text: _tooltip - property bool _allowNegative: (typeof(allowNegative) === 'undefined') ? false : allowNegative + property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false: isExtruderSetting property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false: forceUpdateOnChange + property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip - TextField + UM.SettingPropertyProvider { - id: textField - text: (propertyProvider.properties.value) ? propertyProvider.properties.value : "" - validator: RegExpValidator { regExp: _allowNegative ? /-?[0-9\.]{0,6}/ : /[0-9\.]{0,6}/ } - onEditingFinished: - { - if (propertyProvider && text != propertyProvider.properties.value) + id: propertyProvider + + containerStackId: { + if(_isExtruderSetting) { - propertyProvider.setPropertyValue("value", text); + if(settingsTabs.currentIndex > 0) + { + return Cura.MachineManager.activeStackId; + } + return ""; + } + return Cura.MachineManager.activeMachineId; + } + key: settingKey + watchedProperties: [ "value", "description" ] + storeIndex: manager.containerIndex + } + + CheckBox + { + id: checkBox + text: label + checked: String(propertyProvider.properties.value).toLowerCase() != 'false' + onClicked: + { + propertyProvider.setPropertyValue("value", checked); if(_forceUpdateOnChange) { - var extruderIndex = ExtruderManager.activeExtruderIndex; manager.forceUpdate(); - if(ExtruderManager.activeExtruderIndex != extruderIndex) + } + } + } + } + } + + Component + { + id: numericTextFieldWithUnit + UM.TooltipArea + { + height: childrenRect.height + width: childrenRect.width + text: _tooltip + + property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false: isExtruderSetting + property bool _allowNegative: (typeof(allowNegative) === 'undefined') ? false : allowNegative + property var _afterOnEditingFinished: (typeof(afterOnEditingFinished) === 'undefined') ? undefined : afterOnEditingFinished + property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false : forceUpdateOnChange + property string _label: (typeof(label) === 'undefined') ? "" : label + property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip + + UM.SettingPropertyProvider + { + id: propertyProvider + + containerStackId: { + if(_isExtruderSetting) + { + if(settingsTabs.currentIndex > 0) + { + return Cura.MachineManager.activeStackId; + } + return ""; + } + return Cura.MachineManager.activeMachineId; + } + key: settingKey + watchedProperties: [ "value", "description" ] + storeIndex: manager.containerIndex + } + + Row + { + spacing: UM.Theme.getSize("default_margin").width + + Label + { + text: _label + visible: _label != "" + elide: Text.ElideRight + width: Math.max(0, settingsTabs.columnWidth - 2 * UM.Theme.getSize("default_margin").width - textFieldWithUnit.width) + anchors.verticalCenter: textFieldWithUnit.verticalCenter + } + + Item + { + width: textField.width + height: textField.height + + id: textFieldWithUnit + TextField + { + id: textField + text: (propertyProvider.properties.value) ? propertyProvider.properties.value : "" + validator: RegExpValidator { regExp: _allowNegative ? /-?[0-9\.]{0,6}/ : /[0-9\.]{0,6}/ } + onEditingFinished: + { + if (propertyProvider && text != propertyProvider.properties.value) { - ExtruderManager.setActiveExtruderIndex(extruderIndex) + propertyProvider.setPropertyValue("value", text); + if(_forceUpdateOnChange) + { + var extruderIndex = ExtruderManager.activeExtruderIndex; + manager.forceUpdate(); + if(ExtruderManager.activeExtruderIndex != extruderIndex) + { + ExtruderManager.setActiveExtruderIndex(extruderIndex) + } + } + if(_afterOnEditingFinished) + { + _afterOnEditingFinished(); + } + } + } + } + + Label + { + text: unit + anchors.right: textField.right + anchors.rightMargin: y - textField.y + anchors.verticalCenter: textField.verticalCenter + } + } + } + } + } + + Component + { + id: comboBoxWithOptions + UM.TooltipArea + { + height: childrenRect.height + width: childrenRect.width + text: _tooltip + + property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false : isExtruderSetting + property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false : forceUpdateOnChange + property var _afterOnActivate: (typeof(afterOnActivate) === 'undefined') ? undefined : afterOnActivate + property string _label: (typeof(label) === 'undefined') ? "" : label + property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip + + UM.SettingPropertyProvider + { + id: propertyProvider + + containerStackId: { + if(_isExtruderSetting) + { + if(settingsTabs.currentIndex > 0) + { + return Cura.MachineManager.activeStackId; + } + return ""; + } + return Cura.MachineManager.activeMachineId; + } + key: settingKey + watchedProperties: [ "value", "options", "description" ] + storeIndex: manager.containerIndex + } + + Row + { + spacing: UM.Theme.getSize("default_margin").width + + Label + { + text: _label + visible: _label != "" + elide: Text.ElideRight + width: Math.max(0, settingsTabs.columnWidth - 2 * UM.Theme.getSize("default_margin").width - comboBox.width) + anchors.verticalCenter: comboBox.verticalCenter + } + ComboBox + { + id: comboBox + model: ListModel + { + id: optionsModel + Component.onCompleted: + { + // Options come in as a string-representation of an OrderedDict + var options = propertyProvider.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("', '") + optionsModel.append({text: option[1], value: option[0]}); + } + } + } + } + currentIndex: + { + var currentValue = propertyProvider.properties.value; + var index = 0; + for(var i = 0; i < optionsModel.count; i++) + { + if(optionsModel.get(i).value == currentValue) { + index = i; + break; + } + } + return index + } + onActivated: + { + if(propertyProvider.properties.value != optionsModel.get(index).value) + { + propertyProvider.setPropertyValue("value", optionsModel.get(index).value); + if(_forceUpdateOnChange) + { + manager.forceUpdate(); + } + if(_afterOnActivate) + { + _afterOnActivate(); } } } } } + } + } - Label + Component + { + id: gcodeTextArea + + UM.TooltipArea + { + height: gcodeArea.height + width: gcodeArea.width + text: _tooltip + + property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false: isExtruderSetting + property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip + + UM.SettingPropertyProvider { - text: unit - anchors.right: textField.right - anchors.rightMargin: y - textField.y - anchors.verticalCenter: textField.verticalCenter + id: propertyProvider + + containerStackId: { + if(_isExtruderSetting) + { + if(settingsTabs.currentIndex > 0) + { + return Cura.MachineManager.activeStackId; + } + return ""; + } + return Cura.MachineManager.activeMachineId; + } + key: settingKey + watchedProperties: [ "value", "description" ] + storeIndex: manager.containerIndex + } + + TextArea + { + id: gcodeArea + width: areaWidth + height: areaHeight + font: UM.Theme.getFont("fixed") + text: (propertyProvider.properties.value) ? propertyProvider.properties.value : "" + onActiveFocusChanged: + { + if(!activeFocus) + { + propertyProvider.setPropertyValue("value", gcodeField.text) + } + } + Component.onCompleted: + { + wrapMode = TextEdit.NoWrap; + } } } } - UM.SettingPropertyProvider + Component { - id: machineWidthProvider + id: headPolygonTextField + UM.TooltipArea + { + height: textField.height + width: textField.width + text: tooltip - containerStackId: Cura.MachineManager.activeMachineId - key: "machine_width" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex + property string _label: (typeof(label) === 'undefined') ? "" : label + + Row + { + spacing: UM.Theme.getSize("default_margin").width + + Label + { + text: _label + visible: _label != "" + elide: Text.ElideRight + width: Math.max(0, settingsTabs.columnWidth - 2 * UM.Theme.getSize("default_margin").width - textFieldWithUnit.width) + anchors.verticalCenter: textFieldWithUnit.verticalCenter + } + + Item + { + id: textFieldWithUnit + width: textField.width + height: textField.height + + TextField + { + id: textField + text: + { + 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 (side == "min") { + result = Math.min(result, polygon[i][item]); + } else { + result = Math.max(result, polygon[i][item]); + } + } + result = Math.abs(result); + printHeadPolygon[axis][side] = result; + return result; + } + validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ } + onEditingFinished: + { + printHeadPolygon[axis][side] = parseFloat(textField.text); + var polygon = []; + polygon.push([-printHeadPolygon["x"]["min"], printHeadPolygon["y"]["max"]]); + polygon.push([-printHeadPolygon["x"]["min"],-printHeadPolygon["y"]["min"]]); + polygon.push([ printHeadPolygon["x"]["max"], printHeadPolygon["y"]["max"]]); + polygon.push([ printHeadPolygon["x"]["max"],-printHeadPolygon["y"]["mìn"]]); + var polygon_string = JSON.stringify(polygon); + if(polygon_string != machineHeadPolygonProvider.properties.value) + { + machineHeadPolygonProvider.setPropertyValue("value", polygon_string); + manager.forceUpdate(); + } + } + } + + Label + { + text: catalog.i18nc("@label", "mm") + anchors.right: textField.right + anchors.rightMargin: y - textField.y + anchors.verticalCenter: textField.verticalCenter + } + } + } + } } - UM.SettingPropertyProvider + property var printHeadPolygon: { - id: machineDepthProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "machine_depth" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex + "x": { + "min": 0, + "max": 0, + }, + "y": { + "min": 0, + "max": 0, + }, } - UM.SettingPropertyProvider - { - id: machineHeightProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "machine_height" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: machineShapeProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "machine_shape" - watchedProperties: [ "value", "options" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: machineHeatedBedProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "machine_heated_bed" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: machineCenterIsZeroProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "machine_center_is_zero" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: machineGCodeFlavorProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "machine_gcode_flavor" - watchedProperties: [ "value", "options" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: materialDiameterProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "material_diameter" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: machineNozzleSizeProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "machine_nozzle_size" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } UM.SettingPropertyProvider { @@ -786,17 +864,7 @@ Cura.MachineAction containerStackId: Cura.MachineManager.activeMachineId key: "machine_extruder_count" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: gantryHeightProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "gantry_height" - watchedProperties: [ "value" ] + watchedProperties: [ "value", "description" ] storeIndex: manager.containerIndex } @@ -809,75 +877,4 @@ Cura.MachineAction watchedProperties: [ "value" ] storeIndex: manager.containerIndex } - - - UM.SettingPropertyProvider - { - id: machineStartGcodeProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "machine_start_gcode" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: machineEndGcodeProvider - - containerStackId: Cura.MachineManager.activeMachineId - key: "machine_end_gcode" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: extruderNozzleSizeProvider - - containerStackId: settingsTabs.currentIndex > 0 ? Cura.MachineManager.activeStackId : "" - key: "machine_nozzle_size" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: extruderOffsetXProvider - - containerStackId: settingsTabs.currentIndex > 0 ? Cura.MachineManager.activeStackId : "" - key: "machine_nozzle_offset_x" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: extruderOffsetYProvider - - containerStackId: settingsTabs.currentIndex > 0 ? Cura.MachineManager.activeStackId : "" - key: "machine_nozzle_offset_y" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: extruderStartGcodeProvider - - containerStackId: settingsTabs.currentIndex > 0 ? Cura.MachineManager.activeStackId : "" - key: "machine_extruder_start_code" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } - - UM.SettingPropertyProvider - { - id: extruderEndGcodeProvider - - containerStackId: settingsTabs.currentIndex > 0 ? Cura.MachineManager.activeStackId : "" - key: "machine_extruder_end_code" - watchedProperties: [ "value" ] - storeIndex: manager.containerIndex - } } \ No newline at end of file