Cura.qml 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. // Copyright (c) 2017 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 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.3 as UM
  9. import Cura 1.0 as Cura
  10. import "Menus"
  11. UM.MainWindow
  12. {
  13. id: base
  14. //: Cura application window title
  15. title: catalog.i18nc("@title:window","Ultimaker Cura");
  16. viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0)
  17. property bool showPrintMonitor: false
  18. Connections
  19. {
  20. target: Printer
  21. onShowPrintMonitor: {
  22. if (show) {
  23. topbar.startMonitoringPrint()
  24. } else {
  25. topbar.stopMonitoringPrint()
  26. }
  27. }
  28. }
  29. Component.onCompleted:
  30. {
  31. CuraApplication.setMinimumWindowSize(UM.Theme.getSize("window_minimum_size"))
  32. // Workaround silly issues with QML Action's shortcut property.
  33. //
  34. // Currently, there is no way to define shortcuts as "Application Shortcut".
  35. // This means that all Actions are "Window Shortcuts". The code for this
  36. // implements a rather naive check that just checks if any of the action's parents
  37. // are a window. Since the "Actions" object is a singleton it has no parent by
  38. // default. If we set its parent to something contained in this window, the
  39. // shortcut will activate properly because one of its parents is a window.
  40. //
  41. // This has been fixed for QtQuick Controls 2 since the Shortcut item has a context property.
  42. Cura.Actions.parent = backgroundItem
  43. }
  44. Item
  45. {
  46. id: backgroundItem;
  47. anchors.fill: parent;
  48. UM.I18nCatalog{id: catalog; name:"cura"}
  49. signal hasMesh(string name) //this signal sends the filebase name so it can be used for the JobSpecs.qml
  50. function getMeshName(path){
  51. //takes the path the complete path of the meshname and returns only the filebase
  52. var fileName = path.slice(path.lastIndexOf("/") + 1)
  53. var fileBase = fileName.slice(0, fileName.indexOf("."))
  54. return fileBase
  55. }
  56. //DeleteSelection on the keypress backspace event
  57. Keys.onPressed: {
  58. if (event.key == Qt.Key_Backspace)
  59. {
  60. Cura.Actions.deleteSelection.trigger()
  61. }
  62. }
  63. UM.ApplicationMenu
  64. {
  65. id: menu
  66. window: base
  67. Menu
  68. {
  69. id: fileMenu
  70. title: catalog.i18nc("@title:menu menubar:toplevel","&File");
  71. MenuItem
  72. {
  73. action: Cura.Actions.newProject;
  74. }
  75. MenuItem
  76. {
  77. action: Cura.Actions.open;
  78. }
  79. RecentFilesMenu { }
  80. MenuSeparator { }
  81. MenuItem
  82. {
  83. text: catalog.i18nc("@action:inmenu menubar:file", "&Save Selection to File");
  84. enabled: UM.Selection.hasSelection;
  85. iconName: "document-save-as";
  86. onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetype": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"});
  87. }
  88. MenuItem
  89. {
  90. id: saveAsMenu
  91. text: catalog.i18nc("@title:menu menubar:file", "Save &As...")
  92. onTriggered:
  93. {
  94. var localDeviceId = "local_file";
  95. UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetype": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"});
  96. }
  97. }
  98. MenuItem
  99. {
  100. id: saveWorkspaceMenu
  101. text: catalog.i18nc("@title:menu menubar:file","Save project")
  102. onTriggered:
  103. {
  104. if(UM.Preferences.getValue("cura/dialog_on_project_save"))
  105. {
  106. saveWorkspaceDialog.open()
  107. }
  108. else
  109. {
  110. UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false, "file_type": "workspace" })
  111. }
  112. }
  113. }
  114. MenuItem { action: Cura.Actions.reloadAll; }
  115. MenuSeparator { }
  116. MenuItem { action: Cura.Actions.quit; }
  117. }
  118. Menu
  119. {
  120. title: catalog.i18nc("@title:menu menubar:toplevel","&Edit");
  121. MenuItem { action: Cura.Actions.undo; }
  122. MenuItem { action: Cura.Actions.redo; }
  123. MenuSeparator { }
  124. MenuItem { action: Cura.Actions.selectAll; }
  125. MenuItem { action: Cura.Actions.arrangeAll; }
  126. MenuItem { action: Cura.Actions.deleteSelection; }
  127. MenuItem { action: Cura.Actions.deleteAll; }
  128. MenuItem { action: Cura.Actions.resetAllTranslation; }
  129. MenuItem { action: Cura.Actions.resetAll; }
  130. MenuSeparator { }
  131. MenuItem { action: Cura.Actions.groupObjects;}
  132. MenuItem { action: Cura.Actions.mergeObjects;}
  133. MenuItem { action: Cura.Actions.unGroupObjects;}
  134. }
  135. ViewMenu { title: catalog.i18nc("@title:menu", "&View") }
  136. Menu
  137. {
  138. id: settingsMenu
  139. title: catalog.i18nc("@title:menu", "&Settings")
  140. PrinterMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&Printer") }
  141. Instantiator
  142. {
  143. model: Cura.ExtrudersModel { simpleNames: true }
  144. Menu {
  145. title: model.name
  146. visible: machineExtruderCount.properties.value > 1
  147. NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index }
  148. MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index }
  149. ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); }
  150. MenuSeparator { }
  151. MenuItem { text: catalog.i18nc("@action:inmenu", "Set as Active Extruder"); onTriggered: Cura.ExtruderManager.setActiveExtruderIndex(model.index) }
  152. }
  153. onObjectAdded: settingsMenu.insertItem(index, object)
  154. onObjectRemoved: settingsMenu.removeItem(object)
  155. }
  156. NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasVariants }
  157. MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasMaterials }
  158. ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); visible: machineExtruderCount.properties.value <= 1 }
  159. MenuSeparator { }
  160. MenuItem { action: Cura.Actions.configureSettingVisibility }
  161. }
  162. Menu
  163. {
  164. id: extension_menu
  165. title: catalog.i18nc("@title:menu menubar:toplevel","E&xtensions");
  166. Instantiator
  167. {
  168. id: extensions
  169. model: UM.ExtensionModel { }
  170. Menu
  171. {
  172. id: sub_menu
  173. title: model.name;
  174. visible: actions != null
  175. enabled: actions != null
  176. Instantiator
  177. {
  178. model: actions
  179. MenuItem
  180. {
  181. text: model.text
  182. onTriggered: extensions.model.subMenuTriggered(name, model.text)
  183. }
  184. onObjectAdded: sub_menu.insertItem(index, object)
  185. onObjectRemoved: sub_menu.removeItem(object)
  186. }
  187. }
  188. onObjectAdded: extension_menu.insertItem(index, object)
  189. onObjectRemoved: extension_menu.removeItem(object)
  190. }
  191. }
  192. Menu
  193. {
  194. id: plugin_menu
  195. title: catalog.i18nc("@title:menu menubar:toplevel", "P&lugins")
  196. MenuItem { action: Cura.Actions.browsePlugins }
  197. MenuItem { action: Cura.Actions.configurePlugins }
  198. }
  199. Menu
  200. {
  201. title: catalog.i18nc("@title:menu menubar:toplevel","P&references");
  202. MenuItem { action: Cura.Actions.preferences; }
  203. }
  204. Menu
  205. {
  206. //: Help menu
  207. title: catalog.i18nc("@title:menu menubar:toplevel","&Help");
  208. MenuItem { action: Cura.Actions.showProfileFolder; }
  209. MenuItem { action: Cura.Actions.documentation; }
  210. MenuItem { action: Cura.Actions.reportBug; }
  211. MenuSeparator { }
  212. MenuItem { action: Cura.Actions.about; }
  213. }
  214. }
  215. UM.SettingPropertyProvider
  216. {
  217. id: machineExtruderCount
  218. containerStackId: Cura.MachineManager.activeMachineId
  219. key: "machine_extruder_count"
  220. watchedProperties: [ "value" ]
  221. storeIndex: 0
  222. }
  223. Item
  224. {
  225. id: contentItem;
  226. y: menu.height
  227. width: parent.width;
  228. height: parent.height - menu.height;
  229. Keys.forwardTo: menu
  230. DropArea
  231. {
  232. anchors.fill: parent;
  233. onDropped:
  234. {
  235. if (drop.urls.length > 0)
  236. {
  237. // As the drop area also supports plugins, first check if it's a plugin that was dropped.
  238. if (drop.urls.length == 1)
  239. {
  240. if (PluginRegistry.isPluginFile(drop.urls[0]))
  241. {
  242. // Try to install plugin & close.
  243. var result = PluginRegistry.installPlugin(drop.urls[0]);
  244. pluginInstallDialog.text = result.message;
  245. if (result.status == "ok")
  246. {
  247. pluginInstallDialog.icon = StandardIcon.Information;
  248. }
  249. else if (result.status == "duplicate")
  250. {
  251. pluginInstallDialog.icon = StandardIcon.Warning;
  252. }
  253. else
  254. {
  255. pluginInstallDialog.icon = StandardIcon.Critical;
  256. }
  257. pluginInstallDialog.open();
  258. return;
  259. }
  260. }
  261. openDialog.handleOpenFileUrls(drop.urls);
  262. }
  263. }
  264. }
  265. JobSpecs
  266. {
  267. id: jobSpecs
  268. anchors
  269. {
  270. bottom: parent.bottom;
  271. right: sidebar.left;
  272. bottomMargin: UM.Theme.getSize("default_margin").height;
  273. rightMargin: UM.Theme.getSize("default_margin").width;
  274. }
  275. }
  276. Button
  277. {
  278. id: openFileButton;
  279. text: catalog.i18nc("@action:button","Open File");
  280. iconSource: UM.Theme.getIcon("load")
  281. style: UM.Theme.styles.tool_button
  282. tooltip: '';
  283. anchors
  284. {
  285. top: topbar.bottom;
  286. topMargin: UM.Theme.getSize("default_margin").height;
  287. left: parent.left;
  288. }
  289. action: Cura.Actions.open;
  290. }
  291. Toolbar
  292. {
  293. id: toolbar;
  294. property int mouseX: base.mouseX
  295. property int mouseY: base.mouseY
  296. anchors {
  297. top: openFileButton.bottom;
  298. topMargin: UM.Theme.getSize("window_margin").height;
  299. left: parent.left;
  300. }
  301. }
  302. Topbar
  303. {
  304. id: topbar
  305. anchors.left:parent.left
  306. anchors.right: parent.right
  307. anchors.top: parent.top
  308. monitoringPrint: base.showPrintMonitor
  309. onStartMonitoringPrint: base.showPrintMonitor = true
  310. onStopMonitoringPrint: base.showPrintMonitor = false
  311. }
  312. Sidebar
  313. {
  314. id: sidebar;
  315. anchors
  316. {
  317. top: topbar.bottom;
  318. bottom: parent.bottom;
  319. right: parent.right;
  320. }
  321. z: 1
  322. width: UM.Theme.getSize("sidebar").width;
  323. monitoringPrint: base.showPrintMonitor
  324. }
  325. Rectangle
  326. {
  327. id: viewportOverlay
  328. color: UM.Theme.getColor("viewport_overlay")
  329. anchors
  330. {
  331. top: topbar.bottom
  332. bottom: parent.bottom
  333. left:parent.left
  334. right: sidebar.left
  335. }
  336. visible: opacity > 0
  337. opacity: base.showPrintMonitor ? 1 : 0
  338. MouseArea {
  339. anchors.fill: parent
  340. acceptedButtons: Qt.AllButtons
  341. onWheel: wheel.accepted = true
  342. }
  343. }
  344. Loader
  345. {
  346. sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null
  347. visible: base.showPrintMonitor
  348. anchors.horizontalCenter: parent.horizontalCenter
  349. anchors.verticalCenter: parent.verticalCenter
  350. anchors.horizontalCenterOffset: - UM.Theme.getSize("sidebar").width / 2
  351. anchors.verticalCenterOffset: UM.Theme.getSize("sidebar_header").height / 2
  352. property real maximumWidth: viewportOverlay.width
  353. property real maximumHeight: viewportOverlay.height
  354. }
  355. UM.MessageStack
  356. {
  357. anchors
  358. {
  359. horizontalCenter: parent.horizontalCenter
  360. horizontalCenterOffset: -(UM.Theme.getSize("sidebar").width/ 2)
  361. top: parent.verticalCenter;
  362. bottom: parent.bottom;
  363. }
  364. }
  365. }
  366. }
  367. UM.PreferencesDialog
  368. {
  369. id: preferences
  370. Component.onCompleted:
  371. {
  372. //; Remove & re-add the general page as we want to use our own instead of uranium standard.
  373. removePage(0);
  374. insertPage(0, catalog.i18nc("@title:tab","General"), Qt.resolvedUrl("Preferences/GeneralPage.qml"));
  375. removePage(1);
  376. insertPage(1, catalog.i18nc("@title:tab","Settings"), Qt.resolvedUrl("Preferences/SettingVisibilityPage.qml"));
  377. insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("Preferences/MachinesPage.qml"));
  378. insertPage(3, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml"));
  379. insertPage(4, catalog.i18nc("@title:tab", "Profiles"), Qt.resolvedUrl("Preferences/ProfilesPage.qml"));
  380. //Force refresh
  381. setPage(0);
  382. }
  383. onVisibleChanged:
  384. {
  385. // When the dialog closes, switch to the General page.
  386. // This prevents us from having a heavy page like Setting Visiblity active in the background.
  387. setPage(0);
  388. }
  389. }
  390. WorkspaceSummaryDialog
  391. {
  392. id: saveWorkspaceDialog
  393. onYes: UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false, "file_type": "workspace" })
  394. }
  395. Connections
  396. {
  397. target: Cura.Actions.preferences
  398. onTriggered: preferences.visible = true
  399. }
  400. MessageDialog
  401. {
  402. id: newProjectDialog
  403. modality: Qt.ApplicationModal
  404. title: catalog.i18nc("@title:window", "New project")
  405. text: catalog.i18nc("@info:question", "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings.")
  406. standardButtons: StandardButton.Yes | StandardButton.No
  407. icon: StandardIcon.Question
  408. onYes:
  409. {
  410. CuraApplication.deleteAll();
  411. Cura.Actions.resetProfile.trigger();
  412. }
  413. }
  414. Connections
  415. {
  416. target: Cura.Actions.newProject
  417. onTriggered:
  418. {
  419. if(Printer.platformActivity || Cura.MachineManager.hasUserSettings)
  420. {
  421. newProjectDialog.visible = true
  422. }
  423. }
  424. }
  425. Connections
  426. {
  427. target: Cura.Actions.addProfile
  428. onTriggered:
  429. {
  430. preferences.show();
  431. preferences.setPage(4);
  432. // Create a new profile after a very short delay so the preference page has time to initiate
  433. createProfileTimer.start();
  434. }
  435. }
  436. Connections
  437. {
  438. target: Cura.Actions.configureMachines
  439. onTriggered:
  440. {
  441. preferences.visible = true;
  442. preferences.setPage(2);
  443. }
  444. }
  445. Connections
  446. {
  447. target: Cura.Actions.manageProfiles
  448. onTriggered:
  449. {
  450. preferences.visible = true;
  451. preferences.setPage(4);
  452. }
  453. }
  454. Connections
  455. {
  456. target: Cura.Actions.manageMaterials
  457. onTriggered:
  458. {
  459. preferences.visible = true;
  460. preferences.setPage(3)
  461. }
  462. }
  463. Connections
  464. {
  465. target: Cura.Actions.configureSettingVisibility
  466. onTriggered:
  467. {
  468. preferences.visible = true;
  469. preferences.setPage(1);
  470. preferences.getCurrentItem().scrollToSection(source.key);
  471. }
  472. }
  473. // show the installed plugins page in the preferences dialog
  474. Connections
  475. {
  476. target: Cura.Actions.configurePlugins
  477. onTriggered:
  478. {
  479. preferences.visible = true
  480. preferences.setPage(5)
  481. }
  482. }
  483. UM.ExtensionModel {
  484. id: curaExtensions
  485. }
  486. // show the plugin browser dialog
  487. Connections
  488. {
  489. target: Cura.Actions.browsePlugins
  490. onTriggered: {
  491. curaExtensions.callExtensionMethod("Plugin Browser", "browsePlugins")
  492. }
  493. }
  494. Timer
  495. {
  496. id: createProfileTimer
  497. repeat: false
  498. interval: 1
  499. onTriggered: preferences.getCurrentItem().createProfile()
  500. }
  501. // BlurSettings is a way to force the focus away from any of the setting items.
  502. // We need to do this in order to keep the bindings intact.
  503. Connections
  504. {
  505. target: Cura.MachineManager
  506. onBlurSettings:
  507. {
  508. contentItem.forceActiveFocus()
  509. }
  510. }
  511. ContextMenu {
  512. id: contextMenu
  513. }
  514. Connections
  515. {
  516. target: Cura.Actions.quit
  517. onTriggered: CuraApplication.closeApplication();
  518. }
  519. Connections
  520. {
  521. target: Cura.Actions.toggleFullScreen
  522. onTriggered: base.toggleFullscreen();
  523. }
  524. FileDialog
  525. {
  526. id: openDialog;
  527. //: File open dialog title
  528. title: catalog.i18nc("@title:window","Open file(s)")
  529. modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
  530. selectMultiple: true
  531. nameFilters: UM.MeshFileHandler.supportedReadFileTypes;
  532. folder: CuraApplication.getDefaultPath("dialog_load_path")
  533. onAccepted:
  534. {
  535. // Because several implementations of the file dialog only update the folder
  536. // when it is explicitly set.
  537. var f = folder;
  538. folder = f;
  539. CuraApplication.setDefaultPath("dialog_load_path", folder);
  540. handleOpenFileUrls(fileUrls);
  541. }
  542. // Yeah... I know... it is a mess to put all those things here.
  543. // There are lots of user interactions in this part of the logic, such as showing a warning dialog here and there,
  544. // etc. This means it will come back and forth from time to time between QML and Python. So, separating the logic
  545. // and view here may require more effort but make things more difficult to understand.
  546. function handleOpenFileUrls(fileUrlList)
  547. {
  548. // look for valid project files
  549. var projectFileUrlList = [];
  550. var hasGcode = false;
  551. var nonGcodeFileList = [];
  552. for (var i in fileUrlList)
  553. {
  554. var endsWithG = /\.g$/;
  555. var endsWithGcode = /\.gcode$/;
  556. if (endsWithG.test(fileUrlList[i]) || endsWithGcode.test(fileUrlList[i]))
  557. {
  558. continue;
  559. }
  560. else if (CuraApplication.checkIsValidProjectFile(fileUrlList[i]))
  561. {
  562. projectFileUrlList.push(fileUrlList[i]);
  563. }
  564. nonGcodeFileList.push(fileUrlList[i]);
  565. }
  566. hasGcode = nonGcodeFileList.length < fileUrlList.length;
  567. // show a warning if selected multiple files together with Gcode
  568. var hasProjectFile = projectFileUrlList.length > 0;
  569. var selectedMultipleFiles = fileUrlList.length > 1;
  570. if (selectedMultipleFiles && hasGcode)
  571. {
  572. infoMultipleFilesWithGcodeDialog.selectedMultipleFiles = selectedMultipleFiles;
  573. infoMultipleFilesWithGcodeDialog.hasProjectFile = hasProjectFile;
  574. infoMultipleFilesWithGcodeDialog.fileUrls = nonGcodeFileList.slice();
  575. infoMultipleFilesWithGcodeDialog.projectFileUrlList = projectFileUrlList.slice();
  576. infoMultipleFilesWithGcodeDialog.open();
  577. }
  578. else
  579. {
  580. handleOpenFiles(selectedMultipleFiles, hasProjectFile, fileUrlList, projectFileUrlList);
  581. }
  582. }
  583. function handleOpenFiles(selectedMultipleFiles, hasProjectFile, fileUrlList, projectFileUrlList)
  584. {
  585. // we only allow opening one project file
  586. if (selectedMultipleFiles && hasProjectFile)
  587. {
  588. openFilesIncludingProjectsDialog.fileUrls = fileUrlList.slice();
  589. openFilesIncludingProjectsDialog.show();
  590. return;
  591. }
  592. if (hasProjectFile)
  593. {
  594. var projectFile = projectFileUrlList[0];
  595. // check preference
  596. var choice = UM.Preferences.getValue("cura/choice_on_open_project");
  597. if (choice == "open_as_project")
  598. {
  599. openFilesIncludingProjectsDialog.loadProjectFile(projectFile);
  600. }
  601. else if (choice == "open_as_model")
  602. {
  603. openFilesIncludingProjectsDialog.loadModelFiles([projectFile].slice());
  604. }
  605. else // always ask
  606. {
  607. // ask whether to open as project or as models
  608. askOpenAsProjectOrModelsDialog.fileUrl = projectFile;
  609. askOpenAsProjectOrModelsDialog.show();
  610. }
  611. }
  612. else
  613. {
  614. openFilesIncludingProjectsDialog.loadModelFiles(fileUrlList.slice());
  615. }
  616. }
  617. }
  618. MessageDialog
  619. {
  620. id: pluginInstallDialog
  621. title: catalog.i18nc("@window:title", "Install Plugin");
  622. standardButtons: StandardButton.Ok
  623. modality: Qt.ApplicationModal
  624. }
  625. MessageDialog {
  626. id: infoMultipleFilesWithGcodeDialog
  627. title: catalog.i18nc("@title:window", "Open File(s)")
  628. icon: StandardIcon.Information
  629. standardButtons: StandardButton.Ok
  630. text: catalog.i18nc("@text:window", "We have found one or more G-Code files within the files you have selected. You can only open one G-Code file at a time. If you want to open a G-Code file, please just select only one.")
  631. property var selectedMultipleFiles
  632. property var hasProjectFile
  633. property var fileUrls
  634. property var projectFileUrlList
  635. onAccepted:
  636. {
  637. openDialog.handleOpenFiles(selectedMultipleFiles, hasProjectFile, fileUrls, projectFileUrlList);
  638. }
  639. }
  640. Connections
  641. {
  642. target: Cura.Actions.open
  643. onTriggered: openDialog.open()
  644. }
  645. OpenFilesIncludingProjectsDialog
  646. {
  647. id: openFilesIncludingProjectsDialog
  648. }
  649. AskOpenAsProjectOrModelsDialog
  650. {
  651. id: askOpenAsProjectOrModelsDialog
  652. }
  653. EngineLog
  654. {
  655. id: engineLog;
  656. }
  657. Connections
  658. {
  659. target: Cura.Actions.showProfileFolder
  660. onTriggered:
  661. {
  662. var path = UM.Resources.getPath(UM.Resources.Preferences, "");
  663. if(Qt.platform.os == "windows") {
  664. path = path.replace(/\\/g,"/");
  665. }
  666. Qt.openUrlExternally(path);
  667. }
  668. }
  669. AddMachineDialog
  670. {
  671. id: addMachineDialog
  672. onMachineAdded:
  673. {
  674. machineActionsWizard.firstRun = addMachineDialog.firstRun
  675. machineActionsWizard.start(id)
  676. }
  677. }
  678. // Dialog to handle first run machine actions
  679. UM.Wizard
  680. {
  681. id: machineActionsWizard;
  682. title: catalog.i18nc("@title:window", "Add Printer")
  683. property var machine;
  684. function start(id)
  685. {
  686. var actions = Cura.MachineActionManager.getFirstStartActions(id)
  687. resetPages() // Remove previous pages
  688. for (var i = 0; i < actions.length; i++)
  689. {
  690. actions[i].displayItem.reset()
  691. machineActionsWizard.appendPage(actions[i].displayItem, catalog.i18nc("@title", actions[i].label));
  692. }
  693. //Only start if there are actions to perform.
  694. if (actions.length > 0)
  695. {
  696. machineActionsWizard.currentPage = 0;
  697. show()
  698. }
  699. }
  700. }
  701. MessageDialog
  702. {
  703. id: messageDialog
  704. modality: Qt.ApplicationModal
  705. onAccepted: CuraApplication.messageBoxClosed(clickedButton)
  706. onApply: CuraApplication.messageBoxClosed(clickedButton)
  707. onDiscard: CuraApplication.messageBoxClosed(clickedButton)
  708. onHelp: CuraApplication.messageBoxClosed(clickedButton)
  709. onNo: CuraApplication.messageBoxClosed(clickedButton)
  710. onRejected: CuraApplication.messageBoxClosed(clickedButton)
  711. onReset: CuraApplication.messageBoxClosed(clickedButton)
  712. onYes: CuraApplication.messageBoxClosed(clickedButton)
  713. }
  714. Connections
  715. {
  716. target: Printer
  717. onShowMessageBox:
  718. {
  719. messageDialog.title = title
  720. messageDialog.text = text
  721. messageDialog.informativeText = informativeText
  722. messageDialog.detailedText = detailedText
  723. messageDialog.standardButtons = buttons
  724. messageDialog.icon = icon
  725. messageDialog.visible = true
  726. }
  727. }
  728. DiscardOrKeepProfileChangesDialog
  729. {
  730. id: discardOrKeepProfileChangesDialog
  731. }
  732. Connections
  733. {
  734. target: CuraApplication
  735. onShowDiscardOrKeepProfileChanges:
  736. {
  737. discardOrKeepProfileChangesDialog.show()
  738. }
  739. }
  740. Connections
  741. {
  742. target: Cura.Actions.addMachine
  743. onTriggered: addMachineDialog.visible = true;
  744. }
  745. AboutDialog
  746. {
  747. id: aboutDialog
  748. }
  749. Connections
  750. {
  751. target: Cura.Actions.about
  752. onTriggered: aboutDialog.visible = true;
  753. }
  754. Connections
  755. {
  756. target: Printer
  757. onRequestAddPrinter:
  758. {
  759. addMachineDialog.visible = true
  760. addMachineDialog.firstRun = false
  761. }
  762. }
  763. Timer
  764. {
  765. id: startupTimer;
  766. interval: 100;
  767. repeat: false;
  768. running: true;
  769. onTriggered:
  770. {
  771. if(!base.visible)
  772. {
  773. base.visible = true;
  774. }
  775. // check later if the user agreement dialog has been closed
  776. if (CuraApplication.needToShowUserAgreement)
  777. {
  778. restart();
  779. }
  780. else if(Cura.MachineManager.activeMachineId == null || Cura.MachineManager.activeMachineId == "")
  781. {
  782. addMachineDialog.open();
  783. }
  784. }
  785. }
  786. }