diff --git a/gpxsee.pro b/gpxsee.pro index 0d668643..3e9341de 100644 --- a/gpxsee.pro +++ b/gpxsee.pro @@ -106,6 +106,7 @@ HEADERS += src/common/config.h \ src/map/IMG/textpathitem.h \ src/map/IMG/textpointitem.h \ src/map/bsbmap.h \ + src/map/invalidmap.h \ src/map/polyconic.h \ src/map/projection.h \ src/map/ellipsoid.h \ diff --git a/src/GUI/gui.cpp b/src/GUI/gui.cpp index 9afe2c07..b01ec198 100644 --- a/src/GUI/gui.cpp +++ b/src/GUI/gui.cpp @@ -131,11 +131,17 @@ void GUI::createMapActions() if (mapDir.isNull()) return; - QString unused; - QList maps(MapList::loadMaps(mapDir, unused)); + QList maps(MapList::loadMaps(mapDir)); for (int i = 0; i < maps.count(); i++) { - MapAction *a = createMapAction(maps.at(i)); - connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized())); + Map *map = maps.at(i); + if (map->isValid()) { + MapAction *a = createMapAction(map); + connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized())); + } else { + qWarning("%s: %s", qPrintable(map->path()), + qPrintable(map->errorString())); + delete map; + } } } @@ -160,7 +166,7 @@ void GUI::mapInitialized() _showMapAction->setEnabled(true); _clearMapCacheAction->setEnabled(true); } else { - qWarning("%s: %s", qPrintable(map->name()), qPrintable(map->errorString())); + qWarning("%s: %s", qPrintable(map->path()), qPrintable(map->errorString())); action->deleteLater(); } } @@ -1463,32 +1469,36 @@ static MapAction *findMapAction(const QList &mapActions, bool GUI::loadMap(const QString &fileName, MapAction *&action, bool silent) { - QString error; - QList maps(MapList::loadMaps(fileName, error)); - if (maps.isEmpty()) { - error = tr("Error loading map:") + "\n\n" + fileName + "\n\n" + error; - if (!silent) - QMessageBox::critical(this, APP_NAME, error); - return false; - } - + QList maps(MapList::loadMaps(fileName)); + QList existingActions(_mapsActionGroup->actions()); MapAction *lastReady = 0; - QList mapActions(_mapsActionGroup->actions()); + bool valid = false; for (int i = 0; i < maps.size(); i++) { Map *map = maps.at(i); MapAction *a; - if (!(a = findMapAction(mapActions, map))) { - a = createMapAction(map); - _mapMenu->insertAction(_mapsEnd, a); - if (map->isReady()) { - lastReady = a; - _showMapAction->setEnabled(true); - _clearMapCacheAction->setEnabled(true); - } else - connect(a, SIGNAL(loaded()), this, SLOT(mapLoaded())); + if (!(a = findMapAction(existingActions, map))) { + if (!map->isValid()) { + if (!silent) + QMessageBox::critical(this, APP_NAME, + tr("Error loading map:") + "\n\n" + map->path() + "\n\n" + + map->errorString()); + delete map; + } else { + valid = true; + a = createMapAction(map); + _mapMenu->insertAction(_mapsEnd, a); + + if (map->isReady()) { + lastReady = a; + _showMapAction->setEnabled(true); + _clearMapCacheAction->setEnabled(true); + } else + connect(a, SIGNAL(loaded()), this, SLOT(mapLoaded())); + } } else { + valid = true; map = a->data().value(); if (map->isReady()) lastReady = a; @@ -1497,7 +1507,7 @@ bool GUI::loadMap(const QString &fileName, MapAction *&action, bool silent) action = lastReady; - return true; + return valid; } void GUI::mapLoaded() @@ -1510,7 +1520,23 @@ void GUI::mapLoaded() _showMapAction->setEnabled(true); _clearMapCacheAction->setEnabled(true); } else { - QString error = tr("Error loading map:") + "\n\n" + map->name() + "\n\n" + QString error = tr("Error loading map:") + "\n\n" + map->path() + "\n\n" + + map->errorString(); + QMessageBox::critical(this, APP_NAME, error); + action->deleteLater(); + } +} + +void GUI::mapLoadedNoTrigger() +{ + MapAction *action = static_cast(QObject::sender()); + Map *map = action->data().value(); + + if (map->isValid()) { + _showMapAction->setEnabled(true); + _clearMapCacheAction->setEnabled(true); + } else { + QString error = tr("Error loading map:") + "\n\n" + map->path() + "\n\n" + map->errorString(); QMessageBox::critical(this, APP_NAME, error); action->deleteLater(); @@ -1524,35 +1550,39 @@ void GUI::loadMapDir() if (dir.isEmpty()) return; - QString error; - QList maps(MapList::loadMaps(dir, error)); - if (maps.isEmpty()) { - QMessageBox::critical(this, APP_NAME, tr("No usable map found")); - return; - } - - QList items(_mapView->loadMaps(maps)); - QList mapActions(_mapsActionGroup->actions()); - + QList maps(MapList::loadMaps(dir)); + QList actions; + QList existingActions(_mapsActionGroup->actions()); QFileInfo fi(dir); QMenu *menu = new QMenu(fi.fileName()); for (int i = 0; i < maps.size(); i++) { Map *map = maps.at(i); + MapAction *a; - if (!findMapAction(mapActions, map)) { - MapAction *a = createMapAction(map); - menu->addAction(a); - if (map->isReady()) { - _showMapAction->setEnabled(true); - _clearMapCacheAction->setEnabled(true); - } else - connect(a, SIGNAL(loaded()), this, SLOT(mapLoaded())); + if (!(a = findMapAction(existingActions, map))) { + if (!map->isValid()) { + QMessageBox::critical(this, APP_NAME, tr("Error loading map:") + + "\n\n" + map->path() + "\n\n" + map->errorString()); + delete map; + } else { + a = createMapAction(map); + menu->addAction(a); + actions.append(a); - connect(items.at(i), SIGNAL(triggered()), a, SLOT(trigger())); - } + if (map->isReady()) { + _showMapAction->setEnabled(true); + _clearMapCacheAction->setEnabled(true); + } else + connect(a, SIGNAL(loaded()), this, + SLOT(mapLoadedNoTrigger())); + } + } else + actions.append(a); } + _mapView->loadMaps(actions); + if (menu->isEmpty()) delete menu; else { diff --git a/src/GUI/gui.h b/src/GUI/gui.h index c0063353..fc42509b 100644 --- a/src/GUI/gui.h +++ b/src/GUI/gui.h @@ -96,6 +96,7 @@ private slots: void logicalDotsPerInchChanged(qreal dpi); void mapLoaded(); + void mapLoadedNoTrigger(); void mapInitialized(); private: diff --git a/src/GUI/mapview.cpp b/src/GUI/mapview.cpp index c20961d0..39e7e715 100644 --- a/src/GUI/mapview.cpp +++ b/src/GUI/mapview.cpp @@ -18,6 +18,7 @@ #include "mapitem.h" #include "keys.h" #include "graphicsscene.h" +#include "mapaction.h" #include "mapview.h" @@ -271,13 +272,19 @@ QList MapView::loadData(const Data &data) return paths; } -QList MapView::loadMaps(const QList &maps) +void MapView::loadMaps(const QList &maps) { - QList items; int zoom = _map->zoom(); - for (int i = 0; i < maps.size(); i++) - items.append(addMap(maps.at(i))); + for (int i = 0; i < maps.size(); i++) { + MapAction *a = maps.at(i); + Map *map = a->data().value(); + if (map->isReady()) { + MapItem *mi = addMap(map); + connect(mi, SIGNAL(triggered()), a, SLOT(trigger())); + } else + connect(a, SIGNAL(loaded()), this, SLOT(mapLoaded())); + } if (fitMapZoom() != zoom) rescale(); @@ -287,8 +294,29 @@ QList MapView::loadMaps(const QList &maps) updateZValues(_areas); centerOn(contentCenter()); +} - return items; +void MapView::mapLoaded() +{ + MapAction *action = static_cast(QObject::sender()); + Map *map = action->data().value(); + + if (!map->isValid()) + return; + + int zoom = _map->zoom(); + + MapItem *mi = addMap(map); + connect(mi, SIGNAL(triggered()), action, SLOT(trigger())); + + if (fitMapZoom() != zoom) + rescale(); + else + updatePOIVisibility(); + + updateZValues(_areas); + + centerOn(contentCenter()); } int MapView::fitMapZoom() const diff --git a/src/GUI/mapview.h b/src/GUI/mapview.h index cd33ab08..d800b621 100644 --- a/src/GUI/mapview.h +++ b/src/GUI/mapview.h @@ -34,6 +34,7 @@ class MapItem; class Area; class GraphicsScene; class QTimeZone; +class MapAction; class MapView : public QGraphicsView { @@ -50,7 +51,7 @@ public: MapView(Map *map, POI *poi, QWidget *parent = 0); QList loadData(const Data &data); - QList loadMaps(const QList &maps); + void loadMaps(const QList &maps); void setPalette(const Palette &palette); void setPOI(POI *poi); @@ -104,6 +105,7 @@ public slots: private slots: void updatePOI(); void reloadMap(); + void mapLoaded(); private: typedef QHash, WaypointItem*> POIHash; diff --git a/src/map/invalidmap.h b/src/map/invalidmap.h new file mode 100644 index 00000000..d676580e --- /dev/null +++ b/src/map/invalidmap.h @@ -0,0 +1,30 @@ +#ifndef INVALIDMAP_H +#define INVALIDMAP_H + +#include "map.h" + +class InvalidMap : public Map +{ + Q_OBJECT + +public: + InvalidMap(const QString &fileName, const QString &error, QObject *parent = 0) + : Map(fileName, parent), _errorString(error) {} + + QString name() const {return QString();} + + QRectF bounds() {return QRectF();} + + QPointF ll2xy(const Coordinates &) {return QPointF();} + Coordinates xy2ll(const QPointF &) {return Coordinates();} + + void draw(QPainter *, const QRectF &, Flags) {} + + bool isValid() const {return false;} + QString errorString() const {return _errorString;} + +private: + QString _errorString; +}; + +#endif // INVALIDMAP_H diff --git a/src/map/maplist.cpp b/src/map/maplist.cpp index 451e8c00..1d1bfc2c 100644 --- a/src/map/maplist.cpp +++ b/src/map/maplist.cpp @@ -11,11 +11,11 @@ #include "imgmap.h" #include "IMG/gmap.h" #include "bsbmap.h" +#include "invalidmap.h" #include "maplist.h" -Map *MapList::loadFile(const QString &path, QString &errorString, - bool *terminate) +Map *MapList::loadFile(const QString &path, bool *terminate) { QFileInfo fi(path); QString suffix = fi.suffix().toLower(); @@ -27,12 +27,11 @@ Map *MapList::loadFile(const QString &path, QString &errorString, map = new Atlas(path); } else if (suffix == "xml") { if (MapSource::isMap(path)) { - if (!(map = MapSource::loadMap(path, errorString))) - return 0; + map = MapSource::loadMap(path); } else if (GMAP::isGMAP(path)) { + map = new IMGMap(path); if (terminate) *terminate = true; - map = new IMGMap(path); } } else if (suffix == "jnx") map = new JNXMap(path); @@ -49,16 +48,10 @@ Map *MapList::loadFile(const QString &path, QString &errorString, else if (suffix == "kap") map = new BSBMap(path); - if (map && map->isValid()) - return map; - else { - errorString = (map) ? map->errorString() : "Unknown file format"; - delete map; - return 0; - } + return map ? map : new InvalidMap(path, "Unknown file format"); } -QList MapList::loadDir(const QString &path, QString &errorString) +QList MapList::loadDir(const QString &path) { QDir md(path); md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); @@ -72,14 +65,9 @@ QList MapList::loadDir(const QString &path, QString &errorString) bool terminate = false; if (fi.isDir() && fi.fileName() != "set") - list.append(loadDir(fi.absoluteFilePath(), errorString)); + list.append(loadDir(fi.absoluteFilePath())); else if (filter().contains("*." + suffix)) { - Map *map = loadFile(fi.absoluteFilePath(), errorString, &terminate); - if (map) - list.append(map); - else - qWarning("%s: %s", qPrintable(fi.absoluteFilePath()), - qPrintable(errorString)); + list.append(loadFile(fi.absoluteFilePath(), &terminate)); if (terminate) break; } @@ -88,15 +76,13 @@ QList MapList::loadDir(const QString &path, QString &errorString) return list; } -QList MapList::loadMaps(const QString &path, QString &errorString) +QList MapList::loadMaps(const QString &path) { if (QFileInfo(path).isDir()) - return loadDir(path, errorString); + return loadDir(path); else { QList list; - Map *map = loadFile(path, errorString, 0); - if (map) - list.append(map); + list.append(loadFile(path, 0)); return list; } } diff --git a/src/map/maplist.h b/src/map/maplist.h index e558dcf1..37a8d21b 100644 --- a/src/map/maplist.h +++ b/src/map/maplist.h @@ -8,14 +8,13 @@ class Map; class MapList { public: - static QList loadMaps(const QString &path, QString &errorString); + static QList loadMaps(const QString &path); static QString formats(); static QStringList filter(); private: - static Map *loadFile(const QString &path, QString &errorString, - bool *terminate); - static QList loadDir(const QString &path, QString &errorString); + static Map *loadFile(const QString &path, bool *terminate); + static QList loadDir(const QString &path); }; #endif // MAPLIST_H diff --git a/src/map/mapsource.cpp b/src/map/mapsource.cpp index 82f3aa90..46088c4e 100644 --- a/src/map/mapsource.cpp +++ b/src/map/mapsource.cpp @@ -5,6 +5,7 @@ #include "wmtsmap.h" #include "wmsmap.h" #include "osm.h" +#include "invalidmap.h" #include "mapsource.h" @@ -236,16 +237,14 @@ bool MapSource::isMap(const QString &path) return false; } -Map *MapSource::loadMap(const QString &path, QString &errorString) +Map *MapSource::loadMap(const QString &path) { Config config; QFile file(path); - if (!file.open(QFile::ReadOnly | QFile::Text)) { - errorString = file.errorString(); - return 0; - } + if (!file.open(QFile::ReadOnly | QFile::Text)) + return new InvalidMap(path, file.errorString()); QXmlStreamReader reader(&file); if (reader.readNextStartElement()) { @@ -254,41 +253,27 @@ Map *MapSource::loadMap(const QString &path, QString &errorString) else reader.raiseError("Not an online map source file"); } - if (reader.error()) { - errorString = QString("%1: %2").arg(reader.lineNumber()) - .arg(reader.errorString()); - return 0; - } + if (reader.error()) + return new InvalidMap(path, QString("%1: %2").arg(reader.lineNumber()) + .arg(reader.errorString())); - if (config.name.isEmpty()) { - errorString = "Missing name definition"; - return 0; - } - if (config.url.isEmpty()) { - errorString = "Missing URL definition"; - return 0; - } + if (config.name.isEmpty()) + return new InvalidMap(path, "Missing name definition"); + if (config.url.isEmpty()) + return new InvalidMap(path, "Missing URL definition"); if (config.type == WMTS || config.type == WMS) { - if (config.layer.isEmpty()) { - errorString = "Missing layer definition"; - return 0; - } - if (config.format.isEmpty()) { - errorString = "Missing format definition"; - return 0; - } + if (config.layer.isEmpty()) + return new InvalidMap(path, "Missing layer definition"); + if (config.format.isEmpty()) + return new InvalidMap(path, "Missing format definition"); } if (config.type == WMTS) { - if (config.set.isEmpty()) { - errorString = "Missing set definiton"; - return 0; - } + if (config.set.isEmpty()) + return new InvalidMap(path, "Missing set definiton"); } if (config.type == WMS) { - if (config.crs.isEmpty()) { - errorString = "Missing CRS definiton"; - return 0; - } + if (config.crs.isEmpty()) + return new InvalidMap(path, "Missing CRS definiton"); } switch (config.type) { @@ -315,6 +300,6 @@ Map *MapSource::loadMap(const QString &path, QString &errorString) config.bounds, config.tileRatio, config.authorization, config.tileSize, config.scalable, false, true); default: - return 0; + return new InvalidMap(path, "Invalid map type"); } } diff --git a/src/map/mapsource.h b/src/map/mapsource.h index abeecdd6..564e9dc6 100644 --- a/src/map/mapsource.h +++ b/src/map/mapsource.h @@ -14,7 +14,7 @@ class QXmlStreamReader; class MapSource { public: - static Map *loadMap(const QString &path, QString &errorString); + static Map *loadMap(const QString &path); static bool isMap(const QString &path); private: