MaterialsPage.qml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. // Copyright (c) 2018 Ultimaker B.V.
  2. // Uranium is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.7
  4. import QtQuick.Controls 1.4
  5. import QtQuick.Layouts 1.3
  6. import QtQuick.Dialogs 1.2
  7. import UM 1.2 as UM
  8. import Cura 1.5 as Cura
  9. Item
  10. {
  11. id: base
  12. // Keep PreferencesDialog happy
  13. property var resetEnabled: false
  14. property var currentItem: null
  15. property var materialManagementModel: CuraApplication.getMaterialManagementModel()
  16. property var hasCurrentItem: base.currentItem != null
  17. property var isCurrentItemActivated:
  18. {
  19. if (!hasCurrentItem)
  20. {
  21. return false
  22. }
  23. const extruder_position = Cura.ExtruderManager.activeExtruderIndex
  24. const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]
  25. return base.currentItem.root_material_id == root_material_id
  26. }
  27. property string newRootMaterialIdToSwitchTo: ""
  28. property bool toActivateNewMaterial: false
  29. property var extruder_position: Cura.ExtruderManager.activeExtruderIndex
  30. property var active_root_material_id: Cura.MachineManager.currentRootMaterialId[extruder_position]
  31. UM.I18nCatalog
  32. {
  33. id: catalog
  34. name: "cura"
  35. }
  36. function resetExpandedActiveMaterial()
  37. {
  38. materialListView.expandActiveMaterial(active_root_material_id)
  39. }
  40. function setExpandedActiveMaterial(root_material_id)
  41. {
  42. materialListView.expandActiveMaterial(root_material_id)
  43. }
  44. // When loaded, try to select the active material in the tree
  45. Component.onCompleted:
  46. {
  47. resetExpandedActiveMaterial()
  48. base.newRootMaterialIdToSwitchTo = active_root_material_id
  49. }
  50. // Every time the selected item has changed, notify to the details panel
  51. onCurrentItemChanged:
  52. {
  53. forceActiveFocus()
  54. if(materialDetailsPanel.currentItem != currentItem)
  55. {
  56. materialDetailsPanel.currentItem = currentItem
  57. // CURA-6679 If the current item is gone after the model update, reset the current item to the active material.
  58. if (currentItem == null)
  59. {
  60. resetExpandedActiveMaterial()
  61. }
  62. }
  63. }
  64. // Main layout
  65. Label
  66. {
  67. id: titleLabel
  68. anchors
  69. {
  70. top: parent.top
  71. left: parent.left
  72. right: parent.right
  73. margins: 5 * screenScaleFactor
  74. }
  75. font.pointSize: 18
  76. text: catalog.i18nc("@title:tab", "Materials")
  77. }
  78. // Button Row
  79. Row
  80. {
  81. id: buttonRow
  82. anchors
  83. {
  84. left: parent.left
  85. right: parent.right
  86. top: titleLabel.bottom
  87. }
  88. height: childrenRect.height
  89. // Activate button
  90. Button
  91. {
  92. id: activateMenuButton
  93. text: catalog.i18nc("@action:button", "Activate")
  94. iconName: "list-activate"
  95. enabled: !isCurrentItemActivated && Cura.MachineManager.activeMachine.hasMaterials
  96. onClicked:
  97. {
  98. forceActiveFocus()
  99. // Set the current material as the one to be activated (needed to force the UI update)
  100. base.newRootMaterialIdToSwitchTo = base.currentItem.root_material_id
  101. const extruder_position = Cura.ExtruderManager.activeExtruderIndex
  102. Cura.MachineManager.setMaterial(extruder_position, base.currentItem.container_node)
  103. }
  104. }
  105. // Create button
  106. Button
  107. {
  108. id: createMenuButton
  109. text: catalog.i18nc("@action:button", "Create")
  110. iconName: "list-add"
  111. enabled: Cura.MachineManager.activeMachine.hasMaterials
  112. onClicked:
  113. {
  114. forceActiveFocus();
  115. base.newRootMaterialIdToSwitchTo = base.materialManagementModel.createMaterial();
  116. base.toActivateNewMaterial = true;
  117. }
  118. }
  119. // Duplicate button
  120. Button
  121. {
  122. id: duplicateMenuButton
  123. text: catalog.i18nc("@action:button", "Duplicate");
  124. iconName: "list-add"
  125. enabled: base.hasCurrentItem
  126. onClicked:
  127. {
  128. forceActiveFocus();
  129. base.newRootMaterialIdToSwitchTo = base.materialManagementModel.duplicateMaterial(base.currentItem.container_node);
  130. base.toActivateNewMaterial = true;
  131. }
  132. }
  133. // Remove button
  134. Button
  135. {
  136. id: removeMenuButton
  137. text: catalog.i18nc("@action:button", "Remove")
  138. iconName: "list-remove"
  139. enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated && base.materialManagementModel.canMaterialBeRemoved(base.currentItem.container_node)
  140. onClicked:
  141. {
  142. forceActiveFocus();
  143. confirmRemoveMaterialDialog.open();
  144. }
  145. }
  146. // Import button
  147. Button
  148. {
  149. id: importMenuButton
  150. text: catalog.i18nc("@action:button", "Import")
  151. iconName: "document-import"
  152. onClicked:
  153. {
  154. forceActiveFocus();
  155. importMaterialDialog.open();
  156. }
  157. enabled: Cura.MachineManager.activeMachine.hasMaterials
  158. }
  159. // Export button
  160. Button
  161. {
  162. id: exportMenuButton
  163. text: catalog.i18nc("@action:button", "Export")
  164. iconName: "document-export"
  165. onClicked:
  166. {
  167. forceActiveFocus();
  168. exportMaterialDialog.open();
  169. }
  170. enabled: base.hasCurrentItem
  171. }
  172. }
  173. Item {
  174. id: contentsItem
  175. anchors
  176. {
  177. top: titleLabel.bottom
  178. left: parent.left
  179. right: parent.right
  180. bottom: parent.bottom
  181. margins: 5 * screenScaleFactor
  182. bottomMargin: 0
  183. }
  184. clip: true
  185. }
  186. Item
  187. {
  188. anchors
  189. {
  190. top: buttonRow.bottom
  191. topMargin: UM.Theme.getSize("default_margin").height
  192. left: parent.left
  193. right: parent.right
  194. bottom: parent.bottom
  195. }
  196. SystemPalette { id: palette }
  197. Label
  198. {
  199. id: captionLabel
  200. anchors
  201. {
  202. top: parent.top
  203. left: parent.left
  204. }
  205. visible: text != ""
  206. text:
  207. {
  208. var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachine.name;
  209. if (Cura.MachineManager.activeMachine.hasVariants)
  210. {
  211. var activeVariantName = ""
  212. if(Cura.MachineManager.activeStack != null)
  213. {
  214. activeVariantName = Cura.MachineManager.activeStack.variant.name
  215. }
  216. caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + activeVariantName;
  217. }
  218. return caption;
  219. }
  220. width: materialScrollView.width
  221. elide: Text.ElideRight
  222. }
  223. ScrollView
  224. {
  225. id: materialScrollView
  226. anchors
  227. {
  228. top: captionLabel.visible ? captionLabel.bottom : parent.top
  229. topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0
  230. bottom: parent.bottom
  231. left: parent.left
  232. }
  233. Rectangle
  234. {
  235. parent: viewport
  236. anchors.fill: parent
  237. color: palette.light
  238. }
  239. width: (parent.width * 0.4) | 0
  240. frameVisible: true
  241. horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
  242. MaterialsList
  243. {
  244. id: materialListView
  245. width: materialScrollView.viewport.width
  246. }
  247. }
  248. MaterialsDetailsPanel
  249. {
  250. id: materialDetailsPanel
  251. anchors
  252. {
  253. left: materialScrollView.right
  254. leftMargin: UM.Theme.getSize("default_margin").width
  255. top: parent.top
  256. bottom: parent.bottom
  257. right: parent.right
  258. }
  259. }
  260. }
  261. // Dialogs
  262. MessageDialog
  263. {
  264. id: confirmRemoveMaterialDialog
  265. icon: StandardIcon.Question;
  266. title: catalog.i18nc("@title:window", "Confirm Remove")
  267. property string materialName: base.currentItem !== null ? base.currentItem.name : ""
  268. text: catalog.i18nc("@label (%1 is object name)", "Are you sure you wish to remove %1? This cannot be undone!").arg(materialName)
  269. standardButtons: StandardButton.Yes | StandardButton.No
  270. modality: Qt.ApplicationModal
  271. onYes:
  272. {
  273. // Set the active material as the fallback. It will be selected when the current material is deleted
  274. base.newRootMaterialIdToSwitchTo = base.active_root_material_id
  275. base.materialManagementModel.removeMaterial(base.currentItem.container_node);
  276. }
  277. }
  278. FileDialog
  279. {
  280. id: importMaterialDialog
  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.importMaterialContainer(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. }
  295. else if (result.status == "duplicate")
  296. {
  297. messageDialog.icon = StandardIcon.Warning;
  298. }
  299. else
  300. {
  301. messageDialog.icon = StandardIcon.Critical;
  302. }
  303. messageDialog.open();
  304. CuraApplication.setDefaultPath("dialog_material_path", folder);
  305. }
  306. }
  307. FileDialog
  308. {
  309. id: exportMaterialDialog
  310. title: catalog.i18nc("@title:window", "Export Material")
  311. selectExisting: false
  312. nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
  313. folder: CuraApplication.getDefaultPath("dialog_material_path")
  314. onAccepted:
  315. {
  316. var result = Cura.ContainerManager.exportContainer(base.currentItem.root_material_id, selectedNameFilter, fileUrl);
  317. messageDialog.title = catalog.i18nc("@title:window", "Export Material");
  318. if (result.status == "error")
  319. {
  320. messageDialog.icon = StandardIcon.Critical;
  321. 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);
  322. messageDialog.open();
  323. }
  324. else if (result.status == "success")
  325. {
  326. messageDialog.icon = StandardIcon.Information;
  327. messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully exported material to <filename>%1</filename>").arg(result.path);
  328. messageDialog.open();
  329. }
  330. CuraApplication.setDefaultPath("dialog_material_path", folder);
  331. }
  332. }
  333. MessageDialog
  334. {
  335. id: messageDialog
  336. }
  337. }