MaterialsPage.qml 11 KB

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