File indexing completed on 2025-03-09 04:53:44
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 <Akonadi/ETMCalendar> 0011 #include <QObject> 0012 0013 #include <KConfigWatcher> 0014 #include <KFormat> 0015 #include <QAbstractItemModel> 0016 #include <QColor> 0017 #include <QDateTime> 0018 #include <QList> 0019 #include <QSharedPointer> 0020 #include <QTimer> 0021 0022 class Filter; 0023 namespace KCalendarCore 0024 { 0025 class Incidence; 0026 } 0027 namespace Akonadi 0028 { 0029 class ETMCalendar; 0030 } 0031 0032 using namespace KCalendarCore; 0033 0034 /** 0035 * Loads all event occurrences within the given period and matching the given filter. 0036 * 0037 * Recurrences are expanded 0038 */ 0039 class IncidenceOccurrenceModel : public QAbstractListModel 0040 { 0041 Q_OBJECT 0042 Q_PROPERTY(QDate start READ start WRITE setStart NOTIFY startChanged) 0043 Q_PROPERTY(int length READ length WRITE setLength NOTIFY lengthChanged) 0044 Q_PROPERTY(Filter *filter READ filter WRITE setFilter NOTIFY filterChanged) 0045 Q_PROPERTY(Akonadi::ETMCalendar::Ptr calendar READ calendar WRITE setCalendar NOTIFY calendarChanged) 0046 Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged) 0047 Q_PROPERTY(int resetThrottleInterval READ resetThrottleInterval WRITE setResetThrottleInterval NOTIFY resetThrottleIntervalChanged) 0048 0049 public: 0050 enum Roles { 0051 Summary = Qt::UserRole + 1, 0052 Description, 0053 Location, 0054 StartTime, 0055 EndTime, 0056 Duration, 0057 DurationString, 0058 Recurs, 0059 HasReminders, 0060 Priority, 0061 Color, 0062 CollectionId, 0063 AllDay, 0064 TodoCompleted, 0065 IsOverdue, 0066 IsReadOnly, 0067 IncidenceId, 0068 IncidenceType, 0069 IncidenceTypeStr, 0070 IncidenceTypeIcon, 0071 IncidencePtr, 0072 IncidenceOccurrence, 0073 LastRole 0074 }; 0075 Q_ENUM(Roles) 0076 explicit IncidenceOccurrenceModel(QObject *parent = nullptr); 0077 ~IncidenceOccurrenceModel() override = default; 0078 0079 int rowCount(const QModelIndex &parent = {}) const override; 0080 QVariant data(const QModelIndex &index, int role) const override; 0081 0082 Akonadi::ETMCalendar::Ptr calendar() const; 0083 QDate start() const; 0084 int length() const; 0085 Filter *filter() const; 0086 bool loading() const; 0087 int resetThrottleInterval() const; 0088 0089 struct Occurrence { 0090 QDateTime start; 0091 QDateTime end; 0092 KCalendarCore::Incidence::Ptr incidence; 0093 QColor color; 0094 qint64 collectionId; 0095 bool allDay; 0096 }; 0097 0098 Q_SIGNALS: 0099 void startChanged(); 0100 void lengthChanged(); 0101 void filterChanged(); 0102 void calendarChanged(); 0103 void loadingChanged(); 0104 void resetThrottleIntervalChanged(); 0105 0106 public Q_SLOTS: 0107 void setStart(const QDate &start); 0108 void setLength(int length); 0109 void setFilter(Filter *filter); 0110 void setCalendar(Akonadi::ETMCalendar::Ptr calendar); 0111 void setResetThrottleInterval(const int resetThrottleInterval); 0112 0113 private Q_SLOTS: 0114 void loadColors(); 0115 void scheduleReset(); 0116 void resetFromSource(); 0117 void setLoading(const bool loading); 0118 0119 private: 0120 static std::pair<QDateTime, QDateTime> incidenceOccurrenceStartEnd(const QDateTime &ocStart, const KCalendarCore::Incidence::Ptr &incidence); 0121 bool incidencePassesFilter(const KCalendarCore::Incidence::Ptr &incidence); 0122 0123 QColor getColor(const KCalendarCore::Incidence::Ptr &incidence); 0124 qint64 getCollectionId(const KCalendarCore::Incidence::Ptr &incidence); 0125 0126 QSharedPointer<QAbstractItemModel> mSourceModel; 0127 QDate mStart; 0128 QDate mEnd; 0129 int mLength{0}; 0130 Akonadi::ETMCalendar::Ptr m_coreCalendar; 0131 0132 QTimer m_resetThrottlingTimer; 0133 int m_resetThrottleInterval = 100; 0134 0135 bool m_loading = false; 0136 QList<Occurrence> m_incidences; // We need incidences to be in a preditable order for the model 0137 QHash<Akonadi::Collection::Id, QColor> m_colors; 0138 KConfigWatcher::Ptr m_colorWatcher; 0139 Filter *mFilter = nullptr; 0140 KFormat m_format; 0141 }; 0142 0143 Q_DECLARE_METATYPE(IncidenceOccurrenceModel::Occurrence)