123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778 |
- // Copyright (c) 2022 Ultimaker B.V.
- // Cura is released under the terms of the LGPLv3 or higher.
- import QtQuick 2.7
- import QtQuick.Controls 2.15
- import QtQuick.Layouts 1.3
- import QtQuick.Dialogs
- import UM 1.5 as UM
- import Cura 1.0 as Cura
- Item
- {
- id: base
- property QtObject properties
- property var currentMaterialNode: null
- property bool editingEnabled: false
- property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€"
- property string containerId: ""
- property var materialPreferenceValues: UM.Preferences.getValue("cura/material_settings") ? JSON.parse(UM.Preferences.getValue("cura/material_settings")) : {}
- property var materialManagementModel: CuraApplication.getMaterialManagementModel()
- property double spoolLength: calculateSpoolLength()
- property real costPerMeter: calculateCostPerMeter()
- signal resetSelectedMaterial()
- property bool reevaluateLinkedMaterials: false
- property string linkedMaterialNames:
- {
- if (reevaluateLinkedMaterials)
- {
- reevaluateLinkedMaterials = false;
- }
- if (!base.containerId || !base.editingEnabled || !base.currentMaterialNode)
- {
- return "";
- }
- var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.currentMaterialNode, true);
- if (linkedMaterials.length == 0)
- {
- return "";
- }
- return linkedMaterials.join(", ");
- }
- function getApproximateDiameter(diameter)
- {
- return Math.round(diameter);
- }
- // This trick makes sure to make all fields lose focus so their onEditingFinished will be triggered
- // and modified values will be saved. This can happen when a user changes a value and then closes the
- // dialog directly.
- //
- // Please note that somehow this callback is ONLY triggered when visible is false.
- onVisibleChanged:
- {
- if (!visible)
- {
- base.focus = false;
- }
- }
- Rectangle
- {
- color: UM.Theme.getColor("main_background")
- anchors
- {
- top: pageSelectorTabRow.bottom
- topMargin: -UM.Theme.getSize("default_lining").width
- left: parent.left
- right: parent.right
- bottom: parent.bottom
- }
- border.width: UM.Theme.getSize("default_lining").width
- border.color: UM.Theme.getColor("border_main")
- ScrollView
- {
- id: informationPage
- anchors
- {
- fill: parent
- topMargin: UM.Theme.getSize("thin_margin").height
- bottomMargin: UM.Theme.getSize("thin_margin").height
- leftMargin: UM.Theme.getSize("thin_margin").width
- rightMargin: UM.Theme.getSize("thin_margin").width
- }
- ScrollBar.vertical: UM.ScrollBar
- {
- id: scrollBar
- parent: informationPage.parent
- anchors
- {
- top: parent.top
- right: parent.right
- bottom: parent.bottom
- }
- }
- ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
- clip: true
- visible: pageSelectorTabRow.currentItem.activeView === "information"
- property real columnWidth: Math.floor((width - scrollBar.width - UM.Theme.getSize("narrow_margin").width) / 2)
- property real rowHeight: UM.Theme.getSize("setting_control").height
- Column
- {
- width: informationPage.width
- spacing: UM.Theme.getSize("narrow_margin").height
- Cura.MessageDialog
- {
- id: confirmDiameterChangeDialog
- title: catalog.i18nc("@title:window", "Confirm Diameter Change")
- text: catalog.i18nc("@label (%1 is a number)", "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?".arg(new_diameter_value))
- standardButtons: Dialog.Yes | Dialog.No
- property var new_diameter_value: null
- property var old_diameter_value: null
- property var old_approximate_diameter_value: null
- onAccepted:
- {
- base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString());
- base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value);
- // CURA-6868 Make sure to update the extruder to user a diameter-compatible material.
- Cura.MachineManager.updateMaterialWithVariant()
- base.resetSelectedMaterial()
- }
- onRejected:
- {
- base.properties.diameter = old_diameter_value;
- diameterTextField.valueText = Qt.binding(function() { return base.properties.diameter })
- }
- }
- Row
- {
- spacing: UM.Theme.getSize("narrow_margin").width
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- text: catalog.i18nc("@label", "Display Name")
- }
- Cura.TextField
- {
- id: displayNameTextField
- width: informationPage.columnWidth
- text: properties.name
- enabled: base.editingEnabled
- onEditingFinished: base.updateMaterialDisplayName(properties.name, text)
- }
- }
- Row
- {
- spacing: UM.Theme.getSize("narrow_margin").width
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- text: catalog.i18nc("@label", "Brand")
- }
- Cura.TextField
- {
- id: brandTextField
- width: informationPage.columnWidth
- text: properties.brand
- enabled: base.editingEnabled
- onEditingFinished: base.updateMaterialBrand(properties.brand, text)
- }
- }
- Row
- {
- spacing: UM.Theme.getSize("narrow_margin").width
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- text: catalog.i18nc("@label", "Material Type")
- }
- Cura.TextField
- {
- id: materialTypeField
- width: informationPage.columnWidth
- text: properties.material
- enabled: base.editingEnabled
- onEditingFinished: base.updateMaterialType(properties.material, text)
- }
- }
- Row
- {
- spacing: UM.Theme.getSize("narrow_margin").width
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- verticalAlignment: Qt.AlignVCenter
- text: catalog.i18nc("@label", "Color")
- }
- Row
- {
- width: informationPage.columnWidth
- spacing: Math.round(UM.Theme.getSize("default_margin").width / 2)
- // color indicator square
- Item
- {
- id: colorSelector
- anchors.verticalCenter: parent.verticalCenter
- width: colorSelectorBackground.width + 2 * UM.Theme.getSize("narrow_margin").width
- height: colorSelectorBackground.height + 2 * UM.Theme.getSize("narrow_margin").height
- Rectangle
- {
- id: colorSelectorBackground
- color: properties.color_code
- width: UM.Theme.getSize("icon_indicator").width
- height: UM.Theme.getSize("icon_indicator").height
- radius: width / 2
- anchors.centerIn: parent
- }
- // open the color selection dialog on click
- MouseArea
- {
- anchors.fill: parent
- onClicked: colorDialog.open()
- enabled: base.editingEnabled
- }
- }
- // pretty color name text field
- Cura.TextField
- {
- id: colorLabel;
- width: parent.width - colorSelector.width - parent.spacing
- text: properties.color_name;
- enabled: base.editingEnabled
- onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text)
- }
- // popup dialog to select a new color
- // if successful it sets the properties.color_code value to the new color
- Cura.ColorDialog
- {
- id: colorDialog
- title: catalog.i18nc("@title", "Material color picker")
- color: properties.color_code
- onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color)
- }
- }
- }
- UM.Label
- {
- width: parent.width
- height: parent.rowHeight
- font: UM.Theme.getFont("default_bold")
- verticalAlignment: Qt.AlignVCenter
- text: catalog.i18nc("@label", "Properties")
- }
- Row
- {
- height: parent.rowHeight
- spacing: UM.Theme.getSize("narrow_margin").width
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- text: catalog.i18nc("@label", "Density")
- }
- Cura.NumericTextFieldWithUnit
- {
- id: densityTextField
- enabled: base.editingEnabled
- valueText: properties.density
- controlWidth: informationPage.columnWidth
- controlHeight: informationPage.rowHeight
- spacing: 0
- unitText: "g/cm³"
- decimals: 2
- maximum: 1000
- editingFinishedFunction: function()
- {
- var modified_text = valueText.replace(",", ".");
- base.setMetaDataEntry("properties/density", properties.density, modified_text)
- }
- onValueTextChanged: updateCostPerMeter()
- }
- }
- Row
- {
- height: parent.rowHeight
- spacing: UM.Theme.getSize("narrow_margin").width
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- text: catalog.i18nc("@label", "Diameter")
- }
- Cura.NumericTextFieldWithUnit
- {
- id: diameterTextField
- enabled: base.editingEnabled
- valueText: properties.diameter
- controlWidth: informationPage.columnWidth
- controlHeight: informationPage.rowHeight
- spacing: 0
- unitText: "mm"
- decimals: 2
- maximum: 1000
- editingFinishedFunction: function()
- {
- // This does not use a SettingPropertyProvider, because we need to make the change to all containers
- // which derive from the same base_file
- var old_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "properties/diameter");
- var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
- var modified_value = valueText.replace(",", ".");
- var new_approximate_diameter = getApproximateDiameter(modified_value);
- if (new_approximate_diameter != Cura.ExtruderManager.getActiveExtruderStack().approximateMaterialDiameter)
- {
- confirmDiameterChangeDialog.old_diameter_value = old_diameter;
- confirmDiameterChangeDialog.new_diameter_value = modified_value;
- confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter;
- confirmDiameterChangeDialog.open()
- }
- else {
- base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, new_approximate_diameter);
- base.setMetaDataEntry("properties/diameter", properties.diameter, modified_value);
- }
- }
- onValueTextChanged: updateCostPerMeter()
- }
- }
- Row
- {
- height: parent.rowHeight
- spacing: UM.Theme.getSize("narrow_margin").width
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- text: catalog.i18nc("@label", "Filament Cost")
- }
- Cura.NumericTextFieldWithUnit
- {
- id: spoolCostTextField
- valueText: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
- controlWidth: informationPage.columnWidth
- controlHeight: informationPage.rowHeight
- spacing: 0
- unitText: base.currency
- decimals: 2
- maximum: 100000000
- editingFinishedFunction: function()
- {
- var modified_text = valueText.replace(",", ".");
- base.setMaterialPreferenceValue(properties.guid, "spool_cost", modified_text);
- }
- onValueTextChanged: updateCostPerMeter()
- }
- }
- Row
- {
- height: parent.rowHeight
- spacing: UM.Theme.getSize("narrow_margin").width
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- text: catalog.i18nc("@label", "Filament weight")
- }
- Cura.NumericTextFieldWithUnit
- {
- id: spoolWeightTextField
- valueText: base.getMaterialPreferenceValue(properties.guid, "spool_weight", Cura.ContainerManager.getContainerMetaDataEntry(properties.container_id, "properties/weight"))
- controlWidth: informationPage.columnWidth
- controlHeight: informationPage.rowHeight
- spacing: 0
- unitText: " g"
- decimals: 0
- maximum: 10000
- editingFinishedFunction: function()
- {
- var modified_text = valueText.replace(",", ".")
- base.setMaterialPreferenceValue(properties.guid, "spool_weight", modified_text)
- }
- onValueTextChanged: updateCostPerMeter()
- }
- }
- Row
- {
- height: parent.rowHeight
- spacing: UM.Theme.getSize("narrow_margin").width
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- text: catalog.i18nc("@label", "Filament length")
- }
- UM.Label
- {
- width: informationPage.columnWidth
- text: "~ %1 m".arg(Math.round(base.spoolLength))
- height: informationPage.rowHeight
- }
- }
- Row
- {
- height: parent.rowHeight
- spacing: UM.Theme.getSize("narrow_margin").width
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- text: catalog.i18nc("@label", "Cost per Meter")
- }
- UM.Label
- {
- height: informationPage.rowHeight
- width: informationPage.columnWidth
- text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
- }
- }
- UM.Label
- {
- height: parent.rowHeight
- width: informationPage.width
- text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames)
- wrapMode: Text.WordWrap
- visible: unlinkMaterialButton.visible
- }
- Cura.SecondaryButton
- {
- id: unlinkMaterialButton
- text: catalog.i18nc("@label", "Unlink Material")
- visible: base.linkedMaterialNames != ""
- onClicked:
- {
- Cura.ContainerManager.unlinkMaterial(base.currentMaterialNode)
- base.reevaluateLinkedMaterials = true
- }
- }
- UM.Label
- {
- width: informationPage.width
- height: parent.rowHeight
- text: catalog.i18nc("@label", "Description")
- }
- Cura.ReadOnlyTextArea
- {
- text: properties.description
- width: informationPage.width - scrollBar.width
- height: 0.4 * informationPage.width
- wrapMode: Text.WordWrap
- readOnly: !base.editingEnabled
- onEditingFinished: base.setMetaDataEntry("description", properties.description, text)
- }
- UM.Label
- {
- width: informationPage.width
- height: parent.rowHeight
- text: catalog.i18nc("@label", "Adhesion Information")
- }
- Cura.ReadOnlyTextArea
- {
- text: properties.adhesion_info
- width: informationPage.width - scrollBar.width
- height: 0.4 * informationPage.width
- wrapMode: Text.WordWrap
- readOnly: !base.editingEnabled
- onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
- }
- }
- }
- ListView
- {
- id: settingsPage
- visible: pageSelectorTabRow.currentItem.activeView === "settings"
- clip: true
- anchors
- {
- fill: parent
- topMargin: UM.Theme.getSize("thin_margin").height
- bottomMargin: UM.Theme.getSize("thin_margin").height
- leftMargin: UM.Theme.getSize("thin_margin").width
- rightMargin: UM.Theme.getSize("thin_margin").width
- }
- width: settingsPage.width
- spacing: UM.Theme.getSize("narrow_margin").height
- ScrollBar.vertical: UM.ScrollBar
- {
- id: settingScrollBar
- parent: settingsPage.parent
- anchors
- {
- top: parent.top
- right: parent.right
- bottom: parent.bottom
- }
- }
- property real columnWidth: Math.floor((width - settingScrollBar.width - UM.Theme.getSize("narrow_margin").width) / 2)
- model: UM.SettingDefinitionsModel
- {
- containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
- visibilityHandler: Cura.MaterialSettingsVisibilityHandler { }
- expanded: ["*"]
- }
- delegate: UM.TooltipArea
- {
- width: childrenRect.width
- height: childrenRect.height
- UM.TooltipArea
- {
- anchors.fill: parent
- text: model.description
- }
- UM.Label
- {
- id: label
- width: settingsPage.columnWidth
- height: spinBox.height + UM.Theme.getSize("default_lining").height
- text: model.label
- elide: Text.ElideRight
- verticalAlignment: Qt.AlignVCenter
- }
- Cura.SpinBox
- {
- id: spinBox
- anchors.left: label.right
- value:
- {
- // In case the setting is not in the material...
- if (!isNaN(parseFloat(materialPropertyProvider.properties.value)))
- {
- return parseFloat(materialPropertyProvider.properties.value);
- }
- // ... we search in the variant, and if it is not there...
- if (!isNaN(parseFloat(variantPropertyProvider.properties.value)))
- {
- return parseFloat(variantPropertyProvider.properties.value);
- }
- // ... then look in the definition container.
- if (!isNaN(parseFloat(machinePropertyProvider.properties.value)))
- {
- return parseFloat(machinePropertyProvider.properties.value);
- }
- return 0;
- }
- width: settingsPage.columnWidth
- suffix: " " + model.unit
- to: 99999
- decimals: model.unit == "mm" ? 2 : 0
- onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
- }
- UM.ContainerPropertyProvider
- {
- id: materialPropertyProvider
- containerId: base.containerId
- watchedProperties: [ "value" ]
- key: model.key
- }
- UM.ContainerPropertyProvider
- {
- id: variantPropertyProvider
- containerId: Cura.MachineManager.activeStack.variant.id
- watchedProperties: [ "value" ]
- key: model.key
- }
- UM.ContainerPropertyProvider
- {
- id: machinePropertyProvider
- containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
- watchedProperties: ["value"]
- key: model.key
- }
- }
- }
- }
- UM.TabRow
- {
- id: pageSelectorTabRow
- UM.TabRowButton
- {
- text: catalog.i18nc("@title", "Information")
- property string activeView: "information" //To determine which page gets displayed.
- }
- UM.TabRowButton
- {
- text: catalog.i18nc("@label", "Print settings")
- property string activeView: "settings"
- }
- }
- function updateCostPerMeter()
- {
- var modified_weight = spoolWeightTextField.valueText.replace(",", ".")
- var modified_cost = spoolCostTextField.valueText.replace(",", ".")
- var modified_diameter = diameterTextField.valueText.replace(",", ".")
- var modified_density = densityTextField.valueText.replace(",", ".")
- base.spoolLength = calculateSpoolLength(modified_diameter, modified_density, parseInt(modified_weight));
- base.costPerMeter = calculateCostPerMeter(parseFloat(modified_cost));
- }
- function calculateSpoolLength(diameter, density, spoolWeight)
- {
- if(!diameter)
- {
- diameter = properties.diameter;
- }
- if(!density)
- {
- density = properties.density;
- }
- if(!spoolWeight)
- {
- spoolWeight = base.getMaterialPreferenceValue(properties.guid, "spool_weight", Cura.ContainerManager.getContainerMetaDataEntry(properties.container_id, "properties/weight"));
- }
- if (diameter == 0 || density == 0 || spoolWeight == 0)
- {
- return 0;
- }
- var area = Math.PI * Math.pow(diameter / 2, 2); // in mm2
- var volume = (spoolWeight / density); // in cm3
- return volume / area; // in m
- }
- function calculateCostPerMeter(spoolCost)
- {
- if(!spoolCost)
- {
- spoolCost = base.getMaterialPreferenceValue(properties.guid, "spool_cost");
- }
- if (spoolLength == 0)
- {
- return 0;
- }
- return spoolCost / spoolLength;
- }
- // Tiny convenience function to check if a value really changed before trying to set it.
- function setMetaDataEntry(entry_name, old_value, new_value)
- {
- if (old_value != new_value)
- {
- Cura.ContainerManager.setContainerMetaDataEntry(base.currentMaterialNode, entry_name, new_value)
- // make sure the UI properties are updated as well since we don't re-fetch the entire model here
- // When the entry_name is something like properties/diameter, we take the last part of the entry_name
- var list = entry_name.split("/")
- var key = list[list.length - 1]
- properties[key] = new_value
- }
- }
- function setMaterialPreferenceValue(material_guid, entry_name, new_value)
- {
- if(!(material_guid in materialPreferenceValues))
- {
- materialPreferenceValues[material_guid] = {};
- }
- if(entry_name in materialPreferenceValues[material_guid] && materialPreferenceValues[material_guid][entry_name] == new_value)
- {
- // value has not changed
- return;
- }
- if (entry_name in materialPreferenceValues[material_guid] && new_value.toString() == 0)
- {
- // no need to store a 0, that's the default, so remove it
- materialPreferenceValues[material_guid].delete(entry_name);
- if (!(materialPreferenceValues[material_guid]))
- {
- // remove empty map
- materialPreferenceValues.delete(material_guid);
- }
- }
- if (new_value.toString() != 0)
- {
- // store new value
- materialPreferenceValues[material_guid][entry_name] = new_value;
- }
- // store preference
- UM.Preferences.setValue("cura/material_settings", JSON.stringify(materialPreferenceValues));
- }
- function getMaterialPreferenceValue(material_guid, entry_name, default_value)
- {
- if(material_guid in materialPreferenceValues && entry_name in materialPreferenceValues[material_guid])
- {
- return materialPreferenceValues[material_guid][entry_name];
- }
- default_value = default_value | 0;
- return default_value;
- }
- // update the display name of the material
- function updateMaterialDisplayName(old_name, new_name)
- {
- // don't change when new name is the same
- if (old_name == new_name)
- {
- return
- }
- // update the values
- base.materialManagementModel.setMaterialName(base.currentMaterialNode, new_name)
- properties.name = new_name
- }
- // update the type of the material
- function updateMaterialType(old_type, new_type)
- {
- base.setMetaDataEntry("material", old_type, new_type)
- properties.material = new_type
- }
- // update the brand of the material
- function updateMaterialBrand(old_brand, new_brand)
- {
- base.setMetaDataEntry("brand", old_brand, new_brand)
- properties.brand = new_brand
- }
- }
|