MaterialsPage.qml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. // Copyright (c) 2018 Ultimaker B.V.
  2. // Uranium is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.8
  4. import QtQuick.Controls 1.4
  5. import QtQuick.Layouts 1.3
  6. import QtQuick.Dialogs 1.3
  7. import UM 1.2 as UM
  8. import Cura 1.0 as Cura
  9. Item
  10. {
  11. id: base
  12. property var resetEnabled: false // Keep PreferencesDialog happy
  13. UM.I18nCatalog { id: catalog; name: "cura"; }
  14. Cura.NewMaterialsModel {
  15. id: materialsModel
  16. }
  17. Label {
  18. id: titleLabel
  19. anchors {
  20. top: parent.top
  21. left: parent.left
  22. right: parent.right
  23. margins: 5 * screenScaleFactor
  24. }
  25. font.pointSize: 18
  26. text: catalog.i18nc("@title:tab", "Materials")
  27. }
  28. property var hasCurrentItem: materialListView.currentItem != null
  29. property var currentItem: {
  30. var current_index = materialListView.currentIndex;
  31. return materialsModel.getItem(current_index);
  32. }
  33. property var isCurrentItemActivated: {
  34. const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
  35. const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
  36. return base.currentItem.root_material_id == root_material_id;
  37. }
  38. Row // Button Row
  39. {
  40. id: buttonRow
  41. anchors {
  42. left: parent.left
  43. right: parent.right
  44. top: titleLabel.bottom
  45. }
  46. height: childrenRect.height
  47. // Activate button
  48. Button {
  49. text: catalog.i18nc("@action:button", "Activate")
  50. iconName: "list-activate"
  51. enabled: !isCurrentItemActivated
  52. onClicked: {
  53. forceActiveFocus()
  54. const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
  55. Cura.MachineManager.setMaterial(extruder_position, base.currentItem.container_node);
  56. }
  57. }
  58. // Create button
  59. Button {
  60. text: catalog.i18nc("@action:button", "Create")
  61. iconName: "list-add"
  62. onClicked: {
  63. forceActiveFocus();
  64. Cura.ContainerManager.createMaterial();
  65. }
  66. }
  67. // Duplicate button
  68. Button {
  69. text: catalog.i18nc("@action:button", "Duplicate");
  70. iconName: "list-add"
  71. enabled: base.hasCurrentItem
  72. onClicked: {
  73. forceActiveFocus();
  74. Cura.ContainerManager.duplicateMaterial(base.currentItem.container_node);
  75. }
  76. }
  77. // Remove button
  78. Button {
  79. text: catalog.i18nc("@action:button", "Remove")
  80. iconName: "list-remove"
  81. enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated
  82. onClicked: {
  83. forceActiveFocus();
  84. confirmRemoveMaterialDialog.open();
  85. }
  86. }
  87. // Import button
  88. Button {
  89. text: catalog.i18nc("@action:button", "Import")
  90. iconName: "document-import"
  91. onClicked: {
  92. forceActiveFocus();
  93. importMaterialDialog.open();
  94. }
  95. visible: true
  96. }
  97. // Export button
  98. Button {
  99. text: catalog.i18nc("@action:button", "Export")
  100. iconName: "document-export"
  101. onClicked: {
  102. forceActiveFocus();
  103. exportMaterialDialog.open();
  104. }
  105. enabled: currentItem != null
  106. }
  107. }
  108. MessageDialog
  109. {
  110. id: confirmRemoveMaterialDialog
  111. icon: StandardIcon.Question;
  112. title: catalog.i18nc("@title:window", "Confirm Remove")
  113. text: catalog.i18nc("@label (%1 is object name)", "Are you sure you wish to remove %1? This cannot be undone!").arg(base.currentItem.name)
  114. standardButtons: StandardButton.Yes | StandardButton.No
  115. modality: Qt.ApplicationModal
  116. onYes:
  117. {
  118. Cura.ContainerManager.removeMaterial(base.currentItem.container_node);
  119. // reset current item to the first if available
  120. materialListView.currentIndex = 0;
  121. }
  122. }
  123. FileDialog
  124. {
  125. id: importMaterialDialog
  126. title: catalog.i18nc("@title:window", "Import Material")
  127. selectExisting: true
  128. nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
  129. folder: CuraApplication.getDefaultPath("dialog_material_path")
  130. onAccepted:
  131. {
  132. var result = Cura.ContainerManager.importMaterialContainer(fileUrl);
  133. messageDialog.title = catalog.i18nc("@title:window", "Import Material");
  134. 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);
  135. if (result.status == "success") {
  136. messageDialog.icon = StandardIcon.Information;
  137. messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully imported material <filename>%1</filename>").arg(fileUrl);
  138. }
  139. else if (result.status == "duplicate") {
  140. messageDialog.icon = StandardIcon.Warning;
  141. }
  142. else {
  143. messageDialog.icon = StandardIcon.Critical;
  144. }
  145. messageDialog.open();
  146. CuraApplication.setDefaultPath("dialog_material_path", folder);
  147. }
  148. }
  149. FileDialog
  150. {
  151. id: exportMaterialDialog
  152. title: catalog.i18nc("@title:window", "Export Material")
  153. selectExisting: false
  154. nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
  155. folder: CuraApplication.getDefaultPath("dialog_material_path")
  156. onAccepted:
  157. {
  158. var result = Cura.ContainerManager.exportContainer(base.currentItem.root_material_id, selectedNameFilter, fileUrl);
  159. messageDialog.title = catalog.i18nc("@title:window", "Export Material");
  160. if (result.status == "error") {
  161. messageDialog.icon = StandardIcon.Critical;
  162. 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);
  163. messageDialog.open();
  164. }
  165. else if (result.status == "success") {
  166. messageDialog.icon = StandardIcon.Information;
  167. messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully exported material to <filename>%1</filename>").arg(result.path);
  168. messageDialog.open();
  169. }
  170. CuraApplication.setDefaultPath("dialog_material_path", folder);
  171. }
  172. }
  173. MessageDialog
  174. {
  175. id: messageDialog
  176. }
  177. Item {
  178. id: contentsItem
  179. anchors {
  180. top: titleLabel.bottom
  181. left: parent.left
  182. right: parent.right
  183. bottom: parent.bottom
  184. margins: 5 * screenScaleFactor
  185. bottomMargin: 0
  186. }
  187. clip: true
  188. }
  189. Item
  190. {
  191. anchors {
  192. top: buttonRow.bottom
  193. topMargin: UM.Theme.getSize("default_margin").height
  194. left: parent.left
  195. right: parent.right
  196. bottom: parent.bottom
  197. }
  198. SystemPalette { id: palette }
  199. Label
  200. {
  201. id: captionLabel
  202. anchors {
  203. top: parent.top
  204. left: parent.left
  205. }
  206. visible: text != ""
  207. text: {
  208. // OLD STUFF
  209. var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName;
  210. if (Cura.MachineManager.hasVariants)
  211. {
  212. caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName;
  213. }
  214. return caption;
  215. }
  216. width: materialScrollView.width
  217. elide: Text.ElideRight
  218. }
  219. ScrollView
  220. {
  221. id: materialScrollView
  222. anchors {
  223. top: captionLabel.visible ? captionLabel.bottom : parent.top
  224. topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0
  225. bottom: parent.bottom
  226. left: parent.left
  227. }
  228. Rectangle {
  229. parent: viewport
  230. anchors.fill: parent
  231. color: palette.light
  232. }
  233. width: true ? (parent.width * 0.4) | 0 : parent.width
  234. ListView
  235. {
  236. id: materialListView
  237. model: materialsModel
  238. section.property: "brand"
  239. section.criteria: ViewSection.FullString
  240. section.delegate: Rectangle
  241. {
  242. width: materialScrollView.width
  243. height: childrenRect.height
  244. color: palette.light
  245. Label
  246. {
  247. anchors.left: parent.left
  248. anchors.leftMargin: UM.Theme.getSize("default_lining").width
  249. text: section
  250. font.bold: true
  251. color: palette.text
  252. }
  253. }
  254. delegate: Rectangle
  255. {
  256. width: materialScrollView.width
  257. height: childrenRect.height
  258. color: ListView.isCurrentItem ? palette.highlight : (model.index % 2) ? palette.base : palette.alternateBase
  259. Row
  260. {
  261. spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
  262. anchors.left: parent.left
  263. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  264. anchors.right: parent.right
  265. Rectangle
  266. {
  267. width: Math.floor(parent.height * 0.8)
  268. height: Math.floor(parent.height * 0.8)
  269. color: model.color_code
  270. border.color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
  271. anchors.verticalCenter: parent.verticalCenter
  272. }
  273. Label
  274. {
  275. width: Math.floor((parent.width * 0.3))
  276. text: model.material
  277. elide: Text.ElideRight
  278. font.italic: { // TODO: make it easier
  279. const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
  280. const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
  281. return model.root_material_id == root_material_id
  282. }
  283. color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
  284. }
  285. Label
  286. {
  287. text: (model.name != model.material) ? model.name : ""
  288. elide: Text.ElideRight
  289. font.italic: { // TODO: make it easier
  290. const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
  291. const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
  292. return model.root_material_id == root_material_id;
  293. }
  294. color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
  295. }
  296. }
  297. MouseArea
  298. {
  299. anchors.fill: parent
  300. onClicked: {
  301. parent.ListView.view.currentIndex = model.index;
  302. }
  303. }
  304. }
  305. onCurrentIndexChanged:
  306. {
  307. var model = materialsModel.getItem(currentIndex);
  308. materialDetailsView.containerId = model.container_id;
  309. materialDetailsView.currentMaterialNode = model.container_node;
  310. detailsPanel.updateMaterialPropertiesObject();
  311. }
  312. }
  313. }
  314. Item
  315. {
  316. id: detailsPanel
  317. anchors {
  318. left: materialScrollView.right
  319. leftMargin: UM.Theme.getSize("default_margin").width
  320. top: parent.top
  321. bottom: parent.bottom
  322. right: parent.right
  323. }
  324. function updateMaterialPropertiesObject()
  325. {
  326. var currentItem = materialsModel.getItem(materialListView.currentIndex);
  327. materialProperties.name = currentItem.name;
  328. materialProperties.guid = currentItem.guid;
  329. materialProperties.brand = currentItem.brand ? currentItem.brand : "Unknown";
  330. materialProperties.material = currentItem.material ? currentItem.material : "Unknown";
  331. materialProperties.color_name = currentItem.color_name ? currentItem.color_name : "Yellow";
  332. materialProperties.color_code = currentItem.color_code ? currentItem.color_code : "yellow";
  333. materialProperties.description = currentItem.description ? currentItem.description : "";
  334. materialProperties.adhesion_info = currentItem.adhesion_info ? currentItem.adhesion_info : "";
  335. if(currentItem.properties != undefined && currentItem.properties != null)
  336. {
  337. materialProperties.density = currentItem.density ? currentItem.density : 0.0;
  338. materialProperties.diameter = currentItem.diameter ? currentItem.diameter : 0.0;
  339. materialProperties.approximate_diameter = currentItem.approximate_diameter ? currentItem.approximate_diameter : "0";
  340. }
  341. else
  342. {
  343. materialProperties.density = 0.0;
  344. materialProperties.diameter = 0.0;
  345. materialProperties.approximate_diameter = "0";
  346. }
  347. }
  348. Item
  349. {
  350. anchors.fill: parent
  351. Item // Material title Label
  352. {
  353. id: profileName
  354. width: parent.width
  355. height: childrenRect.height
  356. Label {
  357. text: materialProperties.name
  358. font: UM.Theme.getFont("large")
  359. }
  360. }
  361. MaterialView // Material detailed information view below the title Label
  362. {
  363. id: materialDetailsView
  364. anchors
  365. {
  366. left: parent.left
  367. right: parent.right
  368. top: profileName.bottom
  369. topMargin: UM.Theme.getSize("default_margin").height
  370. bottom: parent.bottom
  371. }
  372. editingEnabled: base.currentItem != null && !base.currentItem.is_read_only
  373. properties: materialProperties
  374. containerId: base.currentItem != null ? base.currentItem.id : ""
  375. currentMaterialNode: base.currentItem
  376. property alias pane: base
  377. }
  378. QtObject
  379. {
  380. id: materialProperties
  381. property string guid: "00000000-0000-0000-0000-000000000000"
  382. property string name: "Unknown";
  383. property string profile_type: "Unknown";
  384. property string brand: "Unknown";
  385. property string material: "Unknown"; // This needs to be named as "material" to be consistent with
  386. // the material container's metadata entry
  387. property string color_name: "Yellow";
  388. property color color_code: "yellow";
  389. property real density: 0.0;
  390. property real diameter: 0.0;
  391. property string approximate_diameter: "0";
  392. property real spool_cost: 0.0;
  393. property real spool_weight: 0.0;
  394. property real spool_length: 0.0;
  395. property real cost_per_meter: 0.0;
  396. property string description: "";
  397. property string adhesion_info: "";
  398. }
  399. }
  400. }
  401. }
  402. }