From f9fd1840ec3bc3a45fcfed5cc4549d9a73f2beb3 Mon Sep 17 00:00:00 2001 From: Joachim Kohlhammer Date: Fri, 17 Oct 2025 01:16:06 +0200 Subject: [PATCH] New configuration-options for Calendar (#4716) * Start- and end-hour for day and week view * Summaries can be hidden for day and week view (month view was already available) * The default view for first start can be selected --- src/Charts/PlanningCalendarWindow.cpp | 165 +++++++++++++++++++++++--- src/Charts/PlanningCalendarWindow.h | 22 +++- src/Gui/Calendar.cpp | 104 +++++++++++++++- src/Gui/Calendar.h | 14 +++ 4 files changed, 282 insertions(+), 23 deletions(-) diff --git a/src/Charts/PlanningCalendarWindow.cpp b/src/Charts/PlanningCalendarWindow.cpp index fbf3803ff..fdd11d671 100644 --- a/src/Charts/PlanningCalendarWindow.cpp +++ b/src/Charts/PlanningCalendarWindow.cpp @@ -42,6 +42,9 @@ PlanningCalendarWindow::PlanningCalendarWindow(Context *context) calendar = new Calendar(QDate::currentDate(), static_cast(getFirstDayOfWeek()), context->athlete->measures); + setStartHour(8); + setEndHour(21); + QVBoxLayout *mainLayout = new QVBoxLayout(); setChartLayout(mainLayout); mainLayout->addWidget(calendar); @@ -157,6 +160,23 @@ PlanningCalendarWindow::PlanningCalendarWindow(Context *context) } +int +PlanningCalendarWindow::getDefaultView +() const +{ + return defaultViewCombo->currentIndex(); +} + + +void +PlanningCalendarWindow::setDefaultView +(int view) +{ + defaultViewCombo->setCurrentIndex(view); + calendar->setView(static_cast(view)); +} + + int PlanningCalendarWindow::getFirstDayOfWeek () const @@ -165,14 +185,6 @@ PlanningCalendarWindow::getFirstDayOfWeek } -bool -PlanningCalendarWindow::isSummaryVisibleMonth -() const -{ - return summaryMonthCheck->isChecked(); -} - - void PlanningCalendarWindow::setFirstDayOfWeek (int fdw) @@ -182,12 +194,96 @@ PlanningCalendarWindow::setFirstDayOfWeek } +int +PlanningCalendarWindow::getStartHour +() const +{ + return startHourSpin->value(); +} + + +void +PlanningCalendarWindow::setStartHour +(int hour) +{ + startHourSpin->setValue(hour); + endHourSpin->setMinimum(hour + 1); + if (calendar != nullptr) { + calendar->setStartHour(hour); + updateActivities(); + } +} + + +int +PlanningCalendarWindow::getEndHour +() const +{ + return endHourSpin->value(); +} + + +void +PlanningCalendarWindow::setEndHour +(int hour) +{ + endHourSpin->setValue(hour); + startHourSpin->setMaximum(hour - 1); + if (calendar != nullptr) { + calendar->setEndHour(hour); + updateActivities(); + } +} + + +bool +PlanningCalendarWindow::isSummaryVisibleDay +() const +{ + return summaryDayCheck->isChecked(); +} + + +void +PlanningCalendarWindow::setSummaryVisibleDay +(bool visible) +{ + summaryDayCheck->setChecked(visible); + calendar->setSummaryDayVisible(visible); +} + + +bool +PlanningCalendarWindow::isSummaryVisibleWeek +() const +{ + return summaryWeekCheck->isChecked(); +} + + +void +PlanningCalendarWindow::setSummaryVisibleWeek +(bool visible) +{ + summaryWeekCheck->setChecked(visible); + calendar->setSummaryWeekVisible(visible); +} + + +bool +PlanningCalendarWindow::isSummaryVisibleMonth +() const +{ + return summaryMonthCheck->isChecked(); +} + + void PlanningCalendarWindow::setSummaryVisibleMonth -(bool svm) +(bool visible) { - summaryMonthCheck->setChecked(svm); - calendar->setSummaryMonthVisible(svm); + summaryMonthCheck->setChecked(visible); + calendar->setSummaryMonthVisible(visible); } @@ -376,12 +472,27 @@ PlanningCalendarWindow::mkControls () { QLocale locale; + defaultViewCombo = new QComboBox(); + defaultViewCombo->addItem(tr("Day View")); + defaultViewCombo->addItem(tr("Week View")); + defaultViewCombo->addItem(tr("Month View")); + defaultViewCombo->setCurrentIndex(static_cast(CalendarView::Month)); firstDayOfWeekCombo = new QComboBox(); for (int i = Qt::Monday; i <= Qt::Sunday; ++i) { firstDayOfWeekCombo->addItem(locale.dayName(i, QLocale::LongFormat)); } firstDayOfWeekCombo->setCurrentIndex(locale.firstDayOfWeek() - 1); - summaryMonthCheck = new QCheckBox(tr("Show weekly summary on month view")); + startHourSpin = new QSpinBox(); + startHourSpin->setSuffix(":00"); + startHourSpin->setMinimum(0); + endHourSpin = new QSpinBox(); + endHourSpin->setSuffix(":00"); + endHourSpin->setMaximum(24); + summaryDayCheck = new QCheckBox(tr("Day View")); + summaryDayCheck->setChecked(true); + summaryWeekCheck = new QCheckBox(tr("Week View")); + summaryWeekCheck->setChecked(true); + summaryMonthCheck = new QCheckBox(tr("Month View")); summaryMonthCheck->setChecked(true); primaryMainCombo = new QComboBox(); primaryFallbackCombo = new QComboBox(); @@ -399,41 +510,59 @@ PlanningCalendarWindow::mkControls tertiaryCombo->setCurrentText("Notes"); QStringList summaryMetrics { "ride_count", "total_distance", "coggan_tss", "workout_time" }; multiMetricSelector = new MultiMetricSelector(tr("Available Metrics"), tr("Selected Metrics"), summaryMetrics); + multiMetricSelector->setMinimumHeight(300 * dpiYFactor); QFormLayout *formLayout = newQFormLayout(); - formLayout->addRow(tr("First day of week"), firstDayOfWeekCombo); + formLayout->addRow(tr("Default View on Startup"), defaultViewCombo); + formLayout->addRow(tr("First Day of Week"), firstDayOfWeekCombo); + formLayout->addRow(tr("Default Start Time"), startHourSpin); + formLayout->addRow(tr("Default End Time"), endHourSpin); + formLayout->addRow(tr("Show Summary In"), summaryDayCheck); + formLayout->addRow("", summaryWeekCheck); formLayout->addRow("", summaryMonthCheck); + formLayout->addItem(new QSpacerItem(0, 10 * dpiYFactor, QSizePolicy::Minimum, QSizePolicy::Fixed)); formLayout->addRow(new QLabel(HLO + tr("Calendar Entries") + HLC)); formLayout->addRow(tr("Field for Primary Line"), primaryMainCombo); formLayout->addRow(tr("Fallback Field for Primary Line"), primaryFallbackCombo); formLayout->addRow(tr("Metric for Secondary Line"), secondaryCombo); - formLayout->addRow(tr("Field for Tertiary Line (day and week view)"), tertiaryCombo); + formLayout->addRow(tr("Field for Tertiary Line (Day and Week View)"), tertiaryCombo); + formLayout->addItem(new QSpacerItem(0, 10 * dpiYFactor, QSizePolicy::Minimum, QSizePolicy::Fixed)); formLayout->addRow(new QLabel(HLO + tr("Summary") + HLC)); QWidget *controlsWidget = new QWidget(); - QVBoxLayout *controlsLayout = new QVBoxLayout(controlsWidget); controlsLayout->addWidget(centerLayoutInWidget(formLayout, false)); - controlsLayout->addWidget(multiMetricSelector, 2); - controlsLayout->addStretch(1); + controlsLayout->addWidget(multiMetricSelector); + + QScrollArea *controlsScroller = new QScrollArea(); + controlsScroller->setWidgetResizable(true); + controlsScroller->setWidget(controlsWidget); #if QT_VERSION < 0x060000 + connect(startHourSpin, QOverload::of(&QSpinBox::valueChanged), this, &PlanningCalendarWindow::setStartHour); + connect(endHourSpin, QOverload::of(&QSpinBox::valueChanged), this, &PlanningCalendarWindow::setEndHour); + connect(defaultViewCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &PlanningCalendarWindow::setDefaultView); connect(firstDayOfWeekCombo, QOverload::of(&QComboBox::currentIndexChanged), [=](int idx) { setFirstDayOfWeek(idx + 1); }); connect(primaryMainCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &PlanningCalendarWindow::updateActivities); connect(primaryFallbackCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &PlanningCalendarWindow::updateActivities); connect(secondaryCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &PlanningCalendarWindow::updateActivities); connect(tertiaryCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &PlanningCalendarWindow::updateActivities); #else + connect(startHourSpin, &QSpinBox::valueChanged, this, &PlanningCalendarWindow::setStartHour); + connect(endHourSpin, &QSpinBox::valueChanged, this, &PlanningCalendarWindow::setEndHour); + connect(defaultViewCombo, &QComboBox::currentIndexChanged, this, &PlanningCalendarWindow::setDefaultView); connect(firstDayOfWeekCombo, &QComboBox::currentIndexChanged, [=](int idx) { setFirstDayOfWeek(idx + 1); }); connect(primaryMainCombo, &QComboBox::currentIndexChanged, this, &PlanningCalendarWindow::updateActivities); connect(primaryFallbackCombo, &QComboBox::currentIndexChanged, this, &PlanningCalendarWindow::updateActivities); connect(secondaryCombo, &QComboBox::currentIndexChanged, this, &PlanningCalendarWindow::updateActivities); connect(tertiaryCombo, &QComboBox::currentIndexChanged, this, &PlanningCalendarWindow::updateActivities); #endif + connect(summaryDayCheck, &QCheckBox::toggled, this, &PlanningCalendarWindow::setSummaryVisibleDay); + connect(summaryWeekCheck, &QCheckBox::toggled, this, &PlanningCalendarWindow::setSummaryVisibleWeek); connect(summaryMonthCheck, &QCheckBox::toggled, this, &PlanningCalendarWindow::setSummaryVisibleMonth); connect(multiMetricSelector, &MultiMetricSelector::selectedChanged, this, &PlanningCalendarWindow::updateActivities); - setControls(controlsWidget); + setControls(controlsScroller); } diff --git a/src/Charts/PlanningCalendarWindow.h b/src/Charts/PlanningCalendarWindow.h index ac03eb465..13f7e7ab8 100644 --- a/src/Charts/PlanningCalendarWindow.h +++ b/src/Charts/PlanningCalendarWindow.h @@ -38,7 +38,12 @@ class PlanningCalendarWindow : public GcChartWindow { Q_OBJECT + Q_PROPERTY(int defaultView READ getDefaultView WRITE setDefaultView USER true) Q_PROPERTY(int firstDayOfWeek READ getFirstDayOfWeek WRITE setFirstDayOfWeek USER true) + Q_PROPERTY(int startHour READ getStartHour WRITE setStartHour USER true) + Q_PROPERTY(int endHour READ getEndHour WRITE setEndHour USER true) + Q_PROPERTY(bool summaryVisibleDay READ isSummaryVisibleDay WRITE setSummaryVisibleDay USER true) + Q_PROPERTY(bool summaryVisibleWeek READ isSummaryVisibleWeek WRITE setSummaryVisibleWeek USER true) Q_PROPERTY(bool summaryVisibleMonth READ isSummaryVisibleMonth WRITE setSummaryVisibleMonth USER true) Q_PROPERTY(QString primaryMainField READ getPrimaryMainField WRITE setPrimaryMainField USER true) Q_PROPERTY(QString primaryFallbackField READ getPrimaryFallbackField WRITE setPrimaryFallbackField USER true) @@ -49,7 +54,12 @@ class PlanningCalendarWindow : public GcChartWindow public: PlanningCalendarWindow(Context *context); + int getDefaultView() const; int getFirstDayOfWeek() const; + int getStartHour() const; + int getEndHour() const; + bool isSummaryVisibleDay() const; + bool isSummaryVisibleWeek() const; bool isSummaryVisibleMonth() const; bool isFiltered() const; @@ -62,7 +72,12 @@ class PlanningCalendarWindow : public GcChartWindow QStringList getSummaryMetricsList() const; public slots: + void setDefaultView(int view); void setFirstDayOfWeek(int fdw); + void setStartHour(int hour); + void setEndHour(int hour); + void setSummaryVisibleDay(bool visible); + void setSummaryVisibleWeek(bool visible); void setSummaryVisibleMonth(bool svm); void setPrimaryMainField(const QString &name); void setPrimaryFallbackField(const QString &name); @@ -76,14 +91,19 @@ class PlanningCalendarWindow : public GcChartWindow Context *context; bool first = true; + QComboBox *defaultViewCombo; QComboBox *firstDayOfWeekCombo; + QSpinBox *startHourSpin; + QSpinBox *endHourSpin; + QCheckBox *summaryDayCheck; + QCheckBox *summaryWeekCheck; QCheckBox *summaryMonthCheck; QComboBox *primaryMainCombo; QComboBox *primaryFallbackCombo; QComboBox *secondaryCombo; QComboBox *tertiaryCombo; MultiMetricSelector *multiMetricSelector; - Calendar *calendar; + Calendar *calendar = nullptr; void mkControls(); void updatePrimaryConfigCombos(); diff --git a/src/Gui/Calendar.cpp b/src/Gui/Calendar.cpp index 75495c846..39381012b 100644 --- a/src/Gui/Calendar.cpp +++ b/src/Gui/Calendar.cpp @@ -317,10 +317,8 @@ void CalendarDayTable::fillEntries (const QHash> &activityEntries, const QList &summaries, const QHash> &headlineEntries) { - Q_UNUSED(headlineEntries) - - int startHour = 8; - int endHour = 21; + int startHour = defaultStartHour; + int endHour = defaultEndHour; int numDays = type == CalendarDayTableType::Day ? 1 : 7; for (int i = 0; i < numDays; ++i) { QTableWidgetItem *headlineItem = this->item(0, i + 1); @@ -399,6 +397,22 @@ CalendarDayTable::setFirstDayOfWeek } +void +CalendarDayTable::setStartHour +(int hour) +{ + defaultStartHour = hour; +} + + +void +CalendarDayTable::setEndHour +(int hour) +{ + defaultEndHour = hour; +} + + void CalendarDayTable::changeEvent (QEvent *event) @@ -1423,6 +1437,30 @@ CalendarDayView::setFirstDayOfWeek } +void +CalendarDayView::setStartHour +(int hour) +{ + dayTable->setStartHour(hour); +} + + +void +CalendarDayView::setEndHour +(int hour) +{ + dayTable->setEndHour(hour); +} + + +void +CalendarDayView::setSummaryVisible +(bool visible) +{ + dayTable->setRowHidden(2, ! visible); +} + + void CalendarDayView::fillEntries (const QHash> &activityEntries, const QList &summaries, const QHash> &headlineEntries) @@ -1683,6 +1721,30 @@ CalendarWeekView::setFirstDayOfWeek } +void +CalendarWeekView::setStartHour +(int hour) +{ + weekTable->setStartHour(hour); +} + + +void +CalendarWeekView::setEndHour +(int hour) +{ + weekTable->setEndHour(hour); +} + + +void +CalendarWeekView::setSummaryVisible +(bool visible) +{ + weekTable->setRowHidden(2, ! visible); +} + + void CalendarWeekView::fillEntries (const QHash> &activityEntries, const QList &summaries, const QHash> &headlineEntries) @@ -2077,6 +2139,40 @@ Calendar::setFirstDayOfWeek } +void +Calendar::setStartHour +(int hour) +{ + weekView->setStartHour(hour); + dayView->setStartHour(hour); +} + + +void +Calendar::setEndHour +(int hour) +{ + weekView->setEndHour(hour); + dayView->setEndHour(hour); +} + + +void +Calendar::setSummaryDayVisible +(bool visible) +{ + dayView->setSummaryVisible(visible); +} + + +void +Calendar::setSummaryWeekVisible +(bool visible) +{ + weekView->setSummaryVisible(visible); +} + + void Calendar::setSummaryMonthVisible (bool visible) diff --git a/src/Gui/Calendar.h b/src/Gui/Calendar.h index 4e36e9c2c..83c1348b3 100644 --- a/src/Gui/Calendar.h +++ b/src/Gui/Calendar.h @@ -86,6 +86,8 @@ public: void fillEntries(const QHash> &activityEntries, const QList &summaries, const QHash> &headlineEntries); void limitDateRange(const DateRange &dr); void setFirstDayOfWeek(Qt::DayOfWeek firstDayOfWeek); + void setStartHour(int hour); + void setEndHour(int hour); signals: void dayClicked(const CalendarDay &day, const QTime &time); @@ -121,6 +123,8 @@ private: QDate date; DateRange dr; CalendarDayTableType type; + int defaultStartHour = 8; + int defaultEndHour = 21; QTimer dragTimer; QPoint pressedPos; @@ -220,6 +224,9 @@ public: bool setDay(const QDate &date); void setFirstDayOfWeek(Qt::DayOfWeek firstDayOfWeek); + void setStartHour(int hour); + void setEndHour(int hour); + void setSummaryVisible(bool visible); void fillEntries(const QHash> &activityEntries, const QList &summaries, const QHash> &headlineEntries); void limitDateRange(const DateRange &dr); QDate firstVisibleDay() const; @@ -254,6 +261,9 @@ public: bool setDay(const QDate &date); void setFirstDayOfWeek(Qt::DayOfWeek firstDayOfWeek); + void setStartHour(int hour); + void setEndHour(int hour); + void setSummaryVisible(bool visible); void fillEntries(const QHash> &activityEntries, const QList &summaries, const QHash> &headlineEntries); void limitDateRange(const DateRange &dr); QDate firstVisibleDay() const; @@ -299,6 +309,10 @@ public slots: void setView(CalendarView view); void activateDateRange(const DateRange &dr, bool allowKeepMonth = false); void setFirstDayOfWeek(Qt::DayOfWeek firstDayOfWeek); + void setStartHour(int hour); + void setEndHour(int hour); + void setSummaryDayVisible(bool visible); + void setSummaryWeekVisible(bool visible); void setSummaryMonthVisible(bool visible); void applyNavIcons(); void updateMeasures();