Commit 42c11316 authored by Don Gagne's avatar Don Gagne

New QGCMobileFileDialog

- Convert mission load/save to it
- Allow parameter load/save on mobile
parent a8fa3ebc
...@@ -269,6 +269,7 @@ HEADERS += \ ...@@ -269,6 +269,7 @@ HEADERS += \
src/QGCGeo.h \ src/QGCGeo.h \
src/QGCLoggingCategory.h \ src/QGCLoggingCategory.h \
src/QGCMapPalette.h \ src/QGCMapPalette.h \
src/QGCMobileFileDialogController.h \
src/QGCPalette.h \ src/QGCPalette.h \
src/QGCQmlWidgetHolder.h \ src/QGCQmlWidgetHolder.h \
src/QGCQuickWidget.h \ src/QGCQuickWidget.h \
...@@ -397,6 +398,7 @@ SOURCES += \ ...@@ -397,6 +398,7 @@ SOURCES += \
src/QGCFileDownload.cc \ src/QGCFileDownload.cc \
src/QGCLoggingCategory.cc \ src/QGCLoggingCategory.cc \
src/QGCMapPalette.cc \ src/QGCMapPalette.cc \
src/QGCMobileFileDialogController.cc \
src/QGCPalette.cc \ src/QGCPalette.cc \
src/QGCQuickWidget.cc \ src/QGCQuickWidget.cc \
src/QGCQmlWidgetHolder.cpp \ src/QGCQmlWidgetHolder.cpp \
......
...@@ -64,13 +64,14 @@ ...@@ -64,13 +64,14 @@
<file alias="QGroundControl/Controls/QGCButton.qml">src/QmlControls/QGCButton.qml</file> <file alias="QGroundControl/Controls/QGCButton.qml">src/QmlControls/QGCButton.qml</file>
<file alias="QGroundControl/Controls/QGCCheckBox.qml">src/QmlControls/QGCCheckBox.qml</file> <file alias="QGroundControl/Controls/QGCCheckBox.qml">src/QmlControls/QGCCheckBox.qml</file>
<file alias="QGroundControl/Controls/QGCColoredImage.qml">src/QmlControls/QGCColoredImage.qml</file> <file alias="QGroundControl/Controls/QGCColoredImage.qml">src/QmlControls/QGCColoredImage.qml</file>
<file alias="QGroundControl/Controls/QGCComboBox.qml">src/QmlControls/QGCComboBox.qml</file>
<file alias="QGroundControl/Controls/QGCFlickable.qml">src/QmlControls/QGCFlickable.qml</file> <file alias="QGroundControl/Controls/QGCFlickable.qml">src/QmlControls/QGCFlickable.qml</file>
<file alias="QGroundControl/Controls/QGCPipable.qml">src/QmlControls/QGCPipable.qml</file>
<file alias="QGroundControl/Controls/QGCFlickableVerticalIndicator.qml">src/QmlControls/QGCFlickableVerticalIndicator.qml</file> <file alias="QGroundControl/Controls/QGCFlickableVerticalIndicator.qml">src/QmlControls/QGCFlickableVerticalIndicator.qml</file>
<file alias="QGroundControl/Controls/QGCFlickableHorizontalIndicator.qml">src/QmlControls/QGCFlickableHorizontalIndicator.qml</file> <file alias="QGroundControl/Controls/QGCFlickableHorizontalIndicator.qml">src/QmlControls/QGCFlickableHorizontalIndicator.qml</file>
<file alias="QGroundControl/Controls/QGCComboBox.qml">src/QmlControls/QGCComboBox.qml</file>
<file alias="QGroundControl/Controls/QGCLabel.qml">src/QmlControls/QGCLabel.qml</file> <file alias="QGroundControl/Controls/QGCLabel.qml">src/QmlControls/QGCLabel.qml</file>
<file alias="QGroundControl/Controls/QGCMobileFileDialog.qml">src/QmlControls/QGCMobileFileDialog.qml</file>
<file alias="QGroundControl/Controls/QGCMovableItem.qml">src/QmlControls/QGCMovableItem.qml</file> <file alias="QGroundControl/Controls/QGCMovableItem.qml">src/QmlControls/QGCMovableItem.qml</file>
<file alias="QGroundControl/Controls/QGCPipable.qml">src/QmlControls/QGCPipable.qml</file>
<file alias="QGroundControl/Controls/QGCRadioButton.qml">src/QmlControls/QGCRadioButton.qml</file> <file alias="QGroundControl/Controls/QGCRadioButton.qml">src/QmlControls/QGCRadioButton.qml</file>
<file alias="QGroundControl/Controls/QGCTextField.qml">src/QmlControls/QGCTextField.qml</file> <file alias="QGroundControl/Controls/QGCTextField.qml">src/QmlControls/QGCTextField.qml</file>
<file alias="QGroundControl/Controls/QGCToolBarButton.qml">src/QmlControls/QGCToolBarButton.qml</file> <file alias="QGroundControl/Controls/QGCToolBarButton.qml">src/QmlControls/QGCToolBarButton.qml</file>
......
...@@ -92,7 +92,7 @@ QGCView { ...@@ -92,7 +92,7 @@ QGCView {
if (ScreenTools.isMobile) { if (ScreenTools.isMobile) {
_root.showDialog(mobileFilePicker, "Select Mission File", _root.showDialogDefaultWidth, StandardButton.Yes | StandardButton.Cancel) _root.showDialog(mobileFilePicker, "Select Mission File", _root.showDialogDefaultWidth, StandardButton.Yes | StandardButton.Cancel)
} else { } else {
controller.loadMissionFromFile() controller.loadMissionFromFilePicker()
fitViewportToMissionItems() fitViewportToMissionItems()
} }
} }
...@@ -191,23 +191,13 @@ QGCView { ...@@ -191,23 +191,13 @@ QGCView {
Component { Component {
id: mobileFilePicker id: mobileFilePicker
QGCViewDialog { QGCMobileFileDialog {
ListView { openDialog: true
anchors.margins: _margin fileExtension: QGroundControl.missionFileExtension
anchors.fill: parent
spacing: _margin / 2
orientation: ListView.Vertical
model: controller.getMobileMissionFiles()
delegate: QGCButton {
text: modelData
onClicked: { onFilenameReturned: {
hideDialog() controller.loadMissionFromFile(filename)
controller.loadMobileMissionFromFile(modelData) fitViewportToMissionItems()
fitViewportToMissionItems()
}
}
} }
} }
} }
...@@ -215,24 +205,12 @@ QGCView { ...@@ -215,24 +205,12 @@ QGCView {
Component { Component {
id: mobileFileSaver id: mobileFileSaver
QGCViewDialog { QGCMobileFileDialog {
function accept() { openDialog: false
hideDialog() fileExtension: QGroundControl.missionFileExtension
controller.saveMobileMissionToFile(filenameTextField.text)
}
Column {
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelHeight
QGCLabel { onFilenameReturned: {
text: "File name:" controller.saveMissionToFile(filename)
}
QGCTextField {
id: filenameTextField
}
} }
} }
} }
......
...@@ -422,7 +422,7 @@ bool MissionController::_loadTextMissionFile(QTextStream& stream, QmlObjectListM ...@@ -422,7 +422,7 @@ bool MissionController::_loadTextMissionFile(QTextStream& stream, QmlObjectListM
return true; return true;
} }
void MissionController::_loadMissionFromFile(const QString& filename) void MissionController::loadMissionFromFile(const QString& filename)
{ {
QString errorString; QString errorString;
...@@ -482,7 +482,7 @@ void MissionController::_loadMissionFromFile(const QString& filename) ...@@ -482,7 +482,7 @@ void MissionController::_loadMissionFromFile(const QString& filename)
_initAllVisualItems(); _initAllVisualItems();
} }
void MissionController::loadMissionFromFile(void) void MissionController::loadMissionFromFilePicker(void)
{ {
#ifndef __mobile__ #ifndef __mobile__
QString filename = QGCFileDialog::getOpenFileName(NULL, "Select Mission File to load", QString(), "Mission file (*.mission);;All Files (*.*)"); QString filename = QGCFileDialog::getOpenFileName(NULL, "Select Mission File to load", QString(), "Mission file (*.mission);;All Files (*.*)");
...@@ -490,11 +490,11 @@ void MissionController::loadMissionFromFile(void) ...@@ -490,11 +490,11 @@ void MissionController::loadMissionFromFile(void)
if (filename.isEmpty()) { if (filename.isEmpty()) {
return; return;
} }
_loadMissionFromFile(filename); loadMissionFromFile(filename);
#endif #endif
} }
void MissionController::_saveMissionToFile(const QString& filename) void MissionController::saveMissionToFile(const QString& filename)
{ {
qDebug() << filename; qDebug() << filename;
...@@ -504,7 +504,7 @@ void MissionController::_saveMissionToFile(const QString& filename) ...@@ -504,7 +504,7 @@ void MissionController::_saveMissionToFile(const QString& filename)
QString missionFilename = filename; QString missionFilename = filename;
if (!QFileInfo(filename).fileName().contains(".")) { if (!QFileInfo(filename).fileName().contains(".")) {
missionFilename += ".mission"; missionFilename += QString(".%1").arg(QGCApplication::missionFileExtension);
} }
QFile file(missionFilename); QFile file(missionFilename);
...@@ -566,7 +566,7 @@ void MissionController::_saveMissionToFile(const QString& filename) ...@@ -566,7 +566,7 @@ void MissionController::_saveMissionToFile(const QString& filename)
_visualItems->setDirty(false); _visualItems->setDirty(false);
} }
void MissionController::saveMissionToFile(void) void MissionController::saveMissionToFilePicker(void)
{ {
#ifndef __mobile__ #ifndef __mobile__
QString filename = QGCFileDialog::getSaveFileName(NULL, "Select file to save mission to", QString(), "Mission file (*.mission);;All Files (*.*)"); QString filename = QGCFileDialog::getSaveFileName(NULL, "Select file to save mission to", QString(), "Mission file (*.mission);;All Files (*.*)");
...@@ -574,31 +574,10 @@ void MissionController::saveMissionToFile(void) ...@@ -574,31 +574,10 @@ void MissionController::saveMissionToFile(void)
if (filename.isEmpty()) { if (filename.isEmpty()) {
return; return;
} }
_saveMissionToFile(filename); saveMissionToFile(filename);
#endif #endif
} }
void MissionController::saveMobileMissionToFile(const QString& filename)
{
QStringList docDirs = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
if (docDirs.count() <= 0) {
qWarning() << "No Documents location";
return;
}
_saveMissionToFile(docDirs.at(0) + QDir::separator() + filename);
}
void MissionController::loadMobileMissionFromFile(const QString& filename)
{
QStringList docDirs = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
if (docDirs.count() <= 0) {
qWarning() << "No Documents location";
return;
}
_loadMissionFromFile(docDirs.at(0) + QDir::separator() + filename);
}
void MissionController::_calcPrevWaypointValues(double homeAlt, VisualMissionItem* currentItem, VisualMissionItem* prevItem, double* azimuth, double* distance, double* altDifference) void MissionController::_calcPrevWaypointValues(double homeAlt, VisualMissionItem* currentItem, VisualMissionItem* prevItem, double* azimuth, double* distance, double* altDifference)
{ {
QGeoCoordinate currentCoord = currentItem->coordinate(); QGeoCoordinate currentCoord = currentItem->coordinate();
...@@ -1109,26 +1088,6 @@ void MissionController::_currentMissionItemChanged(int sequenceNumber) ...@@ -1109,26 +1088,6 @@ void MissionController::_currentMissionItemChanged(int sequenceNumber)
} }
} }
QStringList MissionController::getMobileMissionFiles(void)
{
QStringList missionFiles;
QStringList docDirs = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
if (docDirs.count() <= 0) {
qWarning() << "No Documents location";
return QStringList();
}
QDir missionDir = docDirs.at(0);
QFileInfoList missionFileInfoList = missionDir.entryInfoList(QStringList(QStringLiteral("*.mission")), QDir::Files, QDir::Name);
foreach (const QFileInfo& missionFileInfo, missionFileInfoList) {
missionFiles << missionFileInfo.baseName() + ".mission";
}
return missionFiles;
}
bool MissionController::syncInProgress(void) bool MissionController::syncInProgress(void)
{ {
if (_activeVehicle) { if (_activeVehicle) {
......
...@@ -51,13 +51,12 @@ public: ...@@ -51,13 +51,12 @@ public:
Q_INVOKABLE void start(bool editMode); Q_INVOKABLE void start(bool editMode);
Q_INVOKABLE void getMissionItems(void); Q_INVOKABLE void getMissionItems(void);
Q_INVOKABLE void sendMissionItems(void); Q_INVOKABLE void sendMissionItems(void);
Q_INVOKABLE void loadMissionFromFile(void); Q_INVOKABLE void loadMissionFromFilePicker(void);
Q_INVOKABLE void saveMissionToFile(void); Q_INVOKABLE void loadMissionFromFile(const QString& filename);
Q_INVOKABLE void loadMobileMissionFromFile(const QString& file); Q_INVOKABLE void saveMissionToFilePicker(void);
Q_INVOKABLE void saveMobileMissionToFile(const QString& file); Q_INVOKABLE void saveMissionToFile(const QString& filename);
Q_INVOKABLE void removeMissionItem(int index); Q_INVOKABLE void removeMissionItem(int index);
Q_INVOKABLE void removeAllMissionItems(void); Q_INVOKABLE void removeAllMissionItems(void);
Q_INVOKABLE QStringList getMobileMissionFiles(void);
/// Add a new simple mission item to the list /// Add a new simple mission item to the list
/// @param i: index to insert at /// @param i: index to insert at
...@@ -119,8 +118,6 @@ private: ...@@ -119,8 +118,6 @@ private:
double _normalizeLon(double lon); double _normalizeLon(double lon);
bool _loadJsonMissionFile(const QByteArray& bytes, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString); bool _loadJsonMissionFile(const QByteArray& bytes, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString);
bool _loadTextMissionFile(QTextStream& stream, QmlObjectListModel* visualItems, QString& errorString); bool _loadTextMissionFile(QTextStream& stream, QmlObjectListModel* visualItems, QString& errorString);
void _loadMissionFromFile(const QString& file);
void _saveMissionToFile(const QString& file);
int _nextSequenceNumber(void); int _nextSequenceNumber(void);
private: private:
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#include "RadioComponentController.h" #include "RadioComponentController.h"
#include "ESP8266ComponentController.h" #include "ESP8266ComponentController.h"
#include "ScreenToolsController.h" #include "ScreenToolsController.h"
#include "QGCMobileFileDialogController.h"
#include "AutoPilotPlugin.h" #include "AutoPilotPlugin.h"
#include "VehicleComponent.h" #include "VehicleComponent.h"
#include "FirmwarePluginManager.h" #include "FirmwarePluginManager.h"
...@@ -125,6 +126,10 @@ ...@@ -125,6 +126,10 @@
QGCApplication* QGCApplication::_app = NULL; QGCApplication* QGCApplication::_app = NULL;
const char* QGCApplication::parameterFileExtension = "params";
const char* QGCApplication::missionFileExtension = "mission";
const char* QGCApplication::telemetryFileExtension = "tlog";
const char* QGCApplication::_deleteAllSettingsKey = "DeleteAllSettingsNextBoot"; const char* QGCApplication::_deleteAllSettingsKey = "DeleteAllSettingsNextBoot";
const char* QGCApplication::_settingsVersionKey = "SettingsVersion"; const char* QGCApplication::_settingsVersionKey = "SettingsVersion";
const char* QGCApplication::_promptFlightDataSave = "PromptFLightDataSave"; const char* QGCApplication::_promptFlightDataSave = "PromptFLightDataSave";
...@@ -449,6 +454,7 @@ void QGCApplication::_initCommon(void) ...@@ -449,6 +454,7 @@ void QGCApplication::_initCommon(void)
qmlRegisterType<MissionController> ("QGroundControl.Controllers", 1, 0, "MissionController"); qmlRegisterType<MissionController> ("QGroundControl.Controllers", 1, 0, "MissionController");
qmlRegisterType<FlightDisplayViewController> ("QGroundControl.Controllers", 1, 0, "FlightDisplayViewController"); qmlRegisterType<FlightDisplayViewController> ("QGroundControl.Controllers", 1, 0, "FlightDisplayViewController");
qmlRegisterType<ValuesWidgetController> ("QGroundControl.Controllers", 1, 0, "ValuesWidgetController"); qmlRegisterType<ValuesWidgetController> ("QGroundControl.Controllers", 1, 0, "ValuesWidgetController");
qmlRegisterType<QGCMobileFileDialogController> ("QGroundControl.Controllers", 1, 0, "QGCMobileFileDialogController");
#ifndef __mobile__ #ifndef __mobile__
qmlRegisterType<ViewWidgetController> ("QGroundControl.Controllers", 1, 0, "ViewWidgetController"); qmlRegisterType<ViewWidgetController> ("QGroundControl.Controllers", 1, 0, "ViewWidgetController");
...@@ -462,28 +468,6 @@ void QGCApplication::_initCommon(void) ...@@ -462,28 +468,6 @@ void QGCApplication::_initCommon(void)
qmlRegisterSingletonType<QGroundControlQmlGlobal> ("QGroundControl", 1, 0, "QGroundControl", qgroundcontrolQmlGlobalSingletonFactory); qmlRegisterSingletonType<QGroundControlQmlGlobal> ("QGroundControl", 1, 0, "QGroundControl", qgroundcontrolQmlGlobalSingletonFactory);
qmlRegisterSingletonType<ScreenToolsController> ("QGroundControl.ScreenToolsController", 1, 0, "ScreenToolsController", screenToolsControllerSingletonFactory); qmlRegisterSingletonType<ScreenToolsController> ("QGroundControl.ScreenToolsController", 1, 0, "ScreenToolsController", screenToolsControllerSingletonFactory);
qmlRegisterSingletonType<MavlinkQmlSingleton> ("QGroundControl.Mavlink", 1, 0, "Mavlink", mavlinkQmlSingletonFactory); qmlRegisterSingletonType<MavlinkQmlSingleton> ("QGroundControl.Mavlink", 1, 0, "Mavlink", mavlinkQmlSingletonFactory);
// Show user an upgrade message if the settings version has been bumped up
bool settingsUpgraded = false;
if (settings.contains(_settingsVersionKey)) {
if (settings.value(_settingsVersionKey).toInt() != QGC_SETTINGS_VERSION) {
settingsUpgraded = true;
}
} else if (settings.allKeys().count()) {
// Settings version key is missing and there are settings. This is an upgrade scenario.
settingsUpgraded = true;
} else {
settings.setValue(_settingsVersionKey, QGC_SETTINGS_VERSION);
}
if (settingsUpgraded) {
settings.clear();
settings.setValue(_settingsVersionKey, QGC_SETTINGS_VERSION);
showMessage("The format for QGroundControl saved settings has been modified. "
"Your saved settings have been reset to defaults.");
}
settings.sync();
} }
bool QGCApplication::_initForNormalAppBoot(void) bool QGCApplication::_initForNormalAppBoot(void)
...@@ -515,6 +499,28 @@ bool QGCApplication::_initForNormalAppBoot(void) ...@@ -515,6 +499,28 @@ bool QGCApplication::_initForNormalAppBoot(void)
// Load known link configurations // Load known link configurations
toolbox()->linkManager()->loadLinkConfigurationList(); toolbox()->linkManager()->loadLinkConfigurationList();
// Show user an upgrade message if the settings version has been bumped up
bool settingsUpgraded = false;
if (settings.contains(_settingsVersionKey)) {
if (settings.value(_settingsVersionKey).toInt() != QGC_SETTINGS_VERSION) {
settingsUpgraded = true;
}
} else if (settings.allKeys().count()) {
// Settings version key is missing and there are settings. This is an upgrade scenario.
settingsUpgraded = true;
} else {
settings.setValue(_settingsVersionKey, QGC_SETTINGS_VERSION);
}
if (settingsUpgraded) {
settings.clear();
settings.setValue(_settingsVersionKey, QGC_SETTINGS_VERSION);
showMessage("The format for QGroundControl saved settings has been modified. "
"Your saved settings have been reset to defaults.");
}
settings.sync();
return true; return true;
} }
......
...@@ -78,6 +78,10 @@ public: ...@@ -78,6 +78,10 @@ public:
QGCApplication(int &argc, char* argv[], bool unitTesting); QGCApplication(int &argc, char* argv[], bool unitTesting);
~QGCApplication(); ~QGCApplication();
static const char* parameterFileExtension;
static const char* missionFileExtension;
static const char* telemetryFileExtension;
/// @brief Sets the persistent flag to delete all settings the next time QGroundControl is started. /// @brief Sets the persistent flag to delete all settings the next time QGroundControl is started.
void deleteAllSettingsNextBoot(void); void deleteAllSettingsNextBoot(void);
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "QGCMobileFileDialogController.h"
#include <QStandardPaths>
#include <QDebug>
#include <QDir>
QStringList QGCMobileFileDialogController::getFiles(const QString& fileExtension)
{
QStringList files;
QStringList docDirs = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
if (docDirs.count() <= 0) {
qWarning() << "No Documents location";
return QStringList();
}
QDir fileDir = docDirs.at(0);
QFileInfoList fileInfoList = fileDir.entryInfoList(QStringList(QString("*.%1").arg(fileExtension)), QDir::Files, QDir::Name);
foreach (const QFileInfo& fileInfo, fileInfoList) {
files << fileInfo.baseName() + QStringLiteral(".") + fileExtension;
}
return files;
}
QString QGCMobileFileDialogController::fullPath(const QString& filename, const QString& fileExtension)
{
QStringList docDirs = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
if (docDirs.count() <= 0) {
qWarning() << "No Documents location";
return filename;
}
QString fixedFilename(filename);
QString correctExtension = QString(".%1").arg(fileExtension);
if (!filename.endsWith(correctExtension)) {
fixedFilename += correctExtension;
}
QString fullPath = docDirs.at(0) + QDir::separator() + fixedFilename;
qDebug() << fullPath;
return fullPath;
}
bool QGCMobileFileDialogController::fileExists(const QString& filename, const QString& fileExtension)
{
QFile file(fullPath(filename, fileExtension));
return file.exists();
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef QGCMobileFileDialogController_H
#define QGCMobileFileDialogController_H
#include <QObject>
class QGCMobileFileDialogController : public QObject
{
Q_OBJECT
public:
/// Return all file in Documents location which match the specified extension
Q_INVOKABLE QStringList getFiles(const QString& fileExtension);
/// Return the full path for specified file in the Documents location
/// @param filename File name, not fully qualified, may not have extension
/// @param fileExtension Expected file extension, added if needed
Q_INVOKABLE QString fullPath(const QString& filename, const QString& fileExtension);
/// Check for file existance
/// @param filename File name, not fully qualified, may not have extension
/// @param fileExtension Expected file extension, added if needed
/// @return true: File exists at Documents location
Q_INVOKABLE bool fileExists(const QString& filename, const QString& fileExtension);
};
#endif
...@@ -24,17 +24,17 @@ ...@@ -24,17 +24,17 @@
/// @file /// @file
/// @author Don Gagne <don@thegagnes.com> /// @author Don Gagne <don@thegagnes.com>
import QtQuick 2.3 import QtQuick 2.5
import QtQuick.Controls 1.3 import QtQuick.Controls 1.3
import QtQuick.Controls.Styles 1.2 import QtQuick.Dialogs 1.2
import QtQuick.Dialogs 1.2
import QGroundControl.Controls 1.0 import QGroundControl 1.0
import QGroundControl.Palette 1.0 import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0 import QGroundControl.Palette 1.0
import QGroundControl.Controllers 1.0 import QGroundControl.ScreenTools 1.0
import QGroundControl.FactSystem 1.0 import QGroundControl.Controllers 1.0
import QGroundControl.FactControls 1.0 import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
QGCView { QGCView {
id: qgcView id: qgcView
...@@ -123,16 +123,26 @@ QGCView { ...@@ -123,16 +123,26 @@ QGCView {
text: "Search..." text: "Search..."
onTriggered: showDialog(searchDialogComponent, "Parameter Search", qgcView.showDialogDefaultWidth, StandardButton.Reset | StandardButton.Apply) onTriggered: showDialog(searchDialogComponent, "Parameter Search", qgcView.showDialogDefaultWidth, StandardButton.Reset | StandardButton.Apply)
} }
MenuSeparator { visible: !ScreenTools.isMobile } MenuSeparator { }
MenuItem { MenuItem {
text: "Load from file..." text: "Load from file..."
onTriggered: controller.loadFromFile() onTriggered: {
visible: !ScreenTools.isMobile if (ScreenTools.isMobile) {
qgcView.showDialog(mobileFilePicker, "Select Parameter File", qgcView.showDialogDefaultWidth, StandardButton.Yes | StandardButton.Cancel)
} else {
controller.loadFromFilePicker()
}
}
} }
MenuItem { MenuItem {
text: "Save to file..." text: "Save to file..."
onTriggered: controller.saveToFile() onTriggered: {
visible: !ScreenTools.isMobile if (ScreenTools.isMobile) {
qgcView.showDialog(mobileFileSaver, "Save Parameter File", qgcView.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel)
} else {
controller.saveToFilePicker()
}
}
} }
MenuSeparator { visible: _showRCToParam } MenuSeparator { visible: _showRCToParam }
MenuItem { MenuItem {
...@@ -375,4 +385,22 @@ QGCView { ...@@ -375,4 +385,22 @@ QGCView {
} }
} }
Component {
id: mobileFilePicker
QGCMobileFileDialog {
fileExtension: QGroundControl.parameterFileExtension
onFilenameReturned: controller.loadFromFile(filename)
}
}
Component {
id: mobileFileSaver
QGCMobileFileDialog {
openDialog: false
fileExtension: QGroundControl.parameterFileExtension
onFilenameReturned: controller.saveToFile(filename)
}
}
} // QGCView } // QGCView
...@@ -95,27 +95,18 @@ void ParameterEditorController::clearRCToParam(void) ...@@ -95,27 +95,18 @@ void ParameterEditorController::clearRCToParam(void)
_uas->unsetRCToParameterMap(); _uas->unsetRCToParameterMap();
} }
void ParameterEditorController::saveToFile(void) void ParameterEditorController::saveToFile(const QString& filename)
{ {
#ifndef __mobile__
if (!_autopilot) { if (!_autopilot) {
qWarning() << "Internal error _autopilot==NULL"; qWarning() << "Internal error _autopilot==NULL";
return; return;
} }
QString msgTitle("Save Parameters"); if (!filename.isEmpty()) {
QFile file(filename);
QString fileName = QGCFileDialog::getSaveFileName(NULL,
msgTitle,
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
"Parameter Files (*.params)",
"params",
true);
if (!fileName.isEmpty()) {
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qgcApp()->showMessage("Unable to create file"); qgcApp()->showMessage(QString("Unable to create file: %1").arg(filename));
return; return;
} }
...@@ -123,12 +114,23 @@ void ParameterEditorController::saveToFile(void) ...@@ -123,12 +114,23 @@ void ParameterEditorController::saveToFile(void)
_autopilot->writeParametersToStream(stream); _autopilot->writeParametersToStream(stream);
file.close(); file.close();
} }
#endif
} }
void ParameterEditorController::loadFromFile(void) void ParameterEditorController::saveToFilePicker(void)
{ {
#ifndef __mobile__ #ifndef __mobile__
QString fileName = QGCFileDialog::getSaveFileName(NULL,
"Save Parameters",
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
"Parameter Files (*.params)",
"params",
true);
saveToFile(fileName);
#endif
}
void ParameterEditorController::loadFromFile(const QString& filename)
{
QString errors; QString errors;
if (!_autopilot) { if (!_autopilot) {
...@@ -136,17 +138,11 @@ void ParameterEditorController::loadFromFile(void) ...@@ -136,17 +138,11 @@ void ParameterEditorController::loadFromFile(void)
return; return;
} }
QString msgTitle("Load Parameters"); if (!filename.isEmpty()) {
QFile file(filename);
QString fileName = QGCFileDialog::getOpenFileName(NULL,
msgTitle,
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
"Parameter Files (*.params);;All Files (*)");
if (!fileName.isEmpty()) {
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qgcApp()->showMessage("Unable to open file"); qgcApp()->showMessage(QString("Unable to open file: %1").arg(filename));
return; return;
} }
...@@ -158,6 +154,16 @@ void ParameterEditorController::loadFromFile(void) ...@@ -158,6 +154,16 @@ void ParameterEditorController::loadFromFile(void)
emit showErrorMessage(errors); emit showErrorMessage(errors);
} }
} }
}
void ParameterEditorController::loadFromFilePicker(void)
{
#ifndef __mobile__
QString fileName = QGCFileDialog::getOpenFileName(NULL,
"Load Parameters",
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
"Parameter Files (*.params);;All Files (*)");
loadFromFile(fileName);
#endif #endif
} }
......
...@@ -49,9 +49,11 @@ public: ...@@ -49,9 +49,11 @@ public:
Q_INVOKABLE QStringList searchParametersForComponent(int componentId, const QString& searchText, bool searchInName, bool searchInDescriptions); Q_INVOKABLE QStringList searchParametersForComponent(int componentId, const QString& searchText, bool searchInName, bool searchInDescriptions);
Q_INVOKABLE void clearRCToParam(void); Q_INVOKABLE void clearRCToParam(void);
Q_INVOKABLE void saveToFile(void); Q_INVOKABLE void saveToFilePicker(void);
Q_INVOKABLE void loadFromFile(void); Q_INVOKABLE void loadFromFilePicker(void);
Q_INVOKABLE void refresh(void); Q_INVOKABLE void saveToFile(const QString& filename);
Q_INVOKABLE void loadFromFile(const QString& filename);
Q_INVOKABLE void refresh(void);
Q_INVOKABLE void resetAllToDefaults(void); Q_INVOKABLE void resetAllToDefaults(void);
Q_INVOKABLE void setRCToParam(const QString& paramName); Q_INVOKABLE void setRCToParam(const QString& paramName);
......
...@@ -11,7 +11,6 @@ Text { ...@@ -11,7 +11,6 @@ Text {
property bool enabled: true property bool enabled: true
font.pixelSize: ScreenTools.defaultFontPixelSize font.pixelSize: ScreenTools.defaultFontPixelSize
fontSizeMode: Text.HorizontalFit
color: __qgcPal.text color: __qgcPal.text
antialiasing: true antialiasing: true
} }
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
import QtQuick 2.5
import QtQuick.Controls 1.3
import QtQuick.Dialogs 1.2
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Controllers 1.0
import QGroundControl.Palette 1.0
/// Simple file picker for mobile
QGCViewDialog {
property bool openDialog: true ///< true: Show file open dialog, false: show file save dialog
property string fileExtension ///< File extension for file listing
signal filenameReturned(string filename)
readonly property real _margins: ScreenTools.defaultFontPixelHeight / 2
function accept() {
if (!openDialog) {
if (!dialogLoader.item.replaceMessageShown) {
if (controller.fileExists(dialogLoader.item.filename, fileExtension)) {
dialogLoader.item.replaceMessageShown = true
return
}
}
filenameReturned(controller.fullPath(dialogLoader.item.filename, fileExtension))
}
hideDialog()
}
QGCMobileFileDialogController { id: controller }
QGCPalette { id: qgcPal; colorGroupEnabled: true }
Loader {
id: dialogLoader
anchors.fill: parent
sourceComponent: openDialog ? openDialogComponent : saveDialogComponent
}
Component {
id: saveDialogComponent
Column {
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelHeight
property alias filename: filenameTextField.text
property alias replaceMessageShown: replaceMessage.visible
QGCLabel {
text: "File name:"
}
QGCTextField {
id: filenameTextField
onTextChanged: replaceMessage.visible = false
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: "File names must end with ." + fileExtension + " file extension. If missing it will be added."
}
QGCLabel {
id: replaceMessage
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: "The file " + filename + " exists. Click Save again to replace it."
visible: false
color: qgcPal.warningText
}
}
}
Component {
id: openDialogComponent
Item {
anchors.margins: _margins
anchors.fill: parent
ListView {
anchors.fill: parent
spacing: _margins / 2
orientation: ListView.Vertical
model: controller.getFiles(fileExtension)
delegate: QGCButton {
text: modelData
onClicked: {
hideDialog()
filenameReturned(controller.fullPath(modelData, fileExtension))
}
}
}
QGCLabel {
text: "No files"
visible: controller.getFiles(fileExtension).length == 0
}
}
}
}
...@@ -20,6 +20,7 @@ QGCColoredImage 1.0 QGCColoredImage.qml ...@@ -20,6 +20,7 @@ QGCColoredImage 1.0 QGCColoredImage.qml
QGCComboBox 1.0 QGCComboBox.qml QGCComboBox 1.0 QGCComboBox.qml
QGCFlickable 1.0 QGCFlickable.qml QGCFlickable 1.0 QGCFlickable.qml
QGCLabel 1.0 QGCLabel.qml QGCLabel 1.0 QGCLabel.qml
QGCMobileFileDialog 1.0 QGCMobileFileDialog.qml
QGCMovableItem 1.0 QGCMovableItem.qml QGCMovableItem 1.0 QGCMovableItem.qml
QGCPipable 1.0 QGCPipable.qml QGCPipable 1.0 QGCPipable.qml
QGCRadioButton 1.0 QGCRadioButton.qml QGCRadioButton 1.0 QGCRadioButton.qml
......
...@@ -80,6 +80,10 @@ public: ...@@ -80,6 +80,10 @@ public:
Q_PROPERTY(QGeoCoordinate flightMapPosition MEMBER _flightMapPosition NOTIFY flightMapPositionChanged) Q_PROPERTY(QGeoCoordinate flightMapPosition MEMBER _flightMapPosition NOTIFY flightMapPositionChanged)
Q_PROPERTY(int flightMapZoom MEMBER _flightMapZoom NOTIFY flightMapZoomChanged) Q_PROPERTY(int flightMapZoom MEMBER _flightMapZoom NOTIFY flightMapZoomChanged)
Q_PROPERTY(QString parameterFileExtension READ parameterFileExtension CONSTANT)
Q_PROPERTY(QString missionFileExtension READ missionFileExtension CONSTANT)
Q_PROPERTY(QString telemetryFileExtension READ telemetryFileExtension CONSTANT)
/// @ return: true: experimental survey ip code is turned on /// @ return: true: experimental survey ip code is turned on
Q_PROPERTY(bool experimentalSurvey READ experimentalSurvey WRITE setExperimentalSurvey NOTIFY experimentalSurveyChanged) Q_PROPERTY(bool experimentalSurvey READ experimentalSurvey WRITE setExperimentalSurvey NOTIFY experimentalSurveyChanged)
...@@ -140,6 +144,10 @@ public: ...@@ -140,6 +144,10 @@ public:
bool experimentalSurvey(void) const; bool experimentalSurvey(void) const;
void setExperimentalSurvey(bool experimentalSurvey); void setExperimentalSurvey(bool experimentalSurvey);
QString parameterFileExtension(void) const { return QGCApplication::parameterFileExtension; }
QString missionFileExtension(void) const { return QGCApplication::missionFileExtension; }
QString telemetryFileExtension(void) const { return QGCApplication::telemetryFileExtension; }
// Overrides from QGCTool // Overrides from QGCTool
virtual void setToolbox(QGCToolbox* toolbox); virtual void setToolbox(QGCToolbox* toolbox);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment