QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
PX4LogTransferSettings.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Dialogs
4import QtQuick.Layouts
5
6import QGroundControl
7import QGroundControl.FactControls
8import QGroundControl.Controls
9
10Rectangle {
11 id: __mavlinkRoot
12 color: qgcPal.window
13 anchors.fill: parent
14
15 property real _labelWidth: ScreenTools.defaultFontPixelWidth * 28
16 property real _valueWidth: ScreenTools.defaultFontPixelWidth * 24
17 property int _selectedCount: 0
18 property real _columnSpacing: ScreenTools.defaultFontPixelHeight * 0.25
19 property bool _uploadedSelected: false
20 property bool _showMavlinkLog: QGroundControl.corePlugin.options.showPX4LogTransferOptions
21 property bool _showAPMStreamRates: QGroundControl.apmFirmwareSupported && QGroundControl.settingsManager.apmMavlinkStreamRateSettings.visible && _isAPM
22 property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
23 property bool _isPX4: _activeVehicle ? _activeVehicle.px4Firmware : true
24 property bool _isAPM: _activeVehicle ? _activeVehicle.apmFirmware : true
25 property Fact _disableDataPersistenceFact: QGroundControl.settingsManager.appSettings.disableAllPersistence
26 property bool _disableDataPersistence: _disableDataPersistenceFact ? _disableDataPersistenceFact.rawValue : false
27 property var _mavlinkLogManager: _activeVehicle ? _activeVehicle.mavlinkLogManager : null
28
29 QGCPalette { id: qgcPal }
30
31 Connections {
32 target: _mavlinkLogManager
33 onSelectedCountChanged: {
34 _uploadedSelected = false
35 var selected = 0
36 for(var i = 0; i < _mavlinkLogManager.logFiles.count; i++) {
37 var logFile = _mavlinkLogManager.logFiles.get(i)
38 if(logFile.selected) {
39 selected++
40 //-- If an uploaded file is selected, disable "Upload" button
41 if(logFile.uploaded) {
42 _uploadedSelected = true
43 }
44 }
45 }
46 _selectedCount = selected
47 }
48 }
49
50 function saveItems() {
51 _mavlinkLogManager.videoURL = videoUrlField.text
52 _mavlinkLogManager.feedback = feedbackTextArea.text
53 _mavlinkLogManager.emailAddress = emailField.text
54 _mavlinkLogManager.description = descField.text
55 _mavlinkLogManager.uploadURL = urlField.text
56 _mavlinkLogManager.emailAddress = emailField.text
57 if(autoUploadCheck.checked && _mavlinkLogManager.emailAddress === "") {
58 autoUploadCheck.checked = false
59 } else {
60 _mavlinkLogManager.enableAutoUpload = autoUploadCheck.checked
61 }
62 }
63
64 MessageDialog {
65 id: emptyEmailDialog
66 visible: false
67 //icon: StandardIcon.Warning
68 buttons: MessageDialog.Close
69 title: qsTr("MAVLink Logging")
70 text: qsTr("Please enter an email address before uploading MAVLink log files.")
71 }
72
73 QGCFlickable {
74 clip: true
75 anchors.fill: parent
76 anchors.margins: ScreenTools.defaultFontPixelWidth
77 contentHeight: settingsColumn.height
78 contentWidth: settingsColumn.width
79 flickableDirection: Flickable.VerticalFlick
80
81 Column {
82 id: settingsColumn
83 width: __mavlinkRoot.width
84 spacing: ScreenTools.defaultFontPixelHeight * 0.5
85 anchors.margins: ScreenTools.defaultFontPixelWidth
86
87 //-----------------------------------------------------------------
88 //-- Mavlink Logging
89 Item {
90 width: __mavlinkRoot.width * 0.8
91 height: mavlogLabel.height
92 anchors.margins: ScreenTools.defaultFontPixelWidth
93 anchors.horizontalCenter: parent.horizontalCenter
94 visible: _showMavlinkLog && _isPX4
95 QGCLabel {
96 id: mavlogLabel
97 text: qsTr("MAVLink 2.0 Logging (PX4 Pro Only)")
98 font.bold: true
99 }
100 }
101 Rectangle {
102 height: mavlogColumn.height + (ScreenTools.defaultFontPixelHeight * 2)
103 width: __mavlinkRoot.width * 0.8
104 color: qgcPal.windowShade
105 anchors.margins: ScreenTools.defaultFontPixelWidth
106 anchors.horizontalCenter: parent.horizontalCenter
107 visible: _showMavlinkLog && _isPX4
108 Column {
109 id: mavlogColumn
110 spacing: _columnSpacing
111 anchors.centerIn: parent
112 //-----------------------------------------------------------------
113 //-- Manual Start/Stop
114 Row {
115 spacing: ScreenTools.defaultFontPixelWidth
116 anchors.horizontalCenter: parent.horizontalCenter
117 QGCLabel {
118 width: _labelWidth
119 text: qsTr("Manual Start/Stop:")
120 anchors.verticalCenter: parent.verticalCenter
121 }
122 QGCButton {
123 text: qsTr("Start Logging")
124 width: (_valueWidth * 0.5) - (ScreenTools.defaultFontPixelWidth * 0.5)
125 enabled: !_mavlinkLogManager.logRunning && _mavlinkLogManager.canStartLog && !_disableDataPersistence
126 onClicked: _mavlinkLogManager.startLogging()
127 anchors.verticalCenter: parent.verticalCenter
128 }
129 QGCButton {
130 text: qsTr("Stop Logging")
131 width: (_valueWidth * 0.5) - (ScreenTools.defaultFontPixelWidth * 0.5)
132 enabled: _mavlinkLogManager.logRunning && !_disableDataPersistence
133 onClicked: _mavlinkLogManager.stopLogging()
134 anchors.verticalCenter: parent.verticalCenter
135 }
136 }
137 //-----------------------------------------------------------------
138 //-- Enable auto log on arming
139 QGCCheckBox {
140 text: qsTr("Enable automatic logging")
141 checked: _mavlinkLogManager.enableAutoStart
142 enabled: !_disableDataPersistence
143 onClicked: {
144 _mavlinkLogManager.enableAutoStart = checked
145 }
146 }
147 }
148 }
149 //-----------------------------------------------------------------
150 //-- Mavlink Logging
151 Item {
152 width: __mavlinkRoot.width * 0.8
153 height: logLabel.height
154 anchors.margins: ScreenTools.defaultFontPixelWidth
155 anchors.horizontalCenter: parent.horizontalCenter
156 visible: _showMavlinkLog && _isPX4
157 QGCLabel {
158 id: logLabel
159 text: qsTr("MAVLink 2.0 Log Uploads (PX4 Pro Only)")
160 font.bold: true
161 }
162 }
163 Rectangle {
164 height: logColumn.height + (ScreenTools.defaultFontPixelHeight * 2)
165 width: __mavlinkRoot.width * 0.8
166 color: qgcPal.windowShade
167 anchors.margins: ScreenTools.defaultFontPixelWidth
168 anchors.horizontalCenter: parent.horizontalCenter
169 visible: _showMavlinkLog && _isPX4
170 Column {
171 id: logColumn
172 spacing: _columnSpacing
173 anchors.centerIn: parent
174 //-----------------------------------------------------------------
175 //-- Email address Field
176 Row {
177 spacing: ScreenTools.defaultFontPixelWidth
178 QGCLabel {
179 width: _labelWidth
180 anchors.baseline: emailField.baseline
181 text: qsTr("Email address for Log Upload:")
182 }
183 QGCTextField {
184 id: emailField
185 text: _mavlinkLogManager.emailAddress
186 width: _valueWidth
187 enabled: !_disableDataPersistence
188 inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhEmailCharactersOnly
189 anchors.verticalCenter: parent.verticalCenter
190 onEditingFinished: {
191 saveItems();
192 }
193 }
194 }
195 //-----------------------------------------------------------------
196 //-- Description Field
197 Row {
198 spacing: ScreenTools.defaultFontPixelWidth
199 QGCLabel {
200 width: _labelWidth
201 anchors.baseline: descField.baseline
202 text: qsTr("Default Description:")
203 }
204 QGCTextField {
205 id: descField
206 text: _mavlinkLogManager.description
207 width: _valueWidth
208 enabled: !_disableDataPersistence
209 anchors.verticalCenter: parent.verticalCenter
210 onEditingFinished: {
211 saveItems();
212 }
213 }
214 }
215 //-----------------------------------------------------------------
216 //-- Upload URL
217 Row {
218 spacing: ScreenTools.defaultFontPixelWidth
219 QGCLabel {
220 width: _labelWidth
221 anchors.baseline: urlField.baseline
222 text: qsTr("Default Upload URL")
223 }
224 QGCTextField {
225 id: urlField
226 text: _mavlinkLogManager.uploadURL
227 width: _valueWidth
228 enabled: !_disableDataPersistence
229 inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhUrlCharactersOnly
230 anchors.verticalCenter: parent.verticalCenter
231 onEditingFinished: {
232 saveItems();
233 }
234 }
235 }
236 //-----------------------------------------------------------------
237 //-- Video URL
238 Row {
239 spacing: ScreenTools.defaultFontPixelWidth
240 QGCLabel {
241 width: _labelWidth
242 anchors.baseline: videoUrlField.baseline
243 text: qsTr("Video URL:")
244 }
245 QGCTextField {
246 id: videoUrlField
247 text: _mavlinkLogManager.videoURL
248 width: _valueWidth
249 enabled: !_disableDataPersistence
250 inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhUrlCharactersOnly
251 anchors.verticalCenter: parent.verticalCenter
252 }
253 }
254 //-----------------------------------------------------------------
255 //-- Wind Speed
256 Row {
257 spacing: ScreenTools.defaultFontPixelWidth
258 QGCLabel {
259 width: _labelWidth
260 anchors.baseline: windCombo.baseline
261 text: qsTr("Wind Speed:")
262 }
263 QGCComboBox {
264 id: windCombo
265 width: _valueWidth
266 enabled: !_disableDataPersistence
267 textRole: "text"
268 model: ListModel {
269 id: windItems
270 ListElement { text: qsTr("Please Select"); value: -1 }
271 ListElement { text: qsTr("Calm"); value: 0 }
272 ListElement { text: qsTr("Breeze"); value: 5 }
273 ListElement { text: qsTr("Gale"); value: 8 }
274 ListElement { text: qsTr("Storm"); value: 10 }
275 }
276 onActivated: (index) => {
277 saveItems();
278 _mavlinkLogManager.windSpeed = windItems.get(index).value
279 //console.log('Set Wind: ' + windItems.get(index).value)
280 }
281 Component.onCompleted: {
282 for(var i = 0; i < windItems.count; i++) {
283 if(windItems.get(i).value === _mavlinkLogManager.windSpeed) {
284 windCombo.currentIndex = i;
285 //console.log('Wind: ' + windItems.get(i).value)
286 break;
287 }
288 }
289 }
290 }
291 }
292 //-----------------------------------------------------------------
293 //-- Flight Rating
294 Row {
295 spacing: ScreenTools.defaultFontPixelWidth
296 QGCLabel {
297 width: _labelWidth
298 anchors.baseline: ratingCombo.baseline
299 text: qsTr("Flight Rating:")
300 }
301 QGCComboBox {
302 id: ratingCombo
303 width: _valueWidth
304 enabled: !_disableDataPersistence
305 textRole: "text"
306 model: ListModel {
307 id: ratingItems
308 ListElement { text: qsTr("Please Select"); value: "notset"}
309 ListElement { text: qsTr("Crashed (Pilot Error)"); value: "crash_pilot" }
310 ListElement { text: qsTr("Crashed (Software or Hardware issue)"); value: "crash_sw_hw" }
311 ListElement { text: qsTr("Unsatisfactory"); value: "unsatisfactory" }
312 ListElement { text: qsTr("Good"); value: "good" }
313 ListElement { text: qsTr("Great"); value: "great" }
314 }
315 onActivated: (index) => {
316 saveItems();
317 _mavlinkLogManager.rating = ratingItems.get(index).value
318 //console.log('Set Rating: ' + ratingItems.get(index).value)
319 }
320 Component.onCompleted: {
321 for(var i = 0; i < ratingItems.count; i++) {
322 if(ratingItems.get(i).value === _mavlinkLogManager.rating) {
323 ratingCombo.currentIndex = i;
324 //console.log('Rating: ' + ratingItems.get(i).value)
325 break;
326 }
327 }
328 }
329 }
330 }
331 //-----------------------------------------------------------------
332 //-- Feedback
333 Row {
334 spacing: ScreenTools.defaultFontPixelWidth
335 QGCLabel {
336 width: _labelWidth
337 text: qsTr("Additional Feedback:")
338 }
339 TextArea {
340 id: feedbackTextArea
341 width: _valueWidth
342 height: ScreenTools.defaultFontPixelHeight * 4
343 font.pointSize: ScreenTools.defaultFontPointSize
344 text: _mavlinkLogManager.feedback
345 enabled: !_disableDataPersistence
346 color: qgcPal.textFieldText
347 background: Rectangle { color: qgcPal.textField }
348 }
349 }
350 //-----------------------------------------------------------------
351 //-- Public Log
352 QGCCheckBox {
353 text: qsTr("Make this log publicly available")
354 checked: _mavlinkLogManager.publicLog
355 enabled: !_disableDataPersistence
356 onClicked: {
357 _mavlinkLogManager.publicLog = checked
358 }
359 }
360 //-----------------------------------------------------------------
361 //-- Automatic Upload
362 QGCCheckBox {
363 id: autoUploadCheck
364 text: qsTr("Enable automatic log uploads")
365 checked: _mavlinkLogManager.enableAutoUpload
366 enabled: !_disableDataPersistence
367 onClicked: {
368 saveItems();
369 if(checked && _mavlinkLogManager.emailAddress === "")
370 emptyEmailDialog.open()
371 }
372 }
373 //-----------------------------------------------------------------
374 //-- Delete log after upload
375 QGCCheckBox {
376 text: qsTr("Delete log file after uploading")
377 checked: _mavlinkLogManager.deleteAfterUpload
378 enabled: autoUploadCheck.checked && !_disableDataPersistence
379 onClicked: {
380 _mavlinkLogManager.deleteAfterUpload = checked
381 }
382 }
383 }
384 }
385 //-----------------------------------------------------------------
386 //-- Log Files
387 Item {
388 width: __mavlinkRoot.width * 0.8
389 height: logFilesLabel.height
390 anchors.margins: ScreenTools.defaultFontPixelWidth
391 anchors.horizontalCenter: parent.horizontalCenter
392 visible: _showMavlinkLog
393 QGCLabel {
394 id: logFilesLabel
395 text: qsTr("Saved Log Files")
396 font.bold: true
397 }
398 }
399 Rectangle {
400 height: logFilesColumn.height + (ScreenTools.defaultFontPixelHeight * 2)
401 width: __mavlinkRoot.width * 0.8
402 color: qgcPal.windowShade
403 anchors.margins: ScreenTools.defaultFontPixelWidth
404 anchors.horizontalCenter: parent.horizontalCenter
405 visible: _showMavlinkLog
406 Column {
407 id: logFilesColumn
408 spacing: _columnSpacing * 4
409 anchors.centerIn: parent
410 width: ScreenTools.defaultFontPixelWidth * 68
411 Rectangle {
412 width: ScreenTools.defaultFontPixelWidth * 64
413 height: ScreenTools.defaultFontPixelHeight * 14
414 anchors.horizontalCenter: parent.horizontalCenter
415 color: qgcPal.window
416 border.color: qgcPal.text
417 border.width: 0.5
418 QGCListView {
419 width: ScreenTools.defaultFontPixelWidth * 56
420 height: ScreenTools.defaultFontPixelHeight * 12
421 anchors.centerIn: parent
422 orientation: ListView.Vertical
423 model: _mavlinkLogManager.logFiles
424 clip: true
425 delegate: Rectangle {
426 width: ScreenTools.defaultFontPixelWidth * 52
427 height: selectCheck.height
428 color: qgcPal.window
429 Row {
430 width: ScreenTools.defaultFontPixelWidth * 50
431 anchors.centerIn: parent
432 spacing: ScreenTools.defaultFontPixelWidth
433 QGCCheckBox {
434 id: selectCheck
435 width: ScreenTools.defaultFontPixelWidth * 4
436 checked: object.selected
437 enabled: !object.writing && !object.uploading
438 anchors.verticalCenter: parent.verticalCenter
439 onClicked: {
440 object.selected = checked
441 }
442 }
443 QGCLabel {
444 text: object.name
445 width: ScreenTools.defaultFontPixelWidth * 28
446 color: object.writing ? qgcPal.warningText : qgcPal.text
447 anchors.verticalCenter: parent.verticalCenter
448 }
449 QGCLabel {
450 text: Number(object.size).toLocaleString(Qt.locale(), 'f', 0)
451 visible: !object.uploading && !object.uploaded
452 width: ScreenTools.defaultFontPixelWidth * 20;
453 color: object.writing ? qgcPal.warningText : qgcPal.text
454 horizontalAlignment: Text.AlignRight
455 anchors.verticalCenter: parent.verticalCenter
456 }
457 QGCLabel {
458 text: qsTr("Uploaded")
459 visible: object.uploaded
460 width: ScreenTools.defaultFontPixelWidth * 20;
461 horizontalAlignment: Text.AlignRight
462 anchors.verticalCenter: parent.verticalCenter
463 }
464 ProgressBar {
465 visible: object.uploading && !object.uploaded
466 width: ScreenTools.defaultFontPixelWidth * 20;
467 height: ScreenTools.defaultFontPixelHeight
468 anchors.verticalCenter: parent.verticalCenter
469 from: 0
470 to: 100
471 value: object.progress * 100.0
472 }
473 }
474 }
475 }
476 }
477 Row {
478 spacing: ScreenTools.defaultFontPixelWidth
479 anchors.horizontalCenter: parent.horizontalCenter
480 QGCButton {
481 text: qsTr("Check All")
482 enabled: !_mavlinkLogManager.uploading && !_mavlinkLogManager.logRunning
483 onClicked: {
484 for(var i = 0; i < _mavlinkLogManager.logFiles.count; i++) {
485 var logFile = _mavlinkLogManager.logFiles.get(i)
486 logFile.selected = true
487 }
488 }
489 }
490 QGCButton {
491 text: qsTr("Check None")
492 enabled: !_mavlinkLogManager.uploading && !_mavlinkLogManager.logRunning
493 onClicked: {
494 for(var i = 0; i < _mavlinkLogManager.logFiles.count; i++) {
495 var logFile = _mavlinkLogManager.logFiles.get(i)
496 logFile.selected = false
497 }
498 }
499 }
500 QGCButton {
501 text: qsTr("Delete Selected")
502 enabled: _selectedCount > 0 && !_mavlinkLogManager.uploading && !_mavlinkLogManager.logRunning
503 onClicked: deleteDialog.open()
504 MessageDialog {
505 id: deleteDialog
506 visible: false
507 //icon: StandardIcon.Warning
508 buttons: MessageDialog.Yes | MessageDialog.No
509 title: qsTr("Delete Selected Log Files")
510 text: qsTr("Confirm deleting selected log files?")
511 onButtonClicked: function (button, role) {
512 switch (button) {
513 case MessageDialog.Yes:
514 _mavlinkLogManager.deleteLog()
515 break;
516 }
517 }
518 }
519 }
520 QGCButton {
521 text: qsTr("Upload Selected")
522 enabled: _selectedCount > 0 && !_mavlinkLogManager.uploading && !_mavlinkLogManager.logRunning && !_uploadedSelected
523 visible: !_mavlinkLogManager.uploading
524 onClicked: {
525 saveItems();
526 if(_mavlinkLogManager.emailAddress === "")
527 emptyEmailDialog.open()
528 else
529 uploadDialog.open()
530 }
531 MessageDialog {
532 id: uploadDialog
533 visible: false
534 //icon: StandardIcon.Question
535 buttons: MessageDialog.Yes | MessageDialog.No
536 title: qsTr("Upload Selected Log Files")
537 text: qsTr("Confirm uploading selected log files?")
538 onButtonClicked: function (button, role) {
539 switch (button) {
540 case MessageDialog.Yes:
541 _mavlinkLogManager.uploadLog()
542 break;
543 }
544 }
545 }
546 }
547 QGCButton {
548 text: qsTr("Cancel")
549 enabled: _mavlinkLogManager.uploading && !_mavlinkLogManager.logRunning
550 visible: _mavlinkLogManager.uploading
551 onClicked: cancelDialog.open()
552 MessageDialog {
553 id: cancelDialog
554 visible: false
555 //icon: StandardIcon.Warning
556 buttons: MessageDialog.Yes | MessageDialog.No
557 title: qsTr("Cancel Upload")
558 text: qsTr("Confirm canceling the upload process?")
559 onButtonClicked: function (button, role) {
560 switch (button) {
561 case MessageDialog.Yes:
562 _mavlinkLogManager.cancelUpload()
563 break;
564 }
565 }
566 }
567 }
568 }
569 }
570 }
571 }
572 }
573}