Honour RideFile::startTime

When saving the value of startTime should be checked to see
if the filename/notes need to be renamed. In addition, RideItem
now allows the startTime to be modified and reflected in the
ride list. When importing .gc ridefiles the file is serialized
with the correct startTime if the user edited it during import.
This commit is contained in:
Mark Liversedge
2010-03-22 17:15:05 +00:00
committed by Sean Rhea
parent 02a60735f0
commit 4e7e6cfb3a
8 changed files with 144 additions and 42 deletions

View File

@@ -199,7 +199,7 @@ MainWindow::MainWindow(const QDir &home) :
QDateTime dt;
if (parseRideFileName(name, &notesFileName, &dt)) {
last = new RideItem(RIDE_TYPE, home.path(),
name, dt, zones(), notesFileName);
name, dt, zones(), notesFileName, this);
allRides->addChild(last);
calendar->update();
}
@@ -481,7 +481,7 @@ MainWindow::addRide(QString name, bool bSelect /*=true*/)
assert(false);
}
RideItem *last = new RideItem(RIDE_TYPE, home.path(),
name, dt, zones(), notesFileName);
name, dt, zones(), notesFileName, this);
QVariant isAscending = settings->value(GC_ALLRIDES_ASCENDING,Qt::Checked); // default is ascending sort
int index = 0;
@@ -1314,3 +1314,11 @@ MainWindow::notifyConfigChanged()
{
configChanged();
}
// notify children that rideSelected
// called by RideItem when its date/time changes
void
MainWindow::notifyRideSelected()
{
rideSelected();
}

View File

@@ -78,6 +78,8 @@ class MainWindow : public QMainWindow
void notifyConfigChanged(); // used by ConfigDialog to notify MainWindow
// when config has changed - and to get a
// signal emitted to notify its children
void notifyRideSelected(); // used by RideItem to notify when
// rideItem date/time changes
void selectView(int);
protected:

View File

