mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
Added RideCache
.. source files missed off last commit
This commit is contained in:
211
src/RideCache.cpp
Normal file
211
src/RideCache.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Mark Liversedge (liversedge@gmail.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 "RideCache.h"
|
||||
|
||||
#include "Context.h"
|
||||
#include "Athlete.h"
|
||||
#include "Route.h"
|
||||
#include "RouteWindow.h"
|
||||
|
||||
RideCache::RideCache(Context *context) : context(context)
|
||||
{
|
||||
// set the list
|
||||
// populate ride list
|
||||
RideItem *last = NULL;
|
||||
QStringListIterator i(RideFileFactory::instance().listRideFiles(context->athlete->home->activities()));
|
||||
while (i.hasNext()) {
|
||||
QString name = i.next();
|
||||
QDateTime dt;
|
||||
if (RideFile::parseRideFileName(name, &dt)) {
|
||||
last = new RideItem(context->athlete->home->activities().canonicalPath(), name, dt, context);
|
||||
rides_ << last;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// load the store - will unstale once cache restored
|
||||
load();
|
||||
|
||||
// do we have any stale items ?
|
||||
refresh();
|
||||
}
|
||||
|
||||
RideCache::~RideCache()
|
||||
{
|
||||
// save to store
|
||||
save();
|
||||
}
|
||||
|
||||
// add a new ride
|
||||
void
|
||||
RideCache::addRide(QString name, bool dosignal)
|
||||
{
|
||||
// ignore malformed names
|
||||
QDateTime dt;
|
||||
if (!RideFile::parseRideFileName(name, &dt)) return;
|
||||
|
||||
// new ride item
|
||||
RideItem *last = new RideItem(context->athlete->home->activities().canonicalPath(), name, dt, context);
|
||||
|
||||
// now add to the list, or replace if already there
|
||||
bool added = false;
|
||||
for (int index=0; index < rides_.count(); index++) {
|
||||
if (rides_[index]->fileName == last->fileName) {
|
||||
rides_[index] = last;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!added) rides_ << last;
|
||||
qSort(rides_); // sort by date
|
||||
|
||||
// refresh metrics for *this ride only*
|
||||
// XXX not implemented yet XXX
|
||||
|
||||
if (dosignal) context->notifyRideAdded(last); // here so emitted BEFORE rideSelected is emitted!
|
||||
|
||||
//Search routes
|
||||
context->athlete->routes->searchRoutesInRide(last->ride());
|
||||
|
||||
// notify everyone to select it
|
||||
context->ride = last;
|
||||
context->notifyRideSelected(last);
|
||||
}
|
||||
|
||||
void
|
||||
RideCache::removeCurrentRide()
|
||||
{
|
||||
if (context->ride == NULL) return;
|
||||
|
||||
RideItem *select = NULL; // ride to select once its gone
|
||||
RideItem *todelete = context->ride;
|
||||
|
||||
bool found = false;
|
||||
int index=0; // index to wipe out
|
||||
|
||||
// find ours in the list and select the one
|
||||
// immediately after it, but if it is the last
|
||||
// one on the list select the one before
|
||||
for(index=0; index < rides_.count(); index++) {
|
||||
|
||||
if (rides_[index]->fileName == context->ride->fileName) {
|
||||
|
||||
// bingo!
|
||||
found = true;
|
||||
if (rides_.count()-index > 1) select = rides_[index+1];
|
||||
else if (index > 0) select = rides_[index-1];
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// WTAF!?
|
||||
if (!found) {
|
||||
qDebug()<<"ERROR: delete not found.";
|
||||
return;
|
||||
}
|
||||
|
||||
// remove from the cache, before deleting it this is so
|
||||
// any aggregating functions no longer see it, when recalculating
|
||||
// during aride deleted operation
|
||||
rides_.remove(index, 1);
|
||||
|
||||
// delete the file by renaming it
|
||||
QString strOldFileName = context->ride->fileName;
|
||||
|
||||
QFile file(context->athlete->home->activities().canonicalPath() + "/" + 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";
|
||||
|
||||
// in case there was an existing bak file, delete it
|
||||
// ignore errors since it probably isn't there.
|
||||
QFile::remove(context->athlete->home->activities().canonicalPath() + "/" + strNewName);
|
||||
|
||||
if (!file.rename(context->athlete->home->activities().canonicalPath() + "/" + strNewName)) {
|
||||
QMessageBox::critical(NULL, "Rename Error", tr("Can't rename %1 to %2")
|
||||
.arg(strOldFileName).arg(strNewName));
|
||||
}
|
||||
|
||||
// remove any other derived/additional files; notes, cpi etc
|
||||
QStringList extras;
|
||||
extras << "notes" << "cpi" << "cpx";
|
||||
foreach (QString extension, extras) {
|
||||
|
||||
QString deleteMe = QFileInfo(strOldFileName).baseName() + "." + extension;
|
||||
QFile::remove(context->athlete->home->activities().canonicalPath() + "/" + deleteMe);
|
||||
}
|
||||
|
||||
// rename also the source files either in /imports or in /downloads to allow a second round of import
|
||||
QString sourceFilename = todelete->ride()->getTag("Source Filename", "");
|
||||
if (sourceFilename != "") {
|
||||
// try to rename in both directories /imports and /downloads
|
||||
// but don't report any errors - files may have been backup already
|
||||
QFile old1 (context->athlete->home->imports().canonicalPath() + "/" + sourceFilename);
|
||||
old1.rename(context->athlete->home->imports().canonicalPath() + "/" + sourceFilename + ".bak");
|
||||
QFile old2 (context->athlete->home->downloads().canonicalPath() + "/" + sourceFilename);
|
||||
old2.rename(context->athlete->home->downloads().canonicalPath() + "/" + sourceFilename + ".bak");
|
||||
}
|
||||
|
||||
// we don't want the whole delete, select next flicker
|
||||
context->mainWindow->setUpdatesEnabled(false);
|
||||
|
||||
// select a different ride
|
||||
context->ride = select;
|
||||
|
||||
// notify AFTER deleted from DISK..
|
||||
context->notifyRideDeleted(todelete);
|
||||
|
||||
// ..but before MEMORY cleared
|
||||
todelete->freeMemory();
|
||||
delete todelete;
|
||||
|
||||
// now we can update
|
||||
context->mainWindow->setUpdatesEnabled(true);
|
||||
QApplication::processEvents();
|
||||
|
||||
// now select another ride
|
||||
context->notifyRideSelected(select);
|
||||
}
|
||||
|
||||
// work with "rideDB.json" XXX not implemented yet
|
||||
void RideCache::load() {}
|
||||
void RideCache::save() {}
|
||||
|
||||
// refresh the metrics XXX not implemented yet
|
||||
void
|
||||
RideCache::refresh()
|
||||
{
|
||||
if (isRunning()) return;
|
||||
else {
|
||||
|
||||
bool stale = false;
|
||||
foreach(RideItem *item, rides_) {
|
||||
if (item->isstale) {
|
||||
stale = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stale) start();
|
||||
}
|
||||
}
|
||||
|
||||
void RideCache::run()
|
||||
{
|
||||
//XXX not implemented but where metrics and meta get refreshed.
|
||||
}
|
||||
64
src/RideCache.h
Normal file
64
src/RideCache.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Mark Liversedge (liversedge@gmail.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 _GC_RideCache_h
|
||||
#define _GC_RideCache_h 1
|
||||
|
||||
#include "GoldenCheetah.h"
|
||||
#include "MainWindow.h"
|
||||
#include "RideFile.h"
|
||||
#include "RideItem.h"
|
||||
|
||||
#include <QVector>
|
||||
#include <QThread>
|
||||
|
||||
class Context;
|
||||
|
||||
class RideCache : public QThread
|
||||
{
|
||||
public:
|
||||
|
||||
RideCache(Context *context);
|
||||
~RideCache();
|
||||
|
||||
// the ride list
|
||||
QVector<RideItem*>&rides() { return rides_; }
|
||||
|
||||
// add/remove a ride to the list
|
||||
void addRide(QString name, bool dosignal);
|
||||
void removeCurrentRide();
|
||||
|
||||
// restore / dump cache to disk (json)
|
||||
void load();
|
||||
void save();
|
||||
|
||||
// the background refresher !
|
||||
void refresh(); // calls start() and doesn't wait
|
||||
|
||||
// the thread code that gets run to refresh
|
||||
void run();
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
Context *context;
|
||||
QVector<RideItem*> rides_;
|
||||
};
|
||||
|
||||
#endif // _GC_RideCache_h
|
||||
Reference in New Issue
Block a user