AddPrinterByIpContent.qml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. // Copyright (c) 2022 UltiMaker
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.15
  4. import QtQuick.Controls 2.3
  5. import QtQuick.Layouts 1.3
  6. import UM 1.5 as UM
  7. import Cura 1.5 as Cura
  8. //
  9. // This component contains the content for the 'by IP' page of the "Add New Printer" flow of the on-boarding process.
  10. //
  11. Item
  12. {
  13. UM.I18nCatalog { id: catalog; name: "cura" }
  14. id: addPrinterByIpScreen
  15. // If there's a manual address resolve request in progress.
  16. property bool hasRequestInProgress: CuraApplication.getDiscoveredPrintersModel().hasManualDeviceRequestInProgress
  17. // Indicates if a request has finished.
  18. property bool hasRequestFinished: false
  19. property string currentRequestAddress: ""
  20. property var discoveredPrinter: null
  21. property bool isPrinterDiscovered: discoveredPrinter != null
  22. // A printer can only be added if it doesn't have an unknown type and it's the host of a group.
  23. property bool canAddPrinter: isPrinterDiscovered && !discoveredPrinter.isUnknownMachineType && discoveredPrinter.isHostOfGroup
  24. // For validating IP address
  25. property var networkingUtil: Cura.NetworkingUtil {}
  26. // CURA-6483
  27. // For a manually added UM printer, the UM3OutputDevicePlugin will first create a LegacyUM device for it. Later,
  28. // when it gets more info from the printer, it will first REMOVE the LegacyUM device and then add a ClusterUM device.
  29. // The Add-by-IP page needs to make sure that the user do not add an unknown printer or a printer that's not the
  30. // host of a group. Because of the device list change, this page needs to react upon DiscoveredPrintersChanged so
  31. // it has the correct information.
  32. Connections
  33. {
  34. target: CuraApplication.getDiscoveredPrintersModel()
  35. function onDiscoveredPrintersChanged()
  36. {
  37. if (hasRequestFinished && currentRequestAddress)
  38. {
  39. var printer = CuraApplication.getDiscoveredPrintersModel().discoveredPrintersByAddress[currentRequestAddress]
  40. printer = printer ? printer : null
  41. discoveredPrinter = printer
  42. }
  43. }
  44. }
  45. // Make sure to cancel the current request when this page closes.
  46. onVisibleChanged:
  47. {
  48. if (!visible)
  49. {
  50. CuraApplication.getDiscoveredPrintersModel().cancelCurrentManualDeviceRequest()
  51. }
  52. }
  53. UM.Label
  54. {
  55. id: titleLabel
  56. anchors.top: parent.top
  57. anchors.horizontalCenter: parent.horizontalCenter
  58. horizontalAlignment: Text.AlignHCenter
  59. text: catalog.i18nc("@label", "Add printer by IP address")
  60. color: UM.Theme.getColor("primary_button")
  61. font: UM.Theme.getFont("huge")
  62. }
  63. Item
  64. {
  65. anchors.top: titleLabel.bottom
  66. anchors.bottom: connectButton.top
  67. anchors.topMargin: UM.Theme.getSize("default_margin").height
  68. anchors.bottomMargin: UM.Theme.getSize("default_margin").height
  69. anchors.left: parent.left
  70. anchors.right: parent.right
  71. Item
  72. {
  73. anchors.left: parent.left
  74. anchors.right: parent.right
  75. anchors.margins: UM.Theme.getSize("default_margin").width
  76. UM.Label
  77. {
  78. id: explainLabel
  79. height: contentHeight
  80. anchors.left: parent.left
  81. anchors.right: parent.right
  82. anchors.top: parent.top
  83. text: catalog.i18nc("@label", "Enter the IP address of your printer on the network.")
  84. }
  85. Item
  86. {
  87. id: userInputFields
  88. height: childrenRect.height
  89. anchors.left: parent.left
  90. anchors.right: parent.right
  91. anchors.top: explainLabel.bottom
  92. anchors.topMargin: UM.Theme.getSize("default_margin").width
  93. Cura.TextField
  94. {
  95. id: hostnameField
  96. width: (parent.width / 2) | 0
  97. height: addPrinterButton.height
  98. anchors.verticalCenter: addPrinterButton.verticalCenter
  99. anchors.left: parent.left
  100. signal invalidInputDetected()
  101. onInvalidInputDetected: invalidInputLabel.visible = true
  102. validator: RegularExpressionValidator
  103. {
  104. regularExpression: /([a-fA-F0-9.:\?\/]+)?/
  105. }
  106. onTextEdited: invalidInputLabel.visible = false
  107. placeholderText: catalog.i18nc("@text", "Enter your printer's IP address.")
  108. enabled: { ! (addPrinterByIpScreen.hasRequestInProgress || addPrinterByIpScreen.isPrinterDiscovered) }
  109. onAccepted: addPrinterButton.clicked()
  110. }
  111. UM.Label
  112. {
  113. id: invalidInputLabel
  114. anchors.top: hostnameField.bottom
  115. anchors.topMargin: UM.Theme.getSize("default_margin").height
  116. anchors.left: parent.left
  117. visible: false
  118. text: catalog.i18nc("@text", "Please enter a valid IP address.")
  119. }
  120. Cura.SecondaryButton
  121. {
  122. id: addPrinterButton
  123. anchors.top: parent.top
  124. anchors.left: hostnameField.right
  125. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  126. text: catalog.i18nc("@button", "Add")
  127. enabled: !addPrinterByIpScreen.hasRequestInProgress && !addPrinterByIpScreen.isPrinterDiscovered && (hostnameField.state != "invalid" && hostnameField.text != "")
  128. onClicked:
  129. {
  130. addPrinterByIpScreen.hasRequestFinished = false //In case it's pressed multiple times.
  131. const address = hostnameField.text
  132. if (!networkingUtil.isValidIP(address))
  133. {
  134. hostnameField.invalidInputDetected()
  135. return
  136. }
  137. // This address is already in the discovered printer model, no need to add a manual discovery.
  138. if (CuraApplication.getDiscoveredPrintersModel().discoveredPrintersByAddress[address])
  139. {
  140. addPrinterByIpScreen.discoveredPrinter = CuraApplication.getDiscoveredPrintersModel().discoveredPrintersByAddress[address]
  141. addPrinterByIpScreen.hasRequestFinished = true
  142. return
  143. }
  144. addPrinterByIpScreen.currentRequestAddress = address
  145. CuraApplication.getDiscoveredPrintersModel().checkManualDevice(address)
  146. }
  147. busy: addPrinterByIpScreen.hasRequestInProgress
  148. }
  149. }
  150. Item
  151. {
  152. width: parent.width
  153. anchors.top: userInputFields.bottom
  154. anchors.margins: UM.Theme.getSize("default_margin").width
  155. UM.Label
  156. {
  157. id: waitResponseLabel
  158. anchors.top: parent.top
  159. anchors.margins: UM.Theme.getSize("default_margin").width
  160. visible: addPrinterByIpScreen.hasRequestInProgress || (addPrinterByIpScreen.hasRequestFinished && !addPrinterByIpScreen.isPrinterDiscovered)
  161. textFormat: Text.RichText
  162. text:
  163. {
  164. if (addPrinterByIpScreen.hasRequestFinished)
  165. {
  166. return catalog.i18nc("@label", "Could not connect to device.") + "<br /><br /><a href=\"https://ultimaker.com/in/cura/troubleshooting/network?utm_source=cura&utm_medium=software&utm_campaign=add-network-printer-error\">"
  167. + catalog.i18nc("@label", "Can't connect to your UltiMaker printer?") + "</a>";
  168. }
  169. else
  170. {
  171. return catalog.i18nc("@label", "The printer at this address has not responded yet.") + "<br /><br /><a href=\"https://ultimaker.com/in/cura/troubleshooting/network?utm_source=cura&utm_medium=software&utm_campaign=add-network-printer-error\">"
  172. + catalog.i18nc("@label", "Can't connect to your UltiMaker printer?") + "</a>";
  173. }
  174. }
  175. onLinkActivated: Qt.openUrlExternally(link)
  176. }
  177. Item
  178. {
  179. id: printerInfoLabels
  180. anchors.left: parent.left
  181. anchors.right: parent.right
  182. anchors.top: parent.top
  183. anchors.margins: UM.Theme.getSize("default_margin").width
  184. visible: addPrinterByIpScreen.isPrinterDiscovered
  185. UM.Label
  186. {
  187. id: printerNameLabel
  188. anchors.top: parent.top
  189. font: UM.Theme.getFont("large")
  190. text: !addPrinterByIpScreen.isPrinterDiscovered ? "???" : addPrinterByIpScreen.discoveredPrinter.name
  191. }
  192. UM.Label
  193. {
  194. id: printerCannotBeAddedLabel
  195. width: parent.width
  196. anchors.top: printerNameLabel.bottom
  197. anchors.topMargin: UM.Theme.getSize("default_margin").height
  198. text: catalog.i18nc("@label", "This printer cannot be added because it's an unknown printer or it's not the host of a group.")
  199. visible: addPrinterByIpScreen.hasRequestFinished && !addPrinterByIpScreen.canAddPrinter
  200. font: UM.Theme.getFont("default_bold")
  201. wrapMode: Text.WordWrap
  202. }
  203. GridLayout
  204. {
  205. id: printerInfoGrid
  206. anchors.top: printerCannotBeAddedLabel ? printerCannotBeAddedLabel.bottom : printerNameLabel.bottom
  207. anchors.margins: UM.Theme.getSize("default_margin").width
  208. columns: 2
  209. columnSpacing: UM.Theme.getSize("default_margin").width
  210. UM.Label
  211. {
  212. text: catalog.i18nc("@label", "Type")
  213. }
  214. UM.Label
  215. {
  216. id: typeText
  217. text: !addPrinterByIpScreen.isPrinterDiscovered ? "?" : addPrinterByIpScreen.discoveredPrinter.readableMachineType
  218. }
  219. UM.Label
  220. {
  221. text: catalog.i18nc("@label", "Firmware version")
  222. }
  223. UM.Label
  224. {
  225. id: firmwareText
  226. text: !addPrinterByIpScreen.isPrinterDiscovered ? "0.0.0.0" : addPrinterByIpScreen.discoveredPrinter.device.getProperty("firmware_version")
  227. }
  228. UM.Label
  229. {
  230. text: catalog.i18nc("@label", "Address")
  231. }
  232. UM.Label
  233. {
  234. id: addressText
  235. text: !addPrinterByIpScreen.isPrinterDiscovered ? "0.0.0.0" : addPrinterByIpScreen.discoveredPrinter.address
  236. }
  237. }
  238. Connections
  239. {
  240. target: CuraApplication.getDiscoveredPrintersModel()
  241. function onManualDeviceRequestFinished(success)
  242. {
  243. var discovered_printers_model = CuraApplication.getDiscoveredPrintersModel()
  244. var printer = discovered_printers_model.discoveredPrintersByAddress[hostnameField.text]
  245. if (printer)
  246. {
  247. addPrinterByIpScreen.discoveredPrinter = printer
  248. }
  249. addPrinterByIpScreen.hasRequestFinished = true
  250. }
  251. }
  252. }
  253. }
  254. }
  255. }
  256. Cura.SecondaryButton
  257. {
  258. id: backButton
  259. anchors.left: parent.left
  260. anchors.bottom: parent.bottom
  261. text: catalog.i18nc("@button", "Back")
  262. onClicked:
  263. {
  264. CuraApplication.getDiscoveredPrintersModel().cancelCurrentManualDeviceRequest()
  265. base.showPreviousPage()
  266. }
  267. }
  268. Cura.PrimaryButton
  269. {
  270. id: connectButton
  271. anchors.right: parent.right
  272. anchors.bottom: parent.bottom
  273. text: catalog.i18nc("@button", "Connect")
  274. onClicked:
  275. {
  276. CuraApplication.getDiscoveredPrintersModel().createMachineFromDiscoveredPrinter(discoveredPrinter)
  277. base.showNextPage()
  278. }
  279. enabled: addPrinterByIpScreen.canAddPrinter
  280. }
  281. }