WorkspaceDialog.qml 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. // Copyright (c) 2022 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.10
  4. import QtQuick.Controls 2.3
  5. import QtQuick.Layouts 1.3
  6. import QtQuick.Window 2.2
  7. import UM 1.6 as UM
  8. import Cura 1.1 as Cura
  9. UM.Dialog
  10. {
  11. id: workspaceDialog
  12. title: catalog.i18nc("@title:window", "Open Project")
  13. margin: UM.Theme.getSize("default_margin").width
  14. minimumWidth: UM.Theme.getSize("modal_window_minimum").width
  15. minimumHeight: UM.Theme.getSize("modal_window_minimum").height
  16. backgroundColor: UM.Theme.getColor("detail_background")
  17. headerComponent: Rectangle
  18. {
  19. height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").height
  20. color: UM.Theme.getColor("main_background")
  21. UM.Label
  22. {
  23. id: titleLabel
  24. text: catalog.i18nc("@action:title", "Summary - Cura Project")
  25. font: UM.Theme.getFont("large")
  26. anchors.top: parent.top
  27. anchors.left: parent.left
  28. anchors.topMargin: UM.Theme.getSize("default_margin").height
  29. anchors.leftMargin: UM.Theme.getSize("default_margin").height
  30. }
  31. }
  32. Rectangle
  33. {
  34. anchors.fill: parent
  35. UM.I18nCatalog { id: catalog; name: "cura" }
  36. color: UM.Theme.getColor("main_background")
  37. Flickable
  38. {
  39. id: dialogSummaryItem
  40. width: parent.width
  41. height: parent.height
  42. clip: true
  43. contentHeight: contentColumn.height
  44. ScrollBar.vertical: UM.ScrollBar { id: scrollbar }
  45. ListModel
  46. {
  47. id: resolveStrategiesModel
  48. // Instead of directly adding the list elements, we add them afterwards.
  49. // This is because it's impossible to use setting function results to be bound to listElement properties directly.
  50. // See http://stackoverflow.com/questions/7659442/listelement-fields-as-properties
  51. Component.onCompleted:
  52. {
  53. append({"key": "override", "label": catalog.i18nc("@action:ComboBox Update/override existing profile", "Update existing")});
  54. append({"key": "new", "label": catalog.i18nc("@action:ComboBox Save settings in a new profile", "Create new")});
  55. }
  56. }
  57. Column
  58. {
  59. id: contentColumn
  60. width: parent.width - scrollbar.width - UM.Theme.getSize("default_margin").width
  61. height: childrenRect.height
  62. spacing: UM.Theme.getSize("default_margin").height
  63. leftPadding: UM.Theme.getSize("default_margin").width
  64. rightPadding: UM.Theme.getSize("default_margin").width
  65. WorkspaceSection
  66. {
  67. id: printerSection
  68. title: catalog.i18nc("@action:label", "Printer settings")
  69. iconSource: UM.Theme.getIcon("Printer")
  70. content: Column
  71. {
  72. spacing: UM.Theme.getSize("default_margin").height
  73. leftPadding: UM.Theme.getSize("medium_button_icon").width + UM.Theme.getSize("default_margin").width
  74. WorkspaceRow
  75. {
  76. leftLabelText: catalog.i18nc("@action:label", "Type")
  77. rightLabelText: manager.machineType
  78. }
  79. WorkspaceRow
  80. {
  81. leftLabelText: catalog.i18nc("@action:label", manager.isPrinterGroup ? "Printer Group" : "Printer Name")
  82. rightLabelText: manager.machineName == catalog.i18nc("@button", "Create new") ? "" : manager.machineName
  83. }
  84. }
  85. comboboxTitle: catalog.i18nc("@action:label", "Open With")
  86. comboboxTooltipText: catalog.i18nc("@info:tooltip", "Printer settings will be updated to match the settings saved with the project.")
  87. comboboxVisible: workspaceDialog.visible && manager.updatableMachinesModel.count > 1
  88. combobox: Cura.MachineSelector
  89. {
  90. id: machineSelector
  91. headerCornerSide: Cura.RoundedRectangle.Direction.All
  92. width: parent.width
  93. height: parent.height
  94. machineListModel: manager.updatableMachinesModel
  95. machineName: manager.machineName
  96. isConnectedCloudPrinter: false
  97. isCloudRegistered: false
  98. isNetworkPrinter: manager.isNetworked
  99. isGroup: manager.isAbstractMachine
  100. connectionStatus: ""
  101. minDropDownWidth: machineSelector.width
  102. Component
  103. {
  104. id: componentNewPrinter
  105. Cura.SecondaryButton
  106. {
  107. id: createNewPrinter
  108. text: catalog.i18nc("@button", "Create new")
  109. fixedWidthMode: true
  110. width: parent.width - leftPadding * 1.5
  111. visible: manager.allowCreateMachine
  112. onClicked:
  113. {
  114. toggleContent()
  115. manager.setResolveStrategy("machine", "new")
  116. machineSelector.machineName = catalog.i18nc("@button", "Create new")
  117. manager.setIsAbstractMachine(false)
  118. manager.setIsNetworkedMachine(false)
  119. }
  120. }
  121. }
  122. buttons: manager.allowCreateMachine ? [componentNewPrinter.createObject()] : []
  123. onSelectPrinter: function(machine)
  124. {
  125. toggleContent();
  126. machineSelector.machineName = machine.name
  127. manager.setResolveStrategy("machine", "override")
  128. manager.setMachineToOverride(machine.id)
  129. manager.setIsAbstractMachine(machine.isAbstractMachine)
  130. manager.setIsNetworkedMachine(machine.isNetworked)
  131. }
  132. }
  133. }
  134. WorkspaceSection
  135. {
  136. id: profileSection
  137. title: catalog.i18nc("@action:label", "Profile settings")
  138. iconSource: UM.Theme.getIcon("Sliders")
  139. content: Column
  140. {
  141. id: profileSettingsValuesTable
  142. spacing: UM.Theme.getSize("default_margin").height
  143. leftPadding: UM.Theme.getSize("medium_button_icon").width + UM.Theme.getSize("default_margin").width
  144. WorkspaceRow
  145. {
  146. leftLabelText: catalog.i18nc("@action:label", "Name")
  147. rightLabelText: manager.qualityName
  148. visible: manager.isCompatibleMachine
  149. }
  150. WorkspaceRow
  151. {
  152. leftLabelText: catalog.i18nc("@action:label", "Intent")
  153. rightLabelText: manager.intentName
  154. visible: manager.isCompatibleMachine
  155. }
  156. WorkspaceRow
  157. {
  158. leftLabelText: catalog.i18nc("@action:label", "Not in profile")
  159. rightLabelText: catalog.i18ncp("@action:label", "%1 override", "%1 overrides", manager.numUserSettings).arg(manager.numUserSettings)
  160. visible: manager.numUserSettings != 0 && manager.selectSameProfileChecked && manager.isCompatibleMachine
  161. }
  162. WorkspaceRow
  163. {
  164. leftLabelText: catalog.i18nc("@action:label", "Derivative from")
  165. rightLabelText: catalog.i18ncp("@action:label", "%1, %2 override", "%1, %2 overrides", manager.numSettingsOverridenByQualityChanges).arg(manager.qualityType).arg(manager.numSettingsOverridenByQualityChanges)
  166. visible: manager.numSettingsOverridenByQualityChanges != 0 && manager.selectSameProfileChecked && manager.isCompatibleMachine
  167. }
  168. WorkspaceRow
  169. {
  170. leftLabelText: catalog.i18nc("@action:label", "Specific settings")
  171. rightLabelText: catalog.i18ncp("@action:label", "%1 override", "%1 overrides", manager.exportedSettingModel.rowCount()).arg(manager.exportedSettingModel.rowCount())
  172. buttonText: tableViewSpecificSettings.shouldBeVisible ? catalog.i18nc("@action:button", "Hide settings") : catalog.i18nc("@action:button", "Show settings")
  173. visible: !manager.selectSameProfileChecked || !manager.isCompatibleMachine
  174. onButtonClicked: tableViewSpecificSettings.shouldBeVisible = !tableViewSpecificSettings.shouldBeVisible
  175. }
  176. Cura.TableView
  177. {
  178. id: tableViewSpecificSettings
  179. width: parent.width - parent.leftPadding - UM.Theme.getSize("default_margin").width
  180. height: UM.Theme.getSize("card").height
  181. visible: shouldBeVisible && (!manager.selectSameProfileChecked || !manager.isCompatibleMachine)
  182. property bool shouldBeVisible: false
  183. columnHeaders:
  184. [
  185. catalog.i18nc("@title:column", "Applies on"),
  186. catalog.i18nc("@title:column", "Setting"),
  187. catalog.i18nc("@title:column", "Value")
  188. ]
  189. model: UM.TableModel
  190. {
  191. id: tableModel
  192. headers: ["category", "label", "value"]
  193. rows: manager.exportedSettingModel.items
  194. }
  195. }
  196. UM.CheckBox
  197. {
  198. text: catalog.i18nc("@action:checkbox", "Select the same profile")
  199. onEnabledChanged: manager.selectSameProfileChecked = enabled
  200. tooltip: enabled ? "" : catalog.i18nc("@tooltip", "You can use the same profile only if you have the same printer as the project was published with")
  201. visible: manager.hasVisibleSelectSameProfile && manager.isCompatibleMachine
  202. checked: manager.selectSameProfileChecked
  203. onCheckedChanged: manager.selectSameProfileChecked = checked
  204. }
  205. }
  206. comboboxVisible: manager.qualityChangesConflict
  207. combobox: Cura.ComboBox
  208. {
  209. id: qualityChangesResolveComboBox
  210. model: resolveStrategiesModel
  211. textRole: "label"
  212. visible: manager.qualityChangesConflict
  213. contentLeftPadding: UM.Theme.getSize("default_margin").width + UM.Theme.getSize("narrow_margin").width
  214. textFont: UM.Theme.getFont("medium")
  215. background: Cura.RoundedRectangle
  216. {
  217. border.width: UM.Theme.getSize("default_lining").width
  218. border.color: UM.Theme.getColor("lining")
  219. color: qualityChangesResolveComboBox.hovered ? UM.Theme.getColor("expandable_hover") : UM.Theme.getColor("action_button")
  220. cornerSide: Cura.RoundedRectangle.Direction.All
  221. radius: UM.Theme.getSize("default_radius").width
  222. }
  223. // This is a hack. This will trigger onCurrentIndexChanged and set the index when this component in loaded
  224. currentIndex:
  225. {
  226. currentIndex = 0
  227. }
  228. onCurrentIndexChanged:
  229. {
  230. manager.setResolveStrategy("quality_changes", resolveStrategiesModel.get(currentIndex).key)
  231. }
  232. }
  233. }
  234. WorkspaceSection
  235. {
  236. id: materialSection
  237. title: catalog.i18nc("@action:label", "Material settings")
  238. iconSource: UM.Theme.getIcon("Spool")
  239. content: Column
  240. {
  241. spacing: UM.Theme.getSize("default_margin").height
  242. leftPadding: UM.Theme.getSize("medium_button_icon").width + UM.Theme.getSize("default_margin").width
  243. Repeater
  244. {
  245. model: manager.materialLabels
  246. delegate: WorkspaceRow
  247. {
  248. leftLabelText: catalog.i18nc("@action:label", "Name")
  249. rightLabelText: modelData
  250. }
  251. }
  252. }
  253. comboboxVisible: manager.materialConflict
  254. combobox: Cura.ComboBox
  255. {
  256. id: materialResolveComboBox
  257. model: resolveStrategiesModel
  258. textRole: "label"
  259. visible: manager.materialConflict
  260. contentLeftPadding: UM.Theme.getSize("default_margin").width + UM.Theme.getSize("narrow_margin").width
  261. textFont: UM.Theme.getFont("medium")
  262. background: Cura.RoundedRectangle
  263. {
  264. border.width: UM.Theme.getSize("default_lining").width
  265. border.color: UM.Theme.getColor("lining")
  266. color: materialResolveComboBox.hovered ? UM.Theme.getColor("expandable_hover") : UM.Theme.getColor("action_button")
  267. cornerSide: Cura.RoundedRectangle.Direction.All
  268. radius: UM.Theme.getSize("default_radius").width
  269. }
  270. // This is a hack. This will trigger onCurrentIndexChanged and set the index when this component in loaded
  271. currentIndex:
  272. {
  273. currentIndex = 0
  274. }
  275. onCurrentIndexChanged:
  276. {
  277. manager.setResolveStrategy("material", resolveStrategiesModel.get(currentIndex).key)
  278. }
  279. }
  280. }
  281. WorkspaceSection
  282. {
  283. id: visibilitySection
  284. title: catalog.i18nc("@action:label", "Setting visibility")
  285. iconSource: UM.Theme.getIcon("Eye")
  286. content: Column
  287. {
  288. spacing: UM.Theme.getSize("default_margin").height
  289. leftPadding: UM.Theme.getSize("medium_button_icon").width + UM.Theme.getSize("default_margin").width
  290. bottomPadding: UM.Theme.getSize("narrow_margin").height
  291. WorkspaceRow
  292. {
  293. leftLabelText: catalog.i18nc("@action:label", "Mode")
  294. rightLabelText: manager.activeMode
  295. }
  296. WorkspaceRow
  297. {
  298. leftLabelText: catalog.i18nc("@action:label", "%1 out of %2" ).arg(manager.numVisibleSettings).arg(manager.totalNumberOfSettings)
  299. rightLabelText: manager.activeMode
  300. visible: manager.hasVisibleSettingsField
  301. }
  302. }
  303. }
  304. Row
  305. {
  306. id: dropToBuildPlate
  307. width: parent.width
  308. height: childrenRect.height
  309. spacing: UM.Theme.getSize("default_margin").width
  310. UM.CheckBox
  311. {
  312. id: checkDropModels
  313. text: catalog.i18nc("@text:window", "Drop models to buildplate")
  314. checked: UM.Preferences.getValue("physics/automatic_drop_down")
  315. onCheckedChanged: manager.setDropToBuildPlateForModel(checked)
  316. }
  317. function reloadValue()
  318. {
  319. checkDropModels.checked = UM.Preferences.getValue("physics/automatic_drop_down")
  320. }
  321. }
  322. Row
  323. {
  324. id: clearBuildPlateWarning
  325. width: parent.width
  326. height: childrenRect.height
  327. spacing: UM.Theme.getSize("default_margin").width
  328. visible: manager.hasObjectsOnPlate
  329. UM.ColorImage
  330. {
  331. width: warningLabel.height
  332. height: width
  333. source: UM.Theme.getIcon("Information")
  334. color: UM.Theme.getColor("text")
  335. }
  336. UM.Label
  337. {
  338. id: warningLabel
  339. text: catalog.i18nc("@action:warning", "Loading a project will clear all models on the build plate.")
  340. }
  341. }
  342. }
  343. }
  344. }
  345. property bool warning: manager.missingPackages.length > 0
  346. footerComponent: Rectangle
  347. {
  348. color: warning ? UM.Theme.getColor("warning") : "transparent"
  349. anchors.bottom: parent.bottom
  350. width: parent.width
  351. height: childrenRect.height + (warning ? 2 * workspaceDialog.margin : workspaceDialog.margin)
  352. Column
  353. {
  354. height: childrenRect.height
  355. spacing: workspaceDialog.margin
  356. anchors.leftMargin: workspaceDialog.margin
  357. anchors.rightMargin: workspaceDialog.margin
  358. anchors.bottomMargin: workspaceDialog.margin
  359. anchors.topMargin: warning ? workspaceDialog.margin : 0
  360. anchors.left: parent.left
  361. anchors.right: parent.right
  362. anchors.top: parent.top
  363. RowLayout
  364. {
  365. id: warningRow
  366. height: childrenRect.height
  367. visible: warning
  368. spacing: workspaceDialog.margin
  369. UM.ColorImage
  370. {
  371. width: UM.Theme.getSize("extruder_icon").width
  372. height: UM.Theme.getSize("extruder_icon").height
  373. source: UM.Theme.getIcon("Warning")
  374. }
  375. UM.Label
  376. {
  377. id: warningText
  378. text: catalog.i18nc("@label", "This project contains materials or plugins that are currently not installed in Cura.<br/>Install the missing packages and reopen the project.")
  379. }
  380. }
  381. Loader
  382. {
  383. width: parent.width
  384. height: childrenRect.height
  385. sourceComponent: buttonRow
  386. }
  387. }
  388. }
  389. buttonSpacing: UM.Theme.getSize("wide_margin").width
  390. rightButtons: [
  391. Cura.TertiaryButton
  392. {
  393. visible: !warning
  394. text: catalog.i18nc("@action:button", "Cancel")
  395. onClicked: reject()
  396. },
  397. Cura.PrimaryButton
  398. {
  399. visible: !warning
  400. text: catalog.i18nc("@action:button", "Open")
  401. onClicked: accept()
  402. },
  403. Cura.TertiaryButton
  404. {
  405. visible: warning
  406. text: catalog.i18nc("@action:button", "Open project anyway")
  407. onClicked: {
  408. manager.showMissingMaterialsWarning();
  409. accept();
  410. }
  411. },
  412. Cura.PrimaryButton
  413. {
  414. visible: warning
  415. text: catalog.i18nc("@action:button", "Install missing packages")
  416. onClicked: manager.installMissingPackages()
  417. }
  418. ]
  419. onClosing: manager.notifyClosed()
  420. onRejected: manager.onCancelButtonClicked()
  421. onAccepted: manager.onOkButtonClicked()
  422. onVisibleChanged:
  423. {
  424. if (visible)
  425. {
  426. // Force relead the comboboxes
  427. // Since this dialog is only created once the first time you open it, these comboxes need to be reloaded
  428. // each time it is shown after the first time so that the indexes will update correctly.
  429. materialSection.reloadValues()
  430. profileSection.reloadValues()
  431. printerSection.reloadValues()
  432. dropToBuildPlate.reloadValue()
  433. }
  434. }
  435. }