WorkspaceDialog.qml 22 KB

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