Athlete Measures on Calendar Day View (#4706)

* Showing the athlete measures to the calendar day view
* Actions to add or edit measures
* Refactoring: Moved the UI of the day view to its own class
This commit is contained in:
Joachim Kohlhammer
2025-09-25 01:44:33 +02:00
committed by GitHub
parent 36c98119d4
commit d0d5105bd3
3 changed files with 407 additions and 122 deletions

View File

@@ -40,7 +40,7 @@ PlanningCalendarWindow::PlanningCalendarWindow(Context *context)
{
mkControls();
calendar = new Calendar(QDate::currentDate(), static_cast<Qt::DayOfWeek>(getFirstDayOfWeek()));
calendar = new Calendar(QDate::currentDate(), static_cast<Qt::DayOfWeek>(getFirstDayOfWeek()), context->athlete->measures);
QVBoxLayout *mainLayout = new QVBoxLayout();
setChartLayout(mainLayout);
@@ -289,6 +289,9 @@ PlanningCalendarWindow::configChanged
updateSecondaryConfigCombo();
multiMetricSelector->updateMetrics();
}
if (what & CONFIG_ATHLETE) {
calendar->updateMeasures();
}
if (what & CONFIG_APPEARANCE) {
// change colors to reflect preferences
setProperty("color", GColor(CPLOTBACKGROUND));

View File

@@ -25,6 +25,8 @@
#include <QMouseEvent>
#include <QMenu>
#include <QToolBar>
#include <QDialog>
#include <QDialogButtonBox>
#include <QActionGroup>
#include <QHash>
#include <QDrag>
@@ -36,6 +38,7 @@
#include "Colors.h"
#include "Settings.h"
#include "Context.h"
//////////////////////////////////////////////////////////////////////////////
@@ -169,13 +172,9 @@ CalendarDayTable::CalendarDayTable
setItemDelegateForRow(0, new ColumnDelegatingItemDelegate(row0Delegates, this));
setItemDelegateForRow(1, new CalendarSummaryDelegate(20, this));
QStringList headers;
headers << ""
<< tr("Activities");
setHorizontalHeaderLabels(headers);
horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
horizontalHeader()->setVisible(false);
verticalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
verticalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
verticalHeader()->setVisible(false);
@@ -489,6 +488,8 @@ void
CalendarDayTable::dragLeaveEvent
(QDragLeaveEvent *event)
{
Q_UNUSED(event)
setDropIndicator(-1, BlockIndicator::NoBlock);
}
@@ -1208,57 +1209,327 @@ CalendarMonthTable::showContextMenu
//////////////////////////////////////////////////////////////////////////////
// Calendar
// CalendarDayView
Calendar::Calendar
(Qt::DayOfWeek firstDayOfWeek, QWidget *parent)
: Calendar(QDate::currentDate(), firstDayOfWeek, parent)
CalendarDayView::CalendarDayView
(const QDate &dateInMonth, Qt::DayOfWeek firstDayOfWeek, Measures * const athleteMeasures, QWidget *parent)
: QWidget(parent), athleteMeasures(athleteMeasures)
{
}
Calendar::Calendar
(const QDate &dateInMonth, Qt::DayOfWeek firstDayOfWeek, QWidget *parent)
: QWidget(parent)
{
qRegisterMetaType<CalendarDay>("CalendarDay");
qRegisterMetaType<CalendarSummary>("CalendarSummary");
dayDateSelector = new CalendarOverview();
dayPhaseLabel = new QLabel(tr("No Phase"));
dayPhaseLabel->setWordWrap(true);
dayEventLabel = new QLabel(tr("No Event"));
dayEventLabel->setWordWrap(true);
measureTabs = new QTabWidget();
QWidget *dayLeftPane = new QWidget();
QVBoxLayout *leftPaneLayout = new QVBoxLayout(dayLeftPane);
leftPaneLayout->addWidget(dayDateSelector);
leftPaneLayout->addWidget(dayPhaseLabel);
leftPaneLayout->addWidget(dayEventLabel);
leftPaneLayout->addStretch();
leftPaneLayout->addWidget(measureTabs, 1);
dayTable = new CalendarDayTable(dateInMonth);
dayCalendar = new QWidget();
QHBoxLayout *dayLayout = new QHBoxLayout(dayCalendar);
QHBoxLayout *dayLayout = new QHBoxLayout(this);
dayLayout->addWidget(dayLeftPane, 1);
dayLayout->addWidget(dayTable, 3);
monthTable = new CalendarMonthTable(dateInMonth, firstDayOfWeek);
connect(dayDateSelector, &QCalendarWidget::selectionChanged, [=]() {
if (dayTable->selectedDate() != dayDateSelector->selectedDate()) {
setDay(dayDateSelector->selectedDate());
}
});
connect(dayTable, &CalendarDayTable::dayChanged, [=](const QDate &date) {
dayDateSelector->setSelectedDate(date);
emit dayChanged(date);
});
connect(dayTable, &CalendarDayTable::viewActivity, this, &CalendarDayView::viewActivity);
connect(dayTable, &CalendarDayTable::addActivity, this, &CalendarDayView::addActivity);
connect(dayTable, &CalendarDayTable::showInTrainMode, this, &CalendarDayView::showInTrainMode);
connect(dayTable, &CalendarDayTable::delActivity, this, &CalendarDayView::delActivity);
connect(dayTable, &CalendarDayTable::entryMoved, this, &CalendarDayView::entryMoved);
}
tableStack = new QStackedWidget();
tableStack->addWidget(dayCalendar);
tableStack->addWidget(monthTable);
bool
CalendarDayView::setDay
(const QDate &date)
{
updateMeasures(date);
return dayTable->setDay(date);
}
void
CalendarDayView::setFirstDayOfWeek
(Qt::DayOfWeek firstDayOfWeek)
{
dayDateSelector->setFirstDayOfWeek(firstDayOfWeek);
}
void
CalendarDayView::fillEntries
(const QHash<QDate, QList<CalendarEntry>> &activityEntries, const QList<CalendarSummary> &summaries, const QHash<QDate, QList<CalendarEntry>> &headlineEntries)
{
QDate dayViewDate = selectedDate();
dayDateSelector->fillEntries(activityEntries, headlineEntries);
QList<CalendarEntry> todayHeadline = headlineEntries.value(dayViewDate);
QStringList phaseList;
QStringList eventList;
for (const CalendarEntry &entry : todayHeadline) {
if (entry.type == ENTRY_TYPE_EVENT) {
eventList << entry.primary;
} else if (entry.type == ENTRY_TYPE_PHASE) {
phaseList << entry.primary;
}
}
if (phaseList.count() == 0) {
dayPhaseLabel->setText(tr("No Phase"));
} else if (phaseList.count() == 1) {
dayPhaseLabel->setText(tr("Phase: %1").arg(phaseList.join(", ")));
} else {
dayPhaseLabel->setText(tr("Phases: %1").arg(phaseList.join(", ")));
}
if (eventList.count() == 0) {
dayEventLabel->setText(tr("No Event"));
} else if (eventList.count() == 1) {
dayEventLabel->setText(tr("Event: %1").arg(eventList.join(", ")));
} else {
dayEventLabel->setText(tr("Events: %1").arg(eventList.join(", ")));
}
dayTable->fillEntries(activityEntries.value(dayViewDate), summaries.value(0), headlineEntries.value(dayViewDate));
}
void
CalendarDayView::limitDateRange
(const DateRange &dr)
{
dayDateSelector->limitDateRange(dr);
}
QDate
CalendarDayView::firstVisibleDay
() const
{
return dayDateSelector->firstVisibleDay();
}
QDate
CalendarDayView::lastVisibleDay
() const
{
return dayDateSelector->lastVisibleDay();
}
QDate
CalendarDayView::selectedDate
() const
{
return dayTable->selectedDate();
}
void
CalendarDayView::updateMeasures
()
{
updateMeasures(selectedDate());
}
void
CalendarDayView::updateMeasures
(const QDate &date)
{
int currentIndex = measureTabs->currentIndex();
while (measureTabs->count() > 0) {
QWidget *page = measureTabs->widget(0);
measureTabs->removeTab(0);
delete page;
}
bool metricUnits = GlobalContext::context()->useMetricUnits;
for (MeasuresGroup * const measuresGroup : athleteMeasures->getGroups()) {
QWidget *measureWidget = new QWidget();
Measure measure;
measuresGroup->getMeasure(date, measure);
QVBoxLayout *measureLayout = new QVBoxLayout();
int buttonType = 0;
if (measure.when.isValid()) {
QFormLayout *form = newQFormLayout();
for (int i = 0; i < measuresGroup->getFieldNames().count(); ++i) {
QString measureText;
double fieldValue = measuresGroup->getFieldValue(date, i, metricUnits);
if (fieldValue > 0) {
if (measuresGroup->getFieldUnits(i, metricUnits).size() > 0) {
measureText = QString("%1 %2").arg(fieldValue).arg(measuresGroup->getFieldUnits(i, metricUnits));
} else {
measureText = QString("%1").arg(fieldValue);
}
form->addRow(measuresGroup->getFieldNames()[i], new QLabel(measureText));
}
}
QTextEdit *commentField = new QTextEdit();
commentField->setAcceptRichText(false);
commentField->setReadOnly(true);
commentField->setText(measure.comment);
form->addRow(tr("Comment"), commentField);
QLocale locale;
QString validText = locale.toString(measure.when, QLocale::ShortFormat);
int validDays = measure.when.date().daysTo(date);
if (validDays > 1) {
validText.append(tr(" (%1 days earlier)").arg(validDays));
} else if (validDays > 0) {
validText.append(tr(" (%1 day earlier)").arg(validDays));
}
form->addRow(tr("Valid since"), new QLabel(validText));
measureLayout->addLayout(form);
if (validDays == 0) {
buttonType = 1;
}
} else {
QLabel *noMeasureLabel = new QLabel(tr("No measure available"));
noMeasureLabel->setAlignment(Qt::AlignCenter);
measureLayout->addStretch();
measureLayout->addWidget(noMeasureLabel, Qt::AlignCenter);
measureLayout->addStretch();
}
if (buttonType == 0) {
QPushButton *addButton = new QPushButton(tr("Add Measure"));
connect(addButton, &QPushButton::clicked, [=]() {
if (measureDialog(QDateTime(date, QTime::currentTime()), measuresGroup, false)) {
QTimer::singleShot(0, this, [=]() {
updateMeasures(date);
});
}
});
measureLayout->addWidget(addButton);
} else {
QPushButton *editButton = new QPushButton(tr("Edit Measure"));
connect(editButton, &QPushButton::clicked, [=]() {
if (measureDialog(measure.when, measuresGroup, true)) {
QTimer::singleShot(0, this, [=]() {
updateMeasures(date);
});
}
});
measureLayout->addWidget(editButton);
}
measureWidget->setLayout(measureLayout);
measureTabs->addTab(measureWidget, measuresGroup->getName());
}
if (measureTabs->count() > currentIndex) {
measureTabs->setCurrentIndex(currentIndex);
}
}
bool
CalendarDayView::measureDialog
(const QDateTime &when, MeasuresGroup * const measuresGroup, bool update)
{
QDialog dialog;
dialog.setWindowTitle(update ? tr("Edit Measure") : tr("Add Measure"));
QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Apply
| QDialogButtonBox::Discard);
connect(buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), &dialog, SLOT(accept()));
connect(buttonBox->button(QDialogButtonBox::Discard), SIGNAL(clicked()), &dialog, SLOT(reject()));
QFormLayout *form = newQFormLayout(&dialog);
QLocale locale;
form->addRow(tr("Start Date"), new QLabel(locale.toString(when, QLocale::ShortFormat)));
QList<double> unitsFactors = measuresGroup->getFieldUnitsFactors();
QStringList fieldNames = measuresGroup->getFieldNames();
QList<QLabel*> valuesLabel;
QList<QDoubleSpinBox*> valuesEdit;
bool metricUnits = GlobalContext::context()->useMetricUnits;
int i = 0;
for (QString &fieldName : fieldNames) {
valuesLabel << new QLabel(fieldName);
valuesEdit << new QDoubleSpinBox(this);
valuesEdit[i]->setMaximum(9999.99);
valuesEdit[i]->setMinimum(0.0);
valuesEdit[i]->setDecimals(2);
valuesEdit[i]->setValue(measuresGroup->getFieldValue(when.date(), i, metricUnits));
valuesEdit[i]->setSuffix(QString(" %1").arg(measuresGroup->getFieldUnits(i, metricUnits)));
form->addRow(valuesLabel[i], valuesEdit[i]);
++i;
}
Measure measure;
measuresGroup->getMeasure(when.date(), measure);
QTextEdit *commentEdit = new QTextEdit(measure.comment);
commentEdit->setAcceptRichText(false);
form->addRow(tr("Comment"), commentEdit);
form->addRow(buttonBox);
int dialogRet = dialog.exec();
if (dialogRet != QDialog::Accepted) {
return false;
}
for (i = 0; i < valuesEdit.count(); ++i) {
measure.values[i] = valuesEdit[i]->value();
}
measure.when = when;
measure.comment = commentEdit->toPlainText();
QList<Measure> measures = measuresGroup->measures();
bool found = false;
for (int measureIdx = 0; measureIdx < measures.count(); ++measureIdx) {
if (measures[measureIdx].when == measure.when) {
measures[measureIdx] = measure;
found = true;
break;
}
}
if (! found) {
measures << measure;
}
std::reverse(measures.begin(), measures.end());
measuresGroup->setMeasures(measures);
measuresGroup->write();
return true;
}
//////////////////////////////////////////////////////////////////////////////
// Calendar
Calendar::Calendar
(const QDate &dateInMonth, Qt::DayOfWeek firstDayOfWeek, Measures * const athleteMeasures, QWidget *parent)
: QWidget(parent)
{
qRegisterMetaType<CalendarDay>("CalendarDay");
qRegisterMetaType<CalendarSummary>("CalendarSummary");
dayView = new CalendarDayView(dateInMonth, firstDayOfWeek, athleteMeasures);
monthView = new CalendarMonthTable(dateInMonth, firstDayOfWeek);
viewStack = new QStackedWidget();
viewStack->addWidget(dayView);
viewStack->addWidget(monthView);
QToolBar *toolbar = new QToolBar();
prevYAction = toolbar->addAction("Previous Year");
prevMAction = toolbar->addAction("Previous Month");
nextMAction = toolbar->addAction("Next Month");
nextYAction = toolbar->addAction("Next Year");
todayAction = toolbar->addAction("Today");
prevYAction = toolbar->addAction(tr("Previous Year"));
prevMAction = toolbar->addAction(tr("Previous Month"));
nextMAction = toolbar->addAction(tr("Next Month"));
nextYAction = toolbar->addAction(tr("Next Year"));
todayAction = toolbar->addAction(tr("Today"));
toolbar->addSeparator();
dateLabel = new QLabel();
@@ -1282,46 +1553,40 @@ Calendar::Calendar
applyNavIcons();
connect(dayDateSelector, &QCalendarWidget::selectionChanged, [=]() {
if (dayTable->selectedDate() != dayDateSelector->selectedDate()) {
dayTable->setDay(dayDateSelector->selectedDate());
}
});
connect(dayTable, &CalendarDayTable::dayChanged, [=](const QDate &date) {
connect(dayView, &CalendarDayView::dayChanged, [=](const QDate &date) {
QLocale locale;
dateLabel->setText(locale.toString(dayTable->selectedDate(), QLocale::LongFormat));
dayDateSelector->setSelectedDate(date);
dateLabel->setText(locale.toString(dayView->selectedDate(), QLocale::LongFormat));
emit dayChanged(date);
});
connect(dayTable, &CalendarDayTable::viewActivity, this, &Calendar::viewActivity);
connect(dayTable, &CalendarDayTable::addActivity, this, &Calendar::addActivity);
connect(dayTable, &CalendarDayTable::showInTrainMode, this, &Calendar::showInTrainMode);
connect(dayTable, &CalendarDayTable::delActivity, this, &Calendar::delActivity);
connect(dayTable, &CalendarDayTable::entryMoved, this, &Calendar::moveActivity);
connect(monthTable, &CalendarMonthTable::entryDblClicked, [=](const CalendarDay &day, int entryIdx) {
connect(dayView, &CalendarDayView::viewActivity, this, &Calendar::viewActivity);
connect(dayView, &CalendarDayView::addActivity, this, &Calendar::addActivity);
connect(dayView, &CalendarDayView::showInTrainMode, this, &Calendar::showInTrainMode);
connect(dayView, &CalendarDayView::delActivity, this, &Calendar::delActivity);
connect(dayView, &CalendarDayView::entryMoved, this, &Calendar::moveActivity);
connect(monthView, &CalendarMonthTable::entryDblClicked, [=](const CalendarDay &day, int entryIdx) {
viewActivity(day.entries[entryIdx]);
});
connect(monthTable, &CalendarMonthTable::daySelected, [=](const CalendarDay &day) {
connect(monthView, &CalendarMonthTable::daySelected, [=](const CalendarDay &day) {
emit daySelected(day.date);
});
connect(monthTable, &CalendarMonthTable::moreClicked, [=]() {
connect(monthView, &CalendarMonthTable::moreClicked, [=]() {
setView(CalendarView::Day);
});
connect(monthTable, &CalendarMonthTable::dayDblClicked, [=]() {
connect(monthView, &CalendarMonthTable::dayDblClicked, [=]() {
setView(CalendarView::Day);
});
connect(monthTable, &CalendarMonthTable::showInTrainMode, this, &Calendar::showInTrainMode);
connect(monthTable, &CalendarMonthTable::viewActivity, this, &Calendar::viewActivity);
connect(monthTable, &CalendarMonthTable::addActivity, this, &Calendar::addActivity);
connect(monthTable, &CalendarMonthTable::repeatSchedule, this, &Calendar::repeatSchedule);
connect(monthTable, &CalendarMonthTable::delActivity, this, &Calendar::delActivity);
connect(monthTable, &CalendarMonthTable::entryMoved, this, &Calendar::moveActivity);
connect(monthTable, &CalendarMonthTable::insertRestday, this, &Calendar::insertRestday);
connect(monthTable, &CalendarMonthTable::delRestday, this, &Calendar::delRestday);
connect(monthTable, &CalendarMonthTable::monthChanged, [=](const QDate &month, const QDate &firstVisible, const QDate &lastVisible) {
connect(monthView, &CalendarMonthTable::showInTrainMode, this, &Calendar::showInTrainMode);
connect(monthView, &CalendarMonthTable::viewActivity, this, &Calendar::viewActivity);
connect(monthView, &CalendarMonthTable::addActivity, this, &Calendar::addActivity);
connect(monthView, &CalendarMonthTable::repeatSchedule, this, &Calendar::repeatSchedule);
connect(monthView, &CalendarMonthTable::delActivity, this, &Calendar::delActivity);
connect(monthView, &CalendarMonthTable::entryMoved, this, &Calendar::moveActivity);
connect(monthView, &CalendarMonthTable::insertRestday, this, &Calendar::insertRestday);
connect(monthView, &CalendarMonthTable::delRestday, this, &Calendar::delRestday);
connect(monthView, &CalendarMonthTable::monthChanged, [=](const QDate &month, const QDate &firstVisible, const QDate &lastVisible) {
setNavButtonState();
QLocale locale;
dateLabel->setText(locale.toString(monthTable->firstOfCurrentMonth(), ("MMMM yyyy")));
dateLabel->setText(locale.toString(monthView->firstOfCurrentMonth(), ("MMMM yyyy")));
emit monthChanged(month, firstVisible, lastVisible);
});
connect(prevYAction, &QAction::triggered, [=]() { addYears(-1); });
@@ -1332,7 +1597,7 @@ Calendar::Calendar
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(toolbar);
mainLayout->addWidget(tableStack);
mainLayout->addWidget(viewStack);
setView(CalendarView::Month);
setDate(dateInMonth);
@@ -1344,10 +1609,10 @@ Calendar::setDate
(const QDate &date, bool allowKeepMonth)
{
if (currentView() == CalendarView::Day) {
dayTable->setDay(date);
dayView->setDay(date);
} else {
if (monthTable->isInDateRange(date)) {
monthTable->setMonth(date, allowKeepMonth);
if (monthView->isInDateRange(date)) {
monthView->setMonth(date, allowKeepMonth);
}
}
}
@@ -1358,35 +1623,9 @@ Calendar::fillEntries
(const QHash<QDate, QList<CalendarEntry>> &activityEntries, const QList<CalendarSummary> &summaries, const QHash<QDate, QList<CalendarEntry>> &headlineEntries)
{
if (currentView() == CalendarView::Day) {
QDate dayViewDate = selectedDate();
dayDateSelector->fillEntries(activityEntries, headlineEntries);
QList<CalendarEntry> todayHeadline = headlineEntries.value(dayViewDate);
QStringList phaseList;
QStringList eventList;
for (const CalendarEntry &entry : todayHeadline) {
if (entry.type == ENTRY_TYPE_EVENT) {
eventList << entry.primary;
} else if (entry.type == ENTRY_TYPE_PHASE) {
phaseList << entry.primary;
}
}
if (phaseList.count() == 0) {
dayPhaseLabel->setText(tr("No Phase"));
} else if (phaseList.count() == 1) {
dayPhaseLabel->setText(tr("Phase: %1").arg(phaseList.join(", ")));
} else {
dayPhaseLabel->setText(tr("Phases: %1").arg(phaseList.join(", ")));
}
if (eventList.count() == 0) {
dayEventLabel->setText(tr("No Event"));
} else if (eventList.count() == 1) {
dayEventLabel->setText(tr("Event: %1").arg(eventList.join(", ")));
} else {
dayEventLabel->setText(tr("Events: %1").arg(eventList.join(", ")));
}
dayTable->fillEntries(activityEntries.value(dayViewDate), summaries.value(0), headlineEntries.value(dayViewDate));
dayView->fillEntries(activityEntries, summaries, headlineEntries);
} else {
monthTable->fillEntries(activityEntries, summaries, headlineEntries);
monthView->fillEntries(activityEntries, summaries, headlineEntries);
}
}
@@ -1395,7 +1634,7 @@ QDate
Calendar::firstOfCurrentMonth
() const
{
return monthTable->firstOfCurrentMonth();
return monthView->firstOfCurrentMonth();
}
@@ -1404,9 +1643,9 @@ Calendar::firstVisibleDay
() const
{
if (currentView() == CalendarView::Day) {
return dayDateSelector->firstVisibleDay();
return dayView->firstVisibleDay();
} else {
return monthTable->firstVisibleDay();
return monthView->firstVisibleDay();
}
}
@@ -1416,9 +1655,9 @@ Calendar::lastVisibleDay
() const
{
if (currentView() == CalendarView::Day) {
return dayDateSelector->lastVisibleDay();
return dayView->lastVisibleDay();
} else {
return monthTable->lastVisibleDay();
return monthView->lastVisibleDay();
}
}
@@ -1428,9 +1667,9 @@ Calendar::selectedDate
() const
{
if (currentView() == CalendarView::Day) {
return dayTable->selectedDate();
return dayView->selectedDate();
} else {
return monthTable->selectedDate();
return monthView->selectedDate();
}
}
@@ -1439,7 +1678,7 @@ CalendarView
Calendar::currentView
() const
{
return static_cast<CalendarView>(tableStack->currentIndex());
return static_cast<CalendarView>(viewStack->currentIndex());
}
@@ -1499,9 +1738,9 @@ Calendar::canAddMonths
(int months) const
{
if (currentView() == CalendarView::Day) {
return isInDateRange(dayTable->selectedDate().addMonths(months));
return isInDateRange(dayView->selectedDate().addMonths(months));
} else {
QDate fom = monthTable->firstOfCurrentMonth();
QDate fom = monthView->firstOfCurrentMonth();
QDate lom(fom.year(), fom.month(), fom.daysInMonth());
fom = fom.addMonths(months);
lom = lom.addMonths(months);
@@ -1515,9 +1754,9 @@ Calendar::canAddYears
(int years) const
{
if (currentView() == CalendarView::Day) {
return isInDateRange(dayTable->selectedDate().addYears(years));
return isInDateRange(dayView->selectedDate().addYears(years));
} else {
QDate fom = monthTable->firstOfCurrentMonth();
QDate fom = monthView->firstOfCurrentMonth();
QDate lom(fom.year(), fom.month(), fom.daysInMonth());
fom = fom.addYears(years);
lom = lom.addYears(years);
@@ -1539,8 +1778,8 @@ Calendar::activateDateRange
(const DateRange &dr, bool allowKeepMonth)
{
dateRange = dr;
monthTable->limitDateRange(dr, allowKeepMonth);
dayDateSelector->limitDateRange(dr);
monthView->limitDateRange(dr, allowKeepMonth);
dayView->limitDateRange(dr);
setNavButtonState();
setDate(fitDate(selectedDate(), true));
emit dateRangeActivated(dr.name);
@@ -1552,8 +1791,8 @@ Calendar::setFirstDayOfWeek
(Qt::DayOfWeek firstDayOfWeek)
{
QDate currentDate = selectedDate();
monthTable->setFirstDayOfWeek(firstDayOfWeek);
dayDateSelector->setFirstDayOfWeek(firstDayOfWeek);
monthView->setFirstDayOfWeek(firstDayOfWeek);
dayView->setFirstDayOfWeek(firstDayOfWeek);
if (currentView() == CalendarView::Month) {
setDate(fitDate(currentDate, false), true);
}
@@ -1564,7 +1803,7 @@ void
Calendar::setSummaryMonthVisible
(bool visible)
{
monthTable->setColumnHidden(7, ! visible);
monthView->setColumnHidden(7, ! visible);
}
@@ -1598,21 +1837,31 @@ Calendar::applyNavIcons
}
void
Calendar::updateMeasures
()
{
if (currentView() == CalendarView::Day) {
dayView->updateMeasures();
}
}
void
Calendar::setView
(CalendarView view)
{
int idx = static_cast<int>(view);
int oldIdx = tableStack->currentIndex();
int oldIdx = viewStack->currentIndex();
if (idx != oldIdx) {
if (view == CalendarView::Day) {
dayAction->setChecked(true);
dayTable->setDay(monthTable->selectedDate());
dayView->setDay(monthView->selectedDate());
} else {
monthAction->setChecked(true);
monthTable->setMonth(fitDate(dayTable->selectedDate(), false), true);
monthView->setMonth(fitDate(dayView->selectedDate(), false), true);
}
tableStack->setCurrentIndex(idx);
viewStack->setCurrentIndex(idx);
emit viewChanged(view, static_cast<CalendarView>(oldIdx));
}
}

View File

@@ -34,6 +34,7 @@
#include "CalendarItemDelegates.h"
#include "CalendarData.h"
#include "TimeUtils.h"
#include "Measures.h"
class CalendarOverview : public QCalendarWidget {
@@ -196,12 +197,47 @@ enum class CalendarView {
};
class CalendarDayView : public QWidget {
Q_OBJECT
public:
explicit CalendarDayView(const QDate &dateInMonth, Qt::DayOfWeek firstDayOfWeek = Qt::Monday, Measures * const athleteMeasures = nullptr, QWidget *parent = nullptr);
bool setDay(const QDate &date);
void setFirstDayOfWeek(Qt::DayOfWeek firstDayOfWeek);
void fillEntries(const QHash<QDate, QList<CalendarEntry>> &activityEntries, const QList<CalendarSummary> &summaries, const QHash<QDate, QList<CalendarEntry>> &headlineEntries);
void limitDateRange(const DateRange &dr);
QDate firstVisibleDay() const;
QDate lastVisibleDay() const;
QDate selectedDate() const;
void updateMeasures();
signals:
void showInTrainMode(const CalendarEntry &activity);
void viewActivity(const CalendarEntry &activity);
void addActivity(bool plan, const QDate &day, const QTime &time);
void delActivity(const CalendarEntry &activity);
void entryMoved(const CalendarEntry &activity, const QDate &srcDay, const QDate &destDay, const QTime &destTime);
void dayChanged(const QDate &date);
private:
Measures * const athleteMeasures;
CalendarOverview *dayDateSelector;
QLabel *dayPhaseLabel;
QLabel *dayEventLabel;
QTabWidget *measureTabs;
CalendarDayTable *dayTable;
bool measureDialog(const QDateTime &when, MeasuresGroup * const measuresGroup, bool update);
void updateMeasures(const QDate &date);
};
class Calendar : public QWidget {
Q_OBJECT
public:
explicit Calendar(Qt::DayOfWeek firstDayOfWeek = Qt::Monday, QWidget *parent = nullptr);
explicit Calendar(const QDate &dateInMonth, Qt::DayOfWeek firstDayOfWeek = Qt::Monday, QWidget *parent = nullptr);
explicit Calendar(const QDate &dateInMonth, Qt::DayOfWeek firstDayOfWeek = Qt::Monday, Measures * const athleteMeasures = nullptr, QWidget *parent = nullptr);
void setDate(const QDate &dateInMonth, bool allowKeepMonth = false);
void fillEntries(const QHash<QDate, QList<CalendarEntry>> &activityEntries, const QList<CalendarSummary> &summaries, const QHash<QDate, QList<CalendarEntry>> &headlineEntries);
@@ -224,6 +260,7 @@ public slots:
void setFirstDayOfWeek(Qt::DayOfWeek firstDayOfWeek);
void setSummaryMonthVisible(bool visible);
void applyNavIcons();
void updateMeasures();
signals:
void viewChanged(CalendarView newView, CalendarView oldView);
@@ -251,13 +288,9 @@ private:
QAction *dayAction;
QAction *monthAction;
QLabel *dateLabel;
QStackedWidget *tableStack;
QWidget *dayCalendar;
CalendarOverview *dayDateSelector;
QLabel *dayPhaseLabel;
QLabel *dayEventLabel;
CalendarDayTable *dayTable;
CalendarMonthTable *monthTable;
QStackedWidget *viewStack;
CalendarDayView *dayView;
CalendarMonthTable *monthView;
DateRange dateRange;
void setNavButtonState();