From 1a845a0e3570af2177ceff2a480dbbd9c91572b3 Mon Sep 17 00:00:00 2001 From: Gus Grubba Date: Tue, 21 Mar 2017 17:14:32 -0400 Subject: [PATCH] Adding ability to export a selected set of tile sets. --- src/QtLocationPlugin/QGCMapEngineData.h | 34 +++- src/QtLocationPlugin/QGCMapTileSet.cpp | 12 ++ src/QtLocationPlugin/QGCMapTileSet.h | 6 + src/QtLocationPlugin/QGCTileCacheWorker.cpp | 158 +++++++++++++++--- src/QtLocationPlugin/QGCTileCacheWorker.h | 4 +- .../QMLControl/OfflineMap.qml | 112 +++++++++++-- .../QMLControl/QGCMapEngineManager.cc | 67 ++++++++ .../QMLControl/QGCMapEngineManager.h | 7 + src/VehicleSetup/SetupView.qml | 8 +- 9 files changed, 364 insertions(+), 44 deletions(-) diff --git a/src/QtLocationPlugin/QGCMapEngineData.h b/src/QtLocationPlugin/QGCMapEngineData.h index 5765aa856..63401f4b7 100644 --- a/src/QtLocationPlugin/QGCMapEngineData.h +++ b/src/QtLocationPlugin/QGCMapEngineData.h @@ -119,7 +119,8 @@ public: taskUpdateTileDownloadState, taskDeleteTileSet, taskPruneCache, - taskReset + taskReset, + taskExport }; QGCMapTask(TaskType type) @@ -365,5 +366,36 @@ signals: void resetCompleted(); }; +//----------------------------------------------------------------------------- +class QGCExportTileTask : public QGCMapTask +{ + Q_OBJECT +public: + QGCExportTileTask(QVector sets, QString path) + : QGCMapTask(QGCMapTask::taskExport) + , _sets(sets) + , _path(path) + {} + + ~QGCExportTileTask() + { + } + + QVector sets() { return _sets; } + QString path() { return _path; } + + void setExportCompleted() + { + emit exportCompleted(); + } + +private: + QVector _sets; + QString _path; + +signals: + void exportCompleted(); +}; + #endif // QGC_MAP_ENGINE_DATA_H diff --git a/src/QtLocationPlugin/QGCMapTileSet.cpp b/src/QtLocationPlugin/QGCMapTileSet.cpp index f5c0e1082..70e70f2e8 100644 --- a/src/QtLocationPlugin/QGCMapTileSet.cpp +++ b/src/QtLocationPlugin/QGCMapTileSet.cpp @@ -52,6 +52,7 @@ QGCCachedTileSet::QGCCachedTileSet(const QString& name) , _noMoreTiles(false) , _batchRequested(false) , _manager(NULL) + , _selected(false) { } @@ -349,3 +350,14 @@ QGCCachedTileSet::setManager(QGCMapEngineManager* mgr) { _manager = mgr; } + +//----------------------------------------------------------------------------- +void +QGCCachedTileSet::setSelected(bool sel) +{ + _selected = sel; + emit selectedChanged(); + if(_manager) { + emit _manager->selectedCountChanged(); + } +} diff --git a/src/QtLocationPlugin/QGCMapTileSet.h b/src/QtLocationPlugin/QGCMapTileSet.h index dc8217e61..36241b7f5 100644 --- a/src/QtLocationPlugin/QGCMapTileSet.h +++ b/src/QtLocationPlugin/QGCMapTileSet.h @@ -72,6 +72,8 @@ public: Q_PROPERTY(quint32 errorCount READ errorCount NOTIFY errorCountChanged) Q_PROPERTY(QString errorCountStr READ errorCountStr NOTIFY errorCountChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectedChanged) + Q_INVOKABLE void createDownloadTask (); Q_INVOKABLE void resumeDownloadTask (); Q_INVOKABLE void cancelDownloadTask (); @@ -109,7 +111,9 @@ public: bool downloading () { return _downloading; } quint32 errorCount () { return _errorCount; } QString errorCountStr (); + bool selected () { return _selected; } + void setSelected (bool sel); void setName (QString name) { _name = name; } void setMapTypeStr (QString typeStr) { _mapTypeStr = typeStr; } void setTopleftLat (double lat) { _topleftLat = lat; } @@ -142,6 +146,7 @@ signals: void savedTileSizeChanged (); void completeChanged (); void errorCountChanged (); + void selectedChanged (); private slots: void _tileListFetched (QList tiles); @@ -181,6 +186,7 @@ private: bool _noMoreTiles; bool _batchRequested; QGCMapEngineManager* _manager; + bool _selected; }; #endif // QGC_MAP_TILE_SET_H diff --git a/src/QtLocationPlugin/QGCTileCacheWorker.cpp b/src/QtLocationPlugin/QGCTileCacheWorker.cpp index 254e4c9e2..01382a6a1 100644 --- a/src/QtLocationPlugin/QGCTileCacheWorker.cpp +++ b/src/QtLocationPlugin/QGCTileCacheWorker.cpp @@ -30,7 +30,8 @@ #include "time.h" const char* kDefaultSet = "Default Tile Set"; -const QString kSession = QLatin1String("QGeoTileWorkerSession"); +const QString kSession = QLatin1String("QGeoTileWorkerSession"); +const QString kExportSession = QLatin1String("QGeoTileExportSession"); QGC_LOGGING_CATEGORY(QGCTileCacheLog, "QGCTileCacheLog") @@ -153,6 +154,9 @@ QGCCacheWorker::run() case QGCMapTask::taskReset: _resetCacheDatabase(task); break; + case QGCMapTask::taskExport: + _exportSets(task); + break; case QGCMapTask::taskTestInternet: _testInternet(); break; @@ -262,8 +266,7 @@ QGCCacheWorker::_saveTile(QGCMapTask *mtask) void QGCCacheWorker::_getTile(QGCMapTask* mtask) { - if(!_valid) { - mtask->setError("No Cache Database"); + if(!_testTask(mtask)) { return; } bool found = false; @@ -291,8 +294,7 @@ QGCCacheWorker::_getTile(QGCMapTask* mtask) void QGCCacheWorker::_getTileSets(QGCMapTask* mtask) { - if(!_valid) { - mtask->setError("No Cache Database"); + if(!_testTask(mtask)) { return; } QGCFetchTileSetTask* task = static_cast(mtask); @@ -506,8 +508,7 @@ QGCCacheWorker::_createTileSet(QGCMapTask *mtask) void QGCCacheWorker::_getTileDownloadList(QGCMapTask* mtask) { - if(!_valid) { - mtask->setError("No Cache Database"); + if(!_testTask(mtask)) { return; } QList tiles; @@ -538,8 +539,7 @@ QGCCacheWorker::_getTileDownloadList(QGCMapTask* mtask) void QGCCacheWorker::_updateTileDownloadState(QGCMapTask* mtask) { - if(!_valid) { - mtask->setError("No Cache Database"); + if(!_testTask(mtask)) { return; } QGCUpdateTileDownloadStateTask* task = static_cast(mtask); @@ -563,8 +563,7 @@ QGCCacheWorker::_updateTileDownloadState(QGCMapTask* mtask) void QGCCacheWorker::_pruneCache(QGCMapTask* mtask) { - if(!_valid) { - mtask->setError("No Cache Database"); + if(!_testTask(mtask)) { return; } QGCPruneCacheTask* task = static_cast(mtask); @@ -594,8 +593,7 @@ QGCCacheWorker::_pruneCache(QGCMapTask* mtask) void QGCCacheWorker::_deleteTileSet(QGCMapTask* mtask) { - if(!_valid) { - mtask->setError("No Cache Database"); + if(!_testTask(mtask)) { return; } QGCDeleteTileSetTask* task = static_cast(mtask); @@ -613,12 +611,12 @@ QGCCacheWorker::_deleteTileSet(QGCMapTask* mtask) _updateTotals(); task->setTileSetDeleted(); } + //----------------------------------------------------------------------------- void QGCCacheWorker::_resetCacheDatabase(QGCMapTask* mtask) { - if(!_valid) { - mtask->setError("No Cache Database"); + if(!_testTask(mtask)) { return; } QGCResetTask* task = static_cast(mtask); @@ -632,10 +630,112 @@ QGCCacheWorker::_resetCacheDatabase(QGCMapTask* mtask) query.exec(s); s = QString("DROP TABLE TilesDownload"); query.exec(s); - _createDB(); + _valid = _createDB(_db); task->setResetCompleted(); } +//----------------------------------------------------------------------------- +void +QGCCacheWorker::_exportSets(QGCMapTask* mtask) +{ + if(!_testTask(mtask)) { + return; + } + bool res = false; + QGCExportTileTask* task = static_cast(mtask); + //-- Create exported database + QSqlDatabase *dbExport = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE", kExportSession)); + dbExport->setDatabaseName(task->path()); + dbExport->setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE"); + if (dbExport->open()) { + if(_createDB(dbExport, false)) { + //-- Iterate sets to save + for(int i = 0; i < task->sets().count(); i++) { + QGCCachedTileSet* set = task->sets()[i]; + //-- Create Tile Exported Set + QSqlQuery exportQuery(*dbExport); + exportQuery.prepare("INSERT INTO TileSets(" + "name, typeStr, topleftLat, topleftLon, bottomRightLat, bottomRightLon, minZoom, maxZoom, type, numTiles, date" + ") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + QString name = set->name(); + if(set->defaultSet()) { + name = "Exported Default Set"; + } + exportQuery.addBindValue(name); + exportQuery.addBindValue(set->mapTypeStr()); + exportQuery.addBindValue(set->topleftLat()); + exportQuery.addBindValue(set->topleftLon()); + exportQuery.addBindValue(set->bottomRightLat()); + exportQuery.addBindValue(set->bottomRightLon()); + exportQuery.addBindValue(set->minZoom()); + exportQuery.addBindValue(set->maxZoom()); + exportQuery.addBindValue(set->type()); + exportQuery.addBindValue(set->totalTileCount()); + exportQuery.addBindValue(QDateTime::currentDateTime().toTime_t()); + if(!exportQuery.exec()) { + task->setError("Error adding tile set to exported database"); + break; + } else { + //-- Get just created (auto-incremented) setID + quint64 exportSetID = exportQuery.lastInsertId().toULongLong(); + //-- Find set tiles + QString s = QString("SELECT * FROM SetTiles WHERE setID = %1").arg(set->id()); + QSqlQuery query(*_db); + if(query.exec(s)) { + while(query.next()) { + quint64 tileID = query.value("tileID").toULongLong(); + //-- Get tile + QString s = QString("SELECT * FROM Tiles WHERE tileID = \"%1\"").arg(tileID); + QSqlQuery subQuery(*_db); + if(subQuery.exec(s)) { + if(subQuery.next()) { + QString hash = subQuery.value("hash").toString(); + QString format = subQuery.value("format").toString(); + QByteArray img = subQuery.value("tile").toByteArray(); + int type = subQuery.value("type").toInt(); + //-- Save tile + exportQuery.prepare("INSERT INTO Tiles(hash, format, tile, size, type, date) VALUES(?, ?, ?, ?, ?, ?)"); + exportQuery.addBindValue(hash); + exportQuery.addBindValue(format); + exportQuery.addBindValue(img); + exportQuery.addBindValue(img.size()); + exportQuery.addBindValue(type); + exportQuery.addBindValue(QDateTime::currentDateTime().toTime_t()); + if(exportQuery.exec()) { + quint64 exportTileID = exportQuery.lastInsertId().toULongLong(); + QString s = QString("INSERT INTO SetTiles(tileID, setID) VALUES(%1, %2)").arg(exportTileID).arg(exportSetID); + exportQuery.prepare(s); + exportQuery.exec(); + } + } + } + } + } + } + } + } else { + task->setError("Error creating export database"); + } + } else { + qCritical() << "Map Cache SQL error (create export database):" << dbExport->lastError(); + task->setError("Error opening export database"); + } + delete dbExport; + if(res) { + task->setExportCompleted(); + } +} + +//----------------------------------------------------------------------------- +bool QGCCacheWorker::_testTask(QGCMapTask* mtask) +{ + if(!_valid) { + mtask->setError("No Cache Database"); + return false; + } + return true; +} + //----------------------------------------------------------------------------- bool QGCCacheWorker::_init() @@ -648,7 +748,10 @@ QGCCacheWorker::_init() _db->setDatabaseName(_databasePath); _db->setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE"); if (_db->open()) { - _createDB(); + _valid = _createDB(_db); + if(!_valid) { + _failed = true; + } } else { qCritical() << "Map Cache SQL error (init() open db):" << _db->lastError(); _failed = true; @@ -665,10 +768,11 @@ QGCCacheWorker::_init() } //----------------------------------------------------------------------------- -void -QGCCacheWorker::_createDB() +bool +QGCCacheWorker::_createDB(QSqlDatabase* db, bool createDefault) { - QSqlQuery query(*_db); + bool res = false; + QSqlQuery query(*db); if(!query.exec( "CREATE TABLE IF NOT EXISTS Tiles (" "tileID INTEGER PRIMARY KEY NOT NULL, " @@ -719,13 +823,13 @@ QGCCacheWorker::_createDB() qWarning() << "Map Cache SQL error (create TilesDownload db):" << query.lastError().text(); } else { //-- Database it ready for use - _valid = true; + res = true; } } } } //-- Create default tile set - if(_valid) { + if(res && createDefault) { QString s = QString("SELECT name FROM TileSets WHERE name = \"%1\"").arg(kDefaultSet); if(query.exec(s)) { if(!query.next()) { @@ -734,19 +838,19 @@ QGCCacheWorker::_createDB() query.addBindValue(1); query.addBindValue(QDateTime::currentDateTime().toTime_t()); if(!query.exec()) { - qWarning() << "Map Cache SQL error (Creating default tile set):" << _db->lastError(); - _valid = false; + qWarning() << "Map Cache SQL error (Creating default tile set):" << db->lastError(); + res = false; } } } else { - qWarning() << "Map Cache SQL error (Looking for default tile set):" << _db->lastError(); + qWarning() << "Map Cache SQL error (Looking for default tile set):" << db->lastError(); } } - if(!_valid) { + if(!res) { QFile file(_databasePath); file.remove(); } - _failed = !_valid; + return res; } //----------------------------------------------------------------------------- diff --git a/src/QtLocationPlugin/QGCTileCacheWorker.h b/src/QtLocationPlugin/QGCTileCacheWorker.h index 1b87e1d4f..79925b63a 100644 --- a/src/QtLocationPlugin/QGCTileCacheWorker.h +++ b/src/QtLocationPlugin/QGCTileCacheWorker.h @@ -59,13 +59,15 @@ private: void _deleteTileSet (QGCMapTask* mtask); void _resetCacheDatabase (QGCMapTask* mtask); void _pruneCache (QGCMapTask* mtask); + void _exportSets (QGCMapTask* mtask); + bool _testTask (QGCMapTask* mtask); void _testInternet (); quint64 _findTile (const QString hash); bool _findTileSetID (const QString name, quint64& setID); void _updateSetTotals (QGCCachedTileSet* set); bool _init (); - void _createDB (); + bool _createDB (QSqlDatabase *db, bool createDefault = true); quint64 _getDefaultTileSet (); void _updateTotals (); diff --git a/src/QtLocationPlugin/QMLControl/OfflineMap.qml b/src/QtLocationPlugin/QMLControl/OfflineMap.qml index e0512dd97..7a70d672a 100644 --- a/src/QtLocationPlugin/QMLControl/OfflineMap.qml +++ b/src/QtLocationPlugin/QMLControl/OfflineMap.qml @@ -37,7 +37,8 @@ QGCView { property string savedMapType: "" property bool _showPreview: true property bool _defaultSet: offlineMapView && offlineMapView._currentSelection && offlineMapView._currentSelection.defaultSet - property real _margins: ScreenTools.defaultFontPixelWidth / 2 + property real _margins: ScreenTools.defaultFontPixelWidth * 0.5 + property real _buttonSize: ScreenTools.defaultFontPixelWidth * 12 property bool _saveRealEstate: ScreenTools.isTinyScreen || ScreenTools.isShortScreen property real _adjustableFontPointSize: _saveRealEstate ? ScreenTools.smallFontPointSize : ScreenTools.defaultFontPointSize @@ -100,10 +101,12 @@ QGCView { _map.visible = true _tileSetList.visible = false infoView.visible = false + _exporTiles.visible = false addNewSetView.visible = true } function showList() { + _exporTiles.visible = false isMapInteractive = false _map.visible = false _tileSetList.visible = true @@ -111,6 +114,15 @@ QGCView { addNewSetView.visible = false } + function showExport() { + isMapInteractive = false + _map.visible = false + _tileSetList.visible = false + infoView.visible = false + addNewSetView.visible = false + _exporTiles.visible = true + } + function showInfo() { isMapInteractive = false if(_currentSelection && !offlineMapView._currentSelection.deleting) { @@ -796,7 +808,7 @@ QGCView { clip: true anchors.margins: ScreenTools.defaultFontPixelWidth anchors.top: parent.top - anchors.bottom: _optionsButton.top + anchors.bottom: _listButtonRow.top anchors.left: parent.left anchors.right: parent.right contentHeight: _cacheList.height @@ -806,7 +818,6 @@ QGCView { width: Math.min(_tileSetList.width, (ScreenTools.defaultFontPixelWidth * 50).toFixed(0)) spacing: ScreenTools.defaultFontPixelHeight * 0.5 anchors.horizontalCenter: parent.horizontalCenter - OfflineMapButton { id: firstButton text: qsTr("Add new set") @@ -834,15 +845,94 @@ QGCView { } } } + Row { + id: _listButtonRow + visible: _tileSetList.visible + spacing: _margins + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.margins: ScreenTools.defaultFontPixelWidth + QGCButton { + text: qsTr("Import") + width: _buttonSize + } + QGCButton { + text: qsTr("Export") + width: _buttonSize + enabled: QGroundControl.mapEngineManager.tileSets.count > 1 + onClicked: showExport() + } + QGCButton { + text: qsTr("Options") + width: _buttonSize + onClicked: showDialog(optionsDialogComponent, qsTr("Offline Maps Options"), qgcView.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel) + } + } - QGCButton { - id: _optionsButton - text: qsTr("Options") - visible: _tileSetList.visible - anchors.bottom: parent.bottom - anchors.right: parent.right - anchors.margins: ScreenTools.defaultFontPixelWidth - onClicked: showDialog(optionsDialogComponent, qsTr("Offline Maps Options"), qgcView.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel) + //-- Export Tile Sets + QGCFlickable { + id: _exporTiles + clip: true + visible: false + anchors.margins: ScreenTools.defaultFontPixelWidth + anchors.top: parent.top + anchors.bottom: _exportButtonRow.top + anchors.left: parent.left + anchors.right: parent.right + contentHeight: _exportList.height + Column { + id: _exportList + width: Math.min(_exporTiles.width, (ScreenTools.defaultFontPixelWidth * 50).toFixed(0)) + spacing: ScreenTools.defaultFontPixelHeight * 0.5 + anchors.horizontalCenter: parent.horizontalCenter + QGCLabel { + text: qsTr("Select Tile Sets to Export") + font.pointSize: ScreenTools.mediumFontPointSize + } + Item { width: 1; height: ScreenTools.defaultFontPixelHeight; } + Repeater { + model: QGroundControl.mapEngineManager.tileSets + delegate: QGCCheckBox { + text: object.name + checked: object.selected + onClicked: { + object.selected = checked + } + } + } + } + } + Row { + id: _exportButtonRow + visible: _exporTiles.visible + spacing: _margins + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.margins: ScreenTools.defaultFontPixelWidth + QGCButton { + text: qsTr("All") + width: _buttonSize + onClicked: QGroundControl.mapEngineManager.selectAll() + } + QGCButton { + text: qsTr("None") + width: _buttonSize + onClicked: QGroundControl.mapEngineManager.selectNone() + } + QGCButton { + text: qsTr("Export") + width: _buttonSize + enabled: QGroundControl.mapEngineManager.selectedCount > 0 + onClicked: { + QGroundControl.mapEngineManager.exportSets() + showList() + } + } + QGCButton { + text: qsTr("Cancel") + width: _buttonSize + onClicked: showList() + } } } // QGCViewPanel } // QGCView diff --git a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc index e05dfeb34..c8f9a63a7 100644 --- a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc +++ b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc @@ -308,6 +308,9 @@ QGCMapEngineManager::taskError(QGCMapTask::TaskType type, QString error) case QGCMapTask::taskReset: task = "Reset Tile Sets"; break; + case QGCMapTask::taskExport: + task = "Export Tile Sets"; + break; default: task = "Database Error"; break; @@ -351,6 +354,70 @@ QGCMapEngineManager::findName(const QString& name) return false; } +//----------------------------------------------------------------------------- +void +QGCMapEngineManager::selectAll() { + for(int i = 0; i < _tileSets.count(); i++ ) { + QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); + Q_ASSERT(set); + set->setSelected(true); + } +} + +//----------------------------------------------------------------------------- +void +QGCMapEngineManager::selectNone() { + for(int i = 0; i < _tileSets.count(); i++ ) { + QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); + Q_ASSERT(set); + set->setSelected(false); + } +} + +//----------------------------------------------------------------------------- +int +QGCMapEngineManager::selectedCount() { + int count = 0; + for(int i = 0; i < _tileSets.count(); i++ ) { + QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); + Q_ASSERT(set); + if(set->selected()) { + count++; + } + } + return count; +} + +//----------------------------------------------------------------------------- +void +QGCMapEngineManager::exportSets(QString path) { + QString dir = path; + if(dir.isEmpty()) { + dir = QDir(QDir::homePath()).filePath(QString("export_%1.db").arg(QDateTime::currentDateTime().toTime_t())); + } + QVector sets; + for(int i = 0; i < _tileSets.count(); i++ ) { + QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); + Q_ASSERT(set); + if(set->selected()) { + sets.append(set); + } + } + if(sets.count()) { + QGCExportTileTask* task = new QGCExportTileTask(sets, dir); + connect(task, &QGCExportTileTask::exportCompleted, this, &QGCMapEngineManager::_exportCompleted); + connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); + getQGCMapEngine()->addTask(task); + } +} + +//----------------------------------------------------------------------------- +void +QGCMapEngineManager::_exportCompleted() +{ + +} + //----------------------------------------------------------------------------- QString QGCMapEngineManager::getUniqueName() diff --git a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h index e168c6b7f..ce7e34ba1 100644 --- a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h +++ b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h @@ -46,6 +46,7 @@ public: //-- Disk Space in MB Q_PROPERTY(quint32 freeDiskSpace READ freeDiskSpace NOTIFY freeDiskSpaceChanged) Q_PROPERTY(quint32 diskSpace READ diskSpace CONSTANT) + Q_PROPERTY(int selectedCount READ selectedCount NOTIFY selectedCountChanged) Q_INVOKABLE void loadTileSets (); Q_INVOKABLE void updateForCurrentView (double lon0, double lat0, double lon1, double lat1, int minZoom, int maxZoom, const QString& mapName); @@ -55,6 +56,9 @@ public: Q_INVOKABLE void deleteTileSet (QGCCachedTileSet* tileSet); Q_INVOKABLE QString getUniqueName (); Q_INVOKABLE bool findName (const QString& name); + Q_INVOKABLE void selectAll (); + Q_INVOKABLE void selectNone (); + Q_INVOKABLE void exportSets (QString path = QString()); int tileX0 () { return _totalSet.tileX0; } int tileX1 () { return _totalSet.tileX1; } @@ -72,6 +76,7 @@ public: QString errorMessage () { return _errorMessage; } quint64 freeDiskSpace () { return _freeDiskSpace; } quint64 diskSpace () { return _diskSpace; } + int selectedCount (); void setMapboxToken (QString token); void setMaxMemCache (quint32 size); @@ -95,6 +100,7 @@ signals: void maxDiskCacheChanged (); void errorMessageChanged (); void freeDiskSpaceChanged (); + void selectedCountChanged (); public slots: void taskError (QGCMapTask::TaskType type, QString error); @@ -105,6 +111,7 @@ private slots: void _tileSetDeleted (quint64 setID); void _updateTotals (quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize); void _resetCompleted (); + void _exportCompleted (); private: void _updateDiskFreeSpace (); diff --git a/src/VehicleSetup/SetupView.qml b/src/VehicleSetup/SetupView.qml index e6ef0a3fb..7876a63dd 100644 --- a/src/VehicleSetup/SetupView.qml +++ b/src/VehicleSetup/SetupView.qml @@ -232,14 +232,14 @@ Rectangle { } Repeater { - model: _corePlugin.settingsPages - visible: _corePlugin.options.combineSettingsAndSetup + model: _corePlugin ? _corePlugin.settingsPages : [] + visible: _corePlugin && _corePlugin.options.combineSettingsAndSetup SubMenuButton { imageResource: modelData.icon setupIndicator: false exclusiveGroup: setupButtonGroup text: modelData.title - visible: _corePlugin.options.combineSettingsAndSetup + visible: _corePlugin && _corePlugin.options.combineSettingsAndSetup onClicked: panelLoader.setSource(modelData.url) Layout.fillWidth: true } @@ -312,7 +312,7 @@ Rectangle { SubMenuButton { setupIndicator: false exclusiveGroup: setupButtonGroup - visible: QGroundControl.multiVehicleManager.parameterReadyVehicleAvailable && _corePlugin.showAdvancedUI + visible: QGroundControl.multiVehicleManager && QGroundControl.multiVehicleManager.parameterReadyVehicleAvailable && _corePlugin.showAdvancedUI text: "Parameters" Layout.fillWidth: true -- 2.22.0