mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-04-15 05:32:21 +00:00
439 lines
15 KiB
C++
439 lines
15 KiB
C++
/*
|
|
* Copyright (c) 2025 Joachim Kohlhammer (joachim.kohlhammer@gmx.de)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#ifndef CALENDAR_H
|
|
#define CALENDAR_H
|
|
|
|
#include <QWidget>
|
|
#include <QStackedWidget>
|
|
#include <QTableWidget>
|
|
#include <QCalendarWidget>
|
|
#include <QToolBar>
|
|
#include <QMenu>
|
|
#include <QLabel>
|
|
#include <QComboBox>
|
|
#include <QDate>
|
|
#include <QStringList>
|
|
#include <QTimer>
|
|
#include <QApplication>
|
|
|
|
#include "CalendarItemDelegates.h"
|
|
#include "CalendarData.h"
|
|
#include "TimeUtils.h"
|
|
#include "Measures.h"
|
|
#include "Qt5Compatibility.h"
|
|
|
|
|
|
class CalendarOverview : public QCalendarWidget {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit CalendarOverview(QWidget *parent = nullptr);
|
|
|
|
QDate firstVisibleDay() const;
|
|
QDate lastVisibleDay() const;
|
|
void limitDateRange(const DateRange &dr);
|
|
void fillEntries(const QHash<QDate, QList<CalendarEntry>> &activityEntries, const QHash<QDate, QList<CalendarEntry>> &headlineEntries);
|
|
|
|
protected:
|
|
#if QT_VERSION < 0x060000
|
|
void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const override;
|
|
#else
|
|
void paintCell(QPainter *painter, const QRect &rect, QDate date) const override;
|
|
#endif
|
|
|
|
private:
|
|
QHash<QDate, QList<CalendarEntry>> activityEntries;
|
|
QHash<QDate, QList<CalendarEntry>> headlineEntries;
|
|
|
|
void drawEntries(QPainter *painter, const QList<CalendarEntry> &entries, QPolygon polygon, int maxEntries, int shiftX) const;
|
|
};
|
|
|
|
|
|
enum class CalendarDayTableType {
|
|
Day,
|
|
Week
|
|
};
|
|
|
|
|
|
class CalendarDayTable : public QTableWidget {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit CalendarDayTable(const QDate &date, CalendarDayTableType type = CalendarDayTableType::Day, Qt::DayOfWeek firstDayOfWeek = Qt::Monday, QWidget *parent = nullptr);
|
|
|
|
bool setDay(const QDate &date);
|
|
QDate firstVisibleDay() const;
|
|
QDate firstVisibleDay(const QDate &date) const;
|
|
QDate lastVisibleDay() const;
|
|
QDate lastVisibleDay(const QDate &date) const;
|
|
QDate selectedDate() const;
|
|
bool isInDateRange(const QDate &date) const;
|
|
void fillEntries(const QHash<QDate, QList<CalendarEntry>> &activityEntries, const QList<CalendarSummary> &summaries, const QHash<QDate, QList<CalendarEntry>> &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);
|
|
void dayRightClicked(const CalendarDay &day, const QTime &time);
|
|
void entryClicked(const CalendarDay &day, int entryIdx);
|
|
void entryRightClicked(const CalendarDay &day, int entryIdx);
|
|
void entryMoved(const CalendarEntry &activity, const QDate &srcDay, const QDate &destDay, const QTime &destTime);
|
|
void dayChanged(const QDate &date);
|
|
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);
|
|
|
|
protected:
|
|
void changeEvent(QEvent *event) override;
|
|
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
|
void mousePressEvent(QMouseEvent *event) override;
|
|
void mouseReleaseEvent(QMouseEvent *event) override;
|
|
void mouseMoveEvent(QMouseEvent *event) override;
|
|
void dragEnterEvent(QDragEnterEvent *event) override;
|
|
void dragMoveEvent(QDragMoveEvent *event) override;
|
|
void dragLeaveEvent(QDragLeaveEvent *event) override;
|
|
void dropEvent(QDropEvent *event) override;
|
|
#if QT_VERSION < 0x060000
|
|
QAbstractItemDelegate *itemDelegateForIndex(const QModelIndex &index) const;
|
|
#endif
|
|
|
|
private slots:
|
|
void showContextMenu(const QPoint &pos);
|
|
|
|
private:
|
|
Qt::DayOfWeek firstDayOfWeek = Qt::Monday;
|
|
QDate date;
|
|
DateRange dr;
|
|
CalendarDayTableType type;
|
|
int defaultStartHour = 8;
|
|
int defaultEndHour = 21;
|
|
|
|
QTimer dragTimer;
|
|
QPoint pressedPos;
|
|
QModelIndex pressedIndex;
|
|
bool isDraggable = false;
|
|
TimeScaleData timeScaleData;
|
|
|
|
void setDropIndicator(int y, BlockIndicator block);
|
|
};
|
|
|
|
|
|
class CalendarMonthTable : public QTableWidget {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
enum CalendarDayTableRoles {
|
|
DateRole = Qt::UserRole + 1000 // [QDate] Date of cell
|
|
};
|
|
|
|
explicit CalendarMonthTable(Qt::DayOfWeek firstDayOfWeek = Qt::Monday, QWidget *parent = nullptr);
|
|
explicit CalendarMonthTable(const QDate &dateInMonth, Qt::DayOfWeek firstDayOfWeek = Qt::Monday, QWidget *parent = nullptr);
|
|
|
|
bool selectDay(const QDate &day);
|
|
bool setMonth(const QDate &dateInMonth, bool allowKeepMonth = false);
|
|
bool isInDateRange(const QDate &date) const;
|
|
void fillEntries(const QHash<QDate, QList<CalendarEntry>> &activityEntries, const QList<CalendarSummary> &summaries, const QHash<QDate, QList<CalendarEntry>> &headlineEntries);
|
|
QDate firstOfCurrentMonth() const;
|
|
QDate firstVisibleDay() const;
|
|
QDate lastVisibleDay() const;
|
|
QDate selectedDate() const;
|
|
void limitDateRange(const DateRange &dr, bool allowKeepMonth = false);
|
|
void setFirstDayOfWeek(Qt::DayOfWeek firstDayOfWeek);
|
|
|
|
signals:
|
|
void daySelected(const CalendarDay &day);
|
|
void dayClicked(const CalendarDay &day);
|
|
void dayDblClicked(const CalendarDay &day);
|
|
void moreClicked(const CalendarDay &day);
|
|
void moreDblClicked(const CalendarDay &day);
|
|
void dayRightClicked(const CalendarDay &day);
|
|
void entryClicked(const CalendarDay &day, int entryIdx);
|
|
void entryDblClicked(const CalendarDay &day, int entryIdx);
|
|
void entryRightClicked(const CalendarDay &day, int entryIdx);
|
|
void entryMoved(const CalendarEntry &activity, const QDate &srcDay, const QDate &destDay, const QTime &destTime);
|
|
void summaryClicked(const QModelIndex &index);
|
|
void summaryDblClicked(const QModelIndex &index);
|
|
void summaryRightClicked(const QModelIndex &index);
|
|
void monthChanged(const QDate &month, const QDate &firstVisible, const QDate &lastVisible);
|
|
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 repeatSchedule(const QDate &day);
|
|
void insertRestday(const QDate &day);
|
|
void delRestday(const QDate &day);
|
|
|
|
protected:
|
|
void changeEvent(QEvent *event) override;
|
|
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
|
void mousePressEvent(QMouseEvent *event) override;
|
|
void mouseReleaseEvent(QMouseEvent *event) override;
|
|
void mouseMoveEvent(QMouseEvent *event) override;
|
|
void dragEnterEvent(QDragEnterEvent *event) override;
|
|
void dragMoveEvent(QDragMoveEvent *event) override;
|
|
void dragLeaveEvent(QDragLeaveEvent *event) override;
|
|
void dropEvent(QDropEvent *event) override;
|
|
#if QT_VERSION < 0x060000
|
|
QAbstractItemDelegate *itemDelegateForIndex(const QModelIndex &index) const;
|
|
#endif
|
|
|
|
private slots:
|
|
void showContextMenu(const QPoint &pos);
|
|
|
|
private:
|
|
Qt::DayOfWeek firstDayOfWeek = Qt::Monday;
|
|
QDate firstOfMonth;
|
|
QDate startDate; // first visible date
|
|
QDate endDate; // last visible date
|
|
QDate currentDate; // currently selected date
|
|
DateRange dr;
|
|
|
|
QTimer dragTimer;
|
|
QPoint pressedPos;
|
|
QModelIndex pressedIndex;
|
|
bool isDraggable = false;
|
|
};
|
|
|
|
|
|
enum class CalendarView {
|
|
Day = 0,
|
|
Week = 1,
|
|
Month = 2,
|
|
Agenda = 3
|
|
};
|
|
|
|
|
|
class CalendarDayView : public QWidget {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit CalendarDayView(const QDate &date, Measures * const athleteMeasures = nullptr, QWidget *parent = nullptr);
|
|
|
|
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<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;
|
|
QTabWidget *measureTabs;
|
|
CalendarDayTable *dayTable;
|
|
|
|
bool measureDialog(const QDateTime &when, MeasuresGroup * const measuresGroup, bool update);
|
|
void updateMeasures(const QDate &date);
|
|
};
|
|
|
|
|
|
class CalendarWeekView : public QWidget {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit CalendarWeekView(const QDate &date, QWidget *parent = nullptr);
|
|
|
|
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<QDate, QList<CalendarEntry>> &activityEntries, const QList<CalendarSummary> &summaries, const QHash<QDate, QList<CalendarEntry>> &headlineEntries);
|
|
void limitDateRange(const DateRange &dr);
|
|
QDate firstVisibleDay() const;
|
|
QDate firstVisibleDay(const QDate &date) const;
|
|
QDate lastVisibleDay() const;
|
|
QDate lastVisibleDay(const QDate &date) const;
|
|
QDate selectedDate() const;
|
|
|
|
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:
|
|
CalendarDayTable *weekTable;
|
|
};
|
|
|
|
|
|
struct CalendarAgendaStyles {
|
|
QFont defaultFont;
|
|
QFont relativeFont;
|
|
QFont hoverFont;
|
|
QFont headlineDefaultFont;
|
|
QFont headlineTodayFont;
|
|
QFont headlineEmptyFont;
|
|
QFont headlineSmallEmptyFont;
|
|
|
|
int sectionSpacerHeight;
|
|
int sectionEntrySpacerHeight;
|
|
int entrySpacerHeight;
|
|
int daySpacerHeight;
|
|
};
|
|
|
|
class CalendarAgendaView : public QWidget {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit CalendarAgendaView(QWidget *parent = nullptr);
|
|
|
|
void updateDate();
|
|
void setDateRange(const DateRange &dateRange);
|
|
void setPastDays(int days);
|
|
void setFutureDays(int days);
|
|
void fillEntries(const QHash<QDate, QList<CalendarEntry>> &activityEntries, const QList<CalendarSummary> &summaries, const QHash<QDate, QList<CalendarEntry>> &headlineEntries);
|
|
QDate firstVisibleDay() const;
|
|
QDate lastVisibleDay() const;
|
|
QDate selectedDate() const;
|
|
|
|
signals:
|
|
void showInTrainMode(const CalendarEntry &activity);
|
|
void showInMonthView(const QDate &date);
|
|
void viewActivity(const CalendarEntry &activity);
|
|
void dayChanged(const QDate &date);
|
|
|
|
protected:
|
|
bool eventFilter(QObject *watched, QEvent *event) override;
|
|
void changeEvent(QEvent *event) override;
|
|
|
|
private:
|
|
QDate currentDate;
|
|
DateRange dateRange;
|
|
int pastDays = 7;
|
|
int futureDays = 7;
|
|
TreeWidget6 *agendaTree;
|
|
QTreeWidgetItem *lastHoveredItem = nullptr;
|
|
int lastHoveredColumn = -1;
|
|
void clearHover();
|
|
void addEntries(const QDate &today, const QDate &date, const QList<CalendarEntry> &entries, QTreeWidgetItem *parent, const CalendarAgendaStyles &cas);
|
|
void addSpacer(QTreeWidgetItem *parent, int height);
|
|
void addSeparator(QTreeWidgetItem *parent, int top, int bottom);
|
|
void fillStyles(CalendarAgendaStyles &cas) const;
|
|
|
|
private slots:
|
|
void showContextMenu(const QPoint &pos);
|
|
};
|
|
|
|
|
|
class Calendar : public QWidget {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
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, bool isFiltered);
|
|
QDate firstOfCurrentMonth() const;
|
|
QDate firstVisibleDay() const;
|
|
QDate lastVisibleDay() const;
|
|
QDate selectedDate() const;
|
|
CalendarView currentView() const;
|
|
|
|
bool goNext(int amount);
|
|
QDate fitToMonth(const QDate &date, bool preferToday = true) const;
|
|
bool canGoNext(int amount) const;
|
|
bool isInDateRange(const QDate &date) const;
|
|
int weekNumber(const QDate &date) const;
|
|
|
|
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 setAgendaPastDays(int days);
|
|
void setAgendaFutureDays(int days);
|
|
void setSummaryDayVisible(bool visible);
|
|
void setSummaryWeekVisible(bool visible);
|
|
void setSummaryMonthVisible(bool visible);
|
|
void applyNavIcons();
|
|
void updateMeasures();
|
|
|
|
signals:
|
|
void viewChanged(CalendarView newView, CalendarView oldView);
|
|
void daySelected(const QDate &date);
|
|
void dayClicked(const QDate &date);
|
|
void summaryClicked(const QDate &date);
|
|
void dayChanged(const QDate &date);
|
|
void monthChanged(const QDate &month, const QDate &firstVisible, const QDate &lastVisible);
|
|
void dateRangeActivated(const QString &name);
|
|
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 repeatSchedule(const QDate &day);
|
|
void moveActivity(const CalendarEntry &activity, const QDate &srcDay, const QDate &destDay, const QTime &destTime);
|
|
void insertRestday(const QDate &day);
|
|
void delRestday(const QDate &day);
|
|
|
|
private:
|
|
QToolBar *toolbar;
|
|
QAction *prevAction;
|
|
QAction *nextAction;
|
|
QAction *todayAction;
|
|
QAction *separator;
|
|
QAction *dayAction;
|
|
QAction *weekAction;
|
|
QAction *monthAction;
|
|
QAction *agendaAction;
|
|
QToolButton *dateNavigator;
|
|
QAction *dateNavigatorAction;
|
|
QMenu *dateMenu;
|
|
QLabel *seasonLabel;
|
|
QAction *seasonLabelAction;
|
|
QAction *filterSpacerAction;
|
|
QLabel *filterLabel;
|
|
QAction *filterLabelAction;
|
|
QStackedWidget *viewStack;
|
|
CalendarDayView *dayView;
|
|
CalendarWeekView *weekView;
|
|
CalendarMonthTable *monthView;
|
|
CalendarAgendaView *agendaView;
|
|
DateRange dateRange;
|
|
Qt::DayOfWeek firstDayOfWeek = Qt::Monday;
|
|
QDate lastNonAgendaDate;
|
|
|
|
void setNavButtonState();
|
|
void updateHeader();
|
|
|
|
private slots:
|
|
void populateDateMenu();
|
|
};
|
|
|
|
#endif
|