DiscoverUM3Action.qml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. // Copyright (c) 2022 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.15
  4. import QtQuick.Controls 2.9
  5. import QtQuick.Layouts 1.1
  6. import QtQuick.Window 2.1
  7. import UM 1.5 as UM
  8. import Cura 1.5 as Cura
  9. Cura.MachineAction
  10. {
  11. id: base
  12. anchors.fill: parent;
  13. property alias currentItemIndex: listview.currentIndex
  14. property var selectedDevice: null
  15. property bool completeProperties: true
  16. // For validating IP addresses
  17. property var networkingUtil: Cura.NetworkingUtil {}
  18. function connectToPrinter()
  19. {
  20. if (base.selectedDevice && base.completeProperties)
  21. {
  22. manager.associateActiveMachineWithPrinterDevice(base.selectedDevice)
  23. completed()
  24. }
  25. }
  26. Column
  27. {
  28. anchors.fill: parent;
  29. id: discoverUM3Action
  30. spacing: UM.Theme.getSize("default_margin").height
  31. UM.I18nCatalog { id: catalog; name:"cura" }
  32. UM.Label
  33. {
  34. id: pageTitle
  35. width: parent.width
  36. text: catalog.i18nc("@title:window", "Connect to Networked Printer")
  37. }
  38. UM.Label
  39. {
  40. id: pageDescription
  41. width: parent.width
  42. text: catalog.i18nc("@label", "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.") + "\n\n" + catalog.i18nc("@label", "Select your printer from the list below:")
  43. }
  44. Row
  45. {
  46. spacing: UM.Theme.getSize("thin_margin").width
  47. Cura.SecondaryButton
  48. {
  49. id: addButton
  50. text: catalog.i18nc("@action:button", "Add");
  51. onClicked:
  52. {
  53. manualPrinterDialog.showDialog("", "");
  54. }
  55. }
  56. Cura.SecondaryButton
  57. {
  58. id: editButton
  59. text: catalog.i18nc("@action:button", "Edit")
  60. enabled: base.selectedDevice != null && base.selectedDevice.getProperty("manual") == "true"
  61. onClicked:
  62. {
  63. manualPrinterDialog.showDialog(base.selectedDevice.key, base.selectedDevice.ipAddress);
  64. }
  65. }
  66. Cura.SecondaryButton
  67. {
  68. id: removeButton
  69. text: catalog.i18nc("@action:button", "Remove")
  70. enabled: base.selectedDevice != null && base.selectedDevice.getProperty("manual") == "true"
  71. onClicked: manager.removeManualDevice(base.selectedDevice.key, base.selectedDevice.ipAddress)
  72. }
  73. Cura.SecondaryButton
  74. {
  75. id: rediscoverButton
  76. text: catalog.i18nc("@action:button", "Refresh")
  77. onClicked: manager.restartDiscovery()
  78. }
  79. }
  80. Row
  81. {
  82. id: contentRow
  83. width: parent.width
  84. spacing: UM.Theme.getSize("default_margin").width
  85. Column
  86. {
  87. width: Math.round(parent.width * 0.5)
  88. spacing: UM.Theme.getSize("default_margin").height
  89. ListView
  90. {
  91. id: listview
  92. width: parent.width
  93. height: base.height - contentRow.y - discoveryTip.height
  94. ScrollBar.vertical: UM.ScrollBar {}
  95. clip: true
  96. model: manager.foundDevices
  97. currentIndex: -1
  98. onCurrentIndexChanged:
  99. {
  100. base.selectedDevice = listview.model[currentIndex];
  101. // Only allow connecting if the printer has responded to API query since the last refresh
  102. base.completeProperties = base.selectedDevice != null && base.selectedDevice.getProperty("incomplete") != "true";
  103. }
  104. Component.onCompleted: manager.startDiscovery()
  105. delegate: UM.Label
  106. {
  107. id: printNameLabel
  108. width: listview.width
  109. height: contentHeight
  110. anchors.left: parent.left
  111. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  112. anchors.right: parent.right
  113. text: listview.model[index].name
  114. elide: Text.ElideRight
  115. MouseArea
  116. {
  117. anchors.fill: parent;
  118. onClicked:
  119. {
  120. if(!parent.ListView.isCurrentItem)
  121. {
  122. parent.ListView.view.currentIndex = index;
  123. }
  124. }
  125. }
  126. background: Rectangle
  127. {
  128. color: parent.ListView.isCurrentItem ? UM.Theme.getColor("background_3") : "transparent"
  129. }
  130. }
  131. }
  132. UM.Label
  133. {
  134. id: discoveryTip
  135. anchors.left: parent.left
  136. anchors.right: parent.right
  137. text: catalog.i18nc("@label", "If your printer is not listed, read the <a href='%1'>network printing troubleshooting guide</a>").arg("https://ultimaker.com/en/cura/troubleshooting/network?utm_source=cura&utm_medium=software&utm_campaign=manage-network-printer");
  138. onLinkActivated: Qt.openUrlExternally(link)
  139. }
  140. }
  141. Column
  142. {
  143. width: Math.round(parent.width * 0.5)
  144. visible: base.selectedDevice ? true : false
  145. spacing: UM.Theme.getSize("default_margin").height
  146. UM.Label
  147. {
  148. width: parent.width
  149. text: base.selectedDevice ? base.selectedDevice.name : ""
  150. font: UM.Theme.getFont("large_bold")
  151. elide: Text.ElideRight
  152. }
  153. GridLayout
  154. {
  155. visible: base.completeProperties
  156. width: parent.width
  157. columns: 2
  158. UM.Label
  159. {
  160. Layout.fillWidth: true
  161. text: catalog.i18nc("@label", "Type")
  162. }
  163. UM.Label
  164. {
  165. Layout.fillWidth: true
  166. text:
  167. {
  168. if (base.selectedDevice) {
  169. return base.selectedDevice.printerTypeName
  170. }
  171. return ""
  172. }
  173. }
  174. UM.Label
  175. {
  176. Layout.fillWidth: true
  177. text: catalog.i18nc("@label", "Firmware version")
  178. }
  179. UM.Label
  180. {
  181. Layout.fillWidth: true
  182. text: base.selectedDevice ? base.selectedDevice.firmwareVersion : ""
  183. }
  184. UM.Label
  185. {
  186. Layout.fillWidth: true
  187. text: catalog.i18nc("@label", "Address")
  188. }
  189. UM.Label
  190. {
  191. Layout.fillWidth: true
  192. text: base.selectedDevice ? base.selectedDevice.ipAddress : ""
  193. }
  194. }
  195. UM.Label
  196. {
  197. width: parent.width
  198. text:{
  199. // The property cluster size does not exist for older UM3 devices.
  200. if(!base.selectedDevice || base.selectedDevice.clusterSize == null || base.selectedDevice.clusterSize == 1)
  201. {
  202. return "";
  203. }
  204. else if (base.selectedDevice.clusterSize === 0)
  205. {
  206. return catalog.i18nc("@label", "This printer is not set up to host a group of printers.");
  207. }
  208. else
  209. {
  210. return catalog.i18nc("@label", "This printer is the host for a group of %1 printers.".arg(base.selectedDevice.clusterSize));
  211. }
  212. }
  213. }
  214. UM.Label
  215. {
  216. width: parent.width
  217. visible: base.selectedDevice != null && !base.completeProperties
  218. text: catalog.i18nc("@label", "The printer at this address has not yet responded." )
  219. }
  220. Cura.SecondaryButton
  221. {
  222. text: catalog.i18nc("@action:button", "Connect")
  223. enabled: (base.selectedDevice && base.completeProperties && base.selectedDevice.clusterSize > 0) ? true : false
  224. onClicked: connectToPrinter()
  225. }
  226. }
  227. }
  228. }
  229. Cura.MessageDialog
  230. {
  231. id: invalidIPAddressMessageDialog
  232. title: catalog.i18nc("@title:window", "Invalid IP address")
  233. text: catalog.i18nc("@text", "Please enter a valid IP address.")
  234. standardButtons: Dialog.Ok
  235. }
  236. Cura.MessageDialog
  237. {
  238. id: manualPrinterDialog
  239. property string printerKey
  240. property alias addressText: addressField.text
  241. title: catalog.i18nc("@title:window", "Printer Address")
  242. width: UM.Theme.getSize("small_popup_dialog").width
  243. height: UM.Theme.getSize("small_popup_dialog").height
  244. anchors.centerIn: Overlay.overlay
  245. standardButtons: Dialog.Yes | Dialog.No
  246. signal showDialog(string key, string address)
  247. onShowDialog:
  248. {
  249. printerKey = key;
  250. addressText = address;
  251. manualPrinterDialog.open();
  252. addressField.selectAll();
  253. addressField.focus = true;
  254. }
  255. Column {
  256. anchors.fill: parent
  257. spacing: UM.Theme.getSize("default_margin").height
  258. UM.Label
  259. {
  260. text: catalog.i18nc("@label", "Enter the IP address of your printer on the network.")
  261. }
  262. Cura.TextField
  263. {
  264. id: addressField
  265. width: parent.width
  266. validator: RegularExpressionValidator { regularExpression: /[a-zA-Z0-9\.\-\_]*/ }
  267. }
  268. }
  269. onAccepted:
  270. {
  271. // Validate the input first
  272. if (!networkingUtil.isValidIP(manualPrinterDialog.addressText))
  273. {
  274. // prefent closing of element, as we want to keep the dialog active after a wrongly entered IP adress
  275. manualPrinterDialog.open()
  276. // show invalid ip warning
  277. invalidIPAddressMessageDialog.open();
  278. return;
  279. }
  280. // if the entered IP address has already been discovered, switch the current item to that item
  281. // and do nothing else.
  282. for (var i = 0; i < manager.foundDevices.length; i++)
  283. {
  284. var device = manager.foundDevices[i]
  285. if (device.address == manualPrinterDialog.addressText)
  286. {
  287. currentItemIndex = i;
  288. return;
  289. }
  290. }
  291. manager.setManualDevice(manualPrinterDialog.printerKey, manualPrinterDialog.addressText);
  292. }
  293. }
  294. }