diff --git a/framework/src/domain/eventmodel.cpp b/framework/src/domain/eventmodel.cpp index a3856378..d14b19fe 100644 --- a/framework/src/domain/eventmodel.cpp +++ b/framework/src/domain/eventmodel.cpp @@ -1,206 +1,208 @@ /* Copyright (c) 2018 Michael Bohlender Copyright (c) 2018 Christian Mollekopf Copyright (c) 2018 Rémi Nicole 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. */ #include "eventmodel.h" #include #include #include #include #include #include #include #include #include #include using Event = Sink::ApplicationDomain::Event; using Calendar = Sink::ApplicationDomain::Calendar; EventModel::EventModel(QObject *parent) : QAbstractItemModel(parent), mCalendarCache{EntityCache::Ptr::create()}, mCalendar{new KCalCore::MemoryCalendar{QTimeZone::systemTimeZone()}} { mRefreshTimer.setSingleShot(true); QObject::connect(&mRefreshTimer, &QTimer::timeout, this, &EventModel::updateFromSource); } void EventModel::updateQuery(const QDate &start, const QDate &end, const QSet &calendarFilter) { qWarning() << "Update query"; mCalendarFilter = calendarFilter; Sink::Query query; query.setFlags(Sink::Query::LiveQuery); query.request(); query.request(); query.request(); query.request(); query.request(); query.request(); query.request(); query.filter(Sink::Query::Comparator(QVariantList{start, end}, Sink::Query::Comparator::Overlap)); mSourceModel = Sink::Store::loadModel(query); QObject::connect(mSourceModel.data(), &QAbstractItemModel::dataChanged, this, &EventModel::refreshView); QObject::connect(mSourceModel.data(), &QAbstractItemModel::layoutChanged, this, &EventModel::refreshView); QObject::connect(mSourceModel.data(), &QAbstractItemModel::modelReset, this, &EventModel::refreshView); QObject::connect(mSourceModel.data(), &QAbstractItemModel::rowsInserted, this, &EventModel::refreshView); QObject::connect(mSourceModel.data(), &QAbstractItemModel::rowsMoved, this, &EventModel::refreshView); QObject::connect(mSourceModel.data(), &QAbstractItemModel::rowsRemoved, this, &EventModel::refreshView); refreshView(); } void EventModel::refreshView() { if (!mRefreshTimer.isActive()) { //Instant update, but then only refresh every 50ms max. updateFromSource(); mRefreshTimer.start(50); } } void EventModel::updateFromSource() { beginResetModel(); mEvents.clear(); for (int i = 0; i < mSourceModel->rowCount(); ++i) { auto event = mSourceModel->index(i, 0).data(Sink::Store::DomainObjectRole).value(); if (!mCalendarFilter.contains(event->getCalendar())) { continue; } //Parse the event auto icalEvent = KCalCore::ICalFormat().readIncidence(event->getIcal()).dynamicCast(); if(!icalEvent) { SinkWarning() << "Invalid ICal to process, ignoring..."; continue; } if (icalEvent->recurs()) { const auto duration = icalEvent->hasDuration() ? icalEvent->duration().asSeconds() : 0; KCalCore::OccurrenceIterator occurrenceIterator{*mCalendar, icalEvent, QDateTime{mStart, {0, 0, 0}}, QDateTime{mEnd, {12, 59, 59}}}; while (occurrenceIterator.hasNext()) { occurrenceIterator.next(); const auto start = occurrenceIterator.occurrenceStartDate(); const auto end = start.addSecs(duration); if (start.date() < mEnd && end.date() >= mStart) { - mEvents.append({start, end, occurrenceIterator.incidence(), getColor(event->getCalendar())}); + mEvents.append({start, end, occurrenceIterator.incidence(), getColor(event->getCalendar()), event->getAllDay()}); } } } else { if (icalEvent->dtStart().date() < mEnd && icalEvent->dtEnd().date() >= mStart) { - mEvents.append({icalEvent->dtStart(), icalEvent->dtEnd(), icalEvent, getColor(event->getCalendar())}); + mEvents.append({icalEvent->dtStart(), icalEvent->dtEnd(), icalEvent, getColor(event->getCalendar()), event->getAllDay()}); } } } endResetModel(); } QModelIndex EventModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) { return {}; } if (!parent.isValid()) { return createIndex(row, column); } return {}; } QModelIndex EventModel::parent(const QModelIndex &index) const { return {}; } int EventModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { return mEvents.size(); } return 0; } int EventModel::columnCount(const QModelIndex &parent) const { return 1; } QByteArray EventModel::getColor(const QByteArray &calendar) const { const auto color = mCalendarCache->getProperty(calendar, "color").toByteArray(); if (color.isEmpty()) { qWarning() << "Failed to get color for calendar " << calendar; } return color; } // QDateTime EventModel::getStartTimeOfDay(const QDateTime &dateTime, int day) const // { // if (bucketOf(dateTime.date()) < day) { // return QDateTime{mPeriodStart.addDays(day), QTime{0,0}}; // } // return dateTime; // } // QDateTime EventModel::getEndTimeOfDay(const QDateTime &dateTime, int day) const // { // if (bucketOf(dateTime.date()) > day) { // return QDateTime{mPeriodStart.addDays(day), QTime{23, 59, 59}}; // } // return dateTime; // } QVariant EventModel::data(const QModelIndex &idx, int role) const { if (!hasIndex(idx.row(), idx.column())) { return {}; } auto event = mEvents.at(idx.row()); auto icalEvent = event.incidence; switch (role) { case Summary: return icalEvent->summary(); case Description: return icalEvent->description(); case StartTime: return event.start; case EndTime: return event.end; case Color: return event.color; + case AllDay: + return event.allDay; default: SinkWarning() << "Unknown role for event:" << QMetaEnum::fromType().valueToKey(role); return {}; } } diff --git a/framework/src/domain/eventmodel.h b/framework/src/domain/eventmodel.h index 19307a67..7fccec1d 100644 --- a/framework/src/domain/eventmodel.h +++ b/framework/src/domain/eventmodel.h @@ -1,87 +1,89 @@ /* Copyright (c) 2018 Michael Bohlender Copyright (c) 2018 Christian Mollekopf Copyright (c) 2018 Rémi Nicole 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. */ #pragma once #include "kube_export.h" #include #include #include #include #include #include namespace KCalCore { class MemoryCalendar; class Incidence; } class EntityCacheInterface; class KUBE_EXPORT EventModel : public QAbstractItemModel { Q_OBJECT public: enum Roles { Summary = Qt::UserRole + 1, Description, StartTime, EndTime, - Color + Color, + AllDay }; Q_ENUM(Roles); EventModel(QObject *parent = nullptr); ~EventModel() = default; QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override; QModelIndex parent(const QModelIndex &index) const override; int rowCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; void updateQuery(const QDate &start, const QDate &end, const QSet &calendarFilter); private: void updateQuery(); void refreshView(); void updateFromSource(); QByteArray getColor(const QByteArray &calendar) const; QSharedPointer mSourceModel; QSet mCalendarFilter; QDate mStart; QDate mEnd; QSharedPointer mCalendarCache; QSharedPointer mCalendar; QTimer mRefreshTimer; struct Occurrence { QDateTime start; QDateTime end; QSharedPointer incidence; QByteArray color; + bool allDay; }; QList mEvents; };