@@ -142,7 +142,7 @@ RideFile *ManualFileReader::openRideFile(QFile &file, QStringList &errors) const
rideFile->setRecIntSecs(rideSec);
QRegExp rideTime("^.*/(\\d\\d\\d\\d)_(\\d\\d)_(\\d\\d)_"
"(\\d\\d)_(\\d\\d)_(\\d\\d)\\.csv$");
"(\\d\\d)_(\\d\\d)_(\\d\\d)\\.man$");
if (rideTime.indexIn(file.fileName()) >= 0) {
QDateTime datetime(QDate(rideTime.cap(1).toInt(),
rideTime.cap(2).toInt(),

View File

@@ -78,12 +78,12 @@ void RideCalendar::paintCell(QPainter *painter, const QRect &rect, const QDate &
RideIter i;
if (ascending) {
RideItemDateLessThan comp;
RideItem search(0, "", "", QDateTime(date), NULL, "");
RideItem search(0, "", "", QDateTime(date), NULL, "", NULL);
i = std::lower_bound(begin, end, &search, comp);
}
else {
RideItemDateGreaterThan comp;
RideItem search(0, "", "", QDateTime(date.addDays(1)), NULL, "");
RideItem search(0, "", "", QDateTime(date.addDays(1)), NULL, "", NULL);
i = std::upper_bound(begin, end, &search, comp);
}

View File

@@ -26,6 +26,7 @@
#include <QWaitCondition>
#include "Settings.h"
#include "Units.h"
#include "GcRideFile.h"
// drag and drop passes urls ... convert to a list of files and call main constructor
@@ -354,8 +355,8 @@ RideImportWizard::process()
if (t->text().startsWith(tr("Error"))) continue;
// date needed?
if (blanks[i]) {
needdates++;
if (blanks[i] || filenames[i].endsWith(".gc", Qt::CaseInsensitive)) { // but we can override gc ride files
if (blanks[i]) needdates++; // count the blanks tho
t = tableWidget->item(i,1);
t->setFlags(t->flags() | (Qt::ItemIsEditable)); // make editable ONLY if not present -
// we cannot override the RideFileReader
@@ -642,43 +643,83 @@ RideImportWizard::abortClicked()
.arg ( targetnosuffix )
.arg ( suffix );
QString fulltarget = home.absolutePath() + "/" + target;
// so now we have sourcefile in 'filenames[i]' and target file name in 'target'
if (!fulltarget.compare(filenames[i])) { // they are the same file! so skip copy
tableWidget->item(i,5)->setText(tr("Error - Source is Target"));
} else if (QFileInfo(fulltarget).exists()) {
if (overwriteFiles) {
tableWidget->item(i,5)->setText(tr("Overwriting file..."));
QFile source(filenames[i]);
QString fulltargettmp(home.absolutePath() + tr("/") + targetnosuffix + tr(".tmp"));
if (source.copy(fulltargettmp)) {
// tmp version saved now zap original
QFile original(fulltarget);
original.remove(); // zap!
// mv tmp to target
QFile temp(fulltargettmp);
if (temp.rename(fulltarget)) {
tableWidget->item(i,5)->setText(tr("File Overwritten"));
//no need to add since its already there!
} else
tableWidget->item(i,5)->setText(tr("Error - overwrite failed"));
// if its a gc file we need to parse and serialize
// using the ridedatetime and target filename
if (filenames[i].endsWith(".gc", Qt::CaseInsensitive)) {
bool existed;
if ((existed=QFileInfo(fulltarget).exists()) && !overwriteFiles) {
tableWidget->item(i,5)->setText(tr("Error - File exists"));
} else {
// read the file (again)
QStringList errors;
QFile thisfile(filenames[i]);
RideFile *ride(RideFileFactory::instance().openRideFile(thisfile, errors));
// update ridedatetime
ride->setStartTime(ridedatetime);
// serialize
GcFileReader reader;
QFile target(fulltarget);
reader.writeRideFile(ride, target);
// clear
delete ride;
if (existed) {
tableWidget->item(i,5)->setText(tr("File Overwritten"));
} else {
tableWidget->item(i,5)->setText(tr("Error - overwrite failed"));
tableWidget->item(i,5)->setText(tr("File Saved"));
mainWindow->addRide(QFileInfo(fulltarget).fileName(), true);
}
}
} else {
// for native file formats the filename IS the ride date time so
// no need to write -- we just copy
// so now we have sourcefile in 'filenames[i]' and target file name in 'target'
if (!fulltarget.compare(filenames[i])) { // they are the same file! so skip copy
tableWidget->item(i,5)->setText(tr("Error - Source is Target"));
} else if (QFileInfo(fulltarget).exists()) {
if (overwriteFiles) {
tableWidget->item(i,5)->setText(tr("Overwriting file..."));
QFile source(filenames[i]);
QString fulltargettmp(home.absolutePath() + tr("/") + targetnosuffix + tr(".tmp"));
if (source.copy(fulltargettmp)) {
// tmp version saved now zap original
QFile original(fulltarget);
original.remove(); // zap!
// mv tmp to target
QFile temp(fulltargettmp);
if (temp.rename(fulltarget)) {
tableWidget->item(i,5)->setText(tr("File Overwritten"));
//no need to add since its already there!
} else
tableWidget->item(i,5)->setText(tr("Error - overwrite failed"));
} else {
tableWidget->item(i,5)->setText(tr("Error - overwrite failed"));
}
} else {
tableWidget->item(i,5)->setText(tr("Error - File exists"));
}
} else {
tableWidget->item(i,5)->setText(tr("Error - File exists"));
tableWidget->item(i,5)->setText(tr("Saving file..."));
QFile source(filenames[i]);
if (source.copy(fulltarget)) {
tableWidget->item(i,5)->setText(tr("File Saved"));
mainWindow->addRide(QFileInfo(fulltarget).fileName(), true); // add to tree view
// free immediately otherwise all imported rides are cached
// and with large imports this can lead to memory exhaustion
mainWindow->rideItem()->freeMemory();
} else
tableWidget->item(i,5)->setText(tr("Error - copy failed"));
}
} else {
tableWidget->item(i,5)->setText(tr("Saving file..."));
QFile source(filenames[i]);
if (source.copy(fulltarget)) {
tableWidget->item(i,5)->setText(tr("File Saved"));
mainWindow->addRide(QFileInfo(fulltarget).fileName(), true); // add to tree view
// free immediately otherwise all imported rides are cached
// and with large imports this can lead to memory exhaustion
mainWindow->rideItem()->freeMemory();
} else
tableWidget->item(i,5)->setText(tr("Error - copy failed"));
}
QApplication::processEvents();
if (aborted) { done(0); }

View File

@@ -19,14 +19,15 @@
#include "RideItem.h"
#include "RideMetric.h"
#include "RideFile.h"
#include "MainWindow.h"
#include "Zones.h"
#include <assert.h>
#include <math.h>
RideItem::RideItem(int type,
QString path, QString fileName, const QDateTime &dateTime,
const Zones *zones, QString notesFileName) :
QTreeWidgetItem(type), ride_(NULL), isdirty(false), path(path), fileName(fileName),
const Zones *zones, QString notesFileName, MainWindow *main) :
QTreeWidgetItem(type), ride_(NULL), main(main), isdirty(false), path(path), fileName(fileName),
dateTime(dateTime), zones(zones), notesFileName(notesFileName)
{
setText(0, dateTime.toString("ddd"));
@@ -146,3 +147,14 @@ RideItem::computeMetrics()
metrics = RideMetric::computeMetrics(ride(), zones, allMetrics);
}
void
RideItem::setStartTime(QDateTime newDateTime)
{
dateTime = newDateTime;
setText(0, dateTime.toString("ddd"));
setText(1, dateTime.toString("MMM d, yyyy"));
setText(2, dateTime.toString("h:mm AP"));
ride()->setStartTime(newDateTime);
main->notifyRideSelected();
}

View File

@@ -23,6 +23,7 @@
#include "RideMetric.h"
class RideFile;
class MainWindow;
class Zones;
class RideItem : public QTreeWidgetItem {
@@ -32,6 +33,7 @@ class RideItem : public QTreeWidgetItem {
QVector<double> time_in_zone;
RideFile *ride_;
QStringList errors_;
MainWindow *main; // to notify widgets when date/time changes
bool isdirty;
public:
@@ -49,11 +51,12 @@ class RideItem : public QTreeWidgetItem {
RideItem(int type, QString path,
QString fileName, const QDateTime &dateTime,
const Zones *zones, QString notesFileName);
const Zones *zones, QString notesFileName, MainWindow *main);
void setDirty(bool);
bool isDirty() { return isdirty; }
void setFileName(QString, QString);
void setStartTime(QDateTime);
void computeMetrics();
void freeMemory();

View File

@@ -131,6 +131,42 @@ MainWindow::saveSilent(RideItem *rideItem)
if (currentType != "GC") convert = true;
else convert = false;
// Has the date/time changed?
QDateTime ridedatetime = rideItem->ride()->startTime();
QChar zero = QLatin1Char ( '0' );
QString targetnosuffix = QString ( "%1_%2_%3_%4_%5_%6" )
.arg ( ridedatetime.date().year(), 4, 10, zero )
.arg ( ridedatetime.date().month(), 2, 10, zero )
.arg ( ridedatetime.date().day(), 2, 10, zero )
.arg ( ridedatetime.time().hour(), 2, 10, zero )
.arg ( ridedatetime.time().minute(), 2, 10, zero )
.arg ( ridedatetime.time().second(), 2, 10, zero );
// When datetime changes we need to update
// the filename & rename/delete old file
// we also need to preserve the notes file
if (currentFI.baseName() != targetnosuffix) {
// if there is a notes file we need to rename it (cpi we will ignore)
QFile notesFile(currentFI.path() + QDir::separator() + currentFI.baseName() + ".notes");
if (notesFile.exists())
notesFile.rename(notesFile.fileName(),
rideItem->path + QDir::separator() + targetnosuffix + ".notes");
// we also need to update the path to the notes filename
ride->notesFileName = targetnosuffix + ".notes";
// rename as backup current if converting, or just delete it if its already .gc
if (convert) currentFile.rename(currentFile.fileName(), currentFile.fileName() + ".sav");
else currentFile.remove();
convert = false; // we just did it already!
// set the new filename & Start time everywhere
currentFile.setFileName(rideItem->path + QDir::separator() + targetnosuffix + ".gc");
rideItem->setFileName(QFileInfo(currentFile).path(), QFileInfo(currentFile).fileName());
}
// set target filename
if (convert) {
// rename the source