From a8c332bd163832b2fae150b784181193b7d9a202 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Date: Fri, 26 Jun 2015 23:23:14 -0300 Subject: [PATCH] Setup pace zones for running and swimming in New Athlete Changed CV default according to sport Part of #1298 --- src/NewCyclistDialog.cpp | 96 +++++++++++++++++++++++++++++++++------- src/NewCyclistDialog.h | 4 ++ src/PaceZones.h | 3 ++ src/Pages.cpp | 4 +- 4 files changed, 90 insertions(+), 17 deletions(-) diff --git a/src/NewCyclistDialog.cpp b/src/NewCyclistDialog.cpp index 204539cef..fc7e1752b 100644 --- a/src/NewCyclistDialog.cpp +++ b/src/NewCyclistDialog.cpp @@ -19,6 +19,7 @@ #include "NewCyclistDialog.h" #include "Zones.h" #include "HrZones.h" +#include "PaceZones.h" #include "GcUpgrade.h" #include "Athlete.h" @@ -42,10 +43,15 @@ NewCyclistDialog::NewCyclistDialog(QDir home) : QDialog(NULL, Qt::Dialog), home( QLabel *resthrlabel = new QLabel(tr("Resting Heartrate")); QLabel *lthrlabel = new QLabel(tr("Lactate Heartrate")); QLabel *maxhrlabel = new QLabel(tr("Maximum Heartrate")); + cvRnlabel = new QLabel(tr("CV Run (%1)").arg(useMetricUnits ? tr("min/km") : tr("min/mile"))); + cvSwlabel = new QLabel(tr("CV Swim (%1)").arg(useMetricUnits ? tr("min/100m") : tr("min/100yd"))); QString weighttext = QString(tr("Weight (%1)")).arg(useMetricUnits ? tr("kg") : tr("lb")); weightlabel = new QLabel(weighttext); + QString heighttext = QString(tr("Height (%1)")).arg(useMetricUnits ? tr("cm") : tr("in")); + heightlabel = new QLabel(heighttext); + name = new QLineEdit(this); dob = new QDateEdit(this); @@ -64,6 +70,12 @@ NewCyclistDialog::NewCyclistDialog(QDir home) : QDialog(NULL, Qt::Dialog), home( weight->setDecimals(1); weight->setValue(75); // default + height = new QDoubleSpinBox(this); + height->setMaximum(999.9); + height->setMinimum(0.0); + height->setDecimals(1); + height->setValue(175); // default + cp = new QSpinBox(this); cp->setMinimum(100); // juniors may average 100w for an hour, lower values might be seen for para-juniors (?) cp->setMaximum(500); // thats over 6w/kg for a 80kg rider, anything higher is physiologically unlikely @@ -107,6 +119,18 @@ NewCyclistDialog::NewCyclistDialog(QDir home) : QDialog(NULL, Qt::Dialog), home( maxhr->setSingleStep(1); maxhr->setValue(190); + // cvRn default is a nice round number comparable to CP default + cvRn = new QTimeEdit(QTime::fromString("04:00", "mm:ss")); + cvRn->setMinimumTime(QTime::fromString("01:00", "mm:ss")); + cvRn->setMaximumTime(QTime::fromString("20:00", "mm:ss")); + cvRn->setDisplayFormat("mm:ss"); + + // cvSw default is in 4-1 relation to cvRun + cvSw = new QTimeEdit(QTime::fromString("01:36", "mm:ss")); + cvSw->setMinimumTime(QTime::fromString("01:00", "mm:ss")); + cvSw->setMaximumTime(QTime::fromString("20:00", "mm:ss")); + cvSw->setDisplayFormat("mm:ss"); + bio = new QTextEdit(this); avatar = QPixmap(":/images/noavatar.png"); @@ -125,28 +149,34 @@ NewCyclistDialog::NewCyclistDialog(QDir home) : QDialog(NULL, Qt::Dialog), home( grid->addWidget(sexlabel, 2, 0, alignment); grid->addWidget(unitlabel, 3, 0, alignment); grid->addWidget(weightlabel, 4, 0, alignment); - grid->addWidget(cplabel, 5, 0, alignment); - grid->addWidget(wlabel, 6, 0, alignment); - grid->addWidget(pmaxlabel, 7, 0, alignment); - grid->addWidget(wbaltaulabel, 8, 0, alignment); - grid->addWidget(resthrlabel, 9, 0, alignment); - grid->addWidget(lthrlabel, 10, 0, alignment); - grid->addWidget(maxhrlabel, 11, 0, alignment); - grid->addWidget(biolabel, 12, 0, alignment); + grid->addWidget(heightlabel, 5, 0, alignment); + grid->addWidget(cplabel, 6, 0, alignment); + grid->addWidget(wlabel, 7, 0, alignment); + grid->addWidget(pmaxlabel, 8, 0, alignment); + grid->addWidget(wbaltaulabel, 9, 0, alignment); + grid->addWidget(resthrlabel, 10, 0, alignment); + grid->addWidget(lthrlabel, 11, 0, alignment); + grid->addWidget(maxhrlabel, 12, 0, alignment); + grid->addWidget(cvRnlabel, 13, 0, alignment); + grid->addWidget(cvSwlabel, 14, 0, alignment); + grid->addWidget(biolabel, 15, 0, alignment); grid->addWidget(name, 0, 1, alignment); grid->addWidget(dob, 1, 1, alignment); grid->addWidget(sex, 2, 1, alignment); grid->addWidget(unitCombo, 3, 1, alignment); grid->addWidget(weight, 4, 1, alignment); - grid->addWidget(cp, 5, 1, alignment); - grid->addWidget(w, 6, 1, alignment); - grid->addWidget(pmax, 7, 1, alignment); - grid->addWidget(wbaltau, 8, 1, alignment); - grid->addWidget(resthr, 9, 1, alignment); - grid->addWidget(lthr, 10, 1, alignment); - grid->addWidget(maxhr, 11, 1, alignment); - grid->addWidget(bio, 13, 0, 1, 4); + grid->addWidget(height, 5, 1, alignment); + grid->addWidget(cp, 6, 1, alignment); + grid->addWidget(w, 7, 1, alignment); + grid->addWidget(pmax, 8, 1, alignment); + grid->addWidget(wbaltau, 9, 1, alignment); + grid->addWidget(resthr, 10, 1, alignment); + grid->addWidget(lthr, 11, 1, alignment); + grid->addWidget(maxhr, 12, 1, alignment); + grid->addWidget(cvRn, 13, 1, alignment); + grid->addWidget(cvSw, 14, 1, alignment); + grid->addWidget(bio, 16, 0, 1, 4); grid->addWidget(avatarButton, 0, 2, 4, 2, Qt::AlignRight|Qt::AlignVCenter); all->addLayout(grid); @@ -187,12 +217,36 @@ NewCyclistDialog::unitChanged(int currentIndex) QString weighttext = QString(tr("Weight (%1)")).arg(tr("kg")); weightlabel->setText(weighttext); weight->setValue(weight->value() / LB_PER_KG); + QString heighttext = QString(tr("Height (%1)")).arg(tr("cm")); + heightlabel->setText(heighttext); + height->setValue(height->value() * CM_PER_INCH); + + cvRnlabel->setText(tr("CV Run (%1)").arg(tr("min/km"))); + PaceZones rnPaceZones(false); + cvRn->setTime(QTime::fromString(rnPaceZones.kphToPaceString(rnPaceZones.kphFromTime(cvRn, false), true), "mm:ss")); + + cvSwlabel->setText(tr("CV Swim (%1)").arg(tr("min/100m"))); + PaceZones swPaceZones(true); + cvSw->setTime(QTime::fromString(swPaceZones.kphToPaceString(swPaceZones.kphFromTime(cvSw, false), true), "mm:ss")); + useMetricUnits = true; } else { QString weighttext = QString(tr("Weight (%1)")).arg(tr("lb")); weightlabel->setText(weighttext); weight->setValue(weight->value() * LB_PER_KG); + QString heighttext = QString(tr("Height (%1)")).arg(tr("in")); + heightlabel->setText(heighttext); + height->setValue(height->value() / CM_PER_INCH); + + cvRnlabel->setText(tr("CV Run (%1)").arg(tr("min/mile"))); + PaceZones rnPaceZones(false); + cvRn->setTime(QTime::fromString(rnPaceZones.kphToPaceString(rnPaceZones.kphFromTime(cvRn, true), false), "mm:ss")); + + cvSwlabel->setText(tr("CV Swim (%1)").arg(tr("min/100yd"))); + PaceZones swPaceZones(true); + cvSw->setTime(QTime::fromString(swPaceZones.kphToPaceString(swPaceZones.kphFromTime(cvSw, true), false), "mm:ss")); + useMetricUnits = false; } } @@ -249,6 +303,7 @@ NewCyclistDialog::saveClicked() appsettings->setCValue(name->text(), GC_DOB, dob->date()); appsettings->setCValue(name->text(), GC_WEIGHT, weight->value() * (useMetricUnits ? 1.0 : KG_PER_LB)); + appsettings->setCValue(name->text(), GC_HEIGHT, height->value() * (useMetricUnits ? 1.0/100.0 : CM_PER_INCH/100.0)); appsettings->setCValue(name->text(), GC_WBALTAU, wbaltau->value()); appsettings->setCValue(name->text(), GC_SEX, sex->currentIndex()); appsettings->setCValue(name->text(), GC_BIO, bio->toPlainText()); @@ -264,6 +319,15 @@ NewCyclistDialog::saveClicked() hrzones.addHrZoneRange(QDate(1900, 01, 01), lthr->value(), resthr->value(), maxhr->value()); hrzones.write(athleteHome->config().canonicalPath()); + // Pace Zones for Run + PaceZones rnPaceZones(false); + rnPaceZones.addZoneRange(QDate(1900, 01, 01), rnPaceZones.kphFromTime(cvRn, useMetricUnits)); + rnPaceZones.write(athleteHome->config().canonicalPath()); + + // Pace Zones for Run + PaceZones swPaceZones(true); + swPaceZones.addZoneRange(QDate(1900, 01, 01), swPaceZones.kphFromTime(cvSw, useMetricUnits)); + swPaceZones.write(athleteHome->config().canonicalPath()); accept(); } else { diff --git a/src/NewCyclistDialog.h b/src/NewCyclistDialog.h index 244996b99..cc01f36ce 100644 --- a/src/NewCyclistDialog.h +++ b/src/NewCyclistDialog.h @@ -54,9 +54,13 @@ class NewCyclistDialog : public QDialog QDateEdit *dob; QComboBox *sex; QLabel *weightlabel; + QLabel *heightlabel; + QLabel *cvRnlabel, *cvSwlabel; QComboBox *unitCombo; QSpinBox *cp, *w, *pmax, *lthr, *resthr, *maxhr; // mandatory non-zero, default from age + QTimeEdit *cvRn, *cvSw; QDoubleSpinBox *weight; + QDoubleSpinBox *height; QSpinBox *wbaltau; QTextEdit *bio; QPushButton *avatarButton; diff --git a/src/PaceZones.h b/src/PaceZones.h index 1e5656ada..32a20df4c 100644 --- a/src/PaceZones.h +++ b/src/PaceZones.h @@ -122,6 +122,9 @@ class PaceZones : public QObject // or to defaults using Skiba's coefficients void initializeZoneParameters(); + // Sport + bool isSwim() { return swim; } + // // Zone history - Ranges // diff --git a/src/Pages.cpp b/src/Pages.cpp index 96fe777a3..99861b9a2 100644 --- a/src/Pages.cpp +++ b/src/Pages.cpp @@ -4735,7 +4735,9 @@ CVPage::CVPage(PaceZonePage* zonePage) : zonePage(zonePage) dateEdit = new QDateEdit; dateEdit->setDate(QDate::currentDate()); - cvEdit = new QTimeEdit(QTime::fromString("05:00", "mm:ss")); + // CV default is 4min/km for Running a round number inline with + // CP default and 1:36min/100 for swimming (4:1 relation) + cvEdit = new QTimeEdit(QTime::fromString(zonePage->zones->isSwim() ? "01:36" : "04:00", "mm:ss")); cvEdit->setMinimumTime(QTime::fromString("01:00", "mm:ss")); cvEdit->setMaximumTime(QTime::fromString("20:00", "mm:ss")); cvEdit->setDisplayFormat("mm:ss");