1 // SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>
2 // SPDX-License-Identifier: LGPL-2.1-or-later
3 
4 #pragma once
5 
6 #include <CalendarSupport/KCalPrefs>
7 #include <CalendarSupport/Utils>
8 #include <KCalUtils/RecurrenceActions>
9 #include <QByteArray>
10 #include <QObject>
11 #include <akonadi_version.h>
12 #if AKONADI_VERSION >= QT_VERSION_CHECK(5, 18, 41)
13 #include <Akonadi/CollectionIdentificationAttribute>
14 #include <Akonadi/Item>
15 #include <Akonadi/ItemFetchJob>
16 #include <Akonadi/ItemFetchScope>
17 #include <Akonadi/ItemMonitor>
18 #else
19 #include <AkonadiCore/CollectionIdentificationAttribute>
20 #include <AkonadiCore/Item>
21 #include <AkonadiCore/ItemFetchJob>
22 #include <AkonadiCore/ItemFetchScope>
23 #include <AkonadiCore/ItemMonitor>
24 #endif
25 #include "attachmentsmodel.h"
26 #include "attendeesmodel.h"
27 #include "recurrenceexceptionsmodel.h"
28 #include "remindersmodel.h"
29 
30 /**
31  * This class is a wrapper for a KCalendarCore::Incidence::Ptr object.
32  * We can use it to create new incidences, or create incidence pointers from
33  * pre-existing incidences, to more cleanly pass around to our QML code
34  * or to the CalendarManager, which handles the back-end stuff of
35  * adding and editing the incidence in the collection of our choice.
36  */
37 
38 class IncidenceWrapper : public QObject, public Akonadi::ItemMonitor
39 {
40     Q_OBJECT
41     Q_PROPERTY(Akonadi::Item incidenceItem READ incidenceItem WRITE setIncidenceItem NOTIFY incidenceItemChanged)
42     Q_PROPERTY(KCalendarCore::Incidence::Ptr incidencePtr READ incidencePtr WRITE setIncidencePtr NOTIFY incidencePtrChanged)
43     Q_PROPERTY(KCalendarCore::Incidence::Ptr originalIncidencePtr READ originalIncidencePtr NOTIFY originalIncidencePtrChanged)
44     Q_PROPERTY(int incidenceType READ incidenceType NOTIFY incidenceTypeChanged)
45     Q_PROPERTY(QString incidenceTypeStr READ incidenceTypeStr NOTIFY incidenceTypeStrChanged)
46     Q_PROPERTY(QString incidenceIconName READ incidenceIconName NOTIFY incidenceIconNameChanged)
47     Q_PROPERTY(QString uid READ uid CONSTANT);
48 
49     Q_PROPERTY(qint64 collectionId READ collectionId WRITE setCollectionId NOTIFY collectionIdChanged)
50     Q_PROPERTY(QString parent READ parent WRITE setParent NOTIFY parentChanged)
51     Q_PROPERTY(QString summary READ summary WRITE setSummary NOTIFY summaryChanged)
52     Q_PROPERTY(QStringList categories READ categories WRITE setCategories NOTIFY categoriesChanged)
53     Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
54     Q_PROPERTY(QString location READ location WRITE setLocation NOTIFY locationChanged)
55     Q_PROPERTY(bool hasGeo READ hasGeo CONSTANT)
56     Q_PROPERTY(float geoLatitude READ geoLatitude CONSTANT)
57     Q_PROPERTY(float geoLongitude READ geoLongitude CONSTANT)
58 
59     Q_PROPERTY(QDateTime incidenceStart READ incidenceStart WRITE setIncidenceStart NOTIFY incidenceStartChanged)
60     Q_PROPERTY(QString incidenceStartDateDisplay READ incidenceStartDateDisplay NOTIFY incidenceStartDateDisplayChanged)
61     Q_PROPERTY(QString incidenceStartTimeDisplay READ incidenceStartTimeDisplay NOTIFY incidenceStartTimeDisplayChanged)
62     Q_PROPERTY(QDateTime incidenceEnd READ incidenceEnd WRITE setIncidenceEnd NOTIFY incidenceEndChanged)
63     Q_PROPERTY(QString incidenceEndDateDisplay READ incidenceEndDateDisplay NOTIFY incidenceEndDateDisplayChanged)
64     Q_PROPERTY(QString incidenceEndTimeDisplay READ incidenceEndTimeDisplay NOTIFY incidenceEndTimeDisplayChanged)
65     Q_PROPERTY(QByteArray timeZone READ timeZone WRITE setTimeZone NOTIFY timeZoneChanged)
66     Q_PROPERTY(int startTimeZoneUTCOffsetMins READ startTimeZoneUTCOffsetMins NOTIFY startTimeZoneUTCOffsetMinsChanged)
67     Q_PROPERTY(int endTimeZoneUTCOffsetMins READ endTimeZoneUTCOffsetMins NOTIFY endTimeZoneUTCOffsetMinsChanged)
68     Q_PROPERTY(bool allDay READ allDay WRITE setAllDay NOTIFY allDayChanged)
69     Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
70 
71     Q_PROPERTY(KCalendarCore::Recurrence *recurrence READ recurrence NOTIFY incidencePtrChanged)
72     Q_PROPERTY(QVariantMap recurrenceData READ recurrenceData NOTIFY recurrenceDataChanged)
73     Q_PROPERTY(RecurrenceExceptionsModel *recurrenceExceptionsModel READ recurrenceExceptionsModel NOTIFY recurrenceExceptionsModelChanged)
74 
75     Q_PROPERTY(AttendeesModel *attendeesModel READ attendeesModel NOTIFY attendeesModelChanged)
76     Q_PROPERTY(QVariantMap organizer READ organizer NOTIFY organizerChanged)
77     Q_PROPERTY(KCalendarCore::Attendee::List attendees READ attendees NOTIFY attendeesChanged)
78 
79     Q_PROPERTY(RemindersModel *remindersModel READ remindersModel NOTIFY remindersModelChanged)
80     Q_PROPERTY(AttachmentsModel *attachmentsModel READ attachmentsModel NOTIFY attachmentsModelChanged)
81 
82     Q_PROPERTY(bool todoCompleted READ todoCompleted WRITE setTodoCompleted NOTIFY todoCompletedChanged)
83     Q_PROPERTY(QDateTime todoCompletionDt READ todoCompletionDt NOTIFY todoCompletionDtChanged)
84     Q_PROPERTY(int todoPercentComplete READ todoPercentComplete WRITE setTodoPercentComplete NOTIFY todoPercentCompleteChanged)
85 
86 public:
87     enum RecurrenceIntervals {
88         Daily,
89         Weekly,
90         Monthly,
91         Yearly,
92     };
93     Q_ENUM(RecurrenceIntervals);
94 
95     enum IncidenceTypes {
96         TypeEvent = KCalendarCore::IncidenceBase::TypeEvent,
97         TypeTodo = KCalendarCore::IncidenceBase::TypeTodo,
98         TypeJournal = KCalendarCore::IncidenceBase::TypeJournal,
99     };
100     Q_ENUM(IncidenceTypes)
101 
102     enum RecurrenceActions {
103         AllOccurrences = KCalUtils::RecurrenceActions::AllOccurrences,
104         SelectedOccurrence = KCalUtils::RecurrenceActions::SelectedOccurrence,
105         FutureOccurrences = KCalUtils::RecurrenceActions::FutureOccurrences,
106     };
107     Q_ENUM(RecurrenceActions)
108 
109     IncidenceWrapper(QObject *parent = nullptr);
110     ~IncidenceWrapper() override;
111 
112     void notifyDataChanged();
113 
114     Akonadi::Item incidenceItem() const;
115     void setIncidenceItem(const Akonadi::Item &incidenceItem);
116     KCalendarCore::Incidence::Ptr incidencePtr() const;
117     void setIncidencePtr(KCalendarCore::Incidence::Ptr incidencePtr);
118     KCalendarCore::Incidence::Ptr originalIncidencePtr();
119     int incidenceType() const;
120     QString incidenceTypeStr() const;
121     QString incidenceIconName() const;
122     QString uid() const;
123     qint64 collectionId() const;
124     void setCollectionId(qint64 collectionId);
125     QString parent() const;
126     void setParent(QString parent);
127     QString summary() const;
128     void setSummary(const QString &summary);
129     QStringList categories();
130     void setCategories(QStringList categories);
131     QString description() const;
132     void setDescription(const QString &description);
133     QString location() const;
134     void setLocation(const QString &location);
135     bool hasGeo() const;
136     float geoLatitude() const;
137     float geoLongitude() const;
138 
139     QDateTime incidenceStart() const;
140     Q_INVOKABLE void setIncidenceStart(const QDateTime &incidenceStart, bool respectTimeZone = false);
141     Q_INVOKABLE void setIncidenceStartDate(int day, int month, int year);
142     Q_INVOKABLE void setIncidenceStartTime(int hours, int minutes);
143     QString incidenceStartDateDisplay() const;
144     QString incidenceStartTimeDisplay() const;
145     QDateTime incidenceEnd() const;
146     Q_INVOKABLE void setIncidenceEnd(const QDateTime &incidenceEnd, bool respectTimeZone = false);
147     Q_INVOKABLE void setIncidenceEndDate(int day, int month, int year);
148     Q_INVOKABLE void setIncidenceEndTime(int hours, int minutes);
149     QString incidenceEndDateDisplay() const;
150     QString incidenceEndTimeDisplay() const;
151     QByteArray timeZone() const;
152     void setTimeZone(const QByteArray &timeZone);
153     int startTimeZoneUTCOffsetMins();
154     int endTimeZoneUTCOffsetMins();
155     bool allDay() const;
156     void setAllDay(bool allDay);
157     int priority() const;
158     void setPriority(int priority);
159 
160     KCalendarCore::Recurrence *recurrence() const;
161     QVariantMap recurrenceData();
162     Q_INVOKABLE void setRecurrenceDataItem(const QString &key, const QVariant &value);
163 
164     QVariantMap organizer();
165     KCalendarCore::Attendee::List attendees() const;
166 
167     RemindersModel *remindersModel();
168     AttendeesModel *attendeesModel();
169     RecurrenceExceptionsModel *recurrenceExceptionsModel();
170     AttachmentsModel *attachmentsModel();
171 
172     bool todoCompleted();
173     void setTodoCompleted(bool completed);
174     QDateTime todoCompletionDt();
175     int todoPercentComplete();
176     void setTodoPercentComplete(int todoPercentComplete);
177 
178     Q_INVOKABLE void triggerEditMode();
179     Q_INVOKABLE void setNewEvent();
180     Q_INVOKABLE void setNewTodo();
181     Q_INVOKABLE void addAlarms(KCalendarCore::Alarm::List alarms);
182     Q_INVOKABLE void setRegularRecurrence(IncidenceWrapper::RecurrenceIntervals interval, int freq = 1);
183     Q_INVOKABLE void setMonthlyPosRecurrence(short pos, int day);
184     Q_INVOKABLE void setRecurrenceOccurrences(int occurrences);
185     Q_INVOKABLE void clearRecurrences();
186 
187 Q_SIGNALS:
188     void incidenceItemChanged();
189     void incidencePtrChanged(KCalendarCore::Incidence::Ptr incidencePtr);
190     void originalIncidencePtrChanged();
191     void incidenceTypeChanged();
192     void incidenceTypeStrChanged();
193     void incidenceIconNameChanged();
194     void collectionIdChanged();
195     void parentChanged();
196     void summaryChanged();
197     void categoriesChanged();
198     void descriptionChanged();
199     void locationChanged();
200     void incidenceStartChanged();
201     void incidenceStartDateDisplayChanged();
202     void incidenceStartTimeDisplayChanged();
203     void incidenceEndChanged();
204     void incidenceEndDateDisplayChanged();
205     void incidenceEndTimeDisplayChanged();
206     void timeZoneChanged();
207     void startTimeZoneUTCOffsetMinsChanged();
208     void endTimeZoneUTCOffsetMinsChanged();
209     void allDayChanged();
210     void priorityChanged();
211     void remindersModelChanged();
212     void recurrenceDataChanged();
213     void organizerChanged();
214     void attendeesModelChanged();
215     void recurrenceExceptionsModelChanged();
216     void attachmentsModelChanged();
217     void todoCompletedChanged();
218     void todoCompletionDtChanged();
219     void todoPercentCompleteChanged();
220     void attendeesChanged();
221 
222 protected:
223     void itemChanged(const Akonadi::Item &item) override;
224 
225 private:
226     KCalendarCore::Incidence::Ptr m_incidence;
227     KCalendarCore::Incidence::Ptr m_originalIncidence;
228     qint64 m_collectionId = -1; // For when we want to edit, this is temporary
229     RemindersModel m_remindersModel;
230     AttendeesModel m_attendeesModel;
231     RecurrenceExceptionsModel m_recurrenceExceptionsModel;
232     AttachmentsModel m_attachmentsModel;
233 };
234