Cura.qml 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  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.2 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","Cura");
  16. viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0)
  17. property bool monitoringPrint: false
  18. Component.onCompleted:
  19. {
  20. Printer.setMinimumWindowSize(UM.Theme.getSize("window_minimum_size"))
  21. // Workaround silly issues with QML Action's shortcut property.
  22. //
  23. // Currently, there is no way to define shortcuts as "Application Shortcut".
  24. // This means that all Actions are "Window Shortcuts". The code for this
  25. // implements a rather naive check that just checks if any of the action's parents
  26. // are a window. Since the "Actions" object is a singleton it has no parent by
  27. // default. If we set its parent to something contained in this window, the
  28. // shortcut will activate properly because one of its parents is a window.
  29. //
  30. // This has been fixed for QtQuick Controls 2 since the Shortcut item has a context property.
  31. Cura.Actions.parent = backgroundItem
  32. }
  33. Item
  34. {
  35. id: backgroundItem;
  36. anchors.fill: parent;
  37. UM.I18nCatalog{id: catalog; name:"cura"}
  38. signal hasMesh(string name) //this signal sends the filebase name so it can be used for the JobSpecs.qml
  39. function getMeshName(path){
  40. //takes the path the complete path of the meshname and returns only the filebase
  41. var fileName = path.slice(path.lastIndexOf("/") + 1)
  42. var fileBase = fileName.slice(0, fileName.lastIndexOf("."))
  43. return fileBase
  44. }
  45. //DeleteSelection on the keypress backspace event
  46. Keys.onPressed: {
  47. if (event.key == Qt.Key_Backspace)
  48. {
  49. Cura.Actions.deleteSelection.trigger()
  50. }
  51. }
  52. UM.ApplicationMenu
  53. {
  54. id: menu
  55. window: base
  56. Menu
  57. {
  58. id: fileMenu
  59. title: catalog.i18nc("@title:menu menubar:toplevel","&File");
  60. MenuItem {
  61. action: Cura.Actions.open;
  62. }
  63. RecentFilesMenu { }
  64. MenuSeparator { }
  65. MenuItem
  66. {
  67. text: catalog.i18nc("@action:inmenu menubar:file", "&Save Selection to File");
  68. enabled: UM.Selection.hasSelection;
  69. iconName: "document-save-as";
  70. onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false });
  71. }
  72. Menu
  73. {
  74. id: saveAllMenu
  75. title: catalog.i18nc("@title:menu menubar:file","Save &All")
  76. iconName: "document-save-all";
  77. enabled: devicesModel.rowCount() > 0 && UM.Backend.progress > 0.99;
  78. Instantiator
  79. {
  80. model: UM.OutputDevicesModel { id: devicesModel; }
  81. MenuItem
  82. {
  83. text: model.description;
  84. onTriggered: UM.OutputDeviceManager.requestWriteToDevice(model.id, PrintInformation.jobName, { "filter_by_machine": false });
  85. }
  86. onObjectAdded: saveAllMenu.insertItem(index, object)
  87. onObjectRemoved: saveAllMenu.removeItem(object)
  88. }
  89. }
  90. MenuItem { action: Cura.Actions.reloadAll; }
  91. MenuSeparator { }
  92. MenuItem { action: Cura.Actions.quit; }
  93. }
  94. Menu
  95. {
  96. title: catalog.i18nc("@title:menu menubar:toplevel","&Edit");
  97. MenuItem { action: Cura.Actions.undo; }
  98. MenuItem { action: Cura.Actions.redo; }
  99. MenuSeparator { }
  100. MenuItem { action: Cura.Actions.selectAll; }
  101. MenuItem { action: Cura.Actions.deleteSelection; }
  102. MenuItem { action: Cura.Actions.deleteAll; }
  103. MenuItem { action: Cura.Actions.resetAllTranslation; }
  104. MenuItem { action: Cura.Actions.resetAll; }
  105. MenuSeparator { }
  106. MenuItem { action: Cura.Actions.groupObjects;}
  107. MenuItem { action: Cura.Actions.mergeObjects;}
  108. MenuItem { action: Cura.Actions.unGroupObjects;}
  109. }
  110. ViewMenu { title: catalog.i18nc("@title:menu", "&View") }
  111. Menu
  112. {
  113. id: settingsMenu
  114. title: catalog.i18nc("@title:menu", "&Settings")
  115. PrinterMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&Printer") }
  116. Instantiator
  117. {
  118. model: Cura.ExtrudersModel { }
  119. Menu {
  120. title: model.name
  121. NozzleMenu { title: catalog.i18nc("@title:menu", "&Nozzle"); visible: Cura.MachineManager.hasVariants }
  122. MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials }
  123. ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); }
  124. MenuSeparator { }
  125. MenuItem { text: "Set as Active Extruder" }
  126. }
  127. onObjectAdded: settingsMenu.insertItem(index, object)
  128. onObjectRemoved: settingsMenu.removeItem(object)
  129. }
  130. NozzleMenu { title: catalog.i18nc("@title:menu", "&Nozzle"); visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasVariants }
  131. MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasMaterials }
  132. ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); visible: machineExtruderCount.properties.value <= 1 }
  133. MenuSeparator { }
  134. MenuItem { action: Cura.Actions.configureSettingVisibility }
  135. }
  136. Menu
  137. {
  138. id: extension_menu
  139. title: catalog.i18nc("@title:menu menubar:toplevel","E&xtensions");
  140. Instantiator
  141. {
  142. id: extensions
  143. model: UM.ExtensionModel { }
  144. Menu
  145. {
  146. id: sub_menu
  147. title: model.name;
  148. visible: actions != null
  149. enabled:actions != null
  150. Instantiator
  151. {
  152. model: actions
  153. MenuItem
  154. {
  155. text: model.text
  156. onTriggered: extensions.model.subMenuTriggered(name, model.text)
  157. }
  158. onObjectAdded: sub_menu.insertItem(index, object)
  159. onObjectRemoved: sub_menu.removeItem(object)
  160. }
  161. }
  162. onObjectAdded: extension_menu.insertItem(index, object)
  163. onObjectRemoved: extension_menu.removeItem(object)
  164. }
  165. }
  166. Menu
  167. {
  168. title: catalog.i18nc("@title:menu menubar:toplevel","P&references");
  169. MenuItem { action: Cura.Actions.preferences; }
  170. }
  171. Menu
  172. {
  173. //: Help menu
  174. title: catalog.i18nc("@title:menu menubar:toplevel","&Help");
  175. MenuItem { action: Cura.Actions.showEngineLog; }
  176. MenuItem { action: Cura.Actions.documentation; }
  177. MenuItem { action: Cura.Actions.reportBug; }
  178. MenuSeparator { }
  179. MenuItem { action: Cura.Actions.about; }
  180. }
  181. }
  182. UM.SettingPropertyProvider
  183. {
  184. id: machineExtruderCount
  185. containerStackId: Cura.MachineManager.activeMachineId
  186. key: "machine_extruder_count"
  187. watchedProperties: [ "value" ]
  188. storeIndex: 0
  189. }
  190. Item
  191. {
  192. id: contentItem;
  193. y: menu.height
  194. width: parent.width;
  195. height: parent.height - menu.height;
  196. Keys.forwardTo: menu
  197. DropArea
  198. {
  199. anchors.fill: parent;
  200. onDropped:
  201. {
  202. if(drop.urls.length > 0)
  203. {
  204. for(var i in drop.urls)
  205. {
  206. UM.MeshFileHandler.readLocalFile(drop.urls[i]);
  207. if (i == drop.urls.length - 1)
  208. {
  209. var meshName = backgroundItem.getMeshName(drop.urls[i].toString())
  210. backgroundItem.hasMesh(decodeURIComponent(meshName))
  211. }
  212. }
  213. }
  214. }
  215. }
  216. JobSpecs
  217. {
  218. id: jobSpecs
  219. anchors
  220. {
  221. bottom: parent.bottom;
  222. right: sidebar.left;
  223. bottomMargin: UM.Theme.getSize("default_margin").height;
  224. rightMargin: UM.Theme.getSize("default_margin").width;
  225. }
  226. }
  227. Loader
  228. {
  229. id: view_panel
  230. anchors.top: viewModeButton.bottom
  231. anchors.topMargin: UM.Theme.getSize("default_margin").height;
  232. anchors.left: viewModeButton.left;
  233. height: childrenRect.height;
  234. source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "";
  235. }
  236. Button
  237. {
  238. id: openFileButton;
  239. text: catalog.i18nc("@action:button","Open File");
  240. iconSource: UM.Theme.getIcon("load")
  241. style: UM.Theme.styles.tool_button
  242. tooltip: '';
  243. anchors
  244. {
  245. top: parent.top;
  246. left: parent.left;
  247. }
  248. action: Cura.Actions.open;
  249. }
  250. Image
  251. {
  252. id: logo
  253. anchors
  254. {
  255. left: parent.left
  256. leftMargin: UM.Theme.getSize("default_margin").width;
  257. bottom: parent.bottom
  258. bottomMargin: UM.Theme.getSize("default_margin").height;
  259. }
  260. source: UM.Theme.getImage("logo");
  261. width: UM.Theme.getSize("logo").width;
  262. height: UM.Theme.getSize("logo").height;
  263. z: -1;
  264. sourceSize.width: width;
  265. sourceSize.height: height;
  266. }
  267. Toolbar
  268. {
  269. id: toolbar;
  270. property int mouseX: base.mouseX
  271. property int mouseY: base.mouseY
  272. anchors {
  273. top: openFileButton.bottom;
  274. topMargin: UM.Theme.getSize("window_margin").height;
  275. left: parent.left;
  276. }
  277. }
  278. Sidebar
  279. {
  280. id: sidebar;
  281. anchors
  282. {
  283. top: parent.top;
  284. bottom: parent.bottom;
  285. right: parent.right;
  286. }
  287. onMonitoringPrintChanged: base.monitoringPrint = monitoringPrint
  288. width: UM.Theme.getSize("sidebar").width;
  289. }
  290. Button
  291. {
  292. id: viewModeButton
  293. anchors
  294. {
  295. top: toolbar.bottom;
  296. topMargin: UM.Theme.getSize("window_margin").height;
  297. left: parent.left;
  298. }
  299. text: catalog.i18nc("@action:button","View Mode");
  300. iconSource: UM.Theme.getIcon("viewmode");
  301. style: UM.Theme.styles.tool_button;
  302. tooltip: '';
  303. menu: ViewMenu { }
  304. }
  305. Rectangle
  306. {
  307. id: viewportOverlay
  308. color: UM.Theme.getColor("viewport_overlay")
  309. anchors
  310. {
  311. top: parent.top
  312. bottom: parent.bottom
  313. left:parent.left
  314. right: sidebar.left
  315. }
  316. visible: opacity > 0
  317. opacity: base.monitoringPrint ? 0.75 : 0
  318. Behavior on opacity { NumberAnimation { duration: 100; } }
  319. MouseArea {
  320. anchors.fill: parent
  321. acceptedButtons: Qt.AllButtons
  322. onWheel: wheel.accepted = true
  323. }
  324. }
  325. Image
  326. {
  327. id: cameraImage
  328. width: Math.min(viewportOverlay.width, sourceSize.width)
  329. height: sourceSize.height * width / sourceSize.width
  330. anchors.horizontalCenter: parent.horizontalCenter
  331. anchors.verticalCenter: parent.verticalCenter
  332. anchors.horizontalCenterOffset: - UM.Theme.getSize("sidebar").width / 2
  333. visible: base.monitoringPrint
  334. source: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].cameraImage : ""
  335. }
  336. UM.MessageStack
  337. {
  338. anchors
  339. {
  340. horizontalCenter: parent.horizontalCenter
  341. horizontalCenterOffset: -(UM.Theme.getSize("sidebar").width/ 2)
  342. top: parent.verticalCenter;
  343. bottom: parent.bottom;
  344. }
  345. }
  346. }
  347. }
  348. UM.PreferencesDialog
  349. {
  350. id: preferences
  351. Component.onCompleted:
  352. {
  353. //; Remove & re-add the general page as we want to use our own instead of uranium standard.
  354. removePage(0);
  355. insertPage(0, catalog.i18nc("@title:tab","General"), Qt.resolvedUrl("Preferences/GeneralPage.qml"));
  356. insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("Preferences/MachinesPage.qml"));
  357. insertPage(3, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml"));
  358. insertPage(4, catalog.i18nc("@title:tab", "Profiles"), Qt.resolvedUrl("Preferences/ProfilesPage.qml"));
  359. //Force refresh
  360. setPage(0);
  361. }
  362. onVisibleChanged:
  363. {
  364. if(!visible)
  365. {
  366. // When the dialog closes, switch to the General page.
  367. // This prevents us from having a heavy page like Setting Visiblity active in the background.
  368. setPage(0);
  369. }
  370. }
  371. }
  372. Connections
  373. {
  374. target: Cura.Actions.preferences
  375. onTriggered: preferences.visible = true
  376. }
  377. Connections
  378. {
  379. target: Cura.Actions.addProfile
  380. onTriggered:
  381. {
  382. Cura.MachineManager.newQualityContainerFromQualityAndUser();
  383. preferences.setPage(4);
  384. preferences.show();
  385. // Show the renameDialog after a very short delay so the preference page has time to initiate
  386. showProfileNameDialogTimer.start();
  387. }
  388. }
  389. Connections
  390. {
  391. target: Cura.Actions.configureMachines
  392. onTriggered:
  393. {
  394. preferences.visible = true;
  395. preferences.setPage(2);
  396. }
  397. }
  398. Connections
  399. {
  400. target: Cura.Actions.manageProfiles
  401. onTriggered:
  402. {
  403. preferences.visible = true;
  404. preferences.setPage(4);
  405. }
  406. }
  407. Connections
  408. {
  409. target: Cura.Actions.manageMaterials
  410. onTriggered:
  411. {
  412. preferences.visible = true;
  413. preferences.setPage(3)
  414. }
  415. }
  416. Connections
  417. {
  418. target: Cura.Actions.configureSettingVisibility
  419. onTriggered:
  420. {
  421. preferences.visible = true;
  422. preferences.setPage(1);
  423. preferences.getCurrentItem().scrollToSection(source.key);
  424. }
  425. }
  426. Timer
  427. {
  428. id: showProfileNameDialogTimer
  429. repeat: false
  430. interval: 1
  431. onTriggered: preferences.getCurrentItem().showProfileNameDialog()
  432. }
  433. // BlurSettings is a way to force the focus away from any of the setting items.
  434. // We need to do this in order to keep the bindings intact.
  435. Connections
  436. {
  437. target: Cura.MachineManager
  438. onBlurSettings:
  439. {
  440. contentItem.focus = true
  441. }
  442. }
  443. Menu
  444. {
  445. id: objectContextMenu;
  446. property variant objectId: -1;
  447. MenuItem { action: Cura.Actions.centerObject; }
  448. MenuItem { action: Cura.Actions.deleteObject; }
  449. MenuItem { action: Cura.Actions.multiplyObject; }
  450. MenuSeparator { }
  451. MenuItem { action: Cura.Actions.selectAll; }
  452. MenuItem { action: Cura.Actions.deleteAll; }
  453. MenuItem { action: Cura.Actions.reloadAll; }
  454. MenuItem { action: Cura.Actions.resetAllTranslation; }
  455. MenuItem { action: Cura.Actions.resetAll; }
  456. MenuSeparator { }
  457. MenuItem { action: Cura.Actions.groupObjects; }
  458. MenuItem { action: Cura.Actions.mergeObjects; }
  459. MenuItem { action: Cura.Actions.unGroupObjects; }
  460. Connections
  461. {
  462. target: Cura.Actions.deleteObject
  463. onTriggered:
  464. {
  465. if(objectContextMenu.objectId != 0)
  466. {
  467. Printer.deleteObject(objectContextMenu.objectId);
  468. objectContextMenu.objectId = 0;
  469. }
  470. }
  471. }
  472. Connections
  473. {
  474. target: Cura.Actions.multiplyObject
  475. onTriggered:
  476. {
  477. if(objectContextMenu.objectId != 0)
  478. {
  479. Printer.multiplyObject(objectContextMenu.objectId, 1);
  480. objectContextMenu.objectId = 0;
  481. }
  482. }
  483. }
  484. Connections
  485. {
  486. target: Cura.Actions.centerObject
  487. onTriggered:
  488. {
  489. if(objectContextMenu.objectId != 0)
  490. {
  491. Printer.centerObject(objectContextMenu.objectId);
  492. objectContextMenu.objectId = 0;
  493. }
  494. }
  495. }
  496. }
  497. Menu
  498. {
  499. id: contextMenu;
  500. MenuItem { action: Cura.Actions.selectAll; }
  501. MenuItem { action: Cura.Actions.deleteAll; }
  502. MenuItem { action: Cura.Actions.reloadAll; }
  503. MenuItem { action: Cura.Actions.resetAllTranslation; }
  504. MenuItem { action: Cura.Actions.resetAll; }
  505. MenuSeparator { }
  506. MenuItem { action: Cura.Actions.groupObjects; }
  507. MenuItem { action: Cura.Actions.mergeObjects; }
  508. MenuItem { action: Cura.Actions.unGroupObjects; }
  509. }
  510. Connections
  511. {
  512. target: UM.Controller
  513. onContextMenuRequested:
  514. {
  515. if(objectId == 0)
  516. {
  517. contextMenu.popup();
  518. } else
  519. {
  520. objectContextMenu.objectId = objectId;
  521. objectContextMenu.popup();
  522. }
  523. }
  524. }
  525. Connections
  526. {
  527. target: Cura.Actions.quit
  528. onTriggered: base.visible = false;
  529. }
  530. Connections
  531. {
  532. target: Cura.Actions.toggleFullScreen
  533. onTriggered: base.toggleFullscreen();
  534. }
  535. FileDialog
  536. {
  537. id: openDialog;
  538. //: File open dialog title
  539. title: catalog.i18nc("@title:window","Open file")
  540. modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
  541. //TODO: Support multiple file selection, workaround bug in KDE file dialog
  542. //selectMultiple: true
  543. nameFilters: UM.MeshFileHandler.supportedReadFileTypes;
  544. folder: CuraApplication.getDefaultPath("dialog_load_path")
  545. onAccepted:
  546. {
  547. //Because several implementations of the file dialog only update the folder
  548. //when it is explicitly set.
  549. var f = folder;
  550. folder = f;
  551. CuraApplication.setDefaultPath("dialog_load_path", folder);
  552. UM.MeshFileHandler.readLocalFile(fileUrl)
  553. var meshName = backgroundItem.getMeshName(fileUrl.toString())
  554. backgroundItem.hasMesh(decodeURIComponent(meshName))
  555. }
  556. }
  557. Connections
  558. {
  559. target: Cura.Actions.open
  560. onTriggered: openDialog.open()
  561. }
  562. EngineLog
  563. {
  564. id: engineLog;
  565. }
  566. Connections
  567. {
  568. target: Cura.Actions.showEngineLog
  569. onTriggered: engineLog.visible = true;
  570. }
  571. AddMachineDialog
  572. {
  573. id: addMachineDialog
  574. onMachineAdded:
  575. {
  576. machineActionsWizard.start(id)
  577. }
  578. }
  579. // Dialog to handle first run machine actions
  580. UM.Wizard
  581. {
  582. id: machineActionsWizard;
  583. title: catalog.i18nc("@title:window", "Add Printer")
  584. property var machine;
  585. function start(id)
  586. {
  587. var actions = Cura.MachineActionManager.getFirstStartActions(id)
  588. resetPages() // Remove previous pages
  589. for (var i = 0; i < actions.length; i++)
  590. {
  591. actions[i].displayItem.reset()
  592. machineActionsWizard.appendPage(actions[i].displayItem, catalog.i18nc("@title", actions[i].label));
  593. }
  594. //Only start if there are actions to perform.
  595. if (actions.length > 0)
  596. {
  597. machineActionsWizard.currentPage = 0;
  598. show()
  599. }
  600. }
  601. }
  602. MessageDialog
  603. {
  604. id: messageDialog
  605. modality: Qt.ApplicationModal
  606. onAccepted: Printer.messageBoxClosed(clickedButton)
  607. onApply: Printer.messageBoxClosed(clickedButton)
  608. onDiscard: Printer.messageBoxClosed(clickedButton)
  609. onHelp: Printer.messageBoxClosed(clickedButton)
  610. onNo: Printer.messageBoxClosed(clickedButton)
  611. onRejected: Printer.messageBoxClosed(clickedButton)
  612. onReset: Printer.messageBoxClosed(clickedButton)
  613. onYes: Printer.messageBoxClosed(clickedButton)
  614. }
  615. Connections
  616. {
  617. target: Printer
  618. onShowMessageBox:
  619. {
  620. messageDialog.title = title
  621. messageDialog.text = text
  622. messageDialog.informativeText = informativeText
  623. messageDialog.detailedText = detailedText
  624. messageDialog.standardButtons = buttons
  625. messageDialog.icon = icon
  626. messageDialog.visible = true
  627. }
  628. }
  629. Connections
  630. {
  631. target: Cura.Actions.addMachine
  632. onTriggered: addMachineDialog.visible = true;
  633. }
  634. AboutDialog
  635. {
  636. id: aboutDialog
  637. }
  638. Connections
  639. {
  640. target: Cura.Actions.about
  641. onTriggered: aboutDialog.visible = true;
  642. }
  643. Connections
  644. {
  645. target: Printer
  646. onRequestAddPrinter:
  647. {
  648. addMachineDialog.visible = true
  649. addMachineDialog.firstRun = false
  650. }
  651. }
  652. Timer
  653. {
  654. id: startupTimer;
  655. interval: 100;
  656. repeat: false;
  657. running: true;
  658. onTriggered:
  659. {
  660. if(!base.visible)
  661. {
  662. base.visible = true;
  663. restart();
  664. }
  665. else if(Cura.MachineManager.activeMachineId == null || Cura.MachineManager.activeMachineId == "")
  666. {
  667. addMachineDialog.open();
  668. }
  669. }
  670. }
  671. }