mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
Reinstate mini calendar on sidebar
This is the first step to reinstating the calendar on the analysis view sidebar. Next step is to enhance it to show multiple months and then to refactor the diary sidebar GcCalendar to use it.
This commit is contained in:
@@ -702,3 +702,360 @@ GcCalendar::setSummary()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
GcMiniCalendar::GcMiniCalendar(MainWindow *main) : main(main)
|
||||
{
|
||||
setContentsMargins(0,0,0,0);
|
||||
setAutoFillBackground(true);
|
||||
|
||||
month = year = 0;
|
||||
_ride = NULL;
|
||||
|
||||
setStyleSheet("QLabel { color: gray; }");
|
||||
layout = new QVBoxLayout(this);
|
||||
layout->setSpacing(0);
|
||||
layout->setContentsMargins(10,10,10,10);
|
||||
|
||||
black.setColor(QPalette::WindowText, Qt::gray);
|
||||
white.setColor(QPalette::WindowText, Qt::white);
|
||||
grey.setColor(QPalette::WindowText, Qt::gray);
|
||||
|
||||
// get the model
|
||||
fieldDefinitions = main->rideMetadata()->getFields();
|
||||
calendarModel = new GcCalendarModel(this, &fieldDefinitions, main);
|
||||
calendarModel->setSourceModel(main->listView->sqlModel);
|
||||
|
||||
QHBoxLayout *line = new QHBoxLayout;
|
||||
line->setSpacing(0);
|
||||
line->setContentsMargins(0,0,0,0);
|
||||
|
||||
QFont font;
|
||||
font.setPointSize(12);
|
||||
left = new GcLabel("<", this);
|
||||
left->setAutoFillBackground(false);
|
||||
left->setPalette(white);
|
||||
left->setFont(font);
|
||||
left->setAlignment(Qt::AlignLeft);
|
||||
line->addWidget(left);
|
||||
connect (left, SIGNAL(clicked()), this, SLOT(previous()));
|
||||
|
||||
font.setPointSize(12);
|
||||
monthName = new GcLabel("January 2012", this);
|
||||
monthName->setAutoFillBackground(false);
|
||||
monthName->setPalette(white);
|
||||
monthName->setFont(font);
|
||||
monthName->setAlignment(Qt::AlignCenter);
|
||||
line->addWidget(monthName);
|
||||
|
||||
font.setPointSize(12);
|
||||
right = new GcLabel(">", this);
|
||||
right->setAutoFillBackground(false);
|
||||
right->setPalette(white);
|
||||
right->setFont(font);
|
||||
right->setAlignment(Qt::AlignRight);
|
||||
line->addWidget(right);
|
||||
connect (right, SIGNAL(clicked()), this, SLOT(next()));
|
||||
|
||||
QWidget *month = new QWidget(this);
|
||||
month->setContentsMargins(0,0,0,0);
|
||||
month->setFixedWidth(180);
|
||||
month->setFixedHeight(180);
|
||||
QGridLayout *dayLayout = new QGridLayout(month);
|
||||
dayLayout->setSpacing(1);
|
||||
dayLayout->setContentsMargins(0,0,0,0);
|
||||
dayLayout->addLayout(line, 0,0,1,7);
|
||||
layout->addWidget(month, Qt::AlignCenter);
|
||||
|
||||
font.setWeight(QFont::Normal);
|
||||
|
||||
// Mon
|
||||
font.setPointSize(9);
|
||||
GcLabel *day = new GcLabel("Mon", this);
|
||||
day->setFont(font);
|
||||
day->setAutoFillBackground(false);
|
||||
day->setPalette(white);
|
||||
day->setFont(font);
|
||||
day->setAlignment(Qt::AlignCenter);
|
||||
dayLayout->addWidget(day, 1, 0);
|
||||
|
||||
// Tue
|
||||
day = new GcLabel("Tue", this);
|
||||
day->setFont(font);
|
||||
day->setAutoFillBackground(false);
|
||||
day->setPalette(white);
|
||||
day->setFont(font);
|
||||
day->setAlignment(Qt::AlignCenter);
|
||||
dayLayout->addWidget(day, 1, 1);
|
||||
|
||||
// Wed
|
||||
day = new GcLabel("Wed", this);
|
||||
day->setFont(font);
|
||||
day->setAutoFillBackground(false);
|
||||
day->setPalette(white);
|
||||
day->setFont(font);
|
||||
day->setAlignment(Qt::AlignCenter);
|
||||
dayLayout->addWidget(day, 1, 2);
|
||||
|
||||
// Thu
|
||||
day = new GcLabel("Thu", this);
|
||||
day->setFont(font);
|
||||
day->setAutoFillBackground(false);
|
||||
day->setPalette(white);
|
||||
day->setFont(font);
|
||||
day->setAlignment(Qt::AlignCenter);
|
||||
dayLayout->addWidget(day, 1, 3);
|
||||
|
||||
// Fri
|
||||
day = new GcLabel("Fri", this);
|
||||
day->setFont(font);
|
||||
day->setAutoFillBackground(false);
|
||||
day->setPalette(white);
|
||||
day->setFont(font);
|
||||
day->setAlignment(Qt::AlignCenter);
|
||||
dayLayout->addWidget(day, 1, 4);
|
||||
|
||||
// Sat
|
||||
day = new GcLabel("Sat", this);
|
||||
day->setFont(font);
|
||||
day->setAutoFillBackground(false);
|
||||
day->setPalette(white);
|
||||
day->setFont(font);
|
||||
day->setAlignment(Qt::AlignCenter);
|
||||
dayLayout->addWidget(day, 1, 5);
|
||||
|
||||
// Sun
|
||||
day = new GcLabel("Sun", this);
|
||||
day->setFont(font);
|
||||
day->setAutoFillBackground(false);
|
||||
day->setPalette(white);
|
||||
day->setFont(font);
|
||||
day->setAlignment(Qt::AlignCenter);
|
||||
dayLayout->addWidget(day, 1, 6);
|
||||
|
||||
signalMapper = new QSignalMapper(this);
|
||||
font.setPointSize(11);
|
||||
for (int row=2; row<8; row++) {
|
||||
|
||||
for (int col=0; col < 7; col++) {
|
||||
|
||||
GcLabel *d = new GcLabel(QString("%1").arg((row-2)*7+col), this);
|
||||
d->setFont(font);
|
||||
d->setAutoFillBackground(false);
|
||||
d->setPalette(grey);
|
||||
d->setStyleSheet("color: gray;");
|
||||
d->setAlignment(Qt::AlignCenter);
|
||||
dayLayout->addWidget(d,row,col);
|
||||
|
||||
// we like squares
|
||||
d->setFixedHeight(22);
|
||||
d->setFixedWidth(22);
|
||||
|
||||
dayLabels << d;
|
||||
|
||||
if (row== 3 && col == 4) d->setSelected(true);
|
||||
|
||||
connect (d, SIGNAL(clicked()), signalMapper, SLOT(map()));
|
||||
signalMapper->setMapping(d, (row-2)*7+col);
|
||||
}
|
||||
}
|
||||
layout->addStretch();
|
||||
|
||||
// day clicked
|
||||
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(dayClicked(int)));
|
||||
|
||||
// refresh on these events...
|
||||
connect(main, SIGNAL(rideAdded(RideItem*)), this, SLOT(refresh()));
|
||||
connect(main, SIGNAL(rideDeleted(RideItem*)), this, SLOT(refresh()));
|
||||
connect(main, SIGNAL(configChanged()), this, SLOT(refresh()));
|
||||
|
||||
// set up for current selections
|
||||
refresh();
|
||||
}
|
||||
|
||||
void
|
||||
GcMiniCalendar::refresh()
|
||||
{
|
||||
calendarModel->setMonth(month, year);
|
||||
repaint();
|
||||
}
|
||||
|
||||
bool
|
||||
GcMiniCalendar::event(QEvent *e)
|
||||
{
|
||||
if (e->type() != QEvent::ToolTip && e->type() != QEvent::Paint && e->type() != QEvent::Destroy &&
|
||||
e->type() != QEvent::LayoutRequest) {
|
||||
main->setBubble("");
|
||||
//qDebug()<<"event"<<e->type();
|
||||
}
|
||||
|
||||
if (e->type() == QEvent::Paint) {
|
||||
// fill the background
|
||||
QPainter painter(this);
|
||||
QRect all(0,0,width(),height());
|
||||
//painter.fillRect(all, QColor("#B3B4BA"));
|
||||
painter.fillRect(all, QColor(Qt::white));
|
||||
}
|
||||
|
||||
int n=0;
|
||||
if (e->type() == QEvent::ToolTip) {
|
||||
|
||||
// are we hovering over a label?
|
||||
foreach(GcLabel *label, dayLabels) {
|
||||
if (label->underMouse()) {
|
||||
if (dayLabels.at(n)->text() == "") return false;
|
||||
|
||||
// select a ride if there is one for this one?
|
||||
int row = n / 7;
|
||||
int col = n % 7;
|
||||
|
||||
QModelIndex p = calendarModel->index(row,col);
|
||||
QStringList files = calendarModel->data(p, GcCalendarModel::FilenamesRole).toStringList();
|
||||
|
||||
QPoint pos = dynamic_cast<QHelpEvent*>(e)->pos();
|
||||
|
||||
// Popup bubble for ride
|
||||
if (files.count()) {
|
||||
if (files[0] == "calendar") ; // handle planned rides
|
||||
else main->setBubble(files.at(0), mapToGlobal(pos+QPoint(+2,+2)));
|
||||
}
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
void
|
||||
GcMiniCalendar::dayClicked(int i)
|
||||
{
|
||||
if (dayLabels.at(i)->text() == "") return;
|
||||
|
||||
// select a ride if there is one for this one?
|
||||
int row = i / 7;
|
||||
int col = i % 7;
|
||||
|
||||
|
||||
QModelIndex p = calendarModel->index(row,col);
|
||||
QStringList files = calendarModel->data(p, GcCalendarModel::FilenamesRole).toStringList();
|
||||
|
||||
if (files.count()) // if more than one file cycle through them?
|
||||
main->selectRideFile(QFileInfo(files[0]).fileName());
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
GcMiniCalendar::previous()
|
||||
{
|
||||
QList<QDateTime> allDates = main->metricDB->db()->getAllDates();
|
||||
qSort(allDates);
|
||||
|
||||
// begin of month
|
||||
QDateTime bom(QDate(year,month,01), QTime(0,0,0));
|
||||
for(int i=allDates.count()-1; i>0; i--) {
|
||||
if (allDates.at(i) < bom) {
|
||||
|
||||
QDate date = allDates.at(i).date();
|
||||
calendarModel->setMonth(date.month(), date.year());
|
||||
|
||||
// find the day in the calendar...
|
||||
for (int day=42; day>0;day--) {
|
||||
|
||||
QModelIndex p = calendarModel->index(day/7,day%7);
|
||||
QDate heredate = calendarModel->date(p);
|
||||
if (date == heredate) {
|
||||
// select this ride...
|
||||
QStringList files = calendarModel->data(p, GcCalendarModel::FilenamesRole).toStringList();
|
||||
if (files.count()) main->selectRideFile(QFileInfo(files[0]).fileName());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GcMiniCalendar::next()
|
||||
{
|
||||
QList<QDateTime> allDates = main->metricDB->db()->getAllDates();
|
||||
qSort(allDates);
|
||||
|
||||
// end of month
|
||||
QDateTime eom(QDate(year,month,01).addMonths(1), QTime(00,00,00));
|
||||
for(int i=0; i<allDates.count(); i++) {
|
||||
if (allDates.at(i) >= eom) {
|
||||
|
||||
QDate date = allDates.at(i).date();
|
||||
calendarModel->setMonth(date.month(), date.year());
|
||||
|
||||
// find the day in the calendar...
|
||||
for (int day=0; day<42;day++) {
|
||||
|
||||
QModelIndex p = calendarModel->index(day/7,day%7);
|
||||
QDate heredate = calendarModel->date(p);
|
||||
if (date == heredate) {
|
||||
// select this ride...
|
||||
QStringList files = calendarModel->data(p, GcCalendarModel::FilenamesRole).toStringList();
|
||||
if (files.count()) main->selectRideFile(QFileInfo(files[0]).fileName());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GcMiniCalendar::setRide(RideItem *ride)
|
||||
{
|
||||
_ride = ride;
|
||||
|
||||
QDate when;
|
||||
if (_ride && _ride->ride()) when = _ride->dateTime.date();
|
||||
else when = QDate::currentDate();
|
||||
|
||||
// refresh the model
|
||||
if (when.month() != month || when.year() != year) {
|
||||
calendarModel->setMonth(when.month(), when.year());
|
||||
year = when.year();
|
||||
month = when.month();
|
||||
|
||||
monthName->setText(when.toString("MMMM yyyy"));
|
||||
}
|
||||
|
||||
// now reapply for each row/col of calendar...
|
||||
for (int row=0; row<6; row++) {
|
||||
for (int col=0; col < 7; col++) {
|
||||
|
||||
GcLabel *d = dayLabels.at(row*7+col);
|
||||
QModelIndex p = calendarModel->index(row,col);
|
||||
QDate date = calendarModel->date(p);
|
||||
|
||||
if (date.month() != month || date.year() != year) {
|
||||
d->setText("");
|
||||
d->setBg(false);
|
||||
d->setSelected(false);
|
||||
} else {
|
||||
d->setText(QString("%1").arg(date.day()));
|
||||
|
||||
// what color should it be?
|
||||
// for taste we /currently/ just set to bg to
|
||||
// highlight there is a ride there, colors /will/ come
|
||||
// back later when worked out a way of making it look
|
||||
// nice and not garish
|
||||
QList<QColor> colors = p.data(Qt::BackgroundRole).value<QList<QColor> >();
|
||||
if (colors.count()) {
|
||||
d->setBg(true);
|
||||
d->setPalette(black);
|
||||
d->setBgColor(colors.at(0)); // use first always
|
||||
} else {
|
||||
d->setBg(false);
|
||||
d->setPalette(white);
|
||||
}
|
||||
if (date == when) {
|
||||
d->setSelected(true);
|
||||
d->setPalette(white);
|
||||
} else d->setSelected(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
@@ -64,6 +64,47 @@ protected:
|
||||
QColor bgColor;
|
||||
};
|
||||
|
||||
class GcMiniCalendar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
GcMiniCalendar(MainWindow *);
|
||||
|
||||
public slots:
|
||||
|
||||
void setRide(RideItem *ride);
|
||||
void refresh();
|
||||
|
||||
void dayClicked(int num); // for when a day is selected
|
||||
void next();
|
||||
void previous();
|
||||
|
||||
bool event(QEvent *e);
|
||||
|
||||
signals:
|
||||
|
||||
protected:
|
||||
MainWindow *main;
|
||||
RideItem *_ride;
|
||||
int month, year;
|
||||
|
||||
QVBoxLayout *layout;
|
||||
|
||||
GcLabel *left, *right; // < ... >
|
||||
GcLabel *monthName; // January 2012
|
||||
GcLabel *dayNames[7]; // Mon .. Sun
|
||||
|
||||
QList<GcLabel*> dayLabels; // 1 .. 31
|
||||
|
||||
QSignalMapper *signalMapper; // for mapping dayLabels "clicked"
|
||||
|
||||
QPalette black, grey, white;
|
||||
QList<FieldDefinition> fieldDefinitions;
|
||||
GcCalendarModel *calendarModel;
|
||||
};
|
||||
|
||||
class GcCalendar : public QWidget // not a GcWindow - belongs on sidebar
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -659,12 +659,16 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
intervalSplitter->setCollapsible(0, false);
|
||||
intervalSplitter->setCollapsible(1, false);
|
||||
|
||||
GcSplitterItem *calendarItem = new GcSplitterItem(tr("Calendar"), iconFromPNG(":images/sidebar/calendar.png"), this);
|
||||
gcMiniCalendar = new GcMiniCalendar(this);
|
||||
calendarItem->addWidget(gcMiniCalendar);
|
||||
|
||||
analItem = new GcSplitterItem(tr("Activities"), iconFromPNG(":images/sidebar/folder.png"), this);
|
||||
QAction *moreAnalAct = new QAction(iconFromPNG(":images/sidebar/extra.png"), tr("Menu"), this);
|
||||
analItem->addAction(moreAnalAct);
|
||||
connect(moreAnalAct, SIGNAL(triggered(void)), this, SLOT(analysisPopup()));
|
||||
|
||||
analItem->addWidget(activityHistory);
|
||||
|
||||
intervalItem = new GcSplitterItem(tr("Intervals"), iconFromPNG(":images/mac/stop.png"), this);
|
||||
QAction *moreIntervalAct = new QAction(iconFromPNG(":images/sidebar/extra.png"), tr("Menu"), this);
|
||||
intervalItem->addAction(moreIntervalAct);
|
||||
@@ -672,6 +676,7 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
intervalItem->addWidget(intervalSplitter);
|
||||
|
||||
analSidebar = new GcSplitter(Qt::Vertical);
|
||||
analSidebar->addWidget(calendarItem);
|
||||
analSidebar->addWidget(analItem);
|
||||
analSidebar->addWidget(intervalItem);
|
||||
analSidebar->prepare(cyclist, "analysis");
|
||||
@@ -1235,6 +1240,7 @@ MainWindow::rideTreeWidgetSelectionChanged()
|
||||
diaryWindow->setProperty("ride", QVariant::fromValue<RideItem*>(dynamic_cast<RideItem*>(ride)));
|
||||
trainWindow->setProperty("ride", QVariant::fromValue<RideItem*>(dynamic_cast<RideItem*>(ride)));
|
||||
gcCalendar->setRide(ride);
|
||||
gcMiniCalendar->setRide(ride);
|
||||
|
||||
enableSaveButton(); // should it be enabled or not?
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ class IntervalSummaryWindow;
|
||||
class RideNavigator;
|
||||
class GcToolBar;
|
||||
class GcCalendar;
|
||||
class GcMiniCalendar;
|
||||
class GcBubble;
|
||||
class LTMSidebar;
|
||||
class LionFullScreen;
|
||||
@@ -415,6 +416,7 @@ class MainWindow : public QMainWindow
|
||||
QMenu *windowMenu;
|
||||
GcBubble *bubble;
|
||||
GcCalendar *gcCalendar;
|
||||
GcMiniCalendar *gcMiniCalendar;
|
||||
|
||||
// each view has its own controls XXX more to come
|
||||
QStackedWidget *masterControls,
|
||||
|
||||
@@ -39,6 +39,7 @@ class SearchFilterBox;
|
||||
class DiaryWindow;
|
||||
class BUGFIXQSortFilterProxyModel;
|
||||
class DataFilter;
|
||||
class GcMiniCalendar;
|
||||
|
||||
//
|
||||
// The RideNavigator
|
||||
@@ -62,6 +63,7 @@ class RideNavigator : public GcWindow
|
||||
friend class ::GroupByModel;
|
||||
friend class ::DiaryWindow;
|
||||
friend class ::GcCalendar;
|
||||
friend class ::GcMiniCalendar;
|
||||
friend class ::DataFilter;
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user