From 4e7e6cfb3a74f4e34b95c61460ebdf4b2fa830a9 Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Mon, 22 Mar 2010 17:15:05 +0000 Subject: [PATCH] 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. --- src/MainWindow.cpp | 12 ++++- src/MainWindow.h | 2 + src/ManualRideFile.cpp | 2 +- src/RideCalendar.cpp | 4 +- src/RideImportWizard.cpp | 109 +++++++++++++++++++++++++++------------ src/RideItem.cpp | 16 +++++- src/RideItem.h | 5 +- src/SaveDialogs.cpp | 36 +++++++++++++ 8 files changed, 144 insertions(+), 42 deletions(-) diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 5361c0f0d..314d09170 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -199,7 +199,7 @@ MainWindow::MainWindow(const QDir &home) : QDateTime dt; if (parseRideFileName(name, ¬esFileName, &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(); +} diff --git a/src/MainWindow.h b/src/MainWindow.h index 0acad2920..965409511 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -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: diff --git a/src/ManualRideFile.cpp b/src/ManualRideFile.cpp index 690870801..4361973fd 100644 --- a/src/ManualRideFile.cpp +++ b/src/ManualRideFile.cpp @@ -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(), diff --git a/src/RideCalendar.cpp b/src/RideCalendar.cpp index c2ca7832b..76622b831 100644 --- a/src/RideCalendar.cpp +++ b/src/RideCalendar.cpp @@ -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); } diff --git a/src/RideImportWizard.cpp b/src/RideImportWizard.cpp index af99ca00b..29baf50de 100644 --- a/src/RideImportWizard.cpp +++ b/src/RideImportWizard.cpp @@ -26,6 +26,7 @@ #include #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); } diff --git a/src/RideItem.cpp b/src/RideItem.cpp index 156cae687..4a7584517 100644 --- a/src/RideItem.cpp +++ b/src/RideItem.cpp @@ -19,14 +19,15 @@ #include "RideItem.h" #include "RideMetric.h" #include "RideFile.h" +#include "MainWindow.h" #include "Zones.h" #include #include 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(); +} diff --git a/src/RideItem.h b/src/RideItem.h index dc85e210e..578ce3157 100644 --- a/src/RideItem.h +++ b/src/RideItem.h @@ -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 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(); diff --git a/src/SaveDialogs.cpp b/src/SaveDialogs.cpp index fd484d832..3f614488f 100644 --- a/src/SaveDialogs.cpp +++ b/src/SaveDialogs.cpp @@ -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