diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 4243d6100e1c9ae3da0a65d5de6e62b15d81d7a1..9a1431a5ab1df0de5b2c7c4f3e111afe584fdbb0 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -1,4 +1,4 @@ - /**************************************************************************** +/**************************************************************************** * * (c) 2009-2016 QGROUNDCONTROL PROJECT * @@ -82,19 +82,19 @@ #include "SettingsManager.h" #ifndef NO_SERIAL_LINK - #include "SerialLink.h" +#include "SerialLink.h" #endif #ifndef __mobile__ - #include "QGCFileDialog.h" - #include "QGCMessageBox.h" - #include "FirmwareUpgradeController.h" - #include "MainWindow.h" - #include "GeoTagController.h" +#include "QGCFileDialog.h" +#include "QGCMessageBox.h" +#include "FirmwareUpgradeController.h" +#include "MainWindow.h" +#include "GeoTagController.h" #endif #ifdef QGC_RTLAB_ENABLED - #include "OpalLink.h" +#include "OpalLink.h" #endif #ifdef Q_OS_LINUX @@ -162,15 +162,15 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) #ifdef __mobile__ : QGuiApplication(argc, argv) , _qmlAppEngine(NULL) -#else + #else : QApplication(argc, argv) -#endif + #endif , _runningUnitTests(unitTesting) , _fakeMobile(false) , _settingsUpgraded(false) -#ifdef QT_DEBUG + #ifdef QT_DEBUG , _testHighDPI(false) -#endif + #endif , _toolbox(NULL) , _bluetoothAvailable(false) , _lastKnownHomePosition(37.803784, -122.462276, 0.0) @@ -237,9 +237,9 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) { "--clear-settings", &fClearSettingsOptions, NULL }, { "--logging", &logging, &loggingOptions }, { "--fake-mobile", &_fakeMobile, NULL }, -#ifdef QT_DEBUG + #ifdef QT_DEBUG { "--test-high-dpi", &_testHighDPI, NULL }, -#endif + #endif // Add additional command line option flags here }; @@ -498,33 +498,67 @@ void QGCApplication::criticalMessageBoxOnMainThread(const QString& title, const } #ifndef __mobile__ -void QGCApplication::saveTempFlightDataLogOnMainThread(QString tempLogfile) +void QGCApplication::saveTelemetryLogOnMainThread(QString tempLogfile) { - bool saveError; - do{ - saveError = false; - QString saveFilename = QGCFileDialog::getSaveFileName( - MainWindow::instance(), - tr("Save Flight Data Log"), - QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), - tr("Flight Data Log Files (*.mavlink)"), - "mavlink"); - - if (!saveFilename.isEmpty()) { - // if file exsits already, try to remove it first to overwrite it - if(QFile::exists(saveFilename) && !QFile::remove(saveFilename)){ - // if the file cannot be removed, prompt user and ask new path - saveError = true; - QGCMessageBox::warning("File Error","Could not overwrite existing file.\nPlease provide a different file name to save to."); - } else if(!QFile::copy(tempLogfile, saveFilename)) { - // if file could not be copied, prompt user and ask new path - saveError = true; - QGCMessageBox::warning("File Error","Could not create file.\nPlease provide a different file name to save to."); - } + // The vehicle is gone now and we are shutting down so we need to use a message box for errors to hold shutdown and show the error + if (_checkTelemetrySavePath(true /* useMessageBox */)) { + + QString saveDirPath = _toolbox->settingsManager()->appSettings()->telemetrySavePath()->rawValue().toString(); + QDir saveDir(saveDirPath); + + QString nameFormat("%1%2.mavlink"); + QString dtFormat("yyyy-MMM-dd hh-mm-ss"); + + int tryIndex = 1; + QString saveFileName = nameFormat.arg(QDateTime::currentDateTime().toString(dtFormat)).arg(""); + while (saveDir.exists(saveFileName)) { + saveFileName = nameFormat.arg(QDateTime::currentDateTime().toString(dtFormat)).arg(QStringLiteral(".%1").arg(tryIndex++)); + } + QString saveFilePath = saveDir.absoluteFilePath(saveFileName); + + QFile tempFile(tempLogfile); + if (!tempFile.copy(saveFilePath)) { + QGCMessageBox::warning(tr("Telemetry save error"), tr("Unable to save telemetry log. Error copying telemetry to '%1': '%2'.").arg(saveFilePath).arg(tempFile.errorString())); } - } while(saveError); // if the file could not be overwritten, ask for new file + } + QFile::remove(tempLogfile); } + +void QGCApplication::checkTelemetrySavePathOnMainThread(void) +{ + // This is called with an active vehicle so don't pop message boxes which holds ui thread + _checkTelemetrySavePath(false /* useMessageBox */); +} + +bool QGCApplication::_checkTelemetrySavePath(bool useMessageBox) +{ + QString errorTitle = tr("Telemetry save error"); + + QString saveDirPath = _toolbox->settingsManager()->appSettings()->telemetrySavePath()->rawValue().toString(); + if (saveDirPath.isEmpty()) { + QString error = tr("Unable to save telemetry log. Telemetry save directory is not set."); + if (useMessageBox) { + QGCMessageBox::warning(errorTitle, error); + } else { + showMessage(error); + } + return false; + } + + QDir saveDir(saveDirPath); + if (!saveDir.exists()) { + QString error = tr("Unable to save telemetry log. Telemetry save directory \"%1\" does not exist.").arg(saveDirPath); + if (useMessageBox) { + QGCMessageBox::warning(errorTitle, error); + } else { + showMessage(error); + } + return false; + } + + return true; +} #endif void QGCApplication::_loadCurrentStyleSheet(void) diff --git a/src/QGCApplication.h b/src/QGCApplication.h index 91bb3a28745a17a3833d12d508e89a9efd1b2ac2..bdc71476ce3c9e58efb3a8b87769a30a68cd402e 100644 --- a/src/QGCApplication.h +++ b/src/QGCApplication.h @@ -116,8 +116,11 @@ public slots: void qmlAttemptWindowClose(void); #ifndef __mobile__ - /// Save the specified Flight Data Log - void saveTempFlightDataLogOnMainThread(QString tempLogfile); + /// Save the specified telemetry Log + void saveTelemetryLogOnMainThread(QString tempLogfile); + + /// Check that the telemetry save path is set correctly + void checkTelemetrySavePathOnMainThread(void); #endif signals: @@ -150,6 +153,8 @@ public: /// Shutdown the application object void _shutdown(void); + bool _checkTelemetrySavePath(bool useMessageBox); + private slots: void _missingParamsDisplay(void); diff --git a/src/Settings/App.SettingsGroup.json b/src/Settings/App.SettingsGroup.json index d73f459253917a3371998b3a4a5867a99f8230bb..4632012ff671d6679ee6554a230c7dad20954ad4 100644 --- a/src/Settings/App.SettingsGroup.json +++ b/src/Settings/App.SettingsGroup.json @@ -64,15 +64,15 @@ }, { "name": "PromptFLightDataSave", - "shortDescription": "Prompt to save Flight Data Log after each flight", - "longDescription": "If this option is enabled you will be prompted to save Flight Data Log after each flight completes.", + "shortDescription": "Save telemetry Log after each flight", + "longDescription": "If this option is enabled a telemetry will be saved after each flight completes.", "type": "bool", "defaultValue": true }, { "name": "PromptFLightDataSaveNotArmed", - "shortDescription": "Prompt to save Flight Data Log even if vehicle was not armed", - "longDescription": "If this option is enabled you will be prompted to save Flight Data Log even if vehicle was never armed.", + "shortDescription": "Save telemetry log even if vehicle was not armed", + "longDescription": "If this option is enabled a telemtry log will be saved even if vehicle was never armed.", "type": "bool", "defaultValue": false }, @@ -114,5 +114,12 @@ "longDescription": "Show large compass on instrument panel", "type": "bool", "defaultValue": false +}, +{ + "name": "TelemetrySavePath", + "shortDescription": "Telemetry log save directory", + "longDescription": "The directory to which telemetry logs are automatically saved to.", + "type": "string", + "defaultValue": "" } ] diff --git a/src/Settings/AppSettings.cc b/src/Settings/AppSettings.cc index 22e0f3d56d16dda9a704f6d0d3216ded8e885cc9..5a370d333dc6c2764300605ab54bc43400e8e5d8 100644 --- a/src/Settings/AppSettings.cc +++ b/src/Settings/AppSettings.cc @@ -22,13 +22,14 @@ const char* AppSettings::offlineEditingHoverSpeedSettingsName = "Offline const char* AppSettings::batteryPercentRemainingAnnounceSettingsName = "batteryPercentRemainingAnnounce"; const char* AppSettings::defaultMissionItemAltitudeSettingsName = "DefaultMissionItemAltitude"; const char* AppSettings::missionAutoLoadDirSettingsName = "MissionAutoLoadDir"; -const char* AppSettings::promptFlightTelemetrySaveName = "PromptFLightDataSave"; -const char* AppSettings::promptFlightTelemetrySaveNotArmedName = "PromptFLightDataSaveNotArmed"; +const char* AppSettings::telemetrySaveName = "PromptFLightDataSave"; +const char* AppSettings::telemetrySaveNotArmedName = "PromptFLightDataSaveNotArmed"; const char* AppSettings::audioMutedName = "AudioMuted"; const char* AppSettings::virtualJoystickName = "VirtualTabletJoystick"; const char* AppSettings::appFontPointSizeName = "BaseDeviceFontPointSize"; const char* AppSettings::indoorPaletteName = "StyleIsDark"; const char* AppSettings::showLargeCompassName = "ShowLargeCompass"; +const char* AppSettings::telemetrySavePathName = "TelemetrySavePath"; AppSettings::AppSettings(QObject* parent) : SettingsGroup(appSettingsGroupName, QString() /* root settings group */, parent) @@ -39,13 +40,14 @@ AppSettings::AppSettings(QObject* parent) , _batteryPercentRemainingAnnounceFact(NULL) , _defaultMissionItemAltitudeFact(NULL) , _missionAutoLoadDirFact(NULL) - , _promptFlightTelemetrySaveFact(NULL) - , _promptFlightTelemetrySaveNotArmedFact(NULL) + , _telemetrySaveFact(NULL) + , _telemetrySaveNotArmedFact(NULL) , _audioMutedFact(NULL) , _virtualJoystickFact(NULL) , _appFontPointSizeFact(NULL) , _indoorPaletteFact(NULL) , _showLargeCompassFact(NULL) + , _telemetrySavePathFact(NULL) { QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); qmlRegisterUncreatableType("QGroundControl.SettingsManager", 1, 0, "AppSettings", "Reference only"); @@ -113,22 +115,22 @@ Fact* AppSettings::missionAutoLoadDir(void) return _missionAutoLoadDirFact; } -Fact* AppSettings::promptFlightTelemetrySave(void) +Fact* AppSettings::telemetrySave(void) { - if (!_promptFlightTelemetrySaveFact) { - _promptFlightTelemetrySaveFact = _createSettingsFact(promptFlightTelemetrySaveName); + if (!_telemetrySaveFact) { + _telemetrySaveFact = _createSettingsFact(telemetrySaveName); } - return _promptFlightTelemetrySaveFact; + return _telemetrySaveFact; } -Fact* AppSettings::promptFlightTelemetrySaveNotArmed(void) +Fact* AppSettings::telemetrySaveNotArmed(void) { - if (!_promptFlightTelemetrySaveNotArmedFact) { - _promptFlightTelemetrySaveNotArmedFact = _createSettingsFact(promptFlightTelemetrySaveNotArmedName); + if (!_telemetrySaveNotArmedFact) { + _telemetrySaveNotArmedFact = _createSettingsFact(telemetrySaveNotArmedName); } - return _promptFlightTelemetrySaveNotArmedFact; + return _telemetrySaveNotArmedFact; } Fact* AppSettings::audioMuted(void) @@ -183,3 +185,12 @@ Fact* AppSettings::showLargeCompass(void) return _showLargeCompassFact; } +Fact* AppSettings::telemetrySavePath(void) +{ + if (!_telemetrySavePathFact) { + _telemetrySavePathFact = _createSettingsFact(telemetrySavePathName); + } + + return _telemetrySavePathFact; +} + diff --git a/src/Settings/AppSettings.h b/src/Settings/AppSettings.h index 88b2be4bf7d9e7010cc348d812b75d9acc2544c3..91f1d2031b6d288add7bb4996a007d0aa7134743 100644 --- a/src/Settings/AppSettings.h +++ b/src/Settings/AppSettings.h @@ -26,13 +26,14 @@ public: Q_PROPERTY(Fact* batteryPercentRemainingAnnounce READ batteryPercentRemainingAnnounce CONSTANT) Q_PROPERTY(Fact* defaultMissionItemAltitude READ defaultMissionItemAltitude CONSTANT) Q_PROPERTY(Fact* missionAutoLoadDir READ missionAutoLoadDir CONSTANT) - Q_PROPERTY(Fact* promptFlightTelemetrySave READ promptFlightTelemetrySave CONSTANT) - Q_PROPERTY(Fact* promptFlightTelemetrySaveNotArmed READ promptFlightTelemetrySaveNotArmed CONSTANT) + Q_PROPERTY(Fact* telemetrySave READ telemetrySave CONSTANT) + Q_PROPERTY(Fact* telemetrySaveNotArmed READ telemetrySaveNotArmed CONSTANT) Q_PROPERTY(Fact* audioMuted READ audioMuted CONSTANT) Q_PROPERTY(Fact* virtualJoystick READ virtualJoystick CONSTANT) Q_PROPERTY(Fact* appFontPointSize READ appFontPointSize CONSTANT) Q_PROPERTY(Fact* indoorPalette READ indoorPalette CONSTANT) Q_PROPERTY(Fact* showLargeCompass READ showLargeCompass CONSTANT) + Q_PROPERTY(Fact* telemetrySavePath READ telemetrySavePath CONSTANT) Fact* offlineEditingFirmwareType (void); Fact* offlineEditingVehicleType (void); @@ -41,13 +42,14 @@ public: Fact* batteryPercentRemainingAnnounce (void); Fact* defaultMissionItemAltitude (void); Fact* missionAutoLoadDir (void); - Fact* promptFlightTelemetrySave (void); - Fact* promptFlightTelemetrySaveNotArmed (void); + Fact* telemetrySave (void); + Fact* telemetrySaveNotArmed (void); Fact* audioMuted (void); Fact* virtualJoystick (void); Fact* appFontPointSize (void); Fact* indoorPalette (void); Fact* showLargeCompass (void); + Fact* telemetrySavePath (void); static const char* appSettingsGroupName; @@ -58,13 +60,14 @@ public: static const char* batteryPercentRemainingAnnounceSettingsName; static const char* defaultMissionItemAltitudeSettingsName; static const char* missionAutoLoadDirSettingsName; - static const char* promptFlightTelemetrySaveName; - static const char* promptFlightTelemetrySaveNotArmedName; + static const char* telemetrySaveName; + static const char* telemetrySaveNotArmedName; static const char* audioMutedName; static const char* virtualJoystickName; static const char* appFontPointSizeName; static const char* indoorPaletteName; static const char* showLargeCompassName; + static const char* telemetrySavePathName; private slots: void _indoorPaletteChanged(void); @@ -77,13 +80,14 @@ private: SettingsFact* _batteryPercentRemainingAnnounceFact; SettingsFact* _defaultMissionItemAltitudeFact; SettingsFact* _missionAutoLoadDirFact; - SettingsFact* _promptFlightTelemetrySaveFact; - SettingsFact* _promptFlightTelemetrySaveNotArmedFact; + SettingsFact* _telemetrySaveFact; + SettingsFact* _telemetrySaveNotArmedFact; SettingsFact* _audioMutedFact; SettingsFact* _virtualJoystickFact; SettingsFact* _appFontPointSizeFact; SettingsFact* _indoorPaletteFact; SettingsFact* _showLargeCompassFact; + SettingsFact* _telemetrySavePathFact; }; #endif diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc index 0d031a4f88a72fd664325ff23fb27ad2b0e5d4a3..8177221a86aff4ea944e3efd75e624941b231862 100644 --- a/src/comm/MAVLinkProtocol.cc +++ b/src/comm/MAVLinkProtocol.cc @@ -103,9 +103,10 @@ void MAVLinkProtocol::setToolbox(QGCToolbox *toolbox) } } - connect(this, &MAVLinkProtocol::protocolStatusMessage, _app, &QGCApplication::criticalMessageBoxOnMainThread); + connect(this, &MAVLinkProtocol::protocolStatusMessage, _app, &QGCApplication::criticalMessageBoxOnMainThread); #ifndef __mobile__ - connect(this, &MAVLinkProtocol::saveTempFlightDataLog, _app, &QGCApplication::saveTempFlightDataLogOnMainThread); + connect(this, &MAVLinkProtocol::saveTelemetryLog, _app, &QGCApplication::saveTelemetryLogOnMainThread); + connect(this, &MAVLinkProtocol::checkTelemetrySavePath, _app, &QGCApplication::checkTelemetrySavePathOnMainThread); #endif connect(_multiVehicleManager->vehicles(), &QmlObjectListModel::countChanged, this, &MAVLinkProtocol::_vehicleCountChanged); @@ -413,6 +414,7 @@ void MAVLinkProtocol::_startLogging(void) } qDebug() << "Temp log" << _tempLogFile.fileName(); + emit checkTelemetrySavePath(); _logSuspendError = false; } @@ -424,8 +426,8 @@ void MAVLinkProtocol::_stopLogging(void) if (_closeLogFile()) { // If the signals are not connected it means we are running a unit test. In that case just delete log files SettingsManager* settingsManager = _app->toolbox()->settingsManager(); - if ((_vehicleWasArmed || settingsManager->appSettings()->promptFlightTelemetrySaveNotArmed()->rawValue().toBool()) && settingsManager->appSettings()->promptFlightTelemetrySave()->rawValue().toBool()) { - emit saveTempFlightDataLog(_tempLogFile.fileName()); + if ((_vehicleWasArmed || settingsManager->appSettings()->telemetrySaveNotArmed()->rawValue().toBool()) && settingsManager->appSettings()->telemetrySave()->rawValue().toBool()) { + emit saveTelemetryLog(_tempLogFile.fileName()); } else { QFile::remove(_tempLogFile.fileName()); } @@ -452,12 +454,7 @@ void MAVLinkProtocol::checkForLostLogFiles(void) continue; } - // Give the user a chance to save the orphaned log file - emit protocolStatusMessage(tr("Found unsaved Flight Data"), - tr("This can happen if QGroundControl crashes during Flight Data collection. " - "If you want to save the unsaved Flight Data, select the file you want to save it to. " - "If you do not want to keep the Flight Data, select 'Cancel' on the next dialog.")); - emit saveTempFlightDataLog(fileInfo.filePath()); + emit saveTelemetryLog(fileInfo.filePath()); } } diff --git a/src/comm/MAVLinkProtocol.h b/src/comm/MAVLinkProtocol.h index 3d1cd165799d4f0d7fe5f7465645d4a026669544..7890061b6fbfd38a666f7220db55668419d9e53d 100644 --- a/src/comm/MAVLinkProtocol.h +++ b/src/comm/MAVLinkProtocol.h @@ -158,8 +158,11 @@ signals: void radioStatusChanged(LinkInterface* link, unsigned rxerrors, unsigned fixed, int rssi, int remrssi, unsigned txbuf, unsigned noise, unsigned remnoise); - /// @brief Emitted when a temporary log file is ready for saving - void saveTempFlightDataLog(QString tempLogfile); + /// Emitted when a temporary telemetry log file is ready for saving + void saveTelemetryLog(QString tempLogfile); + + /// Emitted when a telemetry log is started to save. + void checkTelemetrySavePath(void); private slots: void _vehicleCountChanged(int count); diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml index e6372e722971e9822feb16c7d8f40fcbb6e8b76b..6a74e62fd8cf455b42c1dfd47d39c5a290d19e18 100644 --- a/src/ui/preferences/GeneralSettings.qml +++ b/src/ui/preferences/GeneralSettings.qml @@ -37,6 +37,8 @@ QGCView { property Fact _appFontPointSize: QGroundControl.settingsManager.appSettings.appFontPointSize property real _labelWidth: ScreenTools.defaultFontPixelWidth * 15 property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30 + property Fact _telemPath: QGroundControl.settingsManager.appSettings.telemetrySavePath + property Fact _videoPath: QGroundControl.settingsManager.videoSettings.videoSavePath readonly property string _requiresRestart: qsTr("(Requires Restart)") @@ -205,26 +207,61 @@ QGCView { property Fact _audioMuted: QGroundControl.settingsManager.appSettings.audioMuted } + //----------------------------------------------------------------- - //-- Prompt Save Log + //-- Save telemetry log FactCheckBox { id: promptSaveLog - text: qsTr("Prompt to save Flight Data Log after each flight") - fact: _promptFlightTelemetrySave - visible: !ScreenTools.isMobile && _promptFlightTelemetrySave.visible + text: qsTr("Save telemetry log after each flight") + fact: _telemetrySave + visible: !ScreenTools.isMobile && _telemetrySave.visible - property Fact _promptFlightTelemetrySave: QGroundControl.settingsManager.appSettings.promptFlightTelemetrySave + property Fact _telemetrySave: QGroundControl.settingsManager.appSettings.telemetrySave } + //----------------------------------------------------------------- - //-- Prompt Save even if not armed + //-- Save even if not armed FactCheckBox { - text: qsTr("Prompt to save Flight Data Log even if vehicle was not armed") - fact: _promptFlightTelemetrySaveNotArmed - visible: !ScreenTools.isMobile && _promptFlightTelemetrySaveNotArmed.visible + text: qsTr("Save telemetry log even if vehicle was not armed") + fact: _telemetrySaveNotArmed + visible: !ScreenTools.isMobile && _telemetrySaveNotArmed.visible enabled: promptSaveLog.checked - property Fact _promptFlightTelemetrySaveNotArmed: QGroundControl.settingsManager.appSettings.promptFlightTelemetrySaveNotArmed + property Fact _telemetrySaveNotArmed: QGroundControl.settingsManager.appSettings.telemetrySaveNotArmed } + + //----------------------------------------------------------------- + //-- Telemetry save path + Row { + spacing: ScreenTools.defaultFontPixelWidth + visible: QGroundControl.settingsManager.appSettings.telemetrySavePath.visible + + QGCLabel { + anchors.baseline: telemBrowse.baseline + text: qsTr("Telemetry save path:") + enabled: promptSaveLog.checked + } + QGCLabel { + anchors.baseline: telemBrowse.baseline + text: _telemPath.value == "" ? qsTr("") : _telemPath.value + enabled: promptSaveLog.checked + } + QGCButton { + id: telemBrowse + text: "Browse" + enabled: promptSaveLog.checked + onClicked: telemDialog.visible = true + + FileDialog { + id: telemDialog + title: "Choose a location to save telemetry files." + folder: "file://" + _telemPath.value + selectFolder: true + onAccepted: _telemPath.value = QGroundControl.urlToLocalFile(telemDialog.fileUrl) + } + } + } + //----------------------------------------------------------------- //-- Clear settings QGCCheckBox { @@ -329,7 +366,7 @@ QGCView { FileDialog { id: autoloadDirPicker title: qsTr("Choose the location of mission file.") - folder: shortcuts.home + folder: "file://" + _autoLoadDir.value selectFolder: true onAccepted: _autoLoadDir.rawValue = QGroundControl.urlToLocalFile(autoloadDirPicker.fileUrl) } @@ -529,26 +566,27 @@ QGCView { Row { spacing: ScreenTools.defaultFontPixelWidth visible: QGroundControl.settingsManager.videoSettings.videoSavePath.visible && QGroundControl.videoManager.isGStreamer && QGroundControl.videoManager.recordingEnabled + QGCLabel { - anchors.baseline: pathField.baseline - text: qsTr("Save Path:") - width: _labelWidth + anchors.baseline: videoBrowse.baseline + text: qsTr("Save path:") + enabled: promptSaveLog.checked } - FactTextField { - id: pathField - width: _editFieldWidth - fact: QGroundControl.settingsManager.videoSettings.videoSavePath + QGCLabel { + anchors.baseline: videoBrowse.baseline + text: _videoPath.value == "" ? qsTr("") : _videoPath.value } QGCButton { + id: videoBrowse text: "Browse" - onClicked: videoLocationFileDialog.visible = true + onClicked: videoDialog.visible = true FileDialog { - id: videoLocationFileDialog + id: videoDialog title: "Choose a location to save video files." - folder: shortcuts.home + folder: "file://" + _videoPath.value selectFolder: true - onAccepted: QGroundControl.settingsManager.videoSettings.videoSavePath.value = QGroundControl.urlToLocalFile(videoLocationFileDialog.fileUrl) + onAccepted: _videoPath.value = QGroundControl.urlToLocalFile(videoDialog.fileUrl) } } }