DiscoverUM3Action.qml 15 KB

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