Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[nemo-qml-plugin-calendar] Coalesce AgendaModel queries
  • Loading branch information
Aaron Kennedy committed Oct 16, 2013
1 parent b525b3a commit 628ab3a
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 27 deletions.
26 changes: 4 additions & 22 deletions src/calendaragendamodel.cpp
Expand Up @@ -42,8 +42,7 @@
#include "calendardb.h"

NemoCalendarAgendaModel::NemoCalendarAgendaModel(QObject *parent)
: QAbstractListModel(parent), mBuffer(0), mRefreshingModel(false),
mRerefreshNeeded(false), mIsComplete(true)
: QAbstractListModel(parent), mBuffer(0), mIsComplete(true)
{
mRoleNames[EventObjectRole] = "event";
mRoleNames[OccurrenceObjectRole] = "occurrence";
Expand All @@ -58,6 +57,7 @@ NemoCalendarAgendaModel::NemoCalendarAgendaModel(QObject *parent)

NemoCalendarAgendaModel::~NemoCalendarAgendaModel()
{
NemoCalendarEventCache::instance()->cancelAgendaRefresh(this);
qDeleteAll(mEvents);
}

Expand Down Expand Up @@ -105,18 +105,7 @@ void NemoCalendarAgendaModel::refresh()
if (!mIsComplete)
return;

if (mRefreshingModel) {
mRerefreshNeeded = true;
return;
}

mRefreshingModel = true;
doRefresh();
mRefreshingModel = false;
if (mRerefreshNeeded) {
mRerefreshNeeded = false;
refresh();
}
NemoCalendarEventCache::instance()->scheduleAgendaRefresh(this);
}

static bool eventsEqual(const mKCal::ExtendedCalendar::ExpandedIncidence &e1,
Expand All @@ -141,15 +130,8 @@ static bool eventsLessThan(const mKCal::ExtendedCalendar::ExpandedIncidence &e1,
}
}

