/* SPDX-FileCopyrightText: 2013 Mark Gaiser SPDX-FileCopyrightText: 2016 Martin Klapetek SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include "qqmlregistration.h" #include #include #include #include "daysmodel.h" class QAbstractItemModel; class CalendarPrivate; class Calendar : public QObject { Q_OBJECT QML_ELEMENT /* The conversion between QDate and JS Date is broken. The specification says that a date * is represented by the start of the UTC day, but for negative to UTC timezones this results * in wrong dates: Jan 2 in C++ -> Jan 2 (00:00) UTC -> Jan 1 (23:00) UTC-1 in JS. * So use QDateTime for interfacing to always carry a timezone around. * https://bugreports.qt.io/browse/QTBUG-29328 */ /** * This property is used to determine which data from which month to show, it ensures * the day passed in the QDate is visible */ Q_PROPERTY(QDateTime displayedDate READ displayedDate WRITE setDisplayedDate NOTIFY displayedDateChanged) /** * This property is used to determine which data from which month to show, it ensures * the day passed in the QDate is visible */ Q_PROPERTY(QDateTime today READ today WRITE setToday NOTIFY todayChanged) /** * This determines which kind of data types should be contained in * selectedDayModel and upcomingEventsModel. By default all types are included. * NOTE: Only the Event type is fully implemented. * TODO: Fully implement the other data types throughout this code. */ Q_PROPERTY(int types READ types WRITE setTypes NOTIFY typesChanged) /** * This model contains the week numbers for the given date grid. */ Q_PROPERTY(QJsonArray weeksModel READ weeksModel NOTIFY weeksModelChanged) /** * The number of days a week contains. * TODO: perhaps this one can just be removed. A week is 7 days by definition. * However, i don't know if that's also the case in other more exotic calendars. */ Q_PROPERTY(int days READ days WRITE setDays NOTIFY daysChanged) /** * The number of weeks that the model property should contain. */ Q_PROPERTY(int weeks READ weeks WRITE setWeeks NOTIFY weeksChanged) /** * The start day of a week. By default this follows current Locale. It can be * changed. One then needs to use the numbers in the Qt DayOfWeek enum: * * Monday = 1 * Tuesday = 2 * Wednesday = 3 * Thursday = 4 * Friday = 5 * Saturday = 6 * Sunday = 7 * * This value doesn't do anything to other data structures, but helps you * visualizing the data. * * WARNING: QML has different enum values for week days - Sunday is 0, this function * automatically converts that on READ and WRITE and it's stored as QDate format * (ie. the one above). So firstDayOfWeek() call from QML would return 0 for Sunday * while internally it's 7 and vice-versa. */ Q_PROPERTY(int firstDayOfWeek READ firstDayOfWeek WRITE setFirstDayOfWeek NOTIFY firstDayOfWeekChanged) /** * The full year in a numeric value. For example 2013, not 13. */ Q_PROPERTY(int year READ year NOTIFY yearChanged) /** * If an error occurred, it will be set in this string as human readable text. */ Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) /** * This is the human readable long month name. So not "Feb" but "February". * TODO: this should either be done in QML using javascript or by making a * function available because this is limiting. There are places * where you would want the short month name. */ Q_PROPERTY(QString monthName READ monthName NOTIFY monthNameChanged) Q_PROPERTY(int month READ month NOTIFY monthChanged) /** * This model contains the actual grid data of days. For example, if you had set: * - days = 7 (7 days in one week) * - weeks = 6 (6 weeks in one month view) * then this model will contain 42 entries (days * weeks). Each entry contains * metadata about the current day. The exact metadata can be found in "daysmodel.cpp" * where the exact names usable in QML are being set. */ Q_PROPERTY(DaysModel *daysModel READ daysModel CONSTANT) public: enum Type { Holiday = 1, Event = 2, Todo = 4, Journal = 8, }; Q_ENUM(Type) Q_DECLARE_FLAGS(Types, Type) enum DateMatchingPrecision { MatchYear, MatchYearAndMonth, MatchYearMonthAndDay, }; Q_ENUM(DateMatchingPrecision) explicit Calendar(QObject *parent = nullptr); ~Calendar() override; // Displayed date QDateTime displayedDate() const; void setDisplayedDate(const QDate &dateTime); void setDisplayedDate(const QDateTime &dateTime); // The day that represents "today" QDateTime today() const; void setToday(const QDateTime &dateTime); // Types int types() const; void setTypes(int types); // Days int days(); void setDays(int days); // Weeks int weeks() const; void setWeeks(int weeks); // Start day int firstDayOfWeek() const; void setFirstDayOfWeek(int day); // Error message QString errorMessage() const; // Month name QString monthName() const; int month() const; int year() const; // Models DaysModel *daysModel() const; QJsonArray weeksModel() const; // QML invokables Q_INVOKABLE void nextMonth(); Q_INVOKABLE void previousMonth(); Q_INVOKABLE void nextYear(); Q_INVOKABLE void previousYear(); Q_INVOKABLE void nextDecade(); Q_INVOKABLE void previousDecade(); Q_INVOKABLE QString dayName(int weekday) const; Q_INVOKABLE int currentWeek() const; Q_INVOKABLE void resetToToday(); Q_INVOKABLE void goToMonth(int month); Q_INVOKABLE void goToYear(int year); Q_INVOKABLE void goToYearAndMonth(int year, int month); Q_SIGNALS: void displayedDateChanged(); void todayChanged(); void typesChanged(); void daysChanged(); void weeksChanged(); void firstDayOfWeekChanged(); void errorMessageChanged(); void monthNameChanged(); void monthChanged(); void yearChanged(); void weeksModelChanged(); public Q_SLOTS: void updateData(); private: CalendarPrivate *const d; };