[packages/kf5-kcalendarcore] Rel 3

arekm arekm at pld-linux.org
Sun Aug 23 10:52:28 CEST 2026


commit 6039186709534b656310b73d48837ee6cf6ef172
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Sun Aug 23 10:52:05 2026 +0200

    Rel 3

 kcalendarcore-bysecond-dup.patch |  51 ++++
 kcalendarcore-libical4.patch     | 634 +++++++++++++++++++++++++++++++++++++++
 kf5-kcalendarcore.spec           |  12 +-
 3 files changed, 694 insertions(+), 3 deletions(-)
---
diff --git a/kf5-kcalendarcore.spec b/kf5-kcalendarcore.spec
index 0503d94..15111ea 100644
--- a/kf5-kcalendarcore.spec
+++ b/kf5-kcalendarcore.spec
@@ -7,18 +7,22 @@
 Summary:	kcalendarcore
 Name:		kf5-%{kfname}
 Version:	5.116.0
-Release:	2
+Release:	3
 License:	GPL v2+/LGPL v2.1+
 Group:		X11/Libraries
 Source0:	https://download.kde.org/stable/frameworks/%{kdeframever}/%{kfname}-%{version}.tar.xz
 # Source0-md5:	17c2890bc78ebf8547cd90b8c357d41d
+Patch0:		%{kfname}-libical4.patch
+Patch1:		%{kfname}-bysecond-dup.patch
 URL:		http://www.kde.org/
 BuildRequires:	Qt5Core-devel >= %{qtver}
 BuildRequires:	Qt5Gui-devel
-BuildRequires:	Qt5Test-devel >= 5.9.0
+%if %{with tests}
+BuildRequires:	Qt5Test-devel >= %{qtver}
+%endif
 BuildRequires:	cmake >= 3.16.0
 BuildRequires:	kf5-extra-cmake-modules >= 5.53.0
-BuildRequires:	libical-devel >= 2.0
+BuildRequires:	libical-devel >= 3.0
 BuildRequires:	ninja
 BuildRequires:	qt5-build >= %{qtver}
 BuildRequires:	rpmbuild(macros) >= 1.164
@@ -53,6 +57,8 @@ Pliki nagłówkowe dla programistów używających %{kfname}.
 
 %prep
 %setup -q -n %{kfname}-%{version}
+%patch -P0 -p1
+%patch -P1 -p1
 
 %build
 %cmake -B build \
