mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
Merge branch 'origin'
This commit is contained in:
@@ -45,10 +45,13 @@ ConfigDialog::ConfigDialog(QDir _home, Zones *_zones, MainWindow *mainWindow) :
|
||||
configPage = new ConfigurationPage(mainWindow);
|
||||
devicePage = new DevicePage(this);
|
||||
|
||||
twitterPage = new TwitterPage(this);
|
||||
|
||||
pagesWidget = new QStackedWidget;
|
||||
pagesWidget->addWidget(configPage);
|
||||
pagesWidget->addWidget(cyclistPage);
|
||||
pagesWidget->addWidget(devicePage);
|
||||
pagesWidget->addWidget(twitterPage);
|
||||
|
||||
closeButton = new QPushButton(tr("Close"));
|
||||
saveButton = new QPushButton(tr("Save"));
|
||||
@@ -114,6 +117,12 @@ void ConfigDialog::createIcons()
|
||||
realtimeButton->setTextAlignment(Qt::AlignHCenter);
|
||||
realtimeButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
QListWidgetItem *twitterButton = new QListWidgetItem(contentsWidget);
|
||||
twitterButton->setIcon(QIcon(":images/twitter.png"));
|
||||
twitterButton->setText(tr("Twitter"));
|
||||
twitterButton->setTextAlignment(Qt::AlignHCenter);
|
||||
twitterButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
connect(contentsWidget,
|
||||
SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)),
|
||||
this, SLOT(changePage(QListWidgetItem *, QListWidgetItem*)));
|
||||
@@ -160,6 +169,11 @@ void ConfigDialog::save_Clicked()
|
||||
settings->setValue(GC_LTS_DAYS, cyclistPage->perfManLTSavg->text());
|
||||
settings->setValue(GC_SB_TODAY, (int) cyclistPage->showSBToday->isChecked());
|
||||
|
||||
//Save Twitter - Info PASSWORD IS IN CLEAR
|
||||
settings->setValue(GC_TWITTER_USERNAME, twitterPage->accountName->text());
|
||||
settings->setValue(GC_TWITTER_PASSWORD, twitterPage->passwordEdit->text());
|
||||
|
||||
|
||||
// set default stress names if not set:
|
||||
settings->setValue(GC_STS_NAME, settings->value(GC_STS_NAME,tr("Short Term Stress")));
|
||||
settings->setValue(GC_STS_ACRONYM, settings->value(GC_STS_ACRONYM,tr("STS")));
|
||||
|
||||
@@ -38,6 +38,7 @@ class ConfigDialog : public QDialog
|
||||
ConfigurationPage *configPage;
|
||||
CyclistPage *cyclistPage;
|
||||
DevicePage *devicePage;
|
||||
TwitterPage *twitterPage;
|
||||
QPushButton *saveButton;
|
||||
QStackedWidget *pagesWidget;
|
||||
QPushButton *closeButton;
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include "SplitRideDialog.h"
|
||||
#include "PerformanceManagerWindow.h"
|
||||
#include "TrainWindow.h"
|
||||
#include "TwitterDialog.h"
|
||||
|
||||
#ifndef GC_VERSION
|
||||
#define GC_VERSION "(developer build)"
|
||||
@@ -897,6 +898,8 @@ MainWindow::showTreeContextMenuPopup(const QPoint &pos)
|
||||
QAction *actSplitRide = new QAction(tr("Split Ride"), treeWidget);
|
||||
connect(actSplitRide, SIGNAL(triggered(void)), this, SLOT(splitRide()));
|
||||
|
||||
QAction *actTweetRide = new QAction(tr("Tweet Ride"), treeWidget);
|
||||
connect(actTweetRide, SIGNAL(triggered(void)), this, SLOT(tweetRide()));
|
||||
|
||||
|
||||
if (rideItem->isDirty() == true) {
|
||||
@@ -908,6 +911,7 @@ MainWindow::showTreeContextMenuPopup(const QPoint &pos)
|
||||
menu.addAction(actBestInt);
|
||||
menu.addAction(actPowerPeaks);
|
||||
menu.addAction(actSplitRide);
|
||||
menu.addAction(actTweetRide);
|
||||
|
||||
menu.exec(treeWidget->mapToGlobal( pos ));
|
||||
}
|
||||
@@ -1425,3 +1429,19 @@ MainWindow::manualProcess(QString name)
|
||||
p->exec();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::tweetRide()
|
||||
{
|
||||
QTreeWidgetItem *_item = treeWidget->currentItem();
|
||||
if (_item==NULL || _item->type() != RIDE_TYPE)
|
||||
return;
|
||||
|
||||
RideItem *item = dynamic_cast<RideItem*>(_item);
|
||||
item->computeMetrics();
|
||||
|
||||
TwitterDialog *twitterDialog = new TwitterDialog(this, item);
|
||||
twitterDialog->setWindowModality(Qt::ApplicationModal);
|
||||
twitterDialog->exec();
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ class MainWindow : public QMainWindow
|
||||
void frontInterval();
|
||||
void backInterval();
|
||||
void intervalEdited(QTreeWidgetItem *, int);
|
||||
void tweetRide();
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -1819,3 +1819,29 @@ CPPage::zonesChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Twitter Config page
|
||||
//
|
||||
TwitterPage::TwitterPage(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
boost::shared_ptr<QSettings> settings = GetApplicationSettings();
|
||||
QTabWidget *tabs = new QTabWidget(this);
|
||||
QWidget *twitter = new QWidget(this);
|
||||
tabs->addTab(twitter, tr("Twitter Config"));
|
||||
QHBoxLayout *twitterlayout = new QHBoxLayout(twitter);
|
||||
|
||||
accountLabel = new QLabel(tr("Twitter User Name"),this);
|
||||
accountName = new QLineEdit(tr(""), this);
|
||||
|
||||
passwordLabel = new QLabel(tr("Password"),this);
|
||||
passwordEdit = new QLineEdit(tr(""), this);
|
||||
passwordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
twitterlayout->addWidget(accountLabel);
|
||||
twitterlayout->addWidget(accountName);
|
||||
twitterlayout->addWidget(passwordLabel);
|
||||
twitterlayout->addWidget(passwordEdit);
|
||||
|
||||
accountName->setText(settings->value(GC_TWITTER_USERNAME).toString());
|
||||
passwordEdit->setText(settings->value(GC_TWITTER_PASSWORD).toString());
|
||||
}
|
||||
|
||||
31
src/Pages.h
31
src/Pages.h
@@ -395,4 +395,35 @@ class ZonePage : public QWidget
|
||||
// local versions for modification
|
||||
};
|
||||
|
||||
class TwitterPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
TwitterPage(QWidget *parent = 0);
|
||||
void saveClicked();
|
||||
|
||||
// Children talk to each other
|
||||
SchemePage *schemePage;
|
||||
CPPage *cpPage;
|
||||
QLineEdit *accountName;
|
||||
QLineEdit *passwordEdit;
|
||||
|
||||
public slots:
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
MainWindow *main;
|
||||
bool changed;
|
||||
|
||||
QTabWidget *tabs;
|
||||
|
||||
// local versions for modification
|
||||
private:
|
||||
QLabel *accountLabel;
|
||||
QLabel *passwordLabel;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
#define GC_WORKOUTDIR "workoutDir"
|
||||
#define GC_TRAIN_SPLITTER_SIZES "trainwindow/splitterSizes"
|
||||
#define GC_LTM_SPLITTER_SIZES "ltmwindow/splitterSizes"
|
||||
#define GC_TWITTER_USERNAME "TwitterUser"
|
||||
#define GC_TWITTER_PASSWORD "TwitterPass"
|
||||
|
||||
// device Configurations NAME/SPEC/TYPE/DEFI/DEFR all get a number appended
|
||||
// to them to specify which configured device i.e. devices1 ... devicesn where
|
||||
|
||||
226
src/TwitterDialog.cpp
Normal file
226
src/TwitterDialog.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
#include "TwitterDialog.h"
|
||||
#include "Settings.h"
|
||||
#include <Qhttp>
|
||||
#include <QUrl>
|
||||
#include "TimeUtils.h"
|
||||
|
||||
TwitterDialog::TwitterDialog(MainWindow *mainWindow, RideItem *item) :
|
||||
mainWindow(mainWindow)
|
||||
{
|
||||
ride = item;
|
||||
settings = GetApplicationSettings();
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowTitle("Tweet Your Ride");
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
|
||||
QGroupBox *groupBox = new QGroupBox(tr("Choose which metrics you wish to tweet: "));
|
||||
|
||||
workoutTimeChk = new QCheckBox(tr("Workout Time"));
|
||||
timeRidingChk = new QCheckBox(tr("Time Riding"));
|
||||
totalDistanceChk = new QCheckBox(tr("Total Distance"));
|
||||
elevationGainChk = new QCheckBox(tr("Elevation Gain"));
|
||||
totalWorkChk = new QCheckBox(tr("Total Work (kj)"));
|
||||
averageSpeedChk = new QCheckBox(tr("Average Speed"));
|
||||
averagePowerChk = new QCheckBox(tr("Average Power"));
|
||||
averageHRMChk = new QCheckBox(tr("Average Heart Rate"));
|
||||
averageCadenceChk = new QCheckBox(tr("Average Cadence"));
|
||||
maxPowerChk = new QCheckBox(tr("Max Power"));
|
||||
maxHRMChk = new QCheckBox(tr("Max Heart Rate"));
|
||||
|
||||
QGridLayout *vbox = new QGridLayout();
|
||||
vbox->addWidget(workoutTimeChk,0,0);
|
||||
vbox->addWidget(timeRidingChk,0,1);
|
||||
vbox->addWidget(totalWorkChk,1,0);
|
||||
vbox->addWidget(totalDistanceChk,1,1);
|
||||
vbox->addWidget(elevationGainChk,2,0);
|
||||
vbox->addWidget(averageSpeedChk,2,1);
|
||||
vbox->addWidget(averagePowerChk,3,0);
|
||||
vbox->addWidget(averageHRMChk,3,1);
|
||||
vbox->addWidget(averageCadenceChk,4,0);
|
||||
vbox->addWidget(maxPowerChk,4,1);
|
||||
vbox->addWidget(maxHRMChk,5,0);
|
||||
groupBox->setLayout(vbox);
|
||||
|
||||
QHBoxLayout *twitterMetricLayout = new QHBoxLayout;
|
||||
QLabel *twitterLabel = new QLabel(tr("Twitter Message:"));
|
||||
twitterMessageEdit = new QLineEdit();
|
||||
twitterMetricLayout->addWidget(twitterLabel);
|
||||
twitterMetricLayout->addWidget(twitterMessageEdit);
|
||||
twitterLengthLabel = new QLineEdit(tr("Message Length: "));
|
||||
twitterLengthLabel->setEnabled(false);
|
||||
twitterMetricLayout->addWidget(twitterLengthLabel);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
tweetButton = new QPushButton(tr("&Tweet Ride"), this);
|
||||
buttonLayout->addWidget(tweetButton);
|
||||
cancelButton = new QPushButton(tr("&Cancel"), this);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
mainLayout->addWidget(groupBox);
|
||||
mainLayout->addLayout(twitterMetricLayout);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
connect(tweetButton, SIGNAL(clicked()), this, SLOT(tweetCurrentRide()));
|
||||
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
|
||||
connect(workoutTimeChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(timeRidingChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(totalDistanceChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(elevationGainChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(totalWorkChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(averageSpeedChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(averagePowerChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(averageHRMChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(averageCadenceChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(maxPowerChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(maxHRMChk, SIGNAL(stateChanged(int)), this, SLOT(onCheck(int)));
|
||||
connect(twitterMessageEdit, SIGNAL(textChanged(QString)), this, SLOT(tweetMsgChange(QString)));
|
||||
}
|
||||
void
|
||||
TwitterDialog::tweetCurrentRide()
|
||||
{
|
||||
setEnabled(false);
|
||||
QString twitterMsg = getTwitterMessage();
|
||||
QString post = "/statuses/update.xml?status=";
|
||||
QString strUrl = QUrl::toPercentEncoding(twitterMsg + " #goldencheetah");
|
||||
qDebug() << post << strUrl;
|
||||
QHttp *twitter_http_updater = new QHttp();
|
||||
twitter_http_updater->setHost("www.twitter.com");
|
||||
twitter_http_updater->setUser(settings->value(GC_TWITTER_USERNAME).toString(), settings->value(GC_TWITTER_PASSWORD).toString());
|
||||
twitter_http_updater->post(post+strUrl, QByteArray());
|
||||
connect(twitter_http_updater, SIGNAL(done(bool)), this, SLOT(updateTwitterStatusFinish(bool)));
|
||||
}
|
||||
|
||||
void TwitterDialog::updateTwitterStatusFinish(bool error)
|
||||
{
|
||||
if(error == true)
|
||||
QMessageBox::warning(this, tr("Tweeted Ride"), tr("Tweet Not Sent"));
|
||||
else
|
||||
QMessageBox::information(this, tr("Tweeted Ride"), tr("Tweet Sent"));
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
QString TwitterDialog::getTwitterMessage()
|
||||
{
|
||||
RideMetricPtr m;
|
||||
double tmp;
|
||||
QString twitterMsg;
|
||||
QVariant unit = settings->value(GC_UNIT);
|
||||
bool useMetricUnits = (unit.toString() == "Metric");
|
||||
|
||||
if(workoutTimeChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("workout_time");
|
||||
tmp = round(m->value(true));
|
||||
QString msg = QString("Workout Time: %1").arg(time_to_string(tmp));
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
if(timeRidingChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("time_riding");
|
||||
tmp = round(m->value(true));
|
||||
QString msg = QString("Time Riding: %1").arg(time_to_string(tmp));
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
if(totalDistanceChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("total_distance");
|
||||
tmp = round(m->value(useMetricUnits));
|
||||
QString msg = QString("Total Distance: %1 " + (useMetricUnits ? tr("KM") : tr("Miles"))).arg(tmp);
|
||||
qDebug() << msg;
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
if(elevationGainChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("elevation_gain");
|
||||
tmp = round(m->value(useMetricUnits));
|
||||
QString msg = QString("Elevation Gained: %1"+ (useMetricUnits ? tr("Meters") : tr("Feet"))).arg(tmp);
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
if(totalWorkChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("total_work");
|
||||
tmp = round(m->value(true));
|
||||
QString msg = QString("Total Work (kj): %1").arg(tmp);
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
if(averageSpeedChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("average_speed");
|
||||
tmp = round(m->value(useMetricUnits));
|
||||
QString msg = QString("Average Speed: %1"+ (useMetricUnits ? tr("KM/H") : tr("MPH"))).arg(tmp);
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
if(averagePowerChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("average_power");
|
||||
tmp = round(m->value(true));
|
||||
QString msg = QString("Average Power: %1 watts").arg(tmp);
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
if(averageHRMChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("average_hr");
|
||||
tmp = round(m->value(true));
|
||||
QString msg = QString("Average Heart Rate: %1").arg(tmp);
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
if(averageCadenceChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("average_cad");
|
||||
tmp = round(m->value(true));
|
||||
QString msg = QString("Average Cadence: %1").arg(tmp);
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
if(maxPowerChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("max_power");
|
||||
tmp = round(m->value(true));
|
||||
QString msg = QString("Max Power: %1 watts").arg(tmp);
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
if(maxHRMChk->isChecked())
|
||||
{
|
||||
m = ride->metrics.value("max_heartrate");
|
||||
tmp = round(m->value(true));
|
||||
QString msg = QString("Max Heart Rate: %1").arg(tmp);
|
||||
twitterMsg.append(msg + " ");
|
||||
}
|
||||
|
||||
QString msg = twitterMessageEdit->text();
|
||||
if(!msg.endsWith(" "))
|
||||
msg.append(" ");
|
||||
|
||||
QString entireTweet = QString(msg + twitterMsg);
|
||||
|
||||
return entireTweet;
|
||||
|
||||
}
|
||||
|
||||
void TwitterDialog::onCheck(int state)
|
||||
{
|
||||
QString twitterMessage = getTwitterMessage();
|
||||
int tweetLength = twitterMessage.length();
|
||||
tweetLength += 15; //For the hashtag
|
||||
QString tweetMsgLength = QString(tr("Message Length: %1")).arg(tweetLength);
|
||||
twitterLengthLabel->setText(tweetMsgLength);
|
||||
}
|
||||
|
||||
void TwitterDialog::tweetMsgChange(QString)
|
||||
{
|
||||
QString twitterMessage = getTwitterMessage();
|
||||
int tweetLength = twitterMessage.length();
|
||||
tweetLength += 15; //For the hashtag
|
||||
QString tweetMsgLength = QString(tr("Message Length: %1")).arg(tweetLength);
|
||||
twitterLengthLabel->setText(tweetMsgLength);
|
||||
}
|
||||
47
src/TwitterDialog.h
Normal file
47
src/TwitterDialog.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef TWITTERDIALOG_H
|
||||
#define TWITTERDIALOG_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtGui>
|
||||
#include "MainWindow.h"
|
||||
#include "RideItem.h"
|
||||
|
||||
class TwitterDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TwitterDialog(MainWindow *mainWindow, RideItem *item);
|
||||
|
||||
signals:
|
||||
|
||||
private slots:
|
||||
void updateTwitterStatusFinish(bool error);
|
||||
void onCheck(int state);
|
||||
void tweetMsgChange(QString);
|
||||
void tweetCurrentRide();
|
||||
private:
|
||||
|
||||
QPushButton *tweetButton;
|
||||
QPushButton *cancelButton;
|
||||
MainWindow *mainWindow;
|
||||
QCheckBox *workoutTimeChk;
|
||||
QCheckBox *timeRidingChk;
|
||||
QCheckBox *totalDistanceChk;
|
||||
QCheckBox *elevationGainChk;
|
||||
QCheckBox *totalWorkChk;
|
||||
QCheckBox *averageSpeedChk;
|
||||
QCheckBox *averagePowerChk;
|
||||
QCheckBox *averageHRMChk;
|
||||
QCheckBox *averageCadenceChk;
|
||||
QCheckBox *maxPowerChk;
|
||||
QCheckBox *maxHRMChk;
|
||||
QLineEdit *twitterMessageEdit;
|
||||
QLineEdit *twitterLengthLabel;
|
||||
|
||||
RideItem *ride;
|
||||
QString getTwitterMessage();
|
||||
boost::shared_ptr<QSettings> settings;
|
||||
|
||||
};
|
||||
|
||||
#endif // TWITTERDIALOG_H
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>images/twitter.png</file>
|
||||
<file>images/cyclist.png</file>
|
||||
<file>images/imetrics.png</file>
|
||||
<file>images/power.png</file>
|
||||
|
||||
@@ -151,6 +151,7 @@ HEADERS += \
|
||||
TrainTabs.h \
|
||||
TrainTool.h \
|
||||
TrainWindow.h \
|
||||
TwitterDialog.h \
|
||||
Units.h \
|
||||
ViewSelection.h \
|
||||
WeeklySummaryWindow.h \
|
||||
@@ -258,6 +259,7 @@ SOURCES += \
|
||||
TrainTabs.cpp \
|
||||
TrainTool.cpp \
|
||||
TrainWindow.cpp \
|
||||
TwitterDialog.cpp \
|
||||
ViewSelection.cpp \
|
||||
WeeklySummaryWindow.cpp \
|
||||
WkoRideFile.cpp \
|
||||
|
||||
Reference in New Issue
Block a user