mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
CSV import code from Justin Knotzke
This commit is contained in:
63
src/gui/CsvData.cpp
Normal file
63
src/gui/CsvData.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// C++ Implementation: csv
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
//
|
||||
// Author: Justin F. Knotzke <jknotzke@shampoo.ca>, (C) 2007
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "CsvData.h"
|
||||
#include <QTextStream>
|
||||
#include "RawFile.h"
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
void CsvData::readCsvFile(QFile &file, RawFile *rawFile)
|
||||
{
|
||||
|
||||
QTextStream stream( &file );
|
||||
QString line;
|
||||
std::vector<double> vec;
|
||||
double previousSecs = 0.0;
|
||||
//Flush the first line.
|
||||
line = stream.readLine();
|
||||
while ( !stream.atEnd() )
|
||||
{
|
||||
line = stream.readLine();
|
||||
//Parse the line here
|
||||
secs = line.section(',', 0, 0).toDouble();
|
||||
kph = line.section(',', 2, 2).toDouble();
|
||||
watts = line.section(',', 3, 3).toInt();
|
||||
km = line.section(',', 4, 4).toDouble();
|
||||
cad = line.section(',', 5, 5).toInt();
|
||||
hr = line.section(',', 6, 6).toInt();
|
||||
interval = line.section(',', 7, 7).toInt();
|
||||
|
||||
//To figure out the mean recording interval
|
||||
vec.push_back(secs - previousSecs);
|
||||
previousSecs = secs;
|
||||
|
||||
//For the power histogram
|
||||
if (rawFile->powerHist.contains(watts))
|
||||
rawFile->powerHist[watts] +=secs;
|
||||
else
|
||||
rawFile->powerHist[watts] = secs;
|
||||
|
||||
//Assume that all CSV files have km/h
|
||||
RawFilePoint *p1 = new RawFilePoint(
|
||||
secs, 0, kph * 0.621371192 , watts,
|
||||
km * 0.621371192, cad, hr, interval);
|
||||
|
||||
rawFile->points.append(p1);
|
||||
}
|
||||
//Sort it
|
||||
std::sort(vec.begin(), vec.end());
|
||||
int size = vec.size();
|
||||
//Then grab the middle value (the mean) and covert to milliseconds
|
||||
rawFile->rec_int_ms = int(vec[size/2] * 60 * 1000);
|
||||
}
|
||||
|
||||
29
src/gui/CsvData.h
Normal file
29
src/gui/CsvData.h
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// C++ Interface: csv
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
//
|
||||
// Author: Justin F. Knotzke <jknotzke@shampoo.ca>, (C) 2007
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef _csv_h
|
||||
#define _csv_h
|
||||
|
||||
#include <QDate>
|
||||
|
||||
class QFile;
|
||||
class RawFile;
|
||||
|
||||
class CsvData
|
||||
{
|
||||
public:
|
||||
int cad, hr, watts, interval;
|
||||
double kph, km, secs;
|
||||
QDateTime startTime;
|
||||
double recint;
|
||||
void readCsvFile(QFile &file, RawFile *rawFile);
|
||||
};
|
||||
#endif // _srm_h
|
||||
83
src/gui/DatePickerDialog.cpp
Normal file
83
src/gui/DatePickerDialog.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// Author: Justin F. Knotzke <jknotzke@shampoo.ca>, (C) 2007
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
|
||||
#include "DatePickerDialog.h"
|
||||
#include <QtGui>
|
||||
|
||||
void DatePickerDialog::setupUi(QDialog *DatePickerDialog)
|
||||
{
|
||||
if (DatePickerDialog->objectName().isEmpty())
|
||||
DatePickerDialog->setObjectName(QString::fromUtf8("DatePickerDialog"));
|
||||
DatePickerDialog->setWindowModality(Qt::WindowModal);
|
||||
DatePickerDialog->setAcceptDrops(false);
|
||||
DatePickerDialog->setModal(true);
|
||||
|
||||
QGridLayout *mainGrid = new QGridLayout(this); // a 2 x n grid
|
||||
lblOccur = new QLabel("When did this ride occur?", this);
|
||||
mainGrid->addWidget(lblOccur, 0,0);
|
||||
dateTimeEdit = new QDateTimeEdit(this);
|
||||
mainGrid->addWidget(dateTimeEdit,0,1);
|
||||
lblBrowse = new QLabel("Choose a CSV file to upload", this);
|
||||
mainGrid->addWidget(lblBrowse, 1,0);
|
||||
btnBrowse = new QPushButton(this);
|
||||
mainGrid->addWidget(btnBrowse,2,0);
|
||||
txtBrowse = new QLineEdit(this);
|
||||
mainGrid->addWidget(txtBrowse,2,1);
|
||||
|
||||
btnOK = new QPushButton(this);
|
||||
mainGrid->addWidget(btnOK, 3,0);
|
||||
btnCancel = new QPushButton(this);
|
||||
mainGrid->addWidget(btnCancel, 3,1);
|
||||
|
||||
DatePickerDialog->setWindowTitle(
|
||||
QApplication::translate("DatePickerDialog", "Choose a date", 0,
|
||||
QApplication::UnicodeUTF8));
|
||||
|
||||
btnBrowse->setText(
|
||||
QApplication::translate("DatePickerDialog", "File to import...", 0,
|
||||
QApplication::UnicodeUTF8));
|
||||
btnOK->setText(
|
||||
QApplication::translate("DatePickerDialog", "OK", 0,
|
||||
QApplication::UnicodeUTF8));
|
||||
btnCancel->setText(
|
||||
QApplication::translate("DatePickerDialog", "Cancel", 0,
|
||||
QApplication::UnicodeUTF8));
|
||||
|
||||
connect(btnOK, SIGNAL(clicked()), this, SLOT(on_btnOK_clicked()));
|
||||
connect(btnBrowse, SIGNAL(clicked()), this, SLOT(on_btnBrowse_clicked()));
|
||||
connect(btnCancel, SIGNAL(clicked()), this, SLOT(on_btnCancel_clicked()));
|
||||
|
||||
Q_UNUSED(DatePickerDialog);
|
||||
}
|
||||
|
||||
DatePickerDialog::DatePickerDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
}
|
||||
|
||||
void DatePickerDialog::on_btnOK_clicked()
|
||||
{
|
||||
canceled = false;
|
||||
date = dateTimeEdit->dateTime();
|
||||
accept();
|
||||
}
|
||||
|
||||
void DatePickerDialog::on_btnBrowse_clicked()
|
||||
{
|
||||
fileName = QFileDialog::getOpenFileName(
|
||||
this, tr("Import CSV"), QDir::homePath(),
|
||||
tr("Comma Seperated Values (*.csv)"));
|
||||
txtBrowse->setText(fileName);
|
||||
|
||||
}
|
||||
|
||||
void DatePickerDialog::on_btnCancel_clicked()
|
||||
{
|
||||
canceled = true;
|
||||
reject();
|
||||
}
|
||||
|
||||
41
src/gui/DatePickerDialog.h
Normal file
41
src/gui/DatePickerDialog.h
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// C++ Interface: DatePickerDialog
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
//
|
||||
// Author: Justin F. Knotzke <jknotzke@shampoo.ca>, (C) 2007
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include <QDateTime>
|
||||
#include <QtGui>
|
||||
|
||||
class DatePickerDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DatePickerDialog(QWidget *parent = 0);
|
||||
QString fileName;
|
||||
QDateTime date;
|
||||
bool canceled;
|
||||
QString currentText;
|
||||
QLabel *lblOccur;
|
||||
QDateTimeEdit *dateTimeEdit;
|
||||
QHBoxLayout *hboxLayout1;
|
||||
QLabel *lblImport;
|
||||
QLabel *lblBrowse;
|
||||
QPushButton *btnBrowse;
|
||||
QLineEdit *txtBrowse;
|
||||
QPushButton *btnOK;
|
||||
QPushButton *btnCancel;
|
||||
void setupUi(QDialog*);
|
||||
|
||||
private slots:
|
||||
void on_btnOK_clicked();
|
||||
void on_btnBrowse_clicked();
|
||||
void on_btnCancel_clicked();
|
||||
};
|
||||
|
||||
@@ -20,6 +20,8 @@ HEADERS += \
|
||||
AllPlot.h \
|
||||
ChooseCyclistDialog.h \
|
||||
CpintPlot.h \
|
||||
CsvData.h \
|
||||
DatePickerDialog.h \
|
||||
DownloadRideDialog.h \
|
||||
LogTimeScaleDraw.h \
|
||||
LogTimeScaleEngine.h \
|
||||
@@ -34,6 +36,8 @@ SOURCES += \
|
||||
AllPlot.cpp \
|
||||
ChooseCyclistDialog.cpp \
|
||||
CpintPlot.cpp \
|
||||
CsvData.cpp \
|
||||
DatePickerDialog.cpp \
|
||||
DownloadRideDialog.cpp \
|
||||
LogTimeScaleDraw.cpp \
|
||||
LogTimeScaleEngine.cpp \
|
||||
|
||||
@@ -39,11 +39,14 @@
|
||||
#include <qwt_plot_zoomer.h>
|
||||
#include <qwt_data.h>
|
||||
|
||||
#include "DatePickerDialog.h"
|
||||
|
||||
|
||||
#define FOLDER_TYPE 0
|
||||
#define RIDE_TYPE 1
|
||||
|
||||
static char *rideFileRegExp = ("^(\\d\\d\\d\\d)_(\\d\\d)_(\\d\\d)"
|
||||
"_(\\d\\d)_(\\d\\d)_(\\d\\d)\\.(raw|srm)$");
|
||||
"_(\\d\\d)_(\\d\\d)_(\\d\\d)\\.(raw|srm|csv)$");
|
||||
|
||||
QString
|
||||
MainWindow::notesFileName(QString rideFileName) {
|
||||
@@ -51,6 +54,8 @@ MainWindow::notesFileName(QString rideFileName) {
|
||||
return rideFileName.left(rideFileName.length() - 4) + ".notes";
|
||||
else if (rideFileName.endsWith(".srm"))
|
||||
return rideFileName.left(rideFileName.length() - 4) + ".notes";
|
||||
else if ( rideFileName.endsWith (".csv"))
|
||||
return rideFileName.left ( rideFileName.length() - 4) + ".notes";
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
@@ -96,7 +101,7 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
|
||||
QRegExp rx(rideFileRegExp);
|
||||
QStringList filters;
|
||||
filters << "*.raw" << "*.srm";
|
||||
filters << "*.raw" << "*.srm"<<"*.csv";
|
||||
QTreeWidgetItem *last = NULL;
|
||||
QStringListIterator i(home.entryList(filters, QDir::Files));
|
||||
while (i.hasNext()) {
|
||||
@@ -328,6 +333,8 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
SLOT(exportCSV()), tr("Ctrl+E"));
|
||||
rideMenu->addAction(tr("&Import from SRM..."), this,
|
||||
SLOT(importSRM()), tr("Ctrl+I"));
|
||||
rideMenu->addAction ( tr ( "&Import from CSV..." ), this,
|
||||
SLOT (importCSV()), tr ("Ctrl+S"));
|
||||
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||
helpMenu->addAction(tr("&About GoldenCheetah"), this, SLOT(aboutDialog()));
|
||||
@@ -465,6 +472,62 @@ MainWindow::exportCSV()
|
||||
file.close();
|
||||
}
|
||||
|
||||
void MainWindow::importCSV()
|
||||
{
|
||||
// Ask the user if they prefer to export with English or metric units.
|
||||
DatePickerDialog *dpd = new DatePickerDialog(this);
|
||||
dpd->exec();
|
||||
|
||||
if(dpd->canceled == true)
|
||||
return;
|
||||
|
||||
QFile file ( dpd->fileName );
|
||||
QStringList errors;
|
||||
RawFile *raw = RawFile::readFile ( file, errors );
|
||||
|
||||
raw->startTime = dpd->date;
|
||||
|
||||
if ( !raw || !errors.empty() )
|
||||
{
|
||||
QString all =
|
||||
( raw
|
||||
? tr ( "Non-fatal problem(s) opening %1:" )
|
||||
: tr ( "Fatal problem(s) opening %1:" ) ).arg ( dpd->fileName );
|
||||
QStringListIterator i ( errors );
|
||||
while ( i.hasNext() )
|
||||
all += "\n" + i.next();
|
||||
if ( raw )
|
||||
QMessageBox::warning ( this, tr ( "Open Warning" ), all );
|
||||
else
|
||||
{
|
||||
QMessageBox::critical ( this, tr ( "Open Error" ), all );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QChar zero = QLatin1Char ( '0' );
|
||||
|
||||
QString name = QString ( "%1_%2_%3_%4_%5_%6.csv" )
|
||||
.arg ( raw->startTime.date().year(), 4, 10, zero )
|
||||
.arg ( raw->startTime.date().month(), 2, 10, zero )
|
||||
.arg ( raw->startTime.date().day(), 2, 10, zero )
|
||||
.arg ( raw->startTime.time().hour(), 2, 10, zero )
|
||||
.arg ( raw->startTime.time().minute(), 2, 10, zero )
|
||||
.arg ( raw->startTime.time().second(), 2, 10, zero );
|
||||
|
||||
if ( !file.copy ( home.absolutePath() + "/" + name ) )
|
||||
{
|
||||
QMessageBox::critical ( this, tr ( "Copy Error" ),
|
||||
tr ( "Couldn't copy %1" )
|
||||
.arg ( dpd->fileName ) );
|
||||
return;
|
||||
}
|
||||
|
||||
delete raw;
|
||||
delete dpd;
|
||||
addRide ( name );
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::importSRM()
|
||||
{
|
||||
|
||||
@@ -52,6 +52,7 @@ class MainWindow : public QMainWindow
|
||||
void openCyclist();
|
||||
void downloadRide();
|
||||
void exportCSV();
|
||||
void importCSV();
|
||||
void importSRM();
|
||||
void setSmoothingFromSlider();
|
||||
void setSmoothingFromLineEdit();
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <assert.h>
|
||||
#include <QMessageBox>
|
||||
#include "srm.h"
|
||||
#include "CsvData.h"
|
||||
|
||||
extern "C" {
|
||||
#include "pt.h"
|
||||
@@ -121,6 +122,16 @@ RawFile *RawFile::readFile(QFile &file, QStringList &errors)
|
||||
result->points.append(p2);
|
||||
}
|
||||
}
|
||||
else if (file.fileName().indexOf(".csv") == file.fileName().size() - 4)
|
||||
{
|
||||
CsvData data;
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
errors << QString("can't open file %1").arg(file.fileName());
|
||||
return false;
|
||||
}
|
||||
|
||||
data.readCsvFile(file, result);
|
||||
}
|
||||
else {
|
||||
if (!result->file.open(QIODevice::ReadOnly)) {
|
||||
delete result;
|
||||
|
||||
Reference in New Issue
Block a user