MaterialsPage.qml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  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. // TODO
  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: exportMaterialDialog
  126. title: catalog.i18nc("@title:window", "Export Material")
  127. selectExisting: false
  128. nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
  129. folder: CuraApplication.getDefaultPath("dialog_material_path")
  130. onAccepted:
  131. {
  132. var result = Cura.ContainerManager.exportContainer(base.currentItem.root_material_id, selectedNameFilter, fileUrl);
  133. messageDialog.title = catalog.i18nc("@title:window", "Export Material");
  134. if (result.status == "error") {
  135. messageDialog.icon = StandardIcon.Critical;
  136. 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);
  137. messageDialog.open();
  138. }
  139. else if (result.status == "success") {
  140. messageDialog.icon = StandardIcon.Information;
  141. messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully exported material to <filename>%1</filename>").arg(result.path);
  142. messageDialog.open();
  143. }
  144. CuraApplication.setDefaultPath("dialog_material_path", folder);
  145. }
  146. }
  147. MessageDialog
  148. {
  149. id: messageDialog
  150. }
  151. Item {
  152. id: contentsItem
  153. anchors {
  154. top: titleLabel.bottom
  155. left: parent.left
  156. right: parent.right
  157. bottom: parent.bottom
  158. margins: 5 * screenScaleFactor
  159. bottomMargin: 0
  160. }
  161. clip: true
  162. }
  163. Item
  164. {
  165. anchors {
  166. top: buttonRow.bottom
  167. topMargin: UM.Theme.getSize("default_margin").height
  168. left: parent.left
  169. right: parent.right
  170. bottom: parent.bottom
  171. }
  172. SystemPalette { id: palette }
  173. Label
  174. {
  175. id: captionLabel
  176. anchors {
  177. top: parent.top
  178. left: parent.left
  179. }
  180. visible: text != ""
  181. text: {
  182. // OLD STUFF
  183. var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName;
  184. if (Cura.MachineManager.hasVariants)
  185. {
  186. caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName;
  187. }
  188. return caption;
  189. }
  190. width: materialScrollView.width
  191. elide: Text.ElideRight
  192. }
  193. ScrollView
  194. {
  195. id: materialScrollView
  196. anchors {
  197. top: captionLabel.visible ? captionLabel.bottom : parent.top
  198. topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0
  199. bottom: parent.bottom
  200. left: parent.left
  201. }
  202. Rectangle {
  203. parent: viewport
  204. anchors.fill: parent
  205. color: palette.light
  206. }
  207. width: true ? (parent.width * 0.4) | 0 : parent.width
  208. ListView
  209. {
  210. id: materialListView
  211. model: materialsModel
  212. section.property: "brand"
  213. section.criteria: ViewSection.FullString
  214. section.delegate: Rectangle
  215. {
  216. width: materialScrollView.width
  217. height: childrenRect.height
  218. color: palette.light
  219. Label
  220. {
  221. anchors.left: parent.left
  222. anchors.leftMargin: UM.Theme.getSize("default_lining").width
  223. text: section
  224. font.bold: true
  225. color: palette.text
  226. }
  227. }
  228. delegate: Rectangle
  229. {
  230. width: materialScrollView.width
  231. height: childrenRect.height
  232. color: ListView.isCurrentItem ? palette.highlight : (model.index % 2) ? palette.base : palette.alternateBase
  233. Row
  234. {
  235. spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
  236. anchors.left: parent.left
  237. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  238. anchors.right: parent.right
  239. Rectangle
  240. {
  241. width: Math.floor(parent.height * 0.8)
  242. height: Math.floor(parent.height * 0.8)
  243. color: model.color_code
  244. border.color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
  245. anchors.verticalCenter: parent.verticalCenter
  246. }
  247. Label
  248. {
  249. width: Math.floor((parent.width * 0.3))
  250. text: model.material
  251. elide: Text.ElideRight
  252. font.italic: { // TODO: make it easier
  253. const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
  254. const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
  255. return model.root_material_id == root_material_id
  256. }
  257. color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
  258. }
  259. Label
  260. {
  261. text: (model.name != model.material) ? model.name : ""
  262. elide: Text.ElideRight
  263. font.italic: { // TODO: make it easier
  264. const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
  265. const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
  266. return model.root_material_id == root_material_id;
  267. }
  268. color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
  269. }
  270. }
  271. MouseArea
  272. {
  273. anchors.fill: parent
  274. onClicked: {
  275. parent.ListView.view.currentIndex = model.index;
  276. }
  277. }
  278. }
  279. onCurrentIndexChanged:
  280. {
  281. var model = materialsModel.getItem(currentIndex);
  282. materialDetailsView.containerId = model.container_id;
  283. materialDetailsView.currentMaterialNode = model.container_node;
  284. detailsPanel.updateMaterialPropertiesObject();
  285. }
  286. }
  287. }
  288. Item
  289. {
  290. id: detailsPanel
  291. anchors {
  292. left: materialScrollView.right
  293. leftMargin: UM.Theme.getSize("default_margin").width
  294. top: parent.top
  295. bottom: parent.bottom
  296. right: parent.right
  297. }
  298. function updateMaterialPropertiesObject()
  299. {
  300. var currentItem = materialsModel.getItem(materialListView.currentIndex);
  301. materialProperties.name = currentItem.name;
  302. materialProperties.guid = currentItem.guid;
  303. materialProperties.brand = currentItem.brand ? currentItem.brand : "Unknown";
  304. materialProperties.material = currentItem.material ? currentItem.material : "Unknown";
  305. materialProperties.color_name = currentItem.color_name ? currentItem.color_name : "Yellow";
  306. materialProperties.color_code = currentItem.color_code ? currentItem.color_code : "yellow";
  307. materialProperties.description = currentItem.description ? currentItem.description : "";
  308. materialProperties.adhesion_info = currentItem.adhesion_info ? currentItem.adhesion_info : "";
  309. if(currentItem.properties != undefined && currentItem.properties != null)
  310. {
  311. materialProperties.density = currentItem.density ? currentItem.density : 0.0;
  312. materialProperties.diameter = currentItem.diameter ? currentItem.diameter : 0.0;
  313. materialProperties.approximate_diameter = currentItem.approximate_diameter ? currentItem.approximate_diameter : "0";
  314. }
  315. else
  316. {
  317. materialProperties.density = 0.0;
  318. materialProperties.diameter = 0.0;
  319. materialProperties.approximate_diameter = "0";
  320. }
  321. }
  322. Item
  323. {
  324. anchors.fill: parent
  325. Item // Material title Label
  326. {
  327. id: profileName
  328. width: parent.width
  329. height: childrenRect.height
  330. Label {
  331. text: materialProperties.name
  332. font: UM.Theme.getFont("large")
  333. }
  334. }
  335. MaterialView // Material detailed information view below the title Label
  336. {
  337. id: materialDetailsView
  338. anchors
  339. {
  340. left: parent.left
  341. right: parent.right
  342. top: profileName.bottom
  343. topMargin: UM.Theme.getSize("default_margin").height
  344. bottom: parent.bottom
  345. }
  346. editingEnabled: base.currentItem != null && !base.currentItem.is_read_only
  347. properties: materialProperties
  348. containerId: base.currentItem != null ? base.currentItem.id : ""
  349. currentMaterialNode: base.currentItem
  350. property alias pane: base
  351. }
  352. QtObject
  353. {
  354. id: materialProperties
  355. property string guid: "00000000-0000-0000-0000-000000000000"
  356. property string name: "Unknown";
  357. property string profile_type: "Unknown";
  358. property string brand: "Unknown";
  359. property string material: "Unknown"; // This needs to be named as "material" to be consistent with
  360. // the material container's metadata entry
  361. property string color_name: "Yellow";
  362. property color color_code: "yellow";
  363. property real density: 0.0;
  364. property real diameter: 0.0;
  365. property string approximate_diameter: "0";
  366. property real spool_cost: 0.0;
  367. property real spool_weight: 0.0;
  368. property real spool_length: 0.0;
  369. property real cost_per_meter: 0.0;
  370. property string description: "";
  371. property string adhesion_info: "";
  372. }
  373. }
  374. }
  375. }
  376. }