File indexing completed on 2024-11-24 04:50:40

0001 // SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>
0002 // SPDX-License-Identifier: LGPL-2.1-or-later
0003 
0004 #pragma once
0005 
0006 #include "calendarmanager.h"
0007 #include "models/attachmentsmodel.h"
0008 #include "models/attendeesmodel.h"
0009 #include "models/recurrenceexceptionsmodel.h"
0010 
0011 #include <Akonadi/CollectionIdentificationAttribute>
0012 #include <Akonadi/Item>
0013 #include <Akonadi/ItemFetchJob>
0014 #include <Akonadi/ItemFetchScope>
0015 #include <Akonadi/ItemMonitor>
0016 #include <KCalUtils/RecurrenceActions>
0017 #include <KFormat>
0018 #include <QByteArray>
0019 #include <QObject>
0020 #include <QPointer>
0021 
0022 /**
0023  * This class is a wrapper for a KCalendarCore::Incidence::Ptr object.
0024  * We can use it to create new incidences, or create incidence pointers from
0025  * pre-existing incidences, to more cleanly pass around to our QML code
0026  * or to the CalendarManager, which handles the back-end stuff of
0027  * adding and editing the incidence in the collection of our choice.
0028  */
0029 
0030 class IncidenceWrapper : public QObject, public Akonadi::ItemMonitor
0031 {
0032     Q_OBJECT
0033 
0034     // Akonadi properties
0035     Q_PROPERTY(Akonadi::Item incidenceItem READ incidenceItem WRITE setIncidenceItem NOTIFY incidenceItemChanged)
0036     Q_PROPERTY(qint64 collectionId READ collectionId WRITE setCollectionId NOTIFY collectionIdChanged)
0037 
0038     // Incidence properties
0039     Q_PROPERTY(KCalendarCore::Incidence::Ptr incidencePtr READ incidencePtr WRITE setIncidencePtr NOTIFY incidencePtrChanged)
0040     Q_PROPERTY(KCalendarCore::Incidence::Ptr originalIncidencePtr READ originalIncidencePtr NOTIFY originalIncidencePtrChanged)
0041     Q_PROPERTY(int incidenceType READ incidenceType NOTIFY incidenceTypeChanged)
0042     Q_PROPERTY(QString incidenceTypeStr READ incidenceTypeStr NOTIFY incidenceTypeStrChanged)
0043     Q_PROPERTY(QString incidenceIconName READ incidenceIconName NOTIFY incidenceIconNameChanged)
0044     Q_PROPERTY(QString uid READ uid CONSTANT) // TODO: This needs to not be a CONSTANT
0045 
0046     Q_PROPERTY(QString parent READ parent WRITE setParent NOTIFY parentChanged)
0047     Q_PROPERTY(IncidenceWrapper *parentIncidence READ parentIncidence NOTIFY parentIncidenceChanged)
0048     Q_PROPERTY(QVariantList childIncidences READ childIncidences NOTIFY childIncidencesChanged)
0049 
0050     Q_PROPERTY(QString summary READ summary WRITE setSummary NOTIFY summaryChanged)
0051     Q_PROPERTY(QStringList categories READ categories WRITE setCategories NOTIFY categoriesChanged)
0052     Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
0053     Q_PROPERTY(QString location READ location WRITE setLocation NOTIFY locationChanged)
0054     Q_PROPERTY(bool hasGeo READ hasGeo CONSTANT) // TODO: This needs to not be a CONSTANT
0055     Q_PROPERTY(float geoLatitude READ geoLatitude CONSTANT) // TODO: This needs to not be a CONSTANT
0056     Q_PROPERTY(float geoLongitude READ geoLongitude CONSTANT) // TODO: This needs to not be a CONSTANT
0057 
0058     Q_PROPERTY(QDateTime incidenceStart READ incidenceStart WRITE setIncidenceStart NOTIFY incidenceStartChanged)
0059     Q_PROPERTY(QString incidenceStartDateDisplay READ incidenceStartDateDisplay NOTIFY incidenceStartDateDisplayChanged)
0060     Q_PROPERTY(QString incidenceStartTimeDisplay READ incidenceStartTimeDisplay NOTIFY incidenceStartTimeDisplayChanged)
0061     Q_PROPERTY(QDateTime incidenceEnd READ incidenceEnd WRITE setIncidenceEnd NOTIFY incidenceEndChanged)
0062     Q_PROPERTY(QString incidenceEndDateDisplay READ incidenceEndDateDisplay NOTIFY incidenceEndDateDisplayChanged)
0063     Q_PROPERTY(QString incidenceEndTimeDisplay READ incidenceEndTimeDisplay NOTIFY incidenceEndTimeDisplayChanged)
0064     Q_PROPERTY(QByteArray timeZone READ timeZone WRITE setTimeZone NOTIFY timeZoneChanged)
0065     Q_PROPERTY(int startTimeZoneUTCOffsetMins READ startTimeZoneUTCOffsetMins NOTIFY startTimeZoneUTCOffsetMinsChanged)
0066     Q_PROPERTY(int endTimeZoneUTCOffsetMins READ endTimeZoneUTCOffsetMins NOTIFY endTimeZoneUTCOffsetMinsChanged)
0067     Q_PROPERTY(KCalendarCore::Duration duration READ duration NOTIFY durationChanged)
0068     Q_PROPERTY(QString durationDisplayString READ durationDisplayString NOTIFY durationDisplayStringChanged)
0069     Q_PROPERTY(bool allDay READ allDay WRITE setAllDay NOTIFY allDayChanged)
0070     Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
0071 
0072     Q_PROPERTY(KCalendarCore::Recurrence *recurrence READ recurrence NOTIFY incidencePtrChanged)
0073     Q_PROPERTY(QVariantMap recurrenceData READ recurrenceData NOTIFY recurrenceDataChanged)
0074     Q_PROPERTY(RecurrenceExceptionsModel *recurrenceExceptionsModel READ recurrenceExceptionsModel NOTIFY recurrenceExceptionsModelChanged)
0075 
0076     Q_PROPERTY(AttendeesModel *attendeesModel READ attendeesModel NOTIFY attendeesModelChanged)
0077     Q_PROPERTY(QVariantMap organizer READ organizer NOTIFY organizerChanged)
0078     Q_PROPERTY(KCalendarCore::Attendee::List attendees READ attendees NOTIFY attendeesChanged)
0079 
0080     Q_PROPERTY(AttachmentsModel *attachmentsModel READ attachmentsModel NOTIFY attachmentsModelChanged)
0081 
0082     Q_PROPERTY(bool todoCompleted READ todoCompleted WRITE setTodoCompleted NOTIFY todoCompletedChanged)
0083     Q_PROPERTY(QDateTime todoCompletionDt READ todoCompletionDt NOTIFY todoCompletionDtChanged)
0084     Q_PROPERTY(int todoPercentComplete READ todoPercentComplete WRITE setTodoPercentComplete NOTIFY todoPercentCompleteChanged)
0085 
0086     Q_PROPERTY(QString googleConferenceUrl READ googleConferenceUrl NOTIFY googleConferenceUrlChanged)
0087 
0088 public:
0089     enum RecurrenceIntervals {
0090         Daily,
0091         Weekly,
0092         Monthly,
0093         Yearly,
0094     };
0095     Q_ENUM(RecurrenceIntervals)
0096 
0097     enum IncidenceTypes {
0098         TypeEvent = KCalendarCore::IncidenceBase::TypeEvent,
0099         TypeTodo = KCalendarCore::IncidenceBase::TypeTodo,
0100         TypeJournal = KCalendarCore::IncidenceBase::TypeJournal,
0101     };
0102     Q_ENUM(IncidenceTypes)
0103 
0104     enum RecurrenceActions {
0105         AllOccurrences = KCalUtils::RecurrenceActions::AllOccurrences,
0106         SelectedOccurrence = KCalUtils::RecurrenceActions::SelectedOccurrence,
0107         FutureOccurrences = KCalUtils::RecurrenceActions::FutureOccurrences,
0108     };
0109     Q_ENUM(RecurrenceActions)
0110 
0111     typedef QSharedPointer<IncidenceWrapper> Ptr;
0112 
0113     explicit IncidenceWrapper(CalendarManager *CalendarManager, QObject *parent = nullptr);
0114     ~IncidenceWrapper() override;
0115 
0116     void notifyDataChanged();
0117 
0118     Akonadi::Item incidenceItem() const;
0119     void setIncidenceItem(const Akonadi::Item &incidenceItem);
0120     KCalendarCore::Incidence::Ptr incidencePtr() const;
0121     KCalendarCore::Incidence::Ptr originalIncidencePtr();
0122     int incidenceType() const;
0123     QString incidenceTypeStr() const;
0124     QString incidenceIconName() const;
0125     QString uid() const;
0126     qint64 collectionId() const;
0127     void setCollectionId(qint64 collectionId);
0128     QString parent() const;
0129     void setParent(QString parent);
0130     IncidenceWrapper *parentIncidence();
0131     QVariantList childIncidences();
0132 
0133     QString summary() const;
0134     void setSummary(const QString &summary);
0135     QStringList categories();
0136     void setCategories(QStringList categories);
0137     QString description() const;
0138     void setDescription(const QString &description);
0139     QString location() const;
0140     void setLocation(const QString &location);
0141     bool hasGeo() const;
0142     float geoLatitude() const;
0143     float geoLongitude() const;
0144 
0145     QDateTime incidenceStart() const;
0146     Q_INVOKABLE void setIncidenceStart(const QDateTime &incidenceStart, bool respectTimeZone = false);
0147     Q_INVOKABLE void setIncidenceStartDate(int day, int month, int year);
0148     Q_INVOKABLE void setIncidenceStartTime(int hours, int minutes);
0149     QString incidenceStartDateDisplay() const;
0150     QString incidenceStartTimeDisplay() const;
0151     QDateTime incidenceEnd() const;
0152     Q_INVOKABLE void setIncidenceEnd(const QDateTime &incidenceEnd, bool respectTimeZone = false);
0153     Q_INVOKABLE void setIncidenceEndDate(int day, int month, int year);
0154     Q_INVOKABLE void setIncidenceEndTime(int hours, int minutes);
0155     QString incidenceEndDateDisplay() const;
0156     QString incidenceEndTimeDisplay() const;
0157     Q_INVOKABLE void setIncidenceTimeToNearestQuarterHour(bool setStartTime = true, bool setEndTime = true);
0158     QByteArray timeZone() const;
0159     void setTimeZone(const QByteArray &timeZone);
0160     int startTimeZoneUTCOffsetMins();
0161     int endTimeZoneUTCOffsetMins();
0162     KCalendarCore::Duration duration() const;
0163     QString durationDisplayString() const;
0164     bool allDay() const;
0165     void setAllDay(bool allDay);
0166     int priority() const;
0167     void setPriority(int priority);
0168 
0169     KCalendarCore::Recurrence *recurrence() const;
0170     QVariantMap recurrenceData();
0171     Q_INVOKABLE void setRecurrenceDataItem(const QString &key, const QVariant &value);
0172 
0173     QVariantMap organizer();
0174     KCalendarCore::Attendee::List attendees() const;
0175 
0176     AttendeesModel *attendeesModel();
0177     RecurrenceExceptionsModel *recurrenceExceptionsModel();
0178     AttachmentsModel *attachmentsModel();
0179 
0180     bool todoCompleted() const;
0181     void setTodoCompleted(bool completed);
0182     QDateTime todoCompletionDt();
0183     int todoPercentComplete() const;
0184     void setTodoPercentComplete(int todoPercentComplete);
0185 
0186     Q_INVOKABLE void triggerEditMode();
0187     Q_INVOKABLE void setNewEvent();
0188     Q_INVOKABLE void setNewTodo();
0189     Q_INVOKABLE void addAlarms(const KCalendarCore::Alarm::List &alarms);
0190     Q_INVOKABLE bool hasReminders() const;
0191     Q_INVOKABLE void setRegularRecurrence(IncidenceWrapper::RecurrenceIntervals interval, int freq = 1);
0192     Q_INVOKABLE void setMonthlyPosRecurrence(short pos, int day);
0193     Q_INVOKABLE void setRecurrenceOccurrences(int occurrences);
0194     Q_INVOKABLE void clearRecurrences();
0195 
0196     Q_INVOKABLE void setCollection(const Akonadi::Collection &collection);
0197 
0198     QString googleConferenceUrl();
0199 Q_SIGNALS:
0200     void incidenceItemChanged();
0201     void incidencePtrChanged(KCalendarCore::Incidence::Ptr incidencePtr);
0202     void originalIncidencePtrChanged();
0203     void incidenceTypeChanged();
0204     void incidenceTypeStrChanged();
0205     void incidenceIconNameChanged();
0206     void collectionIdChanged();
0207     void parentChanged();
0208     void parentIncidenceChanged();
0209     void childIncidencesChanged();
0210 
0211     void summaryChanged();
0212     void categoriesChanged();
0213     void descriptionChanged();
0214     void locationChanged();
0215 
0216     void incidenceStartChanged();
0217     void incidenceStartDateDisplayChanged();
0218     void incidenceStartTimeDisplayChanged();
0219     void incidenceEndChanged();
0220     void incidenceEndDateDisplayChanged();
0221     void incidenceEndTimeDisplayChanged();
0222     void timeZoneChanged();
0223     void startTimeZoneUTCOffsetMinsChanged();
0224     void endTimeZoneUTCOffsetMinsChanged();
0225     void durationChanged();
0226     void durationDisplayStringChanged();
0227     void allDayChanged();
0228     void priorityChanged();
0229 
0230     void recurrenceDataChanged();
0231     void organizerChanged();
0232     void attendeesModelChanged();
0233     void recurrenceExceptionsModelChanged();
0234     void attachmentsModelChanged();
0235 
0236     void todoCompletedChanged();
0237     void todoCompletionDtChanged();
0238     void todoPercentCompleteChanged();
0239     void attendeesChanged();
0240 
0241     void googleConferenceUrlChanged();
0242 
0243 protected:
0244     void itemChanged(const Akonadi::Item &item) override;
0245 
0246 private:
0247     void setIncidencePtr(KCalendarCore::Incidence::Ptr incidencePtr);
0248     void setNewIncidence(KCalendarCore::Incidence::Ptr incidence);
0249     void updateParentIncidence();
0250     void resetChildIncidences();
0251     void cleanupChildIncidences();
0252 
0253     QPointer<CalendarManager> m_calendarManager = nullptr;
0254 
0255     KCalendarCore::Incidence::Ptr m_incidence;
0256     KCalendarCore::Incidence::Ptr m_originalIncidence;
0257     qint64 m_collectionId = -1; // For when we want to edit, this is temporary
0258     AttendeesModel m_attendeesModel;
0259     RecurrenceExceptionsModel m_recurrenceExceptionsModel;
0260     AttachmentsModel m_attachmentsModel;
0261 
0262     KFormat m_format;
0263     Ptr m_parentIncidence;
0264     QVariantList m_childIncidences;
0265 };