diff --git a/src/QGCToolbox.cc b/src/QGCToolbox.cc index 8a78cd18090..4cb9177e5cd 100644 --- a/src/QGCToolbox.cc +++ b/src/QGCToolbox.cc @@ -17,7 +17,6 @@ #include "MAVLinkProtocol.h" #include "MissionCommandTree.h" #include "MultiVehicleManager.h" -#include "QGCMapEngineManager.h" #include "FollowMe.h" #include "PositionManager.h" #include "VideoManager.h" @@ -55,7 +54,6 @@ QGCToolbox::QGCToolbox(QGCApplication* app) _mavlinkProtocol = new MAVLinkProtocol (app, this); _missionCommandTree = new MissionCommandTree (app, this); _multiVehicleManager = new MultiVehicleManager (app, this); - _mapEngineManager = new QGCMapEngineManager (app, this); _qgcPositionManager = new QGCPositionManager (app, this); _followMe = new FollowMe (app, this); _videoManager = new VideoManager (app, this); @@ -85,7 +83,6 @@ void QGCToolbox::setChildToolboxes(void) _mavlinkProtocol->setToolbox(this); _missionCommandTree->setToolbox(this); _multiVehicleManager->setToolbox(this); - _mapEngineManager->setToolbox(this); _followMe->setToolbox(this); _qgcPositionManager->setToolbox(this); _videoManager->setToolbox(this); diff --git a/src/QGCToolbox.h b/src/QGCToolbox.h index dd8c01f3165..d5390cabbec 100644 --- a/src/QGCToolbox.h +++ b/src/QGCToolbox.h @@ -21,7 +21,6 @@ class LinkManager; class MAVLinkProtocol; class MissionCommandTree; class MultiVehicleManager; -class QGCMapEngineManager; class QGCApplication; class QGCPositionManager; class VideoManager; @@ -49,7 +48,6 @@ class QGCToolbox : public QObject { MAVLinkProtocol* mavlinkProtocol () { return _mavlinkProtocol; } MissionCommandTree* missionCommandTree () { return _missionCommandTree; } MultiVehicleManager* multiVehicleManager () { return _multiVehicleManager; } - QGCMapEngineManager* mapEngineManager () { return _mapEngineManager; } FollowMe* followMe () { return _followMe; } QGCPositionManager* qgcPositionManager () { return _qgcPositionManager; } VideoManager* videoManager () { return _videoManager; } @@ -80,7 +78,6 @@ class QGCToolbox : public QObject { MAVLinkProtocol* _mavlinkProtocol = nullptr; MissionCommandTree* _missionCommandTree = nullptr; MultiVehicleManager* _multiVehicleManager = nullptr; - QGCMapEngineManager* _mapEngineManager = nullptr; FollowMe* _followMe = nullptr; QGCPositionManager* _qgcPositionManager = nullptr; VideoManager* _videoManager = nullptr; diff --git a/src/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc index 8d7ed4513be..e5f175775f3 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.cc +++ b/src/QmlControls/QGroundControlQmlGlobal.cc @@ -15,6 +15,7 @@ #include "FirmwarePluginManager.h" #include "AppSettings.h" #include "PositionManager.h" +#include "QGCMapEngineManager.h" #ifndef NO_SERIAL_LINK #include "GPSManager.h" #endif @@ -30,7 +31,8 @@ QGeoCoordinate QGroundControlQmlGlobal::_coord = QGeoCoordinate(0.0,0.0); double QGroundControlQmlGlobal::_zoom = 2; QGroundControlQmlGlobal::QGroundControlQmlGlobal(QGCApplication* app, QGCToolbox* toolbox) - : QGCTool (app, toolbox) + : QGCTool(app, toolbox) + , _mapEngineManager(QGCMapEngineManager::instance()) { // We clear the parent on this object since we run into shutdown problems caused by hybrid qml app. Instead we let it leak on shutdown. // setParent(nullptr); @@ -73,7 +75,6 @@ void QGroundControlQmlGlobal::setToolbox(QGCToolbox* toolbox) _linkManager = toolbox->linkManager(); _multiVehicleManager = toolbox->multiVehicleManager(); - _mapEngineManager = toolbox->mapEngineManager(); _qgcPositionManager = toolbox->qgcPositionManager(); _missionCommandTree = toolbox->missionCommandTree(); _videoManager = toolbox->videoManager(); diff --git a/src/QmlControls/QmlObjectListModel.h b/src/QmlControls/QmlObjectListModel.h index 3cfcc084699..5a5524e9765 100644 --- a/src/QmlControls/QmlObjectListModel.h +++ b/src/QmlControls/QmlObjectListModel.h @@ -27,6 +27,7 @@ class QmlObjectListModel : public QAbstractListModel Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged) Q_INVOKABLE QObject* get(int index); + const QObject *get(int index) const; // Property accessors diff --git a/src/QtLocationPlugin/CMakeLists.txt b/src/QtLocationPlugin/CMakeLists.txt index 56e01f34e5d..421c79a822e 100644 --- a/src/QtLocationPlugin/CMakeLists.txt +++ b/src/QtLocationPlugin/CMakeLists.txt @@ -53,6 +53,7 @@ endif() target_link_libraries(QGCLocation PRIVATE Qt6::Positioning + QGC Settings Utilities PUBLIC @@ -61,7 +62,6 @@ target_link_libraries(QGCLocation Qt6::LocationPrivate Qt6::Network Qt6::Sql - QGC QmlControls ) @@ -71,15 +71,8 @@ target_include_directories(QGCLocation QMLControl ) -set_source_files_properties(QMLControl/OfflineMap.qml - PROPERTIES - QT_RESOURCE_ALIAS OfflineMap.qml -) - -set_source_files_properties(QMLControl/OfflineMapEditor.qml - PROPERTIES - QT_RESOURCE_ALIAS OfflineMapEditor.qml -) +set_source_files_properties(QMLControl/OfflineMap.qml PROPERTIES QT_RESOURCE_ALIAS OfflineMap.qml) +set_source_files_properties(QMLControl/OfflineMapEditor.qml PROPERTIES QT_RESOURCE_ALIAS OfflineMapEditor.qml) # qt_add_qml_module(QGCLocation # URI QGroundControl.QGCLocation diff --git a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc index c476d6e3471..d49e0a46a14 100644 --- a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc +++ b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc @@ -11,141 +11,119 @@ /// @file /// @author Gus Grubba -#if !defined(__mobile__) -//-- TODO: #include "QGCQFileDialog.h" -#endif - #include "QGCMapEngineManager.h" #include "QGCCachedTileSet.h" #include "QGCMapUrlEngine.h" -#include "ElevationMapProvider.h" #include "QGCMapEngine.h" +#include "ElevationMapProvider.h" +#include "QmlObjectListModel.h" #include "QGCApplication.h" #include "QGCLoggingCategory.h" -#include +#include #include +#include #include #include -QGC_LOGGING_CATEGORY(QGCMapEngineManagerLog, "QGCMapEngineManagerLog") +QGC_LOGGING_CATEGORY(QGCMapEngineManagerLog, "qgc.qtlocation.qmlcontrol.qgcmapenginemanagerlog") static const QString kQmlOfflineMapKeyName = QStringLiteral("QGCOfflineMap"); -static const QString kElevationMapType = QString(CopernicusElevationProvider::kProviderKey); - -//----------------------------------------------------------------------------- -QGCMapEngineManager::QGCMapEngineManager(QGCApplication* app, QGCToolbox* toolbox) - : QGCTool(app, toolbox) - , _topleftLat(0.0) - , _topleftLon(0.0) - , _bottomRightLat(0.0) - , _bottomRightLon(0.0) - , _minZoom(0) - , _maxZoom(0) - , _setID(UINT64_MAX) - , _freeDiskSpace(0) - , _diskSpace(0) - , _fetchElevation(true) - , _actionProgress(0) - , _importAction(ActionNone) - , _importReplace(false) -{ +static const QString kElevationMapType = QString(CopernicusElevationProvider::kProviderKey); // TODO: Variable Elevation Provider Type -} +Q_APPLICATION_STATIC(QGCMapEngineManager, _mapEngineManager); -//----------------------------------------------------------------------------- -QGCMapEngineManager::~QGCMapEngineManager() +QGCMapEngineManager *QGCMapEngineManager::instance() { - _tileSets.clear(); + return _mapEngineManager(); } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::setToolbox(QGCToolbox *toolbox) +QGCMapEngineManager::QGCMapEngineManager(QObject *parent) + : QObject(parent) + , _tileSets(new QmlObjectListModel(this)) { - QGCTool::setToolbox(toolbox); - QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); - qmlRegisterUncreatableType("QGroundControl.QGCMapEngineManager", 1, 0, "QGCMapEngineManager", "Reference only"); - connect(getQGCMapEngine(), &QGCMapEngine::updateTotals, this, &QGCMapEngineManager::_updateTotals); + qmlRegisterUncreatableType("QGroundControl.QGCMapEngineManager", 1, 0, "QGCMapEngineManager", "Reference only"); + + (void) connect(getQGCMapEngine(), &QGCMapEngine::updateTotals, this, &QGCMapEngineManager::_updateTotals); + _updateDiskFreeSpace(); + + // qCDebug(QGCMapEngineManagerLog) << Q_FUNC_INFO << this; +} + +QGCMapEngineManager::~QGCMapEngineManager() +{ + _tileSets->clear(); + + // qCDebug(QGCMapEngineManagerLog) << Q_FUNC_INFO << this; } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::updateForCurrentView(double lon0, double lat0, double lon1, double lat1, int minZoom, int maxZoom, const QString& mapName) +void QGCMapEngineManager::updateForCurrentView(double lon0, double lat0, double lon1, double lat1, int minZoom, int maxZoom, const QString &mapName) { - _topleftLat = lat0; - _topleftLon = lon0; + _topleftLat = lat0; + _topleftLon = lon0; _bottomRightLat = lat1; _bottomRightLon = lon1; - _minZoom = minZoom; - _maxZoom = maxZoom; + _minZoom = minZoom; + _maxZoom = maxZoom; _imageSet.clear(); _elevationSet.clear(); - for(int z = minZoom; z <= maxZoom; z++) { - QGCTileSet set = UrlFactory::getTileCount(z, lon0, lat0, lon1, lat1, mapName); + for (int z = minZoom; z <= maxZoom; z++) { + const QGCTileSet set = UrlFactory::getTileCount(z, lon0, lat0, lon1, lat1, mapName); _imageSet += set; } + if (_fetchElevation) { - QGCTileSet set = UrlFactory::getTileCount(1, lon0, lat0, lon1, lat1, kElevationMapType); + const QGCTileSet set = UrlFactory::getTileCount(1, lon0, lat0, lon1, lat1, kElevationMapType); _elevationSet += set; } emit tileCountChanged(); emit tileSizeChanged(); - qCDebug(QGCMapEngineManagerLog) << "updateForCurrentView" << lat0 << lon0 << lat1 << lon1 << minZoom << maxZoom; + qCDebug(QGCMapEngineManagerLog) << Q_FUNC_INFO << lat0 << lon0 << lat1 << lon1 << minZoom << maxZoom; } -//----------------------------------------------------------------------------- -QString -QGCMapEngineManager::tileCountStr() const +QString QGCMapEngineManager::tileCountStr() const { return qgcApp()->numberToString(_imageSet.tileCount + _elevationSet.tileCount); } -//----------------------------------------------------------------------------- -QString -QGCMapEngineManager::tileSizeStr() const +QString QGCMapEngineManager::tileSizeStr() const { return qgcApp()->bigSizeToString(_imageSet.tileSize + _elevationSet.tileSize); } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::loadTileSets() +void QGCMapEngineManager::loadTileSets() { - if(_tileSets.count()) { - _tileSets.clear(); + if (_tileSets->count()) { + _tileSets->clear(); emit tileSetsChanged(); } - QGCFetchTileSetTask* task = new QGCFetchTileSetTask(); - connect(task, &QGCFetchTileSetTask::tileSetFetched, this, &QGCMapEngineManager::_tileSetFetched); - connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); + + QGCFetchTileSetTask* const task = new QGCFetchTileSetTask(nullptr); + (void) connect(task, &QGCFetchTileSetTask::tileSetFetched, this, &QGCMapEngineManager::_tileSetFetched); + (void) connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); (void) getQGCMapEngine()->addTask(task); } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::_tileSetFetched(QGCCachedTileSet* tileSet) +void QGCMapEngineManager::_tileSetFetched(QGCCachedTileSet *tileSet) { - //-- A blank (default) type means it uses various types and not just one - if(tileSet->type() == "Invalid") { - tileSet->setMapTypeStr("Various"); + if (tileSet->type() == QStringLiteral("Invalid")) { + tileSet->setMapTypeStr(QStringLiteral("Various")); } - _tileSets.append(tileSet); + tileSet->setManager(this); + (void) _tileSets->append(tileSet); emit tileSetsChanged(); } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::startDownload(const QString& name, const QString& mapType) +void QGCMapEngineManager::startDownload(const QString &name, const QString &mapType) { - if(_imageSet.tileSize) { - QGCCachedTileSet* set = new QGCCachedTileSet(name); + if (_imageSet.tileSize) { + QGCCachedTileSet* const set = new QGCCachedTileSet(name); set->setMapTypeStr(mapType); set->setTopleftLat(_topleftLat); set->setTopleftLon(_topleftLon); @@ -156,16 +134,17 @@ QGCMapEngineManager::startDownload(const QString& name, const QString& mapType) set->setTotalTileSize(_imageSet.tileSize); set->setTotalTileCount(static_cast(_imageSet.tileCount)); set->setType(mapType); - QGCCreateTileSetTask* task = new QGCCreateTileSetTask(set); - //-- Create Tile Set (it will also create a list of tiles to download) - connect(task, &QGCCreateTileSetTask::tileSetSaved, this, &QGCMapEngineManager::_tileSetSaved); - connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); + + QGCCreateTileSetTask* const task = new QGCCreateTileSetTask(set); + (void) connect(task, &QGCCreateTileSetTask::tileSetSaved, this, &QGCMapEngineManager::_tileSetSaved); + (void) connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); (void) getQGCMapEngine()->addTask(task); } else { - qWarning() << "QGCMapEngineManager::startDownload() No Tiles to save"; + qCWarning(QGCMapEngineManagerLog) << Q_FUNC_INFO << "No Tiles to save"; } - if (mapType != kElevationMapType && _fetchElevation) { - QGCCachedTileSet* set = new QGCCachedTileSet(name + " Elevation"); + + if ((mapType != kElevationMapType) && _fetchElevation) { + QGCCachedTileSet* const set = new QGCCachedTileSet(name + QStringLiteral(" Elevation")); set->setMapTypeStr(kElevationMapType); set->setTopleftLat(_topleftLat); set->setTopleftLon(_topleftLon); @@ -176,196 +155,169 @@ QGCMapEngineManager::startDownload(const QString& name, const QString& mapType) set->setTotalTileSize(_elevationSet.tileSize); set->setTotalTileCount(static_cast(_elevationSet.tileCount)); set->setType(kElevationMapType); - QGCCreateTileSetTask* task = new QGCCreateTileSetTask(set); - //-- Create Tile Set (it will also create a list of tiles to download) - connect(task, &QGCCreateTileSetTask::tileSetSaved, this, &QGCMapEngineManager::_tileSetSaved); - connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); + + QGCCreateTileSetTask* const task = new QGCCreateTileSetTask(set); + (void) connect(task, &QGCCreateTileSetTask::tileSetSaved, this, &QGCMapEngineManager::_tileSetSaved); + (void) connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); (void) getQGCMapEngine()->addTask(task); } else { - qWarning() << "QGCMapEngineManager::startDownload() No Tiles to save"; + qCWarning(QGCMapEngineManagerLog) << Q_FUNC_INFO << "No Tiles to save"; } } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::_tileSetSaved(QGCCachedTileSet *set) +void QGCMapEngineManager::_tileSetSaved(QGCCachedTileSet *set) { qCDebug(QGCMapEngineManagerLog) << "New tile set saved (" << set->name() << "). Starting download..."; - _tileSets.append(set); + + (void) _tileSets->append(set); emit tileSetsChanged(); - //-- Start downloading tiles set->createDownloadTask(); } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::saveSetting (const QString& key, const QString& value) +void QGCMapEngineManager::saveSetting(const QString &key, const QString &value) { QSettings settings; settings.beginGroup(kQmlOfflineMapKeyName); settings.setValue(key, value); } -//----------------------------------------------------------------------------- -QString -QGCMapEngineManager::loadSetting (const QString& key, const QString& defaultValue) +QString QGCMapEngineManager::loadSetting(const QString &key, const QString &defaultValue) { QSettings settings; settings.beginGroup(kQmlOfflineMapKeyName); return settings.value(key, defaultValue).toString(); } -//----------------------------------------------------------------------------- -QStringList -QGCMapEngineManager::mapList() -{ - return UrlFactory::getProviderTypes(); -} -//----------------------------------------------------------------------------- -QStringList -QGCMapEngineManager::mapProviderList() +QStringList QGCMapEngineManager::mapTypeList(const QString &provider) { - QStringList maps = mapList(); - - // Don't return the Elevations provider. This is not selectable as a map provider by the user. - maps.removeAll(kElevationMapType); + QStringList mapStringList = mapList(); + mapStringList = mapStringList.filter(QRegularExpression(provider)); - // Extract Provider name from MapName ( format : "Provider Type") - maps.replaceInStrings(QRegularExpression("^([^\\ ]*) (.*)$"),"\\1"); - maps.removeDuplicates(); + static const QRegularExpression providerType = QRegularExpression(QStringLiteral("^([^\\ ]*) (.*)$")); + (void) mapStringList.replaceInStrings(providerType,"\\2"); + (void) mapStringList.removeDuplicates(); - return maps; + return mapStringList; } -//----------------------------------------------------------------------------- -QStringList -QGCMapEngineManager::mapTypeList(QString provider) +void QGCMapEngineManager::deleteTileSet(QGCCachedTileSet *tileSet) { - // Extract type name from MapName ( format : "Provider Type") - QStringList maps = mapList(); - maps = maps.filter(QRegularExpression(provider)); - maps.replaceInStrings(QRegularExpression("^([^\\ ]*) (.*)$"),"\\2"); - maps.removeDuplicates(); - return maps; -} + qCDebug(QGCMapEngineManagerLog) << "Deleting tile set" << tileSet->name(); -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::deleteTileSet(QGCCachedTileSet* tileSet) -{ - qCDebug(QGCMapEngineManagerLog) << "Deleting tile set " << tileSet->name(); - //-- If deleting default set, delete it all - if(tileSet->defaultSet()) { - for(int i = 0; i < _tileSets.count(); i++ ) { - QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); - if(set) { + if (tileSet->defaultSet()) { + for (qsizetype i = 0; i < _tileSets->count(); i++ ) { + QGCCachedTileSet* const set = qobject_cast(_tileSets->get(i)); + if (set) { set->setDeleting(true); } } - QGCResetTask* task = new QGCResetTask(); - connect(task, &QGCResetTask::resetCompleted, this, &QGCMapEngineManager::_resetCompleted); - connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); + + QGCResetTask* const task = new QGCResetTask(nullptr); + (void) connect(task, &QGCResetTask::resetCompleted, this, &QGCMapEngineManager::_resetCompleted); + (void) connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); (void) getQGCMapEngine()->addTask(task); } else { tileSet->setDeleting(true); - QGCDeleteTileSetTask* task = new QGCDeleteTileSetTask(tileSet->id()); - connect(task, &QGCDeleteTileSetTask::tileSetDeleted, this, &QGCMapEngineManager::_tileSetDeleted); - connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); + + QGCDeleteTileSetTask* const task = new QGCDeleteTileSetTask(tileSet->id()); + (void) connect(task, &QGCDeleteTileSetTask::tileSetDeleted, this, &QGCMapEngineManager::_tileSetDeleted); + (void) connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); (void) getQGCMapEngine()->addTask(task); } } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::renameTileSet(QGCCachedTileSet* tileSet, QString newName) +void QGCMapEngineManager::renameTileSet(QGCCachedTileSet *tileSet, const QString &newName) { - //-- Name must be unique int idx = 1; QString name = newName; - while(findName(name)) { + while (findName(name)) { name = QString("%1 (%2)").arg(newName).arg(idx++); } - qCDebug(QGCMapEngineManagerLog) << "Renaming tile set " << tileSet->name() << "to" << name; + + qCDebug(QGCMapEngineManagerLog) << "Renaming tile set" << tileSet->name() << "to" << name; tileSet->setName(name); - QGCRenameTileSetTask* task = new QGCRenameTileSetTask(tileSet->id(), name); - connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); - (void) getQGCMapEngine()->addTask(task); emit tileSet->nameChanged(); -} -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::_resetCompleted() -{ - //-- Reload sets - loadTileSets(); + QGCRenameTileSetTask* const task = new QGCRenameTileSetTask(tileSet->id(), name); + (void) connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); + (void) getQGCMapEngine()->addTask(task); } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::_tileSetDeleted(quint64 setID) +void QGCMapEngineManager::_tileSetDeleted(quint64 setID) { - //-- Tile Set successfully deleted - QGCCachedTileSet* setToDelete = nullptr; - int i = 0; - for(i = 0; i < _tileSets.count(); i++ ) { - QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); - if (set && set->id() == setID) { - setToDelete = set; - break; + for (qsizetype i = 0; i < _tileSets->count(); i++ ) { + QGCCachedTileSet* const set = qobject_cast(_tileSets->get(i)); + if (set && (set->id() == setID)) { + _tileSets->removeAt(i); + delete set; + emit tileSetsChanged(); + return; } } - if(setToDelete) { - _tileSets.removeAt(i); - delete setToDelete; - } - emit tileSetsChanged(); } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::taskError(QGCMapTask::TaskType type, QString error) +void QGCMapEngineManager::taskError(QGCMapTask::TaskType type, const QString &error) { QString task; - switch(type) { + switch (type) { case QGCMapTask::taskFetchTileSets: - task = "Fetch Tile Set"; + task = QStringLiteral("Fetch Tile Set"); break; case QGCMapTask::taskCreateTileSet: - task = "Create Tile Set"; + task = QStringLiteral("Create Tile Set"); break; case QGCMapTask::taskGetTileDownloadList: - task = "Get Tile Download List"; + task = QStringLiteral("Get Tile Download List"); break; case QGCMapTask::taskUpdateTileDownloadState: - task = "Update Tile Download Status"; + task = QStringLiteral("Update Tile Download Status"); break; case QGCMapTask::taskDeleteTileSet: - task = "Delete Tile Set"; + task = QStringLiteral("Delete Tile Set"); break; case QGCMapTask::taskReset: - task = "Reset Tile Sets"; + task = QStringLiteral("Reset Tile Sets"); break; case QGCMapTask::taskExport: - task = "Export Tile Sets"; + task = QStringLiteral("Export Tile Sets"); break; default: - task = "Database Error"; + task = QStringLiteral("Database Error"); break; } + QString serror = "Error in task: " + task; serror += "\nError description:\n"; serror += error; - qWarning() << "QGCMapEngineManager::_taskError()"; + setErrorMessage(serror); + + qCWarning(QGCMapEngineManagerLog) << serror; } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::_updateTotals(quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize) +// FIXME: Results are unused +void QGCMapEngineManager::_updateDiskFreeSpace() { - for(int i = 0; i < _tileSets.count(); i++ ) { - QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); + const QString path = getQGCMapEngine()->getCachePath(); + if (path.isEmpty()) { + return; + } + + const QStorageInfo info(path); + + const quint32 total = static_cast(info.bytesTotal() / 1024); + _diskSpace = total; + + const quint32 free = static_cast(info.bytesFree() / 1024); + setFreeDiskSpace(free); + + qCDebug(QGCMapEngineManagerLog) << info.rootPath() << "has" << free << "Kbytes available."; +} + +void QGCMapEngineManager::_updateTotals(quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize) +{ + for (qsizetype i = 0; i < _tileSets->count(); i++) { + QGCCachedTileSet* const set = qobject_cast(_tileSets->get(i)); if (set && set->defaultSet()) { set->setSavedTileSize(totalsize); set->setSavedTileCount(totaltiles); @@ -374,187 +326,143 @@ QGCMapEngineManager::_updateTotals(quint32 totaltiles, quint64 totalsize, quint3 return; } } + _updateDiskFreeSpace(); } -//----------------------------------------------------------------------------- -bool -QGCMapEngineManager::findName(const QString& name) +bool QGCMapEngineManager::findName(const QString &name) const { - for(int i = 0; i < _tileSets.count(); i++ ) { - QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); - if (set && set->name() == name) { + for (qsizetype i = 0; i < _tileSets->count(); i++) { + const QGCCachedTileSet* const set = qobject_cast(_tileSets->get(i)); + if (set && (set->name() == name)) { return true; } } + return false; } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::selectAll() { - for(int i = 0; i < _tileSets.count(); i++ ) { - QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); - if(set) { +void QGCMapEngineManager::selectAll() +{ + for (qsizetype i = 0; i < _tileSets->count(); i++) { + QGCCachedTileSet* const set = qobject_cast(_tileSets->get(i)); + if (set) { set->setSelected(true); } } } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::selectNone() { - for(int i = 0; i < _tileSets.count(); i++ ) { - QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); - if(set) { +void QGCMapEngineManager::selectNone() +{ + for (qsizetype i = 0; i < _tileSets->count(); i++) { + QGCCachedTileSet* const set = qobject_cast(_tileSets->get(i)); + if (set) { set->setSelected(false); } } } -//----------------------------------------------------------------------------- -int -QGCMapEngineManager::selectedCount() { +int QGCMapEngineManager::selectedCount() const +{ int count = 0; - for(int i = 0; i < _tileSets.count(); i++ ) { - QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); - if(set && set->selected()) { + + for (qsizetype i = 0; i < _tileSets->count(); i++) { + const QGCCachedTileSet* const set = qobject_cast(_tileSets->get(i)); + if (set && set->selected()) { count++; } } + 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().toSecsSinceEpoch())); -#else - dir = QString(); //-- TODO: QGCQFileDialog::getOpenFileName( - // nullptr, - // "Import 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); - (void) getQGCMapEngine()->addTask(task); - return true; +bool QGCMapEngineManager::importSets(const QString &path) +{ + setImportAction(ActionNone); + + if (path.isEmpty()) { + return false; } - return false; + + setImportAction(ActionImporting); + + QGCImportTileTask* const task = new QGCImportTileTask(path, _importReplace); + (void) connect(task, &QGCImportTileTask::actionCompleted, this, &QGCMapEngineManager::_actionCompleted); + (void) connect(task, &QGCImportTileTask::actionProgress, this, &QGCMapEngineManager::_actionProgressHandler); + (void) connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); + (void) getQGCMapEngine()->addTask(task); + + return true; } -//----------------------------------------------------------------------------- -bool -QGCMapEngineManager::exportSets(QString path) { - _importAction = ActionNone; - emit importActionChanged(); - QString dir = path; - if(dir.isEmpty()) { -#if defined(__mobile__) - dir = QDir(QDir::homePath()).filePath(QString("export_%1.db").arg(QDateTime::currentDateTime().toSecsSinceEpoch())); -#else - dir = QString(); //-- TODO: QGCQFileDialog::getSaveFileName( - // MainWindow::instance(), - // "Export Tile Set", - // QDir::homePath(), - // "Tile Sets (*.qgctiledb)", - // "qgctiledb", - // true); -#endif +bool QGCMapEngineManager::exportSets(const QString &path) +{ + setImportAction(ActionNone); + + if (path.isEmpty()) { + return false; } - if(!dir.isEmpty()) { - QVector sets; - for(int i = 0; i < _tileSets.count(); i++ ) { - QGCCachedTileSet* set = qobject_cast(_tileSets.get(i)); - if(set->selected()) { - sets.append(set); - } - } - if(sets.count()) { - _importAction = ActionExporting; - emit importActionChanged(); - QGCExportTileTask* task = new QGCExportTileTask(sets, dir); - connect(task, &QGCExportTileTask::actionCompleted, this, &QGCMapEngineManager::_actionCompleted); - connect(task, &QGCExportTileTask::actionProgress, this, &QGCMapEngineManager::_actionProgressHandler); - connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); - (void) getQGCMapEngine()->addTask(task); - return true; + + QVector sets; + + for (qsizetype i = 0; i < _tileSets->count(); i++) { + QGCCachedTileSet* const set = qobject_cast(_tileSets->get(i)); + if (set->selected()) { + (void) sets.append(set); } } - return false; -} -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::_actionProgressHandler(int percentage) -{ - _actionProgress = percentage; - emit actionProgressChanged(); + if (sets.isEmpty()) { + return false; + } + + setImportAction(ActionExporting); + + QGCExportTileTask* const task = new QGCExportTileTask(sets, path); + (void) connect(task, &QGCExportTileTask::actionCompleted, this, &QGCMapEngineManager::_actionCompleted); + (void) connect(task, &QGCExportTileTask::actionProgress, this, &QGCMapEngineManager::_actionProgressHandler); + (void) connect(task, &QGCMapTask::error, this, &QGCMapEngineManager::taskError); + (void) getQGCMapEngine()->addTask(task); + + return true; } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::_actionCompleted() +void QGCMapEngineManager::_actionCompleted() { - ImportAction oldState = _importAction; - _importAction = ActionDone; - emit importActionChanged(); - //-- If we just imported, reload it all - if(oldState == ActionImporting) { + const ImportAction oldState = _importAction; + setImportAction(ActionDone); + + if (oldState == ActionImporting) { loadTileSets(); } } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::resetAction() +QString QGCMapEngineManager::getUniqueName() const { - _importAction = ActionNone; - emit importActionChanged(); -} - -//----------------------------------------------------------------------------- -QString -QGCMapEngineManager::getUniqueName() -{ - QString test = "Tile Set "; - QString name; int count = 1; while (true) { - name = test; - name += QString::asprintf("%03d", count++); - if(!findName(name)) + const QString name = QStringLiteral("Tile Set ") + QString::asprintf("%03d", count++); + if (!findName(name)) { return name; + } } + + return QStringLiteral(""); } -//----------------------------------------------------------------------------- -void -QGCMapEngineManager::_updateDiskFreeSpace() +QStringList QGCMapEngineManager::mapList() { - QString path = getQGCMapEngine()->getCachePath(); - if(!path.isEmpty()) { - QStorageInfo info(path); - quint32 total = static_cast(info.bytesTotal() / 1024); - quint32 free = static_cast(info.bytesFree() / 1024); - qCDebug(QGCMapEngineManagerLog) << info.rootPath() << "has" << free << "Mbytes available."; - if(_freeDiskSpace != free) { - _freeDiskSpace = free; - _diskSpace = total; - emit freeDiskSpaceChanged(); - } - } + return UrlFactory::getProviderTypes(); +} + +QStringList QGCMapEngineManager::mapProviderList() +{ + QStringList mapStringList = mapList(); + (void) mapStringList.removeAll(CopernicusElevationProvider::kProviderKey); + + static const QRegularExpression providerType = QRegularExpression(QStringLiteral("^([^\\ ]*) (.*)$")); + (void) mapStringList.replaceInStrings(providerType,"\\1"); + (void) mapStringList.removeDuplicates(); + + return mapStringList; } diff --git a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h index d7364e5f384..b7c930620a7 100644 --- a/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h +++ b/src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h @@ -13,23 +13,45 @@ #pragma once -#include "QmlObjectListModel.h" -#include "QGCToolbox.h" #include "QGCTileSet.h" #include "QGCMapTasks.h" +// #include #include Q_DECLARE_LOGGING_CATEGORY(QGCMapEngineManagerLog) class QGCCachedTileSet; +class QmlObjectListModel; -class QGCMapEngineManager : public QGCTool +class QGCMapEngineManager : public QObject { Q_OBJECT + // QML_ELEMENT + // QML_SINGLETON + Q_MOC_INCLUDE("QmlObjectListModel.h") + Q_MOC_INCLUDE("QGCCachedTileSet.h") + + Q_PROPERTY(bool fetchElevation MEMBER _fetchElevation NOTIFY fetchElevationChanged) + Q_PROPERTY(bool importReplace MEMBER _importReplace NOTIFY importReplaceChanged) + Q_PROPERTY(ImportAction importAction READ importAction WRITE setImportAction NOTIFY importActionChanged) + Q_PROPERTY(int actionProgress READ actionProgress NOTIFY actionProgressChanged) + Q_PROPERTY(int selectedCount READ selectedCount NOTIFY selectedCountChanged) + Q_PROPERTY(QmlObjectListModel *tileSets READ tileSets NOTIFY tileSetsChanged) + Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) + Q_PROPERTY(QString tileCountStr READ tileCountStr NOTIFY tileCountChanged) + Q_PROPERTY(QString tileSizeStr READ tileSizeStr NOTIFY tileSizeChanged) + Q_PROPERTY(QStringList mapList READ mapList CONSTANT) + Q_PROPERTY(QStringList mapProviderList READ mapProviderList CONSTANT) + Q_PROPERTY(quint32 diskSpace READ diskSpace) + Q_PROPERTY(quint32 freeDiskSpace READ freeDiskSpace NOTIFY freeDiskSpaceChanged) + Q_PROPERTY(quint64 tileCount READ tileCount NOTIFY tileCountChanged) + Q_PROPERTY(quint64 tileSize READ tileSize NOTIFY tileSizeChanged) + public: - QGCMapEngineManager(QGCApplication* app, QGCToolbox* toolbox); + QGCMapEngineManager(QObject *parent = nullptr); ~QGCMapEngineManager(); + static QGCMapEngineManager *instance(); enum ImportAction { ActionNone, @@ -39,110 +61,85 @@ class QGCMapEngineManager : public QGCTool }; Q_ENUM(ImportAction) - Q_PROPERTY(quint64 tileCount READ tileCount NOTIFY tileCountChanged) - Q_PROPERTY(QString tileCountStr READ tileCountStr NOTIFY tileCountChanged) - Q_PROPERTY(quint64 tileSize READ tileSize NOTIFY tileSizeChanged) - Q_PROPERTY(QString tileSizeStr READ tileSizeStr NOTIFY tileSizeChanged) - Q_PROPERTY(QmlObjectListModel* tileSets READ tileSets NOTIFY tileSetsChanged) - Q_PROPERTY(QStringList mapList READ mapList CONSTANT) - Q_PROPERTY(QStringList mapProviderList READ mapProviderList CONSTANT) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) - Q_PROPERTY(bool fetchElevation READ fetchElevation WRITE setFetchElevation NOTIFY fetchElevationChanged) - //-- Disk Space in MB - Q_PROPERTY(quint32 freeDiskSpace READ freeDiskSpace NOTIFY freeDiskSpaceChanged) - Q_PROPERTY(quint32 diskSpace READ diskSpace CONSTANT) - //-- Tile set export - Q_PROPERTY(int selectedCount READ selectedCount NOTIFY selectedCountChanged) - Q_PROPERTY(int actionProgress READ actionProgress NOTIFY actionProgressChanged) - Q_PROPERTY(ImportAction importAction READ importAction WRITE setImportAction 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); - Q_INVOKABLE void startDownload (const QString& name, const QString& mapType); - Q_INVOKABLE void saveSetting (const QString& key, const QString& value); - Q_INVOKABLE QString loadSetting (const QString& key, const QString& defaultValue); - Q_INVOKABLE void deleteTileSet (QGCCachedTileSet* tileSet); - Q_INVOKABLE void renameTileSet (QGCCachedTileSet* tileSet, QString newName); - Q_INVOKABLE QString getUniqueName (); - Q_INVOKABLE bool findName (const QString& name); - Q_INVOKABLE void selectAll (); - Q_INVOKABLE void selectNone (); - Q_INVOKABLE bool exportSets (QString path = QString()); - Q_INVOKABLE bool importSets (QString path = QString()); - Q_INVOKABLE void resetAction (); - - quint64 tileCount () const{ return _imageSet.tileCount + _elevationSet.tileCount; } - QString tileCountStr () const; - quint64 tileSize () const{ return _imageSet.tileSize + _elevationSet.tileSize; } - QString tileSizeStr () const; - QStringList mapList (); - QStringList mapProviderList (); - Q_INVOKABLE QStringList mapTypeList (QString provider); - QmlObjectListModel* tileSets () { return &_tileSets; } - QString errorMessage () { return _errorMessage; } - bool fetchElevation () const{ return _fetchElevation; } - quint64 freeDiskSpace () const{ return _freeDiskSpace; } - quint64 diskSpace () const{ return _diskSpace; } - int selectedCount (); - int actionProgress () const{ return _actionProgress; } - ImportAction importAction () { return _importAction; } - bool importReplace () const{ return _importReplace; } - - void setImportReplace (bool replace) { _importReplace = replace; emit importReplaceChanged(); } - void setImportAction (ImportAction action) {_importAction = action; emit importActionChanged(); } - void setErrorMessage (const QString& error) { _errorMessage = error; emit errorMessageChanged(); } - void setFetchElevation (bool fetchElevation) { _fetchElevation = fetchElevation; emit fetchElevationChanged(); } - - // Override from QGCTool - void setToolbox(QGCToolbox *toolbox); + Q_INVOKABLE bool exportSets(const QString &path = QString()); + Q_INVOKABLE bool findName(const QString &name) const; + Q_INVOKABLE bool importSets(const QString &path = QString()); + Q_INVOKABLE QString getUniqueName() const; + Q_INVOKABLE void deleteTileSet(QGCCachedTileSet *tileSet); + Q_INVOKABLE void loadTileSets(); + Q_INVOKABLE void renameTileSet(QGCCachedTileSet *tileSet, const QString &newName); + Q_INVOKABLE void resetAction() { setImportAction(ActionNone); } + Q_INVOKABLE void selectAll(); + Q_INVOKABLE void selectNone(); + Q_INVOKABLE void startDownload(const QString &name, const QString &mapType); + Q_INVOKABLE void updateForCurrentView(double lon0, double lat0, double lon1, double lat1, int minZoom, int maxZoom, const QString &mapName); + + Q_INVOKABLE static QString loadSetting(const QString &key, const QString &defaultValue); + Q_INVOKABLE static QStringList mapTypeList(const QString &provider); + Q_INVOKABLE static void saveSetting(const QString &key, const QString &value); + + ImportAction importAction() const { return _importAction; } + int actionProgress() const { return _actionProgress; } + int selectedCount() const; + QmlObjectListModel *tileSets() { return _tileSets; } + QString errorMessage() const { return _errorMessage; } + QString tileCountStr() const; + QString tileSizeStr() const; + quint64 diskSpace() const { return _diskSpace; } + quint64 freeDiskSpace() const { return _freeDiskSpace; } + quint64 tileCount() const { return (_imageSet.tileCount + _elevationSet.tileCount); } + quint64 tileSize() const { return (_imageSet.tileSize + _elevationSet.tileSize); } + + void setActionProgress(int percentage) { if (percentage != _actionProgress) { _actionProgress = percentage; emit actionProgressChanged(); } } + void setErrorMessage(const QString &error) { if (error != _errorMessage) { _errorMessage = error; emit errorMessageChanged(); } } + void setFreeDiskSpace(quint64 diskSpace) { if (diskSpace != _freeDiskSpace) { _freeDiskSpace = diskSpace; emit freeDiskSpaceChanged(); } } + void setImportAction(ImportAction action) { if (action != _importAction) { _importAction = action; emit importActionChanged(); } } + + static QStringList mapList(); + static QStringList mapProviderList(); signals: - void tileCountChanged (); - void tileSizeChanged (); - void tileSetsChanged (); - void maxMemCacheChanged (); - void maxDiskCacheChanged (); - void errorMessageChanged (); - void fetchElevationChanged (); - void freeDiskSpaceChanged (); - void selectedCountChanged (); - void actionProgressChanged (); - void importActionChanged (); - void importReplaceChanged (); + void actionProgressChanged(); + void errorMessageChanged(); + void fetchElevationChanged(); + void freeDiskSpaceChanged(); + void importActionChanged(); + void importReplaceChanged(); + void selectedCountChanged(); + void tileCountChanged(); + void tileSetsChanged(); + void tileSizeChanged(); public slots: - void taskError (QGCMapTask::TaskType type, QString error); + void taskError(QGCMapTask::TaskType type, const QString &error); private slots: - void _tileSetSaved (QGCCachedTileSet* set); - void _tileSetFetched (QGCCachedTileSet* tileSets); - void _tileSetDeleted (quint64 setID); - void _updateTotals (quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize); - void _resetCompleted (); - void _actionCompleted (); - void _actionProgressHandler (int percentage); - -private: - void _updateDiskFreeSpace (); + void _actionCompleted(); + void _actionProgressHandler(int percentage) { setActionProgress(percentage); } + void _resetCompleted() { loadTileSets(); } + void _tileSetDeleted(quint64 setID); + void _tileSetFetched(QGCCachedTileSet *tileSets); + void _tileSetSaved(QGCCachedTileSet *set); + void _updateTotals(quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize); private: - QGCTileSet _imageSet; - QGCTileSet _elevationSet; - double _topleftLat; - double _topleftLon; - double _bottomRightLat; - double _bottomRightLon; - int _minZoom; - int _maxZoom; - quint64 _setID; - quint32 _freeDiskSpace; - quint32 _diskSpace; - QmlObjectListModel _tileSets; - QString _errorMessage; - bool _fetchElevation; - int _actionProgress; - ImportAction _importAction; - bool _importReplace; + void _updateDiskFreeSpace(); + + QmlObjectListModel *_tileSets = nullptr; + QGCTileSet _imageSet; + QGCTileSet _elevationSet; + ImportAction _importAction = ActionNone; + double _topleftLat = 0.; + double _topleftLon = 0.; + double _bottomRightLat = 0.; + double _bottomRightLon = 0.; + int _minZoom = 0; + int _maxZoom = 0; + int _actionProgress = 0; + quint64 _setID = UINT64_MAX; + quint32 _freeDiskSpace = 0; + quint32 _diskSpace = 0; + QString _errorMessage; + bool _fetchElevation = true; + bool _importReplace = false; };