diff --git a/src/SplitRideDialog.cpp b/src/SplitRideDialog.cpp new file mode 100644 index 000000000..7c9035607 --- /dev/null +++ b/src/SplitRideDialog.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2009 Ned Harding (ned@hardinggroup.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "SplitRideDialog.h" +#include "MainWindow.h" +#include "RideFile.h" +#include +#include +#include +#include +#include + +namespace +{ + QString MakeTimeString(double secs) + { + QString strTime; + double mins = ((int) secs) / 60; + secs = secs - mins * 60.0; + double hrs = ((int) mins) / 60; + mins = mins - hrs * 60.0; + strTime.sprintf("%02.0f:%02.0f:%02.0f", hrs, mins, secs); + return strTime; + } + + class ListItem_Split : public QListWidgetItem + { + public: + int m_nRecNum; + explicit ListItem_Split(int nRecNum, const QString &text, QListWidget *view) + : QListWidgetItem(text, view) + , m_nRecNum(nRecNum) + { + } + }; +} + +SplitRideDialog::SplitRideDialog(MainWindow *mainWindow) + : mainWindow(mainWindow) +{ + setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle("Split Ride"); + + listWidget = new QListWidget(this); + listWidget->setSelectionMode(QAbstractItemView::SingleSelection); + + QLabel *splitLabel = new QLabel(tr("Split at the following positions:"), this); + QLabel *labelSpacer = new QLabel(this); + labelSpacer->setIndent(10); + + okButton = new QPushButton(tr("&OK"), this); + cancelButton = new QPushButton(tr("&Cancel"), this); + + connect(okButton, SIGNAL(clicked()), this, SLOT(okClicked())); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancelClicked())); + connect(listWidget, + SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged())); + + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addWidget(okButton); + buttonLayout->addWidget(cancelButton); + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(splitLabel); + mainLayout->addWidget(listWidget); + mainLayout->addWidget(labelSpacer); + mainLayout->addLayout(buttonLayout); + + double dLastSeconds = -1.0; + int nLastInterval = 0; + int nDataPoint = 0; + const RideFile *ride = mainWindow->currentRide(); + + for (QListIterator i(ride->dataPoints()); i.hasNext(); ++nDataPoint) + { + const RideFilePoint *point = i.next(); + if (dLastSeconds>=0 && + ((point->secs-dLastSeconds)>=30 || nLastInterval!=point->interval)) + { + + QString strDesc; + if (nLastInterval!=point->interval) + strDesc.sprintf("Interval #%d", point->interval); + else + strDesc = "Time Gap: " + MakeTimeString(point->secs-dLastSeconds); + + strDesc = MakeTimeString(point->secs) + " - " + strDesc; + ListItem_Split *pItem = new ListItem_Split(nDataPoint, strDesc, listWidget); + + if ((point->secs-dLastSeconds)>20*60) + pItem->setCheckState(Qt::Checked); + else + pItem->setCheckState(Qt::Unchecked); + } + + dLastSeconds = point->secs; + nLastInterval = point->interval; + } +} + + +void +SplitRideDialog::cancelClicked() +{ + reject(); +} + +void +SplitRideDialog::CreateNewRideFile(const RideFile *ride, int nRecStart, int nRecEnd) +{ + QDateTime newStart = ride->startTime(); + RideFilePoint *pointStart = ride->dataPoints().at(nRecStart); + newStart = newStart.addMSecs(static_cast(pointStart->secs*1000 + 0.5)); + boost::scoped_ptr newRideFile(new RideFile(newStart, ride->recIntSecs())); + for (int nItem = nRecStart; nItemdataPoints().at(nItem); + newRideFile->appendPoint(pPoint->secs-pointStart->secs, pPoint->cad, pPoint->hr, pPoint->km - pointStart->km, + pPoint->kph, pPoint->nm, pPoint->watts, pPoint->interval-pointStart->interval); + } + + QString fileName; + fileName.sprintf("%04d_%02d_%02d_%02d_%02d_%02d.csv", + newStart.date().year(), newStart.date().month(), + newStart.date().day(), newStart.time().hour(), newStart.time().minute(), + newStart.time().second()); + QString filePath = mainWindow->home.absolutePath() + "/" + fileName; + + QFile file(filePath); + if (file.exists()) + { + QMessageBox::critical(this, tr("Split Ride"), tr("The file %1 already exists and will not be overwritten").arg(filePath)); + return; + } + if (!file.open(QFile::WriteOnly | QFile::Truncate)) + QMessageBox::critical(this, tr("Split Ride"), tr("The file %1 can't be opened for writing").arg(filePath)); + + newRideFile->writeAsCsv(file, true); + + mainWindow->addRide(fileName, false); +} +void +SplitRideDialog::okClicked() +{ + const RideFile *ride = mainWindow->currentRide(); + + int nStartPoint = 0; + for (int nRow=0; nRowcount(); ++nRow) + { + const ListItem_Split *pItem = static_cast(listWidget->item(nRow)); + if (pItem->checkState()==Qt::Checked) + { + CreateNewRideFile(ride, nStartPoint, pItem->m_nRecNum); + nStartPoint = pItem->m_nRecNum; + } + } + + if (nStartPoint!=0) + { + CreateNewRideFile(ride, nStartPoint, mainWindow->currentRide()->dataPoints().count()); + mainWindow->removeCurrentRide(); + } + + done(0); +} + +void +SplitRideDialog::selectionChanged() +{ +} diff --git a/src/SplitRideDialog.h b/src/SplitRideDialog.h new file mode 100644 index 000000000..4ac9d78dc --- /dev/null +++ b/src/SplitRideDialog.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2009 Ned Harding (ned@hardinggroup.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SPLITRIDEDIALOG_H +#define SPLITRIDEDIALOG_H + +#include +class MainWindow; +class RideFile; + +class SplitRideDialog : public QDialog +{ + Q_OBJECT + + public: + SplitRideDialog(MainWindow *mainWindow); + + private slots: + void okClicked(); + void cancelClicked(); + void selectionChanged(); + + private: + + MainWindow *mainWindow; + QListWidget *listWidget; + QPushButton *okButton, *cancelButton; + + void CreateNewRideFile(const RideFile *ride, int nRecStart, int nRecEnd); +}; + +#endif // SPLITRIDEDIALOG_H