From be797ffb31d05b0d145d847d9314d4e159a9d1be Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Date: Sun, 7 Aug 2022 14:28:15 -0300 Subject: [PATCH] Train View Perspective Switch - Add Map Workout option So workouts with GPS data but no video can use LiveMap chart, without messing with basic slope workouts Update default layout to include a perspective for each mode Part of #3899 --- src/Gui/Perspective.cpp | 1 + src/Gui/Perspective.h | 2 +- src/Resources/xml/train-perspectives.xml | 356 ++++++++++++++++++----- src/Train/ErgFile.cpp | 8 +- src/Train/ErgFile.h | 3 + src/Train/TrainSidebar.cpp | 4 +- 6 files changed, 300 insertions(+), 74 deletions(-) diff --git a/src/Gui/Perspective.cpp b/src/Gui/Perspective.cpp index 918de68ee..6ee54f46a 100644 --- a/src/Gui/Perspective.cpp +++ b/src/Gui/Perspective.cpp @@ -1906,6 +1906,7 @@ AddPerspectiveDialog::AddPerspectiveDialog(QWidget *parent, Context *context, QS trainSwitch->addItem(tr("Erg Workout"), Perspective::Erg); trainSwitch->addItem(tr("Slope Workout"), Perspective::Slope); trainSwitch->addItem(tr("Video Workout"), Perspective::Video); + trainSwitch->addItem(tr("Map Workout"), Perspective::Map); trainSwitch->setCurrentIndex(trainswitch); form->addRow(new QLabel(tr("Switch for")), trainSwitch); } diff --git a/src/Gui/Perspective.h b/src/Gui/Perspective.h index b041b9dbe..8d0cd4b66 100644 --- a/src/Gui/Perspective.h +++ b/src/Gui/Perspective.h @@ -76,7 +76,7 @@ class Perspective : public GcWindow void setExpression(QString); // trainswitch - enum switchenum { None=0, Erg=1, Slope=2, Video=3 }; + enum switchenum { None=0, Erg=1, Slope=2, Video=3, Map=4 }; int trainSwitch() const { return trainswitch; } void setTrainSwitch(int x) { trainswitch = (switchenum)x; } diff --git a/src/Resources/xml/train-perspectives.xml b/src/Resources/xml/train-perspectives.xml index f33ddf66b..66e018c1b 100644 --- a/src/Resources/xml/train-perspectives.xml +++ b/src/Resources/xml/train-perspectives.xml @@ -1,5 +1,280 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -13,17 +288,17 @@ - - + + - + - + @@ -78,77 +353,22 @@ - + - - + + - - + + - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/src/Train/ErgFile.cpp b/src/Train/ErgFile.cpp index d0658e38e..beafbbaa2 100644 --- a/src/Train/ErgFile.cpp +++ b/src/Train/ErgFile.cpp @@ -57,7 +57,7 @@ bool ErgFile::isWorkout(QString name) return false; } ErgFile::ErgFile(QString filename, int mode, Context *context) : - filename(filename), mode(mode), StrictGradient(true), context(context) + filename(filename), mode(mode), StrictGradient(true), fHasGPS(false), context(context) { if (context->athlete->zones("Bike")) { int zonerange = context->athlete->zones("Bike")->whichRange(QDateTime::currentDateTime().date()); @@ -66,7 +66,7 @@ ErgFile::ErgFile(QString filename, int mode, Context *context) : reload(); } -ErgFile::ErgFile(Context *context) : mode(0), StrictGradient(true), context(context) +ErgFile::ErgFile(Context *context) : mode(0), StrictGradient(true), fHasGPS(false), context(context) { if (context->athlete->zones("Bike")) { int zonerange = context->athlete->zones("Bike")->whichRange(QDateTime::currentDateTime().date()); @@ -757,9 +757,9 @@ void ErgFile::parseFromRideFileFactory() bool fHasKm = ride->areDataPresent()->km; bool fHasLat = ride->areDataPresent()->lat; bool fHasLon = ride->areDataPresent()->lon; - bool fHasGPS = fHasLat && fHasLon; bool fHasAlt = ride->areDataPresent()->alt; bool fHasSlope = ride->areDataPresent()->slope; + fHasGPS = fHasLat && fHasLon; if (fHasKm && fHasSlope) {} // same as crs file else if (fHasKm && fHasAlt) {} // derive slope from distance and alt @@ -900,9 +900,9 @@ void ErgFile::parseTTS() // Enumerate the data types that are available. bool fHasKm = ttsReader.hasKm(); - bool fHasGPS = ttsReader.hasGPS(); bool fHasAlt = ttsReader.hasElevation(); bool fHasSlope = ttsReader.hasGradient(); + fHasGPS = ttsReader.hasGPS(); if (fHasKm && fHasSlope) {} // same as crs file else if (fHasKm && fHasAlt) {} // derive slope from distance and alt diff --git a/src/Train/ErgFile.h b/src/Train/ErgFile.h index e8c5b304a..23b7c37df 100644 --- a/src/Train/ErgFile.h +++ b/src/Train/ErgFile.h @@ -132,6 +132,7 @@ class ErgFile bool hasGradient() const { return CRS == format; } // Has Gradient and Altitude bool hasWatts() const { return ERG == format || MRC == format; } + bool hasGPS() const { return fHasGPS; } // Has Lat/Lon private: void sortLaps() const; @@ -166,6 +167,7 @@ public: bool valid; // did it parse ok? int mode; bool StrictGradient; // should gradient be strict or smoothed? + bool fHasGPS; // has Lat/Lon? QList Points; // points in workout mutable QList Laps; // interval markers in the file @@ -231,6 +233,7 @@ public: // Const getters bool hasGradient() const { return ergFile && ergFile->hasGradient(); } bool hasWatts() const { return ergFile && ergFile->hasWatts(); } + bool hasGPS() const { return ergFile && ergFile->hasGPS(); } double nextLap (double x) const { return !ergFile ? -1 : ergFile->nextLap(x); } double prevLap (double x) const { return !ergFile ? -1 : ergFile->prevLap(x); } diff --git a/src/Train/TrainSidebar.cpp b/src/Train/TrainSidebar.cpp index 7adba3e20..dded3ba47 100644 --- a/src/Train/TrainSidebar.cpp +++ b/src/Train/TrainSidebar.cpp @@ -1600,12 +1600,14 @@ void TrainSidebar::Connect() // if everything has been initialised properly (aka lazy load) // given the connect widget is on the train view it is unlikely // below will ever be false, but no harm in checking +qDebug() << (trainView!=NULL) << (trainView->page()!=NULL); if (trainView && trainView->page()) { Perspective::switchenum want=Perspective::None; if (mediafile != "") want=Perspective::Video; // if media file selected else want = (mode == ERG || mode == MRC) ? Perspective::Erg : Perspective::Slope; // mode always known - + if (want == Perspective::Slope && ergFileQueryAdapter.hasGPS()) want=Perspective::Map; // Map without Video +qDebug()<page()->trainSwitch(); // so we want a view type and the current page isn't what // we want then lets go find one to switch to and switch // to the first one that matches