Commit 0878dfa2 authored by Gus Grubba's avatar Gus Grubba Committed by GitHub

Merge pull request #4817 from dogmaphobic/exportTileSet

Map Tile Set Import/Export
parents fbc34cc5 71813e49
...@@ -119,7 +119,9 @@ public: ...@@ -119,7 +119,9 @@ public:
taskUpdateTileDownloadState, taskUpdateTileDownloadState,
taskDeleteTileSet, taskDeleteTileSet,
taskPruneCache, taskPruneCache,
taskReset taskReset,
taskExport,
taskImport
}; };
QGCMapTask(TaskType type) QGCMapTask(TaskType type)
...@@ -365,5 +367,80 @@ signals: ...@@ -365,5 +367,80 @@ signals:
void resetCompleted(); void resetCompleted();
}; };
//-----------------------------------------------------------------------------
class QGCExportTileTask : public QGCMapTask
{
Q_OBJECT
public:
QGCExportTileTask(QVector<QGCCachedTileSet*> sets, QString path)
: QGCMapTask(QGCMapTask::taskExport)
, _sets(sets)
, _path(path)
{}
~QGCExportTileTask()
{
}
QVector<QGCCachedTileSet*> sets() { return _sets; }
QString path() { return _path; }
void setExportCompleted()
{
emit actionCompleted();
}
void setProgress(int percentage)
{
emit actionProgress(percentage);
}
private:
QVector<QGCCachedTileSet*> _sets;
QString _path;
signals:
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 #endif // QGC_MAP_ENGINE_DATA_H
...@@ -52,6 +52,7 @@ QGCCachedTileSet::QGCCachedTileSet(const QString& name) ...@@ -52,6 +52,7 @@ QGCCachedTileSet::QGCCachedTileSet(const QString& name)
, _noMoreTiles(false) , _noMoreTiles(false)
, _batchRequested(false) , _batchRequested(false)
, _manager(NULL) , _manager(NULL)
, _selected(false)
{ {
} }
...@@ -349,3 +350,14 @@ QGCCachedTileSet::setManager(QGCMapEngineManager* mgr) ...@@ -349,3 +350,14 @@ QGCCachedTileSet::setManager(QGCMapEngineManager* mgr)
{ {
_manager = mgr; _manager = mgr;
} }
//-----------------------------------------------------------------------------
void
QGCCachedTileSet::setSelected(bool sel)
{
_selected = sel;
emit selectedChanged();
if(_manager) {
emit _manager->selectedCountChanged();
}
}
...@@ -72,6 +72,8 @@ public: ...@@ -72,6 +72,8 @@ public:
Q_PROPERTY(quint32 errorCount READ errorCount NOTIFY errorCountChanged) Q_PROPERTY(quint32 errorCount READ errorCount NOTIFY errorCountChanged)
Q_PROPERTY(QString errorCountStr READ errorCountStr 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 createDownloadTask ();
Q_INVOKABLE void resumeDownloadTask (); Q_INVOKABLE void resumeDownloadTask ();
Q_INVOKABLE void cancelDownloadTask (); Q_INVOKABLE void cancelDownloadTask ();
...@@ -109,7 +111,9 @@ public: ...@@ -109,7 +111,9 @@ public:
bool downloading () { return _downloading; } bool downloading () { return _downloading; }
quint32 errorCount () { return _errorCount; } quint32 errorCount () { return _errorCount; }
QString errorCountStr (); QString errorCountStr ();
bool selected () { return _selected; }
void setSelected (bool sel);
void setName (QString name) { _name = name; } void setName (QString name) { _name = name; }
void setMapTypeStr (QString typeStr) { _mapTypeStr = typeStr; } void setMapTypeStr (QString typeStr) { _mapTypeStr = typeStr; }
void setTopleftLat (double lat) { _topleftLat = lat; } void setTopleftLat (double lat) { _topleftLat = lat; }
...@@ -142,6 +146,7 @@ signals: ...@@ -142,6 +146,7 @@ signals:
void savedTileSizeChanged (); void savedTileSizeChanged ();
void completeChanged (); void completeChanged ();
void errorCountChanged (); void errorCountChanged ();
void selectedChanged ();
private slots: private slots:
void _tileListFetched (QList<QGCTile*> tiles); void _tileListFetched (QList<QGCTile*> tiles);
...@@ -181,6 +186,7 @@ private: ...@@ -181,6 +186,7 @@ private:
bool _noMoreTiles; bool _noMoreTiles;
bool _batchRequested; bool _batchRequested;
QGCMapEngineManager* _manager; QGCMapEngineManager* _manager;
bool _selected;
}; };
#endif // QGC_MAP_TILE_SET_H #endif // QGC_MAP_TILE_SET_H
......
...@@ -30,7 +30,8 @@ ...@@ -30,7 +30,8 @@
#include "time.h" #include "time.h"
const char* kDefaultSet = "Default Tile Set"; 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") QGC_LOGGING_CATEGORY(QGCTileCacheLog, "QGCTileCacheLog")
...@@ -153,6 +154,12 @@ QGCCacheWorker::run() ...@@ -153,6 +154,12 @@ QGCCacheWorker::run()
case QGCMapTask::taskReset: case QGCMapTask::taskReset:
_resetCacheDatabase(task); _resetCacheDatabase(task);
break; break;
case QGCMapTask::taskExport:
_exportSets(task);
break;
case QGCMapTask::taskImport:
_importSets(task);
break;
case QGCMapTask::taskTestInternet: case QGCMapTask::taskTestInternet:
_testInternet(); _testInternet();
break; break;
...@@ -262,8 +269,7 @@ QGCCacheWorker::_saveTile(QGCMapTask *mtask) ...@@ -262,8 +269,7 @@ QGCCacheWorker::_saveTile(QGCMapTask *mtask)
void void
QGCCacheWorker::_getTile(QGCMapTask* mtask) QGCCacheWorker::_getTile(QGCMapTask* mtask)
{ {
if(!_valid) { if(!_testTask(mtask)) {
mtask->setError("No Cache Database");
return; return;
} }
bool found = false; bool found = false;
...@@ -291,8 +297,7 @@ QGCCacheWorker::_getTile(QGCMapTask* mtask) ...@@ -291,8 +297,7 @@ QGCCacheWorker::_getTile(QGCMapTask* mtask)
void void
QGCCacheWorker::_getTileSets(QGCMapTask* mtask) QGCCacheWorker::_getTileSets(QGCMapTask* mtask)
{ {
if(!_valid) { if(!_testTask(mtask)) {
mtask->setError("No Cache Database");
return; return;
} }
QGCFetchTileSetTask* task = static_cast<QGCFetchTileSetTask*>(mtask); QGCFetchTileSetTask* task = static_cast<QGCFetchTileSetTask*>(mtask);
...@@ -506,8 +511,7 @@ QGCCacheWorker::_createTileSet(QGCMapTask *mtask) ...@@ -506,8 +511,7 @@ QGCCacheWorker::_createTileSet(QGCMapTask *mtask)
void void
QGCCacheWorker::_getTileDownloadList(QGCMapTask* mtask) QGCCacheWorker::_getTileDownloadList(QGCMapTask* mtask)
{ {
if(!_valid) { if(!_testTask(mtask)) {
mtask->setError("No Cache Database");
return; return;
} }
QList<QGCTile*> tiles; QList<QGCTile*> tiles;
...@@ -538,8 +542,7 @@ QGCCacheWorker::_getTileDownloadList(QGCMapTask* mtask) ...@@ -538,8 +542,7 @@ QGCCacheWorker::_getTileDownloadList(QGCMapTask* mtask)
void void
QGCCacheWorker::_updateTileDownloadState(QGCMapTask* mtask) QGCCacheWorker::_updateTileDownloadState(QGCMapTask* mtask)
{ {
if(!_valid) { if(!_testTask(mtask)) {
mtask->setError("No Cache Database");
return; return;
} }
QGCUpdateTileDownloadStateTask* task = static_cast<QGCUpdateTileDownloadStateTask*>(mtask); QGCUpdateTileDownloadStateTask* task = static_cast<QGCUpdateTileDownloadStateTask*>(mtask);
...@@ -563,8 +566,7 @@ QGCCacheWorker::_updateTileDownloadState(QGCMapTask* mtask) ...@@ -563,8 +566,7 @@ QGCCacheWorker::_updateTileDownloadState(QGCMapTask* mtask)
void void
QGCCacheWorker::_pruneCache(QGCMapTask* mtask) QGCCacheWorker::_pruneCache(QGCMapTask* mtask)
{ {
if(!_valid) { if(!_testTask(mtask)) {
mtask->setError("No Cache Database");
return; return;
} }
QGCPruneCacheTask* task = static_cast<QGCPruneCacheTask*>(mtask); QGCPruneCacheTask* task = static_cast<QGCPruneCacheTask*>(mtask);
...@@ -594,8 +596,7 @@ QGCCacheWorker::_pruneCache(QGCMapTask* mtask) ...@@ -594,8 +596,7 @@ QGCCacheWorker::_pruneCache(QGCMapTask* mtask)
void void
QGCCacheWorker::_deleteTileSet(QGCMapTask* mtask) QGCCacheWorker::_deleteTileSet(QGCMapTask* mtask)
{ {
if(!_valid) { if(!_testTask(mtask)) {
mtask->setError("No Cache Database");
return; return;
} }
QGCDeleteTileSetTask* task = static_cast<QGCDeleteTileSetTask*>(mtask); QGCDeleteTileSetTask* task = static_cast<QGCDeleteTileSetTask*>(mtask);
...@@ -613,12 +614,12 @@ QGCCacheWorker::_deleteTileSet(QGCMapTask* mtask) ...@@ -613,12 +614,12 @@ QGCCacheWorker::_deleteTileSet(QGCMapTask* mtask)
_updateTotals(); _updateTotals();
task->setTileSetDeleted(); task->setTileSetDeleted();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
QGCCacheWorker::_resetCacheDatabase(QGCMapTask* mtask) QGCCacheWorker::_resetCacheDatabase(QGCMapTask* mtask)
{ {
if(!_valid) { if(!_testTask(mtask)) {
mtask->setError("No Cache Database");
return; return;
} }
QGCResetTask* task = static_cast<QGCResetTask*>(mtask); QGCResetTask* task = static_cast<QGCResetTask*>(mtask);
...@@ -632,10 +633,288 @@ QGCCacheWorker::_resetCacheDatabase(QGCMapTask* mtask) ...@@ -632,10 +633,288 @@ QGCCacheWorker::_resetCacheDatabase(QGCMapTask* mtask)
query.exec(s); query.exec(s);
s = QString("DROP TABLE TilesDownload"); s = QString("DROP TABLE TilesDownload");
query.exec(s); query.exec(s);
_createDB(); _valid = _createDB(_db);
task->setResetCompleted(); task->setResetCompleted();
} }
//-----------------------------------------------------------------------------
void
QGCCacheWorker::_importSets(QGCMapTask* mtask)
{
if(!_testTask(mtask)) {
return;
}
QGCImportTileTask* task = static_cast<QGCImportTileTask*>(mtask);
//-- If replacing, simply copy over it
if(task->replace()) {
//-- Close and delete old database
if(_db) {
delete _db;
_db = NULL;
QSqlDatabase::removeDatabase(kSession);
}
QFile file(_databasePath);
file.remove();
//-- Copy given database
QFile::copy(task->path(), _databasePath);
task->setProgress(25);
_init();
if(_valid) {
task->setProgress(50);
_db = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE", kSession));
_db->setDatabaseName(_databasePath);
_db->setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE");
_valid = _db->open();
}
task->setProgress(100);
} else {
//-- Open imported set
QSqlDatabase* dbImport = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE", kExportSession));
dbImport->setDatabaseName(task->path());
dbImport->setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE");
if (dbImport->open()) {
QSqlQuery query(*dbImport);
//-- Prepare progress report
quint64 tileCount = 0;
quint64 currentCount = 0;
QString s;
s = QString("SELECT COUNT(tileID) FROM Tiles");
if(query.exec(s)) {
if(query.next()) {
tileCount = query.value(0).toULongLong();
}
}
if(!tileCount) {
qWarning() << "No tiles found in imported database";
tileCount = 1; //-- Let it run through
}
//-- Iterate Tile Sets
s = QString("SELECT * FROM TileSets ORDER BY defaultSet DESC, name ASC");
if(query.exec(s)) {
while(query.next()) {
QString name = query.value("name").toString();
quint64 setID = query.value("setID").toULongLong();
QString mapType = query.value("typeStr").toString();
double topleftLat = query.value("topleftLat").toDouble();
double topleftLon = query.value("topleftLon").toDouble();
double bottomRightLat = query.value("bottomRightLat").toDouble();
double bottomRightLon = query.value("bottomRightLon").toDouble();
int minZoom = query.value("minZoom").toInt();
int maxZoom = query.value("maxZoom").toInt();
int type = query.value("type").toInt();
quint32 numTiles = query.value("numTiles").toUInt();
int defaultSet = query.value("defaultSet").toInt();
quint64 insertSetID = _getDefaultTileSet();
//-- If not default set, create new one
if(!defaultSet) {
//-- Check if we have this tile set already
int testCount = 0;
while (true) {
QString testName;
testName.sprintf("%s %03d", name.toLatin1().data(), ++testCount);
if(!_findTileSetID(testName, insertSetID) || testCount > 99) {
if(testCount > 1) {
name = testName;
}
break;
}
}
//-- Create new set
QSqlQuery cQuery(*_db);
cQuery.prepare("INSERT INTO TileSets("
"name, typeStr, topleftLat, topleftLon, bottomRightLat, bottomRightLon, minZoom, maxZoom, type, numTiles, defaultSet, date"
") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
cQuery.addBindValue(name);
cQuery.addBindValue(mapType);
cQuery.addBindValue(topleftLat);
cQuery.addBindValue(topleftLon);
cQuery.addBindValue(bottomRightLat);
cQuery.addBindValue(bottomRightLon);
cQuery.addBindValue(minZoom);
cQuery.addBindValue(maxZoom);
cQuery.addBindValue(type);
cQuery.addBindValue(numTiles);
cQuery.addBindValue(defaultSet);
cQuery.addBindValue(QDateTime::currentDateTime().toTime_t());
if(!cQuery.exec()) {
task->setError("Error adding imported tile set to database");
break;
} else {
//-- Get just created (auto-incremented) setID
insertSetID = cQuery.lastInsertId().toULongLong();
}
}
//-- Find set tiles
QSqlQuery cQuery(*_db);
QSqlQuery subQuery(*dbImport);
QString sb = QString("SELECT * FROM Tiles WHERE tileID IN (SELECT A.tileID FROM SetTiles A JOIN SetTiles B ON A.tileID = B.tileID WHERE B.setID = %1 GROUP BY A.tileID HAVING COUNT(A.tileID) = 1)").arg(setID);
if(subQuery.exec(sb)) {
_db->transaction();
while(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
cQuery.prepare("INSERT INTO Tiles(hash, format, tile, size, type, date) VALUES(?, ?, ?, ?, ?, ?)");
cQuery.addBindValue(hash);
cQuery.addBindValue(format);
cQuery.addBindValue(img);
cQuery.addBindValue(img.size());
cQuery.addBindValue(type);
cQuery.addBindValue(QDateTime::currentDateTime().toTime_t());
if(cQuery.exec()) {
quint64 importTileID = cQuery.lastInsertId().toULongLong();
QString s = QString("INSERT INTO SetTiles(tileID, setID) VALUES(%1, %2)").arg(importTileID).arg(insertSetID);
cQuery.prepare(s);
cQuery.exec();
currentCount++;
task->setProgress((int)((double)currentCount / (double)tileCount * 100.0));
}
}
_db->commit();
//-- Update tile count
s = QString("SELECT COUNT(size) FROM Tiles A INNER JOIN SetTiles B on A.tileID = B.tileID WHERE B.setID = %1").arg(insertSetID);
if(cQuery.exec(s)) {
if(cQuery.next()) {
quint64 count = cQuery.value(0).toULongLong();
s = QString("UPDATE TileSets SET numTiles = %1 WHERE setID = %2").arg(count).arg(insertSetID);
cQuery.exec(s);
}
}
}
}
} else {
task->setError("No tile set in database");
}
delete dbImport;
QSqlDatabase::removeDatabase(kExportSession);
} else {
task->setError("Error opening import database");
}
}
task->setImportCompleted();
}
//-----------------------------------------------------------------------------
void
QGCCacheWorker::_exportSets(QGCMapTask* mtask)
{
if(!_testTask(mtask)) {
return;
}
QGCExportTileTask* task = static_cast<QGCExportTileTask*>(mtask);
//-- Delete target if it exists
QFile file(task->path());
file.remove();
//-- 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)) {
//-- Prepare progress report
quint64 tileCount = 0;
quint64 currentCount = 0;
for(int i = 0; i < task->sets().count(); i++) {
QGCCachedTileSet* set = task->sets()[i];
//-- Default set has no unique tiles
if(set->defaultSet()) {
tileCount += set->totalTileCount();
} else {
tileCount += set->uniqueTileCount();
}
}
if(!tileCount) {
tileCount = 1;
}
//-- 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, defaultSet, date"
") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
exportQuery.addBindValue(set->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(set->defaultSet());
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)) {
dbExport->transaction();
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();
currentCount++;
task->setProgress((int)((double)currentCount / (double)tileCount * 100.0));
}
}
}
}
}
dbExport->commit();
}
}
} 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;
QSqlDatabase::removeDatabase(kExportSession);
task->setExportCompleted();
}
//-----------------------------------------------------------------------------
bool QGCCacheWorker::_testTask(QGCMapTask* mtask)
{
if(!_valid) {
mtask->setError("No Cache Database");
return false;
}
return true;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool bool
QGCCacheWorker::_init() QGCCacheWorker::_init()
...@@ -648,7 +927,10 @@ QGCCacheWorker::_init() ...@@ -648,7 +927,10 @@ QGCCacheWorker::_init()
_db->setDatabaseName(_databasePath); _db->setDatabaseName(_databasePath);
_db->setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE"); _db->setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE");
if (_db->open()) { if (_db->open()) {
_createDB(); _valid = _createDB(_db);
if(!_valid) {
_failed = true;
}
} else { } else {
qCritical() << "Map Cache SQL error (init() open db):" << _db->lastError(); qCritical() << "Map Cache SQL error (init() open db):" << _db->lastError();
_failed = true; _failed = true;
...@@ -665,10 +947,11 @@ QGCCacheWorker::_init() ...@@ -665,10 +947,11 @@ QGCCacheWorker::_init()
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void bool
QGCCacheWorker::_createDB() QGCCacheWorker::_createDB(QSqlDatabase* db, bool createDefault)
{ {
QSqlQuery query(*_db); bool res = false;
QSqlQuery query(*db);
if(!query.exec( if(!query.exec(
"CREATE TABLE IF NOT EXISTS Tiles (" "CREATE TABLE IF NOT EXISTS Tiles ("
"tileID INTEGER PRIMARY KEY NOT NULL, " "tileID INTEGER PRIMARY KEY NOT NULL, "
...@@ -719,13 +1002,13 @@ QGCCacheWorker::_createDB() ...@@ -719,13 +1002,13 @@ QGCCacheWorker::_createDB()
qWarning() << "Map Cache SQL error (create TilesDownload db):" << query.lastError().text(); qWarning() << "Map Cache SQL error (create TilesDownload db):" << query.lastError().text();
} else { } else {
//-- Database it ready for use //-- Database it ready for use
_valid = true; res = true;
} }
} }
} }
} }
//-- Create default tile set //-- Create default tile set
if(_valid) { if(res && createDefault) {
QString s = QString("SELECT name FROM TileSets WHERE name = \"%1\"").arg(kDefaultSet); QString s = QString("SELECT name FROM TileSets WHERE name = \"%1\"").arg(kDefaultSet);
if(query.exec(s)) { if(query.exec(s)) {
if(!query.next()) { if(!query.next()) {
...@@ -734,19 +1017,19 @@ QGCCacheWorker::_createDB() ...@@ -734,19 +1017,19 @@ QGCCacheWorker::_createDB()
query.addBindValue(1); query.addBindValue(1);
query.addBindValue(QDateTime::currentDateTime().toTime_t()); query.addBindValue(QDateTime::currentDateTime().toTime_t());
if(!query.exec()) { if(!query.exec()) {
qWarning() << "Map Cache SQL error (Creating default tile set):" << _db->lastError(); qWarning() << "Map Cache SQL error (Creating default tile set):" << db->lastError();
_valid = false; res = false;
} }
} }
} else { } 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); QFile file(_databasePath);
file.remove(); file.remove();
} }
_failed = !_valid; return res;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
......
...@@ -59,13 +59,16 @@ private: ...@@ -59,13 +59,16 @@ private:
void _deleteTileSet (QGCMapTask* mtask); void _deleteTileSet (QGCMapTask* mtask);
void _resetCacheDatabase (QGCMapTask* mtask); void _resetCacheDatabase (QGCMapTask* mtask);
void _pruneCache (QGCMapTask* mtask); void _pruneCache (QGCMapTask* mtask);
void _exportSets (QGCMapTask* mtask);
void _importSets (QGCMapTask* mtask);
bool _testTask (QGCMapTask* mtask);
void _testInternet (); void _testInternet ();
quint64 _findTile (const QString hash); quint64 _findTile (const QString hash);
bool _findTileSetID (const QString name, quint64& setID); bool _findTileSetID (const QString name, quint64& setID);
void _updateSetTotals (QGCCachedTileSet* set); void _updateSetTotals (QGCCachedTileSet* set);
bool _init (); bool _init ();
void _createDB (); bool _createDB (QSqlDatabase *db, bool createDefault = true);
quint64 _getDefaultTileSet (); quint64 _getDefaultTileSet ();
void _updateTotals (); void _updateTotals ();
......
...@@ -15,11 +15,12 @@ import QtQuick.Layouts 1.2 ...@@ -15,11 +15,12 @@ import QtQuick.Layouts 1.2
import QtLocation 5.3 import QtLocation 5.3
import QtPositioning 5.3 import QtPositioning 5.3
import QGroundControl 1.0 import QGroundControl 1.0
import QGroundControl.Controls 1.0 import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0 import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0 import QGroundControl.Palette 1.0
import QGroundControl.FlightMap 1.0 import QGroundControl.FlightMap 1.0
import QGroundControl.QGCMapEngineManager 1.0
QGCView { QGCView {
id: offlineMapView id: offlineMapView
...@@ -37,7 +38,9 @@ QGCView { ...@@ -37,7 +38,9 @@ QGCView {
property string savedMapType: "" property string savedMapType: ""
property bool _showPreview: true property bool _showPreview: true
property bool _defaultSet: offlineMapView && offlineMapView._currentSelection && offlineMapView._currentSelection.defaultSet 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 real _bigButtonSize: ScreenTools.defaultFontPixelWidth * 16
property bool _saveRealEstate: ScreenTools.isTinyScreen || ScreenTools.isShortScreen property bool _saveRealEstate: ScreenTools.isTinyScreen || ScreenTools.isShortScreen
property real _adjustableFontPointSize: _saveRealEstate ? ScreenTools.smallFontPointSize : ScreenTools.defaultFontPointSize property real _adjustableFontPointSize: _saveRealEstate ? ScreenTools.smallFontPointSize : ScreenTools.defaultFontPointSize
...@@ -100,15 +103,27 @@ QGCView { ...@@ -100,15 +103,27 @@ QGCView {
_map.visible = true _map.visible = true
_tileSetList.visible = false _tileSetList.visible = false
infoView.visible = false infoView.visible = false
_exporTiles.visible = false
addNewSetView.visible = true addNewSetView.visible = true
} }
function showList() { function showList() {
_exporTiles.visible = false
isMapInteractive = false isMapInteractive = false
_map.visible = false _map.visible = false
_tileSetList.visible = true _tileSetList.visible = true
infoView.visible = false infoView.visible = false
addNewSetView.visible = false addNewSetView.visible = false
QGroundControl.mapEngineManager.resetAction();
}
function showExport() {
isMapInteractive = false
_map.visible = false
_tileSetList.visible = false
infoView.visible = false
addNewSetView.visible = false
_exporTiles.visible = true
} }
function showInfo() { function showInfo() {
...@@ -796,7 +811,7 @@ QGCView { ...@@ -796,7 +811,7 @@ QGCView {
clip: true clip: true
anchors.margins: ScreenTools.defaultFontPixelWidth anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: _optionsButton.top anchors.bottom: _listButtonRow.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
contentHeight: _cacheList.height contentHeight: _cacheList.height
...@@ -806,7 +821,6 @@ QGCView { ...@@ -806,7 +821,6 @@ QGCView {
width: Math.min(_tileSetList.width, (ScreenTools.defaultFontPixelWidth * 50).toFixed(0)) width: Math.min(_tileSetList.width, (ScreenTools.defaultFontPixelWidth * 50).toFixed(0))
spacing: ScreenTools.defaultFontPixelHeight * 0.5 spacing: ScreenTools.defaultFontPixelHeight * 0.5
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
OfflineMapButton { OfflineMapButton {
id: firstButton id: firstButton
text: qsTr("Add new set") text: qsTr("Add new set")
...@@ -834,15 +848,365 @@ QGCView { ...@@ -834,15 +848,365 @@ QGCView {
} }
} }
} }
Row {
id: _listButtonRow
visible: _tileSetList.visible
spacing: _margins
anchors.bottom: parent.bottom
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
QGCButton {
text: qsTr("Import")
width: _buttonSize
visible: !ScreenTools.isMobile
onClicked: rootLoader.sourceComponent = importDialog
}
QGCButton {
text: qsTr("Export")
width: _buttonSize
visible: !ScreenTools.isMobile
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 { //-- Export Tile Sets
id: _optionsButton QGCFlickable {
text: qsTr("Options") id: _exporTiles
visible: _tileSetList.visible clip: true
anchors.bottom: parent.bottom visible: false
anchors.right: parent.right anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.margins: ScreenTools.defaultFontPixelWidth anchors.top: parent.top
onClicked: showDialog(optionsDialogComponent, qsTr("Offline Maps Options"), qgcView.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel) 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.margins: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
QGCButton {
text: qsTr("Select All")
width: _bigButtonSize
onClicked: QGroundControl.mapEngineManager.selectAll()
}
QGCButton {
text: qsTr("Select None")
width: _bigButtonSize
onClicked: QGroundControl.mapEngineManager.selectNone()
}
QGCButton {
text: qsTr("Export to Disk")
width: _bigButtonSize
enabled: QGroundControl.mapEngineManager.selectedCount > 0
onClicked: {
showList();
if(QGroundControl.mapEngineManager.exportSets()) {
rootLoader.sourceComponent = exportToDiskProgress
}
}
}
QGCButton {
text: qsTr("Export to Device")
width: _bigButtonSize
enabled: QGroundControl.mapEngineManager.selectedCount > 0
onClicked: {
rootLoader.sourceComponent = exportToDevice
}
}
QGCButton {
text: qsTr("Cancel")
width: _bigButtonSize
onClicked: showList()
}
} }
} // QGCViewPanel } // QGCViewPanel
Component {
id: exportToDiskProgress
Rectangle {
width: mainWindow.width
height: mainWindow.height
color: "black"
anchors.centerIn: parent
Rectangle {
width: parent.width * 0.5
height: exportCol.height * 1.25
radius: ScreenTools.defaultFontPixelWidth
color: qgcPal.windowShadeDark
border.color: qgcPal.text
anchors.centerIn: parent
Column {
id: exportCol
spacing: ScreenTools.defaultFontPixelHeight
width: parent.width
anchors.centerIn: parent
QGCLabel {
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
}
ProgressBar {
id: progressBar
width: parent.width * 0.45
maximumValue: 100
value: QGroundControl.mapEngineManager.actionProgress
anchors.horizontalCenter: parent.horizontalCenter
}
BusyIndicator {
visible: QGroundControl.mapEngineManager.exporting
running: QGroundControl.mapEngineManager.exporting
width: exportCloseButton.height
height: exportCloseButton.height
anchors.horizontalCenter: parent.horizontalCenter
}
QGCButton {
id: exportCloseButton
text: qsTr("Close")
width: _buttonSize
visible: !QGroundControl.mapEngineManager.exporting
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
rootLoader.sourceComponent = null
}
}
}
}
}
}
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 * 2
height: width
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: {
rootLoader.sourceComponent = importFromDevice
}
}
QGCButton {
text: qsTr("Cancel")
width: _bigButtonSize * 1.25
onClicked: {
showList();
rootLoader.sourceComponent = null
}
}
}
}
}
}
}
Component {
id: importFromDevice
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: qsTr("Map Tile Set Import From Device");
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: qsTr("NOT YET IMPLEMENTED");
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
QGCButton {
text: qsTr("Close")
width: _bigButtonSize * 1.25
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
showList();
rootLoader.sourceComponent = null
}
}
}
}
}
}
Component {
id: exportToDevice
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: qsTr("Map Tile Set Export To Device");
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: qsTr("NOT YET IMPLEMENTED");
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
QGCButton {
text: qsTr("Close")
width: _bigButtonSize * 1.25
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
showList();
rootLoader.sourceComponent = null
}
}
}
}
}
}
} // QGCView } // QGCView
...@@ -11,6 +11,11 @@ ...@@ -11,6 +11,11 @@
/// @file /// @file
/// @author Gus Grubba <mavlink@grubba.com> /// @author Gus Grubba <mavlink@grubba.com>
#if !defined(__mobile__)
#include "QGCFileDialog.h"
#include "MainWindow.h"
#endif
#include "QGCMapEngineManager.h" #include "QGCMapEngineManager.h"
#include "QGCApplication.h" #include "QGCApplication.h"
#include "QGCMapTileSet.h" #include "QGCMapTileSet.h"
...@@ -36,6 +41,9 @@ QGCMapEngineManager::QGCMapEngineManager(QGCApplication* app) ...@@ -36,6 +41,9 @@ QGCMapEngineManager::QGCMapEngineManager(QGCApplication* app)
, _setID(UINT64_MAX) , _setID(UINT64_MAX)
, _freeDiskSpace(0) , _freeDiskSpace(0)
, _diskSpace(0) , _diskSpace(0)
, _actionProgress(0)
, _importAction(ActionNone)
, _importReplace(false)
{ {
} }
...@@ -308,6 +316,9 @@ QGCMapEngineManager::taskError(QGCMapTask::TaskType type, QString error) ...@@ -308,6 +316,9 @@ QGCMapEngineManager::taskError(QGCMapTask::TaskType type, QString error)
case QGCMapTask::taskReset: case QGCMapTask::taskReset:
task = "Reset Tile Sets"; task = "Reset Tile Sets";
break; break;
case QGCMapTask::taskExport:
task = "Export Tile Sets";
break;
default: default:
task = "Database Error"; task = "Database Error";
break; break;
...@@ -351,6 +362,142 @@ QGCMapEngineManager::findName(const QString& name) ...@@ -351,6 +362,142 @@ QGCMapEngineManager::findName(const QString& name)
return false; return false;
} }
//-----------------------------------------------------------------------------
void
QGCMapEngineManager::selectAll() {
for(int i = 0; i < _tileSets.count(); i++ ) {
QGCCachedTileSet* set = qobject_cast<QGCCachedTileSet*>(_tileSets.get(i));
Q_ASSERT(set);
set->setSelected(true);
}
}
//-----------------------------------------------------------------------------
void
QGCMapEngineManager::selectNone() {
for(int i = 0; i < _tileSets.count(); i++ ) {
QGCCachedTileSet* set = qobject_cast<QGCCachedTileSet*>(_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<QGCCachedTileSet*>(_tileSets.get(i));
Q_ASSERT(set);
if(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().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__)
dir = QDir(QDir::homePath()).filePath(QString("export_%1.db").arg(QDateTime::currentDateTime().toTime_t()));
#else
dir = QGCFileDialog::getSaveFileName(
MainWindow::instance(),
"Export Tile Set",
QDir::homePath(),
"Tile Sets (*.qgctiledb)",
"qgctiledb",
true);
#endif
}
if(!dir.isEmpty()) {
QVector<QGCCachedTileSet*> sets;
for(int i = 0; i < _tileSets.count(); i++ ) {
QGCCachedTileSet* set = qobject_cast<QGCCachedTileSet*>(_tileSets.get(i));
Q_ASSERT(set);
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);
getQGCMapEngine()->addTask(task);
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
void
QGCMapEngineManager::_actionProgressHandler(int percentage)
{
_actionProgress = percentage;
emit actionProgressChanged();
}
//-----------------------------------------------------------------------------
void
QGCMapEngineManager::_actionCompleted()
{
ImportAction oldState = _importAction;
_importAction = ActionDone;
emit importActionChanged();
//-- If we just imported, reload it all
if(oldState == ActionImporting) {
loadTileSets();
}
}
//-----------------------------------------------------------------------------
void
QGCMapEngineManager::resetAction()
{
_importAction = ActionNone;
emit importActionChanged();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QString QString
QGCMapEngineManager::getUniqueName() QGCMapEngineManager::getUniqueName()
......
...@@ -29,6 +29,14 @@ public: ...@@ -29,6 +29,14 @@ public:
QGCMapEngineManager(QGCApplication* app); QGCMapEngineManager(QGCApplication* app);
~QGCMapEngineManager(); ~QGCMapEngineManager();
enum ImportAction {
ActionNone,
ActionImporting,
ActionExporting,
ActionDone,
};
Q_ENUMS(ImportAction)
Q_PROPERTY(int tileX0 READ tileX0 NOTIFY tileX0Changed) Q_PROPERTY(int tileX0 READ tileX0 NOTIFY tileX0Changed)
Q_PROPERTY(int tileX1 READ tileX1 NOTIFY tileX1Changed) Q_PROPERTY(int tileX1 READ tileX1 NOTIFY tileX1Changed)
Q_PROPERTY(int tileY0 READ tileY0 NOTIFY tileY0Changed) Q_PROPERTY(int tileY0 READ tileY0 NOTIFY tileY0Changed)
...@@ -46,6 +54,12 @@ public: ...@@ -46,6 +54,12 @@ public:
//-- Disk Space in MB //-- Disk Space in MB
Q_PROPERTY(quint32 freeDiskSpace READ freeDiskSpace NOTIFY freeDiskSpaceChanged) Q_PROPERTY(quint32 freeDiskSpace READ freeDiskSpace NOTIFY freeDiskSpaceChanged)
Q_PROPERTY(quint32 diskSpace READ diskSpace CONSTANT) 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 NOTIFY importActionChanged)
Q_PROPERTY(bool importReplace READ importReplace WRITE setImportReplace NOTIFY importReplaceChanged)
Q_INVOKABLE void loadTileSets (); 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 updateForCurrentView (double lon0, double lat0, double lon1, double lat1, int minZoom, int maxZoom, const QString& mapName);
...@@ -55,6 +69,11 @@ public: ...@@ -55,6 +69,11 @@ public:
Q_INVOKABLE void deleteTileSet (QGCCachedTileSet* tileSet); Q_INVOKABLE void deleteTileSet (QGCCachedTileSet* tileSet);
Q_INVOKABLE QString getUniqueName (); Q_INVOKABLE QString getUniqueName ();
Q_INVOKABLE bool findName (const QString& name); 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 ();
int tileX0 () { return _totalSet.tileX0; } int tileX0 () { return _totalSet.tileX0; }
int tileX1 () { return _totalSet.tileX1; } int tileX1 () { return _totalSet.tileX1; }
...@@ -72,10 +91,15 @@ public: ...@@ -72,10 +91,15 @@ public:
QString errorMessage () { return _errorMessage; } QString errorMessage () { return _errorMessage; }
quint64 freeDiskSpace () { return _freeDiskSpace; } quint64 freeDiskSpace () { return _freeDiskSpace; }
quint64 diskSpace () { return _diskSpace; } quint64 diskSpace () { return _diskSpace; }
int selectedCount ();
int actionProgress () { return _actionProgress; }
ImportAction importAction () { return _importAction; }
bool importReplace () { return _importReplace; }
void setMapboxToken (QString token); void setMapboxToken (QString token);
void setMaxMemCache (quint32 size); void setMaxMemCache (quint32 size);
void setMaxDiskCache (quint32 size); void setMaxDiskCache (quint32 size);
void setImportReplace (bool replace) { _importReplace = replace; emit importReplaceChanged(); }
void setErrorMessage (const QString& error) { _errorMessage = error; emit errorMessageChanged(); } void setErrorMessage (const QString& error) { _errorMessage = error; emit errorMessageChanged(); }
...@@ -95,6 +119,10 @@ signals: ...@@ -95,6 +119,10 @@ signals:
void maxDiskCacheChanged (); void maxDiskCacheChanged ();
void errorMessageChanged (); void errorMessageChanged ();
void freeDiskSpaceChanged (); void freeDiskSpaceChanged ();
void selectedCountChanged ();
void actionProgressChanged ();
void importActionChanged ();
void importReplaceChanged ();
public slots: public slots:
void taskError (QGCMapTask::TaskType type, QString error); void taskError (QGCMapTask::TaskType type, QString error);
...@@ -105,6 +133,8 @@ private slots: ...@@ -105,6 +133,8 @@ private slots:
void _tileSetDeleted (quint64 setID); void _tileSetDeleted (quint64 setID);
void _updateTotals (quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize); void _updateTotals (quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize);
void _resetCompleted (); void _resetCompleted ();
void _actionCompleted ();
void _actionProgressHandler (int percentage);
private: private:
void _updateDiskFreeSpace (); void _updateDiskFreeSpace ();
...@@ -122,6 +152,9 @@ private: ...@@ -122,6 +152,9 @@ private:
quint32 _diskSpace; quint32 _diskSpace;
QmlObjectListModel _tileSets; QmlObjectListModel _tileSets;
QString _errorMessage; QString _errorMessage;
int _actionProgress;
ImportAction _importAction;
bool _importReplace;
}; };
#endif #endif
...@@ -232,14 +232,14 @@ Rectangle { ...@@ -232,14 +232,14 @@ Rectangle {
} }
Repeater { Repeater {
model: _corePlugin.settingsPages model: _corePlugin ? _corePlugin.settingsPages : []
visible: _corePlugin.options.combineSettingsAndSetup visible: _corePlugin && _corePlugin.options.combineSettingsAndSetup
SubMenuButton { SubMenuButton {
imageResource: modelData.icon imageResource: modelData.icon
setupIndicator: false setupIndicator: false
exclusiveGroup: setupButtonGroup exclusiveGroup: setupButtonGroup
text: modelData.title text: modelData.title
visible: _corePlugin.options.combineSettingsAndSetup visible: _corePlugin && _corePlugin.options.combineSettingsAndSetup
onClicked: panelLoader.setSource(modelData.url) onClicked: panelLoader.setSource(modelData.url)
Layout.fillWidth: true Layout.fillWidth: true
} }
...@@ -312,7 +312,7 @@ Rectangle { ...@@ -312,7 +312,7 @@ Rectangle {
SubMenuButton { SubMenuButton {
setupIndicator: false setupIndicator: false
exclusiveGroup: setupButtonGroup exclusiveGroup: setupButtonGroup
visible: QGroundControl.multiVehicleManager.parameterReadyVehicleAvailable && _corePlugin.showAdvancedUI visible: QGroundControl.multiVehicleManager && QGroundControl.multiVehicleManager.parameterReadyVehicleAvailable && _corePlugin.showAdvancedUI
text: "Parameters" text: "Parameters"
Layout.fillWidth: true Layout.fillWidth: true
......
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