Skip to content

Commit

Permalink
Merge branch 'recur' into 'master'
Browse files Browse the repository at this point in the history
[nemo-qml-plugin-calendar] Add a monthly recurrence on week day position. Contributes to TJC#5565

See merge request mer-core/nemo-qml-plugin-calendar!56
  • Loading branch information
pvuorela committed Jun 16, 2020
2 parents e6ff685 + a74f6d9 commit 4a039cc
Show file tree
Hide file tree
Showing 12 changed files with 230 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/calendardata.h
Expand Up @@ -35,6 +35,7 @@ struct Event {
bool externalInvitation = false;
CalendarEvent::Recur recur;
QDate recurEndDate;
CalendarEvent::Days recurWeeklyDays;
int reminder; // seconds; 15 minutes before event = +900, at time of event = 0, no reminder = negative value.
QString uniqueId;
KDateTime recurrenceId;
Expand Down
5 changes: 5 additions & 0 deletions src/calendarevent.cpp
Expand Up @@ -92,6 +92,11 @@ bool CalendarEvent::hasRecurEndDate() const
return mManager->getEvent(mUniqueId, mRecurrenceId).recurEndDate.isValid();
}

CalendarEvent::Days CalendarEvent::recurWeeklyDays() const
{
return mManager->getEvent(mUniqueId, mRecurrenceId).recurWeeklyDays;
}

