mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
Configure Seasons in ConfigDialog
Allow the user to add,delete and reorder seasons in the config dialog. Although the user could create and manipulate seasons / date ranges in the LTM chart, this provides a more coherent place to do the same but also adds the ability to re-order seasons. Fixes #399.
This commit is contained in:
220
src/Pages.cpp
220
src/Pages.cpp
@@ -250,9 +250,11 @@ CyclistPage::CyclistPage(MainWindow *main) :
|
||||
QWidget *rdTab = new QWidget(this);
|
||||
QWidget *psTab = new QWidget(this);
|
||||
QWidget *pmTab = new QWidget(this);
|
||||
QWidget *seTab = new QWidget(this);
|
||||
tabs->addTab(rdTab, tr("About Me"));
|
||||
tabs->addTab(cpTab, tr("Power Zones"));
|
||||
tabs->addTab(hrTab, tr("HR Zones"));
|
||||
tabs->addTab(seTab, tr("Seasons"));
|
||||
tabs->addTab(pmTab, tr("Performance Manager"));
|
||||
tabs->addTab(psTab, tr("Passwords"));
|
||||
QVBoxLayout *cpLayout = new QVBoxLayout(cpTab);
|
||||
@@ -260,6 +262,7 @@ CyclistPage::CyclistPage(MainWindow *main) :
|
||||
QVBoxLayout *pmLayout = new QVBoxLayout(pmTab);
|
||||
QVBoxLayout *rdLayout = new QVBoxLayout(rdTab);
|
||||
QVBoxLayout *psLayout = new QVBoxLayout(psTab);
|
||||
QVBoxLayout *seLayout = new QVBoxLayout(seTab);
|
||||
|
||||
riderPage = new RiderPage(this, mainWindow);
|
||||
rdLayout->addWidget(riderPage);
|
||||
@@ -273,6 +276,9 @@ CyclistPage::CyclistPage(MainWindow *main) :
|
||||
passPage = new CredentialsPage(this, mainWindow);
|
||||
psLayout->addWidget(passPage);
|
||||
|
||||
seasonsPage = new SeasonsPage(this, mainWindow);
|
||||
seLayout->addWidget(seasonsPage);
|
||||
|
||||
perfManLabel = new QLabel(tr("Performance Manager"));
|
||||
showSBToday = new QCheckBox(tr("Show Stress Balance Today"), this);
|
||||
showSBToday->setChecked(appsettings->cvalue(mainWindow->cyclist, GC_SB_TODAY).toInt());
|
||||
@@ -330,6 +336,7 @@ CyclistPage::saveClicked()
|
||||
hrZonePage->saveClicked();
|
||||
riderPage->saveClicked();
|
||||
passPage->saveClicked();
|
||||
seasonsPage->saveClicked();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -3632,3 +3639,216 @@ void CredentialsPage::saveTwitter()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Season Editor
|
||||
//
|
||||
SeasonsPage::SeasonsPage(QWidget *parent, MainWindow *mainWindow) : QWidget(parent), mainWindow(mainWindow)
|
||||
{
|
||||
QGridLayout *mainLayout = new QGridLayout(this);
|
||||
QFormLayout *editLayout = new QFormLayout;
|
||||
editLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
|
||||
|
||||
// get the list
|
||||
array = mainWindow->seasons->seasons;
|
||||
|
||||
// Edit widgets
|
||||
nameEdit = new QLineEdit(this);
|
||||
typeEdit = new QComboBox(this);
|
||||
foreach(QString t, Season::types) typeEdit->addItem(t);
|
||||
typeEdit->setCurrentIndex(0);
|
||||
fromEdit = new QDateEdit(this);
|
||||
fromEdit->setCalendarPopup(true);
|
||||
|
||||
toEdit = new QDateEdit(this);
|
||||
toEdit->setCalendarPopup(true);
|
||||
|
||||
// set form
|
||||
editLayout->addRow(new QLabel("Name"), nameEdit);
|
||||
editLayout->addRow(new QLabel("Type"), typeEdit);
|
||||
editLayout->addRow(new QLabel("From"), fromEdit);
|
||||
editLayout->addRow(new QLabel("To"), toEdit);
|
||||
|
||||
upButton = new QPushButton(tr("Move up"));
|
||||
downButton = new QPushButton(tr("Move down"));
|
||||
addButton = new QPushButton(tr("Add"));
|
||||
deleteButton = new QPushButton(tr("Delete"));
|
||||
|
||||
QVBoxLayout *actionButtons = new QVBoxLayout;
|
||||
actionButtons->addWidget(deleteButton);
|
||||
actionButtons->addWidget(upButton);
|
||||
actionButtons->addWidget(downButton);
|
||||
actionButtons->addStretch();
|
||||
|
||||
seasons = new QTreeWidget;
|
||||
seasons->headerItem()->setText(0, tr("Name"));
|
||||
seasons->headerItem()->setText(1, tr("Type"));
|
||||
seasons->headerItem()->setText(2, tr("From"));
|
||||
seasons->headerItem()->setText(3, tr("To"));
|
||||
seasons->setColumnCount(4);
|
||||
seasons->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
//seasons->setEditTriggers(QAbstractItemView::SelectedClicked); // allow edit
|
||||
seasons->setUniformRowHeights(true);
|
||||
seasons->setIndentation(0);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
seasons->header()->resizeSection(0,160); // tab
|
||||
seasons->header()->resizeSection(1,80); // name
|
||||
seasons->header()->resizeSection(2,130); // type
|
||||
seasons->header()->resizeSection(3,130); // values
|
||||
#else
|
||||
seasons->header()->resizeSection(0,160); // tab
|
||||
seasons->header()->resizeSection(1,80); // name
|
||||
seasons->header()->resizeSection(2,130); // type
|
||||
seasons->header()->resizeSection(3,130); // values
|
||||
#endif
|
||||
|
||||
foreach(Season season, array) {
|
||||
QTreeWidgetItem *add;
|
||||
|
||||
if (season.type == Season::temporary) continue;
|
||||
|
||||
add = new QTreeWidgetItem(seasons->invisibleRootItem());
|
||||
add->setFlags(add->flags() & ~Qt::ItemIsEditable);
|
||||
|
||||
// tab name
|
||||
add->setText(0, season.name);
|
||||
// type
|
||||
add->setText(1, Season::types[static_cast<int>(season.type)]);
|
||||
// from
|
||||
add->setText(2, season.start.toString("ddd MMM d, yyyy"));
|
||||
// to
|
||||
add->setText(3, season.end.toString("ddd MMM d, yyyy"));
|
||||
// guid -- hidden
|
||||
add->setText(4, season._id.toString());
|
||||
|
||||
}
|
||||
seasons->setCurrentItem(seasons->invisibleRootItem()->child(0));
|
||||
|
||||
mainLayout->addLayout(editLayout, 0,0);
|
||||
mainLayout->addWidget(addButton, 0,1, Qt::AlignTop);
|
||||
mainLayout->addWidget(seasons, 1,0);
|
||||
mainLayout->addLayout(actionButtons, 1,1);
|
||||
|
||||
// set all the edits to a default value
|
||||
clearEdit();
|
||||
|
||||
// connect up slots
|
||||
connect(upButton, SIGNAL(clicked()), this, SLOT(upClicked()));
|
||||
connect(downButton, SIGNAL(clicked()), this, SLOT(downClicked()));
|
||||
connect(addButton, SIGNAL(clicked()), this, SLOT(addClicked()));
|
||||
connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked()));
|
||||
}
|
||||
|
||||
void
|
||||
SeasonsPage::clearEdit()
|
||||
{
|
||||
typeEdit->setCurrentIndex(0);
|
||||
nameEdit->setText("");
|
||||
fromEdit->setDate(QDate::currentDate());
|
||||
toEdit->setDate(QDate::currentDate().addMonths(3));
|
||||
}
|
||||
|
||||
void
|
||||
SeasonsPage::upClicked()
|
||||
{
|
||||
if (seasons->currentItem()) {
|
||||
int index = seasons->invisibleRootItem()->indexOfChild(seasons->currentItem());
|
||||
if (index == 0) return; // its at the top already
|
||||
|
||||
// movin on up!
|
||||
QTreeWidgetItem* moved = seasons->invisibleRootItem()->takeChild(index);
|
||||
seasons->invisibleRootItem()->insertChild(index-1, moved);
|
||||
seasons->setCurrentItem(moved);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SeasonsPage::downClicked()
|
||||
{
|
||||
if (seasons->currentItem()) {
|
||||
int index = seasons->invisibleRootItem()->indexOfChild(seasons->currentItem());
|
||||
if (index == (seasons->invisibleRootItem()->childCount()-1)) return; // its at the bottom already
|
||||
|
||||
QTreeWidgetItem* moved = seasons->invisibleRootItem()->takeChild(index);
|
||||
seasons->invisibleRootItem()->insertChild(index+1, moved);
|
||||
seasons->setCurrentItem(moved);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SeasonsPage::renameClicked()
|
||||
{
|
||||
// which one is selected?
|
||||
if (seasons->currentItem()) seasons->editItem(seasons->currentItem(), 0);
|
||||
}
|
||||
|
||||
void
|
||||
SeasonsPage::addClicked()
|
||||
{
|
||||
if (nameEdit->text() == "") return; // just ignore it
|
||||
|
||||
// swap if not right way around
|
||||
if (fromEdit->date() > toEdit->date()) {
|
||||
QDate temp = fromEdit->date();
|
||||
fromEdit->setDate(toEdit->date());
|
||||
toEdit->setDate(temp);
|
||||
}
|
||||
|
||||
QTreeWidgetItem *add = new QTreeWidgetItem(seasons->invisibleRootItem());
|
||||
add->setFlags(add->flags() & ~Qt::ItemIsEditable);
|
||||
|
||||
// tab name
|
||||
add->setText(0, nameEdit->text());
|
||||
// type
|
||||
add->setText(1, Season::types[typeEdit->currentIndex()]);
|
||||
// from
|
||||
add->setText(2, fromEdit->date().toString("ddd MMM d, yyyy"));
|
||||
// to
|
||||
add->setText(3, toEdit->date().toString("ddd MMM d, yyyy"));
|
||||
// guid -- hidden
|
||||
add->setText(4, QUuid::createUuid().toString());
|
||||
|
||||
// now clear the edits
|
||||
clearEdit();
|
||||
}
|
||||
|
||||
void
|
||||
SeasonsPage::deleteClicked()
|
||||
{
|
||||
if (seasons->currentItem()) {
|
||||
int index = seasons->invisibleRootItem()->indexOfChild(seasons->currentItem());
|
||||
|
||||
// zap!
|
||||
delete seasons->invisibleRootItem()->takeChild(index);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SeasonsPage::saveClicked()
|
||||
{
|
||||
// update the season array to reflect our edits
|
||||
array.clear();
|
||||
for(int i=0; i<seasons->invisibleRootItem()->childCount(); i++) {
|
||||
|
||||
QTreeWidgetItem *item = seasons->invisibleRootItem()->child(i);
|
||||
|
||||
Season add;
|
||||
add.name = item->text(0);
|
||||
add.type = Season::types.indexOf(item->text(1));
|
||||
add.start = QDate::fromString(item->text(2), "ddd MMM d, yyyy");
|
||||
add.end = QDate::fromString(item->text(3), "ddd MMM d, yyyy");
|
||||
add._id = QUuid(item->text(4));
|
||||
array << add;
|
||||
}
|
||||
|
||||
// write to disk
|
||||
QString file = QString(mainWindow->home.absolutePath() + "/seasons.xml");
|
||||
SeasonParser::serialize(file, array);
|
||||
|
||||
// wipe existing mainwindow config
|
||||
delete mainWindow->seasons;
|
||||
|
||||
// re-read
|
||||
mainWindow->seasons = new Seasons(mainWindow->home);
|
||||
}
|
||||
|
||||
37
src/Pages.h
37
src/Pages.h
@@ -24,6 +24,8 @@
|
||||
#include "DeviceConfiguration.h"
|
||||
#include "RideMetadata.h"
|
||||
#include "DataProcessor.h"
|
||||
#include "Season.h"
|
||||
#include "SeasonParser.h"
|
||||
|
||||
#ifdef GC_HAVE_LIBOAUTH
|
||||
extern "C" {
|
||||
@@ -46,6 +48,7 @@ class FieldsPage;
|
||||
class MeasuresPage;
|
||||
class Colors;
|
||||
class RiderPage;
|
||||
class SeasonsPage;
|
||||
|
||||
class ConfigurationPage : public QWidget
|
||||
{
|
||||
@@ -211,6 +214,7 @@ class CyclistPage : public QWidget
|
||||
CredentialsPage *passPage;
|
||||
ZonePage *zonePage;
|
||||
HrZonePage *hrZonePage;
|
||||
SeasonsPage *seasonsPage;
|
||||
|
||||
private:
|
||||
QVBoxLayout *perfManLayout;
|
||||
@@ -684,6 +688,39 @@ protected:
|
||||
// local versions for modification
|
||||
};
|
||||
|
||||
class SeasonsPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
G_OBJECT
|
||||
|
||||
|
||||
public:
|
||||
SeasonsPage(QWidget *parent, MainWindow *main);
|
||||
void getDefinitions(QList<Season>&);
|
||||
|
||||
public slots:
|
||||
void addClicked();
|
||||
void upClicked();
|
||||
void downClicked();
|
||||
void renameClicked();
|
||||
void deleteClicked();
|
||||
void clearEdit();
|
||||
void saveClicked();
|
||||
|
||||
private:
|
||||
|
||||
QTreeWidget *seasons;
|
||||
MainWindow *mainWindow;
|
||||
|
||||
QLineEdit *nameEdit;
|
||||
QComboBox *typeEdit;
|
||||
QDateEdit *fromEdit, *toEdit;
|
||||
|
||||
QPushButton *upButton, *downButton, *addButton, *renameButton, *deleteButton;
|
||||
|
||||
QList<Season> array;
|
||||
};
|
||||
|
||||
class MeasuresPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -25,6 +25,18 @@
|
||||
|
||||
#define tr(s) QObject::tr(s)
|
||||
|
||||
static QList<QString> _setSeasonTypes()
|
||||
{
|
||||
QList<QString> returning;
|
||||
returning << "Season"
|
||||
<< "Cycle"
|
||||
<< "Adhoc"
|
||||
<< "System";
|
||||
return returning;
|
||||
}
|
||||
|
||||
QList<QString> Season::types = _setSeasonTypes();
|
||||
|
||||
Season::Season()
|
||||
{
|
||||
type = season; // by default seasons are of type season
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
class Season
|
||||
{
|
||||
public:
|
||||
static QList<QString> types;
|
||||
enum SeasonType { season=0, cycle=1, adhoc=2, temporary=3 };
|
||||
//typedef enum seasontype SeasonType;
|
||||
|
||||
@@ -48,8 +49,6 @@ class Season
|
||||
void setId(QUuid x) { _id = x; }
|
||||
QVector<int> &load() { return _load; }
|
||||
|
||||
|
||||
private:
|
||||
QDate start; // first day of the season
|
||||
QDate end; // last day of the season
|
||||
int _days; // how many days in this season?
|
||||
|
||||
Reference in New Issue
Block a user