MaterialsPage.qml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. //Copyright (c) 2017 Ultimaker B.V.
  2. //Cura is released under the terms of the AGPLv3 or higher.
  3. import QtQuick 2.1
  4. import QtQuick.Controls 1.1
  5. import QtQuick.Dialogs 1.2
  6. import UM 1.2 as UM
  7. import Cura 1.0 as Cura
  8. UM.ManagementPage
  9. {
  10. id: base;
  11. title: catalog.i18nc("@title:tab", "Materials");
  12. Component.onCompleted:
  13. {
  14. // Workaround to make sure all of the items are visible
  15. objectList.positionViewAtBeginning();
  16. }
  17. model: Cura.MaterialsModel
  18. {
  19. filter:
  20. {
  21. var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value).toString() }
  22. if(Cura.MachineManager.filterMaterialsByMachine)
  23. {
  24. result.definition = Cura.MachineManager.activeQualityDefinitionId;
  25. if(Cura.MachineManager.hasVariants)
  26. {
  27. result.variant = Cura.MachineManager.activeQualityVariantId;
  28. }
  29. }
  30. else
  31. {
  32. result.definition = "fdmprinter";
  33. result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway.
  34. }
  35. return result
  36. }
  37. sectionProperty: "brand"
  38. }
  39. delegate: Rectangle
  40. {
  41. width: objectList.width;
  42. height: childrenRect.height;
  43. color: isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
  44. property bool isCurrentItem: ListView.isCurrentItem
  45. Row
  46. {
  47. spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
  48. anchors.left: parent.left
  49. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  50. anchors.right: parent.right
  51. Rectangle
  52. {
  53. width: (parent.height * 0.8) | 0
  54. height: (parent.height * 0.8) | 0
  55. color: model.metadata.color_code
  56. border.color: isCurrentItem ? palette.highlightedText : palette.text;
  57. anchors.verticalCenter: parent.verticalCenter
  58. }
  59. Label
  60. {
  61. width: (parent.width * 0.3) | 0
  62. text: model.metadata.material
  63. elide: Text.ElideRight
  64. font.italic: model.id == activeId
  65. color: isCurrentItem ? palette.highlightedText : palette.text;
  66. }
  67. Label
  68. {
  69. text: (model.name != model.metadata.material) ? model.name : ""
  70. elide: Text.ElideRight
  71. font.italic: model.id == activeId
  72. color: isCurrentItem ? palette.highlightedText : palette.text;
  73. }
  74. }
  75. MouseArea
  76. {
  77. anchors.fill: parent;
  78. onClicked:
  79. {
  80. forceActiveFocus();
  81. if(!parent.ListView.isCurrentItem)
  82. {
  83. parent.ListView.view.currentIndex = index;
  84. base.itemActivated();
  85. }
  86. }
  87. }
  88. }
  89. activeId: Cura.MachineManager.activeMaterialId
  90. activeIndex: getIndexById(activeId)
  91. function getIndexById(material_id)
  92. {
  93. for(var i = 0; i < model.rowCount(); i++) {
  94. if (model.getItem(i).id == material_id) {
  95. return i;
  96. }
  97. }
  98. return -1;
  99. }
  100. scrollviewCaption:
  101. {
  102. if (Cura.MachineManager.hasVariants)
  103. {
  104. catalog.i18nc("@action:label %1 is printer name, %2 is how this printer names variants, %3 is variant name", "Printer: %1, %2: %3").arg(Cura.MachineManager.activeMachineName).arg(Cura.MachineManager.activeDefinitionVariantsName).arg(Cura.MachineManager.activeVariantName)
  105. }
  106. else
  107. {
  108. catalog.i18nc("@action:label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName)
  109. }
  110. }
  111. detailsVisible: true
  112. section.property: "section"
  113. section.delegate: Label
  114. {
  115. text: section
  116. font.bold: true
  117. anchors.left: parent.left;
  118. anchors.leftMargin: UM.Theme.getSize("default_lining").width;
  119. }
  120. buttons: [
  121. Button
  122. {
  123. text: catalog.i18nc("@action:button", "Activate");
  124. iconName: "list-activate";
  125. enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials
  126. onClicked:
  127. {
  128. forceActiveFocus();
  129. Cura.MachineManager.setActiveMaterial(base.currentItem.id)
  130. currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
  131. }
  132. },
  133. Button
  134. {
  135. text: catalog.i18nc("@action:button", "Create")
  136. iconName: "list-add"
  137. onClicked:
  138. {
  139. forceActiveFocus();
  140. var material_id = Cura.ContainerManager.createMaterial()
  141. if(material_id == "")
  142. {
  143. return
  144. }
  145. if(Cura.MachineManager.hasMaterials)
  146. {
  147. Cura.MachineManager.setActiveMaterial(material_id)
  148. }
  149. base.objectList.currentIndex = base.getIndexById(material_id);
  150. }
  151. },
  152. Button
  153. {
  154. text: catalog.i18nc("@action:button", "Duplicate");
  155. iconName: "list-add";
  156. enabled: base.currentItem != null
  157. onClicked:
  158. {
  159. forceActiveFocus();
  160. var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file")
  161. // We need to copy the base container instead of the specific variant.
  162. var material_id = base_file == "" ? Cura.ContainerManager.duplicateMaterial(base.currentItem.id): Cura.ContainerManager.duplicateMaterial(base_file)
  163. if(material_id == "")
  164. {
  165. return
  166. }
  167. if(Cura.MachineManager.hasMaterials)
  168. {
  169. Cura.MachineManager.setActiveMaterial(material_id)
  170. }
  171. base.objectList.currentIndex = base.getIndexById(material_id);
  172. }
  173. },
  174. Button
  175. {
  176. text: catalog.i18nc("@action:button", "Remove");
  177. iconName: "list-remove";
  178. enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id)
  179. onClicked:
  180. {
  181. forceActiveFocus();
  182. confirmDialog.open();
  183. }
  184. },
  185. Button
  186. {
  187. text: catalog.i18nc("@action:button", "Import");
  188. iconName: "document-import";
  189. onClicked:
  190. {
  191. forceActiveFocus();
  192. importDialog.open();
  193. }
  194. visible: true;
  195. },
  196. Button
  197. {
  198. text: catalog.i18nc("@action:button", "Export")
  199. iconName: "document-export"
  200. onClicked:
  201. {
  202. forceActiveFocus();
  203. exportDialog.open();
  204. }
  205. enabled: currentItem != null
  206. }
  207. ]
  208. Item {
  209. visible: base.currentItem != null
  210. anchors.fill: parent
  211. Item
  212. {
  213. id: profileName
  214. width: parent.width;
  215. height: childrenRect.height
  216. Label { text: materialProperties.name; font: UM.Theme.getFont("large"); }
  217. }
  218. MaterialView
  219. {
  220. anchors
  221. {
  222. left: parent.left
  223. right: parent.right
  224. top: profileName.bottom
  225. topMargin: UM.Theme.getSize("default_margin").height
  226. bottom: parent.bottom
  227. }
  228. editingEnabled: base.currentItem != null && !base.currentItem.readOnly
  229. properties: materialProperties
  230. containerId: base.currentItem != null ? base.currentItem.id : ""
  231. property alias pane: base
  232. }
  233. QtObject
  234. {
  235. id: materialProperties
  236. property string guid: "00000000-0000-0000-0000-000000000000"
  237. property string name: "Unknown";
  238. property string profile_type: "Unknown";
  239. property string supplier: "Unknown";
  240. property string material_type: "Unknown";
  241. property string color_name: "Yellow";
  242. property color color_code: "yellow";
  243. property real density: 0.0;
  244. property real diameter: 0.0;
  245. property string approximate_diameter: "0";
  246. property real spool_cost: 0.0;
  247. property real spool_weight: 0.0;
  248. property real spool_length: 0.0;
  249. property real cost_per_meter: 0.0;
  250. property string description: "";
  251. property string adhesion_info: "";
  252. }
  253. UM.ConfirmRemoveDialog
  254. {
  255. id: confirmDialog
  256. object: base.currentItem != null ? base.currentItem.name : ""
  257. onYes:
  258. {
  259. // A material container can actually be multiple items, so we need to find (and remove) all of them.
  260. var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file")
  261. if(base_file == "")
  262. {
  263. base_file = base.currentItem.id
  264. }
  265. var guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID")
  266. var containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "base_file": base_file, "type": "material"})
  267. for(var i in containers)
  268. {
  269. Cura.ContainerManager.removeContainer(containers[i])
  270. }
  271. if(base.objectList.currentIndex > 0)
  272. {
  273. base.objectList.currentIndex--;
  274. }
  275. currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
  276. }
  277. }
  278. FileDialog
  279. {
  280. id: importDialog;
  281. title: catalog.i18nc("@title:window", "Import Material");
  282. selectExisting: true;
  283. nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
  284. folder: CuraApplication.getDefaultPath("dialog_material_path")
  285. onAccepted:
  286. {
  287. var result = Cura.ContainerManager.importContainer(fileUrl)
  288. messageDialog.title = catalog.i18nc("@title:window", "Import Material")
  289. messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Could not import material <filename>%1</filename>: <message>%2</message>").arg(fileUrl).arg(result.message)
  290. if(result.status == "success")
  291. {
  292. messageDialog.icon = StandardIcon.Information
  293. messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully imported material <filename>%1</filename>").arg(fileUrl)
  294. currentItem = base.model.getItem(base.objectList.currentIndex)
  295. }
  296. else if(result.status == "duplicate")
  297. {
  298. messageDialog.icon = StandardIcon.Warning
  299. }
  300. else
  301. {
  302. messageDialog.icon = StandardIcon.Critical
  303. }
  304. messageDialog.open()
  305. CuraApplication.setDefaultPath("dialog_material_path", folder)
  306. }
  307. }
  308. FileDialog
  309. {
  310. id: exportDialog;
  311. title: catalog.i18nc("@title:window", "Export Material");
  312. selectExisting: false;
  313. nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
  314. folder: CuraApplication.getDefaultPath("dialog_material_path")
  315. onAccepted:
  316. {
  317. if(base.currentItem.metadata.base_file)
  318. {
  319. var result = Cura.ContainerManager.exportContainer(base.currentItem.metadata.base_file, selectedNameFilter, fileUrl)
  320. }
  321. else
  322. {
  323. var result = Cura.ContainerManager.exportContainer(base.currentItem.id, selectedNameFilter, fileUrl)
  324. }
  325. messageDialog.title = catalog.i18nc("@title:window", "Export Material")
  326. if(result.status == "error")
  327. {
  328. messageDialog.icon = StandardIcon.Critical
  329. messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags <filename> and <message>!", "Failed to export material to <filename>%1</filename>: <message>%2</message>").arg(fileUrl).arg(result.message)
  330. messageDialog.open()
  331. }
  332. else if(result.status == "success")
  333. {
  334. messageDialog.icon = StandardIcon.Information
  335. messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully exported material to <filename>%1</filename>").arg(result.path)
  336. messageDialog.open()
  337. }
  338. CuraApplication.setDefaultPath("dialog_material_path", folder)
  339. }
  340. }
  341. MessageDialog
  342. {
  343. id: messageDialog
  344. }
  345. UM.SettingPropertyProvider
  346. {
  347. id: materialDiameterProvider
  348. containerStackId: Cura.MachineManager.activeMachineId
  349. key: "material_diameter"
  350. watchedProperties: [ "value" ]
  351. }
  352. UM.I18nCatalog { id: catalog; name: "cura"; }
  353. SystemPalette { id: palette }
  354. }
  355. onCurrentItemChanged:
  356. {
  357. if(currentItem == null)
  358. {
  359. return
  360. }
  361. materialProperties.name = currentItem.name;
  362. materialProperties.guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID");
  363. if(currentItem.metadata != undefined && currentItem.metadata != null)
  364. {
  365. materialProperties.supplier = currentItem.metadata.brand ? currentItem.metadata.brand : "Unknown";
  366. materialProperties.material_type = currentItem.metadata.material ? currentItem.metadata.material : "Unknown";
  367. materialProperties.color_name = currentItem.metadata.color_name ? currentItem.metadata.color_name : "Yellow";
  368. materialProperties.color_code = currentItem.metadata.color_code ? currentItem.metadata.color_code : "yellow";
  369. materialProperties.description = currentItem.metadata.description ? currentItem.metadata.description : "";
  370. materialProperties.adhesion_info = currentItem.metadata.adhesion_info ? currentItem.metadata.adhesion_info : "";
  371. if(currentItem.metadata.properties != undefined && currentItem.metadata.properties != null)
  372. {
  373. materialProperties.density = currentItem.metadata.properties.density ? currentItem.metadata.properties.density : 0.0;
  374. materialProperties.diameter = currentItem.metadata.properties.diameter ? currentItem.metadata.properties.diameter : 0.0;
  375. materialProperties.approximate_diameter = currentItem.metadata.approximate_diameter ? currentItem.metadata.approximate_diameter : "0";
  376. }
  377. else
  378. {
  379. materialProperties.density = 0.0;
  380. materialProperties.diameter = 0.0;
  381. materialProperties.approximate_diameter = "0";
  382. }
  383. }
  384. }
  385. }