MaterialsView.qml 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. // Copyright (c) 2022 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.7
  4. import QtQuick.Controls 2.15
  5. import QtQuick.Dialogs 1.2
  6. import QtQuick.Layouts 1.3
  7. import UM 1.5 as UM
  8. import Cura 1.0 as Cura
  9. Item
  10. {
  11. id: base
  12. property QtObject properties
  13. property var currentMaterialNode: null
  14. property bool editingEnabled: false
  15. property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€"
  16. property string containerId: ""
  17. property var materialPreferenceValues: UM.Preferences.getValue("cura/material_settings") ? JSON.parse(UM.Preferences.getValue("cura/material_settings")) : {}
  18. property var materialManagementModel: CuraApplication.getMaterialManagementModel()
  19. property double spoolLength: calculateSpoolLength()
  20. property real costPerMeter: calculateCostPerMeter()
  21. signal resetSelectedMaterial()
  22. property bool reevaluateLinkedMaterials: false
  23. property string linkedMaterialNames:
  24. {
  25. if (reevaluateLinkedMaterials)
  26. {
  27. reevaluateLinkedMaterials = false;
  28. }
  29. if (!base.containerId || !base.editingEnabled || !base.currentMaterialNode)
  30. {
  31. return "";
  32. }
  33. var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.currentMaterialNode, true);
  34. if (linkedMaterials.length == 0)
  35. {
  36. return "";
  37. }
  38. return linkedMaterials.join(", ");
  39. }
  40. function getApproximateDiameter(diameter)
  41. {
  42. return Math.round(diameter);
  43. }
  44. // This trick makes sure to make all fields lose focus so their onEditingFinished will be triggered
  45. // and modified values will be saved. This can happen when a user changes a value and then closes the
  46. // dialog directly.
  47. //
  48. // Please note that somehow this callback is ONLY triggered when visible is false.
  49. onVisibleChanged:
  50. {
  51. if (!visible)
  52. {
  53. base.focus = false;
  54. }
  55. }
  56. Rectangle
  57. {
  58. color: UM.Theme.getColor("main_background")
  59. anchors
  60. {
  61. top: pageSelectorTabRow.bottom
  62. topMargin: -UM.Theme.getSize("default_lining").width
  63. left: parent.left
  64. right: parent.right
  65. bottom: parent.bottom
  66. }
  67. border.width: UM.Theme.getSize("default_lining").width
  68. border.color: UM.Theme.getColor("border_main")
  69. ScrollView
  70. {
  71. id: informationPage
  72. anchors
  73. {
  74. fill: parent
  75. topMargin: UM.Theme.getSize("thin_margin").height
  76. bottomMargin: UM.Theme.getSize("thin_margin").height
  77. leftMargin: UM.Theme.getSize("thin_margin").width
  78. rightMargin: UM.Theme.getSize("thin_margin").width
  79. }
  80. ScrollBar.vertical: UM.ScrollBar
  81. {
  82. id: scrollBar
  83. parent: informationPage.parent
  84. anchors
  85. {
  86. top: parent.top
  87. right: parent.right
  88. bottom: parent.bottom
  89. }
  90. }
  91. ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
  92. clip: true
  93. visible: pageSelectorTabRow.currentItem.activeView === "information"
  94. property real columnWidth: Math.floor((width - scrollBar.width - UM.Theme.getSize("narrow_margin").width) / 2)
  95. property real rowHeight: UM.Theme.getSize("setting_control").height
  96. Column
  97. {
  98. width: informationPage.width
  99. spacing: UM.Theme.getSize("narrow_margin").height
  100. Cura.MessageDialog
  101. {
  102. id: confirmDiameterChangeDialog
  103. title: catalog.i18nc("@title:window", "Confirm Diameter Change")
  104. 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))
  105. standardButtons: Dialog.Yes | Dialog.No
  106. property var new_diameter_value: null
  107. property var old_diameter_value: null
  108. property var old_approximate_diameter_value: null
  109. onAccepted:
  110. {
  111. base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString());
  112. base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value);
  113. // CURA-6868 Make sure to update the extruder to user a diameter-compatible material.
  114. Cura.MachineManager.updateMaterialWithVariant()
  115. base.resetSelectedMaterial()
  116. }
  117. onRejected:
  118. {
  119. base.properties.diameter = old_diameter_value;
  120. diameterTextField.valueText = Qt.binding(function() { return base.properties.diameter })
  121. }
  122. }
  123. Row
  124. {
  125. spacing: UM.Theme.getSize("narrow_margin").width
  126. UM.Label
  127. {
  128. height: informationPage.rowHeight
  129. width: informationPage.columnWidth
  130. text: catalog.i18nc("@label", "Display Name")
  131. }
  132. Cura.TextField
  133. {
  134. id: displayNameTextField
  135. width: informationPage.columnWidth
  136. text: properties.name
  137. enabled: base.editingEnabled
  138. onEditingFinished: base.updateMaterialDisplayName(properties.name, text)
  139. }
  140. }
  141. Row
  142. {
  143. spacing: UM.Theme.getSize("narrow_margin").width
  144. UM.Label
  145. {
  146. height: informationPage.rowHeight
  147. width: informationPage.columnWidth
  148. text: catalog.i18nc("@label", "Brand")
  149. }
  150. Cura.TextField
  151. {
  152. id: brandTextField
  153. width: informationPage.columnWidth
  154. text: properties.brand
  155. enabled: base.editingEnabled
  156. onEditingFinished: base.updateMaterialBrand(properties.brand, text)
  157. }
  158. }
  159. Row
  160. {
  161. spacing: UM.Theme.getSize("narrow_margin").width
  162. UM.Label
  163. {
  164. height: informationPage.rowHeight
  165. width: informationPage.columnWidth
  166. text: catalog.i18nc("@label", "Material Type")
  167. }
  168. Cura.TextField
  169. {
  170. id: materialTypeField
  171. width: informationPage.columnWidth
  172. text: properties.material
  173. enabled: base.editingEnabled
  174. onEditingFinished: base.updateMaterialType(properties.material, text)
  175. }
  176. }
  177. Row
  178. {
  179. spacing: UM.Theme.getSize("narrow_margin").width
  180. UM.Label
  181. {
  182. height: informationPage.rowHeight
  183. width: informationPage.columnWidth
  184. verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color")
  185. }
  186. Row
  187. {
  188. width: informationPage.columnWidth
  189. spacing: Math.round(UM.Theme.getSize("default_margin").width / 2)
  190. // color indicator square
  191. Item
  192. {
  193. id: colorSelector
  194. anchors.verticalCenter: parent.verticalCenter
  195. width: colorSelectorBackground.width + 2 * UM.Theme.getSize("narrow_margin").width
  196. height: colorSelectorBackground.height + 2 * UM.Theme.getSize("narrow_margin").height
  197. Rectangle
  198. {
  199. id: colorSelectorBackground
  200. color: properties.color_code
  201. width: UM.Theme.getSize("icon_indicator").width
  202. height: UM.Theme.getSize("icon_indicator").height
  203. radius: width / 2
  204. anchors.centerIn: parent
  205. }
  206. // open the color selection dialog on click
  207. MouseArea
  208. {
  209. anchors.fill: parent
  210. onClicked: colorDialog.open()
  211. enabled: base.editingEnabled
  212. }
  213. }
  214. // pretty color name text field
  215. Cura.TextField
  216. {
  217. id: colorLabel;
  218. width: parent.width - colorSelector.width - parent.spacing
  219. text: properties.color_name;
  220. enabled: base.editingEnabled
  221. onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text)
  222. }
  223. // popup dialog to select a new color
  224. // if successful it sets the properties.color_code value to the new color
  225. Cura.ColorDialog
  226. {
  227. id: colorDialog
  228. title: catalog.i18nc("@title", "Material color picker")
  229. color: properties.color_code
  230. onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color)
  231. }
  232. }
  233. }
  234. UM.Label
  235. {
  236. width: parent.width
  237. height: parent.rowHeight
  238. font: UM.Theme.getFont("default_bold")
  239. verticalAlignment: Qt.AlignVCenter
  240. text: catalog.i18nc("@label", "Properties")
  241. }
  242. Row
  243. {
  244. height: parent.rowHeight
  245. spacing: UM.Theme.getSize("narrow_margin").width
  246. UM.Label
  247. {
  248. height: informationPage.rowHeight
  249. width: informationPage.columnWidth
  250. text: catalog.i18nc("@label", "Density")
  251. }
  252. Cura.NumericTextFieldWithUnit
  253. {
  254. id: densityTextField
  255. enabled: base.editingEnabled
  256. valueText: properties.density
  257. controlWidth: informationPage.columnWidth
  258. controlHeight: informationPage.rowHeight
  259. spacing: 0
  260. unitText: "g/cm³"
  261. decimals: 2
  262. maximum: 1000
  263. editingFinishedFunction: function()
  264. {
  265. var modified_text = valueText.replace(",", ".");
  266. base.setMetaDataEntry("properties/density", properties.density, modified_text)
  267. }
  268. onValueTextChanged: updateCostPerMeter()
  269. }
  270. }
  271. Row
  272. {
  273. height: parent.rowHeight
  274. spacing: UM.Theme.getSize("narrow_margin").width
  275. UM.Label
  276. {
  277. height: informationPage.rowHeight
  278. width: informationPage.columnWidth
  279. text: catalog.i18nc("@label", "Diameter")
  280. }
  281. Cura.NumericTextFieldWithUnit
  282. {
  283. id: diameterTextField
  284. enabled: base.editingEnabled
  285. valueText: properties.diameter
  286. controlWidth: informationPage.columnWidth
  287. controlHeight: informationPage.rowHeight
  288. spacing: 0
  289. unitText: "mm"
  290. decimals: 2
  291. maximum: 1000
  292. editingFinishedFunction: function()
  293. {
  294. // This does not use a SettingPropertyProvider, because we need to make the change to all containers
  295. // which derive from the same base_file
  296. var old_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "properties/diameter");
  297. var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
  298. var modified_value = valueText.replace(",", ".");
  299. var new_approximate_diameter = getApproximateDiameter(modified_value);
  300. if (new_approximate_diameter != Cura.ExtruderManager.getActiveExtruderStack().approximateMaterialDiameter)
  301. {
  302. confirmDiameterChangeDialog.old_diameter_value = old_diameter;
  303. confirmDiameterChangeDialog.new_diameter_value = modified_value;
  304. confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter;
  305. confirmDiameterChangeDialog.open()
  306. }
  307. else {
  308. base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, new_approximate_diameter);
  309. base.setMetaDataEntry("properties/diameter", properties.diameter, modified_value);
  310. }
  311. }
  312. onValueTextChanged: updateCostPerMeter()
  313. }
  314. }
  315. Row
  316. {
  317. height: parent.rowHeight
  318. spacing: UM.Theme.getSize("narrow_margin").width
  319. UM.Label
  320. {
  321. height: informationPage.rowHeight
  322. width: informationPage.columnWidth
  323. text: catalog.i18nc("@label", "Filament Cost")
  324. }
  325. Cura.NumericTextFieldWithUnit
  326. {
  327. id: spoolCostTextField
  328. valueText: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
  329. controlWidth: informationPage.columnWidth
  330. controlHeight: informationPage.rowHeight
  331. spacing: 0
  332. unitText: base.currency
  333. decimals: 2
  334. maximum: 100000000
  335. editingFinishedFunction: function()
  336. {
  337. var modified_text = valueText.replace(",", ".");
  338. base.setMaterialPreferenceValue(properties.guid, "spool_cost", modified_text);
  339. }
  340. onValueTextChanged: updateCostPerMeter()
  341. }
  342. }
  343. Row
  344. {
  345. height: parent.rowHeight
  346. spacing: UM.Theme.getSize("narrow_margin").width
  347. UM.Label
  348. {
  349. height: informationPage.rowHeight
  350. width: informationPage.columnWidth
  351. text: catalog.i18nc("@label", "Filament weight")
  352. }
  353. Cura.NumericTextFieldWithUnit
  354. {
  355. id: spoolWeightTextField
  356. valueText: base.getMaterialPreferenceValue(properties.guid, "spool_weight", Cura.ContainerManager.getContainerMetaDataEntry(properties.container_id, "properties/weight"))
  357. controlWidth: informationPage.columnWidth
  358. controlHeight: informationPage.rowHeight
  359. spacing: 0
  360. unitText: " g"
  361. decimals: 0
  362. maximum: 10000
  363. editingFinishedFunction: function()
  364. {
  365. var modified_text = valueText.replace(",", ".")
  366. base.setMaterialPreferenceValue(properties.guid, "spool_weight", modified_text)
  367. }
  368. onValueTextChanged: updateCostPerMeter()
  369. }
  370. }
  371. Row
  372. {
  373. height: parent.rowHeight
  374. spacing: UM.Theme.getSize("narrow_margin").width
  375. UM.Label
  376. {
  377. height: informationPage.rowHeight
  378. width: informationPage.columnWidth
  379. text: catalog.i18nc("@label", "Filament length")
  380. }
  381. UM.Label
  382. {
  383. width: informationPage.columnWidth
  384. text: "~ %1 m".arg(Math.round(base.spoolLength))
  385. height: informationPage.rowHeight
  386. }
  387. }
  388. Row
  389. {
  390. height: parent.rowHeight
  391. spacing: UM.Theme.getSize("narrow_margin").width
  392. UM.Label
  393. {
  394. height: informationPage.rowHeight
  395. width: informationPage.columnWidth
  396. text: catalog.i18nc("@label", "Cost per Meter")
  397. }
  398. UM.Label
  399. {
  400. height: informationPage.rowHeight
  401. width: informationPage.columnWidth
  402. text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
  403. }
  404. }
  405. UM.Label
  406. {
  407. height: parent.rowHeight
  408. width: informationPage.width
  409. text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames)
  410. wrapMode: Text.WordWrap
  411. visible: unlinkMaterialButton.visible
  412. }
  413. Cura.SecondaryButton
  414. {
  415. id: unlinkMaterialButton
  416. text: catalog.i18nc("@label", "Unlink Material")
  417. visible: base.linkedMaterialNames != ""
  418. onClicked:
  419. {
  420. Cura.ContainerManager.unlinkMaterial(base.currentMaterialNode)
  421. base.reevaluateLinkedMaterials = true
  422. }
  423. }
  424. UM.Label
  425. {
  426. width: informationPage.width
  427. height: parent.rowHeight
  428. text: catalog.i18nc("@label", "Description")
  429. }
  430. Cura.ReadOnlyTextArea
  431. {
  432. text: properties.description
  433. width: informationPage.width - scrollBar.width
  434. height: 0.4 * informationPage.width
  435. wrapMode: Text.WordWrap
  436. readOnly: !base.editingEnabled
  437. onEditingFinished: base.setMetaDataEntry("description", properties.description, text)
  438. }
  439. UM.Label
  440. {
  441. width: informationPage.width
  442. height: parent.rowHeight
  443. text: catalog.i18nc("@label", "Adhesion Information")
  444. }
  445. Cura.ReadOnlyTextArea
  446. {
  447. text: properties.adhesion_info
  448. width: informationPage.width - scrollBar.width
  449. height: 0.4 * informationPage.width
  450. wrapMode: Text.WordWrap
  451. readOnly: !base.editingEnabled
  452. onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
  453. }
  454. }
  455. }
  456. ListView
  457. {
  458. id: settingsPage
  459. visible: pageSelectorTabRow.currentItem.activeView === "settings"
  460. clip: true
  461. anchors
  462. {
  463. fill: parent
  464. topMargin: UM.Theme.getSize("thin_margin").height
  465. bottomMargin: UM.Theme.getSize("thin_margin").height
  466. leftMargin: UM.Theme.getSize("thin_margin").width
  467. rightMargin: UM.Theme.getSize("thin_margin").width
  468. }
  469. width: settingsPage.width
  470. spacing: UM.Theme.getSize("narrow_margin").height
  471. ScrollBar.vertical: UM.ScrollBar
  472. {
  473. id: settingScrollBar
  474. parent: settingsPage.parent
  475. anchors
  476. {
  477. top: parent.top
  478. right: parent.right
  479. bottom: parent.bottom
  480. }
  481. }
  482. property real columnWidth: Math.floor((width - settingScrollBar.width - UM.Theme.getSize("narrow_margin").width) / 2)
  483. model: UM.SettingDefinitionsModel
  484. {
  485. containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
  486. visibilityHandler: Cura.MaterialSettingsVisibilityHandler { }
  487. expanded: ["*"]
  488. }
  489. delegate: UM.TooltipArea
  490. {
  491. width: childrenRect.width
  492. height: childrenRect.height
  493. UM.TooltipArea
  494. {
  495. anchors.fill: parent
  496. text: model.description
  497. }
  498. UM.Label
  499. {
  500. id: label
  501. width: settingsPage.columnWidth
  502. height: spinBox.height + UM.Theme.getSize("default_lining").height
  503. text: model.label
  504. elide: Text.ElideRight
  505. verticalAlignment: Qt.AlignVCenter
  506. }
  507. Cura.SpinBox
  508. {
  509. id: spinBox
  510. anchors.left: label.right
  511. value:
  512. {
  513. // In case the setting is not in the material...
  514. if (!isNaN(parseFloat(materialPropertyProvider.properties.value)))
  515. {
  516. return parseFloat(materialPropertyProvider.properties.value);
  517. }
  518. // ... we search in the variant, and if it is not there...
  519. if (!isNaN(parseFloat(variantPropertyProvider.properties.value)))
  520. {
  521. return parseFloat(variantPropertyProvider.properties.value);
  522. }
  523. // ... then look in the definition container.
  524. if (!isNaN(parseFloat(machinePropertyProvider.properties.value)))
  525. {
  526. return parseFloat(machinePropertyProvider.properties.value);
  527. }
  528. return 0;
  529. }
  530. width: settingsPage.columnWidth
  531. suffix: " " + model.unit
  532. to: 99999
  533. decimals: model.unit == "mm" ? 2 : 0
  534. onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
  535. }
  536. UM.ContainerPropertyProvider
  537. {
  538. id: materialPropertyProvider
  539. containerId: base.containerId
  540. watchedProperties: [ "value" ]
  541. key: model.key
  542. }
  543. UM.ContainerPropertyProvider
  544. {
  545. id: variantPropertyProvider
  546. containerId: Cura.MachineManager.activeStack.variant.id
  547. watchedProperties: [ "value" ]
  548. key: model.key
  549. }
  550. UM.ContainerPropertyProvider
  551. {
  552. id: machinePropertyProvider
  553. containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
  554. watchedProperties: ["value"]
  555. key: model.key
  556. }
  557. }
  558. }
  559. }
  560. UM.TabRow
  561. {
  562. id: pageSelectorTabRow
  563. UM.TabRowButton
  564. {
  565. text: catalog.i18nc("@title", "Information")
  566. property string activeView: "information" //To determine which page gets displayed.
  567. }
  568. UM.TabRowButton
  569. {
  570. text: catalog.i18nc("@label", "Print settings")
  571. property string activeView: "settings"
  572. }
  573. }
  574. function updateCostPerMeter()
  575. {
  576. var modified_weight = spoolWeightTextField.valueText.replace(",", ".")
  577. var modified_cost = spoolCostTextField.valueText.replace(",", ".")
  578. var modified_diameter = diameterTextField.valueText.replace(",", ".")
  579. var modified_density = densityTextField.valueText.replace(",", ".")
  580. base.spoolLength = calculateSpoolLength(modified_diameter, modified_density, parseInt(modified_weight));
  581. base.costPerMeter = calculateCostPerMeter(parseFloat(modified_cost));
  582. }
  583. function calculateSpoolLength(diameter, density, spoolWeight)
  584. {
  585. if(!diameter)
  586. {
  587. diameter = properties.diameter;
  588. }
  589. if(!density)
  590. {
  591. density = properties.density;
  592. }
  593. if(!spoolWeight)
  594. {
  595. spoolWeight = base.getMaterialPreferenceValue(properties.guid, "spool_weight", Cura.ContainerManager.getContainerMetaDataEntry(properties.container_id, "properties/weight"));
  596. }
  597. if (diameter == 0 || density == 0 || spoolWeight == 0)
  598. {
  599. return 0;
  600. }
  601. var area = Math.PI * Math.pow(diameter / 2, 2); // in mm2
  602. var volume = (spoolWeight / density); // in cm3
  603. return volume / area; // in m
  604. }
  605. function calculateCostPerMeter(spoolCost)
  606. {
  607. if(!spoolCost)
  608. {
  609. spoolCost = base.getMaterialPreferenceValue(properties.guid, "spool_cost");
  610. }
  611. if (spoolLength == 0)
  612. {
  613. return 0;
  614. }
  615. return spoolCost / spoolLength;
  616. }
  617. // Tiny convenience function to check if a value really changed before trying to set it.
  618. function setMetaDataEntry(entry_name, old_value, new_value)
  619. {
  620. if (old_value != new_value)
  621. {
  622. Cura.ContainerManager.setContainerMetaDataEntry(base.currentMaterialNode, entry_name, new_value)
  623. // make sure the UI properties are updated as well since we don't re-fetch the entire model here
  624. // When the entry_name is something like properties/diameter, we take the last part of the entry_name
  625. var list = entry_name.split("/")
  626. var key = list[list.length - 1]
  627. properties[key] = new_value
  628. }
  629. }
  630. function setMaterialPreferenceValue(material_guid, entry_name, new_value)
  631. {
  632. if(!(material_guid in materialPreferenceValues))
  633. {
  634. materialPreferenceValues[material_guid] = {};
  635. }
  636. if(entry_name in materialPreferenceValues[material_guid] && materialPreferenceValues[material_guid][entry_name] == new_value)
  637. {
  638. // value has not changed
  639. return;
  640. }
  641. if (entry_name in materialPreferenceValues[material_guid] && new_value.toString() == 0)
  642. {
  643. // no need to store a 0, that's the default, so remove it
  644. materialPreferenceValues[material_guid].delete(entry_name);
  645. if (!(materialPreferenceValues[material_guid]))
  646. {
  647. // remove empty map
  648. materialPreferenceValues.delete(material_guid);
  649. }
  650. }
  651. if (new_value.toString() != 0)
  652. {
  653. // store new value
  654. materialPreferenceValues[material_guid][entry_name] = new_value;
  655. }
  656. // store preference
  657. UM.Preferences.setValue("cura/material_settings", JSON.stringify(materialPreferenceValues));
  658. }
  659. function getMaterialPreferenceValue(material_guid, entry_name, default_value)
  660. {
  661. if(material_guid in materialPreferenceValues && entry_name in materialPreferenceValues[material_guid])
  662. {
  663. return materialPreferenceValues[material_guid][entry_name];
  664. }
  665. default_value = default_value | 0;
  666. return default_value;
  667. }
  668. // update the display name of the material
  669. function updateMaterialDisplayName(old_name, new_name)
  670. {
  671. // don't change when new name is the same
  672. if (old_name == new_name)
  673. {
  674. return
  675. }
  676. // update the values
  677. base.materialManagementModel.setMaterialName(base.currentMaterialNode, new_name)
  678. properties.name = new_name
  679. }
  680. // update the type of the material
  681. function updateMaterialType(old_type, new_type)
  682. {
  683. base.setMetaDataEntry("material", old_type, new_type)
  684. properties.material = new_type
  685. }
  686. // update the brand of the material
  687. function updateMaterialBrand(old_brand, new_brand)
  688. {
  689. base.setMetaDataEntry("brand", old_brand, new_brand)
  690. properties.brand = new_brand
  691. }
  692. }