From dac06b9537474eb1c41e277fa90501bc73403134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Mon, 25 Jul 2016 19:32:36 +0200 Subject: [PATCH] Added tooltip info to tracks/waypoints --- gpxsee.pro | 8 +- lang/gpxsee_cs.ts | 182 +++++++++++++++++++++++-------------------- src/axisitem.cpp | 2 +- src/gui.cpp | 30 +------ src/misc.cpp | 66 ++++++++++++++++ src/misc.h | 11 +++ src/nicenum.cpp | 34 -------- src/nicenum.h | 6 -- src/parser.cpp | 12 ++- src/parser.h | 2 +- src/poi.cpp | 9 ++- src/scaleitem.cpp | 2 +- src/trackview.cpp | 30 ++++++- src/trackview.h | 13 +++- src/waypoint.h | 13 +++- src/waypointitem.cpp | 15 ++-- 16 files changed, 257 insertions(+), 178 deletions(-) create mode 100644 src/misc.cpp create mode 100644 src/misc.h delete mode 100644 src/nicenum.cpp delete mode 100644 src/nicenum.h diff --git a/gpxsee.pro b/gpxsee.pro index 7f17cfbe..02046532 100644 --- a/gpxsee.pro +++ b/gpxsee.pro @@ -27,7 +27,6 @@ HEADERS += src/config.h \ src/downloader.h \ src/units.h \ src/scaleitem.h \ - src/nicenum.h \ src/waypoint.h \ src/trackview.h \ src/track.h \ @@ -45,7 +44,8 @@ HEADERS += src/config.h \ src/fileselectwidget.h \ src/margins.h \ src/temperaturegraph.h \ - src/graphtab.h + src/graphtab.h \ + src/misc.h SOURCES += src/main.cpp \ src/gui.cpp \ src/gpx.cpp \ @@ -64,7 +64,6 @@ SOURCES += src/main.cpp \ src/maplist.cpp \ src/downloader.cpp \ src/scaleitem.cpp \ - src/nicenum.cpp \ src/trackview.cpp \ src/track.cpp \ src/graphview.cpp \ @@ -77,7 +76,8 @@ SOURCES += src/main.cpp \ src/exportdialog.cpp \ src/fileselectwidget.cpp \ src/temperaturegraph.cpp \ - src/trackpoint.cpp + src/trackpoint.cpp \ + src/misc.cpp RESOURCES += gpxsee.qrc TRANSLATIONS = lang/gpxsee_cs.ts macx { diff --git a/lang/gpxsee_cs.ts b/lang/gpxsee_cs.ts index 4c2abc39..379e3cf3 100644 --- a/lang/gpxsee_cs.ts +++ b/lang/gpxsee_cs.ts @@ -163,338 +163,326 @@ 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 - + Open Otevřít - + Quit Ukončit - - - + + + Keyboard controls Ovládací klávesy - + Close Zavřít - + Reload Znovu načíst - + Show Zobrazit - - + + File Soubor - - - + + + Data sources Zdroje dat - + Load POI file Nahrát POI soubor - + Close POI files Zavřit POI soubory - + Show POIs Zobrazit POI - + Show map Zobrazit mapu - + Clear tile cache Vymazat mezipaměť dlaždic - - - + + + Next map Následující mapa - + Show graphs Zobrazovat grafy - + Show toolbars Zobrazovat nástrojové lišty - + Metric Metrické - + Imperial Imperiální - + Fullscreen mode Celoobrazovkový režim - + Next Následující - + Previous Předchozí - + Last Poslední - + First První - + Map Mapa - + POI POI - + POI files POI soubory - + Settings Nastavení - + Units Jednotky - + Help Nápověda - + Previous map Předchozí mapa - - + + Date Datum - + No GPX files loaded Nejsou načteny žádné GPX soubory - + Next file Následující soubor - + Version Verze - + Print... Tisknout... - + Export to PDF... Exportovat do PDF... - + Previous file Předchozí soubor - + First file První soubor - + Last file Poslední soubor - + Append modifier Modifikátor nahradit/přidat - + Map (tiles) source URLs are read on program startup from the following file: URL mapových zdrojů (dlaždic) jsou načteny při startu programu z následujícího souboru: - + 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: - + 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: - + GPX files (*.gpx);;All files (*) Soubory GPX (*.gpx);;Všechny soubory (*) - - + + Line: %1 Řádka: %1 - + GPX files (*.gpx);;CSV files (*.csv);;All files (*) Soubory GPX (*.gpx);;Soubory CSV (*.csv);;Všechny soubory (*) - + Tracks Počet tras - - + mi mi - - ft - ft - - - - + + About GPXSee O aplikaci GPXSee - + Navigation Navigace - + Map sources Mapové zdroje - + POIs POI body - - + + Distance Vzdálenost - + Time Čas - - m - m - - - + %1 tracks Počet tras: %1 - - + km km - - + + Error Chyba - + Error loading GPX file: %1 Soubor GPX nelze otevřít: %1 - + Error loading POI file: %1 Soubor POI nelze otevřít: @@ -553,21 +541,25 @@ QObject + mi mi + ft ft + km km + m m @@ -686,4 +678,22 @@ F + + TrackView + + + Date: + Datum: + + + + Distance: + Vzdálenost: + + + + Time: + Cas: + + diff --git a/src/axisitem.cpp b/src/axisitem.cpp index 4fe0832b..736eb72e 100644 --- a/src/axisitem.cpp +++ b/src/axisitem.cpp @@ -1,7 +1,7 @@ #include #include #include "config.h" -#include "nicenum.h" +#include "misc.h" #include "axisitem.h" diff --git a/src/gui.cpp b/src/gui.cpp index a1fc4489..d5f37e3f 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -35,21 +35,10 @@ #include "cpuarch.h" #include "exportdialog.h" #include "graphtab.h" +#include "misc.h" #include "gui.h" -static QString timeSpan(qreal time) -{ - unsigned h, m, s; - - h = time / 3600; - m = (time - (h * 3600)) / 60; - s = time - (h * 3600) - (m * 60); - - return QString("%1:%2:%3").arg(h).arg(m, 2, 10, QChar('0')) - .arg(s, 2, 10, QChar('0')); -} - GUI::GUI(QWidget *parent) : QMainWindow(parent) { loadMaps(); @@ -858,21 +847,8 @@ void GUI::updateStatusBarInfo() else _fileNameLabel->setText(tr("%1 tracks").arg(_trackCount)); - if (_imperialUnitsAction->isChecked()) { - if (_distance < MIINM) - _distanceLabel->setText(QString::number(_distance * M2FT, 'f', 0) - + UNIT_SPACE + tr("ft")); - else - _distanceLabel->setText(QString::number(_distance * M2MI, 'f', 1) - + UNIT_SPACE + tr("mi")); - } else { - if (_distance < KMINM) - _distanceLabel->setText(QString::number(_distance, 'f', 0) - + UNIT_SPACE + tr("m")); - else - _distanceLabel->setText(QString::number(_distance * M2KM, 'f', 1) - + UNIT_SPACE + tr("km")); - } + Units units = _imperialUnitsAction->isChecked() ? Imperial : Metric; + _distanceLabel->setText(distance(_distance, units)); _timeLabel->setText(timeSpan(_time)); } diff --git a/src/misc.cpp b/src/misc.cpp new file mode 100644 index 00000000..18faf995 --- /dev/null +++ b/src/misc.cpp @@ -0,0 +1,66 @@ +#include +#include +#include "misc.h" + +double niceNum(double x, int round) +{ + int expv; + double f; + double nf; + + expv = (int)floor(log10(x)); + f = x / pow(10.0, expv); + + if (round) { + if (f < 1.5) + nf = 1.0; + else if (f < 3.0) + nf = 2.0; + else if (f < 7.0) + nf = 5.0; + else + nf = 10.0; + } else { + if (f <= 1.0) + nf = 1.0; + else if (f <= 2.0) + nf = 2.0; + else if (f <= 5.0) + nf = 5.0; + else + nf = 10.0; + } + + return nf * pow(10.0, expv); +} + +QString timeSpan(qreal time) +{ + unsigned h, m, s; + + h = time / 3600; + m = (time - (h * 3600)) / 60; + s = time - (h * 3600) - (m * 60); + + return QString("%1:%2:%3").arg(h).arg(m, 2, 10, QChar('0')) + .arg(s, 2, 10, QChar('0')); +} + +QString distance(qreal value, Units units) +{ + if (units == Imperial) { + if (value < MIINM) + return QString::number(value * M2FT, 'f', 0) + + UNIT_SPACE + QObject::tr("ft"); + else + return QString::number(value * M2MI, 'f', 1) + + UNIT_SPACE + QObject::tr("mi"); + } else { + if (value < KMINM) + return QString::number(value, 'f', 0) + UNIT_SPACE + + QObject::tr("m"); + else + return QString::number(value * M2KM, 'f', 1) + + UNIT_SPACE + QObject::tr("km"); + } +} diff --git a/src/misc.h b/src/misc.h new file mode 100644 index 00000000..ac1615f2 --- /dev/null +++ b/src/misc.h @@ -0,0 +1,11 @@ +#ifndef MISC_H +#define MISC_H + +#include +#include "units.h" + +double niceNum(double x, int round); +QString timeSpan(qreal time); +QString distance(qreal value, Units units); + +#endif // MISC_H diff --git a/src/nicenum.cpp b/src/nicenum.cpp deleted file mode 100644 index f81d30b3..00000000 --- a/src/nicenum.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include "nicenum.h" - -double niceNum(double x, int round) -{ - int expv; - double f; - double nf; - - expv = (int)floor(log10(x)); - f = x / pow(10.0, expv); - - if (round) { - if (f < 1.5) - nf = 1.0; - else if (f < 3.0) - nf = 2.0; - else if (f < 7.0) - nf = 5.0; - else - nf = 10.0; - } else { - if (f <= 1.0) - nf = 1.0; - else if (f <= 2.0) - nf = 2.0; - else if (f <= 5.0) - nf = 5.0; - else - nf = 10.0; - } - - return nf * pow(10.0, expv); -} diff --git a/src/nicenum.h b/src/nicenum.h deleted file mode 100644 index 7be831b8..00000000 --- a/src/nicenum.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef NICENUM_H -#define NICENUM_H - -double niceNum(double x, int round); - -#endif // NICENUM_H diff --git a/src/parser.cpp b/src/parser.cpp index 81717cbc..63b12e4f 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -29,8 +29,14 @@ void Parser::handleTrackpointData(TrackpointElement element, void Parser::handleWaypointData(WaypointElement element, const QString &value) { - if (element == Name) - _waypoints.last().setDescription(value); + switch (element) { + case Name: + _waypoints.last().setName(value); + break; + case Description: + _waypoints.last().setDescription(value); + break; + } } void Parser::handleTrackpointAttributes(const QXmlStreamAttributes &attr) @@ -117,6 +123,8 @@ void Parser::waypointData() while (_reader.readNextStartElement()) { if (_reader.name() == "name") handleWaypointData(Name, _reader.readElementText()); + else if (_reader.name() == "desc") + handleWaypointData(Description, _reader.readElementText()); else _reader.skipCurrentElement(); } diff --git a/src/parser.h b/src/parser.h index f7c98887..787a3ca9 100644 --- a/src/parser.h +++ b/src/parser.h @@ -22,7 +22,7 @@ private: Elevation, Time, Geoidheight, Speed, HeartRate, Temperature }; enum WaypointElement { - Name + Name, Description }; bool parse(); diff --git a/src/poi.cpp b/src/poi.cpp index 79c73f29..f017d3e8 100644 --- a/src/poi.cpp +++ b/src/poi.cpp @@ -106,9 +106,14 @@ bool POI::loadCSVFile(const QString &fileName) return false; } QByteArray ba = list[2].trimmed(); + QString name = QString::fromUtf8(ba.data(), ba.size()); + QString description; + if (list.size() > 3) { + ba = list[3].trimmed(); + description = QString::fromUtf8(ba.data(), ba.size()); + } - _data.append(Waypoint(QPointF(lon, lat), - QString::fromUtf8(ba.data(), ba.size()))); + _data.append(Waypoint(QPointF(lon, lat), name, description)); ln++; } index.end = _data.size() - 1; diff --git a/src/scaleitem.cpp b/src/scaleitem.cpp index 728795be..1ccad3b9 100644 --- a/src/scaleitem.cpp +++ b/src/scaleitem.cpp @@ -1,7 +1,7 @@ #include #include "config.h" #include "ll.h" -#include "nicenum.h" +#include "misc.h" #include "scaleitem.h" diff --git a/src/trackview.cpp b/src/trackview.cpp index cc877411..9176e254 100644 --- a/src/trackview.cpp +++ b/src/trackview.cpp @@ -9,6 +9,7 @@ #include "markeritem.h" #include "scaleitem.h" #include "ll.h" +#include "misc.h" #include "trackview.h" @@ -38,6 +39,7 @@ TrackView::TrackView(QWidget *parent) _maxDistance = 0; _plot = false; + _units = Metric; } TrackView::~TrackView() @@ -46,7 +48,16 @@ TrackView::~TrackView() delete _mapScale; } -void TrackView::addTrack(const QVector &track) +QString TrackView::toolTip(const TrackInfo &info) +{ + QString date = info.date.date().toString(Qt::SystemLocaleShortDate); + + return "" + tr("Date:") + " " + date + "
" + tr("Distance:") + + " " + distance(info.distance, _units) + "
" + tr("Time:") + + " " + timeSpan(info.time); +} + +void TrackView::addTrack(const QVector &track, const TrackInfo &info) { QPainterPath path; QGraphicsPathItem *pi; @@ -71,12 +82,15 @@ void TrackView::addTrack(const QVector &track) pi = new QGraphicsPathItem(path); _paths.append(pi); + _info.append(info); _zoom = qMin(_zoom, scale2zoom(trackScale())); _scale = mapScale(_zoom); QBrush brush(_palette.color(), Qt::SolidPattern); QPen pen(brush, TRACK_WIDTH * _scale); pi->setPen(pen); pi->setScale(1.0/_scale); + pi->setToolTip(toolTip(info)); + pi->setCursor(Qt::ArrowCursor); _scene->addItem(pi); mi = new MarkerItem(pi); @@ -91,7 +105,7 @@ void TrackView::addWaypoints(const QList &waypoints) const Waypoint &w = waypoints.at(i); WaypointItem *wi = new WaypointItem( Waypoint(ll2mercator(QPointF(w.coordinates().x(), - -w.coordinates().y())), w.description())); + -w.coordinates().y())), w.name(), w.description())); wi->setPos(wi->entry().coordinates() * 1.0/_scale); wi->setZValue(1); @@ -111,8 +125,10 @@ void TrackView::loadGPX(const GPX &gpx) for (int i = 0; i < gpx.trackCount(); i++) { QVector track; + TrackInfo info = {gpx.track(i).date(), gpx.track(i).distance(), + gpx.track(i).time()}; gpx.track(i).track(track); - addTrack(track); + addTrack(track, info); _maxDistance = qMax(gpx.track(i).distance(), _maxDistance); } @@ -263,7 +279,7 @@ void TrackView::addPOI(const QVector &waypoints) WaypointItem *pi = new WaypointItem( Waypoint(ll2mercator(QPointF(w.coordinates().x(), - -w.coordinates().y())), w.description())); + -w.coordinates().y())), w.name(), w.description())); pi->setPos(pi->entry().coordinates() * 1.0/_scale); pi->setZValue(1); @@ -304,7 +320,12 @@ void TrackView::setMap(Map *map) void TrackView::setUnits(enum Units units) { + _units = units; + _mapScale->setUnits(units); + + for (int i = 0; i < _info.count(); i++) + _paths[i]->setToolTip(toolTip(_info.at(i))); } void TrackView::redraw() @@ -423,6 +444,7 @@ void TrackView::clear() _pois.clear(); _paths.clear(); + _info.clear(); _locations.clear(); _markers.clear(); _scene->clear(); diff --git a/src/trackview.h b/src/trackview.h index ffbb3d04..32d6bb75 100644 --- a/src/trackview.h +++ b/src/trackview.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "units.h" #include "palette.h" #include "waypoint.h" @@ -43,10 +44,18 @@ public slots: void redraw(); private: - void addTrack(const QVector &track); + struct TrackInfo { + QDateTime date; + qreal distance; + qreal time; + }; + + void addTrack(const QVector &track, const TrackInfo &info); void addWaypoints(const QList &waypoints); void addPOI(const QVector &waypoints); + QString toolTip(const TrackInfo &info); + QRectF trackBoundingRect() const; QRectF waypointBoundingRect() const; qreal trackScale() const; @@ -64,6 +73,7 @@ private: QGraphicsScene *_scene; QList _paths; + QList _info; QList _markers; QList _locations; QHash _pois; @@ -79,6 +89,7 @@ private: qreal _scale; int _zoom; + Units _units; bool _plot; }; diff --git a/src/waypoint.h b/src/waypoint.h index 9bc3dcd4..9272be1e 100644 --- a/src/waypoint.h +++ b/src/waypoint.h @@ -9,28 +9,33 @@ class Waypoint { public: Waypoint() {} - Waypoint(const QPointF &coordinates, const QString &description) - : _coordinates(coordinates), _description(description) {} + Waypoint(const QPointF &coordinates, const QString &name, + const QString &description) + : _coordinates(coordinates), _name(name), _description(description) {} const QPointF &coordinates() const {return _coordinates;} + const QString &name() const {return _name;} const QString &description() const {return _description;} void setCoordinates(const QPointF &coordinates) {_coordinates = coordinates;} + void setName(const QString &name) + {_name = name;} void setDescription(const QString &description) {_description = description;} bool operator==(const Waypoint &other) const - {return this->_description == other._description + {return this->_name == other._name && this->_coordinates == other._coordinates;} private: QPointF _coordinates; + QString _name; QString _description; }; inline uint qHash(const Waypoint &key) { - return ::qHash(key.description()); + return ::qHash(key.name()); } #endif // WAYPOINT_H diff --git a/src/waypointitem.cpp b/src/waypointitem.cpp index 297edfe6..5978fa61 100644 --- a/src/waypointitem.cpp +++ b/src/waypointitem.cpp @@ -10,6 +10,11 @@ WaypointItem::WaypointItem(const Waypoint &entry, QGraphicsItem *parent) { _entry = entry; updateBoundingRect(); + + if (!entry.description().isEmpty()) { + setToolTip(entry.description()); + setCursor(Qt::ArrowCursor); + } } void WaypointItem::updateBoundingRect() @@ -18,14 +23,14 @@ void WaypointItem::updateBoundingRect() font.setPixelSize(FONT_SIZE); font.setFamily(FONT_FAMILY); QFontMetrics fm(font); - QRect ts = fm.tightBoundingRect(_entry.description()); + QRect ts = fm.tightBoundingRect(_entry.name()); _boundingRect = QRectF(-POINT_SIZE/2, -POINT_SIZE/2, ts.width() + POINT_SIZE, ts.height() + fm.descent() + POINT_SIZE); } -void WaypointItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget) +void WaypointItem::paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); @@ -33,11 +38,11 @@ void WaypointItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti font.setPixelSize(FONT_SIZE); font.setFamily(FONT_FAMILY); QFontMetrics fm(font); - QRect ts = fm.tightBoundingRect(_entry.description()); + QRect ts = fm.tightBoundingRect(_entry.name()); painter->setFont(font); painter->drawText(POINT_SIZE/2 - qMax(ts.x(), 0), POINT_SIZE/2 + ts.height(), - _entry.description()); + _entry.name()); painter->setBrush(Qt::SolidPattern); painter->drawEllipse(-POINT_SIZE/2, -POINT_SIZE/2, POINT_SIZE, POINT_SIZE);