void NemoCalendarAgendaModel::doRefresh(bool reset)
void NemoCalendarAgendaModel::doRefresh(mKCal::ExtendedCalendar::ExpandedIncidenceList newEvents, bool reset)
{
mKCal::ExtendedCalendar::Ptr calendar = NemoCalendarDb::calendar();

QDate endDate = mEndDate.isValid()?mEndDate:mStartDate;

mKCal::ExtendedCalendar::ExpandedIncidenceList newEvents =
calendar->rawExpandedEvents(mStartDate, endDate, false, false, KDateTime::Spec(KDateTime::LocalZone));

// Filter out excluded notebooks
for (int ii = 0; ii < newEvents.count(); ++ii) {
if (!NemoCalendarEventCache::instance()->mNotebooks.contains(NemoCalendarDb::calendar()->notebook(newEvents.at(ii).second))) {
Expand Down
9 changes: 5 additions & 4 deletions src/calendaragendamodel.h
Expand Up @@ -34,6 +34,7 @@
#define CALENDARAGENDAMODEL_H

#include <QDate>
#include <extendedcalendar.h>
#include <QAbstractListModel>

#ifdef NEMO_USE_QT5
Expand Down Expand Up @@ -85,9 +86,10 @@ class NemoCalendarAgendaModel : public QAbstractListModel, public QQmlParserStat
int rowCount(const QModelIndex &index) const;
QVariant data(const QModelIndex &index, int role) const;

Q_INVOKABLE bool dateHasEvents(QDate) const;

virtual void classBegin();
virtual void componentComplete();

signals:
void countChanged();
void startDateChanged();
Expand All @@ -104,16 +106,15 @@ private slots:
void refresh();

private:
void doRefresh(bool reset = false);
friend class NemoCalendarEventCache;
void doRefresh(mKCal::ExtendedCalendar::ExpandedIncidenceList, bool reset = false);

QDate mStartDate;
QDate mEndDate;
int mBuffer;
QList<NemoCalendarEventOccurrence *> mEvents;
QHash<int,QByteArray> mRoleNames;

bool mRefreshingModel:1;
bool mRerefreshNeeded:1;
bool mIsComplete:1;
};

Expand Down
96 changes: 96 additions & 0 deletions src/calendareventcache.cpp
Expand Up @@ -33,17 +33,20 @@
// Qt
#include <QDebug>
#include <QSettings>
#include <QCoreApplication>

// mkcal
#include <event.h>

#include "calendardb.h"
#include "calendarevent.h"
#include "calendareventcache.h"
#include "calendaragendamodel.h"

NemoCalendarEventCache::NemoCalendarEventCache()
: QObject(0)
, mKCal::ExtendedStorageObserver()
, mRefreshEventSent(false)
{
NemoCalendarDb::storage()->registerObserver(this);

Expand Down Expand Up @@ -162,3 +165,96 @@ QList<NemoCalendarEvent *> NemoCalendarEventCache::events(const KCalCore::Event:
return rv;
}

bool NemoCalendarEventCache::event(QEvent *e)
{
if (e->type() == QEvent::User)
doAgendaRefresh();
return QObject::event(e);
}

void NemoCalendarEventCache::scheduleAgendaRefresh(NemoCalendarAgendaModel *m)
{
mRefreshModels.insert(m);
if (!mRefreshEventSent) {
QCoreApplication::postEvent(this, new QEvent(QEvent::User));
mRefreshEventSent = true;
}
}

void NemoCalendarEventCache::cancelAgendaRefresh(NemoCalendarAgendaModel *m)
{
mRefreshModels.remove(m);
}

static bool agenda_startdate_lessThan(NemoCalendarAgendaModel *lhs, NemoCalendarAgendaModel *rhs)
{
return lhs->startDate() < rhs->startDate();
}

static QDate agenda_endDate(NemoCalendarAgendaModel *a)
{
QDate e = a->endDate();
return e.isValid()?e:a->startDate();
}

struct AgendaDateRange
{
QDate start;
QDate end;
QList<NemoCalendarAgendaModel *> models;
};

void NemoCalendarEventCache::doAgendaRefresh()
{
if (mRefreshModels.isEmpty())
return;

QList<NemoCalendarAgendaModel *> models = mRefreshModels.toList();
mRefreshModels.clear();
mRefreshEventSent = false;

qSort(models.begin(), models.end(), agenda_startdate_lessThan);

QList<AgendaDateRange> ranges;
ranges << AgendaDateRange();
ranges.last().start = models.at(0)->startDate();
ranges.last().end = agenda_endDate(models.at(0));
ranges.last().models << models.at(0);

for (int ii = 1; ii < models.count(); ++ii) {
NemoCalendarAgendaModel *m = models.at(ii);
if (ranges.last().end.addDays(1) >= m->startDate()) {
ranges.last().end = qMax(ranges.last().end, agenda_endDate(m));
ranges.last().models << m;
} else {
ranges << AgendaDateRange();
ranges.last().start = m->startDate();
ranges.last().end = agenda_endDate(m);
ranges.last().models << m;
}
}

mKCal::ExtendedCalendar::Ptr calendar = NemoCalendarDb::calendar();

for (int ii = 0; ii < ranges.count(); ++ii) {
const AgendaDateRange &r = ranges.at(ii);

mKCal::ExtendedCalendar::ExpandedIncidenceList newEvents =
calendar->rawExpandedEvents(r.start, r.end, false, false, KDateTime::Spec(KDateTime::LocalZone));

for (int jj = 0; jj < r.models.count(); ++jj) {
NemoCalendarAgendaModel *m = r.models.at(jj);
QDate start = m->startDate();
QDate end = agenda_endDate(m);
mKCal::ExtendedCalendar::ExpandedIncidenceList filtered;
for (int kk = 0; kk < newEvents.count(); ++kk) {
if (newEvents.at(kk).first.dtStart.date() <= start &&
newEvents.at(kk).first.dtEnd.date() >= end)
filtered.append(newEvents.at(kk));
}

m->doRefresh(filtered);
}
}
}

12 changes: 11 additions & 1 deletion src/calendareventcache.h
Expand Up @@ -42,6 +42,7 @@
#include <extendedstorage.h>

class NemoCalendarEvent;
class NemoCalendarAgendaModel;
class NemoCalendarEventOccurrence;
class NemoCalendarEventCache : public QObject, public mKCal::ExtendedStorageObserver
{
Expand All @@ -63,22 +64,31 @@ class NemoCalendarEventCache : public QObject, public mKCal::ExtendedStorageObse

static QList<NemoCalendarEvent *> events(const KCalCore::Event::Ptr &event);

protected:
virtual bool event(QEvent *);

signals:
void modelReset();

private:

friend class NemoCalendarApi;
friend class NemoCalendarEvent;
friend class NemoCalendarAgendaModel;
friend class NemoCalendarEventOccurrence;

void scheduleAgendaRefresh(NemoCalendarAgendaModel *);
void cancelAgendaRefresh(NemoCalendarAgendaModel *);
void doAgendaRefresh();

QStringList mDefaultNotebookColors;

QSet<QString> mNotebooks;
QHash<QString, QString> mNotebookColors;
QSet<NemoCalendarEvent *> mEvents;
QSet<NemoCalendarEventOccurrence *> mEventOccurrences;

bool mRefreshEventSent;
QSet<NemoCalendarAgendaModel *> mRefreshModels;
};

#endif // CALENDAREVENTCACHE_H

0 comments on commit 628ab3a

Please sign in to comment.