From 81e1664a9b6ccf4ef978988402446a727fb4666a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Thu, 27 Jul 2017 19:47:46 +0200 Subject: [PATCH] Data/map loading code cleanup --- lang/gpxsee_cs.ts | 309 ++++++++++++++++++++++---------------------- lang/gpxsee_de.ts | 309 ++++++++++++++++++++++---------------------- lang/gpxsee_sv.ts | 311 +++++++++++++++++++++++---------------------- src/csvparser.cpp | 7 +- src/csvparser.h | 7 +- src/data.cpp | 64 ++++++---- src/data.h | 19 ++- src/fitparser.cpp | 32 +++-- src/fitparser.h | 14 +- src/gpxparser.cpp | 31 ++--- src/gpxparser.h | 9 +- src/gui.cpp | 59 ++++----- src/gui.h | 2 - src/igcparser.cpp | 20 +-- src/igcparser.h | 11 +- src/kmlparser.cpp | 63 +++++---- src/kmlparser.h | 18 ++- src/maplist.cpp | 136 ++++++++++++-------- src/maplist.h | 15 ++- src/nmeaparser.cpp | 46 ++++--- src/nmeaparser.h | 13 +- src/parser.h | 11 +- src/pathview.cpp | 2 +- src/tcxparser.cpp | 40 +++--- src/tcxparser.h | 14 +- 25 files changed, 820 insertions(+), 742 deletions(-) diff --git a/lang/gpxsee_cs.ts b/lang/gpxsee_cs.ts index 4d8860ad..1f0bf905 100644 --- a/lang/gpxsee_cs.ts +++ b/lang/gpxsee_cs.ts @@ -25,6 +25,54 @@ Maximum + + Data + + + Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) + Podporované soubory (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) + + + + CSV files (*.csv) + Soubory CSV (*.csv) + + + + FIT files (*.fit) + Soubory FIT (*.fit) + + + + GPX files (*.gpx) + Soubory GPX (*.gpx) + + + + IGC files (*.igc) + Soubory IGC (*.igc) + + + + KML files (*.kml) + Soubory KML (*.kml) + + + + NMEA files (*.nmea) + Soubory NMEA (*.nmea) + + + + TCX files (*.tcx) + Soubory TCX (*.tcx) + + + + All files (*) + Všechny soubory (*) + + ElevationGraph @@ -190,366 +238,321 @@ GUI - + GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at Program GPXSee je distribuován pod podmínkami licence GNU General Public License verze 3. Pro více informací navštivte stránky programu na adrese - + Open file Otevřít soubor - + Open POI file Otevřít POI soubor - + Quit Ukončit - - - + + + Keyboard controls Ovládací klávesy - + Close Zavřít - + Reload Znovu načíst - + Show Zobrazit - - + + File Soubor - - FIT files (*.fit) - Soubory FIT (*.fit) - - - - IGC files (*.igc) - Soubory IGC (*.igc) - - - - NMEA files (*.nmea) - Soubory NMEA (*.nmea) - - - - - + + + Data sources Zdroje dat - + Close POI files Zavřit POI soubory - + Overlap POIs Překrývat POI - + Show POI labels Zobrazit názvy POI - + Show POIs Zobrazit POI - + Show map Zobrazit mapu - + Clear tile cache Vymazat mezipaměť dlaždic - + Open... Otevřít... - + Load POI file... Nahrát POI soubor... - + Load map... Nahrát mapu... - - - + + + Next map Následující mapa - + Show tracks Zobrazit cesty - + Show routes Zobrazit trasy - + Show waypoints Zobrazit navigační body - + Waypoint labels Názvy navigačních bodů - + Show graphs Zobrazit grafy - + Show grid Zobrazit mřížku - + Show toolbars Zobrazovat nástrojové lišty - + Total time Celkový čas - - + + Moving time Čistý čas - + Metric Metrické - + Imperial Imperiální - + Fullscreen mode Celoobrazovkový režim - + Options... Nastavení... - + Next Následující - + Previous Předchozí - + Last Poslední - + First První - + Map Mapa - + Graph Graf - + POI POI - + POI files POI soubory - + Data Data - + Display Zobrazit - + Settings Nastavení - + Units Jednotky - + Help Nápověda - + Append file Přidat soubor - + Next/Previous Následující/Předchozí - + Previous map Předchozí mapa - + Zoom in Přiblížit - + Zoom out Oddálit - + Digital zoom Digitální zoom - + Zoom Zoom - + Online maps Online mapy - + Online map URLs are read on program startup from the following file: URL online map jsou načteny při startu programu z následujícího souboru: - + Offline maps are loaded on program startup from the following directory: Offline mapy jsou načítány při startu aplikace z následujícího adresáře: - + Open map file Otevřít mapový soubor - + No files loaded Nejsou načteny žádné soubory - - GPX files (*.gpx) - Soubory GPX (*.gpx) - - - - TCX files (*.tcx) - Soubory TCX (*.tcx) - - - - KML files (*.kml) - Soubory KML (*.kml) - - - - CSV files (*.csv) - Soubory CSV (*.csv) - - - - All files (*) - Všechny soubory (*) - - - - + + Date Datum - + Routes Trasy - - Map files (*.map *.tba *.tar) - Mapové soubory (*.map *.tba *.tar) - - - + Error loading map: Mapu nelze načíst: - + %n files %n soubor @@ -558,127 +561,122 @@ - + Next file Následující soubor - + Version Verze - + Print... Tisknout... - + Export to PDF... Exportovat do PDF... - + Waypoints Navigační body - + Previous file Předchozí soubor - - Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) - Podporované soubory (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) - - - + Route waypoints Body tras - + First file První soubor - + Last file Poslední soubor - + The file format is one map entry per line, consisting of the map name and tiles URL delimited by a TAB character. The tile X and Y coordinates are replaced with $x and $y in the URL and the zoom level is replaced with $z. An example map file could look like: Formát souboru je jeden mapový záznam na řádku, kde mapový záznam sestává ze jména mapy a URL dlaždic navzájem oddělených tabulátorem. Souřadnice dlaždice jsou v URL nahrazeny řetězci $x a $y, úroven přiblížení (zoom) pak řetězcem $z. Příklad: - + Offline maps Offline mapy - + The expected structure is one map/atlas in a separate subdirectory. Supported map formats are OziExplorer maps and TrekBuddy maps/atlases (tared and non-tared). Očekávaná struktura je jedna mapa/atlas v samostatném podadresáři. Podporované mapové formáty jsou OziExplorer mapy a TrekBuddy mapy/atlasy (včetně tar varianty). - + To make GPXSee load a POI file automatically on startup, add the file to the following directory: POI soubory, které se mají automaticky nahrát při startu programu jsou načítány z následujícího adresáře: - + Error loading data file: Datový soubor nelze načíst: - - + + Line: %1 Řádka: %1 - + Error loading POI file: Soubor POI nelze načíst: - + Name Název - + Tracks Cesty - - + + About GPXSee O aplikaci GPXSee - + Navigation Navigace - + POIs POI body - - + + Distance Vzdálenost - - - + + + Time Čas @@ -756,6 +754,19 @@ Maximum + + MapList + + + Map files (*.map *.tba *.tar) + Mapové soubory (*.map *.tba *.tar) + + + + URL list files (*.txt) + Seznamy URL (*.txt) + + OptionsDialog diff --git a/lang/gpxsee_de.ts b/lang/gpxsee_de.ts index 2fc5af3a..93c81a8e 100644 --- a/lang/gpxsee_de.ts +++ b/lang/gpxsee_de.ts @@ -25,6 +25,54 @@ Maximum + + Data + + + Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) + Unterstütze Dateien (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) + + + + CSV files (*.csv) + CSV-Dateien (*.csv) + + + + FIT files (*.fit) + FIT-Dateien (*.fit) + + + + GPX files (*.gpx) + GPX-Dateien (*.gpx) + + + + IGC files (*.igc) + IGC-Dateien (*.igc) + + + + KML files (*.kml) + KML-Dateien (*.kml) + + + + NMEA files (*.nmea) + NMEA-Dateien (*.nmea) + + + + TCX files (*.tcx) + TCX-Dateien (*.tcx) + + + + All files (*) + Alle Dateien (*) + + ElevationGraph @@ -190,335 +238,315 @@ GUI - + GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at GPXSee wird unter der GNU General Public License version 3 vertrieben. Mehr Informationen zu GPXSee auf der Homepage - + Open file Datei öffnen - + Open POI file POI Datei öffnen - + Quit Beenden - - - + + + Keyboard controls Tastaturkürzel - + Close Schließen - + Reload Neu Laden - + Show Ansicht - - + + File Datei - - FIT files (*.fit) - FIT-Dateien (*.fit) - - - - IGC files (*.igc) - IGC-Dateien (*.igc) - - - - NMEA files (*.nmea) - NMEA-Dateien (*.nmea) - - - - - + + + Data sources Datenquellen - + Close POI files POI-Datei schließen - + Overlap POIs POI überlappen - + Show POI labels POI-Labels anzeigen - + Show POIs POIs anzeigen - + Show map Karte anzeigen - + Clear tile cache Tile-Cache bereinigen - + Open... Öffnen... - + Load POI file... POI-Datei laden... - + Load map... Karte laden... - - - + + + Next map Nächste Karte - + Show tracks Strecken anzeigen - + Show routes Routen anzeigen - + Show waypoints Wegpunkte anzeigen - + Waypoint labels Wegpunkt Labels - + Show graphs Graphen anzeigen - + Show grid Gitter anzeigen - + Show toolbars Toolbars anzeigen - + Total time Gesamtzeit - - + + Moving time Bewegungszeit - + Metric Metrisch - + Imperial Imperial - + Fullscreen mode Vollbildmodus - + Options... Einstellungen... - + Next Nächste - + Previous Vorherige - + Last Letzte - + First Erste - + Map Karte - + Graph Graph - + POI POI - + POI files POI-Dateien - + Data Daten - + Display Anzeige - + Settings Einstellungen - + Units Einheiten - + Help Hilfe - + Append file An Datei anhängen - + Next/Previous Nächste/Vorherige - + Previous map Vorherige Karte - + Zoom in Hineinzoomen - + Zoom out Herauszoomen - + Digital zoom Digitaler Zoom - + Zoom Zoom - + Online maps Onlinekarten - + Online map URLs are read on program startup from the following file: Onlinekarten URLs werden zu Programmstart aus der folgenden Datei gelesen: - + Offline maps Offlinekarten - + Offline maps are loaded on program startup from the following directory: Offlinekarten werden zu Programmstart aus dem folgenden Verzeichnis geladen: - + Open map file Karte Datei öffnen - - Map files (*.map *.tba *.tar) - Karten-Dateien (*.map *.tba *.tar) - - - + Error loading map: Fehler beim Laden der Karte-Datei: - + No files loaded Keine Dateien geladen - + %n files %n Datei @@ -526,158 +554,128 @@ - - GPX files (*.gpx) - GPX-Dateien (*.gpx) - - - - TCX files (*.tcx) - TCX-Dateien (*.tcx) - - - - KML files (*.kml) - KML-Dateien (*.kml) - - - - CSV files (*.csv) - CSV-Dateien (*.csv) - - - - All files (*) - Alle Dateien (*) - - - - + + Date Datum - + Routes Routen - + Next file Nächste Datei - + Version Version - + Print... Drucken... - + Export to PDF... Als PDF exportieren... - + Waypoints Wegpunkte - + Previous file Vorherige Datei - - Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) - Unterstütze Dateien (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) - - - + Route waypoints Routen Wegpunkte - + First file Erste Datei - + Last file Letzte Datei - + The file format is one map entry per line, consisting of the map name and tiles URL delimited by a TAB character. The tile X and Y coordinates are replaced with $x and $y in the URL and the zoom level is replaced with $z. An example map file could look like: Das Dateiformat ist eine Karte pro Linie. Jede Linie besteht aus dem Kartenname und die durch ein TAB Zeichen getrennte Tiles URL. X und Y Koordinate einer Tile werden in der URL durch $x und $y ersetzt und das Zoomlevel durch $z. Ein Beispiel einer Kartendatei könnte so aussehen: - + The expected structure is one map/atlas in a separate subdirectory. Supported map formats are OziExplorer maps and TrekBuddy maps/atlases (tared and non-tared). Die erwartete Struktur ist eine Karte/ein Atlas pro Unterverzeichnis. Unterstützte Kartenformate sind OziExplorer Karten und TrekBuddy Karten/Atlanten (mit oder ohne tar Kompression). - + To make GPXSee load a POI file automatically on startup, add the file to the following directory: Damit GPXSee zu Programmstart automatisch eine POI-Datei lädt, fügen Sie diese zu folgendem Verzeichnis hinzu: - + Error loading data file: Fehler beim Laden der Datei: - - + + Line: %1 Linie: %1 - + Error loading POI file: Fehler beim Laden der POI-Datei: - + Name Name - + Tracks Strecken - - + + About GPXSee Über GPXSee - + Navigation Navigation - + POIs POIs - - + + Distance Distanz - - - + + + Time Zeit @@ -755,6 +753,19 @@ Maximum + + MapList + + + Map files (*.map *.tba *.tar) + Karten-Dateien (*.map *.tba *.tar) + + + + URL list files (*.txt) + + + OptionsDialog diff --git a/lang/gpxsee_sv.ts b/lang/gpxsee_sv.ts index 060cf850..68123956 100644 --- a/lang/gpxsee_sv.ts +++ b/lang/gpxsee_sv.ts @@ -1,6 +1,6 @@ - + CadenceGraph @@ -25,6 +25,54 @@ Maximal + + Data + + + Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) + Filer som stöds (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) + + + + CSV files (*.csv) + CSV-filer (*.csv) + + + + FIT files (*.fit) + FIT-filer (*.fit) + + + + GPX files (*.gpx) + GPX-filer (*.gpx) + + + + IGC files (*.igc) + IGC-filer (*.igc) + + + + KML files (*.kml) + KML-filer (*.kml) + + + + NMEA files (*.nmea) + NMEA-filer (*.nmea) + + + + TCX files (*.tcx) + TCX-filer (*.tcx) + + + + All files (*) + Alla filer (*) + + ElevationGraph @@ -190,335 +238,315 @@ GUI - + GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at GPXSee distribueras under vilkoren för GNU General Public License version 3. För mer info om GPXSee, besök hemsidan på - + Open file Öppna fil - + Open POI file Öppna POI-fil - + Quit Avsluta - - - + + + Keyboard controls Snabbtangenter - + Close Stäng - + Reload Uppdatera - + Show Visa - - + + File Arkiv - - FIT files (*.fit) - FIT-filer (*.fit) - - - - IGC files (*.igc) - IGC-filer (*.igc) - - - - NMEA files (*.nmea) - NMEA-filer (*.nmea) - - - - - + + + Data sources Datakällor - + Close POI files Stäng POI-filer - + Overlap POIs Överlappa POI:er - + Show POI labels Visa POI-namn - + Show POIs Visa POI:er - + Show map Visa karta - + Clear tile cache Rensa kart-cache - + Open... Öppna... - + Load POI file... Läs in POI-fil... - + Load map... Läs in karta... - - - + + + Next map Nästa karta - + Show tracks Visa spår - + Show routes Visa rutter - + Show waypoints Visa vägpunkter - + Waypoint labels Vägpunktsnamn - + Show graphs Visa diagram - + Show grid Visa stödlinjer - + Show toolbars Visa verktygsfält - + Total time Total tid - - + + Moving time Förflyttningstid - + Metric Meter - + Imperial Imperial - + Fullscreen mode Helskärmsläge - + Options... Alternativ... - + Next Nästa - + Previous Föregående - + Last Sista - + First Första - + Map Karta - + Graph Diagram - + POI POI - + POI files POI-filer - + Data Data - + Display Visa - + Settings Inställningar - + Units Enhet - + Help Hjälp - + Append file Lägg till fil - + Next/Previous Nästa/Föregående - + Previous map Föregående karta - + Zoom in Zooma in - + Zoom out Zooma ut - + Digital zoom Digital zoom - + Zoom Zoom - + Online maps Online-kartor - + Online map URLs are read on program startup from the following file: Online-kartors URL:er, läses från följande fil vid programstart: - + Offline maps Offline-kartor - + Offline maps are loaded on program startup from the following directory: Offline-kartor läses in från följande mapp vid programstart: - + Open map file Öppna kartfil - - Map files (*.map *.tba *.tar) - Kartfiler (*.map *.tba *.tar) - - - + Error loading map: Fel vid inläsning av karta: - + No files loaded Inga filer inlästa - + %n files %n filer @@ -526,158 +554,128 @@ - - GPX files (*.gpx) - GPX-filer (*.gpx) - - - - TCX files (*.tcx) - TCX-filer (*.tcx) - - - - KML files (*.kml) - KML-filer (*.kml) - - - - CSV files (*.csv) - CSV-filer (*.csv) - - - - All files (*) - Alla filer (*) - - - - + + Date Datum - + Routes Rutter - + Next file Nästa fil - + Version Version - + Print... Skriv ut... - + Export to PDF... Exportera till PDF... - + Waypoints Vägpunkter - + Previous file Föregående fil - - Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) - Filer som stöds (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx) - - - + Route waypoints Ruttvägpunkter - + First file Första filen - + Last file Sista filen - + The file format is one map entry per line, consisting of the map name and tiles URL delimited by a TAB character. The tile X and Y coordinates are replaced with $x and $y in the URL and the zoom level is replaced with $z. An example map file could look like: Filformatet är en kartpost per rad, bestående av kartnamn och kartrutans URL, avgränsade med ett TAB-tecken. Kartrutans X- och Y-koordinater ersätts med $x och $y i URL:en och zoomnivån ersätts med $z. Exempel på en kartfil kan se ut så här: - + The expected structure is one map/atlas in a separate subdirectory. Supported map formats are OziExplorer maps and TrekBuddy maps/atlases (tared and non-tared). Den förväntade strukturen är en karta/atlas i en separat undermapp. Kartformat som stöds är OziExplorer kartor och TrekBuddy-kartor/-kartsamlingar (tarerade och icke tarerade). - + To make GPXSee load a POI file automatically on startup, add the file to the following directory: För att GPXSee skall läsa in en POI-fil automatiskt vid programstart, läggs filen i följande mapp: - + Error loading data file: Fel vid inläsning av datafil: - - + + Line: %1 Rad: %1 - + Error loading POI file: Fel vid inläsning av POI-fil: - + Name Namn - + Tracks Spår - - + + About GPXSee Om GPXSee - + Navigation Navigation - + POIs POI:er - - + + Distance Avstånd - - - + + + Time Tid @@ -755,6 +753,19 @@ Max + + MapList + + + Map files (*.map *.tba *.tar) + Kartfiler (*.map *.tba *.tar) + + + + URL list files (*.txt) + + + OptionsDialog diff --git a/src/csvparser.cpp b/src/csvparser.cpp index 9987646d..f4298bbc 100644 --- a/src/csvparser.cpp +++ b/src/csvparser.cpp @@ -1,7 +1,10 @@ #include "csvparser.h" -bool CSVParser::loadFile(QFile *file) +bool CSVParser::parse(QFile *file, QList &track, + QList &routes, QList &waypoints) { + Q_UNUSED(track); + Q_UNUSED(routes); bool res; _errorLine = 1; @@ -36,7 +39,7 @@ bool CSVParser::loadFile(QFile *file) wp.setDescription(QString::fromUtf8(ba.data(), ba.size())); } - _waypoints.append(wp); + waypoints.append(wp); _errorLine++; } diff --git a/src/csvparser.h b/src/csvparser.h index 36b5c47a..9c840ae2 100644 --- a/src/csvparser.h +++ b/src/csvparser.h @@ -6,12 +6,11 @@ class CSVParser : public Parser { public: - CSVParser(QList &tracks, QList &routes, - QList &waypoints) : Parser(tracks, routes, waypoints) - {_errorLine = 0;} + CSVParser() : _errorLine(0) {} ~CSVParser() {} - bool loadFile(QFile *file); + bool parse(QFile *file, QList &track, QList &routes, + QList &waypoints); QString errorString() const {return _errorString;} int errorLine() const {return _errorLine;} diff --git a/src/data.cpp b/src/data.cpp index 469dda45..ae43e942 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -11,38 +11,32 @@ #include "data.h" -Data::Data() : _errorLine(0) +static QHash parsers() { - _parsers.insert("gpx", new GPXParser(_trackData, _routeData, - _waypointData)); - _parsers.insert("tcx", new TCXParser(_trackData, _routeData, - _waypointData)); - _parsers.insert("kml", new KMLParser(_trackData, _routeData, - _waypointData)); - _parsers.insert("fit", new FITParser(_trackData, _routeData, - _waypointData)); - _parsers.insert("csv", new CSVParser(_trackData, _routeData, - _waypointData)); - _parsers.insert("igc", new IGCParser(_trackData, _routeData, - _waypointData)); - _parsers.insert("nmea", new NMEAParser(_trackData, _routeData, - _waypointData)); + QHash hash; + + hash.insert("gpx", new GPXParser()); + hash.insert("tcx", new TCXParser()); + hash.insert("kml", new KMLParser()); + hash.insert("fit", new FITParser()); + hash.insert("csv", new CSVParser()); + hash.insert("igc", new IGCParser()); + hash.insert("nmea", new NMEAParser()); + + return hash; } +QHash Data::_parsers = parsers(); + Data::~Data() { - QHash::iterator it; - - for (it = _parsers.begin(); it != _parsers.end(); it++) - delete it.value(); - for (int i = 0; i < _tracks.count(); i++) delete _tracks.at(i); for (int i = 0; i < _routes.count(); i++) delete _routes.at(i); } -void Data::createData() +void Data::processData() { for (int i = 0; i < _trackData.count(); i++) _tracks.append(new Track(_trackData.at(i))); @@ -66,8 +60,8 @@ bool Data::loadFile(const QString &fileName) QHash::iterator it; if ((it = _parsers.find(fi.suffix().toLower())) != _parsers.end()) { - if (it.value()->loadFile(&file)) { - createData(); + if (it.value()->parse(&file, _trackData, _routeData, _waypoints)) { + processData(); return true; } @@ -75,8 +69,8 @@ bool Data::loadFile(const QString &fileName) _errorString = it.value()->errorString(); } else { for (it = _parsers.begin(); it != _parsers.end(); it++) { - if (it.value()->loadFile(&file)) { - createData(); + if (it.value()->parse(&file, _trackData, _routeData, _waypoints)) { + processData(); return true; } file.reset(); @@ -93,3 +87,23 @@ bool Data::loadFile(const QString &fileName) return false; } + +QString Data::formats() +{ + return tr("Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx)") + + ";;" + tr("CSV files (*.csv)") + ";;" + tr("FIT files (*.fit)") + ";;" + + tr("GPX files (*.gpx)") + ";;" + tr("IGC files (*.igc)") + ";;" + + tr("KML files (*.kml)") + ";;" + tr("NMEA files (*.nmea)") + ";;" + + tr("TCX files (*.tcx)") + ";;" + tr("All files (*)"); +} + +QStringList Data::filter() +{ + QStringList filter; + QHash::iterator it; + + for (it = _parsers.begin(); it != _parsers.end(); it++) + filter << QString("*.%1").arg(it.key()); + + return filter; +} diff --git a/src/data.h b/src/data.h index ecf7abbc..080ab0e9 100644 --- a/src/data.h +++ b/src/data.h @@ -6,16 +6,19 @@ #include #include #include +#include #include "waypoint.h" #include "track.h" #include "route.h" #include "parser.h" -class Data +class Data : public QObject { + Q_OBJECT + public: - Data(); + Data(QObject *parent = 0) : QObject(parent), _errorLine(0) {} ~Data(); bool loadFile(const QString &fileName); @@ -24,21 +27,25 @@ public: const QList &tracks() const {return _tracks;} const QList &routes() const {return _routes;} - const QList &waypoints() const {return _waypointData;} + const QList &waypoints() const {return _waypoints;} + + static QString formats(); + static QStringList filter(); private: - void createData(); + void processData(); QString _errorString; int _errorLine; - QHash _parsers; QList _tracks; QList _routes; + QList _waypoints; QList _trackData; QList _routeData; - QList _waypointData; + + static QHash _parsers; }; #endif // DATA_H diff --git a/src/fitparser.cpp b/src/fitparser.cpp index 439aad6c..69c397a0 100644 --- a/src/fitparser.cpp +++ b/src/fitparser.cpp @@ -10,8 +10,7 @@ const quint32 FIT_MAGIC = 0x5449462E; // .FIT #define TIMESTAMP_FIELD 253 -FITParser::FITParser(QList &tracks, QList &routes, - QList &waypoints) : Parser(tracks, routes, waypoints) +FITParser::FITParser() { memset(_defs, 0, sizeof(_defs)); @@ -191,7 +190,8 @@ bool FITParser::readField(Field *f, quint32 &val) return ret; } -bool FITParser::parseData(MessageDefinition *def, quint8 offset) +bool FITParser::parseData(TrackData &track, MessageDefinition *def, + quint8 offset) { Field *field; quint32 timestamp = _timestamp + offset; @@ -268,7 +268,7 @@ bool FITParser::parseData(MessageDefinition *def, quint8 offset) if (trackpoint.coordinates().isValid()) { trackpoint.setTimestamp(QDateTime::fromTime_t(timestamp + 631065600)); - _tracks.last().append(trackpoint); + track.append(trackpoint); } else { if (trackpoint.coordinates().isNull()) warning("Missing coordinates"); @@ -282,21 +282,21 @@ bool FITParser::parseData(MessageDefinition *def, quint8 offset) return true; } -bool FITParser::parseDataMessage(quint8 header) +bool FITParser::parseDataMessage(TrackData &track, quint8 header) { int local_id = header & 0xf; MessageDefinition* def = &_defs[local_id]; - return parseData(def, 0); + return parseData(track, def, 0); } -bool FITParser::parseCompressedMessage(quint8 header) +bool FITParser::parseCompressedMessage(TrackData &track, quint8 header) { int local_id = (header >> 5) & 3; MessageDefinition* def = &_defs[local_id]; - return parseData(def, header & 0x1f); + return parseData(track, def, header & 0x1f); } -bool FITParser::parseRecord() +bool FITParser::parseRecord(TrackData &track) { quint8 header; @@ -304,11 +304,11 @@ bool FITParser::parseRecord() return false; if (header & 0x80) - return parseCompressedMessage(header); + return parseCompressedMessage(track, header); else if (header & 0x40) return parseDefinitionMessage(header); else - return parseDataMessage(header); + return parseDataMessage(track, header); } bool FITParser::parseHeader() @@ -337,8 +337,11 @@ bool FITParser::parseHeader() return true; } -bool FITParser::loadFile(QFile *file) +bool FITParser::parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints) { + Q_UNUSED(routes); + Q_UNUSED(waypoints); bool ret = true; _device = file; @@ -348,10 +351,11 @@ bool FITParser::loadFile(QFile *file) if (!parseHeader()) return false; - _tracks.append(TrackData()); + tracks.append(TrackData()); + TrackData &track = tracks.last(); while (_len) - if ((ret = parseRecord()) == false) + if ((ret = parseRecord(track)) == false) break; clearDefinitions(); diff --git a/src/fitparser.h b/src/fitparser.h index 8da65c63..67a8fa5d 100644 --- a/src/fitparser.h +++ b/src/fitparser.h @@ -6,11 +6,11 @@ class FITParser : public Parser { public: - FITParser(QList &tracks, QList &routes, - QList &waypoints); + FITParser(); ~FITParser() {} - bool loadFile(QFile *file); + bool parse(QFile *file, QList &tracks, QList &routes, + QList &waypoints); QString errorString() const {return _errorString;} int errorLine() const {return 0;} @@ -47,11 +47,11 @@ private: bool skipValue(size_t size); bool parseHeader(); - bool parseRecord(); + bool parseRecord(TrackData &track); bool parseDefinitionMessage(quint8 header); - bool parseCompressedMessage(quint8 header); - bool parseDataMessage(quint8 header); - bool parseData(MessageDefinition *def, quint8 offset); + bool parseCompressedMessage(TrackData &track, quint8 header); + bool parseDataMessage(TrackData &track, quint8 header); + bool parseData(TrackData &track, MessageDefinition *def, quint8 offset); bool readField(Field *f, quint32 &val); QIODevice *_device; diff --git a/src/gpxparser.cpp b/src/gpxparser.cpp index 7649de96..4929a30f 100644 --- a/src/gpxparser.cpp +++ b/src/gpxparser.cpp @@ -167,39 +167,36 @@ void GPXParser::track(TrackData &track) } } -void GPXParser::gpx() +void GPXParser::gpx(QList &tracks, QList &routes, + QList &waypoints) { while (_reader.readNextStartElement()) { if (_reader.name() == "trk") { - _tracks.append(TrackData()); - track(_tracks.back()); + tracks.append(TrackData()); + track(tracks.back()); } else if (_reader.name() == "rte") { - _routes.append(RouteData()); - routepoints(_routes.back()); + routes.append(RouteData()); + routepoints(routes.back()); } else if (_reader.name() == "wpt") { - _waypoints.append(Waypoint(coordinates())); - waypointData(_waypoints.last()); + waypoints.append(Waypoint(coordinates())); + waypointData(waypoints.last()); } else _reader.skipCurrentElement(); } } -bool GPXParser::parse() +bool GPXParser::parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints) { + _reader.clear(); + _reader.setDevice(file); + if (_reader.readNextStartElement()) { if (_reader.name() == "gpx") - gpx(); + gpx(tracks, routes, waypoints); else _reader.raiseError("Not a GPX file"); } return !_reader.error(); } - -bool GPXParser::loadFile(QFile *file) -{ - _reader.clear(); - _reader.setDevice(file); - - return parse(); -} diff --git a/src/gpxparser.h b/src/gpxparser.h index 250bbdfa..883a2aa6 100644 --- a/src/gpxparser.h +++ b/src/gpxparser.h @@ -8,17 +8,16 @@ class GPXParser : public Parser { public: - GPXParser(QList &tracks, QList &routes, - QList &waypoints) : Parser(tracks, routes, waypoints) {} ~GPXParser() {} - bool loadFile(QFile *file); + bool parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints); QString errorString() const {return _reader.errorString();} int errorLine() const {return _reader.lineNumber();} private: - bool parse(); - void gpx(); + void gpx(QList &tracks, QList &routes, + QList &waypoints); void track(TrackData &track); void trackpoints(TrackData &track); void routepoints(RouteData &route); diff --git a/src/gui.cpp b/src/gui.cpp index a6b4a878..d206de60 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -102,24 +102,6 @@ GUI::~GUI() } } -const QString GUI::fileFormats() const -{ - return tr("Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx)") - + ";;" + tr("CSV files (*.csv)") + ";;" + tr("FIT files (*.fit)") + ";;" - + tr("GPX files (*.gpx)") + ";;" + tr("IGC files (*.igc)") + ";;" - + tr("KML files (*.kml)") + ";;" + tr("NMEA files (*.nmea)") + ";;" - + tr("TCX files (*.tcx)") + ";;" + tr("All files (*)"); -} - -void GUI::createBrowser() -{ - QStringList filter; - filter << "*.gpx" << "*.tcx" << "*.kml" << "*.fit" << "*.csv" << "*.igc" - << "*.nmea"; - _browser = new FileBrowser(this); - _browser->setFilter(filter); -} - void GUI::loadDatums() { QString ef, df; @@ -175,7 +157,7 @@ void GUI::loadMaps() else if (QFile::exists(GLOBAL_MAP_FILE)) online = GLOBAL_MAP_FILE; - if (!online.isNull() && !_ml->loadList(online)) + if (!online.isNull() && !_ml->loadFile(online)) qWarning("%s: %s", qPrintable(online), qPrintable(_ml->errorString())); @@ -187,12 +169,10 @@ void GUI::loadMaps() if (!offline.isNull()) { QDir md(offline); QFileInfoList ml = md.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - QStringList filters; - filters << "*.map" << "*.tba" << "*.tar"; for (int i = 0; i < ml.size(); i++) { QDir dir(ml.at(i).absoluteFilePath()); - QFileInfoList fl = dir.entryInfoList(filters, QDir::Files); + QFileInfoList fl = dir.entryInfoList(MapList::filter(), QDir::Files); if (fl.isEmpty()) qWarning("%s: no map/atlas file found", @@ -201,7 +181,7 @@ void GUI::loadMaps() qWarning("%s: ambiguous directory content", qPrintable(ml.at(i).absoluteFilePath())); else - if (!_ml->loadMap(fl.first().absoluteFilePath())) + if (!_ml->loadFile(fl.first().absoluteFilePath())) qWarning("%s: %s", qPrintable(fl.first().absoluteFilePath()), qPrintable(_ml->errorString())); } @@ -234,6 +214,12 @@ void GUI::loadPOIs() } } +void GUI::createBrowser() +{ + _browser = new FileBrowser(this); + _browser->setFilter(Data::filter()); +} + void GUI::createMapActions() { _mapsSignalMapper = new QSignalMapper(this); @@ -736,7 +722,7 @@ void GUI::dataSources() void GUI::openFile() { QStringList files = QFileDialog::getOpenFileNames(this, tr("Open file"), - QString(), fileFormats()); + QString(), Data::formats()); QStringList list = files; for (QStringList::Iterator it = list.begin(); it != list.end(); it++) @@ -826,7 +812,7 @@ bool GUI::loadFile(const QString &fileName) void GUI::openPOIFile() { QStringList files = QFileDialog::getOpenFileNames(this, tr("Open POI file"), - QString(), fileFormats()); + QString(), Data::formats()); QStringList list = files; for (QStringList::Iterator it = list.begin(); it != list.end(); it++) @@ -1209,22 +1195,25 @@ void GUI::showGraphGrids(bool show) void GUI::loadMap() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open map file"), - QString(), tr("Map files (*.map *.tba *.tar)")); + QString(), MapList::formats()); if (fileName.isEmpty()) return; - if (_ml->loadMap(fileName)) { - QAction *a = new QAction(_ml->maps().last()->name(), this); - a->setCheckable(true); - a->setActionGroup(_mapsActionGroup); - _mapsSignalMapper->setMapping(a, _ml->maps().size() - 1); - connect(a, SIGNAL(triggered()), _mapsSignalMapper, SLOT(map())); - _mapActions.append(a); - _mapMenu->insertAction(_mapsEnd, a); + int count = _ml->maps().count(); + if (_ml->loadFile(fileName)) { + for (int i = count; i < _ml->maps().count(); i++) { + QAction *a = new QAction(_ml->maps().at(i)->name(), this); + a->setCheckable(true); + a->setActionGroup(_mapsActionGroup); + _mapsSignalMapper->setMapping(a, i); + connect(a, SIGNAL(triggered()), _mapsSignalMapper, SLOT(map())); + _mapActions.append(a); + _mapMenu->insertAction(_mapsEnd, a); + } _showMapAction->setEnabled(true); _clearMapCacheAction->setEnabled(true); - a->activate(QAction::Trigger); + _mapActions.last()->activate(QAction::Trigger); } else { QString error = tr("Error loading map:") + "\n\n" + fileName + "\n\n" + _ml->errorString(); diff --git a/src/gui.h b/src/gui.h index 0b513ff5..d1e60e0d 100644 --- a/src/gui.h +++ b/src/gui.h @@ -121,8 +121,6 @@ private: void readSettings(); void writeSettings(); - const QString fileFormats() const; - void keyPressEvent(QKeyEvent *event); void closeEvent(QCloseEvent *event); void dragEnterEvent(QDragEnterEvent *event); diff --git a/src/igcparser.cpp b/src/igcparser.cpp index d93a73a3..30f1ce95 100644 --- a/src/igcparser.cpp +++ b/src/igcparser.cpp @@ -120,7 +120,7 @@ bool IGCParser::readHRecord(const char *line, int len) return true; } -bool IGCParser::readBRecord(const char *line, int len) +bool IGCParser::readBRecord(TrackData &track, const char *line, int len) { qreal lat, lon, ele; QTime time; @@ -156,12 +156,12 @@ bool IGCParser::readBRecord(const char *line, int len) Trackpoint t(Coordinates(lon, lat)); t.setTimestamp(QDateTime(_date, _time, Qt::UTC)); t.setElevation(ele); - _tracks.last().append(t); + track.append(t); return true; } -bool IGCParser::readCRecord(const char *line, int len) +bool IGCParser::readCRecord(RouteData &route, const char *line, int len) { qreal lat, lon; @@ -183,14 +183,16 @@ bool IGCParser::readCRecord(const char *line, int len) Waypoint w(Coordinates(lon, lat)); w.setName(QString(ba.trimmed())); - _routes.last().append(w); + route.append(w); } return true; } -bool IGCParser::loadFile(QFile *file) +bool IGCParser::parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints) { + Q_UNUSED(waypoints); qint64 len; char line[76 + 2 + 1 + 1]; bool route = false, track = false; @@ -221,11 +223,11 @@ bool IGCParser::loadFile(QFile *file) return false; } else if (line[0] == 'C') { if (route) { - if (!readCRecord(line, len)) + if (!readCRecord(routes.last() ,line, len)) return false; } else { route = true; - _routes.append(RouteData()); + routes.append(RouteData()); } } else if (line[0] == 'B') { if (_date.isNull()) { @@ -233,11 +235,11 @@ bool IGCParser::loadFile(QFile *file) return false; } if (!track) { - _tracks.append(TrackData()); + tracks.append(TrackData()); _time = QTime(0, 0); track = true; } - if (!readBRecord(line, len)) + if (!readBRecord(tracks.last(), line, len)) return false; } } diff --git a/src/igcparser.h b/src/igcparser.h index a9be1abf..2bc1c311 100644 --- a/src/igcparser.h +++ b/src/igcparser.h @@ -9,19 +9,18 @@ class IGCParser : public Parser { public: - IGCParser(QList &tracks, QList &routes, - QList &waypoints) : Parser(tracks, routes, waypoints) - {_errorLine = 0;} + IGCParser() : _errorLine(0) {} ~IGCParser() {} - bool loadFile(QFile *file); + bool parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints); QString errorString() const {return _errorString;} int errorLine() const {return _errorLine;} private: bool readHRecord(const char *line, int len); - bool readBRecord(const char *line, int len); - bool readCRecord(const char *line, int len); + bool readBRecord(TrackData &track, const char *line, int len); + bool readCRecord(RouteData &route, const char *line, int len); int _errorLine; QString _errorString; diff --git a/src/kmlparser.cpp b/src/kmlparser.cpp index d4858b8b..b31c872d 100644 --- a/src/kmlparser.cpp +++ b/src/kmlparser.cpp @@ -251,20 +251,21 @@ void KMLParser::track(TrackData &track) _reader.raiseError(mismatchError); } -void KMLParser::multiGeometry(const QString &name, const QString &desc, +void KMLParser::multiGeometry(QList &tracks, + QList &waypoints, const QString &name, const QString &desc, const QDateTime timestamp) { while (_reader.readNextStartElement()) { if (_reader.name() == "Point") { - _waypoints.append(Waypoint()); - Waypoint &w = _waypoints.last(); + waypoints.append(Waypoint()); + Waypoint &w = waypoints.last(); w.setName(name); w.setDescription(desc); w.setTimestamp(timestamp); point(w); } else if (_reader.name() == "LineString") { - _tracks.append(TrackData()); - TrackData &t = _tracks.last(); + tracks.append(TrackData()); + TrackData &t = tracks.last(); t.setName(name); t.setDescription(desc); lineString(t); @@ -273,7 +274,7 @@ void KMLParser::multiGeometry(const QString &name, const QString &desc, } } -void KMLParser::placemark() +void KMLParser::placemark(QList &tracks, QList &waypoints) { QString name, desc; QDateTime timestamp; @@ -286,23 +287,23 @@ void KMLParser::placemark() else if (_reader.name() == "TimeStamp") timestamp = timeStamp(); else if (_reader.name() == "MultiGeometry") - multiGeometry(name, desc, timestamp); + multiGeometry(tracks, waypoints, name, desc, timestamp); else if (_reader.name() == "Point") { - _waypoints.append(Waypoint()); - Waypoint &w = _waypoints.last(); + waypoints.append(Waypoint()); + Waypoint &w = waypoints.last(); w.setName(name); w.setDescription(desc); w.setTimestamp(timestamp); point(w); } else if (_reader.name() == "LineString") { - _tracks.append(TrackData()); - TrackData &t = _tracks.last(); + tracks.append(TrackData()); + TrackData &t = tracks.last(); t.setName(name); t.setDescription(desc); lineString(t); } else if (_reader.name() == "Track") { - _tracks.append(TrackData()); - TrackData &t = _tracks.last(); + tracks.append(TrackData()); + TrackData &t = tracks.last(); t.setName(name); t.setDescription(desc); track(t); @@ -311,58 +312,56 @@ void KMLParser::placemark() } } -void KMLParser::folder() +void KMLParser::folder(QList &tracks, QList &waypoints) { while (_reader.readNextStartElement()) { if (_reader.name() == "Placemark") - placemark(); + placemark(tracks, waypoints); else if (_reader.name() == "Folder") - folder(); + folder(tracks, waypoints); else _reader.skipCurrentElement(); } } -void KMLParser::document() +void KMLParser::document(QList &tracks, QList &waypoints) { while (_reader.readNextStartElement()) { if (_reader.name() == "Placemark") - placemark(); + placemark(tracks, waypoints); else if (_reader.name() == "Folder") - folder(); + folder(tracks, waypoints); else _reader.skipCurrentElement(); } } -void KMLParser::kml() +void KMLParser::kml(QList &tracks, QList &waypoints) { while (_reader.readNextStartElement()) { if (_reader.name() == "Document") - document(); + document(tracks, waypoints); else if (_reader.name() == "Placemark") - placemark(); + placemark(tracks, waypoints); else _reader.skipCurrentElement(); } } -bool KMLParser::parse() +bool KMLParser::parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints) { + Q_UNUSED(routes); + + _reader.clear(); + _reader.setDevice(file); + if (_reader.readNextStartElement()) { if (_reader.name() == "kml") - kml(); + kml(tracks, waypoints); else _reader.raiseError("Not a KML file"); } return !_reader.error(); } - -bool KMLParser::loadFile(QFile *file) -{ - _reader.clear(); - _reader.setDevice(file); - - return parse(); -} diff --git a/src/kmlparser.h b/src/kmlparser.h index 2e872ebf..54aa4062 100644 --- a/src/kmlparser.h +++ b/src/kmlparser.h @@ -8,22 +8,20 @@ class KMLParser : public Parser { public: - KMLParser(QList &tracks, QList &routes, - QList &waypoints) : Parser(tracks, routes, waypoints) {} ~KMLParser() {} - bool loadFile(QFile *file); + bool parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints); QString errorString() const {return _reader.errorString();} int errorLine() const {return _reader.lineNumber();} private: - bool parse(); - void kml(); - void document(); - void folder(); - void placemark(); - void multiGeometry(const QString &name, const QString &desc, - const QDateTime timestamp); + void kml(QList &tracks, QList &waypoints); + void document(QList &tracks, QList &waypoints); + void folder(QList &tracks, QList &waypoints); + void placemark(QList &tracks, QList &waypoints); + void multiGeometry(QList &tracks, QList &waypoints, + const QString &name, const QString &desc, const QDateTime timestamp); void track(TrackData &track); void lineString(TrackData &track); void point(Waypoint &waypoint); diff --git a/src/maplist.cpp b/src/maplist.cpp index 6d305a9f..a81090da 100644 --- a/src/maplist.cpp +++ b/src/maplist.cpp @@ -6,26 +6,25 @@ #include "maplist.h" -bool MapList::loadListEntry(const QByteArray &line) +Map *MapList::loadListEntry(const QByteArray &line) { QList list = line.split('\t'); if (list.size() != 2) - return false; + return 0; QByteArray ba1 = list[0].trimmed(); QByteArray ba2 = list[1].trimmed(); if (ba1.isEmpty() || ba2.isEmpty()) - return false; + return 0; - _maps.append(new OnlineMap(QString::fromUtf8(ba1.data(), ba1.size()), - QString::fromLatin1(ba2.data(), ba2.size()), this)); - - return true; + return new OnlineMap(QString::fromUtf8(ba1.data(), ba1.size()), + QString::fromLatin1(ba2.data(), ba2.size()), this); } bool MapList::loadList(const QString &path) { QFile file(path); + QList maps; if (!file.open(QFile::ReadOnly | QFile::Text)) { _errorString = file.errorString(); @@ -36,65 +35,102 @@ bool MapList::loadList(const QString &path) while (!file.atEnd()) { ln++; QByteArray line = file.readLine(); + Map *map = loadListEntry(line); - if (!loadListEntry(line)) { + if (map) + maps.append(map); + else { + for (int i = 0; i < maps.count(); i++) + delete maps.at(i); _errorString = QString("Invalid map list entry on line %1.") .arg(QString::number(ln)); return false; } } + _maps += maps; + return true; } bool MapList::loadMap(const QString &path) +{ + OfflineMap *map = new OfflineMap(path, this); + if (map->isValid()) { + _maps.append(map); + return true; + } else { + _errorString = map->errorString(); + delete map; + return false; + } +} + +bool MapList::loadTba(const QString &path) +{ + Atlas *atlas = new Atlas(path, this); + if (atlas->isValid()) { + _maps.append(atlas); + return true; + } else { + _errorString = atlas->errorString(); + delete atlas; + return false; + } +} + +bool MapList::loadTar(const QString &path) +{ + Atlas *atlas = new Atlas(path, this); + if (atlas->isValid()) { + _maps.append(atlas); + return true; + } else { + _errorString = atlas->errorString(); + delete atlas; + OfflineMap *map = new OfflineMap(path, this); + if (map->isValid()) { + _maps.append(map); + return true; + } else { + qWarning("%s: %s", qPrintable(path), qPrintable(_errorString)); + qWarning("%s: %s", qPrintable(path), + qPrintable(map->errorString())); + _errorString = "Not a map/atlas file"; + delete map; + return false; + } + } +} + +bool MapList::loadFile(const QString &path) { QFileInfo fi(path); QString suffix = fi.suffix().toLower(); - if (suffix == "map") { - OfflineMap *om = new OfflineMap(path, this); - if (om->isValid()) { - _maps.append(om); - return true; - } else { - _errorString = om->errorString(); - delete om; - return false; - } - } else if (suffix == "tba") { - Atlas *atlas = new Atlas(path, this); - if (atlas->isValid()) { - _maps.append(atlas); - return true; - } else { - _errorString = atlas->errorString(); - delete atlas; - return false; - } - } else if (suffix == "tar") { - Atlas *atlas = new Atlas(path, this); - if (atlas->isValid()) { - _maps.append(atlas); - return true; - } else { - _errorString = atlas->errorString(); - delete atlas; - OfflineMap *om = new OfflineMap(path, this); - if (om->isValid()) { - _maps.append(om); - return true; - } else { - qWarning("%s: %s", qPrintable(path), qPrintable(_errorString)); - qWarning("%s: %s", qPrintable(path), - qPrintable(om->errorString())); - _errorString = "Not a map/atlas file"; - delete om; - return false; - } - } - } else { + if (suffix == "txt") + return loadList(path); + else if (suffix == "map") + return loadMap(path); + else if (suffix == "tba") + return loadTba(path); + else if (suffix == "tar") + return loadTar(path); + else { _errorString = "Not a map/atlas file"; return false; } } + +QString MapList::formats() +{ + return tr("Map files (*.map *.tba *.tar)") + ";;" + + tr("URL list files (*.txt)"); +} + +QStringList MapList::filter() +{ + QStringList filter; + filter << "*.map" << "*.tba" << "*.tar" << "*.txt"; + return filter; +} diff --git a/src/maplist.h b/src/maplist.h index 8960fdf2..6f9ae083 100644 --- a/src/maplist.h +++ b/src/maplist.h @@ -12,14 +12,21 @@ class MapList : public QObject public: MapList(QObject *parent = 0) : QObject(parent) {} - bool loadMap(const QString &path); - bool loadList(const QString &path); + bool loadFile(const QString &path); - QList &maps() {return _maps;} + const QList &maps() const {return _maps;} const QString &errorString() const {return _errorString;} + static QString formats(); + static QStringList filter(); + private: - bool loadListEntry(const QByteArray &line); + Map *loadListEntry(const QByteArray &line); + + bool loadList(const QString &path); + bool loadMap(const QString &path); + bool loadTba(const QString &path); + bool loadTar(const QString &path); QList _maps; QString _errorString; diff --git a/src/nmeaparser.cpp b/src/nmeaparser.cpp index 9b88bc56..0592eb46 100644 --- a/src/nmeaparser.cpp +++ b/src/nmeaparser.cpp @@ -227,7 +227,7 @@ bool NMEAParser::readEW(const char *data, int len, qreal &lon) return true; } -bool NMEAParser::readRMC(const char *line, int len) +bool NMEAParser::readRMC(TrackData &track, const char *line, int len) { int col = 1; const char *vp = line; @@ -280,22 +280,23 @@ bool NMEAParser::readRMC(const char *line, int len) } if (!date.isNull()) { - if (_date.isNull() && !_time.isNull() && !_tracks.last().isEmpty()) - _tracks.last().last().setTimestamp(QDateTime(date, _time, Qt::UTC)); + if (_date.isNull() && !_time.isNull() && !track.isEmpty()) + track.last().setTimestamp(QDateTime(date, _time, Qt::UTC)); _date = date; } - if (valid && !_GGA && !std::isnan(lat) && !std::isnan(lon)) { - Trackpoint t(Coordinates(lon, lat)); + Coordinates c(lon, lat); + if (valid && !_GGA && c.isValid()) { + Trackpoint t(c); if (!_date.isNull() && !time.isNull()) t.setTimestamp(QDateTime(_date, time, Qt::UTC)); - _tracks.last().append(t); + track.append(t); } return true; } -bool NMEAParser::readGGA(const char *line, int len) +bool NMEAParser::readGGA(TrackData &track, const char *line, int len) { int col = 1; const char *vp = line; @@ -356,13 +357,14 @@ bool NMEAParser::readGGA(const char *line, int len) return false; } - if (!std::isnan(lat) && !std::isnan(lon)) { - Trackpoint t(Coordinates(lon, lat)); + Coordinates c(lon, lat); + if (c.isValid()) { + Trackpoint t(c); if (!(_time.isNull() || _date.isNull())) t.setTimestamp(QDateTime(_date, _time, Qt::UTC)); if (!std::isnan(ele)) t.setElevation(ele - gh); - _tracks.last().append(t); + track.append(t); _GGA = true; } @@ -370,7 +372,7 @@ bool NMEAParser::readGGA(const char *line, int len) return true; } -bool NMEAParser::readWPL(const char *line, int len) +bool NMEAParser::readWPL(QList &waypoints, const char *line, int len) { int col = 1; const char *vp = line; @@ -411,10 +413,11 @@ bool NMEAParser::readWPL(const char *line, int len) return false; } - if (!std::isnan(lat) && !std::isnan(lon)) { - Waypoint w(Coordinates(lon, lat)); + Coordinates c(lon, lat); + if (c.isValid()) { + Waypoint w(c); w.setName(name); - _waypoints.append(w); + waypoints.append(w); } return true; @@ -474,8 +477,10 @@ bool NMEAParser::readZDA(const char *line, int len) return true; } -bool NMEAParser::loadFile(QFile *file) +bool NMEAParser::parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints) { + Q_UNUSED(routes); qint64 len; char line[80 + 2 + 1 + 1]; @@ -486,7 +491,8 @@ bool NMEAParser::loadFile(QFile *file) _time = QTime(); _GGA = false; - _tracks.append(TrackData()); + tracks.append(TrackData()); + TrackData &track = tracks.last(); while (!file->atEnd()) { len = file->readLine(line, sizeof(line)); @@ -501,13 +507,13 @@ bool NMEAParser::loadFile(QFile *file) if (validSentence(line, len)) { if (!memcmp(line + 3, "RMC,", 4)) { - if (!readRMC(line + 7, len)) + if (!readRMC(track, line + 7, len)) return false; } else if (!memcmp(line + 3, "GGA,", 4)) { - if (!readGGA(line + 7, len)) + if (!readGGA(track, line + 7, len)) return false; } else if (!memcmp(line + 3, "WPL,", 4)) { - if (!readWPL(line + 7, len)) + if (!readWPL(waypoints, line + 7, len)) return false; } else if (!memcmp(line + 3, "ZDA,", 4)) { if (!readZDA(line + 7, len)) @@ -518,7 +524,7 @@ bool NMEAParser::loadFile(QFile *file) _errorLine++; } - if (!_tracks.last().size() && !_waypoints.size()) { + if (!tracks.last().size() && !waypoints.size()) { _errorString = "No usable NMEA sentence found"; return false; } diff --git a/src/nmeaparser.h b/src/nmeaparser.h index 445c96d9..d931d521 100644 --- a/src/nmeaparser.h +++ b/src/nmeaparser.h @@ -8,12 +8,11 @@ class NMEAParser : public Parser { public: - NMEAParser(QList &tracks, QList &routes, - QList &waypoints) : Parser(tracks, routes, waypoints) - {_errorLine = 0; _GGA = false;} + NMEAParser() : _errorLine(0), _GGA(false) {} ~NMEAParser() {} - bool loadFile(QFile *file); + bool parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints); QString errorString() const {return _errorString;} int errorLine() const {return _errorLine;} @@ -27,9 +26,9 @@ private: bool readAltitude(const char *data, int len, qreal &ele); bool readGeoidHeight(const char *data, int len, qreal &gh); - bool readRMC(const char *line, int len); - bool readGGA(const char *line, int len); - bool readWPL(const char *line, int len); + bool readRMC(TrackData &track, const char *line, int len); + bool readGGA(TrackData &track, const char *line, int len); + bool readWPL(QList &waypoints, const char *line, int len); bool readZDA(const char *line, int len); int _errorLine; diff --git a/src/parser.h b/src/parser.h index dcb31850..6a0327f9 100644 --- a/src/parser.h +++ b/src/parser.h @@ -12,19 +12,12 @@ class Parser { public: - Parser(QList &tracks, QList &routes, - QList &waypoints) : _tracks(tracks), _routes(routes), - _waypoints(waypoints) {} virtual ~Parser() {} - virtual bool loadFile(QFile *file) = 0; + virtual bool parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints) = 0; virtual QString errorString() const = 0; virtual int errorLine() const = 0; - -protected: - QList &_tracks; - QList &_routes; - QList &_waypoints; }; #endif // PARSER_H diff --git a/src/pathview.cpp b/src/pathview.cpp index 3c99f08f..998de694 100644 --- a/src/pathview.cpp +++ b/src/pathview.cpp @@ -22,7 +22,7 @@ #define SCALE_OFFSET 7 PathView::PathView(Map *map, POI *poi, QWidget *parent) -: QGraphicsView(parent) + : QGraphicsView(parent) { Q_ASSERT(map != 0); Q_ASSERT(poi != 0); diff --git a/src/tcxparser.cpp b/src/tcxparser.cpp index 238c78b9..5a3c53c6 100644 --- a/src/tcxparser.cpp +++ b/src/tcxparser.cpp @@ -131,7 +131,7 @@ void TCXParser::lap(TrackData &track) } } -void TCXParser::course(TrackData &track) +void TCXParser::course(QList &waypoints, TrackData &track) { while (_reader.readNextStartElement()) { if (_reader.name() == "Track") @@ -144,7 +144,7 @@ void TCXParser::course(TrackData &track) Waypoint w; waypointData(w); if (w.coordinates().isValid()) - _waypoints.append(w); + waypoints.append(w); else warning("Missing Trackpoint coordinates"); } else @@ -162,56 +162,54 @@ void TCXParser::activity(TrackData &track) } } -void TCXParser::courses() +void TCXParser::courses(QList &tracks, QList &waypoints) { while (_reader.readNextStartElement()) { if (_reader.name() == "Course") { - _tracks.append(TrackData()); - course(_tracks.back()); + tracks.append(TrackData()); + course(waypoints, tracks.back()); } else _reader.skipCurrentElement(); } } -void TCXParser::activities() +void TCXParser::activities(QList &tracks) { while (_reader.readNextStartElement()) { if (_reader.name() == "Activity") { - _tracks.append(TrackData()); - activity(_tracks.back()); + tracks.append(TrackData()); + activity(tracks.back()); } else _reader.skipCurrentElement(); } } -void TCXParser::tcx() +void TCXParser::tcx(QList &tracks, QList &waypoints) { while (_reader.readNextStartElement()) { if (_reader.name() == "Courses") - courses(); + courses(tracks, waypoints); else if (_reader.name() == "Activities") - activities(); + activities(tracks); else _reader.skipCurrentElement(); } } -bool TCXParser::parse() +bool TCXParser::parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints) { + Q_UNUSED(routes); + + _reader.clear(); + _reader.setDevice(file); + if (_reader.readNextStartElement()) { if (_reader.name() == "TrainingCenterDatabase") - tcx(); + tcx(tracks, waypoints); else _reader.raiseError("Not a TCX file"); } return !_reader.error(); } - -bool TCXParser::loadFile(QFile *file) -{ - _reader.clear(); - _reader.setDevice(file); - - return parse(); -} diff --git a/src/tcxparser.h b/src/tcxparser.h index dc7346db..8a001d6e 100644 --- a/src/tcxparser.h +++ b/src/tcxparser.h @@ -8,20 +8,18 @@ class TCXParser : public Parser { public: - TCXParser(QList &tracks, QList &routes, - QList &waypoints) : Parser(tracks, routes, waypoints) {} ~TCXParser() {} - bool loadFile(QFile *file); + bool parse(QFile *file, QList &tracks, + QList &routes, QList &waypoints); QString errorString() const {return _reader.errorString();} int errorLine() const {return _reader.lineNumber();} private: - bool parse(); - void tcx(); - void courses(); - void activities(); - void course(TrackData &track); + void tcx(QList &tracks, QList &waypoints); + void courses(QList &tracks, QList &waypoints); + void activities(QList &tracks); + void course(QList &waypoints, TrackData &track); void activity(TrackData &track); void lap(TrackData &track); void trackpoints(TrackData &track);