mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 08:08:42 +00:00
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:
committed by
GitHub
parent
36c98119d4
commit
d0d5105bd3
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user