File indexing completed on 2024-11-24 04:44:10

0001 /*
0002  * SPDX-FileCopyrightText: 2012 Christian Mollekopf <mollekopf@kolabsys.com>
0003  *
0004  * SPDX-License-Identifier: LGPL-3.0-or-later
0005  */
0006 
0007 #include "calendaring.h"
0008 #include "pimkolab_debug.h"
0009 
0010 #include <QDate>
0011 #include <QTimeZone>
0012 
0013 #include "conversion/commonconversion.h"
0014 #include "conversion/kcalconversion.h"
0015 
0016 namespace Kolab
0017 {
0018 namespace Calendaring
0019 {
0020 bool conflicts(const Kolab::Event &e1, const Kolab::Event &e2)
0021 {
0022     KCalendarCore::Event::Ptr k1 = Kolab::Conversion::toKCalendarCore(e1);
0023     KCalendarCore::Event::Ptr k2 = Kolab::Conversion::toKCalendarCore(e2);
0024     if (k2->dtEnd() < k1->dtStart()) {
0025         return false;
0026     } else if (k1->dtEnd() < k2->dtStart()) {
0027         return false;
0028     }
0029     return true;
0030 }
0031 
0032 std::vector<std::vector<Event>> getConflictingSets(const std::vector<Event> &events, const std::vector<Event> &events2)
0033 {
0034     std::vector<std::vector<Kolab::Event>> ret;
0035     for (std::size_t i = 0; i < events.size(); i++) {
0036         std::vector<Kolab::Event> set;
0037         const Kolab::Event &event = events.at(i);
0038         set.push_back(event);
0039         for (std::size_t q = i + 1; q < events.size(); q++) {
0040             const Kolab::Event &e2 = events.at(q);
0041             if (conflicts(event, e2)) {
0042                 set.push_back(e2);
0043             }
0044         }
0045         for (std::size_t m = 0; m < events2.size(); m++) {
0046             const Kolab::Event &e2 = events2.at(m);
0047             if (conflicts(event, e2)) {
0048                 set.push_back(e2);
0049             }
0050         }
0051         if (set.size() > 1) {
0052             ret.push_back(set);
0053         }
0054     }
0055     return ret;
0056 }
0057 
0058 std::vector<Kolab::cDateTime> timeInInterval(const Kolab::Event &e, const Kolab::cDateTime &start, const Kolab::cDateTime &end)
0059 {
0060     KCalendarCore::Event::Ptr k = Kolab::Conversion::toKCalendarCore(e);
0061     const KCalendarCore::DateTimeList list = k->recurrence()->timesInInterval(Kolab::Conversion::toDate(start), Kolab::Conversion::toDate(end));
0062     std::vector<Kolab::cDateTime> dtList;
0063     dtList.reserve(list.count());
0064     for (const QDateTime &dt : list) {
0065         dtList.push_back(Kolab::Conversion::fromDate(dt, start.isDateOnly()));
0066     }
0067     return dtList;
0068 }
0069 
0070 Calendar::Calendar()
0071     : mCalendar(new KCalendarCore::MemoryCalendar(Kolab::Conversion::getTimeSpec(true, std::string()))) // Always utc as it doesn't change anything anyways
0072 {
0073 }
0074 
0075 void Calendar::addEvent(const Kolab::Event &event)
0076 {
0077     KCalendarCore::Event::Ptr k = Kolab::Conversion::toKCalendarCore(event);
0078     if (!mCalendar->addEvent(k)) {
0079         qCWarning(PIMKOLAB_LOG) << "failed to add event";
0080     }
0081 }
0082 
0083 std::vector<Kolab::Event> Calendar::getEvents(const Kolab::cDateTime &start, const Kolab::cDateTime &end, bool sort)
0084 {
0085     const QDateTime s = Kolab::Conversion::toDate(start);
0086     const QDateTime e = Kolab::Conversion::toDate(end);
0087     const QTimeZone tz = s.timeZone();
0088     KCalendarCore::Event::List list = mCalendar->events(s.date(), e.date(), tz, true);
0089     if (sort) {
0090         list = mCalendar->sortEvents(std::move(list), KCalendarCore::EventSortStartDate, KCalendarCore::SortDirectionAscending);
0091     }
0092     std::vector<Kolab::Event> eventlist;
0093     for (const KCalendarCore::Event::Ptr &event : std::as_const(list)) {
0094         // We have to filter the list by time
0095         if (event->dtEnd() >= s && e >= event->dtStart()) {
0096             eventlist.push_back(Kolab::Conversion::fromKCalendarCore(*event));
0097         }
0098     }
0099     return eventlist;
0100 }
0101 } // Namespace
0102 } // Namespace