Cura.qml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. // Copyright (c) 2015 Ultimaker B.V.
  2. // Cura is released under the terms of the AGPLv3 or higher.
  3. import QtQuick 2.2
  4. import QtQuick.Controls 1.1
  5. import QtQuick.Controls.Styles 1.1
  6. import QtQuick.Layouts 1.1
  7. import QtQuick.Dialogs 1.1
  8. import UM 1.1 as UM
  9. UM.MainWindow {
  10. id: base
  11. visible: true
  12. //: Cura application window title
  13. title: qsTr("Cura");
  14. Item {
  15. id: backgroundItem;
  16. anchors.fill: parent;
  17. UM.ApplicationMenu {
  18. id: menu
  19. window: base
  20. Menu {
  21. id: fileMenu
  22. //: File menu
  23. title: qsTr("&File");
  24. MenuItem { action: actions.open; }
  25. Menu {
  26. id: recentFilesMenu;
  27. title: "Open Recent"
  28. iconName: "document-open-recent";
  29. enabled: Printer.recentFiles.length > 0;
  30. Instantiator {
  31. model: Printer.recentFiles
  32. MenuItem {
  33. text: {
  34. var path = modelData.toString()
  35. return (index + 1) + ". " + path.slice(path.lastIndexOf("/") + 1);
  36. }
  37. onTriggered: UM.MeshFileHandler.readLocalFile(modelData);
  38. }
  39. onObjectAdded: recentFilesMenu.insertItem(index, object)
  40. onObjectRemoved: recentFilesMenu.removeItem(object)
  41. }
  42. }
  43. MenuSeparator { }
  44. MenuItem {
  45. text: "Save Selection to File";
  46. enabled: UM.Selection.hasSelection;
  47. iconName: "document-save-as";
  48. onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file");
  49. }
  50. Menu {
  51. id: saveAllMenu
  52. title: "Save All"
  53. iconName: "document-save";
  54. enabled: devicesModel.count > 0 && UM.Backend.progress > 0.99;
  55. Instantiator {
  56. model: UM.OutputDevicesModel { id: devicesModel; }
  57. MenuItem {
  58. text: model.description;
  59. onTriggered: UM.OutputDeviceManager.requestWriteToDevice(model.id);
  60. }
  61. onObjectAdded: saveAllMenu.insertItem(index, object)
  62. onObjectRemoved: saveAllMenu.removeItem(object)
  63. }
  64. }
  65. MenuSeparator { }
  66. MenuItem { action: actions.quit; }
  67. }
  68. Menu {
  69. //: Edit menu
  70. title: qsTr("&Edit");
  71. MenuItem { action: actions.undo; }
  72. MenuItem { action: actions.redo; }
  73. MenuSeparator { }
  74. MenuItem { action: actions.deleteSelection; }
  75. MenuItem { action: actions.deleteAll; }
  76. }
  77. Menu
  78. {
  79. title: qsTr("&View");
  80. id: top_view_menu
  81. Instantiator
  82. {
  83. model: UM.Models.viewModel
  84. MenuItem
  85. {
  86. text: model.name;
  87. checkable: true;
  88. checked: model.active;
  89. exclusiveGroup: view_menu_top_group;
  90. onTriggered: UM.Controller.setActiveView(model.id);
  91. }
  92. onObjectAdded: top_view_menu.insertItem(index, object)
  93. onObjectRemoved: top_view_menu.removeItem(object)
  94. }
  95. ExclusiveGroup { id: view_menu_top_group; }
  96. }
  97. Menu {
  98. id: machineMenu;
  99. //: Machine menu
  100. title: qsTr("&Machine");
  101. Instantiator {
  102. model: UM.Models.machinesModel
  103. MenuItem {
  104. text: model.name;
  105. checkable: true;
  106. checked: model.active;
  107. exclusiveGroup: machineMenuGroup;
  108. onTriggered: UM.Models.machinesModel.setActive(index)
  109. }
  110. onObjectAdded: machineMenu.insertItem(index, object)
  111. onObjectRemoved: machineMenu.removeItem(object)
  112. }
  113. ExclusiveGroup { id: machineMenuGroup; }
  114. MenuSeparator { }
  115. MenuItem { action: actions.addMachine; }
  116. MenuItem { action: actions.configureMachines; }
  117. }
  118. Menu {
  119. id: extension_menu
  120. //: Extensions menu
  121. title: qsTr("E&xtensions");
  122. Instantiator
  123. {
  124. model: UM.Models.extensionModel
  125. Menu
  126. {
  127. id: sub_menu
  128. title: model.name;
  129. Instantiator
  130. {
  131. model: actions
  132. MenuItem
  133. {
  134. text: model.text
  135. onTriggered: UM.Models.extensionModel.subMenuTriggered(name, model.text)
  136. }
  137. onObjectAdded: sub_menu.insertItem(index, object)
  138. onObjectRemoved: sub_menu.removeItem(object)
  139. }
  140. }
  141. onObjectAdded: extension_menu.insertItem(index, object)
  142. onObjectRemoved: extension_menu.removeItem(object)
  143. }
  144. }
  145. Menu {
  146. //: Settings menu
  147. title: qsTr("&Settings");
  148. MenuItem { action: actions.preferences; }
  149. }
  150. Menu {
  151. //: Help menu
  152. title: qsTr("&Help");
  153. MenuItem { action: actions.showEngineLog; }
  154. MenuItem { action: actions.documentation; }
  155. MenuItem { action: actions.reportBug; }
  156. MenuSeparator { }
  157. MenuItem { action: actions.about; }
  158. }
  159. }
  160. Item {
  161. id: contentItem;
  162. y: menu.height
  163. width: parent.width;
  164. height: parent.height - menu.height;
  165. Keys.forwardTo: menu
  166. DropArea {
  167. anchors.fill: parent;
  168. onDropped: {
  169. if(drop.urls.length > 0) {
  170. for(var i in drop.urls) {
  171. UM.MeshFileHandler.readLocalFile(drop.urls[i]);
  172. }
  173. }
  174. }
  175. }
  176. UM.MessageStack {
  177. anchors {
  178. horizontalCenter: parent.horizontalCenter
  179. horizontalCenterOffset: -(UM.Theme.sizes.logo.width/ 2)
  180. bottom: parent.bottom;
  181. }
  182. }
  183. Loader
  184. {
  185. id: view_panel
  186. //anchors.left: parent.left;
  187. //anchors.right: parent.right;
  188. //anchors.bottom: parent.bottom
  189. anchors.top: viewModeButton.bottom
  190. anchors.topMargin: UM.Theme.sizes.default_margin.height;
  191. anchors.right: sidebar.left;
  192. anchors.rightMargin: UM.Theme.sizes.window_margin.width;
  193. //anchors.bottom: buttons.top;
  194. //anchors.bottomMargin: UM.Theme.sizes.default_margin.height;
  195. height: childrenRect.height;
  196. source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "";
  197. }
  198. Button {
  199. id: openFileButton;
  200. //style: UM.Backend.progress < 0 ? UM.Theme.styles.open_file_button : UM.Theme.styles.tool_button;
  201. style: UM.Theme.styles.open_file_button
  202. tooltip: '';
  203. anchors {
  204. top: parent.top;
  205. topMargin: UM.Theme.sizes.loadfile_margin.height
  206. left: parent.left;
  207. leftMargin: UM.Theme.sizes.loadfile_margin.width
  208. }
  209. action: actions.open;
  210. }
  211. Image {
  212. id: logo
  213. anchors {
  214. left: parent.left
  215. leftMargin: UM.Theme.sizes.default_margin.width;
  216. bottom: parent.bottom
  217. bottomMargin: UM.Theme.sizes.default_margin.height;
  218. }
  219. source: UM.Theme.images.logo;
  220. width: UM.Theme.sizes.logo.width;
  221. height: UM.Theme.sizes.logo.height;
  222. sourceSize.width: width;
  223. sourceSize.height: height;
  224. }
  225. Button {
  226. id: viewModeButton
  227. anchors {
  228. top: parent.top;
  229. right: sidebar.left;
  230. rightMargin: UM.Theme.sizes.window_margin.width;
  231. }
  232. //: View Mode toolbar button
  233. text: qsTr("View Mode");
  234. iconSource: UM.Theme.icons.viewmode;
  235. style: UM.Theme.styles.tool_button;
  236. tooltip: '';
  237. menu: Menu {
  238. id: viewMenu;
  239. Instantiator {
  240. model: UM.Models.viewModel;
  241. MenuItem {
  242. text: model.name;
  243. checkable: true;
  244. checked: model.active;
  245. exclusiveGroup: viewMenuGroup;
  246. onTriggered: UM.Controller.setActiveView(model.id);
  247. }
  248. onObjectAdded: viewMenu.insertItem(index, object)
  249. onObjectRemoved: viewMenu.removeItem(object)
  250. }
  251. ExclusiveGroup { id: viewMenuGroup; }
  252. }
  253. }
  254. Toolbar {
  255. id: toolbar;
  256. anchors {
  257. horizontalCenter: parent.horizontalCenter
  258. horizontalCenterOffset: -(UM.Theme.sizes.panel.width / 2)
  259. top: parent.top;
  260. }
  261. }
  262. Sidebar {
  263. id: sidebar;
  264. anchors {
  265. top: parent.top;
  266. bottom: parent.bottom;
  267. right: parent.right;
  268. }
  269. width: UM.Theme.sizes.panel.width;
  270. addMachineAction: actions.addMachine;
  271. configureMachinesAction: actions.configureMachines;
  272. }
  273. Rectangle {
  274. x: base.mouseX + UM.Theme.sizes.default_margin.width;
  275. y: base.mouseY + UM.Theme.sizes.default_margin.height;
  276. width: childrenRect.width;
  277. height: childrenRect.height;
  278. Label {
  279. text: UM.ActiveTool.properties.Rotation != undefined ? "%1°".arg(UM.ActiveTool.properties.Rotation) : "";
  280. }
  281. visible: UM.ActiveTool.valid && UM.ActiveTool.properties.Rotation != undefined;
  282. }
  283. }
  284. }
  285. UM.PreferencesDialog {
  286. id: preferences
  287. Component.onCompleted: {
  288. //; Remove & re-add the general page as we want to use our own instead of uranium standard.
  289. removePage(0);
  290. insertPage(0, qsTr("General") , "" , Qt.resolvedUrl("./GeneralPage.qml"));
  291. //: View preferences page title
  292. insertPage(1, qsTr("View"), "view-preview", Qt.resolvedUrl("./ViewPage.qml"));
  293. //Force refresh
  294. setPage(0)
  295. }
  296. }
  297. Actions {
  298. id: actions;
  299. open.onTriggered: openDialog.open();
  300. save.onTriggered: saveDialog.open();
  301. quit.onTriggered: base.visible = false;
  302. undo.onTriggered: UM.OperationStack.undo();
  303. undo.enabled: UM.OperationStack.canUndo;
  304. redo.onTriggered: UM.OperationStack.redo();
  305. redo.enabled: UM.OperationStack.canRedo;
  306. deleteSelection.onTriggered: {
  307. if(objectContextMenu.objectId != 0) {
  308. Printer.deleteObject(objectContextMenu.objectId);
  309. }
  310. }
  311. deleteObject.onTriggered: {
  312. if(objectContextMenu.objectId != 0) {
  313. Printer.deleteObject(objectContextMenu.objectId);
  314. objectContextMenu.objectId = 0;
  315. }
  316. }
  317. multiplyObject.onTriggered: {
  318. if(objectContextMenu.objectId != 0) {
  319. Printer.multiplyObject(objectContextMenu.objectId, 1);
  320. objectContextMenu.objectId = 0;
  321. }
  322. }
  323. centerObject.onTriggered: {
  324. if(objectContextMenu.objectId != 0) {
  325. Printer.centerObject(objectContextMenu.objectId);
  326. objectContextMenu.objectId = 0;
  327. }
  328. }
  329. groupObjects.onTriggered:
  330. {
  331. Printer.groupSelected()
  332. }
  333. unGroupObjects.onTriggered:
  334. {
  335. Printer.ungroupSelected()
  336. }
  337. mergeObjects.onTriggered:
  338. {
  339. Printer.mergeSelected()
  340. }
  341. deleteAll.onTriggered: Printer.deleteAll()
  342. resetAllTranslation.onTriggered: Printer.resetAllTranslation()
  343. resetAll.onTriggered: Printer.resetAll()
  344. reloadAll.onTriggered: Printer.reloadAll()
  345. addMachine.onTriggered: addMachineWizard.visible = true;
  346. preferences.onTriggered: preferences.visible = true;
  347. configureMachines.onTriggered: { preferences.visible = true; preferences.setPage(2); }
  348. documentation.onTriggered: CuraActions.openDocumentation();
  349. reportBug.onTriggered: CuraActions.openBugReportPage();
  350. showEngineLog.onTriggered: engineLog.visible = true;
  351. about.onTriggered: aboutDialog.visible = true;
  352. }
  353. Menu {
  354. id: objectContextMenu;
  355. property variant objectId: -1;
  356. MenuItem { action: actions.centerObject; }
  357. MenuItem { action: actions.deleteObject; }
  358. MenuItem { action: actions.multiplyObject; }
  359. MenuItem { action: actions.splitObject; }
  360. MenuSeparator { }
  361. MenuItem { action: actions.deleteAll; }
  362. MenuItem { action: actions.reloadAll; }
  363. MenuItem { action: actions.resetAllTranslation; }
  364. MenuItem { action: actions.resetAll; }
  365. MenuItem { action: actions.groupObjects;}
  366. MenuItem { action: actions.unGroupObjects;}
  367. MenuItem { action: actions.mergeObjects;}
  368. }
  369. Menu {
  370. id: contextMenu;
  371. MenuItem { action: actions.deleteAll; }
  372. MenuItem { action: actions.reloadAll; }
  373. MenuItem { action: actions.resetAllTranslation; }
  374. MenuItem { action: actions.resetAll; }
  375. MenuItem { action: actions.groupObjects;}
  376. MenuItem { action: actions.unGroupObjects;}
  377. MenuItem { action: actions.mergeObjects;}
  378. }
  379. Connections {
  380. target: UM.Controller
  381. onContextMenuRequested: {
  382. if(objectId == 0) {
  383. contextMenu.popup();
  384. } else {
  385. objectContextMenu.objectId = objectId;
  386. objectContextMenu.popup();
  387. }
  388. }
  389. }
  390. FileDialog {
  391. id: openDialog;
  392. //: File open dialog title
  393. title: qsTr("Open File")
  394. modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
  395. //TODO: Support multiple file selection, workaround bug in KDE file dialog
  396. //selectMultiple: true
  397. nameFilters: UM.MeshFileHandler.supportedReadFileTypes;
  398. onAccepted:
  399. {
  400. UM.MeshFileHandler.readLocalFile(fileUrl)
  401. }
  402. }
  403. EngineLog {
  404. id: engineLog;
  405. }
  406. AddMachineWizard {
  407. id: addMachineWizard
  408. }
  409. AboutDialog {
  410. id: aboutDialog
  411. }
  412. Connections {
  413. target: Printer
  414. onRequestAddPrinter: {
  415. addMachineWizard.visible = true
  416. addMachineWizard.printer = false
  417. }
  418. }
  419. Component.onCompleted: UM.Theme.load(UM.Resources.getPath(UM.Resources.ThemesLocation, "cura"))
  420. }