mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
Deprecate TrainingPeaks
.. from December 7th 2016 read access (for downloading from TrainingPeaks) has been revoked, even for paid up members. .. write access (upload) is not revoked. .. This is essentially anti-competitive behaviour and returns TrainingPeaks and their products, once again to that of a 'closed' product. .. We will no longer support their service since we cannot and will not promote such behaviours now or ever. .. We are now considering the best way to purge all other references to their trademarks and remove any indication that their products are endorsed.
This commit is contained in:
246
deprecated/TPDownload.cpp
Normal file
246
deprecated/TPDownload.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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 "TPDownload.h"
|
||||
#include <QString>
|
||||
#include "Settings.h"
|
||||
#include "RideFile.h"
|
||||
#include "PwxRideFile.h"
|
||||
#include <QtXml>
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QLocale>
|
||||
|
||||
static const QString tptypestrings[]= {
|
||||
"SharedFree", "CoachedFree", "SelfCoachedPremium",
|
||||
"SharedSelfCoachedPremium", "CoachedPremium", "SharedCoachedPremium"
|
||||
};
|
||||
//
|
||||
// Get athletes available for download
|
||||
//
|
||||
TPAthlete::TPAthlete(QObject *parent) : QObject(parent), http(this), waiting(false)
|
||||
{
|
||||
connect(&http, SIGNAL(responseReady(const QtSoapMessage &)),
|
||||
this, SLOT(getResponse(const QtSoapMessage &)));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TPAthlete::list(int type, QString user, QString pass)
|
||||
{
|
||||
// if currently downloading fail!
|
||||
if (waiting == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
// setup the soap message
|
||||
http.setHost("www.trainingpeaks.com", true);
|
||||
http.setAction("http://www.trainingpeaks.com/TPWebServices/GetAccessibleAthletes");
|
||||
current.setMethod("GetAccessibleAthletes", "http://www.trainingpeaks.com/TPWebServices/");
|
||||
current.addMethodArgument("username", "", user);
|
||||
current.addMethodArgument("password", "", pass);
|
||||
current.addMethodArgument("types", "",
|
||||
tptypestrings[type].toLatin1().constData());
|
||||
|
||||
// do it!
|
||||
waiting = true;
|
||||
http.submitRequest(current, "/tpwebservices/service.asmx");
|
||||
}
|
||||
|
||||
void TPAthlete::getResponse(const QtSoapMessage &message)
|
||||
{
|
||||
waiting = false;
|
||||
QString resultStr;
|
||||
QList< QMap<QString, QString> > athletelist;
|
||||
|
||||
if (message.isFault()) {
|
||||
resultStr = tr("Error:") + qPrintable(message.faultString().toString());
|
||||
}
|
||||
else {
|
||||
const QtSoapType &response = message.returnValue();
|
||||
|
||||
if (response.isValid()) {
|
||||
|
||||
// lets take look at the payload as a DomDocument
|
||||
// I tried to use the QtSoapType routines to walk
|
||||
// through the response tree but couldn't get them
|
||||
// to work. This code could be simplified if we
|
||||
// use the QtSoap routines instead.
|
||||
QDomDocument doc;
|
||||
QDomElement results = response.toDomElement(doc);
|
||||
QMap<QString, QString> athlete;
|
||||
|
||||
for (QDomElement personbase = results.firstChildElement("PersonBase");
|
||||
!personbase.isNull();
|
||||
personbase = personbase.nextSiblingElement()) {
|
||||
|
||||
athlete.clear();
|
||||
|
||||
// shove all the personbase attribs into a QMap
|
||||
for (QDomNode child = personbase.firstChild();
|
||||
!child.isNull();
|
||||
child = child.nextSibling()) {
|
||||
|
||||
athlete.insert(child.nodeName(), child.toElement().text());
|
||||
}
|
||||
athletelist << athlete;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return what we got (empty if non-valid response)
|
||||
completed(resultStr, athletelist);
|
||||
}
|
||||
|
||||
//
|
||||
// List workouts
|
||||
//
|
||||
TPWorkout::TPWorkout(QObject *parent) : QObject(parent), http(this), waiting(false)
|
||||
{
|
||||
connect(&http, SIGNAL(responseReady(const QtSoapMessage &)),
|
||||
this, SLOT(getResponse(const QtSoapMessage &)));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TPWorkout::list(int id, QDate from, QDate to, QString user, QString pass)
|
||||
{
|
||||
// if currently downloading fail!
|
||||
if (waiting == true) return;
|
||||
|
||||
current = QtSoapMessage(); // reset
|
||||
|
||||
// setup the soap message
|
||||
http.setHost("www.trainingpeaks.com", true);
|
||||
http.setAction("http://www.trainingpeaks.com/TPWebServices/GetWorkoutsForAccessibleAthlete");
|
||||
current.setMethod("GetWorkoutsForAccessibleAthlete", "http://www.trainingpeaks.com/TPWebServices/");
|
||||
current.addMethodArgument("username", "", user);
|
||||
current.addMethodArgument("password", "", pass);
|
||||
current.addMethodArgument("personId", "", QString("%1").arg(id).toLatin1().constData());
|
||||
current.addMethodArgument("startDate", "", from.toString("yyyy-MM-dd").toLatin1().constData());
|
||||
current.addMethodArgument("endDate", "", to.toString("yyyy-MM-dd").toLatin1().constData());
|
||||
|
||||
// do it!
|
||||
waiting = true;
|
||||
http.submitRequest(current, "/tpwebservices/service.asmx");
|
||||
}
|
||||
|
||||
void TPWorkout::getResponse(const QtSoapMessage &message)
|
||||
{
|
||||
waiting = false;
|
||||
QList< QMap<QString, QString> > workoutlist;
|
||||
|
||||
if (!message.isFault()) {
|
||||
const QtSoapType &response = message.returnValue();
|
||||
|
||||
if (response.isValid()) {
|
||||
|
||||
// lets take look at the payload as a DomDocument
|
||||
// I tried to use the QtSoapType routines to walk
|
||||
// through the response tree but couldn't get them
|
||||
// to work. This code could be simplified if we
|
||||
// use the QtSoap routines instead.
|
||||
QDomDocument doc;
|
||||
QDomElement results = response.toDomElement(doc);
|
||||
QMap<QString, QString> athlete;
|
||||
|
||||
for (QDomElement personbase = results.firstChildElement("Workout");
|
||||
!personbase.isNull();
|
||||
personbase = personbase.nextSiblingElement()) {
|
||||
|
||||
athlete.clear();
|
||||
|
||||
// shove all the personbase attribs into a QMap
|
||||
for (QDomNode child = personbase.firstChild();
|
||||
!child.isNull();
|
||||
child = child.nextSibling()) {
|
||||
|
||||
athlete.insert(child.nodeName(), child.toElement().text());
|
||||
}
|
||||
workoutlist << athlete;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return what we got (empty if failed)
|
||||
completed(workoutlist);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Workout download
|
||||
//
|
||||
TPDownload::TPDownload(QObject *parent) : QObject(parent), http(this), downloading(false)
|
||||
{
|
||||
connect(&http, SIGNAL(responseReady(const QtSoapMessage &)),
|
||||
this, SLOT(getResponse(const QtSoapMessage &)));
|
||||
}
|
||||
|
||||
void
|
||||
TPDownload::download(QString cyclist, int personId, int workoutId)
|
||||
{
|
||||
// if currently downloading fail!
|
||||
if (downloading == true) return;
|
||||
|
||||
current = QtSoapMessage();
|
||||
|
||||
// setup the soap message
|
||||
http.setHost("www.trainingpeaks.com", true);
|
||||
http.setAction("http://www.trainingpeaks.com/TPWebServices/GetExtendedWorkoutsForAccessibleAthlete");
|
||||
current.setMethod("GetExtendedWorkoutsForAccessibleAthlete", "http://www.trainingpeaks.com/TPWebServices/");
|
||||
current.addMethodArgument("username", "", appsettings->cvalue(cyclist, GC_TPUSER).toString());
|
||||
current.addMethodArgument("password", "", appsettings->cvalue(cyclist, GC_TPPASS).toString());
|
||||
current.addMethodArgument("personId", "", personId);
|
||||
|
||||
QtSoapStruct *ints = new QtSoapStruct; // gets taken over by message and free'd there
|
||||
// if you pass a pointer it all goes boom!
|
||||
|
||||
// create a little snippit: <workoutIds><int>xx</int></workoutIds>
|
||||
QDomDocument meh;
|
||||
QDomNode workoutIds = meh.createElement("workoutIds");
|
||||
QDomElement elint = meh.createElement("int");
|
||||
QDomText text = meh.createTextNode(QString("%1").arg(workoutId));
|
||||
elint.appendChild(text);
|
||||
workoutIds.appendChild(elint);
|
||||
|
||||
// turn it into the QtSoapStruct needed by the QtSoapMessage
|
||||
ints->parse(workoutIds);
|
||||
|
||||
// add as method arguments
|
||||
current.addMethodArgument(ints);
|
||||
|
||||
// do it!
|
||||
downloading = true;
|
||||
|
||||
http.submitRequest(current, "/tpwebservices/service.asmx");
|
||||
return;
|
||||
}
|
||||
|
||||
void TPDownload::getResponse(const QtSoapMessage &message)
|
||||
{
|
||||
downloading = false;
|
||||
QString result;
|
||||
QDomDocument pwx("PWX");
|
||||
|
||||
if (!message.isFault()) {
|
||||
const QtSoapType &response = message.returnValue();
|
||||
QDomNode workout = response.toDomElement(pwx).firstChild();
|
||||
pwx.appendChild(workout);
|
||||
}
|
||||
completed(pwx);
|
||||
}
|
||||
90
deprecated/TPDownload.h
Normal file
90
deprecated/TPDownload.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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_Download_h
|
||||
#define _Gc_Download_h
|
||||
#include "GoldenCheetah.h"
|
||||
#include <qtsoap.h>
|
||||
#include <QString>
|
||||
#include "RideFile.h"
|
||||
|
||||
// get list of accessible athletes
|
||||
class TPAthlete : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
G_OBJECT
|
||||
|
||||
public:
|
||||
TPAthlete(QObject *parent = 0);
|
||||
void list(int type, QString user, QString pass);
|
||||
|
||||
signals:
|
||||
void completed(QString, QList<QMap<QString,QString> >);
|
||||
|
||||
private slots:
|
||||
void getResponse(const QtSoapMessage &);
|
||||
|
||||
private:
|
||||
QtSoapHttpTransport http;
|
||||
bool waiting;
|
||||
QtSoapMessage current;
|
||||
};
|
||||
|
||||
// get workout list
|
||||
class TPWorkout : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
G_OBJECT
|
||||
|
||||
public:
|
||||
TPWorkout(QObject *parent = 0);
|
||||
void list(int id, QDate from, QDate to, QString user, QString pass);
|
||||
|
||||
signals:
|
||||
void completed(QList<QMap<QString,QString> >);
|
||||
|
||||
private slots:
|
||||
void getResponse(const QtSoapMessage &);
|
||||
|
||||
private:
|
||||
QtSoapHttpTransport http;
|
||||
bool waiting;
|
||||
QtSoapMessage current;
|
||||
};
|
||||
// uploader to trainingpeaks.com
|
||||
class TPDownload : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
G_OBJECT
|
||||
|
||||
public:
|
||||
TPDownload(QObject *parent = 0);
|
||||
void download(QString cyclist, int PersonId, int WorkoutId);
|
||||
|
||||
signals:
|
||||
void completed(QDomDocument);
|
||||
|
||||
private slots:
|
||||
void getResponse(const QtSoapMessage &);
|
||||
|
||||
private:
|
||||
QtSoapHttpTransport http;
|
||||
bool downloading;
|
||||
QtSoapMessage current;
|
||||
};
|
||||
#endif
|
||||
928
deprecated/TPDownloadDialog.cpp
Normal file
928
deprecated/TPDownloadDialog.cpp
Normal file
@@ -0,0 +1,928 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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 "TPDownloadDialog.h"
|
||||
#include "TPDownload.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Context.h"
|
||||
#include "Athlete.h"
|
||||
#include "PwxRideFile.h"
|
||||
#include "JsonRideFile.h"
|
||||
#include "Settings.h"
|
||||
#include "Units.h"
|
||||
|
||||
TPDownloadDialog::TPDownloadDialog(Context *context) : QDialog(context->mainWindow, Qt::Dialog), context(context), downloading(false), aborted(false)
|
||||
{
|
||||
setWindowTitle(tr("Synchronise TrainingPeaks.com"));
|
||||
|
||||
athleter = new TPAthlete(this);
|
||||
|
||||
connect (athleter, SIGNAL(completed(QString, QList<QMap<QString,QString> >)), this, SLOT(completedAthlete(QString, QList<QMap<QString,QString> >)));
|
||||
athleter->list(appsettings->cvalue(context->athlete->cyclist, GC_TPTYPE, "0").toInt(),
|
||||
appsettings->cvalue(context->athlete->cyclist, GC_TPUSER, "null").toString(),
|
||||
appsettings->cvalue(context->athlete->cyclist, GC_TPPASS, "null").toString());
|
||||
|
||||
setMinimumSize(850,450);
|
||||
QWidget::hide(); // don't show just yet...
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::completedAthlete(QString errorStr, QList<QMap<QString, QString> >athletes)
|
||||
{
|
||||
// did we get any athletes?
|
||||
if (athletes.count() == 0) {
|
||||
QWidget::hide(); // meh
|
||||
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("Download from TrainingPeaks.com"));
|
||||
if (errorStr.size() != 0) { // Something went wrong, so there should be a fault message
|
||||
msgBox.setText(errorStr);
|
||||
}
|
||||
else {
|
||||
msgBox.setText(tr("You must be a premium member to download from TrainingPeaks. Please check your cyclist configurations are correct on the Passwords tab."));
|
||||
}
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.exec();
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
|
||||
// setup tabs
|
||||
tabs = new QTabWidget(this);
|
||||
QWidget * upload = new QWidget(this);
|
||||
QWidget * download = new QWidget(this);
|
||||
QWidget * sync = new QWidget(this);
|
||||
tabs->addTab(download, tr("Download"));
|
||||
tabs->addTab(upload, tr("Upload"));
|
||||
tabs->addTab(sync, tr("Synchronize"));
|
||||
tabs->setCurrentIndex(2);
|
||||
QVBoxLayout *downloadLayout = new QVBoxLayout(download);
|
||||
QVBoxLayout *uploadLayout = new QVBoxLayout(upload);
|
||||
QVBoxLayout *syncLayout = new QVBoxLayout(sync);
|
||||
|
||||
workouter = new TPWorkout(this);
|
||||
connect (workouter, SIGNAL(completed(QList<QMap<QString,QString> >)), this,
|
||||
SLOT(completedWorkout(QList<QMap<QString,QString> >)));
|
||||
|
||||
downloader = new TPDownload(this);
|
||||
connect (downloader, SIGNAL(completed(QDomDocument)), this,
|
||||
SLOT(completedDownload(QDomDocument)));
|
||||
|
||||
uploader = new TPUpload(this);
|
||||
connect (uploader, SIGNAL(completed(QString)), this,
|
||||
SLOT(completedUpload(QString)));
|
||||
|
||||
// OK! Lets build up that dialog box
|
||||
athlete = athletes[0];
|
||||
|
||||
// combo box
|
||||
athleteCombo = new QComboBox(this);
|
||||
for (int i=0; i< athletes.count(); i++) {
|
||||
|
||||
QString name = QString("%1 %2").arg(athletes[i].value("FirstName"))
|
||||
.arg(athletes[i].value("LastName"));
|
||||
int id = athletes[i].value("PersonId").toInt();
|
||||
athleteCombo->addItem(name, id);
|
||||
}
|
||||
athleteCombo->setCurrentIndex(0);
|
||||
|
||||
QLabel *fromLabel = new QLabel(tr("From:"), this);
|
||||
QLabel *toLabel = new QLabel(tr("To:"), this);
|
||||
|
||||
from = new QDateEdit(this);
|
||||
from->setDate(QDate::currentDate().addMonths(-1));
|
||||
from->setCalendarPopup(true);
|
||||
to = new QDateEdit(this);
|
||||
to->setDate(QDate::currentDate());
|
||||
to->setCalendarPopup(true);
|
||||
|
||||
// Buttons
|
||||
refreshButton = new QPushButton(tr("Refresh List"), this);
|
||||
cancelButton = new QPushButton(tr("Close"),this);
|
||||
downloadButton = new QPushButton(tr("Download"),this);
|
||||
|
||||
selectAll = new QCheckBox(tr("Select all"), this);
|
||||
selectAll->setChecked(Qt::Unchecked);
|
||||
|
||||
// ride list
|
||||
rideList = new QTreeWidget(this);
|
||||
rideList->headerItem()->setText(0, " ");
|
||||
rideList->headerItem()->setText(1, "Workout Id");
|
||||
rideList->headerItem()->setText(2, "Date");
|
||||
rideList->headerItem()->setText(3, "Time");
|
||||
rideList->headerItem()->setText(4, "Duration");
|
||||
rideList->headerItem()->setText(5, "Distance");
|
||||
rideList->headerItem()->setText(6, "Exists");
|
||||
rideList->headerItem()->setText(7, "Status");
|
||||
rideList->setColumnCount(8);
|
||||
rideList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
rideList->setEditTriggers(QAbstractItemView::SelectedClicked); // allow edit
|
||||
rideList->setUniformRowHeights(true);
|
||||
rideList->setIndentation(0);
|
||||
rideList->header()->resizeSection(0,20);
|
||||
rideList->header()->resizeSection(1,90);
|
||||
rideList->header()->resizeSection(2,100);
|
||||
rideList->header()->resizeSection(3,100);
|
||||
rideList->header()->resizeSection(4,100);
|
||||
rideList->header()->resizeSection(5,70);
|
||||
rideList->header()->resizeSection(6,50);
|
||||
rideList->setSortingEnabled(true);
|
||||
|
||||
downloadLayout->addWidget(selectAll);
|
||||
downloadLayout->addWidget(rideList);
|
||||
|
||||
selectAllUp = new QCheckBox(tr("Select all"), this);
|
||||
selectAllUp->setChecked(Qt::Unchecked);
|
||||
|
||||
// ride list
|
||||
rideListUp = new QTreeWidget(this);
|
||||
rideListUp->headerItem()->setText(0, " ");
|
||||
rideListUp->headerItem()->setText(1, "File");
|
||||
rideListUp->headerItem()->setText(2, "Date");
|
||||
rideListUp->headerItem()->setText(3, "Time");
|
||||
rideListUp->headerItem()->setText(4, "Duration");
|
||||
rideListUp->headerItem()->setText(5, "Distance");
|
||||
rideListUp->headerItem()->setText(6, "Exists");
|
||||
rideListUp->headerItem()->setText(7, "Status");
|
||||
rideListUp->setColumnCount(8);
|
||||
rideListUp->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
rideListUp->setEditTriggers(QAbstractItemView::SelectedClicked); // allow edit
|
||||
rideListUp->setUniformRowHeights(true);
|
||||
rideListUp->setIndentation(0);
|
||||
rideListUp->header()->resizeSection(0,20);
|
||||
rideListUp->header()->resizeSection(1,200);
|
||||
rideListUp->header()->resizeSection(2,100);
|
||||
rideListUp->header()->resizeSection(3,100);
|
||||
rideListUp->header()->resizeSection(4,100);
|
||||
rideListUp->header()->resizeSection(5,70);
|
||||
rideListUp->header()->resizeSection(6,50);
|
||||
rideListUp->setSortingEnabled(true);
|
||||
|
||||
uploadLayout->addWidget(selectAllUp);
|
||||
uploadLayout->addWidget(rideListUp);
|
||||
|
||||
selectAllSync = new QCheckBox(tr("Select all"), this);
|
||||
selectAllSync->setChecked(Qt::Unchecked);
|
||||
syncMode = new QComboBox(this);
|
||||
syncMode->addItem(tr("Keep all do not delete"));
|
||||
syncMode->addItem(tr("Keep TP.com but delete Local"));
|
||||
syncMode->addItem(tr("Keep Local but delete TP.com"));
|
||||
QHBoxLayout *syncList = new QHBoxLayout;
|
||||
syncList->addWidget(selectAllSync);
|
||||
syncList->addStretch();
|
||||
syncList->addWidget(syncMode);
|
||||
|
||||
|
||||
// ride list
|
||||
rideListSync = new QTreeWidget(this);
|
||||
rideListSync->headerItem()->setText(0, " ");
|
||||
rideListSync->headerItem()->setText(1, "Source");
|
||||
rideListSync->headerItem()->setText(2, "Date");
|
||||
rideListSync->headerItem()->setText(3, "Time");
|
||||
rideListSync->headerItem()->setText(4, "Duration");
|
||||
rideListSync->headerItem()->setText(5, "Distance");
|
||||
rideListSync->headerItem()->setText(6, "Action");
|
||||
rideListSync->headerItem()->setText(7, "Status");
|
||||
rideListSync->setColumnCount(8);
|
||||
rideListSync->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
rideListSync->setEditTriggers(QAbstractItemView::SelectedClicked); // allow edit
|
||||
rideListSync->setUniformRowHeights(true);
|
||||
rideListSync->setIndentation(0);
|
||||
rideListSync->header()->resizeSection(0,20);
|
||||
rideListSync->header()->resizeSection(1,200);
|
||||
rideListSync->header()->resizeSection(2,100);
|
||||
rideListSync->header()->resizeSection(3,100);
|
||||
rideListSync->header()->resizeSection(4,100);
|
||||
rideListSync->header()->resizeSection(5,70);
|
||||
rideListSync->header()->resizeSection(6,100);
|
||||
rideListSync->setSortingEnabled(true);
|
||||
|
||||
syncLayout->addLayout(syncList);
|
||||
syncLayout->addWidget(rideListSync);
|
||||
|
||||
// show progress
|
||||
progressBar = new QProgressBar(this);
|
||||
progressLabel = new QLabel("Initial", this);
|
||||
|
||||
overwrite = new QCheckBox(tr("Overwrite existing files"), this);
|
||||
|
||||
// layout the widget now...
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
|
||||
QHBoxLayout *topline = new QHBoxLayout;
|
||||
topline->addWidget(athleteCombo);
|
||||
topline->addStretch();
|
||||
topline->addWidget(fromLabel);
|
||||
topline->addWidget(from);
|
||||
topline->addWidget(toLabel);
|
||||
topline->addWidget(to);
|
||||
topline->addStretch();
|
||||
topline->addWidget(refreshButton);
|
||||
|
||||
|
||||
QHBoxLayout *botline = new QHBoxLayout;
|
||||
botline->addWidget(progressLabel);
|
||||
botline->addStretch();
|
||||
botline->addWidget(overwrite);
|
||||
botline->addWidget(cancelButton);
|
||||
botline->addWidget(downloadButton);
|
||||
|
||||
mainLayout->addLayout(topline);
|
||||
mainLayout->addWidget(tabs);
|
||||
mainLayout->addWidget(progressBar);
|
||||
mainLayout->addLayout(botline);
|
||||
|
||||
|
||||
connect (cancelButton, SIGNAL(clicked()), this, SLOT(cancelClicked()));
|
||||
connect (refreshButton, SIGNAL(clicked()), this, SLOT(refreshClicked()));
|
||||
connect (selectAll, SIGNAL(stateChanged(int)), this, SLOT(selectAllChanged(int)));
|
||||
connect (selectAllUp, SIGNAL(stateChanged(int)), this, SLOT(selectAllUpChanged(int)));
|
||||
connect (selectAllSync, SIGNAL(stateChanged(int)), this, SLOT(selectAllSyncChanged(int)));
|
||||
connect (downloadButton, SIGNAL(clicked()), this, SLOT(downloadClicked()));
|
||||
connect (tabs, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
|
||||
QWidget::show();
|
||||
|
||||
// refresh anyway
|
||||
refreshClicked();
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::cancelClicked()
|
||||
{
|
||||
reject();
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::refreshClicked()
|
||||
{
|
||||
progressLabel->setText(tr("Downloading list..."));
|
||||
progressBar->setMinimum(0);
|
||||
progressBar->setMaximum(1);
|
||||
progressBar->setValue(0);
|
||||
|
||||
// wipe out current
|
||||
foreach (QTreeWidgetItem *curr, rideList->invisibleRootItem()->takeChildren()) {
|
||||
QCheckBox *check = (QCheckBox*)rideList->itemWidget(curr, 0);
|
||||
QCheckBox *exists = (QCheckBox*)rideList->itemWidget(curr, 6);
|
||||
delete check;
|
||||
delete exists;
|
||||
delete curr;
|
||||
}
|
||||
foreach (QTreeWidgetItem *curr, rideListUp->invisibleRootItem()->takeChildren()) {
|
||||
QCheckBox *check = (QCheckBox*)rideListUp->itemWidget(curr, 0);
|
||||
QCheckBox *exists = (QCheckBox*)rideListUp->itemWidget(curr, 6);
|
||||
delete check;
|
||||
delete exists;
|
||||
delete curr;
|
||||
}
|
||||
foreach (QTreeWidgetItem *curr, rideListSync->invisibleRootItem()->takeChildren()) {
|
||||
QCheckBox *check = (QCheckBox*)rideListSync->itemWidget(curr, 0);
|
||||
delete check;
|
||||
delete curr;
|
||||
}
|
||||
|
||||
// First lets kick off a download of ridefile lookups
|
||||
// since that can take a while
|
||||
workouter->list(
|
||||
athleteCombo->itemData(athleteCombo->currentIndex()).toInt(),
|
||||
from->date(),
|
||||
to->date(),
|
||||
appsettings->cvalue(context->athlete->cyclist, GC_TPUSER, "null").toString(),
|
||||
appsettings->cvalue(context->athlete->cyclist, GC_TPPASS, "null").toString());
|
||||
|
||||
// Whilst we wait for the results lets fill the map of existing rideFiles
|
||||
// (but ignore seconds since they aren't reliable)
|
||||
rideFiles.clear();
|
||||
|
||||
Specification specification;
|
||||
specification.setDateRange(DateRange(from->date(), to->date()));
|
||||
foreach(RideItem *item, context->athlete->rideCache->rides()) {
|
||||
if (specification.pass(item))
|
||||
rideFiles << QFileInfo(item->fileName).baseName().mid(0,14);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::tabChanged(int idx)
|
||||
{
|
||||
if (downloadButton->text() == "Abort") return;
|
||||
|
||||
switch (idx) {
|
||||
|
||||
case 0 : // download
|
||||
downloadButton->setText(tr("Download"));
|
||||
refreshCount();
|
||||
break;
|
||||
case 1 : // upload
|
||||
downloadButton->setText(tr("Upload"));
|
||||
refreshUpCount();
|
||||
break;
|
||||
case 2 : // synchronise
|
||||
downloadButton->setText(tr("Synchronize"));
|
||||
refreshSyncCount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::completedWorkout(QList<QMap<QString, QString> >workouts)
|
||||
{
|
||||
useMetricUnits = context->athlete->useMetricUnits;
|
||||
|
||||
//
|
||||
// Setup the upload list
|
||||
//
|
||||
uploadFiles.clear();
|
||||
for(int i=0; i<workouts.count(); i++) {
|
||||
QTreeWidgetItem *add;
|
||||
|
||||
add = new QTreeWidgetItem(rideList->invisibleRootItem());
|
||||
add->setFlags(add->flags() & ~Qt::ItemIsEditable);
|
||||
|
||||
QCheckBox *check = new QCheckBox("", this);
|
||||
connect (check, SIGNAL(stateChanged(int)), this, SLOT(refreshCount()));
|
||||
rideList->setItemWidget(add, 0, check);
|
||||
|
||||
add->setText(1, workouts[i].value("WorkoutId"));
|
||||
add->setTextAlignment(1, Qt::AlignCenter);
|
||||
|
||||
QDateTime ridedatetime(QDateTime::fromString(workouts[i].value("WorkoutDay"), Qt::ISODate).date(),
|
||||
QDateTime::fromString(workouts[i].value("StartTime"), Qt::ISODate).time());
|
||||
|
||||
add->setText(2, ridedatetime.toString("MMM d, yyyy"));
|
||||
add->setTextAlignment(2, Qt::AlignLeft);
|
||||
add->setText(3, ridedatetime.toString("hh:mm:ss"));
|
||||
add->setTextAlignment(3, Qt::AlignCenter);
|
||||
|
||||
long secs = workouts[i].value("TimeTotalInSeconds").toInt();
|
||||
QChar zero = QLatin1Char ( '0' );
|
||||
QString duration = QString("%1:%2:%3").arg(secs/3600,2,10,zero)
|
||||
.arg(secs%3600/60,2,10,zero)
|
||||
.arg(secs%60,2,10,zero);
|
||||
add->setText(4, duration);
|
||||
add->setTextAlignment(4, Qt::AlignCenter);
|
||||
|
||||
double distance = workouts[i].value("DistanceInMeters").toDouble() / 1000.00;
|
||||
if (useMetricUnits) {
|
||||
add->setText(5, QString("%1 km").arg(distance, 0, 'f', 1));
|
||||
} else {
|
||||
add->setText(5, QString("%1 mi").arg(distance*MILES_PER_KM, 0, 'f', 1));
|
||||
}
|
||||
add->setTextAlignment(5, Qt::AlignRight);
|
||||
|
||||
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 );
|
||||
|
||||
uploadFiles << targetnosuffix.mid(0,14);
|
||||
|
||||
// exists? - we ignore seconds, since TP seems to do odd
|
||||
// things to date times and loses seconds (?)
|
||||
QCheckBox *exists = new QCheckBox("", this);
|
||||
exists->setEnabled(false);
|
||||
rideList->setItemWidget(add, 6, exists);
|
||||
add->setTextAlignment(6, Qt::AlignCenter);
|
||||
if (rideFiles.contains(targetnosuffix.mid(0,14))) exists->setChecked(Qt::Checked);
|
||||
else {
|
||||
exists->setChecked(Qt::Unchecked);
|
||||
|
||||
// doesn't exist -- add it to the sync list too then
|
||||
QTreeWidgetItem *sync = new QTreeWidgetItem(rideListSync->invisibleRootItem());
|
||||
|
||||
QCheckBox *check = new QCheckBox("", this);
|
||||
connect (check, SIGNAL(stateChanged(int)), this, SLOT(refreshSyncCount()));
|
||||
rideListSync->setItemWidget(sync, 0, check);
|
||||
|
||||
sync->setText(1, workouts[i].value("WorkoutId"));
|
||||
sync->setTextAlignment(1, Qt::AlignCenter);
|
||||
sync->setText(2, ridedatetime.toString("MMM d, yyyy"));
|
||||
sync->setTextAlignment(2, Qt::AlignLeft);
|
||||
sync->setText(3, ridedatetime.toString("hh:mm:ss"));
|
||||
sync->setTextAlignment(3, Qt::AlignCenter);
|
||||
sync->setText(4, duration);
|
||||
sync->setTextAlignment(4, Qt::AlignCenter);
|
||||
sync->setText(5, QString("%1 km").arg(distance, 0, 'f', 1));
|
||||
sync->setTextAlignment(5, Qt::AlignRight);
|
||||
sync->setText(6, tr("Download"));
|
||||
sync->setTextAlignment(6, Qt::AlignLeft);
|
||||
sync->setText(7, "");
|
||||
}
|
||||
|
||||
add->setText(7, "");
|
||||
}
|
||||
|
||||
//
|
||||
// Now setup the upload list
|
||||
//
|
||||
Specification specification;
|
||||
specification.setDateRange(DateRange(from->date(), to->date()));
|
||||
for(int i=0; i<context->athlete->rideCache->rides().count(); i++) {
|
||||
|
||||
RideItem *ride = context->athlete->rideCache->rides().at(i);
|
||||
if (!specification.pass(ride)) continue;
|
||||
|
||||
QTreeWidgetItem *add;
|
||||
|
||||
add = new QTreeWidgetItem(rideListUp->invisibleRootItem());
|
||||
add->setFlags(add->flags() & ~Qt::ItemIsEditable);
|
||||
|
||||
QCheckBox *check = new QCheckBox("", this);
|
||||
connect (check, SIGNAL(stateChanged(int)), this, SLOT(refreshUpCount()));
|
||||
rideListUp->setItemWidget(add, 0, check);
|
||||
|
||||
add->setText(1, ride->fileName);
|
||||
add->setTextAlignment(1, Qt::AlignLeft);
|
||||
add->setText(2, ride->dateTime.toString("MMM d, yyyy"));
|
||||
add->setTextAlignment(2, Qt::AlignLeft);
|
||||
add->setText(3, ride->dateTime.toString("hh:mm:ss"));
|
||||
add->setTextAlignment(3, Qt::AlignCenter);
|
||||
|
||||
long secs = ride->getForSymbol("workout_time");
|
||||
QChar zero = QLatin1Char ( '0' );
|
||||
QString duration = QString("%1:%2:%3").arg(secs/3600,2,10,zero)
|
||||
.arg(secs%3600/60,2,10,zero)
|
||||
.arg(secs%60,2,10,zero);
|
||||
add->setText(4, duration);
|
||||
add->setTextAlignment(4, Qt::AlignCenter);
|
||||
|
||||
double distance = ride->getForSymbol("total_distance");
|
||||
add->setText(5, QString("%1 km").arg(distance, 0, 'f', 1));
|
||||
add->setTextAlignment(5, Qt::AlignRight);
|
||||
|
||||
// exists? - we ignore seconds, since TP seems to do odd
|
||||
// things to date times and loses seconds (?)
|
||||
QCheckBox *exists = new QCheckBox("", this);
|
||||
exists->setEnabled(false);
|
||||
rideListUp->setItemWidget(add, 6, exists);
|
||||
add->setTextAlignment(6, Qt::AlignCenter);
|
||||
|
||||
QString targetnosuffix = QString ( "%1_%2_%3_%4_%5_%6" )
|
||||
.arg ( ride->dateTime.date().year(), 4, 10, zero )
|
||||
.arg ( ride->dateTime.date().month(), 2, 10, zero )
|
||||
.arg ( ride->dateTime.date().day(), 2, 10, zero )
|
||||
.arg ( ride->dateTime.time().hour(), 2, 10, zero )
|
||||
.arg ( ride->dateTime.time().minute(), 2, 10, zero )
|
||||
.arg ( ride->dateTime.time().second(), 2, 10, zero );
|
||||
|
||||
// check if on TP.com already
|
||||
if (uploadFiles.contains(targetnosuffix.mid(0,14))) exists->setChecked(Qt::Checked);
|
||||
else {
|
||||
exists->setChecked(Qt::Unchecked);
|
||||
|
||||
// doesn't exist -- add it to the sync list too then
|
||||
QTreeWidgetItem *sync = new QTreeWidgetItem(rideListSync->invisibleRootItem());
|
||||
|
||||
QCheckBox *check = new QCheckBox("", this);
|
||||
connect (check, SIGNAL(stateChanged(int)), this, SLOT(refreshSyncCount()));
|
||||
rideListSync->setItemWidget(sync, 0, check);
|
||||
|
||||
sync->setText(1, ride->fileName);
|
||||
sync->setTextAlignment(1, Qt::AlignCenter);
|
||||
sync->setText(2, ride->dateTime.toString("MMM d, yyyy"));
|
||||
sync->setTextAlignment(2, Qt::AlignLeft);
|
||||
sync->setText(3, ride->dateTime.toString("hh:mm:ss"));
|
||||
sync->setTextAlignment(3, Qt::AlignCenter);
|
||||
sync->setText(4, duration);
|
||||
sync->setTextAlignment(4, Qt::AlignCenter);
|
||||
sync->setText(5, QString("%1 km").arg(distance, 0, 'f', 1));
|
||||
sync->setTextAlignment(5, Qt::AlignRight);
|
||||
sync->setText(6, tr("Upload"));
|
||||
sync->setTextAlignment(6, Qt::AlignLeft);
|
||||
sync->setText(7, "");
|
||||
}
|
||||
add->setText(7, "");
|
||||
}
|
||||
|
||||
// refresh the progress label
|
||||
tabChanged(tabs->currentIndex());
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::selectAllChanged(int state)
|
||||
{
|
||||
for (int i=0; i<rideList->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideList->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideList->itemWidget(curr, 0);
|
||||
check->setChecked(state);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::selectAllUpChanged(int state)
|
||||
{
|
||||
for (int i=0; i<rideListUp->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideListUp->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideListUp->itemWidget(curr, 0);
|
||||
check->setChecked(state);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::selectAllSyncChanged(int state)
|
||||
{
|
||||
for (int i=0; i<rideListSync->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideListSync->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideListSync->itemWidget(curr, 0);
|
||||
check->setChecked(state);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::refreshUpCount()
|
||||
{
|
||||
int selected = 0;
|
||||
|
||||
for (int i=0; i<rideListUp->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideListUp->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideListUp->itemWidget(curr, 0);
|
||||
if (check->isChecked()) selected++;
|
||||
}
|
||||
progressLabel->setText(QString("%1 of %2 selected").arg(selected)
|
||||
.arg(rideListUp->invisibleRootItem()->childCount()));
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::refreshSyncCount()
|
||||
{
|
||||
int selected = 0;
|
||||
|
||||
for (int i=0; i<rideListSync->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideListSync->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideListSync->itemWidget(curr, 0);
|
||||
if (check->isChecked()) selected++;
|
||||
}
|
||||
progressLabel->setText(QString("%1 of %2 selected").arg(selected)
|
||||
.arg(rideListSync->invisibleRootItem()->childCount()));
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::refreshCount()
|
||||
{
|
||||
int selected = 0;
|
||||
|
||||
for (int i=0; i<rideList->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideList->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideList->itemWidget(curr, 0);
|
||||
if (check->isChecked()) selected++;
|
||||
}
|
||||
progressLabel->setText(QString("%1 of %2 selected").arg(selected)
|
||||
.arg(rideList->invisibleRootItem()->childCount()));
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::downloadClicked()
|
||||
{
|
||||
if (downloading == true) {
|
||||
rideList->setSortingEnabled(true);
|
||||
rideListUp->setSortingEnabled(true);
|
||||
progressLabel->setText("");
|
||||
downloadButton->setText("Download");
|
||||
downloading=false;
|
||||
aborted=true;
|
||||
cancelButton->show();
|
||||
return;
|
||||
} else {
|
||||
rideList->setSortingEnabled(false);
|
||||
rideListUp->setSortingEnabled(true);
|
||||
downloading=true;
|
||||
aborted=false;
|
||||
downloadButton->setText("Abort");
|
||||
cancelButton->hide();
|
||||
}
|
||||
|
||||
// keeping track of progress...
|
||||
downloadcounter = 0;
|
||||
successful = 0;
|
||||
downloadtotal = 0;
|
||||
listindex = 0;
|
||||
|
||||
QTreeWidget *which = NULL;
|
||||
switch(tabs->currentIndex()) {
|
||||
case 0 : which = rideList; break;
|
||||
case 1 : which = rideListUp; break;
|
||||
default:
|
||||
case 2 : which = rideListSync; break;
|
||||
}
|
||||
|
||||
for (int i=0; i<which->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = which->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)which->itemWidget(curr, 0);
|
||||
if (check->isChecked()) {
|
||||
downloadtotal++;
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadtotal) {
|
||||
progressBar->setMaximum(downloadtotal);
|
||||
progressBar->setMinimum(0);
|
||||
progressBar->setValue(0);
|
||||
}
|
||||
|
||||
// even if nothing to download this
|
||||
// cleans up variables et al
|
||||
sync = false;
|
||||
switch(tabs->currentIndex()) {
|
||||
case 0 : downloadNext(); break;
|
||||
case 1 : uploadNext(); break;
|
||||
case 2 : sync = true; syncNext(); break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TPDownloadDialog::syncNext()
|
||||
{
|
||||
// the actual download/upload is kicked off using the uploader / downloader
|
||||
// if in sync mode the completedDownload / completedUpload functions
|
||||
// just call completedSync to get the next Sync done
|
||||
for (int i=listindex; i<rideListSync->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideListSync->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideListSync->itemWidget(curr, 0);
|
||||
|
||||
if (check->isChecked()) {
|
||||
|
||||
listindex = i+1; // start from the next one
|
||||
|
||||
progressLabel->setText(QString(tr("Processed %1 of %2")).arg(downloadcounter).arg(downloadtotal));
|
||||
if (curr->text(6) == "Download") {
|
||||
curr->setText(7, tr("Downloading"));
|
||||
rideListSync->setCurrentItem(curr);
|
||||
downloader->download(
|
||||
context->athlete->cyclist,
|
||||
athleteCombo->itemData(athleteCombo->currentIndex()).toInt(),
|
||||
curr->text(1).toInt()
|
||||
);
|
||||
QApplication::processEvents();
|
||||
} else {
|
||||
curr->setText(7, tr("Uploading"));
|
||||
rideListSync->setCurrentItem(curr);
|
||||
|
||||
// read in the file
|
||||
QStringList errors;
|
||||
QFile file(context->athlete->home->activities().canonicalPath() + "/" + curr->text(1));
|
||||
RideFile *ride = RideFileFactory::instance().openRideFile(context, file, errors);
|
||||
|
||||
if (ride) {
|
||||
uploader->upload(context, ride);
|
||||
delete ride; // clean up!
|
||||
QApplication::processEvents();
|
||||
return true;
|
||||
} else {
|
||||
curr->setText(7, "Parse failure");
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Our work is done!
|
||||
//
|
||||
rideList->setSortingEnabled(true);
|
||||
rideListUp->setSortingEnabled(true);
|
||||
rideListSync->setSortingEnabled(true);
|
||||
progressLabel->setText(tr("Sync complete"));
|
||||
downloadButton->setText("Synchronize");
|
||||
downloading=false;
|
||||
aborted=false;
|
||||
sync=false;
|
||||
cancelButton->show();
|
||||
selectAllSync->setChecked(Qt::Unchecked);
|
||||
for (int i=0; i<rideListSync->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideListSync->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideListSync->itemWidget(curr, 0);
|
||||
check->setChecked(false);
|
||||
}
|
||||
progressLabel->setText(QString(tr("Processed %1 of %2 successfully")).arg(successful).arg(downloadtotal));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TPDownloadDialog::downloadNext()
|
||||
{
|
||||
for (int i=listindex; i<rideList->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideList->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideList->itemWidget(curr, 0);
|
||||
QCheckBox *exists = (QCheckBox*)rideList->itemWidget(curr, 6);
|
||||
|
||||
// skip existing if overwrite not set
|
||||
if (check->isChecked() && exists->isChecked() && !overwrite->isChecked()) {
|
||||
curr->setText(7, tr("File exists"));
|
||||
progressBar->setValue(++downloadcounter);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (check->isChecked()) {
|
||||
|
||||
listindex = i+1; // start from the next one
|
||||
curr->setText(7, tr("Downloading"));
|
||||
rideList->setCurrentItem(curr);
|
||||
progressLabel->setText(QString(tr("Downloaded %1 of %2")).arg(downloadcounter).arg(downloadtotal));
|
||||
downloader->download(
|
||||
context->athlete->cyclist,
|
||||
athleteCombo->itemData(athleteCombo->currentIndex()).toInt(),
|
||||
curr->text(1).toInt()
|
||||
);
|
||||
QApplication::processEvents();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Our work is done!
|
||||
//
|
||||
rideList->setSortingEnabled(true);
|
||||
rideListUp->setSortingEnabled(true);
|
||||
progressLabel->setText(tr("Downloads complete"));
|
||||
downloadButton->setText("Download");
|
||||
downloading=false;
|
||||
aborted=false;
|
||||
cancelButton->show();
|
||||
selectAll->setChecked(Qt::Unchecked);
|
||||
for (int i=0; i<rideList->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideList->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideList->itemWidget(curr, 0);
|
||||
check->setChecked(false);
|
||||
}
|
||||
progressLabel->setText(QString(tr("Downloaded %1 of %2 successfully")).arg(successful).arg(downloadtotal));
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::completedDownload(QDomDocument pwx)
|
||||
{
|
||||
QTreeWidget *which = sync ? rideListSync : rideList;
|
||||
|
||||
// was abort pressed?
|
||||
if (aborted == true) {
|
||||
QTreeWidgetItem *curr = which->invisibleRootItem()->child(listindex-1);
|
||||
curr->setText(7, tr("Aborted"));
|
||||
return;
|
||||
}
|
||||
|
||||
// update status...
|
||||
// validate (parse)
|
||||
QStringList errors;
|
||||
PwxFileReader reader;
|
||||
RideFile *ride = reader.PwxFromDomDoc(pwx, errors);
|
||||
|
||||
progressBar->setValue(++downloadcounter);
|
||||
|
||||
QTreeWidgetItem *curr = which->invisibleRootItem()->child(listindex-1);
|
||||
if (ride) {
|
||||
if (saveRide(ride, pwx, errors) == true) {
|
||||
curr->setText(7, tr("Saved"));
|
||||
successful++;
|
||||
} else {
|
||||
curr->setText(7, errors.join(","));
|
||||
}
|
||||
} else {
|
||||
QString err = "Failed:" + errors.join(",");
|
||||
curr->setText(7, err);
|
||||
}
|
||||
QApplication::processEvents();
|
||||
|
||||
if (sync)
|
||||
syncNext();
|
||||
else
|
||||
downloadNext();
|
||||
}
|
||||
|
||||
bool
|
||||
TPDownloadDialog::uploadNext()
|
||||
{
|
||||
for (int i=listindex; i<rideListUp->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideListUp->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideListUp->itemWidget(curr, 0);
|
||||
QCheckBox *exists = (QCheckBox*)rideListUp->itemWidget(curr, 6);
|
||||
|
||||
// skip existing if overwrite not set
|
||||
if (check->isChecked() && exists->isChecked() && !overwrite->isChecked()) {
|
||||
curr->setText(7, tr("File exists"));
|
||||
progressBar->setValue(++downloadcounter);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (check->isChecked()) {
|
||||
|
||||
listindex = i+1; // start from the next one
|
||||
curr->setText(7, tr("Uploading"));
|
||||
rideListUp->setCurrentItem(curr);
|
||||
progressLabel->setText(QString(tr("Uploaded %1 of %2")).arg(downloadcounter).arg(downloadtotal));
|
||||
|
||||
// read in the file
|
||||
QStringList errors;
|
||||
QFile file(context->athlete->home->activities().canonicalPath() + "/" + curr->text(1));
|
||||
RideFile *ride = RideFileFactory::instance().openRideFile(context, file, errors);
|
||||
|
||||
if (ride) {
|
||||
uploader->upload(context, ride);
|
||||
delete ride; // clean up!
|
||||
QApplication::processEvents();
|
||||
return true;
|
||||
} else {
|
||||
curr->setText(7, "Parse failure");
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Our work is done!
|
||||
//
|
||||
rideList->setSortingEnabled(true);
|
||||
rideListUp->setSortingEnabled(true);
|
||||
progressLabel->setText(tr("Uploads complete"));
|
||||
downloadButton->setText("Upload");
|
||||
downloading=false;
|
||||
aborted=false;
|
||||
cancelButton->show();
|
||||
selectAllUp->setChecked(Qt::Unchecked);
|
||||
for (int i=0; i<rideListUp->invisibleRootItem()->childCount(); i++) {
|
||||
QTreeWidgetItem *curr = rideListUp->invisibleRootItem()->child(i);
|
||||
QCheckBox *check = (QCheckBox*)rideListUp->itemWidget(curr, 0);
|
||||
check->setChecked(false);
|
||||
}
|
||||
progressLabel->setText(QString(tr("Uploaded %1 of %2 successfully")).arg(successful).arg(downloadtotal));
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
TPDownloadDialog::completedUpload(QString result)
|
||||
{
|
||||
QTreeWidget *which = sync ? rideListSync : rideListUp;
|
||||
|
||||
// was abort pressed?
|
||||
if (aborted == true) {
|
||||
QTreeWidgetItem *curr = which->invisibleRootItem()->child(listindex-1);
|
||||
curr->setText(7, tr("Aborted"));
|
||||
return;
|
||||
}
|
||||
|
||||
progressBar->setValue(++downloadcounter);
|
||||
|
||||
QTreeWidgetItem *curr = which->invisibleRootItem()->child(listindex-1);
|
||||
curr->setText(7, result);
|
||||
if (result == tr("Upload successful")) successful++;
|
||||
QApplication::processEvents();
|
||||
|
||||
if (sync)
|
||||
syncNext();
|
||||
else
|
||||
uploadNext();
|
||||
}
|
||||
|
||||
bool
|
||||
TPDownloadDialog::saveRide(RideFile *ride, QDomDocument &, QStringList &errors)
|
||||
{
|
||||
QDateTime ridedatetime = 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 );
|
||||
|
||||
QString filename = context->athlete->home->activities().canonicalPath() + "/" + targetnosuffix + ".json";
|
||||
|
||||
// exists?
|
||||
QFileInfo fileinfo(filename);
|
||||
if (fileinfo.exists() && overwrite->isChecked() == false) {
|
||||
errors << "File exists";
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonFileReader reader;
|
||||
QFile file(filename);
|
||||
reader.writeRideFile(context, ride, file);
|
||||
|
||||
// add to the ride list
|
||||
rideFiles<<targetnosuffix;
|
||||
context->athlete->addRide(fileinfo.fileName(), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
134
deprecated/TPDownloadDialog.h
Normal file
134
deprecated/TPDownloadDialog.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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_TPDownloadDialog_h
|
||||
#define _GC_TPDownloadDialog_h 1
|
||||
#include "GoldenCheetah.h"
|
||||
|
||||
#include <QtGui>
|
||||
#include <QDialog>
|
||||
#include <QCheckBox>
|
||||
#include <QHeaderView>
|
||||
#include <QProgressBar>
|
||||
#include <QMessageBox>
|
||||
#include <QTreeWidget>
|
||||
#include <QTabWidget>
|
||||
#include <QLabel>
|
||||
|
||||
#include "RideCache.h"
|
||||
#include "RideItem.h"
|
||||
#include "RideFile.h"
|
||||
#include "TPDownload.h"
|
||||
#include "TPUpload.h"
|
||||
|
||||
class Context;
|
||||
|
||||
class TPDownloadDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
G_OBJECT
|
||||
|
||||
|
||||
public:
|
||||
TPDownloadDialog(Context *context);
|
||||
|
||||
protected:
|
||||
// cached state
|
||||
QSettings *settings;
|
||||
bool useMetricUnits;
|
||||
|
||||
public slots:
|
||||
void completedAthlete(QString, QList<QMap<QString,QString> >);
|
||||
void completedWorkout(QList<QMap<QString,QString> >);
|
||||
void completedDownload(QDomDocument);
|
||||
void completedUpload(QString);
|
||||
void cancelClicked();
|
||||
void refreshClicked();
|
||||
void tabChanged(int);
|
||||
void downloadClicked();
|
||||
void refreshCount();
|
||||
void refreshUpCount();
|
||||
void refreshSyncCount();
|
||||
void selectAllChanged(int);
|
||||
void selectAllUpChanged(int);
|
||||
void selectAllSyncChanged(int);
|
||||
|
||||
private:
|
||||
Context *context;
|
||||
TPDownload *downloader;
|
||||
TPUpload *uploader;
|
||||
TPAthlete *athleter;
|
||||
TPWorkout *workouter;
|
||||
|
||||
bool downloading;
|
||||
bool sync;
|
||||
bool aborted;
|
||||
|
||||
// Quick lists for checking if file exists
|
||||
// locally (rideFiles) or remotely (uploadFiles)
|
||||
QStringList rideFiles;
|
||||
QStringList uploadFiles;
|
||||
|
||||
// keeping track of progress...
|
||||
int downloadcounter, // *x* of n downloading
|
||||
downloadtotal, // x of *n* downloading
|
||||
successful, // how many downloaded ok?
|
||||
listindex; // where in rideList we've got to
|
||||
|
||||
bool saveRide(RideFile *, QDomDocument &, QStringList &);
|
||||
bool syncNext(); // kick off another download/upload
|
||||
// returns false if none left
|
||||
bool downloadNext(); // kick off another download
|
||||
// returns false if none left
|
||||
bool uploadNext(); // kick off another upload
|
||||
// returns false if none left
|
||||
|
||||
// tabs - Upload/Download
|
||||
QTabWidget *tabs;
|
||||
|
||||
// athlete selection
|
||||
QMap<QString, QString> athlete;
|
||||
QComboBox *athleteCombo;
|
||||
|
||||
QPushButton *refreshButton;
|
||||
QPushButton *cancelButton;
|
||||
QPushButton *downloadButton;
|
||||
|
||||
QDateEdit *from, *to;
|
||||
|
||||
// Download
|
||||
QCheckBox *selectAll;
|
||||
QTreeWidget *rideList;
|
||||
|
||||
// Upload
|
||||
QCheckBox *selectAllUp;
|
||||
QTreeWidget *rideListUp;
|
||||
|
||||
// Sync
|
||||
QCheckBox *selectAllSync;
|
||||
QTreeWidget *rideListSync;
|
||||
QComboBox *syncMode;
|
||||
|
||||
// show progress
|
||||
QProgressBar *progressBar;
|
||||
QLabel *progressLabel;
|
||||
|
||||
QCheckBox *overwrite;
|
||||
};
|
||||
|
||||
#endif // _GC_TPDownloadDialog_h
|
||||
128
deprecated/TPUpload.cpp
Normal file
128
deprecated/TPUpload.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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 "TPUpload.h"
|
||||
#include "Context.h"
|
||||
#include "Athlete.h"
|
||||
#include <QString>
|
||||
#include "Settings.h"
|
||||
#include "RideFile.h"
|
||||
#include "PwxRideFile.h"
|
||||
#include <QtXml>
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QLocale>
|
||||
|
||||
#ifdef Q_CC_MSVC
|
||||
#include <QtZlib\zlib.h>
|
||||
#else
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
//
|
||||
// Utility function to create a QByteArray of data in GZIP format
|
||||
// This is essentially the same as qCompress but creates it in
|
||||
// GZIP format (with recquisite headers) instead of ZLIB's format
|
||||
// which has less filename info in the header
|
||||
//
|
||||
static QByteArray zCompress(const QByteArray &source)
|
||||
{
|
||||
// int size is source.size()
|
||||
// const char *data is source.data()
|
||||
z_stream strm;
|
||||
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
|
||||
// note that (15+16) below means windowbits+_16_ adds the gzip header/footer
|
||||
deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY);
|
||||
|
||||
// input data
|
||||
strm.avail_in = source.size();
|
||||
strm.next_in = (Bytef *)source.data();
|
||||
|
||||
// output data - on stack not heap, will be released
|
||||
QByteArray dest(source.size()/2, '\0'); // should compress by 50%, if not don't bother
|
||||
|
||||
strm.avail_out = source.size()/2;
|
||||
strm.next_out = (Bytef *)dest.data();
|
||||
|
||||
// now compress!
|
||||
deflate(&strm, Z_FINISH);
|
||||
|
||||
// return byte array on the stack
|
||||
return QByteArray(dest.data(), (source.size()/2) - strm.avail_out);
|
||||
}
|
||||
|
||||
|
||||
TPUpload::TPUpload(QObject *parent) : QObject(parent), http(this), uploading(false)
|
||||
{
|
||||
connect(&http, SIGNAL(responseReady(const QtSoapMessage &)),
|
||||
this, SLOT(getResponse(const QtSoapMessage &)));
|
||||
}
|
||||
|
||||
int
|
||||
TPUpload::upload(Context *context, const RideFile *ride)
|
||||
{
|
||||
// if currently uploading fail!
|
||||
if (uploading == true) return 0;
|
||||
|
||||
// create the file in .pwx format for upload
|
||||
QString uploadfile(QDir::tempPath() + "/tpupload.pwx");
|
||||
QFile file(uploadfile);
|
||||
PwxFileReader reader;
|
||||
reader.writeRideFile(context, ride, file);
|
||||
|
||||
// read the whole thing back and encode as base64binary
|
||||
file.open(QFile::ReadOnly);
|
||||
QTextStream stream(&file);
|
||||
QString thelot = stream.readAll();
|
||||
QString pwxFile = zCompress(thelot.toUtf8()).toBase64(); // bleck!
|
||||
file.close();
|
||||
|
||||
// setup the soap message
|
||||
current = QtSoapMessage();
|
||||
http.setHost("www.trainingpeaks.com", true);
|
||||
http.setAction("http://www.trainingpeaks.com/TPWebServices/ImportFileForUser");
|
||||
current.setMethod("ImportFileForUser", "http://www.trainingpeaks.com/TPWebServices/");
|
||||
current.addMethodArgument("username", "", appsettings->cvalue(context->athlete->cyclist, GC_TPUSER).toString());
|
||||
current.addMethodArgument("password", "", appsettings->cvalue(context->athlete->cyclist, GC_TPPASS).toString());
|
||||
current.addMethodArgument("byteData", "", pwxFile);
|
||||
|
||||
// do it!
|
||||
uploading = true;
|
||||
http.submitRequest(current, "/tpwebservices/service.asmx");
|
||||
|
||||
return pwxFile.size();
|
||||
}
|
||||
|
||||
void TPUpload::getResponse(const QtSoapMessage &message)
|
||||
{
|
||||
uploading = false;
|
||||
QString result;
|
||||
|
||||
if (message.isFault()) {
|
||||
result = tr("Error:") + qPrintable(message.faultString().toString());
|
||||
} else {
|
||||
// SOAP call succeeded, but was the file accepted?
|
||||
if (message.returnValue().toString() == "true") result = tr("Upload successful");
|
||||
else result = tr("Upload failed - file rejected");
|
||||
}
|
||||
completed(result);
|
||||
}
|
||||
48
deprecated/TPUpload.h
Normal file
48
deprecated/TPUpload.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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_TPUpload_h
|
||||
#define _Gc_TPUpload_h
|
||||
#include "GoldenCheetah.h"
|
||||
#include <qtsoap.h>
|
||||
#include <QString>
|
||||
#include "RideFile.h"
|
||||
|
||||
// uploader to trainingpeaks.com
|
||||
class TPUpload : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
G_OBJECT
|
||||
|
||||
public:
|
||||
TPUpload(QObject *parent = 0);
|
||||
int upload(Context *context, const RideFile *ride);
|
||||
|
||||
signals:
|
||||
void completed(QString);
|
||||
|
||||
private slots:
|
||||
void getResponse(const QtSoapMessage &);
|
||||
|
||||
private:
|
||||
QtSoapHttpTransport http;
|
||||
bool uploading;
|
||||
QtSoapMessage current;
|
||||
};
|
||||
|
||||
#endif
|
||||
78
deprecated/TPUploadDialog.cpp
Normal file
78
deprecated/TPUploadDialog.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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 "TPUploadDialog.h"
|
||||
#include "Context.h"
|
||||
#include "GcRideFile.h"
|
||||
#include "RideItem.h"
|
||||
#include "RideFile.h"
|
||||
#include "TPUpload.h"
|
||||
#include "Settings.h"
|
||||
|
||||
TPUploadDialog::TPUploadDialog(QString cyclist, const RideFile *ride, Context *context) :
|
||||
context(context), cyclist(cyclist), ride(ride)
|
||||
{
|
||||
setWindowTitle(tr("Upload to TrainingPeaks.com"));
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
QHBoxLayout *button = new QHBoxLayout;
|
||||
|
||||
statusLabel = new QLabel(tr("Upload in progress..."));
|
||||
statusLabel->setWordWrap(true);
|
||||
|
||||
progressBar = new QProgressBar(this);
|
||||
progressBar->setMinimum(0);
|
||||
progressBar->setMaximum(0);
|
||||
|
||||
cancelButton = new QPushButton(tr("Abort"));
|
||||
|
||||
button->addStretch();
|
||||
button->addWidget(cancelButton);
|
||||
button->addStretch();
|
||||
|
||||
mainLayout->addWidget(statusLabel);
|
||||
mainLayout->addWidget(progressBar);
|
||||
mainLayout->addLayout(button);
|
||||
|
||||
uploader = new TPUpload(this);
|
||||
|
||||
connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancelClicked()));
|
||||
connect(uploader, SIGNAL(completed(QString)),this, SLOT(completed(QString)));
|
||||
|
||||
uploading = true;
|
||||
int size = uploader->upload(context, ride);
|
||||
|
||||
statusLabel->setText(QString(tr("Uploading (%1 bytes)...")).arg(size));
|
||||
|
||||
setMinimumWidth(250);
|
||||
}
|
||||
|
||||
void
|
||||
TPUploadDialog::cancelClicked()
|
||||
{
|
||||
delete uploader;
|
||||
reject();
|
||||
}
|
||||
|
||||
void
|
||||
TPUploadDialog::completed(QString results)
|
||||
{
|
||||
uploading = false;
|
||||
progressBar->setMaximum(1);
|
||||
progressBar->setValue(1);
|
||||
statusLabel->setText(results);
|
||||
cancelButton->setText(tr("Close"));
|
||||
}
|
||||
58
deprecated/TPUploadDialog.h
Normal file
58
deprecated/TPUploadDialog.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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_TPUploadDialog_h
|
||||
#define _GC_TPUploadDialog_h 1
|
||||
#include "GoldenCheetah.h"
|
||||
|
||||
#include <QtGui>
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QProgressBar>
|
||||
#include "RideFile.h"
|
||||
#include "TPUpload.h"
|
||||
|
||||
class Context;
|
||||
|
||||
class TPUploadDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
G_OBJECT
|
||||
|
||||
|
||||
public:
|
||||
TPUploadDialog(QString cyclist, const RideFile *ride, Context *context);
|
||||
|
||||
public slots:
|
||||
void cancelClicked();
|
||||
void completed(QString);
|
||||
|
||||
private:
|
||||
Context *context;
|
||||
QString cyclist;
|
||||
const RideFile *ride;
|
||||
|
||||
QLabel *statusLabel;
|
||||
QProgressBar *progressBar;
|
||||
QPushButton *cancelButton;
|
||||
bool uploading;
|
||||
|
||||
TPUpload *uploader;
|
||||
};
|
||||
|
||||
#endif // _GC_TPUploadDialog_h
|
||||
Reference in New Issue
Block a user