diff --git a/kcalendarcore-bysecond-dup.patch b/kcalendarcore-bysecond-dup.patch
new file mode 100644
index 0000000..eef2c5c
--- /dev/null
+++ b/kcalendarcore-bysecond-dup.patch
@@ -0,0 +1,51 @@
+diff -urN kcalendarcore-5.116.0.orig/src/icalformat_p.cpp kcalendarcore-5.116.0/src/icalformat_p.cpp
+--- kcalendarcore-5.116.0.orig/src/icalformat_p.cpp	2026-08-23 03:04:52.684385455 +0200
++++ kcalendarcore-5.116.0/src/icalformat_p.cpp	2026-08-23 03:12:16.843234356 +0200
+@@ -921,14 +921,12 @@
+     if (!bys.isEmpty()) {
+         index = 0;
+ #if ICAL_CHECK_VERSION(3, 99, 99)
+-        icalrecur_resize_by(&r.by[ICAL_BY_SECOND], static_cast<short>(2 * bys.count()));
++        icalrecur_resize_by(&r.by[ICAL_BY_SECOND], static_cast<short>(bys.count()));
+ #endif
+         for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+ #if ICAL_CHECK_VERSION(3, 99, 99)
+-            r.by[ICAL_BY_SECOND].data[index++] = *it;
+             r.by[ICAL_BY_SECOND].data[index++] = static_cast<short>(*it);
+ #else
+-            r.by_second[index++] = *it;
+             r.by_second[index++] = static_cast<short>(*it);
+ #endif
+         }
+@@ -938,14 +936,12 @@
+     if (!bys.isEmpty()) {
+         index = 0;
+ #if ICAL_CHECK_VERSION(3, 99, 99)
+-        icalrecur_resize_by(&r.by[ICAL_BY_MINUTE], static_cast<short>(2 * bys.count()));
++        icalrecur_resize_by(&r.by[ICAL_BY_MINUTE], static_cast<short>(bys.count()));
+ #endif
+         for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+ #if ICAL_CHECK_VERSION(3, 99, 99)
+-            r.by[ICAL_BY_MINUTE].data[index++] = *it;
+             r.by[ICAL_BY_MINUTE].data[index++] = static_cast<short>(*it);
+ #else
+-            r.by_minute[index++] = *it;
+             r.by_minute[index++] = static_cast<short>(*it);
+ #endif
+         }
+@@ -955,14 +951,12 @@
+     if (!bys.isEmpty()) {
+         index = 0;
+ #if ICAL_CHECK_VERSION(3, 99, 99)
+-        icalrecur_resize_by(&r.by[ICAL_BY_HOUR], static_cast<short>(2 * bys.count()));
++        icalrecur_resize_by(&r.by[ICAL_BY_HOUR], static_cast<short>(bys.count()));
+ #endif
+         for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+ #if ICAL_CHECK_VERSION(3, 99, 99)
+-            r.by[ICAL_BY_HOUR].data[index++] = *it;
+             r.by[ICAL_BY_HOUR].data[index++] = static_cast<short>(*it);
+ #else
+-            r.by_hour[index++] = *it;
+             r.by_hour[index++] = static_cast<short>(*it);
+ #endif
+         }
diff --git a/kcalendarcore-libical4.patch b/kcalendarcore-libical4.patch
new file mode 100644
index 0000000..38ab08c
--- /dev/null
+++ b/kcalendarcore-libical4.patch
@@ -0,0 +1,634 @@
+diff -urN kcalendarcore-5.116.0.orig/src/icalformat.cpp kcalendarcore-5.116.0/src/icalformat.cpp
+--- kcalendarcore-5.116.0.orig/src/icalformat.cpp	2024-05-04 13:37:43.000000000 +0200
++++ kcalendarcore-5.116.0/src/icalformat.cpp	2026-08-23 03:03:15.774299037 +0200
+@@ -308,7 +308,11 @@
+             if (!tz) {
+                 qCritical() << "bad time zone";
+             } else {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++                component = icalcomponent_clone(icaltimezone_get_component(tz));
++#else
+                 component = icalcomponent_new_clone(icaltimezone_get_component(tz));
++#endif
+                 icalcomponent_add_component(calendar, component);
+                 icaltimezone_free(tz, 1);
+             }
+@@ -378,7 +382,18 @@
+ QString ICalFormat::toString(RecurrenceRule *recurrence)
+ {
+     Q_D(ICalFormat);
+-    icalproperty *property = icalproperty_new_rrule(d->mImpl.writeRecurrenceRule(recurrence));
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    struct icalrecurrencetype *recur = d->mImpl.writeRecurrenceRule(recurrence);
++    if (!recur) {
++        return QString();
++    }
++#else
++    struct icalrecurrencetype recur = d->mImpl.writeRecurrenceRule(recurrence);
++#endif
++    icalproperty *property = icalproperty_new_rrule(recur);
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    icalrecurrencetype_unref(recur);
++#endif
+     QString text = QString::fromUtf8(icalproperty_as_ical_string(property));
+     icalproperty_free(property);
+     return text;
+@@ -401,15 +416,34 @@
+     }
+     bool success = true;
+     icalerror_clear_errno();
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    struct icalrecurrencetype *recur = icalrecurrencetype_new_from_string(rrule.toLatin1().constData());
++#else
+     struct icalrecurrencetype recur = icalrecurrencetype_from_string(rrule.toLatin1().constData());
++#endif
+     if (icalerrno != ICAL_NO_ERROR) {
+         qCDebug(KCALCORE_LOG) << "Recurrence parsing error:" << icalerror_strerror(icalerrno);
+         success = false;
+     }
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    // a rule without FREQ is rejected by returning nullptr, leaving icalerrno untouched
++    if (!recur) {
++        success = false;
++    }
++#endif
+ 
+     if (success) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        d->mImpl.readRecurrence(*recur, recurrence);
++#else
+         d->mImpl.readRecurrence(recur, recurrence);
++#endif
++    }
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    if (recur) {
++        icalrecurrencetype_unref(recur);
+     }
++#endif
+ 
+     return success;
+ }
+diff -urN kcalendarcore-5.116.0.orig/src/icalformat_p.cpp kcalendarcore-5.116.0/src/icalformat_p.cpp
+--- kcalendarcore-5.116.0.orig/src/icalformat_p.cpp	2024-05-04 13:37:43.000000000 +0200
++++ kcalendarcore-5.116.0/src/icalformat_p.cpp	2026-08-23 03:04:52.684385455 +0200
+@@ -479,9 +479,17 @@
+ 
+     // geo
+     if (incidence->hasGeo()) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        // libical 4 stores GEO as strings and no longer formats the doubles itself;
++        // 'f'/6 reproduces the "%f;%f" output libical 3 wrote for the same coordinates
++        icalgeotype geo = {"", ""};
++        strncpy(geo.lat, QString::number(incidence->geoLatitude(), 'f', 6).toLatin1().constData(), ICAL_GEO_LEN - 1);
++        strncpy(geo.lon, QString::number(incidence->geoLongitude(), 'f', 6).toLatin1().constData(), ICAL_GEO_LEN - 1);
++#else
+         icalgeotype geo;
+         geo.lat = incidence->geoLatitude();
+         geo.lon = incidence->geoLongitude();
++#endif
+         icalcomponent_add_property(parent, icalproperty_new_geo(geo));
+     }
+ 
+@@ -512,12 +520,30 @@
+ 
+     const RecurrenceRule::List rrules(incidence->recurrence()->rRules());
+     for (RecurrenceRule *rule : rrules) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        struct icalrecurrencetype *recur = writeRecurrenceRule(rule);
++        if (!recur) {
++            break;
++        }
++        icalcomponent_add_property(parent, icalproperty_new_rrule(recur));
++        icalrecurrencetype_unref(recur);
++#else
+         icalcomponent_add_property(parent, icalproperty_new_rrule(writeRecurrenceRule(rule)));
++#endif
+     }
+ 
+     const RecurrenceRule::List exrules(incidence->recurrence()->exRules());
+     for (RecurrenceRule *rule : exrules) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        struct icalrecurrencetype *recur = writeRecurrenceRule(rule);
++        if (!recur) {
++            break;
++        }
++        icalcomponent_add_property(parent, icalproperty_new_exrule(recur));
++        icalrecurrencetype_unref(recur);
++#else
+         icalcomponent_add_property(parent, icalproperty_new_exrule(writeRecurrenceRule(rule)));
++#endif
+     }
+ 
+     DateList dateList = incidence->recurrence()->exDates();
+@@ -841,10 +867,23 @@
+     return p;
+ }
+ 
++#if ICAL_CHECK_VERSION(3, 99, 99)
++icalrecurrencetype *ICalFormatImpl::writeRecurrenceRule(RecurrenceRule *recur)
++#else
+ icalrecurrencetype ICalFormatImpl::writeRecurrenceRule(RecurrenceRule *recur)
++#endif
+ {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    // libical 4 made the rule refcounted; the reference taken here is handed to the caller
++    icalrecurrencetype *rp = icalrecurrencetype_new();
++    if (!rp) {
++        return nullptr;
++    }
++    icalrecurrencetype &r = *rp;
++#else
+     icalrecurrencetype r;
+     icalrecurrencetype_clear(&r);
++#endif
+ 
+     switch (recur->recurrenceType()) {
+     case RecurrenceRule::rSecondly:
+@@ -879,70 +918,155 @@
+ 
+     // Now write out the BY* parts:
+     bys = recur->bySeconds();
+-    index = 0;
+-    for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+-        r.by_second[index++] = *it;
+-        r.by_second[index++] = static_cast<short>(*it);
++    if (!bys.isEmpty()) {
++        index = 0;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        icalrecur_resize_by(&r.by[ICAL_BY_SECOND], static_cast<short>(2 * bys.count()));
++#endif
++        for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++            r.by[ICAL_BY_SECOND].data[index++] = *it;
++            r.by[ICAL_BY_SECOND].data[index++] = static_cast<short>(*it);
++#else
++            r.by_second[index++] = *it;
++            r.by_second[index++] = static_cast<short>(*it);
++#endif
++        }
+     }
+ 
+     bys = recur->byMinutes();
+-    index = 0;
+-    for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+-        r.by_minute[index++] = *it;
+-        r.by_minute[index++] = static_cast<short>(*it);
++    if (!bys.isEmpty()) {
++        index = 0;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        icalrecur_resize_by(&r.by[ICAL_BY_MINUTE], static_cast<short>(2 * bys.count()));
++#endif
++        for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++            r.by[ICAL_BY_MINUTE].data[index++] = *it;
++            r.by[ICAL_BY_MINUTE].data[index++] = static_cast<short>(*it);
++#else
++            r.by_minute[index++] = *it;
++            r.by_minute[index++] = static_cast<short>(*it);
++#endif
++        }
+     }
+ 
+     bys = recur->byHours();
+-    index = 0;
+-    for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+-        r.by_hour[index++] = *it;
+-        r.by_hour[index++] = static_cast<short>(*it);
++    if (!bys.isEmpty()) {
++        index = 0;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        icalrecur_resize_by(&r.by[ICAL_BY_HOUR], static_cast<short>(2 * bys.count()));
++#endif
++        for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++            r.by[ICAL_BY_HOUR].data[index++] = *it;
++            r.by[ICAL_BY_HOUR].data[index++] = static_cast<short>(*it);
++#else
++            r.by_hour[index++] = *it;
++            r.by_hour[index++] = static_cast<short>(*it);
++#endif
++        }
+     }
+ 
+     bys = recur->byMonthDays();
+-    index = 0;
+-    for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+-        short dShort = static_cast<short>((*it) * 8);
+-        r.by_month_day[index++] = static_cast<short>(icalrecurrencetype_day_position(dShort));
++    if (!bys.isEmpty()) {
++        index = 0;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        icalrecur_resize_by(&r.by[ICAL_BY_MONTH_DAY], static_cast<short>(bys.count()));
++#endif
++        for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++            short dShort = static_cast<short>((*it) * 8);
++            r.by[ICAL_BY_MONTH_DAY].data[index++] = static_cast<short>(icalrecurrencetype_day_position(dShort));
++#else
++            short dShort = static_cast<short>((*it) * 8);
++            r.by_month_day[index++] = static_cast<short>(icalrecurrencetype_day_position(dShort));
++#endif
++        }
+     }
+ 
+     bys = recur->byYearDays();
+-    index = 0;
+-    for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+-        r.by_year_day[index++] = static_cast<short>(*it);
++    if (!bys.isEmpty()) {
++        index = 0;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        icalrecur_resize_by(&r.by[ICAL_BY_YEAR_DAY], static_cast<short>(bys.count()));
++#endif
++        for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++            r.by[ICAL_BY_YEAR_DAY].data[index++] = static_cast<short>(*it);
++#else
++            r.by_year_day[index++] = static_cast<short>(*it);
++#endif
++        }
+     }
+ 
+     bys = recur->byWeekNumbers();
+-    index = 0;
+-    for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+-        r.by_week_no[index++] = static_cast<short>(*it);
++    if (!bys.isEmpty()) {
++        index = 0;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        icalrecur_resize_by(&r.by[ICAL_BY_WEEK_NO], static_cast<short>(bys.count()));
++#endif
++        for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++            r.by[ICAL_BY_WEEK_NO].data[index++] = static_cast<short>(*it);
++#else
++            r.by_week_no[index++] = static_cast<short>(*it);
++#endif
++        }
+     }
+ 
+     bys = recur->byMonths();
+-    index = 0;
+-    for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+-        r.by_month[index++] = static_cast<short>(*it);
++    if (!bys.isEmpty()) {
++        index = 0;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        icalrecur_resize_by(&r.by[ICAL_BY_MONTH], static_cast<short>(bys.count()));
++#endif
++        for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++            r.by[ICAL_BY_MONTH].data[index++] = static_cast<short>(*it);
++#else
++            r.by_month[index++] = static_cast<short>(*it);
++#endif
++        }
+     }
+ 
+     bys = recur->bySetPos();
+-    index = 0;
+-    for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
+-        r.by_set_pos[index++] = static_cast<short>(*it);
++    if (!bys.isEmpty()) {
++        index = 0;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        icalrecur_resize_by(&r.by[ICAL_BY_SET_POS], static_cast<short>(bys.count()));
++#endif
++        for (auto it = bys.constBegin(); it != bys.constEnd(); ++it) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++            r.by[ICAL_BY_SET_POS].data[index++] = static_cast<short>(*it);
++#else
++            r.by_set_pos[index++] = static_cast<short>(*it);
++#endif
++        }
+     }
+ 
+     const QList<RecurrenceRule::WDayPos> &byd = recur->byDays();
+-    int day;
+-    index = 0;
+-    for (auto it = byd.cbegin(); it != byd.cend(); ++it) {
+-        const auto &reRule = *it;
+-        day = (reRule.day() % 7) + 1; // convert from Monday=1 to Sunday=1
+-        if (reRule.pos() < 0) {
+-            day += (-reRule.pos()) * 8;
+-            day = -day;
+-        } else {
+-            day += reRule.pos() * 8;
++    if (!byd.isEmpty()) {
++        int day;
++        index = 0;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        icalrecur_resize_by(&r.by[ICAL_BY_DAY], static_cast<short>(byd.count()));
++#endif
++        for (auto it = byd.cbegin(); it != byd.cend(); ++it) {
++            const auto &reRule = *it;
++            day = (reRule.day() % 7) + 1; // convert from Monday=1 to Sunday=1
++            if (reRule.pos() < 0) {
++                day += (-reRule.pos()) * 8;
++                day = -day;
++            } else {
++                day += reRule.pos() * 8;
++            }
++#if ICAL_CHECK_VERSION(3, 99, 99)
++            r.by[ICAL_BY_DAY].data[index++] = static_cast<short>(day);
++#else
++            r.by_day[index++] = static_cast<short>(day);
++#endif
+         }
+-        r.by_day[index++] = static_cast<short>(day);
+     }
+ 
+     r.week_start = static_cast<icalrecurrencetype_weekday>(recur->weekStart() % 7 + 1);
+@@ -964,7 +1088,11 @@
+         }
+     }
+ 
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    return rp;
++#else
+     return r;
++#endif
+ }
+ 
+ icalcomponent *ICalFormatImpl::writeAlarm(const Alarm::Ptr &alarm)
+@@ -1452,12 +1580,21 @@
+ 
+     p = icalproperty_get_first_parameter(attendee, ICAL_DELEGATEDTO_PARAMETER);
+     if (p) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        // TODO: support multiple delegated_to and delegated_from attendees
++        a.setDelegate(QLatin1String(icalparameter_get_delegatedto_nth(p, 0)));
++#else
+         a.setDelegate(QLatin1String(icalparameter_get_delegatedto(p)));
++#endif
+     }
+ 
+     p = icalproperty_get_first_parameter(attendee, ICAL_DELEGATEDFROM_PARAMETER);
+     if (p) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        a.setDelegator(QLatin1String(icalparameter_get_delegatedfrom_nth(p, 0)));
++#else
+         a.setDelegator(QLatin1String(icalparameter_get_delegatedfrom(p)));
++#endif
+     }
+ 
+     return a;
+@@ -1692,8 +1829,14 @@
+ 
+         case ICAL_GEO_PROPERTY: { // geo
+             icalgeotype geo = icalproperty_get_geo(p);
++#if ICAL_CHECK_VERSION(3, 99, 99)
++            // QByteArray::toFloat() always parses in the C locale, unlike scanf("%lf")
++            incidence->setGeoLatitude(QByteArray(geo.lat, qstrnlen(geo.lat, ICAL_GEO_LEN)).toFloat());
++            incidence->setGeoLongitude(QByteArray(geo.lon, qstrnlen(geo.lon, ICAL_GEO_LEN)).toFloat());
++#else
+             incidence->setGeoLatitude(geo.lat);
+             incidence->setGeoLongitude(geo.lon);
++#endif
+ #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 89)
+             incidence->setHasGeo(true);
+ #endif
+@@ -1972,7 +2115,16 @@
+ {
+     Recurrence *recur = incidence->recurrence();
+ 
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    // borrowed from the property, must not be unref'ed here
++    struct icalrecurrencetype *rp = icalproperty_get_rrule(rrule);
++    if (!rp) {
++        return;
++    }
++    const struct icalrecurrencetype &r = *rp;
++#else
+     struct icalrecurrencetype r = icalproperty_get_rrule(rrule);
++#endif
+     // dumpIcalRecurrence(r);
+ 
+     RecurrenceRule *recurrule = new RecurrenceRule(/*incidence*/);
+@@ -1983,7 +2135,16 @@
+ 
+ void ICalFormatImpl::readExceptionRule(icalproperty *rrule, const Incidence::Ptr &incidence)
+ {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    // borrowed from the property, must not be unref'ed here
++    struct icalrecurrencetype *rp = icalproperty_get_exrule(rrule);
++    if (!rp) {
++        return;
++    }
++    const struct icalrecurrencetype &r = *rp;
++#else
+     struct icalrecurrencetype r = icalproperty_get_exrule(rrule);
++#endif
+     // dumpIcalRecurrence(r);
+ 
+     RecurrenceRule *recurrule = new RecurrenceRule(/*incidence*/);
+@@ -2046,11 +2207,21 @@
+ 
+     // And now all BY*
+     QList<int> lst;
+-    int i;
+     int index = 0;
+ 
+ // clang-format off
+ //@cond PRIVATE
++#if ICAL_CHECK_VERSION(3, 99, 99)
++#define readSetByList( rrulecomp, setfunc )                             \
++    index = 0;                                                            \
++    lst.clear();                                                          \
++    while ( index < r.by[rrulecomp].size ) {                              \
++        lst.append( r.by[rrulecomp].data[index++] );                        \
++    }                                                                     \
++    if ( !lst.isEmpty() ) {                                               \
++        recur->setfunc( lst );                                              \
++    }
++#else
+ #define readSetByList( rrulecomp, setfunc )                             \
+     index = 0;                                                            \
+     lst.clear();                                                          \
+@@ -2060,12 +2231,24 @@
+     if ( !lst.isEmpty() ) {                                               \
+         recur->setfunc( lst );                                              \
+     }
++#endif
+ //@endcond
+     // clang-format on
+ 
+     // BYSECOND, MINUTE and HOUR, MONTHDAY, YEARDAY, WEEKNUMBER, MONTH
+     // and SETPOS are standard int lists, so we can treat them with the
+     // same macro
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    readSetByList(ICAL_BY_SECOND, setBySeconds);
++    readSetByList(ICAL_BY_MINUTE, setByMinutes);
++    readSetByList(ICAL_BY_HOUR, setByHours);
++    readSetByList(ICAL_BY_MONTH_DAY, setByMonthDays);
++    readSetByList(ICAL_BY_YEAR_DAY, setByYearDays);
++    readSetByList(ICAL_BY_WEEK_NO, setByWeekNumbers);
++    readSetByList(ICAL_BY_MONTH, setByMonths);
++    readSetByList(ICAL_BY_SET_POS, setBySetPos);
++#else
++    int i;
+     readSetByList(by_second, setBySeconds);
+     readSetByList(by_minute, setByMinutes);
+     readSetByList(by_hour, setByHours);
+@@ -2074,13 +2257,19 @@
+     readSetByList(by_week_no, setByWeekNumbers);
+     readSetByList(by_month, setByMonths);
+     readSetByList(by_set_pos, setBySetPos);
++#endif
+ #undef readSetByList
+ 
+     // BYDAY is a special case, since it's not an int list
+     QList<RecurrenceRule::WDayPos> wdlst;
+     short day;
+     index = 0;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    while (index < r.by[ICAL_BY_DAY].size) {
++        day = r.by[ICAL_BY_DAY].data[index++];
++#else
+     while ((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
++#endif
+         RecurrenceRule::WDayPos pos;
+         pos.setDay(static_cast<short>((icalrecurrencetype_day_day_of_week(day) + 5) % 7 + 1));
+         pos.setPos(icalrecurrencetype_day_position(day));
+@@ -2938,7 +3127,11 @@
+             if (!icaltz) {
+                 qCritical() << "bad time zone";
+             } else {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++                icalcomponent *tz = icalcomponent_clone(icaltimezone_get_component(icaltz));
++#else
+                 icalcomponent *tz = icalcomponent_new_clone(icaltimezone_get_component(icaltz));
++#endif
+                 icalcomponent_add_component(message, tz);
+                 icaltimezone_free(icaltz, 1);
+             }
+diff -urN kcalendarcore-5.116.0.orig/src/icalformat_p.h kcalendarcore-5.116.0/src/icalformat_p.h
+--- kcalendarcore-5.116.0.orig/src/icalformat_p.h	2024-05-04 13:37:43.000000000 +0200
++++ kcalendarcore-5.116.0/src/icalformat_p.h	2026-08-23 03:03:15.774634396 +0200
+@@ -119,7 +119,11 @@
+     icalproperty *writeOrganizer(const Person &organizer);
+     icalproperty *writeAttachment(const Attachment &attach);
+     icalproperty *writeRecurrenceRule(Recurrence *);
++#if ICAL_CHECK_VERSION(3, 99, 99)
++    icalrecurrencetype *writeRecurrenceRule(RecurrenceRule *recur);
++#else
+     icalrecurrencetype writeRecurrenceRule(RecurrenceRule *recur);
++#endif
+     icalcomponent *writeAlarm(const Alarm::Ptr &alarm);
+     icalproperty *writeConference(const Conference &conference);
+ 
+diff -urN kcalendarcore-5.116.0.orig/src/icaltimezones.cpp kcalendarcore-5.116.0/src/icaltimezones.cpp
+--- kcalendarcore-5.116.0.orig/src/icaltimezones.cpp	2024-05-04 13:37:43.000000000 +0200
++++ kcalendarcore-5.116.0/src/icaltimezones.cpp	2026-08-23 03:03:15.774952311 +0200
+@@ -240,7 +240,11 @@
+         icalcomponent_add_property(phaseComp, icalproperty_new_tzoffsetfrom(preOffset));
+         icalcomponent_add_property(phaseComp, icalproperty_new_tzoffsetto(transit.offsetFromUtc));
+         // Create a component to hold initial RRULE if any, plus all RDATEs
++#if ICAL_CHECK_VERSION(3, 99, 99)
++        icalcomponent *phaseComp1 = icalcomponent_clone(phaseComp);
++#else
+         icalcomponent *phaseComp1 = icalcomponent_new_clone(phaseComp);
++#endif
+         icalcomponent_add_property(phaseComp1, icalproperty_new_dtstart(writeLocalICalDateTime(transits.at(i).atUtc, preOffset)));
+         bool useNewRRULE = false;
+ 
+@@ -340,23 +344,60 @@
+                 }
+                 if (times.count() > (useNewRRULE ? minPhaseCount : minRuleCount)) {
+                     // There are enough dates to combine into an RRULE
++#if ICAL_CHECK_VERSION(3, 99, 99)
++                    icalrecurrencetype *rp = icalrecurrencetype_new();
++                    if (!rp) {
++                        break;
++                    }
++                    icalrecurrencetype &r = *rp;
++                    icalrecur_resize_by(&r.by[ICAL_BY_MONTH], 1);
++#else
+                     icalrecurrencetype r;
+                     icalrecurrencetype_clear(&r);
++#endif
+                     r.freq = ICAL_YEARLY_RECURRENCE;
++#if ICAL_CHECK_VERSION(3, 99, 99)
++                    r.by[ICAL_BY_MONTH].data[0] = month;
++#else
+                     r.by_month[0] = month;
++#endif
+                     if (rule & DAY_OF_MONTH) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++                        icalrecur_resize_by(&r.by[ICAL_BY_MONTH_DAY], 1);
++                        r.by[ICAL_BY_MONTH_DAY].data[0] = dayOfMonth;
++#else
+                         r.by_month_day[0] = dayOfMonth;
++#endif
+                     } else if (rule & WEEKDAY_OF_MONTH) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++                        icalrecur_resize_by(&r.by[ICAL_BY_DAY], 1);
++                        r.by[ICAL_BY_DAY].data[0] = (dayOfWeek % 7 + 1) + (nthFromStart * 8); // Sunday = 1
++#else
+                         r.by_day[0] = (dayOfWeek % 7 + 1) + (nthFromStart * 8); // Sunday = 1
++#endif
+                     } else if (rule & LAST_WEEKDAY_OF_MONTH) {
++#if ICAL_CHECK_VERSION(3, 99, 99)
++                        icalrecur_resize_by(&r.by[ICAL_BY_DAY], 1);
++                        r.by[ICAL_BY_DAY].data[0] = -(dayOfWeek % 7 + 1) - (nthFromEnd * 8); // Sunday = 1
++#else
+                         r.by_day[0] = -(dayOfWeek % 7 + 1) - (nthFromEnd * 8); // Sunday = 1
++#endif
+                     }
+                     r.until = writeLocalICalDateTime(times.takeAt(times.size() - 1), preOffset);
++#if ICAL_CHECK_VERSION(3, 99, 99)
++                    icalproperty *prop = icalproperty_new_rrule(rp);
++                    icalrecurrencetype_unref(rp);
++#else
+                     icalproperty *prop = icalproperty_new_rrule(r);
++#endif
+                     if (useNewRRULE) {
+                         // This RRULE doesn't start from the phase start date, so set it into
+                         // a new STANDARD/DAYLIGHT component in the VTIMEZONE.
++#if ICAL_CHECK_VERSION(3, 99, 99)
++                        icalcomponent *c = icalcomponent_clone(phaseComp);
++#else
+                         icalcomponent *c = icalcomponent_new_clone(phaseComp);
++#endif
+                         icalcomponent_add_property(c, icalproperty_new_dtstart(writeLocalICalDateTime(times[0], preOffset)));
+                         icalcomponent_add_property(c, prop);
+                         icalcomponent_add_component(tzcomp, c);
+@@ -626,7 +667,15 @@
+                 RecurrenceRule r;
+                 ICalFormat icf;
+                 ICalFormatImpl impl(&icf);
++#if ICAL_CHECK_VERSION(3, 99, 99)
++                struct icalrecurrencetype *rrule = icalproperty_get_rrule(p);
++                if (!rrule) {
++                    break;
++                }
++                impl.readRecurrence(*rrule, &r);
++#else
+                 impl.readRecurrence(icalproperty_get_rrule(p), &r);
++#endif
+                 r.setStartDt(utcStart);
+                 // The end date time specified in an RRULE must be in UTC.
+                 // We can not guarantee correctness if this is not the case.
+diff -urN kcalendarcore-5.116.0.orig/src/vcalformat.cpp kcalendarcore-5.116.0/src/vcalformat.cpp
+--- kcalendarcore-5.116.0.orig/src/vcalformat.cpp	2024-05-04 13:37:43.000000000 +0200
++++ kcalendarcore-5.116.0/src/vcalformat.cpp	2026-08-23 03:03:15.775413372 +0200
+@@ -29,6 +29,7 @@
+ #include "kcalendarcore_debug.h"
+ 
+ extern "C" {
++#include <libical/ical.h>
+ #include <libical/vcc.h>
+ #include <libical/vobject.h>
+ }
+@@ -81,7 +82,11 @@
+ {
+ }
+ 
++#if ICAL_CHECK_VERSION(3, 99, 99)
++static void mimeErrorHandler(const char *e)
++#else
+ static void mimeErrorHandler(char *e)
++#endif
+ {
+     qCWarning(KCALCORE_LOG) << "Error parsing vCalendar file:" << e;
+ }
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/kf5-kcalendarcore.git/commitdiff/6039186709534b656310b73d48837ee6cf6ef172



More information about the pld-cvs-commit mailing list