DiscoverUM3Action.qml 14 KB

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