File indexing completed on 2024-06-23 04:42:35
0001 // Copyright (c) 2018 Michael Bohlender <michael.bohlender@kdemail.net> 0002 // Copyright (c) 2018 Christian Mollekopf <mollekopf@kolabsys.com> 0003 // Copyright (c) 2018 RĂ©mi Nicole <minijackson@riseup.net> 0004 // Copyright (c) 2021 Carl Schwan <carlschwan@kde.org> 0005 // Copyright (c) 2021 Claudio Cambra <claudio.cambra@gmail.com> 0006 // SPDX-License-Identifier: LGPL-2.0-or-later 0007 0008 #pragma once 0009 0010 #include <QObject> 0011 #include <QQmlEngine> 0012 #include <Akonadi/ETMCalendar> 0013 0014 #include <KConfigWatcher> 0015 #include <KFormat> 0016 #include <QAbstractItemModel> 0017 #include <QColor> 0018 #include <QDateTime> 0019 #include <QList> 0020 #include <QSharedPointer> 0021 #include <QTimer> 0022 0023 class Filter; 0024 namespace KCalendarCore 0025 { 0026 class Incidence; 0027 } 0028 namespace Akonadi 0029 { 0030 class ETMCalendar; 0031 } 0032 0033 using namespace KCalendarCore; 0034 0035 /** 0036 * Loads all event occurrences within the given period and matching the given filter. 0037 * 0038 * Recurrences are expanded 0039 */ 0040 class IncidenceOccurrenceModel : public QAbstractListModel 0041 { 0042 Q_OBJECT 0043 QML_ELEMENT 0044 Q_PROPERTY(QDate start READ start WRITE setStart NOTIFY startChanged) 0045 Q_PROPERTY(int length READ length WRITE setLength NOTIFY lengthChanged) 0046 Q_PROPERTY(Filter *filter READ filter WRITE setFilter NOTIFY filterChanged) 0047 Q_PROPERTY(Akonadi::ETMCalendar::Ptr calendar READ calendar WRITE setCalendar NOTIFY calendarChanged) 0048 Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged) 0049 Q_PROPERTY(int resetThrottleInterval READ resetThrottleInterval WRITE setResetThrottleInterval NOTIFY resetThrottleIntervalChanged) 0050 0051 public: 0052 enum Roles { 0053 Summary = Qt::UserRole + 1, 0054 Description, 0055 Location, 0056 StartTime, 0057 EndTime, 0058 Duration, 0059 DurationString, 0060 Recurs, 0061 HasReminders, 0062 Priority, 0063 Color, 0064 CollectionId, 0065 AllDay, 0066 TodoCompleted, 0067 IsOverdue, 0068 IsReadOnly, 0069 IncidenceId, 0070 IncidenceType, 0071 IncidenceTypeStr, 0072 IncidenceTypeIcon, 0073 IncidencePtr, 0074 IncidenceOccurrence, 0075 LastRole 0076 }; 0077 Q_ENUM(Roles) 0078 explicit IncidenceOccurrenceModel(QObject *parent = nullptr); 0079 ~IncidenceOccurrenceModel() override = default; 0080 0081 int rowCount(const QModelIndex &parent = {}) const override; 0082 QVariant data(const QModelIndex &index, int role) const override; 0083 QHash<int, QByteArray> roleNames() const override; 0084 0085 Akonadi::ETMCalendar::Ptr calendar() const; 0086 QDate start() const; 0087 int length() const; 0088 Filter *filter() const; 0089 bool loading() const; 0090 int resetThrottleInterval() const; 0091 0092 struct Occurrence { 0093 QDateTime start; 0094 QDateTime end; 0095 KCalendarCore::Incidence::Ptr incidence; 0096 QColor color; 0097 qint64 collectionId; 0098 bool allDay; 0099 }; 0100 0101 Q_SIGNALS: 0102 void startChanged(); 0103 void lengthChanged(); 0104 void filterChanged(); 0105 void calendarChanged(); 0106 void loadingChanged(); 0107 void resetThrottleIntervalChanged(); 0108 0109 public Q_SLOTS: 0110 void setStart(const QDate &start); 0111 void setLength(int length); 0112 void setFilter(Filter *filter); 0113 void setCalendar(Akonadi::ETMCalendar::Ptr calendar); 0114 void setResetThrottleInterval(const int resetThrottleInterval); 0115 0116 private Q_SLOTS: 0117 void loadColors(); 0118 void scheduleReset(); 0119 void resetFromSource(); 0120 0121 void slotSourceDataChanged(const QModelIndex &upperLeft, const QModelIndex &bottomRight); 0122 void slotSourceRowsInserted(const QModelIndex &parent, const int first, const int last); 0123 0124 void setLoading(const bool loading); 0125 0126 private: 0127 static std::pair<QDateTime, QDateTime> incidenceOccurrenceStartEnd(const QDateTime &ocStart, const KCalendarCore::Incidence::Ptr &incidence); 0128 static uint incidenceOccurrenceHash(const QDateTime &ocStart, const QDateTime &ocEnd, const QString &incidenceUid); 0129 bool incidencePassesFilter(const KCalendarCore::Incidence::Ptr &incidence); 0130 0131 QColor getColor(const KCalendarCore::Incidence::Ptr &incidence); 0132 qint64 getCollectionId(const KCalendarCore::Incidence::Ptr &incidence); 0133 0134 QSharedPointer<QAbstractItemModel> mSourceModel; 0135 QDate mStart; 0136 QDate mEnd; 0137 int mLength{0}; 0138 Akonadi::ETMCalendar::Ptr m_coreCalendar; 0139 0140 QTimer m_resetThrottlingTimer; 0141 int m_resetThrottleInterval = 100; 0142 0143 bool m_loading = false; 0144 QVector<Occurrence> m_incidences; // We need incidences to be in a preditable order for the model 0145 QHash<uint, QPersistentModelIndex> m_occurrenceIndexHash; 0146 QHash<QString, QColor> m_colors; 0147 KConfigWatcher::Ptr m_colorWatcher; 0148 Filter *mFilter = nullptr; 0149 KFormat m_format; 0150 }; 0151 0152 Q_DECLARE_METATYPE(IncidenceOccurrenceModel::Occurrence) 0153 0154 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0155 Q_DECLARE_METATYPE(KCalendarCore::Incidence::Ptr) 0156 #endif