From 5d3f9b88cdc49b7c953d4e788151e82526c8b9ee Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Thu, 21 Jan 2016 17:08:31 +0000 Subject: [PATCH] Workout Editor Save (ERG, MRC only) .. no support for pgmf or CRS .. but no edit suport for CRS either. .. no support yet for ZWO either --- src/ErgFile.cpp | 185 ++++++++++++++++++++++++++++++++++++++++++ src/ErgFile.h | 3 + src/WorkoutWidget.cpp | 63 +++++++++++++- src/WorkoutWidget.h | 3 + src/WorkoutWindow.cpp | 8 +- 5 files changed, 258 insertions(+), 4 deletions(-) diff --git a/src/ErgFile.cpp b/src/ErgFile.cpp index 7a3fba26d..bc443c66c 100644 --- a/src/ErgFile.cpp +++ b/src/ErgFile.cpp @@ -379,6 +379,9 @@ void ErgFile::parseComputrainer(QString p) QRegExp pname("^DESCRIPTION *", Qt::CaseInsensitive); if (pname.exactMatch(settings.cap(1))) Name = settings.cap(2); + QRegExp iname("^ERGDBID *", Qt::CaseInsensitive); + if (iname.exactMatch(settings.cap(1))) ErgDBId = settings.cap(2); + QRegExp sname("^SOURCE *", Qt::CaseInsensitive); if (sname.exactMatch(settings.cap(1))) Source = settings.cap(2); @@ -502,6 +505,188 @@ void ErgFile::parseComputrainer(QString p) } } +bool +ErgFile::save(QStringList &errors) +{ + // save the file including changes + // XXX TODO we don't support writing pgmf or CRS just yet... + if (filename.endsWith("pgmf") || format == CRS) { + errors << QString(QObject::tr("Unsupported file format")); + return false; + } + + // type + QString typestring("UNKNOWN"); + if (format==ERG) typestring = "ERG"; + if (format==MRC) typestring = "MRC"; + if (format==CRS) typestring = "CRS"; + + // get CP so we can scale back etc + int CP=0; + if (context->athlete->zones(false)) { + int zonerange = context->athlete->zones(false)->whichRange(QDateTime::currentDateTime().date()); + if (zonerange >= 0) CP = context->athlete->zones(false)->getCP(zonerange); + } + + // MRC and ERG formats are ok + + // + // ERG file + // + if (typestring == "ERG" && format == ERG) { + + // open the file etc + QFile f(filename); + if (f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text) == false) { + errors << "Unable to open file for writing."; + return false; + } + + // setup output stream to file + QTextStream out(&f); + out.setCodec("UTF-8"); + + // write the header + // + // An example header: + // + // [COURSE HEADER] + // FTP=300 + // SOURCE=ErgDB + // ERGDBID=455 + // VERSION=2 + // UNITS=ENGLISH + // DESCRIPTION=Weston Loop + // FILE NAME=weston + // MINUTES WATTS + // [END COURSE HEADER] + out << "[COURSE HEADER]\n"; + if (Ftp) out <<"FTP="< 0) { + out < 0) { + out < #include #include @@ -1385,7 +1386,7 @@ WorkoutWidget::ergFileSelected(ErgFile *ergFile) points_.clear(); // we suport ERG but not MRC/CRS currently - if (ergFile && ergFile->format == ERG) { + if (ergFile && (ergFile->format == MRC || ergFile->format == ERG)) { this->ergFile = ergFile; @@ -1417,6 +1418,66 @@ WorkoutWidget::ergFileSelected(ErgFile *ergFile) repaint(); } +void +WorkoutWidget::save() +{ + // if nothing doing don't save + if (stackptr <= 0) return; + + // no ergfile? + if (ergFile == NULL) { + //XXX nothing for now - will need Save as... + return; + } + + // + // IN CORE + // + // replace all the points - they are scaled to local CP + // so do not need to be scaled back, that happens when + // they are read/written to file on disk + ergFile->Points.clear(); + ergFile->Duration = 0; + foreach(WWPoint *p, points_) { + ergFile->Points.append(ErgFilePoint(p->x * 1000, p->y, p->y)); + ergFile->Duration = p->x * 1000; // whatever the last is + } + + // force any other plots to take the changes + context->notifyErgFileSelected(ergFile); + + // + // SAVE + // + QStringList errors; + if (ergFile->save(errors) == false) { + + // save failed :( + // + // likely caused by unsupported format + QMessageBox msgBox; + msgBox.setText(tr("File save failed.")); + msgBox.setInformativeText(errors.join(".")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + msgBox.setIcon(QMessageBox::Critical); + msgBox.exec(); + + } else { + + // if it succeeds then reset stuff + foreach (WorkoutWidgetCommand *p, stack) delete p; + stack.clear(); + stackptr = 0; + parent->saveAct->setEnabled(false); + parent->undoAct->setEnabled(false); + parent->redoAct->setEnabled(false); + + } + + return; +} + void WorkoutWidget::recompute(bool editing) { diff --git a/src/WorkoutWidget.h b/src/WorkoutWidget.h index a14e26ad9..463b4e863 100644 --- a/src/WorkoutWidget.h +++ b/src/WorkoutWidget.h @@ -217,6 +217,9 @@ class WorkoutWidget : public QWidget // and erg file was selected void ergFileSelected(ErgFile *); + // save or save as (when erfile is NULL) + void save(); + // qwkcode edited void fromQwkcode(QString); diff --git a/src/WorkoutWindow.cpp b/src/WorkoutWindow.cpp index 97d06e448..332ea1788 100644 --- a/src/WorkoutWindow.cpp +++ b/src/WorkoutWindow.cpp @@ -182,7 +182,6 @@ WorkoutWindow::WorkoutWindow(Context *context) : saveAct->setEnabled(false); undoAct->setEnabled(false); redoAct->setEnabled(false); - configChanged(CONFIG_APPEARANCE); // watch for erg run/stop connect(context, SIGNAL(start()), this, SLOT(start())); @@ -191,6 +190,9 @@ WorkoutWindow::WorkoutWindow(Context *context) : // text changed connect(code, SIGNAL(textChanged()), this, SLOT(qwkcodeChanged())); connect(code, SIGNAL(cursorPositionChanged()), workout, SLOT(hoverQwkcode())); + + // set the widgets etc + configChanged(CONFIG_APPEARANCE); } void @@ -227,7 +229,7 @@ WorkoutWindow::configChanged(qint32) // maximum of 20 characters per line ? QFont f; QFontMetrics ff(f); - code->setFixedWidth(ff.width("99x999s@999-999r999s@999-999")); + code->setFixedWidth(ff.boundingRect("99x999s@999-999r999s@999-999").width()+20); // text edit colors QPalette palette; @@ -254,7 +256,7 @@ WorkoutWindow::configChanged(qint32) void WorkoutWindow::saveFile() { - qDebug()<<"SAVE ASKED FOR"; + workout->save(); } void