int CalendarEvent::reminder() const
{
return mManager->getEvent(mUniqueId, mRecurrenceId).reminder;
Expand Down
21 changes: 20 additions & 1 deletion src/calendarevent.h
Expand Up @@ -43,7 +43,6 @@ class CalendarManager;
class CalendarEvent : public QObject
{
Q_OBJECT
Q_ENUMS(Recur)
Q_ENUMS(Reminder)
Q_ENUMS(TimeSpec)
Q_ENUMS(Secrecy)
Expand All @@ -57,6 +56,7 @@ class CalendarEvent : public QObject
Q_PROPERTY(CalendarEvent::Recur recur READ recur NOTIFY recurChanged)
Q_PROPERTY(QDateTime recurEndDate READ recurEndDate NOTIFY recurEndDateChanged)
Q_PROPERTY(bool hasRecurEndDate READ hasRecurEndDate NOTIFY hasRecurEndDateChanged)
Q_PROPERTY(CalendarEvent::Days recurWeeklyDays READ recurWeeklyDays NOTIFY recurWeeklyDaysChanged)
Q_PROPERTY(int reminder READ reminder NOTIFY reminderChanged)
Q_PROPERTY(QString uniqueId READ uniqueId NOTIFY uniqueIdChanged)
Q_PROPERTY(QString recurrenceId READ recurrenceIdString CONSTANT)
Expand All @@ -75,10 +75,27 @@ class CalendarEvent : public QObject
RecurDaily,
RecurWeekly,
RecurBiweekly,
RecurWeeklyByDays,
RecurMonthly,
RecurMonthlyByDayOfWeek,
RecurMonthlyByLastDayOfWeek,
RecurYearly,
RecurCustom
};
Q_ENUM(Recur)

enum Day {
NoDays = 0x00,
Monday = 0x01,
Tuesday = 0x02,
Wednesday = 0x04,
Thursday = 0x08,
Friday = 0x10,
Saturday = 0x20,
Sunday = 0x40
};
Q_DECLARE_FLAGS(Days, Day)
Q_FLAG(Days)

enum TimeSpec {
SpecLocalZone,
Expand Down Expand Up @@ -109,6 +126,7 @@ class CalendarEvent : public QObject
Recur recur() const;
QDateTime recurEndDate() const;
bool hasRecurEndDate() const;
Days recurWeeklyDays() const;
int reminder() const;
QString uniqueId() const;
QString color() const;
Expand Down Expand Up @@ -143,6 +161,7 @@ private slots:
void locationChanged();
void recurEndDateChanged();
void hasRecurEndDateChanged();
void recurWeeklyDaysChanged();
void secrecyChanged();
void ownerStatusChanged();
void rsvpChanged();
Expand Down
13 changes: 13 additions & 0 deletions src/calendareventmodification.cpp
Expand Up @@ -143,6 +143,19 @@ void CalendarEventModification::unsetRecurEndDate()
setRecurEndDate(QDateTime());
}

CalendarEvent::Days CalendarEventModification::recurWeeklyDays() const
{
return m_event.recurWeeklyDays;
}

void CalendarEventModification::setRecurWeeklyDays(CalendarEvent::Days days)
{
if (m_event.recurWeeklyDays != days) {
m_event.recurWeeklyDays = days;
emit recurWeeklyDaysChanged();
}
}

QString CalendarEventModification::recurrenceIdString() const
{
if (m_event.recurrenceId.isValid()) {
Expand Down
5 changes: 5 additions & 0 deletions src/calendareventmodification.h
Expand Up @@ -19,6 +19,7 @@ class CalendarEventModification : public QObject
Q_PROPERTY(bool allDay READ allDay WRITE setAllDay NOTIFY allDayChanged)
Q_PROPERTY(CalendarEvent::Recur recur READ recur WRITE setRecur NOTIFY recurChanged)
Q_PROPERTY(QDateTime recurEndDate READ recurEndDate NOTIFY recurEndDateChanged)
Q_PROPERTY(CalendarEvent::Days recurWeeklyDays READ recurWeeklyDays WRITE setRecurWeeklyDays NOTIFY recurWeeklyDaysChanged)
Q_PROPERTY(bool hasRecurEndDate READ hasRecurEndDate NOTIFY hasRecurEndDateChanged)
Q_PROPERTY(QString recurrenceId READ recurrenceIdString CONSTANT)
Q_PROPERTY(int reminder READ reminder WRITE setReminder NOTIFY reminderChanged)
Expand Down Expand Up @@ -53,6 +54,9 @@ class CalendarEventModification : public QObject
Q_INVOKABLE void setRecurEndDate(const QDateTime &dateTime);
Q_INVOKABLE void unsetRecurEndDate();

CalendarEvent::Days recurWeeklyDays() const;
void setRecurWeeklyDays(CalendarEvent::Days days);

QString recurrenceIdString() const;

int reminder() const;
Expand All @@ -76,6 +80,7 @@ class CalendarEventModification : public QObject
void endTimeChanged();
void allDayChanged();
void recurChanged();
void recurWeeklyDaysChanged();
void reminderChanged();
void locationChanged();
void recurEndDateChanged();
Expand Down
8 changes: 8 additions & 0 deletions src/calendarimportevent.cpp
Expand Up @@ -93,6 +93,14 @@ CalendarEvent::Recur CalendarImportEvent::recur()
return CalendarUtils::convertRecurrence(mEvent);
}

CalendarEvent::Days CalendarImportEvent::recurWeeklyDays()
{
if (!mEvent)
return CalendarEvent::NoDays;

return CalendarUtils::convertDayPositions(mEvent);
}

int CalendarImportEvent::reminder() const
{
// note: returns seconds before event, so 15 minutes before = 900.
Expand Down
2 changes: 2 additions & 0 deletions src/calendarimportevent.h
Expand Up @@ -49,6 +49,7 @@ class CalendarImportEvent : public QObject
Q_PROPERTY(QDateTime endTime READ endTime CONSTANT)
Q_PROPERTY(bool allDay READ allDay CONSTANT)
Q_PROPERTY(CalendarEvent::Recur recur READ recur CONSTANT)
Q_PROPERTY(CalendarEvent::Days recurWeeklyDays READ recurWeeklyDays CONSTANT)
Q_PROPERTY(int reminder READ reminder CONSTANT)
Q_PROPERTY(QString uniqueId READ uniqueId CONSTANT)
Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
Expand All @@ -69,6 +70,7 @@ class CalendarImportEvent : public QObject
QDateTime endTime() const;
bool allDay() const;
CalendarEvent::Recur recur();
CalendarEvent::Days recurWeeklyDays();
int reminder() const;
QString uniqueId() const;
QString color() const;
Expand Down
47 changes: 45 additions & 2 deletions src/calendarutils.cpp
Expand Up @@ -64,19 +64,62 @@ CalendarEvent::Recur CalendarUtils::convertRecurrence(const KCalCore::Event::Ptr

if (rt == KCalCore::Recurrence::rDaily && freq == 1) {
return CalendarEvent::RecurDaily;
} else if (rt == KCalCore::Recurrence::rWeekly && freq == 1 && event->recurrence()->days().count(true) == 0) {
return CalendarEvent::RecurWeekly;
} else if (rt == KCalCore::Recurrence::rWeekly && freq == 1) {
if (event->recurrence()->days().count(true) == 0) {
return CalendarEvent::RecurWeekly;
} else {
return CalendarEvent::RecurWeeklyByDays;
}
} else if (rt == KCalCore::Recurrence::rWeekly && freq == 2 && event->recurrence()->days().count(true) == 0) {
return CalendarEvent::RecurBiweekly;
} else if (rt == KCalCore::Recurrence::rMonthlyDay && freq == 1) {
return CalendarEvent::RecurMonthly;
} else if (rt == KCalCore::Recurrence::rMonthlyPos && freq == 1) {
const QList<KCalCore::RecurrenceRule::WDayPos> monthPositions = event->recurrence()->monthPositions();
if (monthPositions.length() == 1
&& monthPositions.first().day() == event->dtStart().date().dayOfWeek()) {
if (monthPositions.first().pos() > 0) {
return CalendarEvent::RecurMonthlyByDayOfWeek;
} else if (monthPositions.first().pos() == -1) {
return CalendarEvent::RecurMonthlyByLastDayOfWeek;
}
}
} else if (rt == KCalCore::Recurrence::rYearlyMonth && freq == 1) {
return CalendarEvent::RecurYearly;
}

return CalendarEvent::RecurCustom;
}

CalendarEvent::Days CalendarUtils::convertDayPositions(const KCalCore::Event::Ptr &event)
{
if (!event->recurs())
return CalendarEvent::NoDays;

if (event->recurrence()->rRules().count() != 1)
return CalendarEvent::NoDays;

if (event->recurrence()->recurrenceType() != KCalCore::Recurrence::rWeekly
|| event->recurrence()->frequency() != 1)
return CalendarEvent::NoDays;

const CalendarEvent::Day week[7] = {CalendarEvent::Monday,
CalendarEvent::Tuesday,
CalendarEvent::Wednesday,
CalendarEvent::Thursday,
CalendarEvent::Friday,
CalendarEvent::Saturday,
CalendarEvent::Sunday};

const QList<KCalCore::RecurrenceRule::WDayPos> monthPositions = event->recurrence()->monthPositions();
CalendarEvent::Days days = CalendarEvent::NoDays;
for (QList<KCalCore::RecurrenceRule::WDayPos>::ConstIterator it = monthPositions.constBegin();
it != monthPositions.constEnd(); ++it) {
days |= week[it->day() - 1];
}
return days;
}

CalendarEvent::Secrecy CalendarUtils::convertSecrecy(const KCalCore::Event::Ptr &event)
{
KCalCore::Incidence::Secrecy s = event->secrecy();
Expand Down
1 change: 1 addition & 0 deletions src/calendarutils.h
Expand Up @@ -45,6 +45,7 @@
namespace CalendarUtils {

CalendarEvent::Recur convertRecurrence(const KCalCore::Event::Ptr &event);
CalendarEvent::Days convertDayPositions(const KCalCore::Event::Ptr &event);
CalendarEvent::Secrecy convertSecrecy(const KCalCore::Event::Ptr &event);
int getReminder(const KCalCore::Event::Ptr &event);
QList<CalendarData::Attendee> getEventAttendees(const KCalCore::Event::Ptr &event);
Expand Down
35 changes: 32 additions & 3 deletions src/calendarworker.cpp
Expand Up @@ -37,6 +37,7 @@

#include <QDebug>
#include <QSettings>
#include <QBitArray>

// mkcal
#include <notebook.h>
Expand Down Expand Up @@ -272,7 +273,7 @@ void CalendarWorker::setEventData(KCalCore::Event::Ptr &event, const CalendarDat
event->setAllDay(eventData.allDay);
event->setLocation(eventData.location);
setReminder(event, eventData.reminder);
setRecurrence(event, eventData.recur);
setRecurrence(event, eventData.recur, eventData.recurWeeklyDays);

if (eventData.recur != CalendarEvent::RecurOnce) {
event->recurrence()->setEndDate(eventData.recurEndDate);
Expand Down Expand Up @@ -339,7 +340,7 @@ void CalendarWorker::init()
loadNotebooks();
}

bool CalendarWorker::setRecurrence(KCalCore::Event::Ptr &event, CalendarEvent::Recur recur)
bool CalendarWorker::setRecurrence(KCalCore::Event::Ptr &event, CalendarEvent::Recur recur, CalendarEvent::Days days)
{
if (!event)
return false;
Expand All @@ -349,7 +350,10 @@ bool CalendarWorker::setRecurrence(KCalCore::Event::Ptr &event, CalendarEvent::R
if (recur == CalendarEvent::RecurOnce)
event->recurrence()->clear();

if (oldRecur != recur) {
if (oldRecur != recur
|| recur == CalendarEvent::RecurMonthlyByDayOfWeek
|| recur == CalendarEvent::RecurMonthlyByLastDayOfWeek
|| recur == CalendarEvent::RecurWeeklyByDays) {
switch (recur) {
case CalendarEvent::RecurOnce:
break;
Expand All @@ -362,9 +366,33 @@ bool CalendarWorker::setRecurrence(KCalCore::Event::Ptr &event, CalendarEvent::R
case CalendarEvent::RecurBiweekly:
event->recurrence()->setWeekly(2);
break;
case CalendarEvent::RecurWeeklyByDays: {
QBitArray rDays(7);
rDays.setBit(0, days & CalendarEvent::Monday);
rDays.setBit(1, days & CalendarEvent::Tuesday);
rDays.setBit(2, days & CalendarEvent::Wednesday);
rDays.setBit(3, days & CalendarEvent::Thursday);
rDays.setBit(4, days & CalendarEvent::Friday);
rDays.setBit(5, days & CalendarEvent::Saturday);
rDays.setBit(6, days & CalendarEvent::Sunday);
event->recurrence()->setWeekly(1, rDays);
break;
}
case CalendarEvent::RecurMonthly:
event->recurrence()->setMonthly(1);
break;
case CalendarEvent::RecurMonthlyByDayOfWeek: {
event->recurrence()->setMonthly(1);
const QDate at(event->dtStart().date());
event->recurrence()->addMonthlyPos((at.day() - 1) / 7 + 1, at.dayOfWeek());
break;
}
case CalendarEvent::RecurMonthlyByLastDayOfWeek: {
event->recurrence()->setMonthly(1);
const QDate at(event->dtStart().date());
event->recurrence()->addMonthlyPos(-1, at.dayOfWeek());
break;
}
case CalendarEvent::RecurYearly:
event->recurrence()->setYearly(1);
break;
Expand Down Expand Up @@ -786,6 +814,7 @@ CalendarData::Event CalendarWorker::createEventStruct(const KCalCore::Event::Ptr
event.secrecy = CalendarUtils::convertSecrecy(e);
event.readOnly = mStorage->notebook(event.calendarUid)->isReadOnly();
event.recur = CalendarUtils::convertRecurrence(e);
event.recurWeeklyDays = CalendarUtils::convertDayPositions(e);
bool externalInvitation = false;
const QString &calendarOwnerEmail = getNotebookAddress(e);

Expand Down
2 changes: 1 addition & 1 deletion src/calendarworker.h
Expand Up @@ -118,7 +118,7 @@ public slots:
QStringList excludedNotebooks() const;
bool saveExcludeNotebook(const QString &notebookUid, bool exclude);

bool setRecurrence(KCalCore::Event::Ptr &event, CalendarEvent::Recur recur);
bool setRecurrence(KCalCore::Event::Ptr &event, CalendarEvent::Recur recur, CalendarEvent::Days days);
bool setReminder(KCalCore::Event::Ptr &event, int reminderSeconds);
bool needSendCancellation(KCalCore::Event::Ptr &event) const;
void updateEventAttendees(KCalCore::Event::Ptr event, bool newEvent,
Expand Down

0 comments on commit 4a039cc

Please sign in to comment.