diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 81bd9e304..be97157a2 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -44,6 +44,7 @@ #include "DatePickerDialog.h" #include "ToolsDialog.h" +#include "SplitRideDialog.h" /* temp for the qmake/QMAKE_CXXFLAGS bug with xcode */ #ifndef GC_SVN_VERSION @@ -55,7 +56,6 @@ #define FOLDER_TYPE 0 #define RIDE_TYPE 1 -#define MILES_PER_KM 0.62137119 static char *rideFileRegExp = ("^(\\d\\d\\d\\d)_(\\d\\d)_(\\d\\d)" "_(\\d\\d)_(\\d\\d)_(\\d\\d)\\.(raw|srm|csv|tcx)$"); @@ -401,8 +401,10 @@ MainWindow::MainWindow(const QDir &home) : SLOT (importCSV()), tr ("Ctrl+S")); rideMenu->addAction(tr("&Import from TCX..."), this, SLOT (importTCX())); - rideMenu->addAction(tr("Find &best intervals..."), this, - SLOT(findBestIntervals()), tr ("Ctrl+B")); + rideMenu->addAction(tr("Find &best intervals..."), this, + SLOT(findBestIntervals()), tr ("Ctrl+B")); + rideMenu->addAction(tr("Split &ride..."), this, + SLOT(splitRide())); QMenu *optionsMenu = menuBar()->addMenu(tr("&Tools")); optionsMenu->addAction(tr("&Options..."), this, SLOT(showOptions()), tr("Ctrl+O")); @@ -431,7 +433,7 @@ MainWindow::MainWindow(const QDir &home) : } void -MainWindow::addRide(QString name) +MainWindow::addRide(QString name, bool bSelect /*=true*/) { QRegExp rx(rideFileRegExp); if (!rx.exactMatch(name)) { @@ -468,8 +470,51 @@ MainWindow::addRide(QString name) } allRides->insertChild(index, last); cpintPlot->needToScanRides = true; + if (bSelect) + { + tabWidget->setCurrentIndex(0); + treeWidget->setCurrentItem(last); + } +} + +void +MainWindow::removeCurrentRide() +{ + QTreeWidgetItem *_item = treeWidget->currentItem(); + if (_item->type() != RIDE_TYPE) + return; + RideItem *item = reinterpret_cast(_item); + + QTreeWidgetItem *itemToSelect = NULL; + for (int x=0; xchildCount(); ++x) + { + if (item==allRides->child(x)) + { + if ((x+1)childCount()) + itemToSelect = allRides->child(x+1); + else if (x>0) + itemToSelect = allRides->child(x-1); + break; + } + } + + QString strOldFileName = item->fileName; + allRides->removeChild(item); + delete item; + + QFile file(home.absolutePath() + "/" + strOldFileName); + // purposefully don't remove the old ext so the user wouldn't have to figure out what the old file type was + QString strNewName = strOldFileName + ".bak"; + if (!file.rename(home.absolutePath() + "/" + strNewName)) + { + QMessageBox::critical( + this, "Rename Error", + tr("Can't rename %1 to %2") + .arg(strOldFileName).arg(strNewName)); + } + tabWidget->setCurrentIndex(0); - treeWidget->setCurrentItem(last); + treeWidget->setCurrentItem(itemToSelect); } void @@ -546,50 +591,13 @@ MainWindow::exportCSV() return; QFile file(fileName); - // QFileDialog::getSaveFileName checks whether the file exists. - if (!file.open(QFile::WriteOnly | QFile::Truncate)) { - QMessageBox::critical( - this, tr("Open Error"), - tr("Can't open %1 for writing").arg(fileName)); + if (!file.open(QFile::WriteOnly | QFile::Truncate)) + { + QMessageBox::critical(this, tr("Split Ride"), tr("The file %1 can't be opened for writing").arg(fileName)); return; } - // Use the column headers that make WKO+ happy. - double convertUnit; - QTextStream out(&file); - if (units=="English"){ - out << "Minutes,Torq (N-m),MPH,Watts,Miles,Cadence,Hrate,ID\n"; - convertUnit = MILES_PER_KM; - } - else { - out << "Minutes,Torq (N-m),Km/h,Watts,Km,Cadence,Hrate,ID\n"; - // TODO: use KM_TO_MI from lib/pt.c instead? - convertUnit = 1.0; - } - - QListIterator i(ride->ride->dataPoints()); - while (i.hasNext()) { - RideFilePoint *point = i.next(); - if (point->secs == 0.0) - continue; - out << point->secs/60.0; - out << ","; - out << ((point->nm >= 0) ? point->nm : 0.0); - out << ","; - out << ((point->kph >= 0) ? (point->kph * convertUnit) : 0.0); - out << ","; - out << ((point->watts >= 0) ? point->watts : 0.0); - out << ","; - out << point->km * convertUnit; - out << ","; - out << point->cad; - out << ","; - out << point->hr; - out << ","; - out << point->interval << "\n"; - } - - file.close(); + ride->ride->writeAsCsv(file, units!="English"); } void MainWindow::importCSV() @@ -1175,4 +1183,9 @@ void MainWindow::showTools() td->exec(); } +void +MainWindow::splitRide() +{ + (new SplitRideDialog(this))->exec(); +} diff --git a/src/MainWindow.h b/src/MainWindow.h index 8e90e2110..49c591fca 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -38,7 +38,8 @@ class MainWindow : public QMainWindow public: MainWindow(const QDir &home); - void addRide(QString name); + void addRide(QString name, bool bSelect=true); + void removeCurrentRide(); const RideFile *currentRide(); QDir home; protected: @@ -57,6 +58,7 @@ class MainWindow : public QMainWindow void importSRM(); void importTCX(); void findBestIntervals(); + void splitRide(); void setSmoothingFromSlider(); void setSmoothingFromLineEdit(); void setBinWidthFromSlider(); diff --git a/src/RawRideFile.cpp b/src/RawRideFile.cpp index 2a21bdda6..40f3924ee 100644 --- a/src/RawRideFile.cpp +++ b/src/RawRideFile.cpp @@ -61,6 +61,12 @@ static void time_cb(struct tm *, time_t since_epoch, void *context) { ReadState *state = (ReadState*) context; + if (state->rideFile->startTime().isNull()) + { + QDateTime t; + t.setTime_t(since_epoch); + state->rideFile->setStartTime(t); + } if (state->start_since_epoch == 0) state->start_since_epoch = since_epoch; double secs = since_epoch - state->start_since_epoch; diff --git a/src/RideFile.cpp b/src/RideFile.cpp index fba46157b..edb7ff835 100644 --- a/src/RideFile.cpp +++ b/src/RideFile.cpp @@ -104,6 +104,49 @@ RideFile::writeAsXml(QFile &file, QString &err) return true; } +void RideFile::writeAsCsv(QFile &file, bool bIsMetric) const +{ + + // Use the column headers that make WKO+ happy. + double convertUnit; + QTextStream out(&file); + if (!bIsMetric) + { + out << "Minutes,Torq (N-m),MPH,Watts,Miles,Cadence,Hrate,ID\n"; + const double MILES_PER_KM = 0.62137119; + convertUnit = MILES_PER_KM; + } + else { + out << "Minutes,Torq (N-m),Km/h,Watts,Km,Cadence,Hrate,ID\n"; + // TODO: use KM_TO_MI from lib/pt.c instead? + convertUnit = 1.0; + } + + QListIterator i(dataPoints()); + while (i.hasNext()) { + RideFilePoint *point = i.next(); + if (point->secs == 0.0) + continue; + out << point->secs/60.0; + out << ","; + out << ((point->nm >= 0) ? point->nm : 0.0); + out << ","; + out << ((point->kph >= 0) ? (point->kph * convertUnit) : 0.0); + out << ","; + out << ((point->watts >= 0) ? point->watts : 0.0); + out << ","; + out << point->km * convertUnit; + out << ","; + out << point->cad; + out << ","; + out << point->hr; + out << ","; + out << point->interval << "\n"; + } + + file.close(); +} + RideFileFactory *RideFileFactory::instance_; RideFileFactory &RideFileFactory::instance() @@ -149,4 +192,3 @@ QStringList RideFileFactory::listRideFiles(const QDir &dir) const } return dir.entryList(filters, QDir::Files, QDir::Name|QDir::Reversed); } - diff --git a/src/RideFile.h b/src/RideFile.h index 78b4b89f2..5996474b4 100644 --- a/src/RideFile.h +++ b/src/RideFile.h @@ -90,6 +90,7 @@ class RideFile } bool writeAsXml(QFile &file, QString &err); + void writeAsCsv(QFile &file, bool bIsMetric) const; }; struct RideFileReader { diff --git a/src/src.pro b/src/src.pro index e98af938d..31fc381a6 100644 --- a/src/src.pro +++ b/src/src.pro @@ -16,7 +16,7 @@ RC_FILE = images/gc.icns macx { LIBS += -framework Carbon QMAKE_MAC_SDK=/Developer/SDKs/MacOSX10.4u.sdk - CONFIG+=x86 ppc + CONFIG+=x86 } win32 { @@ -64,7 +64,9 @@ HEADERS += \ Serial.h \ ToolsDialog.h \ Zones.h \ - srm.h + srm.h \ + SplitRideDialog.h + SOURCES += \ AllPlot.cpp \ @@ -98,7 +100,8 @@ SOURCES += \ ToolsDialog.cpp \ Zones.cpp \ main.cpp \ - srm.cpp + srm.cpp \ + SplitRideDialog.cpp RESOURCES = application.qrc