diff --git a/src/QtLocationPlugin/QGCMapEngineData.h b/src/QtLocationPlugin/QGCMapEngineData.h index 345d146c041263735b52685bd0bf992ade486ab0..eb0ff7974c60acb64155b25b3f66a41572c0fb0e 100644 --- a/src/QtLocationPlugin/QGCMapEngineData.h +++ b/src/QtLocationPlugin/QGCMapEngineData.h @@ -120,7 +120,8 @@ public: taskDeleteTileSet, taskPruneCache, taskReset, - taskExport + taskExport, + taskImport }; QGCMapTask(TaskType type) @@ -386,12 +387,12 @@ public: void setExportCompleted() { - emit exportCompleted(); + emit actionCompleted(); } void setProgress(int percentage) { - emit exportProgress(percentage); + emit actionProgress(percentage); } private: @@ -399,10 +400,47 @@ private: QString _path; signals: - void exportCompleted (); - void exportProgress (int percentage); + void actionCompleted (); + void actionProgress (int percentage); }; +//----------------------------------------------------------------------------- +class QGCImportTileTask : public QGCMapTask +{ + Q_OBJECT +public: + QGCImportTileTask(QString path, bool replace) + : QGCMapTask(QGCMapTask::taskImport) + , _path(path) + , _replace(replace) + {} + + ~QGCImportTileTask() + { + } + + QString path () { return _path; } + bool replace () { return _replace; } + + void setImportCompleted() + { + emit actionCompleted(); + } + + void setProgress(int percentage) + { + emit actionProgress(percentage); + } + +private: + QString _path; + bool _replace; + +signals: + void actionCompleted (); + void actionProgress (int percentage); + +}; #endif // QGC_MAP_ENGINE_DATA_H diff --git a/src/QtLocationPlugin/QGCTileCacheWorker.cpp b/src/QtLocationPlugin/QGCTileCacheWorker.cpp index 6b81ae456f1c66a354e926fca685c620539f2a7a..67fddb8b69e0c2e6fad1394615c1d2d4d1116360 100644 --- a/src/QtLocationPlugin/QGCTileCacheWorker.cpp +++ b/src/QtLocationPlugin/QGCTileCacheWorker.cpp @@ -157,6 +157,9 @@ QGCCacheWorker::run() case QGCMapTask::taskExport: _exportSets(task); break; + case QGCMapTask::taskImport: + _importSets(task); + break; case QGCMapTask::taskTestInternet: _testInternet(); break; @@ -634,6 +637,22 @@ QGCCacheWorker::_resetCacheDatabase(QGCMapTask* mtask) task->setResetCompleted(); } +//----------------------------------------------------------------------------- +void +QGCCacheWorker::_importSets(QGCMapTask* mtask) +{ + if(!_testTask(mtask)) { + return; + } + QGCImportTileTask* task = static_cast(mtask); + + + + + + task->setImportCompleted(); +} + //----------------------------------------------------------------------------- void QGCCacheWorker::_exportSets(QGCMapTask* mtask) diff --git a/src/QtLocationPlugin/QGCTileCacheWorker.h b/src/QtLocationPlugin/QGCTileCacheWorker.h index 79925b63ad4f1d3791c3cb53d5f8a18c6ff4008c..72fe8ea634cf8dfee8d393d757fc163b7c1ce712 100644 --- a/src/QtLocationPlugin/QGCTileCacheWorker.h +++ b/src/QtLocationPlugin/QGCTileCacheWorker.h @@ -60,6 +60,7 @@ private: void _resetCacheDatabase (QGCMapTask* mtask); void _pruneCache (QGCMapTask* mtask); void _exportSets (QGCMapTask* mtask); + void _importSets (QGCMapTask* mtask); bool _testTask (QGCMapTask* mtask); void _testInternet (); diff --git a/src/QtLocationPlugin/QMLControl/OfflineMap.qml b/src/QtLocationPlugin/QMLControl/OfflineMap.qml index 49100ee87f383fb9f13ff7921b825ca1e917df1b..be4f9aa3866754de29292d9e0c43798e8caa1cb3 100644 --- a/src/QtLocationPlugin/QMLControl/OfflineMap.qml +++ b/src/QtLocationPlugin/QMLControl/OfflineMap.qml @@ -15,11 +15,12 @@ import QtQuick.Layouts 1.2 import QtLocation 5.3 import QtPositioning 5.3 -import QGroundControl 1.0 -import QGroundControl.Controls 1.0 -import QGroundControl.ScreenTools 1.0 -import QGroundControl.Palette 1.0 -import QGroundControl.FlightMap 1.0 +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.FlightMap 1.0 +import QGroundControl.QGCMapEngineManager 1.0 QGCView { id: offlineMapView @@ -856,6 +857,7 @@ QGCView { QGCButton { text: qsTr("Import") width: _buttonSize + onClicked: rootLoader.sourceComponent = importDialog } QGCButton { text: qsTr("Export") @@ -926,8 +928,9 @@ QGCView { enabled: QGroundControl.mapEngineManager.selectedCount > 0 onClicked: { showList(); - QGroundControl.mapEngineManager.exportSets() - rootLoader.sourceComponent = exportToDiskProgress + if(QGroundControl.mapEngineManager.exportSets()) { + rootLoader.sourceComponent = exportToDiskProgress + } } } QGCButton { @@ -935,7 +938,6 @@ QGCView { width: _bigButtonSize enabled: QGroundControl.mapEngineManager.selectedCount > 0 onClicked: { - QGroundControl.mapEngineManager.exportSets() showList() } } @@ -956,18 +958,18 @@ QGCView { anchors.centerIn: parent Rectangle { width: parent.width * 0.5 - height: cameraSettingsCol.height * 1.25 + height: exportCol.height * 1.25 radius: ScreenTools.defaultFontPixelWidth color: qgcPal.windowShadeDark border.color: qgcPal.text anchors.centerIn: parent Column { - id: cameraSettingsCol + id: exportCol spacing: ScreenTools.defaultFontPixelHeight width: parent.width anchors.centerIn: parent QGCLabel { - text: QGroundControl.mapEngineManager.exporting ? qsTr("Tile Set Export Progress") : qsTr("Tile Set Export Completed") + text: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionExporting ? qsTr("Tile Set Export Progress") : qsTr("Tile Set Export Completed") font.family: ScreenTools.demiboldFontFamily font.pointSize: ScreenTools.mediumFontPointSize anchors.horizontalCenter: parent.horizontalCenter @@ -976,7 +978,7 @@ QGCView { id: progressBar width: parent.width * 0.45 maximumValue: 100 - value: QGroundControl.mapEngineManager.exportProgress + value: QGroundControl.mapEngineManager.actionProgress anchors.horizontalCenter: parent.horizontalCenter } BusyIndicator { @@ -1001,4 +1003,118 @@ QGCView { } } + Component { + id: importDialog + Rectangle { + width: mainWindow.width + height: mainWindow.height + color: "black" + anchors.centerIn: parent + Rectangle { + width: parent.width * 0.45 + height: importCol.height * 1.5 + radius: ScreenTools.defaultFontPixelWidth + color: qgcPal.windowShadeDark + border.color: qgcPal.text + anchors.centerIn: parent + Column { + id: importCol + spacing: ScreenTools.defaultFontPixelHeight + width: parent.width + anchors.centerIn: parent + QGCLabel { + text: { + if(QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone) { + return qsTr("Map Tile Set Import"); + } else if(QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting) { + return qsTr("Map Tile Set Import Progress"); + } else { + return qsTr("Map Tile Set Import Completed"); + } + } + font.family: ScreenTools.demiboldFontFamily + font.pointSize: ScreenTools.mediumFontPointSize + anchors.horizontalCenter: parent.horizontalCenter + } + ProgressBar { + id: progressBar + width: parent.width * 0.45 + maximumValue: 100 + visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting + value: QGroundControl.mapEngineManager.actionProgress + anchors.horizontalCenter: parent.horizontalCenter + } + BusyIndicator { + visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting + running: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting + width: ScreenTools.defaultFontPixelWidth + height: ScreenTools.defaultFontPixelWidth + anchors.horizontalCenter: parent.horizontalCenter + } + ExclusiveGroup { id: radioGroup } + Column { + spacing: ScreenTools.defaultFontPixelHeight + width: ScreenTools.defaultFontPixelWidth * 24 + anchors.horizontalCenter: parent.horizontalCenter + QGCRadioButton { + exclusiveGroup: radioGroup + text: qsTr("Append to existing set") + checked: !QGroundControl.mapEngineManager.importReplace + onClicked: QGroundControl.mapEngineManager.importReplace = !checked + visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone + } + QGCRadioButton { + exclusiveGroup: radioGroup + text: qsTr("Replace existing set") + checked: QGroundControl.mapEngineManager.importReplace + onClicked: QGroundControl.mapEngineManager.importReplace = checked + visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone + } + } + QGCButton { + text: qsTr("Close") + width: _bigButtonSize * 1.25 + visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionDone + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + showList() + rootLoader.sourceComponent = null + } + } + Row { + spacing: _margins + visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone + anchors.horizontalCenter: parent.horizontalCenter + QGCButton { + text: qsTr("Import From Disk") + width: _bigButtonSize * 1.25 + onClicked: { + if(!QGroundControl.mapEngineManager.importSets()) { + showList(); + rootLoader.sourceComponent = null + } + } + } + QGCButton { + text: qsTr("Import From Device") + width: _bigButtonSize * 1.25 + onClicked: { + showList(); + rootLoader.sourceComponent = null + } + } + QGCButton { + text: qsTr("Cancel") + width: _bigButtonSize * 1.25 + onClicked: { + showList() + rootLoader.sourceComponent = null + } + } + } + } + } + } + } + } // QGCView diff --git a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc index 05b5b9aaf648748f4c4bc02cc676c183c8cdde7e..48462f68b4dfcaa112b9e8335289e4aba96e1e3b 100644 --- a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc +++ b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc @@ -41,8 +41,9 @@ QGCMapEngineManager::QGCMapEngineManager(QGCApplication* app) , _setID(UINT64_MAX) , _freeDiskSpace(0) , _diskSpace(0) - , _exportProgress(0) - , _exporting(false) + , _actionProgress(0) + , _importAction(ActionNone) + , _importReplace(false) { } @@ -395,9 +396,42 @@ QGCMapEngineManager::selectedCount() { return count; } +//----------------------------------------------------------------------------- +bool +QGCMapEngineManager::importSets(QString path) { + _importAction = ActionNone; + emit importActionChanged(); + QString dir = path; + if(dir.isEmpty()) { +#if defined(__mobile__) + //-- TODO: This has to be something fixed + dir = QDir(QDir::homePath()).filePath(QString("export_%1.db").arg(QDateTime::currentDateTime().toTime_t())); +#else + dir = QGCFileDialog::getOpenFileName( + MainWindow::instance(), + "Export Tile Set", + QDir::homePath(), + "Tile Sets (*.qgctiledb)"); +#endif + } + if(!dir.isEmpty()) { + _importAction = ActionImporting; + emit importActionChanged(); + QGCImportTileTask* task = new QGCImportTileTask(dir, _importReplace); + connect(task, &QGCImportTileTask::actionCompleted, this, &QGCMapEngineManager::_actionCompleted); + connect(task, &QGCImportTileTask::actionProgress, this, &QGCMapEngineManager::_actionProgressHandler); + connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); + getQGCMapEngine()->addTask(task); + return true; + } + return false; +} + //----------------------------------------------------------------------------- bool QGCMapEngineManager::exportSets(QString path) { + _importAction = ActionNone; + emit importActionChanged(); QString dir = path; if(dir.isEmpty()) { #if defined(__mobile__) @@ -422,11 +456,11 @@ QGCMapEngineManager::exportSets(QString path) { } } if(sets.count()) { - _exporting = true; - emit exportingChanged(); + _importAction = ActionExporting; + emit importActionChanged(); QGCExportTileTask* task = new QGCExportTileTask(sets, dir); - connect(task, &QGCExportTileTask::exportCompleted, this, &QGCMapEngineManager::_exportCompleted); - connect(task, &QGCExportTileTask::exportProgress, this, &QGCMapEngineManager::_exportProgressHandler); + connect(task, &QGCExportTileTask::actionCompleted, this, &QGCMapEngineManager::_actionCompleted); + connect(task, &QGCExportTileTask::actionProgress, this, &QGCMapEngineManager::_actionProgressHandler); connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); getQGCMapEngine()->addTask(task); return true; @@ -437,18 +471,18 @@ QGCMapEngineManager::exportSets(QString path) { //----------------------------------------------------------------------------- void -QGCMapEngineManager::_exportProgressHandler(int percentage) +QGCMapEngineManager::_actionProgressHandler(int percentage) { - _exportProgress = percentage; - emit exportProgressChanged(); + _actionProgress = percentage; + emit actionProgressChanged(); } //----------------------------------------------------------------------------- void -QGCMapEngineManager::_exportCompleted() +QGCMapEngineManager::_actionCompleted() { - _exporting = false; - emit exportingChanged(); + _importAction = ActionDone; + emit importActionChanged(); } //----------------------------------------------------------------------------- diff --git a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h index b23f590d5f0245034bc11819badc26e8c2d22e90..07df10752e777540a9c4a789a5de55c05f3e5270 100644 --- a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h +++ b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h @@ -29,6 +29,14 @@ public: QGCMapEngineManager(QGCApplication* app); ~QGCMapEngineManager(); + enum ImportAction { + ActionNone, + ActionImporting, + ActionExporting, + ActionDone, + }; + Q_ENUMS(ImportAction) + Q_PROPERTY(int tileX0 READ tileX0 NOTIFY tileX0Changed) Q_PROPERTY(int tileX1 READ tileX1 NOTIFY tileX1Changed) Q_PROPERTY(int tileY0 READ tileY0 NOTIFY tileY0Changed) @@ -48,8 +56,10 @@ public: Q_PROPERTY(quint32 diskSpace READ diskSpace CONSTANT) //-- Tile set export Q_PROPERTY(int selectedCount READ selectedCount NOTIFY selectedCountChanged) - Q_PROPERTY(int exportProgress READ exportProgress NOTIFY exportProgressChanged) - Q_PROPERTY(bool exporting READ exporting NOTIFY exportingChanged) + Q_PROPERTY(int actionProgress READ actionProgress NOTIFY actionProgressChanged) + Q_PROPERTY(ImportAction importAction READ importAction NOTIFY importActionChanged) + + Q_PROPERTY(bool importReplace READ importReplace WRITE setImportReplace NOTIFY importReplaceChanged) Q_INVOKABLE void loadTileSets (); Q_INVOKABLE void updateForCurrentView (double lon0, double lat0, double lon1, double lat1, int minZoom, int maxZoom, const QString& mapName); @@ -62,6 +72,7 @@ public: Q_INVOKABLE void selectAll (); Q_INVOKABLE void selectNone (); Q_INVOKABLE bool exportSets (QString path = QString()); + Q_INVOKABLE bool importSets (QString path = QString()); int tileX0 () { return _totalSet.tileX0; } int tileX1 () { return _totalSet.tileX1; } @@ -80,12 +91,14 @@ public: quint64 freeDiskSpace () { return _freeDiskSpace; } quint64 diskSpace () { return _diskSpace; } int selectedCount (); - int exportProgress () { return _exportProgress; } - bool exporting () { return _exporting; } + int actionProgress () { return _actionProgress; } + ImportAction importAction () { return _importAction; } + bool importReplace () { return _importReplace; } void setMapboxToken (QString token); void setMaxMemCache (quint32 size); void setMaxDiskCache (quint32 size); + void setImportReplace (bool replace) { _importReplace = replace; emit importReplaceChanged(); } void setErrorMessage (const QString& error) { _errorMessage = error; emit errorMessageChanged(); } @@ -106,8 +119,9 @@ signals: void errorMessageChanged (); void freeDiskSpaceChanged (); void selectedCountChanged (); - void exportProgressChanged (); - void exportingChanged (); + void actionProgressChanged (); + void importActionChanged (); + void importReplaceChanged (); public slots: void taskError (QGCMapTask::TaskType type, QString error); @@ -118,8 +132,8 @@ private slots: void _tileSetDeleted (quint64 setID); void _updateTotals (quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize); void _resetCompleted (); - void _exportCompleted (); - void _exportProgressHandler (int percentage); + void _actionCompleted (); + void _actionProgressHandler (int percentage); private: void _updateDiskFreeSpace (); @@ -137,8 +151,9 @@ private: quint32 _diskSpace; QmlObjectListModel _tileSets; QString _errorMessage; - int _exportProgress; - bool _exporting; + int _actionProgress; + ImportAction _importAction; + bool _importReplace; }; #endif