From 1f01d931607597a809f3b17381ed0d5980b8a4ee Mon Sep 17 00:00:00 2001 From: Damien Caliste Date: Tue, 23 May 2023 10:10:11 +0200 Subject: [PATCH 1/4] [nemo-qml-plugin-calendar] Make Event::instanceId sole identifier for events. Contributes to JB#60800 Remove the recurrenceId from the API, so instanceId is able to uniquely identify an event, or an exception. This is done internally by affecting the result of instanceIdentifier() to Event::instanceId. This would allow later to add a notebook UID information to this instanceId and thus being able to add multi-notebook support without changing once again the API. --- .../calendardataservice.cpp | 3 +- .../calendareventsmodel.cpp | 9 +- .../calendareventsmodel/calendareventsmodel.h | 3 +- lightweight/common/eventdata.cpp | 6 +- lightweight/common/eventdata.h | 3 +- rpm/nemo-qml-plugin-calendar-qt5.spec | 2 +- src/calendaragendamodel.cpp | 5 +- src/calendarapi.cpp | 9 +- src/calendarapi.h | 4 +- src/calendardata.h | 16 +-- src/calendarevent.cpp | 20 ++-- src/calendarevent.h | 6 +- src/calendareventlistmodel.cpp | 2 +- src/calendareventoccurrence.cpp | 11 +- src/calendareventoccurrence.h | 6 +- src/calendareventquery.cpp | 61 +++------- src/calendareventquery.h | 19 +--- src/calendarimportevent.cpp | 3 +- src/calendarinvitationquery.cpp | 25 +---- src/calendarinvitationquery.h | 12 +- src/calendarmanager.cpp | 105 +++++++----------- src/calendarmanager.h | 18 +-- src/calendarutils.cpp | 8 +- src/calendarutils.h | 2 +- src/calendarworker.cpp | 101 ++++++++++------- src/calendarworker.h | 14 ++- tests/tst_calendarevent/tst_calendarevent.cpp | 46 ++++---- .../tst_calendarsearchmodel.cpp | 1 + 28 files changed, 226 insertions(+), 294 deletions(-) diff --git a/lightweight/calendardataservice/calendardataservice.cpp b/lightweight/calendardataservice/calendardataservice.cpp index f3075d6a..61c507b7 100644 --- a/lightweight/calendardataservice/calendardataservice.cpp +++ b/lightweight/calendardataservice/calendardataservice.cpp @@ -105,8 +105,7 @@ void CalendarDataService::updated() } eventStruct.allDay = event->allDay(); eventStruct.color = event->color(); - eventStruct.recurrenceId = event->recurrenceIdString(); - eventStruct.uniqueId = event->uniqueId(); + eventStruct.instanceId = event->instanceId(); eventStruct.cancelled = event->status() == CalendarEvent::StatusCancelled; reply << eventStruct; } diff --git a/lightweight/calendareventsmodel/calendareventsmodel.cpp b/lightweight/calendareventsmodel/calendareventsmodel.cpp index 16164005..e75ab5f9 100644 --- a/lightweight/calendareventsmodel/calendareventsmodel.cpp +++ b/lightweight/calendareventsmodel/calendareventsmodel.cpp @@ -233,16 +233,14 @@ QVariant CalendarEventsModel::data(const QModelIndex &index, int role) const } else { return QDateTime::fromString(eventData.endTime, Qt::ISODate); } - case RecurrenceIdRole: - return eventData.recurrenceId; case AllDayRole: return eventData.allDay; case LocationRole: return eventData.location; case CalendarUidRole: return eventData.calendarUid; - case UidRole: - return eventData.uniqueId; + case InstanceIdRole: + return eventData.instanceId; case ColorRole: return QColor(eventData.color); case CancelledRole: @@ -362,11 +360,10 @@ QHash CalendarEventsModel::roleNames() const roleNames[DescriptionRole] = "description"; roleNames[StartTimeRole] = "startTime"; roleNames[EndTimeRole] = "endTime"; - roleNames[RecurrenceIdRole] = "recurrenceId"; roleNames[AllDayRole] = "allDay"; roleNames[LocationRole] = "location"; roleNames[CalendarUidRole] = "calendarUid"; - roleNames[UidRole] = "uid"; + roleNames[InstanceIdRole] = "instanceId"; roleNames[ColorRole] = "color"; roleNames[CancelledRole] = "cancelled"; diff --git a/lightweight/calendareventsmodel/calendareventsmodel.h b/lightweight/calendareventsmodel/calendareventsmodel.h index e1719c10..ce1d3664 100644 --- a/lightweight/calendareventsmodel/calendareventsmodel.h +++ b/lightweight/calendareventsmodel/calendareventsmodel.h @@ -77,11 +77,10 @@ class CalendarEventsModel : public QAbstractListModel DescriptionRole, StartTimeRole, EndTimeRole, - RecurrenceIdRole, AllDayRole, LocationRole, CalendarUidRole, - UidRole, + InstanceIdRole, ColorRole, CancelledRole }; diff --git a/lightweight/common/eventdata.cpp b/lightweight/common/eventdata.cpp index 993e6214..c99c41ad 100644 --- a/lightweight/common/eventdata.cpp +++ b/lightweight/common/eventdata.cpp @@ -4,8 +4,7 @@ QDBusArgument &operator<<(QDBusArgument &argument, const EventData &eventData) { argument.beginStructure(); argument << eventData.calendarUid - << eventData.uniqueId - << eventData.recurrenceId + << eventData.instanceId << eventData.startTime << eventData.endTime << eventData.allDay @@ -22,8 +21,7 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, EventData &eventD { argument.beginStructure(); argument >> eventData.calendarUid - >> eventData.uniqueId - >> eventData.recurrenceId + >> eventData.instanceId >> eventData.startTime >> eventData.endTime >> eventData.allDay diff --git a/lightweight/common/eventdata.h b/lightweight/common/eventdata.h index 01457543..324574bb 100644 --- a/lightweight/common/eventdata.h +++ b/lightweight/common/eventdata.h @@ -7,8 +7,7 @@ struct EventData { QString calendarUid; - QString uniqueId; - QString recurrenceId; + QString instanceId; QString startTime; QString endTime; bool allDay; diff --git a/rpm/nemo-qml-plugin-calendar-qt5.spec b/rpm/nemo-qml-plugin-calendar-qt5.spec index 84e05af3..883ec442 100644 --- a/rpm/nemo-qml-plugin-calendar-qt5.spec +++ b/rpm/nemo-qml-plugin-calendar-qt5.spec @@ -1,7 +1,7 @@ Name: nemo-qml-plugin-calendar-qt5 Summary: Calendar plugin for Nemo Mobile -Version: 0.6.56 +Version: 0.7.0 Release: 1 License: BSD URL: https://github.com/sailfishos/nemo-qml-plugin-calendar diff --git a/src/calendaragendamodel.cpp b/src/calendaragendamodel.cpp index 795887a0..3c6776b7 100644 --- a/src/calendaragendamodel.cpp +++ b/src/calendaragendamodel.cpp @@ -118,8 +118,7 @@ static bool eventsEqual(const CalendarEventOccurrence *e1, CalendarEvent *eventObject2 = e2->eventObject(); return eventObject1 && eventObject2 && - eventObject1->uniqueId() == eventObject2->uniqueId() && - eventObject1->recurrenceId() == eventObject2->recurrenceId(); + eventObject1->instanceId() == eventObject2->instanceId(); } static bool eventsLessThan(const CalendarEventOccurrence *e1, @@ -130,7 +129,7 @@ static bool eventsLessThan(const CalendarEventOccurrence *e1, e2->eventObject()->displayLabel(), Qt::CaseInsensitive); if (cmp == 0) - return QString::compare(e1->eventObject()->uniqueId(), e2->eventObject()->uniqueId()) < 0; + return QString::compare(e1->eventObject()->instanceId(), e2->eventObject()->instanceId()) < 0; else return cmp < 0; } else { diff --git a/src/calendarapi.cpp b/src/calendarapi.cpp index d6535e62..142f235f 100644 --- a/src/calendarapi.cpp +++ b/src/calendarapi.cpp @@ -58,18 +58,17 @@ CalendarEventModification * CalendarApi::createModification(CalendarStoredEvent return new CalendarEventModification(sourceEvent, occurrence); } -void CalendarApi::remove(const QString &uid, const QString &recurrenceId, const QDateTime &time) +void CalendarApi::remove(const QString &instanceId, const QDateTime &time) { - QDateTime recurrenceTime = QDateTime::fromString(recurrenceId, Qt::ISODate); - CalendarManager::instance()->deleteEvent(uid, recurrenceTime, time); + CalendarManager::instance()->deleteEvent(instanceId, time); // TODO: this sucks CalendarManager::instance()->save(); } -void CalendarApi::removeAll(const QString &uid) +void CalendarApi::removeAll(const QString &instanceId) { - CalendarManager::instance()->deleteAll(uid); + CalendarManager::instance()->deleteAll(instanceId); CalendarManager::instance()->save(); } diff --git a/src/calendarapi.h b/src/calendarapi.h index 5f6cec54..47160887 100644 --- a/src/calendarapi.h +++ b/src/calendarapi.h @@ -56,9 +56,9 @@ class CalendarApi : public QObject Q_INVOKABLE CalendarEventModification *createModification(CalendarStoredEvent *sourceEvent, CalendarEventOccurrence *occurrence = nullptr); - Q_INVOKABLE void remove(const QString &uid, const QString &recurrenceId = QString(), + Q_INVOKABLE void remove(const QString &instanceId, const QDateTime &time = QDateTime()); - Q_INVOKABLE void removeAll(const QString &uid); // remove all instances an event, all recurrenceIds + Q_INVOKABLE void removeAll(const QString &instanceId); // remove all instances of an event, including exceptions QStringList excludedNotebooks() const; void setExcludedNotebooks(const QStringList &); diff --git a/src/calendardata.h b/src/calendardata.h index 2bb2092c..b3b2bec0 100644 --- a/src/calendardata.h +++ b/src/calendardata.h @@ -45,15 +45,14 @@ namespace CalendarData { struct EventOccurrence { - QString eventUid; - QDateTime recurrenceId; + QString instanceId; QDateTime startTime; QDateTime endTime; bool eventAllDay; QString getId() const { - return QString("%1-%2").arg(eventUid).arg(startTime.toMSecsSinceEpoch()); + return QString("%1-%2").arg(instanceId).arg(startTime.toMSecsSinceEpoch()); } }; @@ -71,11 +70,12 @@ struct Event { CalendarEvent::Days recurWeeklyDays; int reminder = -1; // seconds; 15 minutes before event = +900, at time of event = 0, no reminder = negative value. QDateTime reminderDateTime; // Valid when reminder is at a given date and time. - QString uniqueId; - QDateTime recurrenceId; + QString instanceId; // A unique ID, used to identify an instance (incidence or exception) throughout calendars + QString incidenceUid; // The uid of the incidence, shared between parent and exceptions + QDateTime recurrenceId; // An id identifying an exception + QString calendarUid; // The uid of the calendar the instance belong to QString location; CalendarEvent::Secrecy secrecy = CalendarEvent::SecrecyPublic; - QString calendarUid; CalendarEvent::Response ownerStatus = CalendarEvent::ResponseUnspecified; CalendarEvent::Status status = CalendarEvent::StatusNone; CalendarEvent::SyncFailure syncFailure = CalendarEvent::NoSyncFailure; @@ -88,12 +88,12 @@ struct Event { bool operator==(const Event& other) const { - return uniqueId == other.uniqueId; + return instanceId == other.instanceId; } bool isValid() const { - return !uniqueId.isEmpty(); + return !instanceId.isEmpty(); } private: diff --git a/src/calendarevent.cpp b/src/calendarevent.cpp index b1cbd7cb..188d3568 100644 --- a/src/calendarevent.cpp +++ b/src/calendarevent.cpp @@ -157,9 +157,9 @@ QDateTime CalendarEvent::reminderDateTime() const return mData->reminderDateTime; } -QString CalendarEvent::uniqueId() const +QString CalendarEvent::instanceId() const { - return mData->uniqueId; + return mData->instanceId; } bool CalendarEvent::readOnly() const @@ -248,9 +248,9 @@ void CalendarStoredEvent::notebookColorChanged(QString notebookUid) void CalendarStoredEvent::eventUidChanged(QString oldUid, QString newUid) { - if (mData->uniqueId == oldUid) { - mData->uniqueId = newUid; - emit uniqueIdChanged(); + if (mData->instanceId == oldUid) { + mData->instanceId = newUid; + emit instanceIdChanged(); // Event uid changes when the event is moved between notebooks, calendar uid has changed emit calendarUidChanged(); } @@ -258,7 +258,7 @@ void CalendarStoredEvent::eventUidChanged(QString oldUid, QString newUid) bool CalendarStoredEvent::sendResponse(int response) { - if (mManager->sendResponse(mData->uniqueId, mData->recurrenceId, (Response)response)) { + if (mManager->sendResponse(mData->instanceId, (Response)response)) { mManager->save(); return true; } else { @@ -268,7 +268,7 @@ bool CalendarStoredEvent::sendResponse(int response) void CalendarStoredEvent::deleteEvent() { - mManager->deleteEvent(mData->uniqueId, mData->recurrenceId, QDateTime()); + mManager->deleteEvent(mData->instanceId, QDateTime()); mManager->save(); } @@ -276,13 +276,13 @@ void CalendarStoredEvent::deleteEvent() QString CalendarStoredEvent::iCalendar(const QString &prodId) const { Q_UNUSED(prodId); - if (mData->uniqueId.isEmpty()) { + if (mData->instanceId.isEmpty()) { qWarning() << "Event has no uid, returning empty iCalendar string." << "Save event before calling this function"; return QString(); } - return mManager->convertEventToICalendarSync(mData->uniqueId, prodId); + return mManager->convertEventToICalendarSync(mData->instanceId, prodId); } QString CalendarStoredEvent::color() const @@ -332,5 +332,5 @@ void CalendarStoredEvent::setEvent(const CalendarData::Event *data) CalendarData::Event CalendarStoredEvent::dissociateSingleOccurrence(const CalendarEventOccurrence *occurrence) const { - return occurrence ? mManager->dissociateSingleOccurrence(mData->uniqueId, occurrence->startTime()) : CalendarData::Event(); + return occurrence ? mManager->dissociateSingleOccurrence(mData->instanceId, occurrence->startTime()) : CalendarData::Event(); } diff --git a/src/calendarevent.h b/src/calendarevent.h index ea982a8f..b66147be 100644 --- a/src/calendarevent.h +++ b/src/calendarevent.h @@ -62,7 +62,7 @@ class CalendarEvent : public QObject Q_PROPERTY(CalendarEvent::Days recurWeeklyDays READ recurWeeklyDays NOTIFY recurWeeklyDaysChanged) Q_PROPERTY(int reminder READ reminder NOTIFY reminderChanged) Q_PROPERTY(QDateTime reminderDateTime READ reminderDateTime NOTIFY reminderDateTimeChanged) - Q_PROPERTY(QString uniqueId READ uniqueId NOTIFY uniqueIdChanged) + Q_PROPERTY(QString instanceId READ instanceId NOTIFY instanceIdChanged) Q_PROPERTY(QString recurrenceId READ recurrenceIdString CONSTANT) Q_PROPERTY(bool readOnly READ readOnly CONSTANT) Q_PROPERTY(QString calendarUid READ calendarUid NOTIFY calendarUidChanged) @@ -160,7 +160,7 @@ class CalendarEvent : public QObject Days recurWeeklyDays() const; int reminder() const; QDateTime reminderDateTime() const; - QString uniqueId() const; + QString instanceId() const; virtual bool readOnly() const; QString calendarUid() const; QString location() const; @@ -183,7 +183,7 @@ class CalendarEvent : public QObject void recurChanged(); void reminderChanged(); void reminderDateTimeChanged(); - void uniqueIdChanged(); + void instanceIdChanged(); void calendarUidChanged(); void locationChanged(); void recurEndDateChanged(); diff --git a/src/calendareventlistmodel.cpp b/src/calendareventlistmodel.cpp index 781f722b..83871ec9 100644 --- a/src/calendareventlistmodel.cpp +++ b/src/calendareventlistmodel.cpp @@ -153,7 +153,7 @@ void CalendarEventListModel::doRefresh() if (event.isValid()) { CalendarEventOccurrence *occurrence = CalendarManager::instance()->getNextOccurrence - (event.uniqueId, event.recurrenceId, mStartTime); + (event.instanceId, mStartTime); if (occurrence->startTime().isValid()) { occurrence->setProperty("identifier", id); mEvents.append(occurrence); diff --git a/src/calendareventoccurrence.cpp b/src/calendareventoccurrence.cpp index 46e44824..7d619054 100644 --- a/src/calendareventoccurrence.cpp +++ b/src/calendareventoccurrence.cpp @@ -37,12 +37,11 @@ #include "calendarevent.h" #include "calendarmanager.h" -CalendarEventOccurrence::CalendarEventOccurrence(const QString &eventUid, - const QDateTime &recurrenceId, +CalendarEventOccurrence::CalendarEventOccurrence(const QString &instanceId, const QDateTime &startTime, const QDateTime &endTime, QObject *parent) - : QObject(parent), mEventUid(eventUid), mRecurrenceId(recurrenceId), mStartTime(startTime), mEndTime(endTime) + : QObject(parent), mInstanceId(instanceId), mStartTime(startTime), mEndTime(endTime) { connect(CalendarManager::instance(), SIGNAL(eventUidChanged(QString,QString)), this, SLOT(eventUidChanged(QString,QString))); @@ -69,13 +68,13 @@ QDateTime CalendarEventOccurrence::endTime() const CalendarStoredEvent *CalendarEventOccurrence::eventObject() const { - return CalendarManager::instance()->eventObject(mEventUid, mRecurrenceId); + return CalendarManager::instance()->eventObject(mInstanceId); } void CalendarEventOccurrence::eventUidChanged(QString oldUid, QString newUid) { - if (mEventUid == oldUid) - mEventUid = newUid; + if (mInstanceId == oldUid) + mInstanceId = newUid; } static QDateTime toEventDateTime(const QDateTime &dateTime, diff --git a/src/calendareventoccurrence.h b/src/calendareventoccurrence.h index 2199bfa8..c247d0d5 100644 --- a/src/calendareventoccurrence.h +++ b/src/calendareventoccurrence.h @@ -50,8 +50,7 @@ class CalendarEventOccurrence : public QObject Q_PROPERTY(CalendarStoredEvent *event READ eventObject CONSTANT) public: - CalendarEventOccurrence(const QString &eventUid, - const QDateTime &recurrenceId, + CalendarEventOccurrence(const QString &instanceId, const QDateTime &startTime, const QDateTime &endTime, QObject *parent = 0); @@ -73,8 +72,7 @@ private slots: void eventUidChanged(QString oldUid, QString newUid); private: - QString mEventUid; - QDateTime mRecurrenceId; + QString mInstanceId; QDateTime mStartTime; QDateTime mEndTime; }; diff --git a/src/calendareventquery.cpp b/src/calendareventquery.cpp index 07b2c4c5..f3e2f745 100644 --- a/src/calendareventquery.cpp +++ b/src/calendareventquery.cpp @@ -58,18 +58,18 @@ CalendarEventQuery::~CalendarEventQuery() } } -// The uid of the matched event -QString CalendarEventQuery::uniqueId() const +// The instanceId of the matched event +QString CalendarEventQuery::instanceId() const { - return mUid; + return mInstanceId; } -void CalendarEventQuery::setUniqueId(const QString &uid) +void CalendarEventQuery::setInstanceId(const QString &instanceId) { - if (uid == mUid) + if (instanceId == mInstanceId) return; - mUid = uid; - emit uniqueIdChanged(); + mInstanceId = instanceId; + emit instanceIdChanged(); if (mEvent.isValid()) { mEvent = CalendarData::Event(); @@ -84,28 +84,6 @@ void CalendarEventQuery::setUniqueId(const QString &uid) refresh(); } -QString CalendarEventQuery::recurrenceIdString() -{ - if (mRecurrenceId.isValid()) { - return CalendarUtils::recurrenceIdToString(mRecurrenceId); - } else { - return QString(); - } -} - -void CalendarEventQuery::setRecurrenceIdString(const QString &recurrenceId) -{ - QDateTime recurrenceIdTime = QDateTime::fromString(recurrenceId, Qt::ISODate); - if (mRecurrenceId == recurrenceIdTime) { - return; - } - - mRecurrenceId = recurrenceIdTime; - emit recurrenceIdStringChanged(); - - refresh(); -} - // The ideal start time of the occurrence. If there is no occurrence with // the exact start time, the first occurrence following startTime is returned. // If there is no following occurrence, the previous occurrence is returned. @@ -132,8 +110,8 @@ void CalendarEventQuery::resetStartTime() QObject *CalendarEventQuery::event() const { - if (mEvent.isValid() && mEvent.uniqueId == mUid) - return CalendarManager::instance()->eventObject(mUid, mRecurrenceId); + if (mEvent.isValid() && mEvent.instanceId == mInstanceId) + return CalendarManager::instance()->eventObject(mInstanceId); else return nullptr; } @@ -147,7 +125,7 @@ QList CalendarEventQuery::attendees() { if (!mAttendeesCached) { bool resultValid = false; - mAttendees = CalendarManager::instance()->getEventAttendees(mUid, mRecurrenceId, &resultValid); + mAttendees = CalendarManager::instance()->getEventAttendees(mInstanceId, &resultValid); if (resultValid) { mAttendeesCached = true; } @@ -169,14 +147,14 @@ void CalendarEventQuery::componentComplete() void CalendarEventQuery::doRefresh(CalendarData::Event event, bool eventError) { - // The value of mUid may have changed, verify that we got what we asked for - if (event.isValid() && (event.uniqueId != mUid || event.recurrenceId != mRecurrenceId)) + // The value of mInstanceId may have changed, verify that we got what we asked for + if (event.isValid() && event.instanceId != mInstanceId) return; bool updateOccurrence = mUpdateOccurrence; bool signalEventChanged = false; - if (event.uniqueId != mEvent.uniqueId || event.recurrenceId != mEvent.recurrenceId) { + if (event.instanceId != mEvent.instanceId) { mEvent = event; signalEventChanged = true; updateOccurrence = true; @@ -197,7 +175,7 @@ void CalendarEventQuery::doRefresh(CalendarData::Event event, bool eventError) if (mEvent.isValid()) { CalendarEventOccurrence *occurrence = CalendarManager::instance()->getNextOccurrence( - mUid, mRecurrenceId, mStartTime); + mInstanceId, mStartTime); if (occurrence) { mOccurrence = occurrence; mOccurrence->setParent(this); @@ -213,7 +191,7 @@ void CalendarEventQuery::doRefresh(CalendarData::Event event, bool eventError) // check if attendees have changed. bool resultValid = false; QList attendees = CalendarManager::instance()->getEventAttendees( - mUid, mRecurrenceId, &resultValid); + mInstanceId, &resultValid); if (resultValid && mAttendees != attendees) { mAttendees = attendees; mAttendeesCached = true; @@ -231,14 +209,9 @@ bool CalendarEventQuery::eventError() const return mEventError; } -QDateTime CalendarEventQuery::recurrenceId() -{ - return mRecurrenceId; -} - void CalendarEventQuery::refresh() { - if (!mIsComplete || mUid.isEmpty()) + if (!mIsComplete || mInstanceId.isEmpty()) return; CalendarManager::instance()->scheduleEventQueryRefresh(this); @@ -257,7 +230,7 @@ void CalendarEventQuery::onTimezoneChanged() void CalendarEventQuery::eventUidChanged(QString oldUid, QString newUid) { - if (mUid == oldUid) { + if (mInstanceId == oldUid) { emit newUniqueId(newUid); refresh(); } diff --git a/src/calendareventquery.h b/src/calendareventquery.h index faaa80a4..696e0b1a 100644 --- a/src/calendareventquery.h +++ b/src/calendareventquery.h @@ -99,8 +99,7 @@ class CalendarEventQuery : public QObject, public QQmlParserStatus { Q_OBJECT Q_INTERFACES(QQmlParserStatus) - Q_PROPERTY(QString uniqueId READ uniqueId WRITE setUniqueId NOTIFY uniqueIdChanged) - Q_PROPERTY(QString recurrenceId READ recurrenceIdString WRITE setRecurrenceIdString NOTIFY recurrenceIdStringChanged) + Q_PROPERTY(QString instanceId READ instanceId WRITE setInstanceId NOTIFY instanceIdChanged) Q_PROPERTY(QDateTime startTime READ startTime WRITE setStartTime RESET resetStartTime NOTIFY startTimeChanged) Q_PROPERTY(QObject *event READ event NOTIFY eventChanged) Q_PROPERTY(QObject *occurrence READ occurrence NOTIFY occurrenceChanged) @@ -111,12 +110,8 @@ class CalendarEventQuery : public QObject, public QQmlParserStatus CalendarEventQuery(); ~CalendarEventQuery(); - QString uniqueId() const; - void setUniqueId(const QString &); - - QString recurrenceIdString(); - void setRecurrenceIdString(const QString &recurrenceId); - QDateTime recurrenceId(); + QString instanceId() const; + void setInstanceId(const QString &); QDateTime startTime() const; void setStartTime(const QDateTime &); @@ -135,8 +130,7 @@ class CalendarEventQuery : public QObject, public QQmlParserStatus void doRefresh(CalendarData::Event event, bool eventError); signals: - void uniqueIdChanged(); - void recurrenceIdStringChanged(); + void instanceIdChanged(); void eventChanged(); void occurrenceChanged(); void attendeesChanged(); @@ -144,7 +138,7 @@ class CalendarEventQuery : public QObject, public QQmlParserStatus void eventErrorChanged(); // Indicates that the event UID has changed in database, event has been moved between notebooks. - // The property uniqueId will not be changed, the data pointer properties event and occurrence + // The property instanceId will not be changed, the data pointer properties event and occurrence // will reset to null pointers. void newUniqueId(QString newUid); @@ -155,8 +149,7 @@ private slots: private: bool mIsComplete; - QString mUid; - QDateTime mRecurrenceId; + QString mInstanceId; QDateTime mStartTime; CalendarData::Event mEvent; CalendarEventOccurrence *mOccurrence; diff --git a/src/calendarimportevent.cpp b/src/calendarimportevent.cpp index 05a41cc8..b1f53f64 100644 --- a/src/calendarimportevent.cpp +++ b/src/calendarimportevent.cpp @@ -96,8 +96,7 @@ bool CalendarImportEvent::sendResponse(int response) QObject *CalendarImportEvent::nextOccurrence() { - return new CalendarEventOccurrence(mOccurrence.eventUid, - mOccurrence.recurrenceId, + return new CalendarEventOccurrence(mOccurrence.uniqueId, mOccurrence.startTime, mOccurrence.endTime); } diff --git a/src/calendarinvitationquery.cpp b/src/calendarinvitationquery.cpp index f779ed16..24893b7f 100644 --- a/src/calendarinvitationquery.cpp +++ b/src/calendarinvitationquery.cpp @@ -55,14 +55,9 @@ QString CalendarInvitationQuery::notebookUid() const return mNotebookUid; } -QString CalendarInvitationQuery::uid() const +QString CalendarInvitationQuery::instanceId() const { - return mUid; -} - -QString CalendarInvitationQuery::rid() const -{ - return mRid; + return mInstanceId; } QString CalendarInvitationQuery::startTime() const @@ -127,7 +122,6 @@ void CalendarInvitationQuery::queryResult(CalendarData::Event event) { bool needNUidEmit = false; bool needUidEmit = false; - bool needRidEmit = false; bool needSTEmit = false; if (mNotebookUid != event.calendarUid) { @@ -135,17 +129,11 @@ void CalendarInvitationQuery::queryResult(CalendarData::Event event) needNUidEmit = true; } - if (mUid != event.uniqueId) { - mUid = event.uniqueId; + if (mInstanceId != event.instanceId) { + mInstanceId = event.instanceId; needUidEmit = true; } - const QString &recurrenceIdString = CalendarUtils::recurrenceIdToString(event.recurrenceId); - if (mRid != recurrenceIdString) { - mRid = recurrenceIdString; - needRidEmit = true; - } - if (mStartTime != event.startTime.toString(Qt::ISODate)) { mStartTime = event.startTime.toString(Qt::ISODate); needSTEmit = true; @@ -157,10 +145,7 @@ void CalendarInvitationQuery::queryResult(CalendarData::Event event) emit notebookUidChanged(); } if (needUidEmit) { - emit uidChanged(); - } - if (needRidEmit) { - emit ridChanged(); + emit instanceIdChanged(); } if (needSTEmit) { emit startTimeChanged(); diff --git a/src/calendarinvitationquery.h b/src/calendarinvitationquery.h index c709584f..29b84583 100644 --- a/src/calendarinvitationquery.h +++ b/src/calendarinvitationquery.h @@ -46,8 +46,7 @@ class CalendarInvitationQuery : public QObject, public QQmlParserStatus Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QString invitationFile READ invitationFile WRITE setInvitationFile NOTIFY invitationFileChanged) Q_PROPERTY(QString notebookUid READ notebookUid NOTIFY notebookUidChanged) - Q_PROPERTY(QString uid READ uid NOTIFY uidChanged) - Q_PROPERTY(QString rid READ rid NOTIFY ridChanged) + Q_PROPERTY(QString instanceId READ instanceId NOTIFY instanceIdChanged) Q_PROPERTY(QString startTime READ startTime NOTIFY startTimeChanged) Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) @@ -59,8 +58,7 @@ class CalendarInvitationQuery : public QObject, public QQmlParserStatus void setInvitationFile(const QString &file); QString notebookUid() const; - QString uid() const; - QString rid() const; + QString instanceId() const; QString startTime() const; bool busy() const; @@ -73,8 +71,7 @@ class CalendarInvitationQuery : public QObject, public QQmlParserStatus signals: void invitationFileChanged(); void notebookUidChanged(); - void uidChanged(); - void ridChanged(); + void instanceIdChanged(); void startTimeChanged(); void busyChanged(); void queryFinished(); @@ -89,8 +86,7 @@ class CalendarInvitationQuery : public QObject, public QQmlParserStatus QString mInvitationFile; QString mNotebookUid; - QString mUid; - QString mRid; + QString mInstanceId; QString mStartTime; }; diff --git a/src/calendarmanager.cpp b/src/calendarmanager.cpp index ed77cd29..04666e78 100644 --- a/src/calendarmanager.cpp +++ b/src/calendarmanager.cpp @@ -138,31 +138,22 @@ void CalendarManager::setDefaultNotebook(const QString ¬ebookUid) Q_ARG(QString, notebookUid)); } -static QString instanceIdentifier(const QString &uid, const QDateTime &recurrenceId) +CalendarStoredEvent* CalendarManager::eventObject(const QString &instanceId) { - KCalendarCore::Event inc; - inc.setUid(uid); - inc.setRecurrenceId(recurrenceId); - return inc.instanceIdentifier(); -} - -CalendarStoredEvent* CalendarManager::eventObject(const QString &eventUid, const QDateTime &recurrenceId) -{ - const QString id = instanceIdentifier(eventUid, recurrenceId); - const QHash::ConstIterator it = mEventObjects.find(id); - if (it != mEventObjects.constEnd()) { + QHash::ConstIterator it = mEventObjects.find(instanceId); + if (it != mEventObjects.end()) { return *it; } - CalendarData::Event event = mEvents.value(id); - if (event.isValid()) { - CalendarStoredEvent *calendarEvent = new CalendarStoredEvent(this, &event); - mEventObjects.insert(id, calendarEvent); + const QHash::ConstIterator event = mEvents.find(instanceId); + if (event != mEvents.constEnd()) { + CalendarStoredEvent *calendarEvent = new CalendarStoredEvent(this, &(*event)); + mEventObjects.insert(instanceId, calendarEvent); return calendarEvent; } // TODO: maybe attempt to read event from DB? This situation should not happen. - qWarning() << Q_FUNC_INFO << "No event with uid" << eventUid << recurrenceId << ", returning empty event"; + qWarning() << Q_FUNC_INFO << "No event with uid" << instanceId << ", returning empty event"; return new CalendarStoredEvent(this, nullptr); } @@ -178,7 +169,7 @@ void CalendarManager::saveModification(CalendarData::Event eventData, bool updat Q_ARG(QList, optional)); } -CalendarData::Event CalendarManager::dissociateSingleOccurrence(const QString &eventUid, const QDateTime &recurrenceId) const +CalendarData::Event CalendarManager::dissociateSingleOccurrence(const QString &instanceId, const QDateTime &datetime) const { CalendarData::Event event; // Worker method is not calling any storage method that could block. @@ -187,8 +178,8 @@ CalendarData::Event CalendarManager::dissociateSingleOccurrence(const QString &e QMetaObject::invokeMethod(mCalendarWorker, "dissociateSingleOccurrence", Qt::BlockingQueuedConnection, Q_RETURN_ARG(CalendarData::Event, event), - Q_ARG(QString, eventUid), - Q_ARG(QDateTime, recurrenceId)); + Q_ARG(QString, instanceId), + Q_ARG(QDateTime, datetime)); return event; } @@ -434,15 +425,14 @@ void CalendarManager::updateAgendaModel(CalendarAgendaModel *model) foreach (const QString &id, mEventOccurrenceForDates.value(model->startDate())) { if (mEventOccurrences.contains(id)) { CalendarData::EventOccurrence eo = mEventOccurrences.value(id); - filtered.append(new CalendarEventOccurrence(eo.eventUid, eo.recurrenceId, - eo.startTime, eo.endTime)); + filtered.append(new CalendarEventOccurrence(eo.uniqueId, eo.startTime, eo.endTime)); } else { qWarning() << "no occurrence with id" << id; } } } else { foreach (const CalendarData::EventOccurrence &eo, mEventOccurrences.values()) { - CalendarEvent *event = eventObject(eo.eventUid, eo.recurrenceId); + CalendarEvent *event = eventObject(eo.instanceId); if (!event) { qWarning() << "no event for occurrence"; continue; @@ -460,8 +450,7 @@ void CalendarManager::updateAgendaModel(CalendarAgendaModel *model) && eo.endTime.date() >= model->startDate()) || (!eo.eventAllDay && eo.startTime < endDt && eo.endTime >= startDt)) { - filtered.append(new CalendarEventOccurrence(eo.eventUid, eo.recurrenceId, - eo.startTime, eo.endTime)); + filtered.append(new CalendarEventOccurrence(eo.uniqueId, eo.startTime, eo.endTime)); } } } @@ -503,16 +492,15 @@ void CalendarManager::doAgendaAndQueryRefresh() QList queryList = mQueryRefreshList; mQueryRefreshList.clear(); foreach (CalendarEventQuery *query, queryList) { - const QString eventUid = query->uniqueId(); - if (eventUid.isEmpty()) + const QString instanceId = query->instanceId(); + if (instanceId.isEmpty()) continue; - const QString id = instanceIdentifier(eventUid, query->recurrenceId()); - bool loaded = mLoadedQueries.contains(id); - CalendarData::Event event = mEvents.value(id); + bool loaded = mLoadedQueries.contains(instanceId); + CalendarData::Event event = mEvents.value(instanceId); if (((!event.isValid() && !loaded) || mResetPending) - && !missingInstanceList.contains(id)) { - missingInstanceList << id; + && !missingInstanceList.contains(instanceId)) { + missingInstanceList << instanceId; } query->doRefresh(event, !event.isValid() && loaded); } @@ -554,20 +542,17 @@ void CalendarManager::timeout() doAgendaAndQueryRefresh(); } -void CalendarManager::deleteEvent(const QString &uid, const QDateTime &recurrenceId, const QDateTime &time) +void CalendarManager::deleteEvent(const QString &instanceId, const QDateTime &time) { QMetaObject::invokeMethod(mCalendarWorker, "deleteEvent", Qt::QueuedConnection, - Q_ARG(QString, uid), - Q_ARG(QDateTime, recurrenceId), + Q_ARG(QString, instanceId), Q_ARG(QDateTime, time)); } -void CalendarManager::deleteAll(const QString &uid) +void CalendarManager::deleteAll(const QString &instanceId) { - QMetaObject::invokeMethod(mCalendarWorker, "deleteEvent", Qt::QueuedConnection, - Q_ARG(QString, uid), - Q_ARG(QDateTime, QDateTime()), - Q_ARG(QDateTime, QDateTime())); + QMetaObject::invokeMethod(mCalendarWorker, "deleteAll", Qt::QueuedConnection, + Q_ARG(QString, instanceId)); } void CalendarManager::save() @@ -575,31 +560,30 @@ void CalendarManager::save() QMetaObject::invokeMethod(mCalendarWorker, "save", Qt::QueuedConnection); } -QString CalendarManager::convertEventToICalendarSync(const QString &uid, const QString &prodId) +QString CalendarManager::convertEventToICalendarSync(const QString &instanceId, const QString &prodId) { QString vEvent; QMetaObject::invokeMethod(mCalendarWorker, "convertEventToICalendar", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, vEvent), - Q_ARG(QString, uid), + Q_ARG(QString, instanceId), Q_ARG(QString, prodId)); return vEvent; } -CalendarData::Event CalendarManager::getEvent(const QString &instanceIdentifier, bool *loaded) const +CalendarData::Event CalendarManager::getEvent(const QString &instanceId, bool *loaded) const { if (loaded) { - *loaded = mLoadedQueries.contains(instanceIdentifier); + *loaded = mLoadedQueries.contains(instanceId); } - return mEvents.value(instanceIdentifier); + return mEvents.value(instanceId); } -bool CalendarManager::sendResponse(const QString &uid, const QDateTime &recurrenceId, CalendarEvent::Response response) +bool CalendarManager::sendResponse(const QString &instanceId, CalendarEvent::Response response) { bool result; QMetaObject::invokeMethod(mCalendarWorker, "sendResponse", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result), - Q_ARG(QString, uid), - Q_ARG(QDateTime, recurrenceId), + Q_ARG(QString, instanceId), Q_ARG(CalendarEvent::Response, response)); return result; } @@ -665,8 +649,8 @@ void CalendarManager::eventNotebookChanged(const QString &oldEventUid, const QSt mEventObjects.remove(oldEventUid); } foreach (QString occurrenceUid, mEventOccurrences.keys()) { - if (mEventOccurrences.value(occurrenceUid).eventUid == oldEventUid) - mEventOccurrences[occurrenceUid].eventUid = newEventUid; + if (mEventOccurrences.value(occurrenceUid).instanceId == oldEventUid) + mEventOccurrences[occurrenceUid].instanceId = newEventUid; } emit eventUidChanged(oldEventUid, newEventUid); @@ -731,34 +715,32 @@ void CalendarManager::notebooksChangedSlot(const QList & } } -CalendarEventOccurrence* CalendarManager::getNextOccurrence(const QString &uid, const QDateTime &recurrenceId, +CalendarEventOccurrence* CalendarManager::getNextOccurrence(const QString &instanceId, const QDateTime &start) { CalendarData::EventOccurrence eo; - const CalendarData::Event event = mEvents.value(instanceIdentifier(uid, recurrenceId)); + const CalendarData::Event event = mEvents.value(instanceId); if (event.recur == CalendarEvent::RecurOnce) { const QTimeZone systemTimeZone = QTimeZone::systemTimeZone(); - eo.eventUid = event.uniqueId; - eo.recurrenceId = event.recurrenceId; + eo.instanceId = event.instanceId; eo.startTime = event.startTime.toTimeZone(systemTimeZone); eo.endTime = event.endTime.toTimeZone(systemTimeZone); } else { QMetaObject::invokeMethod(mCalendarWorker, "getNextOccurrence", Qt::BlockingQueuedConnection, Q_RETURN_ARG(CalendarData::EventOccurrence, eo), - Q_ARG(QString, uid), - Q_ARG(QDateTime, recurrenceId), + Q_ARG(QString, instanceId), Q_ARG(QDateTime, start)); } if (!eo.startTime.isValid()) { - qWarning() << Q_FUNC_INFO << "Unable to find occurrence for event" << uid << recurrenceId; - return new CalendarEventOccurrence(QString(), QDateTime(), QDateTime(), QDateTime()); + qWarning() << Q_FUNC_INFO << "Unable to find occurrence for event" << instanceId; + return new CalendarEventOccurrence(QString(), QDateTime(), QDateTime()); } - return new CalendarEventOccurrence(eo.eventUid, eo.recurrenceId, eo.startTime, eo.endTime); + return new CalendarEventOccurrence(eo.uniqueId, eo.startTime, eo.endTime); } -QList CalendarManager::getEventAttendees(const QString &uid, const QDateTime &recurrenceId, bool *resultValid) +QList CalendarManager::getEventAttendees(const QString &instanceId, bool *resultValid) { QList attendees; @@ -776,8 +758,7 @@ QList CalendarManager::getEventAttendees(const QString & if (*resultValid) { QMetaObject::invokeMethod(mCalendarWorker, "getEventAttendees", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QList, attendees), - Q_ARG(QString, uid), - Q_ARG(QDateTime, recurrenceId)); + Q_ARG(QString, instanceId)); } return attendees; diff --git a/src/calendarmanager.h b/src/calendarmanager.h index 0e71a1d8..8feef46d 100644 --- a/src/calendarmanager.h +++ b/src/calendarmanager.h @@ -61,22 +61,22 @@ class CalendarManager : public QObject static CalendarManager *instance(bool createIfNeeded = true); ~CalendarManager(); - CalendarStoredEvent* eventObject(const QString &eventUid, const QDateTime &recurrenceId); + CalendarStoredEvent* eventObject(const QString &instanceId); void saveModification(CalendarData::Event eventData, bool updateAttendees, const QList &required, const QList &optional); - void deleteEvent(const QString &uid, const QDateTime &recurrenceId, const QDateTime &dateTime); - void deleteAll(const QString &uid); + void deleteEvent(const QString &instanceId, const QDateTime &dateTime); + void deleteAll(const QString &instanceId); void save(); // Synchronous DB thread access - QString convertEventToICalendarSync(const QString &uid, const QString &prodId); + QString convertEventToICalendarSync(const QString &instanceId, const QString &prodId); // Event - CalendarData::Event getEvent(const QString& instanceIdentifier, bool *loaded = nullptr) const; - CalendarData::Event dissociateSingleOccurrence(const QString &eventUid, const QDateTime &recurrenceId) const; - bool sendResponse(const QString &uid, const QDateTime &recurrenceId, CalendarEvent::Response response); + CalendarData::Event getEvent(const QString& instanceId, bool *loaded = nullptr) const; + CalendarData::Event dissociateSingleOccurrence(const QString &instanceId, const QDateTime &datetime) const; + bool sendResponse(const QString &instanceId, CalendarEvent::Response response); // Notebooks QList notebooks(); @@ -111,10 +111,10 @@ class CalendarManager : public QObject // Caller gets ownership of returned CalendarEventOccurrence object // Does synchronous DB thread access - no DB operations, though, fast when no ongoing DB ops - CalendarEventOccurrence* getNextOccurrence(const QString &uid, const QDateTime &recurrenceId, + CalendarEventOccurrence* getNextOccurrence(const QString &instanceId, const QDateTime &start); // return attendees for given event, synchronous call - QList getEventAttendees(const QString &uid, const QDateTime &recurrenceId, bool *resultValid); + QList getEventAttendees(const QString &instanceId, bool *resultValid); private slots: void storageModifiedSlot(); diff --git a/src/calendarutils.cpp b/src/calendarutils.cpp index 2b45f427..4635b8fe 100644 --- a/src/calendarutils.cpp +++ b/src/calendarutils.cpp @@ -53,7 +53,8 @@ CalendarData::Event::Event(const KCalendarCore::Event &event) , startTime(event.dtStart()) , endTime(event.dtEnd()) , allDay(event.allDay()) - , uniqueId(event.uid()) + , instanceId(event.instanceIdentifier()) + , incidenceUid(event.uid()) , recurrenceId(event.recurrenceId()) , location(event.location()) { @@ -351,7 +352,7 @@ QDateTime CalendarData::Event::fromKReminderDateTime(const KCalendarCore::Event return QDateTime(); } -QList CalendarUtils::getEventAttendees(const KCalendarCore::Event::Ptr &event) +QList CalendarUtils::getEventAttendees(const KCalendarCore::Incidence::Ptr &event) { QList result; const KCalendarCore::Person calOrganizer = event->organizer(); @@ -441,8 +442,7 @@ CalendarData::EventOccurrence CalendarUtils::getNextOccurrence(const KCalendarCo CalendarData::EventOccurrence occurrence; if (event) { - occurrence.eventUid = event->uid(); - occurrence.recurrenceId = event->recurrenceId(); + occurrence.instanceId = event->instanceIdentifier(); occurrence.eventAllDay = event->allDay(); occurrence.startTime = event->dtStart().toTimeZone(systemTimeZone); occurrence.endTime = event->dtEnd().toTimeZone(systemTimeZone); diff --git a/src/calendarutils.h b/src/calendarutils.h index ea7b1266..869d6226 100644 --- a/src/calendarutils.h +++ b/src/calendarutils.h @@ -44,7 +44,7 @@ namespace CalendarUtils { -QList getEventAttendees(const KCalendarCore::Event::Ptr &event); +QList getEventAttendees(const KCalendarCore::Incidence::Ptr &event); QList convertAttendeeList(const QList &list); CalendarData::EventOccurrence getNextOccurrence(const KCalendarCore::Event::Ptr &event, const QDateTime &start = QDateTime::currentDateTime(), diff --git a/src/calendarworker.cpp b/src/calendarworker.cpp index 4b1476ba..09b8af36 100644 --- a/src/calendarworker.cpp +++ b/src/calendarworker.cpp @@ -59,7 +59,7 @@ #include namespace { - void updateAttendee(KCalendarCore::Event::Ptr event, + void updateAttendee(KCalendarCore::Incidence::Ptr event, const KCalendarCore::Attendee &attendee, const KCalendarCore::Attendee &updated) { @@ -155,14 +155,20 @@ void CalendarWorker::storageUpdated(mKCal::ExtendedStorage *storage, emit storageModifiedSignal(); } -void CalendarWorker::deleteEvent(const QString &uid, const QDateTime &recurrenceId, const QDateTime &dateTime) +KCalendarCore::Incidence::Ptr CalendarWorker::getInstance(const QString &instanceId) const { - KCalendarCore::Event::Ptr event = mCalendar->event(uid, recurrenceId); - if (!event && mStorage->load(uid)) { - event = mCalendar->event(uid, recurrenceId); + KCalendarCore::Incidence::Ptr event = mCalendar->instance(instanceId); + if (!event && mStorage->loadIncidenceInstance(instanceId)) { + event = mCalendar->instance(instanceId); } + return event; +} + +void CalendarWorker::deleteEvent(const QString &instanceId, const QDateTime &dateTime) +{ + KCalendarCore::Incidence::Ptr event = getInstance(instanceId); if (!event) { - qDebug() << uid << "event already deleted from DB"; + qDebug() << instanceId << "event already deleted from DB"; return; } @@ -177,23 +183,38 @@ void CalendarWorker::deleteEvent(const QString &uid, const QDateTime &recurrence event->setRevision(event->revision() + 1); } else if (event->hasRecurrenceId()) { // We consider that deleting an exception implies to create an exdate for the parent. - KCalendarCore::Event::Ptr parent = mCalendar->event(uid); + KCalendarCore::Event::Ptr parent = mCalendar->event(event->uid()); if (parent) { parent->recurrence()->addExDateTime(event->recurrenceId()); parent->setRevision(parent->revision() + 1); } - mCalendar->deleteEvent(event); + mCalendar->deleteIncidence(event); } else { - mCalendar->deleteEvent(event); + mCalendar->deleteIncidence(event); } } -bool CalendarWorker::sendResponse(const QString &uid, const QDateTime &recurrenceId, +void CalendarWorker::deleteAll(const QString &instanceId) +{ + KCalendarCore::Incidence::Ptr event = getInstance(instanceId); + if (!event) { + qDebug() << instanceId << "event already deleted from DB"; + return; + } + if (event->hasRecurrenceId()) { + KCalendarCore::Incidence::Ptr parent = mCalendar->incidence(event->uid()); + if (parent) + event = parent; + } + mCalendar->deleteIncidence(event); +} + +bool CalendarWorker::sendResponse(const QString &instanceId, const CalendarEvent::Response response) { - KCalendarCore::Event::Ptr event = mCalendar->event(uid, recurrenceId); + KCalendarCore::Incidence::Ptr event = mCalendar->instance(instanceId); if (!event) { - qWarning() << "Failed to send response, event not found. UID = " << uid; + qWarning() << "Failed to send response, event not found. UID = " << instanceId; return false; } const QString ownerEmail = getNotebookAddress(mCalendar->notebook(event)); @@ -221,18 +242,20 @@ bool CalendarWorker::sendResponse(const QString &uid, const QDateTime &recurrenc if (!sent) updateAttendee(event, updated, origAttendee); } else { - qWarning() << "Failed to load notebook for incidence" << event->instanceIdentifier(); + qWarning() << "Failed to load notebook for incidence" << instanceId; } return sent; } -QString CalendarWorker::convertEventToICalendar(const QString &uid, const QString &prodId) const +QString CalendarWorker::convertEventToICalendar(const QString &instanceId, const QString &prodId) const { - // NOTE: not fetching eventInstances() with different recurrenceId - KCalendarCore::Event::Ptr event = mCalendar->event(uid); + // NOTE: exporting only the matching occurrence with instanceId, + // for recurring parent, it will not append the exceptions, + // for exceptions, it will not append the parent. + KCalendarCore::Incidence::Ptr event = mCalendar->instance(instanceId); if (event.isNull()) { - qWarning() << "No event with uid " << uid << ", unable to create iCalendar"; + qWarning() << "No event with uid " << instanceId << ", unable to create iCalendar"; return QString(); } @@ -259,8 +282,8 @@ void CalendarWorker::saveEvent(const CalendarData::Event &eventData, bool update } KCalendarCore::Event::Ptr event; - if (!eventData.uniqueId.isEmpty()) { - event = mCalendar->event(eventData.uniqueId, eventData.recurrenceId); + if (!eventData.instanceId.isEmpty()) { + event = mCalendar->instance(eventData.instanceId).staticCast(); if (!event && eventData.recurrenceId.isNull()) { // possibility that event was removed while changes were edited. options to either skip, as done now, // or resurrect the event @@ -278,16 +301,16 @@ void CalendarWorker::saveEvent(const CalendarData::Event &eventData, bool update // UIDs, but original UIDs for invitations/events sent from Outlook Web interface are in // upper case. To workaround such behaviour it is easier for us to generate an upper case UIDs // for new events than trying to implement some complex logic in basesailfish-eas. - if (eventData.uniqueId.isEmpty()) { + if (eventData.instanceId.isEmpty()) { event->setUid(event->uid().toUpper()); } else { - event->setUid(eventData.uniqueId); + event->setUid(eventData.incidenceUid); event->setRecurrenceId(eventData.recurrenceId); } } else { if (!notebookUid.isEmpty() && mCalendar->notebook(event) != notebookUid) { // mkcal does funny things when moving event between notebooks, work around by changing uid - KCalendarCore::Event::Ptr newEvent = KCalendarCore::Event::Ptr(event->clone()); + KCalendarCore::Event::Ptr newEvent(event->clone()); newEvent->setUid(KCalendarCore::CalFormat::createUniqueId().toUpper()); emit eventNotebookChanged(event->uid(), newEvent->uid(), notebookUid); mCalendar->deleteEvent(event); @@ -319,11 +342,11 @@ void CalendarWorker::saveEvent(const CalendarData::Event &eventData, bool update save(); } -CalendarData::Event CalendarWorker::dissociateSingleOccurrence(const QString &uid, const QDateTime &recurrenceId) +CalendarData::Event CalendarWorker::dissociateSingleOccurrence(const QString &instanceId, const QDateTime &datetime) { - KCalendarCore::Event::Ptr event = mCalendar->event(uid); - if (!event) { - qWarning("Event to create occurrence replacement for not found"); + KCalendarCore::Incidence::Ptr event = mCalendar->instance(instanceId); + if (!event || event->hasRecurrenceId()) { + qWarning("Event to create occurrence replacement for not found or already an exception"); return CalendarData::Event(); } @@ -331,8 +354,8 @@ CalendarData::Event CalendarWorker::dissociateSingleOccurrence(const QString &ui // zone is also an exception when travelling to another time, we use the // LocalTime spec. const QDateTime occurrence = event->allDay() - ? QDateTime(recurrenceId.date(), recurrenceId.time(), Qt::LocalTime) - : recurrenceId; + ? QDateTime(datetime.date(), datetime.time(), Qt::LocalTime) + : datetime; KCalendarCore::Incidence::Ptr replacement = mCalendar->dissociateSingleOccurrence(event, occurrence); if (!replacement) { qWarning("Unable to create the replacing occurrence"); @@ -628,8 +651,7 @@ CalendarWorker::eventOccurrences(const QList &ranges) const it.incidence()->dateTime(KCalendarCore::Incidence::RoleDisplayEnd), KCalendarCore::Duration::Seconds); CalendarData::EventOccurrence occurrence; - occurrence.eventUid = it.incidence()->uid(); - occurrence.recurrenceId = it.incidence()->recurrenceId(); + occurrence.instanceId = it.incidence()->instanceIdentifier(); occurrence.startTime = sdt; occurrence.endTime = elapsed.end(sdt); occurrence.eventAllDay = it.incidence()->allDay(); @@ -671,9 +693,7 @@ void CalendarWorker::loadData(const QList &ranges, } foreach (const QString &id, instanceList) { - if (mCalendar->instance(id).isNull()) { - mStorage->loadIncidenceInstance(id); - } + mStorage->loadIncidenceInstance(id); } if (reset) @@ -912,27 +932,22 @@ void CalendarWorker::loadNotebooks() } -CalendarData::EventOccurrence CalendarWorker::getNextOccurrence(const QString &uid, - const QDateTime &recurrenceId, +CalendarData::EventOccurrence CalendarWorker::getNextOccurrence(const QString &instanceId, const QDateTime &start) const { - KCalendarCore::Event::Ptr event = mCalendar->event(uid, recurrenceId); - if (!event) { - mStorage->load(uid); - event = mCalendar->event(uid, recurrenceId); - } + KCalendarCore::Event::Ptr event = getInstance(instanceId).staticCast(); if (!event) { - qWarning() << "Failed to get next occurrence, event not found. UID = " << uid << recurrenceId; + qWarning() << "Failed to get next occurrence, event not found. UID = " << instanceId; return CalendarData::EventOccurrence(); } return CalendarUtils::getNextOccurrence(event, start, event->recurs() ? mCalendar->instances(event) : KCalendarCore::Incidence::List()); } -QList CalendarWorker::getEventAttendees(const QString &uid, const QDateTime &recurrenceId) +QList CalendarWorker::getEventAttendees(const QString &instanceId) { QList result; - KCalendarCore::Event::Ptr event = mCalendar->event(uid, recurrenceId); + KCalendarCore::Incidence::Ptr event = mCalendar->instance(instanceId); if (event.isNull()) { return result; diff --git a/src/calendarworker.h b/src/calendarworker.h index 3966efce..a8fa23df 100644 --- a/src/calendarworker.h +++ b/src/calendarworker.h @@ -71,10 +71,11 @@ public slots: void saveEvent(const CalendarData::Event &eventData, bool updateAttendees, const QList &required, const QList &optional); - CalendarData::Event dissociateSingleOccurrence(const QString &uid, const QDateTime &recurrenceId); - void deleteEvent(const QString &uid, const QDateTime &recurrenceId, const QDateTime &dateTime); - bool sendResponse(const QString &uid, const QDateTime &recurrenceId, const CalendarEvent::Response response); - QString convertEventToICalendar(const QString &uid, const QString &prodId) const; + CalendarData::Event dissociateSingleOccurrence(const QString &instanceId, const QDateTime &datetime); + void deleteEvent(const QString &instanceId, const QDateTime &dateTime); + void deleteAll(const QString &instanceId); + bool sendResponse(const QString &instanceId, const CalendarEvent::Response response); + QString convertEventToICalendar(const QString &instanceId, const QString &prodId) const; QList notebooks() const; void setNotebookColor(const QString ¬ebookUid, const QString &color); @@ -87,9 +88,9 @@ public slots: void search(const QString &searchString, int limit); - CalendarData::EventOccurrence getNextOccurrence(const QString &uid, const QDateTime &recurrenceId, + CalendarData::EventOccurrence getNextOccurrence(const QString &instanceId, const QDateTime &startTime) const; - QList getEventAttendees(const QString &uid, const QDateTime &recurrenceId); + QList getEventAttendees(const QString &instanceId); void findMatchingEvent(const QString &invitationFile); void onTimedSignal(const Maemo::Timed::WallClock::Info &info, bool time_changed); @@ -127,6 +128,7 @@ public slots: const QList &optional, const QString ¬ebookUid); QString getNotebookAddress(const QString ¬ebookUid) const; + KCalendarCore::Incidence::Ptr getInstance(const QString &instanceId) const; CalendarData::Event createEventStruct(const KCalendarCore::Event::Ptr &event, mKCal::Notebook::Ptr notebook = mKCal::Notebook::Ptr()) const; diff --git a/tests/tst_calendarevent/tst_calendarevent.cpp b/tests/tst_calendarevent/tst_calendarevent.cpp index 044fdca5..80211a63 100644 --- a/tests/tst_calendarevent/tst_calendarevent.cpp +++ b/tests/tst_calendarevent/tst_calendarevent.cpp @@ -233,7 +233,7 @@ void tst_CalendarEvent::testSave() CalendarEventQuery query; QSignalSpy eventSpy(&query, &CalendarEventQuery::eventChanged); - query.setUniqueId(uid); + query.setInstanceId(uid); QVERIFY(eventSpy.wait()); CalendarStoredEvent *eventB = (CalendarStoredEvent*) query.event(); @@ -286,7 +286,7 @@ void tst_CalendarEvent::testModify() CalendarEventQuery query; QSignalSpy eventSpy(&query, &CalendarEventQuery::eventChanged); - query.setUniqueId(uid); + query.setInstanceId(uid); QVERIFY(eventSpy.wait()); CalendarStoredEvent *event = qobject_cast(query.event()); @@ -340,7 +340,7 @@ void tst_CalendarEvent::testTimeZone() CalendarEventQuery query; QSignalSpy eventSpy(&query, &CalendarEventQuery::eventChanged); - query.setUniqueId(uid); + query.setInstanceId(uid); QVERIFY(eventSpy.wait()); CalendarStoredEvent *eventB = (CalendarStoredEvent*) query.event(); @@ -395,7 +395,7 @@ void tst_CalendarEvent::testRecurrenceException() // need event and occurrence to replace.... CalendarEventQuery query; QSignalSpy updated(&query, &CalendarEventQuery::eventChanged); - query.setUniqueId(uid); + query.setInstanceId(uid); QDateTime secondStart = startTime.addDays(7); query.setStartTime(secondStart); QVERIFY(updated.wait()); @@ -419,7 +419,7 @@ void tst_CalendarEvent::testRecurrenceException() // Delete fourth occurrence const QDateTime fourth = startTime.addDays(21).toLocalTime(); - calendarApi->remove(savedEvent->uniqueId(), QString(), fourth); + calendarApi->remove(savedEvent->instanceId(), fourth); QVERIFY(dataUpdated.wait()); // Create an exception on the fifth occurrence @@ -444,29 +444,29 @@ void tst_CalendarEvent::testRecurrenceException() qputenv("TZ", "Europe/Paris"); // check the occurrences are correct - CalendarEventOccurrence *occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime(), + CalendarEventOccurrence *occurrence = CalendarManager::instance()->getNextOccurrence(uid, startTime.addDays(-1)); QVERIFY(occurrence); // first QCOMPARE(occurrence->startTime(), startTime); // third - occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime(), startTime.addDays(1)); + occurrence = CalendarManager::instance()->getNextOccurrence(uid, startTime.addDays(1)); QVERIFY(occurrence); QCOMPARE(occurrence->startTime(), startTime.addDays(14)); // second is exception - occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime::fromString(recurrenceException->recurrenceIdString(), Qt::ISODate), + occurrence = CalendarManager::instance()->getNextOccurrence(recurrenceException->instanceId(), startTime.addDays(1)); QVERIFY(occurrence); QCOMPARE(occurrence->startTime(), modifiedSecond); // fourth has been deleted and fifth is an exception - occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime(), startTime.addDays(15)); + occurrence = CalendarManager::instance()->getNextOccurrence(uid, startTime.addDays(15)); QVERIFY(occurrence); QCOMPARE(occurrence->startTime(), startTime.addDays(35)); // update the exception time QSignalSpy eventChangeSpy(&query, SIGNAL(eventChanged())); query.resetStartTime(); - query.setRecurrenceIdString(recurrenceException->recurrenceIdString()); + query.setInstanceId(recurrenceException->instanceId()); eventChangeSpy.wait(); QVERIFY(eventChangeSpy.count() > 0); QVERIFY(query.event()); @@ -484,14 +484,14 @@ void tst_CalendarEvent::testRecurrenceException() QVERIFY(dataUpdated.wait()); // allow saved data to be reloaded // check the occurrences are correct - occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime(), startTime.addDays(-1)); + occurrence = CalendarManager::instance()->getNextOccurrence(uid, startTime.addDays(-1)); // first QCOMPARE(occurrence->startTime(), startTime); // third - occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime(), startTime.addDays(1)); + occurrence = CalendarManager::instance()->getNextOccurrence(uid, startTime.addDays(1)); QCOMPARE(occurrence->startTime(), startTime.addDays(14)); // second is exception - occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime::fromString(recurrenceException->recurrenceIdString(), Qt::ISODate), + occurrence = CalendarManager::instance()->getNextOccurrence(recurrenceException->instanceId(), startTime.addDays(1)); QVERIFY(occurrence); @@ -499,9 +499,9 @@ void tst_CalendarEvent::testRecurrenceException() // Delete the second exception and check that no // occurrence of the parent is present. - calendarApi->remove(uid, recurrenceSecondException->recurrenceIdString(), QDateTime()); + calendarApi->remove(recurrenceSecondException->instanceId()); QVERIFY(dataUpdated.wait()); - occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime(), startTime.addDays(15)); + occurrence = CalendarManager::instance()->getNextOccurrence(uid, startTime.addDays(15)); QVERIFY(occurrence); // Fourth (+21 days) and fifth (+28) are now deleted. QCOMPARE(occurrence->startTime(), startTime.addDays(35)); @@ -517,12 +517,12 @@ void tst_CalendarEvent::testRecurrenceException() QVERIFY(dataUpdated.wait()); // and check - occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime(), startTime.addDays(-1)); + occurrence = CalendarManager::instance()->getNextOccurrence(uid, startTime.addDays(-1)); QCOMPARE(occurrence->startTime(), modifiedStart); - occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime(), startTime.addDays(1)); + occurrence = CalendarManager::instance()->getNextOccurrence(uid, startTime.addDays(1)); // TODO: Would be the best if second occurrence in the main series stays away, but at the moment it doesn't. //QCOMPARE(occurrence->startTime(), modifiedStart.addDays(14)); - occurrence = CalendarManager::instance()->getNextOccurrence(uid, QDateTime::fromString(recurrenceException->recurrenceIdString(), Qt::ISODate), + occurrence = CalendarManager::instance()->getNextOccurrence(recurrenceException->instanceId(), startTime.addDays(1)); QVERIFY(occurrence); QCOMPARE(occurrence->startTime(), modifiedSecond); @@ -604,7 +604,7 @@ bool tst_CalendarEvent::saveEvent(CalendarEventModification *eventMod, QString * CalendarEvent *modelEvent = qvariant_cast(eventVariant); // assume no left-over events with same description if (modelEvent && modelEvent->description() == eventMod->description()) { - *uid = modelEvent->uniqueId(); + *uid = modelEvent->instanceId(); break; } } @@ -677,7 +677,7 @@ void tst_CalendarEvent::testRecurrence() CalendarEventQuery query; QSignalSpy eventSpy(&query, &CalendarEventQuery::eventChanged); - query.setUniqueId(uid); + query.setInstanceId(uid); QVERIFY(eventSpy.wait()); CalendarStoredEvent *event = (CalendarStoredEvent*)query.event(); @@ -716,7 +716,7 @@ void tst_CalendarEvent::testRecurWeeklyDays() CalendarEventQuery query; QSignalSpy eventSpy(&query, &CalendarEventQuery::eventChanged); - query.setUniqueId(uid); + query.setInstanceId(uid); QVERIFY(eventSpy.wait()); CalendarStoredEvent *event = (CalendarStoredEvent*)query.event(); @@ -764,7 +764,7 @@ void tst_CalendarEvent::testAttendees() CalendarEventQuery query; QSignalSpy eventSpy(&query, &CalendarEventQuery::attendeesChanged); - query.setUniqueId(uid); + query.setInstanceId(uid); QVERIFY(!eventSpy.wait(250)); QVERIFY(query.attendees().isEmpty()); @@ -818,7 +818,7 @@ void tst_CalendarEvent::testAttendees() QVERIFY(sentAttendees.contains(attCarl)); // Check that saved event locally is presenting the right data. - query.setUniqueId(uid); + query.setInstanceId(uid); QVERIFY(eventSpy.wait()); QList attendees = query.attendees(); diff --git a/tests/tst_calendarsearchmodel/tst_calendarsearchmodel.cpp b/tests/tst_calendarsearchmodel/tst_calendarsearchmodel.cpp index 2ed0e6f9..5c5f7884 100644 --- a/tests/tst_calendarsearchmodel/tst_calendarsearchmodel.cpp +++ b/tests/tst_calendarsearchmodel/tst_calendarsearchmodel.cpp @@ -40,6 +40,7 @@ void tst_CalendarSearchModel::initTestCase() &CalendarManager::storageModified); CalendarEventModification *event = calendarApi->createNewEvent(); QVERIFY(event != 0); + event->setStartTime(QDateTime(QDate(2023,5,22), QTime(15,31)), Qt::LocalTime); event->setDisplayLabel(QString::fromLatin1("Summary with string 'azerty' %plop.")); event->save(); QVERIFY(modified.wait()); From 13101fa6a7fe3c4b36918618110591702c9d40e3 Mon Sep 17 00:00:00 2001 From: Damien Caliste Date: Wed, 24 May 2023 14:31:06 +0200 Subject: [PATCH 2/4] [nemo-qml-plugin-calendar] Create occurrence objects from CalendarData structure. --- src/calendareventoccurrence.cpp | 14 ++++++++++---- src/calendareventoccurrence.h | 7 ++++--- src/calendarimportevent.cpp | 4 +--- src/calendarmanager.cpp | 9 ++++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/calendareventoccurrence.cpp b/src/calendareventoccurrence.cpp index 7d619054..029344a7 100644 --- a/src/calendareventoccurrence.cpp +++ b/src/calendareventoccurrence.cpp @@ -37,11 +37,17 @@ #include "calendarevent.h" #include "calendarmanager.h" -CalendarEventOccurrence::CalendarEventOccurrence(const QString &instanceId, - const QDateTime &startTime, - const QDateTime &endTime, +CalendarEventOccurrence::CalendarEventOccurrence(QObject *parent) + : QObject(parent) +{ +} + +CalendarEventOccurrence::CalendarEventOccurrence(const CalendarData::EventOccurrence &occurrence, QObject *parent) - : QObject(parent), mInstanceId(instanceId), mStartTime(startTime), mEndTime(endTime) + : QObject(parent) + , mInstanceId(occurrence.instanceId) + , mStartTime(occurrence.startTime) + , mEndTime(occurrence.endTime) { connect(CalendarManager::instance(), SIGNAL(eventUidChanged(QString,QString)), this, SLOT(eventUidChanged(QString,QString))); diff --git a/src/calendareventoccurrence.h b/src/calendareventoccurrence.h index c247d0d5..98208f40 100644 --- a/src/calendareventoccurrence.h +++ b/src/calendareventoccurrence.h @@ -33,6 +33,8 @@ #ifndef CALENDAREVENTOCCURRENCE_H #define CALENDAREVENTOCCURRENCE_H +#include "calendardata.h" + #include #include @@ -50,9 +52,8 @@ class CalendarEventOccurrence : public QObject Q_PROPERTY(CalendarStoredEvent *event READ eventObject CONSTANT) public: - CalendarEventOccurrence(const QString &instanceId, - const QDateTime &startTime, - const QDateTime &endTime, + CalendarEventOccurrence(QObject *parent = 0); + CalendarEventOccurrence(const CalendarData::EventOccurrence &occurrence, QObject *parent = 0); ~CalendarEventOccurrence(); diff --git a/src/calendarimportevent.cpp b/src/calendarimportevent.cpp index b1f53f64..fa5c5504 100644 --- a/src/calendarimportevent.cpp +++ b/src/calendarimportevent.cpp @@ -96,7 +96,5 @@ bool CalendarImportEvent::sendResponse(int response) QObject *CalendarImportEvent::nextOccurrence() { - return new CalendarEventOccurrence(mOccurrence.uniqueId, - mOccurrence.startTime, - mOccurrence.endTime); + return new CalendarEventOccurrence(mOccurrence); } diff --git a/src/calendarmanager.cpp b/src/calendarmanager.cpp index 04666e78..c5aa2c73 100644 --- a/src/calendarmanager.cpp +++ b/src/calendarmanager.cpp @@ -424,8 +424,7 @@ void CalendarManager::updateAgendaModel(CalendarAgendaModel *model) if (model->startDate() == model->endDate() || !model->endDate().isValid()) { foreach (const QString &id, mEventOccurrenceForDates.value(model->startDate())) { if (mEventOccurrences.contains(id)) { - CalendarData::EventOccurrence eo = mEventOccurrences.value(id); - filtered.append(new CalendarEventOccurrence(eo.uniqueId, eo.startTime, eo.endTime)); + filtered.append(new CalendarEventOccurrence(mEventOccurrences.value(id))); } else { qWarning() << "no occurrence with id" << id; } @@ -450,7 +449,7 @@ void CalendarManager::updateAgendaModel(CalendarAgendaModel *model) && eo.endTime.date() >= model->startDate()) || (!eo.eventAllDay && eo.startTime < endDt && eo.endTime >= startDt)) { - filtered.append(new CalendarEventOccurrence(eo.uniqueId, eo.startTime, eo.endTime)); + filtered.append(new CalendarEventOccurrence(eo)); } } } @@ -734,10 +733,10 @@ CalendarEventOccurrence* CalendarManager::getNextOccurrence(const QString &insta if (!eo.startTime.isValid()) { qWarning() << Q_FUNC_INFO << "Unable to find occurrence for event" << instanceId; - return new CalendarEventOccurrence(QString(), QDateTime(), QDateTime()); + return new CalendarEventOccurrence(); } - return new CalendarEventOccurrence(eo.uniqueId, eo.startTime, eo.endTime); + return new CalendarEventOccurrence(eo); } QList CalendarManager::getEventAttendees(const QString &instanceId, bool *resultValid) From 3a0a5be91b45e7f8840c814d357c486c2d6480d3 Mon Sep 17 00:00:00 2001 From: Damien Caliste Date: Wed, 31 May 2023 16:28:32 +0200 Subject: [PATCH 3/4] [nemo-qml-plugin-calendar] Hide recurrenceId from CalendarEvent objects. Instead, create properties to get access to the parent in case of an exception, or to know if an event is an exception. --- src/calendarevent.cpp | 32 +++++++++++-------- src/calendarevent.h | 7 ++-- tests/tst_calendarevent/tst_calendarevent.cpp | 4 +-- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/calendarevent.cpp b/src/calendarevent.cpp index 188d3568..4f4452a9 100644 --- a/src/calendarevent.cpp +++ b/src/calendarevent.cpp @@ -36,6 +36,8 @@ #include #include +#include + #include "calendarutils.h" #include "calendarmanager.h" #include "calendareventoccurrence.h" @@ -162,6 +164,11 @@ QString CalendarEvent::instanceId() const return mData->instanceId; } +bool CalendarEvent::isException() const +{ + return mData->recurrenceId.isValid(); +} + bool CalendarEvent::readOnly() const { return mData->readOnly; @@ -212,20 +219,6 @@ bool CalendarEvent::externalInvitation() const return mData->externalInvitation; } -QDateTime CalendarEvent::recurrenceId() const -{ - return mData->recurrenceId; -} - -QString CalendarEvent::recurrenceIdString() const -{ - if (mData->recurrenceId.isValid()) { - return CalendarUtils::recurrenceIdToString(mData->recurrenceId); - } else { - return QString(); - } -} - CalendarStoredEvent::CalendarStoredEvent(CalendarManager *manager, const CalendarData::Event *data) : CalendarEvent(data, manager) , mManager(manager) @@ -285,6 +278,17 @@ QString CalendarStoredEvent::iCalendar(const QString &prodId) const return mManager->convertEventToICalendarSync(mData->instanceId, prodId); } +CalendarStoredEvent* CalendarStoredEvent::parent() const +{ + if (isException()) { + KCalendarCore::Event event; + event.setUid(mData->incidenceUid); + return mManager->eventObject(event.instanceIdentifier()); + } else { + return nullptr; + } +} + QString CalendarStoredEvent::color() const { return mManager->getNotebookColor(mData->calendarUid); diff --git a/src/calendarevent.h b/src/calendarevent.h index b66147be..5faae21c 100644 --- a/src/calendarevent.h +++ b/src/calendarevent.h @@ -63,7 +63,7 @@ class CalendarEvent : public QObject Q_PROPERTY(int reminder READ reminder NOTIFY reminderChanged) Q_PROPERTY(QDateTime reminderDateTime READ reminderDateTime NOTIFY reminderDateTimeChanged) Q_PROPERTY(QString instanceId READ instanceId NOTIFY instanceIdChanged) - Q_PROPERTY(QString recurrenceId READ recurrenceIdString CONSTANT) + Q_PROPERTY(bool isException READ isException CONSTANT) Q_PROPERTY(bool readOnly READ readOnly CONSTANT) Q_PROPERTY(QString calendarUid READ calendarUid NOTIFY calendarUidChanged) Q_PROPERTY(QString location READ location NOTIFY locationChanged) @@ -161,11 +161,10 @@ class CalendarEvent : public QObject int reminder() const; QDateTime reminderDateTime() const; QString instanceId() const; + bool isException() const; virtual bool readOnly() const; QString calendarUid() const; QString location() const; - QDateTime recurrenceId() const; - QString recurrenceIdString() const; Secrecy secrecy() const; Status status() const; SyncFailure syncFailure() const; @@ -207,12 +206,14 @@ class CalendarStoredEvent : public CalendarEvent { Q_OBJECT Q_PROPERTY(QString color READ color NOTIFY colorChanged) + Q_PROPERTY(CalendarStoredEvent *recurringParent READ parent CONSTANT) public: CalendarStoredEvent(CalendarManager *manager, const CalendarData::Event *data); ~CalendarStoredEvent(); CalendarData::Event dissociateSingleOccurrence(const CalendarEventOccurrence *occurrence) const; void setEvent(const CalendarData::Event *event); + CalendarStoredEvent* parent() const; QString color() const; Q_INVOKABLE bool sendResponse(int response); diff --git a/tests/tst_calendarevent/tst_calendarevent.cpp b/tests/tst_calendarevent/tst_calendarevent.cpp index 80211a63..7d513b9f 100644 --- a/tests/tst_calendarevent/tst_calendarevent.cpp +++ b/tests/tst_calendarevent/tst_calendarevent.cpp @@ -409,7 +409,7 @@ void tst_CalendarEvent::testRecurrenceException() // adjust second occurrence a bit CalendarEventModification *recurrenceException = calendarApi->createModification(savedEvent, qobject_cast(query.occurrence())); QVERIFY(recurrenceException != 0); - QVERIFY(!recurrenceException->recurrenceIdString().isEmpty()); + QVERIFY(recurrenceException->isException()); QDateTime modifiedSecond = secondStart.addSecs(10*60); // 12:10 recurrenceException->setStartTime(modifiedSecond, Qt::TimeZone, "Asia/Ho_Chi_Minh"); recurrenceException->setEndTime(modifiedSecond.addSecs(10*60), Qt::TimeZone, "Asia/Ho_Chi_Minh"); @@ -435,7 +435,7 @@ void tst_CalendarEvent::testRecurrenceException() (qobject_cast(query.event()), qobject_cast(query.occurrence())); QVERIFY(recurrenceSecondException != 0); - QVERIFY(!recurrenceSecondException->recurrenceIdString().isEmpty()); + QVERIFY(recurrenceSecondException->isException()); recurrenceSecondException->setDisplayLabel("Modified recurring event fifth instance"); recurrenceSecondException->save(); QVERIFY(dataUpdated.wait()); From 1f5893709e3cb9c7df93174b6aa300db2d0ffb53 Mon Sep 17 00:00:00 2001 From: Damien Caliste Date: Tue, 6 Jun 2023 11:41:56 +0200 Subject: [PATCH 4/4] [nemo-qml-plugin-calendar] Handle events changing notebooks. Contributes to JB#60800 When an event change notebook, its instanceId is changing also. Properly propage instanceId changes to occurence and event objects. --- src/calendarevent.cpp | 12 ++++++---- src/calendarevent.h | 2 +- src/calendareventoccurrence.cpp | 12 ++++++---- src/calendareventoccurrence.h | 2 +- src/calendareventquery.cpp | 19 ++++++++++----- src/calendareventquery.h | 7 +----- src/calendarmanager.cpp | 42 ++++++++++----------------------- src/calendarmanager.h | 6 +++-- src/calendarworker.cpp | 13 +++++++--- src/calendarworker.h | 2 +- 10 files changed, 58 insertions(+), 59 deletions(-) diff --git a/src/calendarevent.cpp b/src/calendarevent.cpp index 4f4452a9..5e5647b1 100644 --- a/src/calendarevent.cpp +++ b/src/calendarevent.cpp @@ -225,8 +225,8 @@ CalendarStoredEvent::CalendarStoredEvent(CalendarManager *manager, const Calenda { connect(mManager, SIGNAL(notebookColorChanged(QString)), this, SLOT(notebookColorChanged(QString))); - connect(mManager, SIGNAL(eventUidChanged(QString,QString)), - this, SLOT(eventUidChanged(QString,QString))); + connect(mManager, &CalendarManager::instanceIdChanged, + this, &CalendarStoredEvent::instanceIdNotified); } CalendarStoredEvent::~CalendarStoredEvent() @@ -239,13 +239,15 @@ void CalendarStoredEvent::notebookColorChanged(QString notebookUid) emit colorChanged(); } -void CalendarStoredEvent::eventUidChanged(QString oldUid, QString newUid) +void CalendarStoredEvent::instanceIdNotified(QString oldId, QString newId, QString notebookUid) { - if (mData->instanceId == oldUid) { - mData->instanceId = newUid; + if (mData->instanceId == oldId) { + mData->instanceId = newId; emit instanceIdChanged(); // Event uid changes when the event is moved between notebooks, calendar uid has changed + mData->calendarUid = notebookUid; emit calendarUidChanged(); + emit colorChanged(); } } diff --git a/src/calendarevent.h b/src/calendarevent.h index 5faae21c..e64daf26 100644 --- a/src/calendarevent.h +++ b/src/calendarevent.h @@ -225,7 +225,7 @@ class CalendarStoredEvent : public CalendarEvent private slots: void notebookColorChanged(QString notebookUid); - void eventUidChanged(QString oldUid, QString newUid); + void instanceIdNotified(QString oldId, QString newId, QString notebookUid); private: CalendarManager *mManager; diff --git a/src/calendareventoccurrence.cpp b/src/calendareventoccurrence.cpp index 029344a7..903de4ad 100644 --- a/src/calendareventoccurrence.cpp +++ b/src/calendareventoccurrence.cpp @@ -49,8 +49,8 @@ CalendarEventOccurrence::CalendarEventOccurrence(const CalendarData::EventOccurr , mStartTime(occurrence.startTime) , mEndTime(occurrence.endTime) { - connect(CalendarManager::instance(), SIGNAL(eventUidChanged(QString,QString)), - this, SLOT(eventUidChanged(QString,QString))); + connect(CalendarManager::instance(), &CalendarManager::instanceIdChanged, + this, &CalendarEventOccurrence::instanceIdChanged); } CalendarEventOccurrence::~CalendarEventOccurrence() @@ -77,10 +77,12 @@ CalendarStoredEvent *CalendarEventOccurrence::eventObject() const return CalendarManager::instance()->eventObject(mInstanceId); } -void CalendarEventOccurrence::eventUidChanged(QString oldUid, QString newUid) +void CalendarEventOccurrence::instanceIdChanged(QString oldId, QString newId, QString notebookUid) { - if (mInstanceId == oldUid) - mInstanceId = newUid; + Q_UNUSED(notebookUid); + + if (mInstanceId == oldId) + mInstanceId = newId; } static QDateTime toEventDateTime(const QDateTime &dateTime, diff --git a/src/calendareventoccurrence.h b/src/calendareventoccurrence.h index 98208f40..2a2c591b 100644 --- a/src/calendareventoccurrence.h +++ b/src/calendareventoccurrence.h @@ -70,7 +70,7 @@ class CalendarEventOccurrence : public QObject void endTimeChanged(); private slots: - void eventUidChanged(QString oldUid, QString newUid); + void instanceIdChanged(QString oldId, QString newId, QString notebookUid); private: QString mInstanceId; diff --git a/src/calendareventquery.cpp b/src/calendareventquery.cpp index f3e2f745..6446c629 100644 --- a/src/calendareventquery.cpp +++ b/src/calendareventquery.cpp @@ -46,8 +46,8 @@ CalendarEventQuery::CalendarEventQuery() connect(CalendarManager::instance(), &CalendarManager::timezoneChanged, this, &CalendarEventQuery::onTimezoneChanged); - connect(CalendarManager::instance(), SIGNAL(eventUidChanged(QString,QString)), - this, SLOT(eventUidChanged(QString,QString))); + connect(CalendarManager::instance(), &CalendarManager::instanceIdChanged, + this, &CalendarEventQuery::instanceIdNotified); } CalendarEventQuery::~CalendarEventQuery() @@ -228,10 +228,17 @@ void CalendarEventQuery::onTimezoneChanged() } } -void CalendarEventQuery::eventUidChanged(QString oldUid, QString newUid) +void CalendarEventQuery::instanceIdNotified(QString oldId, QString newId, QString notebookUid) { - if (mInstanceId == oldUid) { - emit newUniqueId(newUid); - refresh(); + if (mInstanceId == oldId) { + mInstanceId = newId; + emit instanceIdChanged(); + + if (mEvent.isValid()) { + mEvent.instanceId = newId; + mEvent.calendarUid = notebookUid; + } else { + refresh(); + } } } diff --git a/src/calendareventquery.h b/src/calendareventquery.h index 696e0b1a..1091b86b 100644 --- a/src/calendareventquery.h +++ b/src/calendareventquery.h @@ -137,15 +137,10 @@ class CalendarEventQuery : public QObject, public QQmlParserStatus void startTimeChanged(); void eventErrorChanged(); - // Indicates that the event UID has changed in database, event has been moved between notebooks. - // The property instanceId will not be changed, the data pointer properties event and occurrence - // will reset to null pointers. - void newUniqueId(QString newUid); - private slots: void refresh(); void onTimezoneChanged(); - void eventUidChanged(QString oldUid, QString newUid); + void instanceIdNotified(QString oldId, QString newId, QString notebookUid); private: bool mIsComplete; diff --git a/src/calendarmanager.cpp b/src/calendarmanager.cpp index c5aa2c73..382337ff 100644 --- a/src/calendarmanager.cpp +++ b/src/calendarmanager.cpp @@ -633,39 +633,23 @@ void CalendarManager::calendarTimezoneChangedSlot() emit timezoneChanged(); } -void CalendarManager::eventNotebookChanged(const QString &oldEventUid, const QString &newEventUid, +void CalendarManager::eventNotebookChanged(const QString &oldInstanceId, + const QString &newInstanceId, const QString ¬ebookUid) { - // FIXME: adapt to multihash + recurrenceId. -#if 0 - if (mEvents.contains(oldEventUid)) { - mEvents.insert(newEventUid, mEvents.value(oldEventUid)); - mEvents[newEventUid].calendarUid = notebookUid; - mEvents.remove(oldEventUid); + if (mEvents.contains(oldInstanceId)) { + mEvents.insert(newInstanceId, mEvents.value(oldInstanceId)); + mEvents[newInstanceId].calendarUid = notebookUid; + mEvents.remove(oldInstanceId); } - if (mEventObjects.contains(oldEventUid)) { - mEventObjects.insert(newEventUid, mEventObjects.value(oldEventUid)); - mEventObjects.remove(oldEventUid); + // newInstanceId points to the same object than oldInstanceId + // to avoid CalendarEventQuery or CalendarEventOccurrence to + // emit object changed. + if (mEventObjects.contains(oldInstanceId)) { + mEventObjects.insert(newInstanceId, mEventObjects.value(oldInstanceId)); + mEventObjects.remove(oldInstanceId); } - foreach (QString occurrenceUid, mEventOccurrences.keys()) { - if (mEventOccurrences.value(occurrenceUid).instanceId == oldEventUid) - mEventOccurrences[occurrenceUid].instanceId = newEventUid; - } - - emit eventUidChanged(oldEventUid, newEventUid); - - // Event uid is changed when events are moved between notebooks, the notebook color - // associated with this event has changed. Emit color changed after emitting eventUidChanged, - // so that data models have the correct event uid to use when querying for CalendarEvent - // instances, see CalendarEventOccurrence::eventObject(), used by CalendarAgendaModel. - CalendarEvent *eventObject = mEventObjects.value(newEventUid); - if (eventObject) - emit eventObject->colorChanged(); -#else - Q_UNUSED(oldEventUid) - Q_UNUSED(newEventUid) - Q_UNUSED(notebookUid) -#endif + emit instanceIdChanged(oldInstanceId, newInstanceId, notebookUid); } void CalendarManager::excludedNotebooksChangedSlot(const QStringList &excludedNotebooks) diff --git a/src/calendarmanager.h b/src/calendarmanager.h index 8feef46d..56efd349 100644 --- a/src/calendarmanager.h +++ b/src/calendarmanager.h @@ -119,7 +119,9 @@ class CalendarManager : public QObject private slots: void storageModifiedSlot(); void calendarTimezoneChangedSlot(); - void eventNotebookChanged(const QString &oldEventUid, const QString &newEventUid, const QString ¬ebookUid); + void eventNotebookChanged(const QString &oldInstanceId, + const QString &newInstanceId, + const QString ¬ebookUid); void excludedNotebooksChangedSlot(const QStringList &excludedNotebooks); void notebooksChangedSlot(const QList ¬ebooks); void dataLoadedSlot(const QList &ranges, @@ -142,7 +144,7 @@ private slots: void storageModified(); void timezoneChanged(); void dataUpdated(); - void eventUidChanged(QString oldUid, QString newUid); + void instanceIdChanged(QString oldId, QString newId, QString notebookUid); private: friend class tst_CalendarManager; diff --git a/src/calendarworker.cpp b/src/calendarworker.cpp index 09b8af36..900d2e84 100644 --- a/src/calendarworker.cpp +++ b/src/calendarworker.cpp @@ -309,12 +309,19 @@ void CalendarWorker::saveEvent(const CalendarData::Event &eventData, bool update } } else { if (!notebookUid.isEmpty() && mCalendar->notebook(event) != notebookUid) { - // mkcal does funny things when moving event between notebooks, work around by changing uid KCalendarCore::Event::Ptr newEvent(event->clone()); - newEvent->setUid(KCalendarCore::CalFormat::createUniqueId().toUpper()); - emit eventNotebookChanged(event->uid(), newEvent->uid(), notebookUid); +#if 0 + // mkcal does not support keeping the same UID for events + // in different notebooks. One should keep the same UID + // for the deleted event and the new event not to confuse + // sync processes, if the event has been uploaded to a server + // already. + // So this code is currently broken and requires mKCal + // to support multi-notebook incidences sharing the same UID. + emit eventNotebookChanged(eventData.instanceId, newEvent->instanceIdentifier(), notebookUid); mCalendar->deleteEvent(event); mCalendar->addEvent(newEvent, notebookUid); +#endif event = newEvent; } else { event->setRevision(event->revision() + 1); diff --git a/src/calendarworker.h b/src/calendarworker.h index a8fa23df..1c37358b 100644 --- a/src/calendarworker.h +++ b/src/calendarworker.h @@ -99,7 +99,7 @@ public slots: void storageModifiedSignal(); void calendarTimezoneChanged(); - void eventNotebookChanged(const QString &oldEventUid, const QString &newEventUid, const QString ¬ebookUid); + void eventNotebookChanged(const QString &oldInstanceId, const QString &newInstanceId, const QString ¬ebookUid); void excludedNotebooksChanged(const QStringList &excludedNotebooks); void notebookColorChanged(const CalendarData::Notebook ¬ebook);