DiscoverUM3Action.qml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. import UM 1.2 as UM
  2. import Cura 1.0 as Cura
  3. import QtQuick 2.2
  4. import QtQuick.Controls 1.1
  5. import QtQuick.Layouts 1.1
  6. import QtQuick.Window 2.1
  7. import QtQuick.Dialogs 1.2
  8. Cura.MachineAction
  9. {
  10. id: base
  11. anchors.fill: parent;
  12. property var selectedDevice: null
  13. property bool completeProperties: true
  14. function connectToPrinter()
  15. {
  16. if(base.selectedDevice && base.completeProperties)
  17. {
  18. var printerKey = base.selectedDevice.key
  19. var printerName = base.selectedDevice.name // TODO To change when the groups have a name
  20. if (manager.getStoredKey() != printerKey)
  21. {
  22. // Check if there is another instance with the same key
  23. if (!manager.existsKey(printerKey))
  24. {
  25. manager.setKey(printerKey)
  26. manager.setGroupName(printerName) // TODO To change when the groups have a name
  27. completed()
  28. }
  29. else
  30. {
  31. existingConnectionDialog.open()
  32. }
  33. }
  34. }
  35. }
  36. MessageDialog
  37. {
  38. id: existingConnectionDialog
  39. title: catalog.i18nc("@window:title", "Existing Connection")
  40. icon: StandardIcon.Information
  41. text: catalog.i18nc("@message:text", "This printer/group is already added to Cura. Please select another printer/group.")
  42. standardButtons: StandardButton.Ok
  43. modality: Qt.ApplicationModal
  44. }
  45. Column
  46. {
  47. anchors.fill: parent;
  48. id: discoverUM3Action
  49. spacing: UM.Theme.getSize("default_margin").height
  50. SystemPalette { id: palette }
  51. UM.I18nCatalog { id: catalog; name:"cura" }
  52. Label
  53. {
  54. id: pageTitle
  55. width: parent.width
  56. text: catalog.i18nc("@title:window", "Connect to Networked Printer")
  57. wrapMode: Text.WordWrap
  58. font.pointSize: 18
  59. }
  60. Label
  61. {
  62. id: pageDescription
  63. width: parent.width
  64. wrapMode: Text.WordWrap
  65. 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\nSelect your printer from the list below:")
  66. }
  67. Row
  68. {
  69. spacing: UM.Theme.getSize("default_lining").width
  70. Button
  71. {
  72. id: addButton
  73. text: catalog.i18nc("@action:button", "Add");
  74. onClicked:
  75. {
  76. manualPrinterDialog.showDialog("", "");
  77. }
  78. }
  79. Button
  80. {
  81. id: editButton
  82. text: catalog.i18nc("@action:button", "Edit")
  83. enabled: base.selectedDevice != null && base.selectedDevice.getProperty("manual") == "true"
  84. onClicked:
  85. {
  86. manualPrinterDialog.showDialog(base.selectedDevice.key, base.selectedDevice.ipAddress);
  87. }
  88. }
  89. Button
  90. {
  91. id: removeButton
  92. text: catalog.i18nc("@action:button", "Remove")
  93. enabled: base.selectedDevice != null && base.selectedDevice.getProperty("manual") == "true"
  94. onClicked: manager.removeManualDevice(base.selectedDevice.key, base.selectedDevice.ipAddress)
  95. }
  96. Button
  97. {
  98. id: rediscoverButton
  99. text: catalog.i18nc("@action:button", "Refresh")
  100. onClicked: manager.restartDiscovery()
  101. }
  102. }
  103. Row
  104. {
  105. id: contentRow
  106. width: parent.width
  107. spacing: UM.Theme.getSize("default_margin").width
  108. Column
  109. {
  110. width: Math.round(parent.width * 0.5)
  111. spacing: UM.Theme.getSize("default_margin").height
  112. ScrollView
  113. {
  114. id: objectListContainer
  115. frameVisible: true
  116. width: parent.width
  117. height: base.height - contentRow.y - discoveryTip.height
  118. Rectangle
  119. {
  120. parent: viewport
  121. anchors.fill: parent
  122. color: palette.light
  123. }
  124. ListView
  125. {
  126. id: listview
  127. model: manager.foundDevices
  128. onModelChanged:
  129. {
  130. var selectedKey = manager.getLastManualEntryKey()
  131. // If there is no last manual entry key, then we select the stored key (if any)
  132. if (selectedKey == "")
  133. selectedKey = manager.getStoredKey()
  134. for(var i = 0; i < model.length; i++) {
  135. if(model[i].key == selectedKey)
  136. {
  137. currentIndex = i;
  138. return
  139. }
  140. }
  141. currentIndex = -1;
  142. }
  143. width: parent.width
  144. currentIndex: -1
  145. onCurrentIndexChanged:
  146. {
  147. base.selectedDevice = listview.model[currentIndex];
  148. // Only allow connecting if the printer has responded to API query since the last refresh
  149. base.completeProperties = base.selectedDevice != null && base.selectedDevice.getProperty("incomplete") != "true";
  150. }
  151. Component.onCompleted: manager.startDiscovery()
  152. delegate: Rectangle
  153. {
  154. height: childrenRect.height
  155. color: ListView.isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
  156. width: parent.width
  157. Label
  158. {
  159. anchors.left: parent.left
  160. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  161. anchors.right: parent.right
  162. text: listview.model[index].name
  163. color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text
  164. elide: Text.ElideRight
  165. }
  166. MouseArea
  167. {
  168. anchors.fill: parent;
  169. onClicked:
  170. {
  171. if(!parent.ListView.isCurrentItem)
  172. {
  173. parent.ListView.view.currentIndex = index;
  174. }
  175. }
  176. }
  177. }
  178. }
  179. }
  180. Label
  181. {
  182. id: discoveryTip
  183. anchors.left: parent.left
  184. anchors.right: parent.right
  185. wrapMode: Text.WordWrap
  186. 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/troubleshooting");
  187. onLinkActivated: Qt.openUrlExternally(link)
  188. }
  189. }
  190. Column
  191. {
  192. width: Math.round(parent.width * 0.5)
  193. visible: base.selectedDevice ? true : false
  194. spacing: UM.Theme.getSize("default_margin").height
  195. Label
  196. {
  197. width: parent.width
  198. wrapMode: Text.WordWrap
  199. text: base.selectedDevice ? base.selectedDevice.name : ""
  200. font: UM.Theme.getFont("large")
  201. elide: Text.ElideRight
  202. }
  203. Grid
  204. {
  205. visible: base.completeProperties
  206. width: parent.width
  207. columns: 2
  208. Label
  209. {
  210. width: Math.round(parent.width * 0.5)
  211. wrapMode: Text.WordWrap
  212. text: catalog.i18nc("@label", "Type")
  213. }
  214. Label
  215. {
  216. width: Math.round(parent.width * 0.5)
  217. wrapMode: Text.WordWrap
  218. text:
  219. {
  220. if(base.selectedDevice)
  221. {
  222. if (base.selectedDevice.printerType == "ultimaker3")
  223. {
  224. return "Ultimaker 3";
  225. }
  226. else if (base.selectedDevice.printerType == "ultimaker3_extended")
  227. {
  228. return "Ultimaker 3 Extended";
  229. }
  230. else if (base.selectedDevice.printerType == "ultimaker_s5")
  231. {
  232. return "Ultimaker S5";
  233. }
  234. else
  235. {
  236. return catalog.i18nc("@label", "Unknown") // We have no idea what type it is. Should not happen 'in the field'
  237. }
  238. }
  239. else
  240. {
  241. return ""
  242. }
  243. }
  244. }
  245. Label
  246. {
  247. width: Math.round(parent.width * 0.5)
  248. wrapMode: Text.WordWrap
  249. text: catalog.i18nc("@label", "Firmware version")
  250. }
  251. Label
  252. {
  253. width: Math.round(parent.width * 0.5)
  254. wrapMode: Text.WordWrap
  255. text: base.selectedDevice ? base.selectedDevice.firmwareVersion : ""
  256. }
  257. Label
  258. {
  259. width: Math.round(parent.width * 0.5)
  260. wrapMode: Text.WordWrap
  261. text: catalog.i18nc("@label", "Address")
  262. }
  263. Label
  264. {
  265. width: Math.round(parent.width * 0.5)
  266. wrapMode: Text.WordWrap
  267. text: base.selectedDevice ? base.selectedDevice.ipAddress : ""
  268. }
  269. }
  270. Label
  271. {
  272. width: parent.width
  273. wrapMode: Text.WordWrap
  274. text:{
  275. // The property cluster size does not exist for older UM3 devices.
  276. if(!base.selectedDevice || base.selectedDevice.clusterSize == null || base.selectedDevice.clusterSize == 1)
  277. {
  278. return "";
  279. }
  280. else if (base.selectedDevice.clusterSize === 0)
  281. {
  282. return catalog.i18nc("@label", "This printer is not set up to host a group of Ultimaker 3 printers.");
  283. }
  284. else
  285. {
  286. return catalog.i18nc("@label", "This printer is the host for a group of %1 Ultimaker 3 printers.".arg(base.selectedDevice.clusterSize));
  287. }
  288. }
  289. }
  290. Label
  291. {
  292. width: parent.width
  293. wrapMode: Text.WordWrap
  294. visible: base.selectedDevice != null && !base.completeProperties
  295. text: catalog.i18nc("@label", "The printer at this address has not yet responded." )
  296. }
  297. Button
  298. {
  299. text: catalog.i18nc("@action:button", "Connect")
  300. enabled: (base.selectedDevice && base.completeProperties && base.selectedDevice.clusterSize > 0) ? true : false
  301. onClicked: connectToPrinter()
  302. }
  303. }
  304. }
  305. }
  306. UM.Dialog
  307. {
  308. id: manualPrinterDialog
  309. property string printerKey
  310. property alias addressText: addressField.text
  311. title: catalog.i18nc("@title:window", "Printer Address")
  312. minimumWidth: 400 * screenScaleFactor
  313. minimumHeight: 130 * screenScaleFactor
  314. width: minimumWidth
  315. height: minimumHeight
  316. signal showDialog(string key, string address)
  317. onShowDialog:
  318. {
  319. printerKey = key;
  320. addressText = address;
  321. manualPrinterDialog.show();
  322. addressField.selectAll();
  323. addressField.focus = true;
  324. }
  325. onAccepted:
  326. {
  327. manager.setManualDevice(printerKey, addressText)
  328. }
  329. Column {
  330. anchors.fill: parent
  331. spacing: UM.Theme.getSize("default_margin").height
  332. Label
  333. {
  334. text: catalog.i18nc("@alabel","Enter the IP address or hostname of your printer on the network.")
  335. width: parent.width
  336. wrapMode: Text.WordWrap
  337. }
  338. TextField
  339. {
  340. id: addressField
  341. width: parent.width
  342. maximumLength: 40
  343. validator: RegExpValidator
  344. {
  345. regExp: /[a-zA-Z0-9\.\-\_]*/
  346. }
  347. onAccepted: btnOk.clicked()
  348. }
  349. }
  350. rightButtons: [
  351. Button {
  352. text: catalog.i18nc("@action:button","Cancel")
  353. onClicked:
  354. {
  355. manualPrinterDialog.reject()
  356. manualPrinterDialog.hide()
  357. }
  358. },
  359. Button {
  360. id: btnOk
  361. text: catalog.i18nc("@action:button", "OK")
  362. onClicked:
  363. {
  364. manualPrinterDialog.accept()
  365. manualPrinterDialog.hide()
  366. }
  367. enabled: manualPrinterDialog.addressText.trim() != ""
  368. isDefault: true
  369. }
  370. ]
  371. }
  372. }