summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vrátil <[email protected]>2017-09-13 15:29:38 +0200
committerDaniel Vrátil <[email protected]>2017-09-13 15:29:38 +0200
commit0a8f6a6ddfa8d4d0fda4199c1d3485304051abea (patch)
treea103a1a72ac55de22d8a8c78d90ad454bccac859
parent7fb2492c3289bd6ad52f19825b313ba9aa114a3f (diff)
Move the KCalCore porting utils to KAlarmCal
KAlarmCal and KAlarm are the only last two components depending heavily on KDateTime. The helper utilities from KCalCore help to bridge them with the QDateTime world.
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/kaevent.cpp53
-rw-r--r--src/karecurrence.cpp58
-rw-r--r--src/utils.cpp155
-rw-r--r--src/utils.h45
5 files changed, 258 insertions, 55 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 99220e9..6a56360 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -15,6 +15,7 @@ set(kalarmcal_LIB_SRCS
collectionattribute.cpp
compatibilityattribute.cpp
eventattribute.cpp
+ utils.cpp
)
ecm_qt_declare_logging_category(kalarmcal_LIB_SRCS HEADER kalarmcal_debug.h IDENTIFIER KALARMCAL_LOG CATEGORY_NAME org.kde.pim.kalarmcal)
@@ -60,6 +61,7 @@ ecm_generate_headers(KAlarmCal_CamelCase_HEADERS
KAEvent
KARecurrence
Repetition
+ Utils
PREFIX KAlarmCal
REQUIRED_HEADERS KAlarmCal_HEADERS
)
diff --git a/src/kaevent.cpp b/src/kaevent.cpp
index 1dd40de..2707da8 100644
--- a/src/kaevent.cpp
+++ b/src/kaevent.cpp
@@ -25,6 +25,8 @@
#include "alarmtext.h"
#include "identities.h"
#include "version.h"
+#include "utils.h"
+
#include <kholidays/holidayregion.h>
#include <kcalcore/memorycalendar.h>
#include <kholidays/holiday.h>
@@ -33,7 +35,6 @@ using namespace KHolidays;
#include <ksystemtimezone.h>
#include <klocalizedstring.h>
#include <kglobal.h>
-#include <kcalcore/utils.h>
#include "kalarmcal_debug.h"
@@ -196,11 +197,11 @@ public:
DateTime mainDateTime(bool withRepeats = false) const
{
return (withRepeats && mNextRepeat && mRepetition)
- ? KCalCore::q2k(mRepetition.duration(mNextRepeat).end(KCalCore::k2q(mNextMainDateTime.kDateTime()))) : mNextMainDateTime;
+ ? q2k(mRepetition.duration(mNextRepeat).end(k2q(mNextMainDateTime.kDateTime()))) : mNextMainDateTime;
}
DateTime mainEndRepeatTime() const
{
- return mRepetition ? KCalCore::q2k(mRepetition.duration().end(KCalCore::k2q(mNextMainDateTime.kDateTime()))) : mNextMainDateTime;
+ return mRepetition ? q2k(mRepetition.duration().end(k2q(mNextMainDateTime.kDateTime()))) : mNextMainDateTime;
}
DateTime deferralLimit(KAEvent::DeferLimitType * = nullptr) const;
KAEvent::Flags flags() const;
@@ -855,7 +856,7 @@ void KAEventPrivate::set(const Event::Ptr &event)
}
}
mNextMainDateTime = readDateTime(event, dateOnly, mStartDateTime);
- mCreatedDateTime = KCalCore::q2k(event->created());
+ mCreatedDateTime = q2k(event->created());
if (dateOnly && !mRepetition.isDaily()) {
mRepetition.set(Duration(mRepetition.intervalDays(), Duration::Days));
}
@@ -902,7 +903,7 @@ void KAEventPrivate::set(const Event::Ptr &event)
Duration deferralOffset;
for (AlarmMap::ConstIterator it = alarmMap.constBegin(); it != alarmMap.constEnd(); ++it) {
const AlarmData &data = it.value();
- const DateTime dateTime = data.alarm->hasStartOffset() ? KCalCore::q2k(data.alarm->startOffset().end(KCalCore::k2q(mNextMainDateTime.effectiveKDateTime()))) : KCalCore::q2k(data.alarm->time());
+ const DateTime dateTime = data.alarm->hasStartOffset() ? q2k(data.alarm->startOffset().end(k2q(mNextMainDateTime.effectiveKDateTime()))) : q2k(data.alarm->time());
switch (data.type) {
case MAIN_ALARM:
mMainExpired = false;
@@ -949,7 +950,7 @@ void KAEventPrivate::set(const Event::Ptr &event)
mDeferral = (data.type == DEFERRED_REMINDER_ALARM) ? REMINDER_DEFERRAL : NORMAL_DEFERRAL;
if (data.timedDeferral) {
// Don't use start-of-day time for applying timed deferral alarm offset
- mDeferralTime = data.alarm->hasStartOffset() ? KCalCore::q2k(data.alarm->startOffset().end(KCalCore::k2q(mNextMainDateTime.calendarKDateTime()))) : KCalCore::q2k(data.alarm->time());
+ mDeferralTime = data.alarm->hasStartOffset() ? q2k(data.alarm->startOffset().end(k2q(mNextMainDateTime.calendarKDateTime()))) : q2k(data.alarm->time());
} else {
mDeferralTime = dateTime;
mDeferralTime.setDateOnly(true);
@@ -1091,10 +1092,10 @@ void KAEventPrivate::set(const Event::Ptr &event)
DateTime dt = mRecurrence->getNextDateTime(mStartDateTime.addDays(-1).kDateTime());
dt.setDateOnly(mStartDateTime.isDateOnly());
if (mDeferralTime.isDateOnly()) {
- mDeferralTime = KCalCore::q2k(deferralOffset.end(KCalCore::k2q(dt.kDateTime())));
+ mDeferralTime = q2k(deferralOffset.end(k2q(dt.kDateTime())));
mDeferralTime.setDateOnly(true);
} else {
- mDeferralTime = KCalCore::q2k(deferralOffset.end(KCalCore::k2q(dt.effectiveKDateTime())));
+ mDeferralTime = q2k(deferralOffset.end(k2q(dt.effectiveKDateTime())));
}
}
if (mDeferral != NO_DEFERRAL) {
@@ -1330,7 +1331,7 @@ bool KAEventPrivate::updateKCalEvent(const Event::Ptr &ev, KAEvent::UidAction ui
* UTC DATE-TIME value. So always use a time relative to DTSTART instead of
* an absolute time.
*/
- ev->setDtStart(KCalCore::k2q(mStartDateTime.calendarKDateTime()));
+ ev->setDtStart(k2q(mStartDateTime.calendarKDateTime()));
ev->setAllDay(false);
ev->setDtEnd(QDateTime());
@@ -1484,7 +1485,7 @@ bool KAEventPrivate::updateKCalEvent(const Event::Ptr &ev, KAEvent::UidAction ui
ev->clearRecurrence();
}
if (mCreatedDateTime.isValid()) {
- ev->setCreated(KCalCore::k2q(mCreatedDateTime));
+ ev->setCreated(k2q(mCreatedDateTime));
}
ev->setReadOnly(readOnly);
ev->endUpdates(); // finally issue an update notification
@@ -3150,7 +3151,7 @@ bool KAEventPrivate::occursAfter(const KDateTime &preDateTime, bool includeRepet
}
if (includeRepetitions && mRepetition) {
- if (preDateTime < KCalCore::q2k(mRepetition.duration().end(KCalCore::k2q(dt)))) {
+ if (preDateTime < q2k(mRepetition.duration().end(k2q(dt)))) {
return true;
}
}
@@ -3180,7 +3181,7 @@ KAEvent::OccurType KAEventPrivate::setNextOccurrence(const KDateTime &preDateTim
// we find the earliest recurrence which has a repetition falling after
// the specified preDateTime.
if (mRepetition) {
- pre = KCalCore::q2k(mRepetition.duration(-mRepetition.count()).end(KCalCore::k2q(preDateTime)));
+ pre = q2k(mRepetition.duration(-mRepetition.count()).end(k2q(preDateTime)));
}
DateTime afterPre; // next recurrence after 'pre'
@@ -3249,7 +3250,7 @@ KAEvent::OccurType KAEventPrivate::nextOccurrence(const KDateTime &preDateTime,
if (!mRepetition) {
includeRepetitions = KAEvent::IGNORE_REPETITION;
} else {
- pre = KCalCore::q2k(mRepetition.duration(-mRepetition.count()).end(KCalCore::k2q(preDateTime)));
+ pre = q2k(mRepetition.duration(-mRepetition.count()).end(k2q(preDateTime)));
}
}
@@ -3269,7 +3270,7 @@ KAEvent::OccurType KAEventPrivate::nextOccurrence(const KDateTime &preDateTime,
// RETURN_REPETITION or ALLOW_FOR_REPETITION
// The next occurrence is a sub-repetition
int repetition = mRepetition.nextRepeatCount(result.kDateTime(), preDateTime);
- const DateTime repeatDT = KCalCore::q2k(mRepetition.duration(repetition).end(KCalCore::k2q(result.kDateTime())));
+ const DateTime repeatDT = q2k(mRepetition.duration(repetition).end(k2q(result.kDateTime())));
if (recurs) {
// We've found a recurrence before the specified date/time, which has
// a sub-repetition after the date/time.
@@ -3283,7 +3284,7 @@ KAEvent::OccurType KAEventPrivate::nextOccurrence(const KDateTime &preDateTime,
if (includeRepetitions == KAEvent::RETURN_REPETITION && result <= preDateTime) {
// The next occurrence is a sub-repetition
repetition = mRepetition.nextRepeatCount(result.kDateTime(), preDateTime);
- result = KCalCore::q2k(mRepetition.duration(repetition).end(KCalCore::k2q(result.kDateTime())));
+ result = q2k(mRepetition.duration(repetition).end(k2q(result.kDateTime())));
type = static_cast<KAEvent::OccurType>(type | KAEvent::OCCURRENCE_REPEAT);
}
return type;
@@ -3349,7 +3350,7 @@ KAEvent::OccurType KAEventPrivate::previousOccurrence(const KDateTime &afterDate
// Find the latest repetition which is before the specified time.
const int repetition = mRepetition.previousRepeatCount(result.effectiveKDateTime(), afterDateTime);
if (repetition > 0) {
- result = KCalCore::q2k(mRepetition.duration(qMin(repetition, mRepetition.count())).end(KCalCore::k2q(result.kDateTime())));
+ result = q2k(mRepetition.duration(qMin(repetition, mRepetition.count())).end(k2q(result.kDateTime())));
return static_cast<KAEvent::OccurType>(type | KAEvent::OCCURRENCE_REPEAT);
}
}
@@ -3840,7 +3841,7 @@ void KAEventPrivate::dumpDebug() const
*/
DateTime KAEventPrivate::readDateTime(const Event::Ptr &event, bool dateOnly, DateTime &start)
{
- start = KCalCore::q2k(event->dtStart());
+ start = q2k(event->dtStart());
if (dateOnly) {
// A date-only event is indicated by the X-KDE-KALARM-FLAGS:DATE property, not
// by a date-only start date/time (for the reasons given in updateKCalEvent()).
@@ -5052,12 +5053,12 @@ bool KAEvent::convertKCalEvents(const Calendar::Ptr &calendar, int calendarVersi
if (adjustSummerTime) {
// The calendar file was written by the KDE 3.0.0 version of KAlarm 0.5.7.
// Summer time was ignored when converting to UTC.
- KDateTime dt = KCalCore::q2k(alarm->time());
+ KDateTime dt = q2k(alarm->time());
const time_t t = dt.toTime_t();
const struct tm *dtm = localtime(&t);
if (dtm->tm_isdst) {
dt = dt.addSecs(-3600);
- alarm->setTime(KCalCore::k2q(dt));
+ alarm->setTime(k2q(dt));
}
}
}
@@ -5244,7 +5245,7 @@ bool KAEvent::convertKCalEvents(const Calendar::Ptr &calendar, int calendarVersi
*/
const QStringList flags = event->customProperty(KACalendar::APPNAME, KAEventPrivate::FLAGS_PROPERTY).split(KAEventPrivate::SC, QString::SkipEmptyParts);
const bool dateOnly = flags.contains(KAEventPrivate::DATE_ONLY_FLAG);
- KDateTime startDateTime = KCalCore::q2k(event->dtStart(), dateOnly);
+ KDateTime startDateTime = q2k(event->dtStart(), dateOnly);
if (dateOnly) {
startDateTime.setDateOnly(true);
}
@@ -5282,7 +5283,7 @@ bool KAEvent::convertKCalEvents(const Calendar::Ptr &calendar, int calendarVersi
// All main alarms are supposed to be at the same time, so
// don't readjust the event's time for subsequent main alarms.
mainExpired = false;
- nextMainDateTime = KCalCore::q2k(alarm->time());
+ nextMainDateTime = q2k(alarm->time());
nextMainDateTime.setDateOnly(dateOnly);
nextMainDateTime = nextMainDateTime.toTimeSpec(startDateTime);
if (nextMainDateTime != startDateTime) {
@@ -5300,7 +5301,7 @@ bool KAEvent::convertKCalEvents(const Calendar::Ptr &calendar, int calendarVersi
// It's an expired recurrence.
// Set the alarm offset relative to the first actual occurrence
// (taking account of possible exceptions).
- KDateTime dt = KCalCore::q2k(event->recurrence()->getNextDateTime(KCalCore::k2q(startDateTime).addDays(-1)));
+ KDateTime dt = q2k(event->recurrence()->getNextDateTime(k2q(startDateTime).addDays(-1)));
dt.setDateOnly(dateOnly);
adjustment = startDateTime.secsTo(dt);
} else {
@@ -5488,10 +5489,10 @@ bool KAEventPrivate::convertStartOfDay(const Event::Ptr &event)
const QStringList flags = event->customProperty(KACalendar::APPNAME, KAEventPrivate::FLAGS_PROPERTY).split(KAEventPrivate::SC, QString::SkipEmptyParts);
if (flags.indexOf(KAEventPrivate::DATE_ONLY_FLAG) >= 0) {
// It's an untimed event, so fix it
- const KDateTime oldDt = KCalCore::q2k(event->dtStart());
+ const KDateTime oldDt = q2k(event->dtStart());
const int adjustment = oldDt.time().secsTo(midnight);
if (adjustment) {
- event->setDtStart(QDateTime(oldDt.date(), midnight, KCalCore::specToZone(oldDt.timeSpec())));
+ event->setDtStart(QDateTime(oldDt.date(), midnight, specToZone(oldDt.timeSpec())));
int deferralOffset = 0;
AlarmMap alarmMap;
readAlarms(event, &alarmMap);
@@ -5528,7 +5529,7 @@ bool KAEventPrivate::convertStartOfDay(const Event::Ptr &event)
}
if ((data.type & DEFERRED_ALARM) && !data.timedDeferral) {
// Found a date-only deferral alarm, so adjust its time
- QDateTime altime = data.alarm->startOffset().end(KCalCore::k2q(nextMainDateTime));
+ QDateTime altime = data.alarm->startOffset().end(k2q(nextMainDateTime));
altime.setTime(midnight);
deferralOffset = data.alarm->startOffset().asSeconds();
newDeferralOffset = event->dtStart().secsTo(altime);
@@ -5650,7 +5651,7 @@ KAAlarm::Type KAAlarm::type() const
DateTime KAAlarm::dateTime(bool withRepeats) const
{
return (withRepeats && d->mNextRepeat && d->mRepetition)
- ? KCalCore::q2k(d->mRepetition.duration(d->mNextRepeat).end(KCalCore::k2q(d->mNextMainDateTime.kDateTime())))
+ ? q2k(d->mRepetition.duration(d->mNextRepeat).end(k2q(d->mNextMainDateTime.kDateTime())))
: d->mNextMainDateTime;
}
diff --git a/src/karecurrence.cpp b/src/karecurrence.cpp
index b4391bc..f334db9 100644
--- a/src/karecurrence.cpp
+++ b/src/karecurrence.cpp
@@ -21,10 +21,10 @@
*/
#include "karecurrence.h"
+#include "utils.h"
#include <kcalcore/recurrence.h>
#include <kcalcore/icalformat.h>
-#include <kcalcore/utils.h>
#include <klocalizedstring.h>
#include "kalarmcal_debug.h"
@@ -238,7 +238,7 @@ bool KARecurrence::Private::init(RecurrenceRule::PeriodType recurType, int freq,
} else if (dateOnly) {
mRecurrence.setEndDate(end.date());
} else {
- mRecurrence.setEndDateTime(KCalCore::k2q(end));
+ mRecurrence.setEndDateTime(k2q(end));
}
KDateTime startdt = start;
if (recurType == RecurrenceRule::rYearly
@@ -258,7 +258,7 @@ bool KARecurrence::Private::init(RecurrenceRule::PeriodType recurType, int freq,
}
mFeb29Type = feb29Type;
}
- mRecurrence.setStartDateTime(KCalCore::k2q(startdt), dateOnly); // sets recurrence all-day if date-only
+ mRecurrence.setStartDateTime(k2q(startdt), dateOnly); // sets recurrence all-day if date-only
return true;
}
@@ -485,7 +485,7 @@ void KARecurrence::Private::writeRecurrence(const KARecurrence *q, Recurrence &r
if (count) {
recur.setDuration(count);
} else {
- recur.setEndDateTime(KCalCore::k2q(endDateTime()));
+ recur.setEndDateTime(k2q(endDateTime()));
}
switch (q->type()) {
case DAILY:
@@ -525,7 +525,7 @@ void KARecurrence::Private::writeRecurrence(const KARecurrence *q, Recurrence &r
rrule2->setStartDt(mRecurrence.startDateTime());
rrule2->setAllDay(mRecurrence.allDay());
if (!count) {
- rrule2->setEndDt(KCalCore::k2q(endDateTime()));
+ rrule2->setEndDt(k2q(endDateTime()));
}
if (mFeb29Type == Feb29_Mar1) {
QList<int> ds;
@@ -564,14 +564,14 @@ void KARecurrence::Private::writeRecurrence(const KARecurrence *q, Recurrence &r
* is not lost should the user later change the recurrence count.
*/
const KDateTime end = endDateTime();
- const int count1 = rrule1->durationTo(KCalCore::k2q(end))
+ const int count1 = rrule1->durationTo(k2q(end))
- (rrule1->recursOn(mRecurrence.startDate(), mRecurrence.startDateTime().timeZone()) ? 0 : 1);
if (count1 > 0) {
rrule1->setDuration(count1);
} else {
rrule1->setEndDt(mRecurrence.startDateTime());
}
- const int count2 = rrule2->durationTo(KCalCore::k2q(end))
+ const int count2 = rrule2->durationTo(k2q(end))
- (rrule2->recursOn(mRecurrence.startDate(), mRecurrence.startDateTime().timeZone()) ? 0 : 1);
if (count2 > 0) {
rrule2->setDuration(count2);
@@ -591,7 +591,7 @@ void KARecurrence::Private::writeRecurrence(const KARecurrence *q, Recurrence &r
KDateTime KARecurrence::startDateTime() const
{
- return KCalCore::q2k(d->mRecurrence.startDateTime());
+ return q2k(d->mRecurrence.startDateTime());
}
QDate KARecurrence::startDate() const
@@ -601,7 +601,7 @@ QDate KARecurrence::startDate() const
void KARecurrence::setStartDateTime(const KDateTime &dt, bool dateOnly)
{
- d->mRecurrence.setStartDateTime(KCalCore::k2q(dt), dateOnly);
+ d->mRecurrence.setStartDateTime(k2q(dt), dateOnly);
if (dateOnly) {
d->mRecurrence.setAllDay(true);
}
@@ -623,7 +623,7 @@ KDateTime KARecurrence::Private::endDateTime() const
* (count = 0), or it ends on the start date (count = 1).
* So just use the normal KCal end date calculation.
*/
- return KCalCore::q2k(mRecurrence.endDateTime());
+ return q2k(mRecurrence.endDateTime());
}
/* Create a temporary recurrence rule to find the end date.
@@ -633,7 +633,7 @@ KDateTime KARecurrence::Private::endDateTime() const
*/
RecurrenceRule *rrule = new RecurrenceRule();
rrule->setRecurrenceType(RecurrenceRule::rYearly);
- KDateTime dt = KCalCore::q2k(mRecurrence.startDateTime());
+ KDateTime dt = q2k(mRecurrence.startDateTime());
QDate da = dt.date();
switch (da.day()) {
case 29:
@@ -658,7 +658,7 @@ KDateTime KARecurrence::Private::endDateTime() const
break;
}
dt.setDate(da);
- rrule->setStartDt(KCalCore::k2q(dt));
+ rrule->setStartDt(k2q(dt));
rrule->setAllDay(mRecurrence.allDay());
rrule->setFrequency(mRecurrence.frequency());
rrule->setDuration(mRecurrence.duration());
@@ -666,7 +666,7 @@ KDateTime KARecurrence::Private::endDateTime() const
ds.append(28);
rrule->setByMonthDays(ds);
rrule->setByMonths(mRecurrence.defaultRRuleConst()->byMonths());
- dt = KCalCore::q2k(rrule->endDt());
+ dt = q2k(rrule->endDt());
delete rrule;
// We've found the end date for a recurrence on the 28th. Unless that date
@@ -693,7 +693,7 @@ void KARecurrence::setEndDate(const QDate &endDate)
void KARecurrence::setEndDateTime(const KDateTime &endDateTime)
{
- d->mRecurrence.setEndDateTime(KCalCore::k2q(endDateTime));
+ d->mRecurrence.setEndDateTime(k2q(endDateTime));
}
bool KARecurrence::allDay() const
@@ -801,10 +801,10 @@ KDateTime KARecurrence::getNextDateTime(const KDateTime &preDateTime) const
case ANNUAL_POS: {
Recurrence recur;
writeRecurrence(recur);
- return KCalCore::q2k(recur.getNextDateTime(KCalCore::k2q(preDateTime)));
+ return q2k(recur.getNextDateTime(k2q(preDateTime)));
}
default:
- return KCalCore::q2k(d->mRecurrence.getNextDateTime(KCalCore::k2q(preDateTime)));
+ return q2k(d->mRecurrence.getNextDateTime(k2q(preDateTime)));
}
}
@@ -818,10 +818,10 @@ KDateTime KARecurrence::getPreviousDateTime(const KDateTime &afterDateTime) cons
case ANNUAL_POS: {
Recurrence recur;
writeRecurrence(recur);
- return KCalCore::q2k(recur.getPreviousDateTime(KCalCore::k2q(afterDateTime)));
+ return q2k(recur.getPreviousDateTime(k2q(afterDateTime)));
}
default:
- return KCalCore::q2k(d->mRecurrence.getPreviousDateTime(KCalCore::k2q(afterDateTime)));
+ return q2k(d->mRecurrence.getPreviousDateTime(k2q(afterDateTime)));
}
}
@@ -831,7 +831,7 @@ KDateTime KARecurrence::getPreviousDateTime(const KDateTime &afterDateTime) cons
*/
bool KARecurrence::recursOn(const QDate &dt, const KDateTime::Spec &timeSpec) const
{
- if (!d->mRecurrence.recursOn(dt, KCalCore::specToZone(timeSpec))) {
+ if (!d->mRecurrence.recursOn(dt, specToZone(timeSpec))) {
return false;
}
if (dt != d->mRecurrence.startDate()) {
@@ -844,7 +844,7 @@ bool KARecurrence::recursOn(const QDate &dt, const KDateTime::Spec &timeSpec) co
}
const RecurrenceRule::List rulelist = d->mRecurrence.rRules();
for (int rri = 0, rrend = rulelist.count(); rri < rrend; ++rri)
- if (rulelist[rri]->recursOn(dt, KCalCore::specToZone(timeSpec))) {
+ if (rulelist[rri]->recursOn(dt, specToZone(timeSpec))) {
return true;
}
const auto dtlist = d->mRecurrence.rDateTimes();
@@ -857,17 +857,17 @@ bool KARecurrence::recursOn(const QDate &dt, const KDateTime::Spec &timeSpec) co
bool KARecurrence::recursAt(const KDateTime &dt) const
{
- return d->mRecurrence.recursAt(KCalCore::k2q(dt));
+ return d->mRecurrence.recursAt(k2q(dt));
}
TimeList KARecurrence::recurTimesOn(const QDate &date, const KDateTime::Spec &timeSpec) const
{
- return d->mRecurrence.recurTimesOn(date, KCalCore::specToZone(timeSpec));
+ return d->mRecurrence.recurTimesOn(date, specToZone(timeSpec));
}
DateTimeList KARecurrence::timesInInterval(const KDateTime &start, const KDateTime &end) const
{
- const auto l = d->mRecurrence.timesInInterval(KCalCore::k2q(start), KCalCore::k2q(end));
+ const auto l = d->mRecurrence.timesInInterval(k2q(start), k2q(end));
DateTimeList rv;
rv.reserve(l.size());
for (const auto &qdt : l) {
@@ -898,7 +898,7 @@ void KARecurrence::setDuration(int duration)
int KARecurrence::durationTo(const KDateTime &dt) const
{
- return d->mRecurrence.durationTo(KCalCore::k2q(dt));
+ return d->mRecurrence.durationTo(k2q(dt));
}
int KARecurrence::durationTo(const QDate &date) const
@@ -935,8 +935,8 @@ int KARecurrence::Private::combineDurations(const RecurrenceRule *rrule1, const
count1 = count2 = 0;
}
// Get the two rules sorted by end date.
- KDateTime end1 = KCalCore::q2k(rrule1->endDt());
- KDateTime end2 = KCalCore::q2k(rrule2->endDt());
+ KDateTime end1 = q2k(rrule1->endDt());
+ KDateTime end2 = q2k(rrule2->endDt());
if (end1.date() == end2.date()) {
end = end1.date();
return count1 + count2;
@@ -959,7 +959,7 @@ int KARecurrence::Private::combineDurations(const RecurrenceRule *rrule1, const
// Get the date of the next occurrence after the end of the earlier ending rule
RecurrenceRule rr(*rr1);
rr.setDuration(-1);
- KDateTime next1(KCalCore::q2k(rr.getNextDate(KCalCore::k2q(end1))));
+ KDateTime next1(q2k(rr.getNextDate(k2q(end1))));
next1.setDateOnly(true);
if (!next1.isValid()) {
end = end1.date();
@@ -971,7 +971,7 @@ int KARecurrence::Private::combineDurations(const RecurrenceRule *rrule1, const
end = end2.date();
return count1 + count2;
}
- const QDate prev2 = rr2->getPreviousDate(KCalCore::k2q(next1)).date();
+ const QDate prev2 = rr2->getPreviousDate(k2q(next1)).date();
end = (prev2 > end1.date()) ? prev2 : end1.date();
}
if (count2) {
@@ -1226,7 +1226,7 @@ void KARecurrence::setExDates(const DateList &exdates)
void KARecurrence::addExDateTime(const KDateTime &exdate)
{
- d->mRecurrence.addExDateTime(KCalCore::k2q(exdate));
+ d->mRecurrence.addExDateTime(k2q(exdate));
}
void KARecurrence::addExDate(const QDate &exdate)
diff --git a/src/utils.cpp b/src/utils.cpp
new file mode 100644
index 0000000..c16c556
--- /dev/null
+++ b/src/utils.cpp
@@ -0,0 +1,155 @@
+/*
+ This file is part of the kalarmcal library.
+
+ Copyright (c) 2017 Daniel Vrátil <[email protected]>
+
+ 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 "utils.h"
+
+#include <KTimeZone>
+#include <KSystemTimeZones>
+#include <QDebug>
+
+KDateTime::Spec KAlarmCal::zoneToSpec(const QTimeZone& zone)
+{
+ if (!zone.isValid())
+ return KDateTime::Invalid;
+ if (zone == QTimeZone::utc())
+ return KDateTime::UTC;
+ if (zone == QTimeZone::systemTimeZone())
+ return KDateTime::LocalZone;
+ if (zone.id().startsWith("UTC")) {
+ return KDateTime::Spec(KDateTime::OffsetFromUTC, zone.offsetFromUtc(QDateTime::currentDateTimeUtc()));
+ } else {
+ return KSystemTimeZones::zone(QString::fromLatin1(zone.id()));
+ }
+}
+
+namespace {
+
+QTimeZone resolveCustomTZ(const KTimeZone &ktz)
+{
+ // First, let's try Microsoft
+ const auto msIana = QTimeZone::windowsIdToDefaultIanaId(ktz.name().toUtf8());
+ if (!msIana.isEmpty()) {
+ return QTimeZone(msIana);
+ }
+
+ int standardUtcOffset = 0;
+ bool matched = false;
+ const auto phases = ktz.phases();
+ for (const auto &phase : phases) {
+ if (!phase.isDst()) {
+ standardUtcOffset = phase.utcOffset();
+ matched = true;
+ break;
+ }
+ }
+ if (!matched) {
+ standardUtcOffset = ktz.currentOffset(Qt::UTC);
+ }
+
+ const auto candidates = QTimeZone::availableTimeZoneIds(standardUtcOffset);
+ QMap<int, QTimeZone> matchedCandidates;
+ for (const auto &tzid : candidates) {
+ const QTimeZone candidate(tzid);
+ // This would be a fallback
+ if (candidate.hasTransitions() != ktz.hasTransitions()) {
+ matchedCandidates.insert(0, candidate);
+ continue;
+ }
+
+ // Without transitions, we can't do any more precise matching, so just
+ // accept this candidate and be done with it
+ if (!candidate.hasTransitions() && !ktz.hasTransitions()) {
+ return candidate;
+ }
+
+ // Calculate how many transitions this candidate shares with the ktz.
+ // The candidate with the most matching transitions will win.
+ const auto transitions = ktz.transitions(QDateTime(), QDateTime::currentDateTimeUtc());
+ int matchedTransitions = 0;
+ for (auto it = transitions.rbegin(), end = transitions.rend(); it != end; ++it) {
+ const auto &transition = *it;
+ const QTimeZone::OffsetDataList candidateTransitions = candidate.transitions(transition.time(), transition.time());
+ if (candidateTransitions.isEmpty()) {
+ continue;
+ }
+ const auto candidateTransition = candidateTransitions[0];
+ const auto abvs = transition.phase().abbreviations();
+ for (const auto &abv : abvs) {
+ if (candidateTransition.abbreviation == QString::fromUtf8(abv)) {
+ ++matchedTransitions;
+ break;
+ }
+ }
+ }
+ matchedCandidates.insert(matchedTransitions, candidate);
+ }
+
+ if (!matchedCandidates.isEmpty()) {
+ return matchedCandidates.value(matchedCandidates.lastKey());
+ }
+
+ return {};
+}
+
+}
+
+QTimeZone KAlarmCal::specToZone(const KDateTime::Spec &spec)
+{
+ switch (spec.type()) {
+ case KDateTime::Invalid:
+ return QTimeZone();
+ case KDateTime::LocalZone:
+ case KDateTime::ClockTime:
+ return QTimeZone::systemTimeZone();
+ case KDateTime::UTC:
+ return QTimeZone::utc();
+ default: {
+ auto tz = QTimeZone(spec.timeZone().name().toUtf8());
+ if (!tz.isValid()) {
+ tz = resolveCustomTZ(spec.timeZone());
+ qDebug() << "Resolved" << spec.timeZone().name() << "to" << tz.id();
+ }
+ return tz;
+ }
+ }
+
+ return QTimeZone::systemTimeZone();
+}
+
+QDateTime KAlarmCal::k2q(const KDateTime &kdt)
+{
+ if (kdt.isValid()) {
+ return QDateTime(kdt.date(), kdt.time(), specToZone(kdt.timeSpec()));
+ } else {
+ return QDateTime();
+ }
+}
+
+KDateTime KAlarmCal::q2k(const QDateTime &qdt, bool allDay)
+{
+ if (qdt.isValid()) {
+ KDateTime kdt(qdt.date(), qdt.time(), zoneToSpec(qdt.timeZone()));
+ kdt.setDateOnly(allDay && qdt.time() == QTime(0, 0, 0));
+ return kdt;
+ } else {
+ return KDateTime();
+ }
+}
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..11749b1
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,45 @@
+/*
+ This file is part of the kalarmcal library.
+
+ Copyright (c) 2017 Daniel Vrátil <[email protected]>
+
+ 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.
+*/
+
+#ifndef KALARMCAL_UTILS_H_
+#define KALARMCAL_UTILS_H_
+
+#include <KDateTime>
+#include <QDateTime>
+#include <QTimeZone>
+
+#include "kalarmcal_export.h"
+
+namespace KAlarmCal {
+
+/** Convert a QTimeZone to a KDateTime::Spec */
+KALARMCAL_EXPORT KDateTime::Spec zoneToSpec(const QTimeZone &zone);
+
+/** Convert a QTimeZone to a KDateTime::Spec */
+KALARMCAL_EXPORT QTimeZone specToZone(const KDateTime::Spec &spec);
+
+/** Convert KDateTime to QDateTime, correctly preserves timespec */
+KALARMCAL_EXPORT QDateTime k2q(const KDateTime &kdt);
+KALARMCAL_EXPORT KDateTime q2k(const QDateTime &qdt, bool isAllDay = false);
+
+}
+
+#endif