MaterialsPage.qml 12 KB

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