diff --git a/src/memorycalendar.cpp b/src/memorycalendar.cpp index d49e71249..034216b7e 100644 --- a/src/memorycalendar.cpp +++ b/src/memorycalendar.cpp @@ -1,874 +1,875 @@ /* This file is part of the kcalcore library. Copyright (c) 1998 Preston Brown Copyright (c) 2001,2003,2004 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** @file This file is part of the API for handling calendar data and defines the MemoryCalendar class. @brief This class provides a calendar stored as a local file. @author Preston Brown \ @author Cornelius Schumacher \ */ #include "memorycalendar.h" #include "kcalcore_debug.h" #include "utils.h" +#include "calformat.h" #include #include template static QVector values(const QMultiHash &c) { QVector v; v.reserve(c.size()); for (typename QMultiHash::const_iterator it = c.begin(), end = c.end(); it != end; ++it) { v.push_back(it.value()); } return v; } template static QVector values(const QMultiHash &c, const K &x) { QVector v; typename QMultiHash::const_iterator it = c.find(x); while (it != c.end() && it.key() == x) { v.push_back(it.value()); ++it; } return v; } using namespace KCalCore; /** Private class that helps to provide binary compatibility between releases. @internal */ //@cond PRIVATE class Q_DECL_HIDDEN KCalCore::MemoryCalendar::Private { public: Private(MemoryCalendar *qq) : q(qq), mFormat(nullptr) { } ~Private() { } MemoryCalendar *q; CalFormat *mFormat; // calendar format QString mIncidenceBeingUpdated; // Instance identifier of Incidence currently being updated /** * List of all incidences. * First indexed by incidence->type(), then by incidence->uid(); */ QMap > mIncidences; /** * Has all incidences, indexed by identifier. */ QHash mIncidencesByIdentifier; /** * List of all deleted incidences. * First indexed by incidence->type(), then by incidence->uid(); */ QMap > mDeletedIncidences; /** * Contains incidences ( to-dos; non-recurring, non-multiday events; journals; ) * indexed by start/due date. * * The QMap key is the incidence->type(). * The QMultiHash key is the dtStart/dtDue().toString() * * Note: We had 3 variables, mJournalsForDate, mTodosForDate and mEventsForDate * but i merged them into one (indexed by type) because it simplifies code using * it. No need to if else based on type. */ QMap > mIncidencesForDate; void insertIncidence(const Incidence::Ptr &incidence); Incidence::Ptr incidence(const QString &uid, const IncidenceBase::IncidenceType type, const QDateTime &recurrenceId = {}) const; Incidence::Ptr deletedIncidence(const QString &uid, const QDateTime &recurrenceId, const IncidenceBase::IncidenceType type) const; void deleteAllIncidences(const IncidenceBase::IncidenceType type); }; //@endcond MemoryCalendar::MemoryCalendar(const QTimeZone &timeZone) : Calendar(timeZone), d(new KCalCore::MemoryCalendar::Private(this)) { } MemoryCalendar::MemoryCalendar(const QByteArray &timeZoneId) : Calendar(timeZoneId), d(new KCalCore::MemoryCalendar::Private(this)) { } MemoryCalendar::~MemoryCalendar() { close(); delete d; } void MemoryCalendar::close() { setObserversEnabled(false); // Don't call the virtual function deleteEvents() etc, the base class might have // other ways of deleting the data. d->deleteAllIncidences(Incidence::TypeEvent); d->deleteAllIncidences(Incidence::TypeTodo); d->deleteAllIncidences(Incidence::TypeJournal); d->mIncidencesByIdentifier.clear(); d->mDeletedIncidences.clear(); setModified(false); setObserversEnabled(true); } bool MemoryCalendar::deleteIncidence(const Incidence::Ptr &incidence) { // Handle orphaned children // relations is an Incidence's property, not a Todo's, so // we remove relations in deleteIncidence, not in deleteTodo. removeRelations(incidence); const Incidence::IncidenceType type = incidence->type(); const QString uid = incidence->uid(); if (d->mIncidences[type].contains(uid, incidence)) { // Notify while the incidence is still available, // this is necessary so korganizer still has time to query for exceptions notifyIncidenceAboutToBeDeleted(incidence); d->mIncidences[type].remove(uid, incidence); d->mIncidencesByIdentifier.remove(incidence->instanceIdentifier()); setModified(true); notifyIncidenceDeletedOld(incidence); if (deletionTracking()) { d->mDeletedIncidences[type].insert(uid, incidence); } const KDateTime dt = incidence->dateTime(Incidence::RoleCalendarHashing); if (dt.isValid()) { d->mIncidencesForDate[type].remove(dt.date().toString(), incidence); } // Delete child-incidences. if (!incidence->hasRecurrenceId()) { deleteIncidenceInstances(incidence); } notifyIncidenceDeleted(incidence); return true; } else { qCWarning(KCALCORE_LOG) << incidence->typeStr() << " not found. uid=" << uid; return false; } } bool MemoryCalendar::deleteIncidenceInstances(const Incidence::Ptr &incidence) { const Incidence::IncidenceType type = incidence->type(); Incidence::List values = ::values(d->mIncidences[type], incidence->uid()); for (auto it = values.constBegin(); it != values.constEnd(); ++it) { Incidence::Ptr i = *it; if (i->hasRecurrenceId()) { qCDebug(KCALCORE_LOG) << "deleting child" << ", type=" << int(type) << ", uid=" << i->uid() // << ", start=" << i->dtStart() << " from calendar"; deleteIncidence(i); } } return true; } //@cond PRIVATE void MemoryCalendar::Private::deleteAllIncidences(const Incidence::IncidenceType incidenceType) { QHashIteratori(mIncidences[incidenceType]); while (i.hasNext()) { i.next(); q->notifyIncidenceAboutToBeDeleted(i.value()); i.value()->unRegisterObserver(q); } mIncidences[incidenceType].clear(); mIncidencesForDate[incidenceType].clear(); } Incidence::Ptr MemoryCalendar::Private::incidence(const QString &uid, const Incidence::IncidenceType type, const QDateTime &recurrenceId) const { Incidence::List values = ::values(mIncidences[type], uid); for (auto it = values.constBegin(); it != values.constEnd(); ++it) { Incidence::Ptr i = *it; if (recurrenceId.isNull()) { if (!i->hasRecurrenceId()) { return i; } } else { if (i->hasRecurrenceId() && i->recurrenceId() == recurrenceId) { return i; } } } return Incidence::Ptr(); } Incidence::Ptr MemoryCalendar::Private::deletedIncidence(const QString &uid, const QDateTime &recurrenceId, const IncidenceBase::IncidenceType type) const { if (!q->deletionTracking()) { return Incidence::Ptr(); } Incidence::List values = ::values(mDeletedIncidences[type], uid); for (auto it = values.constBegin(); it != values.constEnd(); ++it) { Incidence::Ptr i = *it; if (recurrenceId.isNull()) { if (!i->hasRecurrenceId()) { return i; } } else { if (i->hasRecurrenceId() && i->recurrenceId() == recurrenceId) { return i; } } } return Incidence::Ptr(); } void MemoryCalendar::Private::insertIncidence(const Incidence::Ptr &incidence) { const QString uid = incidence->uid(); const Incidence::IncidenceType type = incidence->type(); if (!mIncidences[type].contains(uid, incidence)) { mIncidences[type].insert(uid, incidence); mIncidencesByIdentifier.insert(incidence->instanceIdentifier(), incidence); const KDateTime dt = incidence->dateTime(Incidence::RoleCalendarHashing); if (dt.isValid()) { mIncidencesForDate[type].insert(dt.date().toString(), incidence); } } else { #ifndef NDEBUG // if we already have an to-do with this UID, it must be the same incidence, // otherwise something's really broken Q_ASSERT(mIncidences[type].value(uid) == incidence); #endif } } //@endcond bool MemoryCalendar::addIncidence(const Incidence::Ptr &incidence) { d->insertIncidence(incidence); notifyIncidenceAdded(incidence); incidence->registerObserver(this); setupRelations(incidence); setModified(true); return true; } bool MemoryCalendar::addEvent(const Event::Ptr &event) { return addIncidence(event); } bool MemoryCalendar::deleteEvent(const Event::Ptr &event) { return deleteIncidence(event); } bool MemoryCalendar::deleteEventInstances(const Event::Ptr &event) { return deleteIncidenceInstances(event); } Event::Ptr MemoryCalendar::event(const QString &uid, const QDateTime &recurrenceId) const { return d->incidence(uid, Incidence::TypeEvent, recurrenceId).staticCast(); } Event::Ptr MemoryCalendar::deletedEvent(const QString &uid, const QDateTime &recurrenceId) const { return d->deletedIncidence(uid, recurrenceId, Incidence::TypeEvent).staticCast(); } bool MemoryCalendar::addTodo(const Todo::Ptr &todo) { return addIncidence(todo); } bool MemoryCalendar::deleteTodo(const Todo::Ptr &todo) { return deleteIncidence(todo); } bool MemoryCalendar::deleteTodoInstances(const Todo::Ptr &todo) { return deleteIncidenceInstances(todo); } Todo::Ptr MemoryCalendar::todo(const QString &uid, const QDateTime &recurrenceId) const { return d->incidence(uid, Incidence::TypeTodo, recurrenceId).staticCast(); } Todo::Ptr MemoryCalendar::deletedTodo(const QString &uid, const QDateTime &recurrenceId) const { return d->deletedIncidence(uid, recurrenceId, Incidence::TypeTodo).staticCast(); } Todo::List MemoryCalendar::rawTodos(TodoSortField sortField, SortDirection sortDirection) const { Todo::List todoList; todoList.reserve(d->mIncidences[Incidence::TypeTodo].count()); QHashIteratori(d->mIncidences[Incidence::TypeTodo]); while (i.hasNext()) { i.next(); todoList.append(i.value().staticCast()); } return Calendar::sortTodos(todoList, sortField, sortDirection); } Todo::List MemoryCalendar::deletedTodos(TodoSortField sortField, SortDirection sortDirection) const { if (!deletionTracking()) { return Todo::List(); } Todo::List todoList; todoList.reserve(d->mDeletedIncidences[Incidence::TypeTodo].count()); QHashIteratori(d->mDeletedIncidences[Incidence::TypeTodo]); while (i.hasNext()) { i.next(); todoList.append(i.value().staticCast()); } return Calendar::sortTodos(todoList, sortField, sortDirection); } Todo::List MemoryCalendar::todoInstances(const Incidence::Ptr &todo, TodoSortField sortField, SortDirection sortDirection) const { Todo::List list; Incidence::List values = ::values(d->mIncidences[Incidence::TypeTodo], todo->uid()); for (auto it = values.constBegin(); it != values.constEnd(); ++it) { Todo::Ptr t = (*it).staticCast(); if (t->hasRecurrenceId()) { list.append(t); } } return Calendar::sortTodos(list, sortField, sortDirection); } Todo::List MemoryCalendar::rawTodosForDate(const QDate &date) const { Todo::List todoList; Todo::Ptr t; const QString dateStr = date.toString(); QMultiHash::const_iterator it = d->mIncidencesForDate[Incidence::TypeTodo].constFind(dateStr); while (it != d->mIncidencesForDate[Incidence::TypeTodo].constEnd() && it.key() == dateStr) { t = it.value().staticCast(); todoList.append(t); ++it; } // Iterate over all todos. Look for recurring todoss that occur on this date QHashIteratori(d->mIncidences[Incidence::TypeTodo]); while (i.hasNext()) { i.next(); t = i.value().staticCast(); if (t->recurs()) { if (t->recursOn(date, timeZone())) { todoList.append(t); } } } return todoList; } Todo::List MemoryCalendar::rawTodos(const QDate &start, const QDate &end, const QTimeZone &timeZone, bool inclusive) const { Q_UNUSED(inclusive); // use only exact dtDue/dtStart, not dtStart and dtEnd Todo::List todoList; const auto ts = timeZone.isValid() ? timeZone : this->timeZone(); QDateTime st(start, QTime(0, 0, 0), ts); QDateTime nd(end, QTime(23, 59, 59, 999), ts); // Get todos QHashIteratori(d->mIncidences[Incidence::TypeTodo]); Todo::Ptr todo; while (i.hasNext()) { i.next(); todo = i.value().staticCast(); if (!isVisible(todo)) { continue; } QDateTime rStart = todo->hasDueDate() ? k2q(todo->dtDue()) : todo->hasStartDate() ? k2q(todo->dtStart()) : QDateTime(); if (!rStart.isValid()) { continue; } if (!todo->recurs()) { // non-recurring todos if (nd.isValid() && nd < rStart) { continue; } if (st.isValid() && rStart < st) { continue; } } else { // recurring events switch (todo->recurrence()->duration()) { case -1: // infinite break; case 0: // end date given default: // count given QDateTime rEnd(todo->recurrence()->endDate(), QTime(23, 59, 59, 999), ts); if (!rEnd.isValid()) { continue; } if (st.isValid() && rEnd < st) { continue; } break; } // switch(duration) } //if(recurs) todoList.append(todo); } return todoList; } Alarm::List MemoryCalendar::alarmsTo(const QDateTime &to) const { return alarms(QDateTime(QDate(1900, 1, 1), QTime(0, 0, 0)), to); } Alarm::List MemoryCalendar::alarms(const QDateTime &from, const QDateTime &to, bool excludeBlockedAlarms) const { Q_UNUSED(excludeBlockedAlarms); Alarm::List alarmList; QHashIteratorie(d->mIncidences[Incidence::TypeEvent]); Event::Ptr e; while (ie.hasNext()) { ie.next(); e = ie.value().staticCast(); if (e->recurs()) { appendRecurringAlarms(alarmList, e, from, to); } else { appendAlarms(alarmList, e, from, to); } } QHashIteratorit(d->mIncidences[Incidence::TypeTodo]); Todo::Ptr t; while (it.hasNext()) { it.next(); t = it.value().staticCast(); if (!t->isCompleted()) { appendAlarms(alarmList, t, from, to); if (t->recurs()) { appendRecurringAlarms(alarmList, t, from, to); } else { appendAlarms(alarmList, t, from, to); } } } return alarmList; } void MemoryCalendar::incidenceUpdate(const QString &uid, const QDateTime &recurrenceId) { Incidence::Ptr inc = incidence(uid, recurrenceId); if (inc) { if (!d->mIncidenceBeingUpdated.isEmpty()) { qCWarning(KCALCORE_LOG) << "Incidence::update() called twice without an updated() call in between."; } // Save it so we can detect changes to uid or recurringId. d->mIncidenceBeingUpdated = inc->instanceIdentifier(); const KDateTime dt = inc->dateTime(Incidence::RoleCalendarHashing); if (dt.isValid()) { const Incidence::IncidenceType type = inc->type(); d->mIncidencesForDate[type].remove(dt.date().toString(), inc); } } } void MemoryCalendar::incidenceUpdated(const QString &uid, const QDateTime &recurrenceId) { Incidence::Ptr inc = incidence(uid, recurrenceId); if (inc) { if (d->mIncidenceBeingUpdated.isEmpty()) { qCWarning(KCALCORE_LOG) << "Incidence::updated() called twice without an update() call in between."; } else if (inc->instanceIdentifier() != d->mIncidenceBeingUpdated) { // Instance identifier changed, update our hash table d->mIncidencesByIdentifier.remove(d->mIncidenceBeingUpdated); d->mIncidencesByIdentifier.insert(inc->instanceIdentifier(), inc); } d->mIncidenceBeingUpdated = QString(); inc->setLastModified(QDateTime::currentDateTimeUtc()); // we should probably update the revision number here, // or internally in the Event itself when certain things change. // need to verify with ical documentation. const KDateTime dt = inc->dateTime(Incidence::RoleCalendarHashing); if (dt.isValid()) { const Incidence::IncidenceType type = inc->type(); d->mIncidencesForDate[type].insert(dt.date().toString(), inc); } notifyIncidenceChanged(inc); setModified(true); } } Event::List MemoryCalendar::rawEventsForDate(const QDate &date, const QTimeZone &timeZone, EventSortField sortField, SortDirection sortDirection) const { Event::List eventList; if (!date.isValid()) { // There can't be events on invalid dates return eventList; } Event::Ptr ev; // Find the hash for the specified date const QString dateStr = date.toString(); QMultiHash::const_iterator it = d->mIncidencesForDate[Incidence::TypeEvent].constFind(dateStr); // Iterate over all non-recurring, single-day events that start on this date const auto ts = timeZone.isValid() ? timeZone : this->timeZone(); while (it != d->mIncidencesForDate[Incidence::TypeEvent].constEnd() && it.key() == dateStr) { ev = it.value().staticCast(); KDateTime end(ev->dtEnd().toTimeSpec(ev->dtStart())); if (ev->allDay()) { end.setDateOnly(true); } else { end = end.addSecs(-1); } if (end.date() >= date) { eventList.append(ev); } ++it; } // Iterate over all events. Look for recurring events that occur on this date QHashIteratori(d->mIncidences[Incidence::TypeEvent]); while (i.hasNext()) { i.next(); ev = i.value().staticCast(); if (ev->recurs()) { if (ev->isMultiDay()) { int extraDays = ev->dtStart().date().daysTo(ev->dtEnd().date()); for (int i = 0; i <= extraDays; ++i) { if (ev->recursOn(date.addDays(-i), ts)) { eventList.append(ev); break; } } } else { if (ev->recursOn(date, ts)) { eventList.append(ev); } } } else { if (ev->isMultiDay()) { if (ev->dtStart().date() <= date && ev->dtEnd().date() >= date) { eventList.append(ev); } } } } return Calendar::sortEvents(eventList, sortField, sortDirection); } Event::List MemoryCalendar::rawEvents(const QDate &start, const QDate &end, const QTimeZone &timeZone, bool inclusive) const { Event::List eventList; const auto ts = timeZone.isValid() ? timeZone : this->timeZone(); QDateTime st(start, QTime(0, 0, 0), ts); QDateTime nd(end, QTime(23, 59, 59, 999), ts); QDateTime yesterStart = st.addDays(-1); // Get non-recurring events QHashIteratori(d->mIncidences[Incidence::TypeEvent]); Event::Ptr event; while (i.hasNext()) { i.next(); event = i.value().staticCast(); QDateTime rStart = k2q(event->dtStart()); if (nd < rStart) { continue; } if (inclusive && rStart < st) { continue; } if (!event->recurs()) { // non-recurring events QDateTime rEnd = k2q(event->dtEnd()); if (rEnd < st) { continue; } if (inclusive && nd < rEnd) { continue; } } else { // recurring events switch (event->recurrence()->duration()) { case -1: // infinite if (inclusive) { continue; } break; case 0: // end date given default: // count given QDateTime rEnd(event->recurrence()->endDate(), QTime(23, 59, 59, 999), ts); if (!rEnd.isValid()) { continue; } if (rEnd < st) { continue; } if (inclusive && nd < rEnd) { continue; } break; } // switch(duration) } //if(recurs) eventList.append(event); } return eventList; } Event::List MemoryCalendar::rawEventsForDate(const QDateTime &kdt) const { return rawEventsForDate(kdt.date(), kdt.timeZone()); } Event::List MemoryCalendar::rawEvents(EventSortField sortField, SortDirection sortDirection) const { Event::List eventList; eventList.reserve(d->mIncidences[Incidence::TypeEvent].count()); QHashIterator i(d->mIncidences[Incidence::TypeEvent]); while (i.hasNext()) { i.next(); eventList.append(i.value().staticCast()); } return Calendar::sortEvents(eventList, sortField, sortDirection); } Event::List MemoryCalendar::deletedEvents(EventSortField sortField, SortDirection sortDirection) const { if (!deletionTracking()) { return Event::List(); } Event::List eventList; eventList.reserve(d->mDeletedIncidences[Incidence::TypeEvent].count()); QHashIteratori(d->mDeletedIncidences[Incidence::TypeEvent]); while (i.hasNext()) { i.next(); eventList.append(i.value().staticCast()); } return Calendar::sortEvents(eventList, sortField, sortDirection); } Event::List MemoryCalendar::eventInstances(const Incidence::Ptr &event, EventSortField sortField, SortDirection sortDirection) const { Event::List list; Incidence::List values = ::values(d->mIncidences[Incidence::TypeEvent], event->uid()); for (auto it = values.constBegin(); it != values.constEnd(); ++it) { Event::Ptr ev = (*it).staticCast(); if (ev->hasRecurrenceId()) { list.append(ev); } } return Calendar::sortEvents(list, sortField, sortDirection); } bool MemoryCalendar::addJournal(const Journal::Ptr &journal) { return addIncidence(journal); } bool MemoryCalendar::deleteJournal(const Journal::Ptr &journal) { return deleteIncidence(journal); } bool MemoryCalendar::deleteJournalInstances(const Journal::Ptr &journal) { return deleteIncidenceInstances(journal); } Journal::Ptr MemoryCalendar::journal(const QString &uid, const QDateTime &recurrenceId) const { return d->incidence(uid, Incidence::TypeJournal, recurrenceId).staticCast(); } Journal::Ptr MemoryCalendar::deletedJournal(const QString &uid, const QDateTime &recurrenceId) const { return d->deletedIncidence(uid, recurrenceId, Incidence::TypeJournal).staticCast(); } Journal::List MemoryCalendar::rawJournals(JournalSortField sortField, SortDirection sortDirection) const { Journal::List journalList; QHashIteratori(d->mIncidences[Incidence::TypeJournal]); while (i.hasNext()) { i.next(); journalList.append(i.value().staticCast()); } return Calendar::sortJournals(journalList, sortField, sortDirection); } Journal::List MemoryCalendar::deletedJournals(JournalSortField sortField, SortDirection sortDirection) const { if (!deletionTracking()) { return Journal::List(); } Journal::List journalList; journalList.reserve(d->mDeletedIncidences[Incidence::TypeJournal].count()); QHashIteratori(d->mDeletedIncidences[Incidence::TypeJournal]); while (i.hasNext()) { i.next(); journalList.append(i.value().staticCast()); } return Calendar::sortJournals(journalList, sortField, sortDirection); } Journal::List MemoryCalendar::journalInstances(const Incidence::Ptr &journal, JournalSortField sortField, SortDirection sortDirection) const { Journal::List list; Incidence::List values = ::values(d->mIncidences[Incidence::TypeJournal], journal->uid()); for (auto it = values.constBegin(); it != values.constEnd(); ++it) { Journal::Ptr j = (*it).staticCast(); if (j->hasRecurrenceId()) { list.append(j); } } return Calendar::sortJournals(list, sortField, sortDirection); } Journal::List MemoryCalendar::rawJournalsForDate(const QDate &date) const { Journal::List journalList; Journal::Ptr j; QString dateStr = date.toString(); QMultiHash::const_iterator it = d->mIncidencesForDate[Incidence::TypeJournal].constFind(dateStr); while (it != d->mIncidencesForDate[Incidence::TypeJournal].constEnd() && it.key() == dateStr) { j = it.value().staticCast(); journalList.append(j); ++it; } return journalList; } Incidence::Ptr MemoryCalendar::instance(const QString &identifier) const { return d->mIncidencesByIdentifier.value(identifier); } void MemoryCalendar::virtual_hook(int id, void *data) { Q_UNUSED(id); Q_UNUSED(data); Q_ASSERT(false); } diff --git a/src/memorycalendar.h b/src/memorycalendar.h index 23648c58b..94b63f76b 100644 --- a/src/memorycalendar.h +++ b/src/memorycalendar.h @@ -1,335 +1,334 @@ /* This file is part of the kcalcore library. Copyright (c) 1998 Preston Brown Copyright (c) 2001,2003 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** @file This file is part of the API for handling calendar data and defines the MemoryCalendar class. Very simple implementation of a Calendar that is only in memory @author Preston Brown \ @author Cornelius Schumacher \ */ #ifndef KCALCORE_MEMORYCALENDAR_H #define KCALCORE_MEMORYCALENDAR_H #include "kcalcore_export.h" #include "calendar.h" namespace KCalCore { -class CalFormat; /** @brief This class provides a calendar stored in memory. */ class KCALCORE_EXPORT MemoryCalendar : public Calendar { Q_OBJECT public: /** A shared pointer to a MemoryCalendar */ typedef QSharedPointer Ptr; /** @copydoc Calendar::Calendar(const QTimeZone &) */ explicit MemoryCalendar(const QTimeZone &timeZone); /** @copydoc Calendar::Calendar(const QString &) */ explicit MemoryCalendar(const QByteArray &timeZoneId); /** @copydoc Calendar::~Calendar() */ ~MemoryCalendar(); /** Clears out the current calendar, freeing all used memory etc. etc. */ void close() override; /** @copydoc Calendar::deleteIncidence() */ bool deleteIncidence(const Incidence::Ptr &incidence) override; /** @copydoc Calendar::deleteIncidenceInstances */ bool deleteIncidenceInstances(const Incidence::Ptr &incidence) override; /** @copydoc Calendar::addIncidence() */ bool addIncidence(const Incidence::Ptr &incidence) override; // Event Specific Methods // /** @copydoc Calendar::addEvent() */ bool addEvent(const Event::Ptr &event) override; /** @copydoc Calendar::deleteEvent() */ bool deleteEvent(const Event::Ptr &event) override; /** @copydoc Calendar::deleteEventInstances() */ bool deleteEventInstances(const Event::Ptr &event) override; /** @copydoc Calendar::rawEvents(EventSortField, SortDirection)const */ Event::List rawEvents( EventSortField sortField = EventSortUnsorted, SortDirection sortDirection = SortDirectionAscending) const override; /** @copydoc Calendar::rawEvents(const QDate &, const QDate &, const QTimeZone &, bool)const */ Event::List rawEvents(const QDate &start, const QDate &end, const QTimeZone &timeZone = {}, bool inclusive = false) const override; /** Returns an unfiltered list of all Events which occur on the given date. @param date request unfiltered Event list for this QDate only. @param timeZone time zone to interpret @p date, or the calendar's default time zone if none is specified @param sortField specifies the EventSortField. @param sortDirection specifies the SortDirection. @return the list of unfiltered Events occurring on the specified QDate. */ Event::List rawEventsForDate( const QDate &date, const QTimeZone &timeZone = {}, EventSortField sortField = EventSortUnsorted, SortDirection sortDirection = SortDirectionAscending) const override; /** @copydoc Calendar::rawEventsForDate(const QDateTime &)const */ Event::List rawEventsForDate(const QDateTime &dt) const override; /** * Returns an incidence by identifier. * @see Incidence::instanceIdentifier() * @since 4.11 */ Incidence::Ptr instance(const QString &identifier) const; /** @copydoc Calendar::event() */ Event::Ptr event(const QString &uid, const QDateTime &recurrenceId = {}) const override; /** @copydoc Calendar::deletedEvent() */ Event::Ptr deletedEvent(const QString &uid, const QDateTime &recurrenceId = {}) const override; /** @copydoc Calendar::deletedEvents(EventSortField, SortDirection)const */ Event::List deletedEvents( EventSortField sortField = EventSortUnsorted, SortDirection sortDirection = SortDirectionAscending) const override; /** @copydoc Calendar::eventInstances(const Incidence::Ptr &, EventSortField, SortDirection)const */ Event::List eventInstances( const Incidence::Ptr &event, EventSortField sortField = EventSortUnsorted, SortDirection sortDirection = SortDirectionAscending) const override; // To-do Specific Methods // /** @copydoc Calendar::addTodo() */ bool addTodo(const Todo::Ptr &todo) override; /** @copydoc Calendar::deleteTodo() */ bool deleteTodo(const Todo::Ptr &todo) override; /** @copydoc Calendar::deleteTodoInstances() */ bool deleteTodoInstances(const Todo::Ptr &todo) override; /** @copydoc Calendar::rawTodos(TodoSortField, SortDirection)const */ Todo::List rawTodos( TodoSortField sortField = TodoSortUnsorted, SortDirection sortDirection = SortDirectionAscending) const override; /** @copydoc Calendar::rawTodos(const QDate &, const QDate &, const QTimeZone &, bool)const */ Todo::List rawTodos( const QDate &start, const QDate &end, const QTimeZone &timeZone = {}, bool inclusive = false) const override; /** @copydoc Calendar::rawTodosForDate() */ Todo::List rawTodosForDate(const QDate &date) const override; /** @copydoc Calendar::todo() */ Todo::Ptr todo(const QString &uid, const QDateTime &recurrenceId = {}) const override; /** @copydoc Calendar::deletedTodo() */ Todo::Ptr deletedTodo(const QString &uid, const QDateTime &recurrenceId = {}) const override; /** @copydoc Calendar::deletedTodos(TodoSortField, SortDirection)const */ Todo::List deletedTodos( TodoSortField sortField = TodoSortUnsorted, SortDirection sortDirection = SortDirectionAscending) const override; /** @copydoc Calendar::todoInstances(const Incidence::Ptr &, TodoSortField, SortDirection)const */ Todo::List todoInstances(const Incidence::Ptr &todo, TodoSortField sortField = TodoSortUnsorted, SortDirection sortDirection = SortDirectionAscending) const override; // Journal Specific Methods // /** @copydoc Calendar::addJournal() */ bool addJournal(const Journal::Ptr &journal) override; /** @copydoc Calendar::deleteJournal() */ bool deleteJournal(const Journal::Ptr &journal) override; /** @copydoc Calendar::deleteJournalInstances() */ bool deleteJournalInstances(const Journal::Ptr &journal) override; /** @copydoc Calendar::rawJournals() */ Journal::List rawJournals( JournalSortField sortField = JournalSortUnsorted, SortDirection sortDirection = SortDirectionAscending) const override; /** @copydoc Calendar::rawJournalsForDate() */ Journal::List rawJournalsForDate(const QDate &date) const override; /** @copydoc Calendar::journal() */ Journal::Ptr journal(const QString &uid, const QDateTime &recurrenceId = {}) const override; /** @copydoc Calendar::deletedJournal() */ Journal::Ptr deletedJournal(const QString &uid, const QDateTime &recurrenceId = {}) const override; /** @copydoc Calendar::deletedJournals(JournalSortField, SortDirection)const */ Journal::List deletedJournals( JournalSortField sortField = JournalSortUnsorted, SortDirection sortDirection = SortDirectionAscending) const override; /** @copydoc Calendar::journalInstances(const Incidence::Ptr &, JournalSortField, SortDirection)const */ Journal::List journalInstances(const Incidence::Ptr &journal, JournalSortField sortField = JournalSortUnsorted, SortDirection sortDirection = SortDirectionAscending) const override; // Alarm Specific Methods // /** @copydoc Calendar::alarms() */ Alarm::List alarms(const QDateTime &from, const QDateTime &to, bool excludeBlockedAlarms = false) const override; /** Return a list of Alarms that occur before the specified timestamp. @param to is the ending timestamp. @return the list of Alarms occurring before the specified QDateTime. */ Alarm::List alarmsTo(const QDateTime &to) const; /** @copydoc Calendar::incidenceUpdate(const QString &,const QDateTime &) */ void incidenceUpdate(const QString &uid, const QDateTime &recurrenceId) override; /** @copydoc Calendar::incidenceUpdated(const QString &,const QDateTime &) */ void incidenceUpdated(const QString &uid, const QDateTime &recurrenceId) override; using QObject::event; // prevent warning about hidden virtual method protected: /** @copydoc IncidenceBase::virtual_hook() */ void virtual_hook(int id, void *data) override; private: //@cond PRIVATE class Private; Private *const d; //@endcond Q_DISABLE_COPY(MemoryCalendar) }; } #endif