Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 605b9045 authored by Ricki Hirner's avatar Ricki Hirner
Browse files

Event: improved local handling of exceptions of recurring events

parent c1442429
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -254,9 +254,7 @@ abstract class AndroidEvent(

        // exceptions from recurring events
        row.getAsLong(Events.ORIGINAL_INSTANCE_TIME)?.let { originalInstanceTime ->
            var originalAllDay = false
            row.getAsInteger(Events.ORIGINAL_ALL_DAY)?.let { originalAllDay = it != 0 }

            val originalAllDay = (row.getAsInteger(Events.ORIGINAL_ALL_DAY) ?: 0) != 0
            val originalDate = if (originalAllDay)
                    Date(originalInstanceTime) else
                    DateTime(originalInstanceTime)
+9 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ import net.fortuna.ical4j.model.TimeZone
import net.fortuna.ical4j.model.component.VTimeZone
import net.fortuna.ical4j.model.parameter.Value
import net.fortuna.ical4j.model.property.DateListProperty
import net.fortuna.ical4j.model.property.DateProperty
import net.fortuna.ical4j.model.property.ExDate
import net.fortuna.ical4j.model.property.RDate
import java.io.StringReader
@@ -74,6 +75,14 @@ object DateUtils {
        return deviceTZ
    }

    /**
     * Determines whether a given date represents a DATE-TIME value.
     * @param date date property to check
     * @return *true* if the date is a DATE-TIME value; *false* otherwise (for instance, when the
     * date is a DATE value or null)
     */
    fun isDateTime(date: DateProperty?) = date != null && date.date is DateTime

    /**
     * Parses a VTIMEZONE definition to a VTimeZone object.
     * @param timezoneDef VTIMEZONE definition
+30 −16
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@

package at.bitfire.ical4android

import at.bitfire.ical4android.DateUtils.isDateTime
import at.bitfire.ical4android.ICalendar.Companion.CALENDAR_NAME
import net.fortuna.ical4j.data.CalendarOutputter
import net.fortuna.ical4j.data.ParserException
@@ -206,17 +207,31 @@ class Event: ICalendar() {

        // recurrence exceptions
        for (exception in exceptions) {
            // make sure that
            //     - exceptions have the same UID as the main event and
            //     - RECURRENCE-IDs have the same timezone as the main event's DTSTART
            // exceptions must always have the same UID as the main event
            exception.uid = uid
            exception.recurrenceId?.let { recurrenceId ->
                if (recurrenceId.timeZone != dtStart.timeZone) {

            val recurrenceId = exception.recurrenceId
            if (recurrenceId == null) {
                Constants.log.warning("Ignoring exception without recurrenceId")
                continue
            }

            /* Exceptions must always have the same value type as DTSTART [RFC 5545 3.8.4.4].
               If this is not the case, we don't add the exception to the event because we're
               strict in what we send (and servers may reject such a case).
             */
            if (isDateTime(recurrenceId) != isDateTime(dtStart)) {
                Constants.log.warning("Ignoring exception $recurrenceId with other date type than dtStart: $dtStart")
                continue
            }

            // for simplicity and compatibility, rewrite date-time exceptions to the same time zone as DTSTART
            if (isDateTime(recurrenceId) && recurrenceId.timeZone != dtStart.timeZone) {
                Constants.log.fine("Changing timezone of $recurrenceId to same time zone as dtStart: $dtStart")
                recurrenceId.timeZone = dtStart.timeZone
                    exception.recurrenceId = recurrenceId
            }

                // create VEVENT for exception
            // create and add VEVENT for exception
            val vException = exception.toVEvent()
            components += vException

@@ -224,7 +239,6 @@ class Event: ICalendar() {
            exception.dtStart?.timeZone?.let(usedTimeZones::add)
            exception.dtEnd?.timeZone?.let(usedTimeZones::add)
        }
        }

        // add VTIMEZONE components
        usedTimeZones.forEach {
@@ -243,7 +257,7 @@ class Event: ICalendar() {
     * @return generated VEvent
     */
    private fun toVEvent(): VEvent {
        val event = VEvent(true /* generates DTSTAMP */)
        val event = VEvent(/* generates DTSTAMP */)
        val props = event.properties
        props += Uid(uid)

@@ -258,7 +272,7 @@ class Event: ICalendar() {
        description?.let { props += Description(it) }
        color?.let { props += Color(null, it.name) }

        props += dtStart
        dtStart?.let { props += it }
        dtEnd?.let { props += it }
        duration?.let { props += it }

+0 −2
Original line number Diff line number Diff line
@@ -99,8 +99,6 @@ open class ICalendar {

        // time zone helpers

        fun isDateTime(date: DateProperty?) = date != null && date.date is DateTime

        /**
         * Minifies a VTIMEZONE so that only components after [start] are kept.
         * Doesn't return the smallest possible VTIMEZONE at the moment, but
+3 −3
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ package at.bitfire.ical4android
import android.content.ContentValues
import android.database.Cursor
import android.database.DatabaseUtils
import net.fortuna.ical4j.model.TextList
import at.bitfire.ical4android.DateUtils.isDateTime
import net.fortuna.ical4j.model.property.DateProperty
import net.fortuna.ical4j.util.TimeZones
import java.lang.reflect.Modifier
@@ -25,7 +25,7 @@ object MiscUtils {
     * @param date DateProperty to validate. Values which are not DATE-TIME will be ignored.
     */
    fun androidifyTimeZone(date: DateProperty?) {
        if (ICalendar.isDateTime(date)) {
        if (isDateTime(date)) {
            val tz = date!!.timeZone ?: return
            val tzID = tz.id ?: return
            val deviceTzID = DateUtils.findAndroidTimezoneID(tzID)
@@ -47,7 +47,7 @@ object MiscUtils {
     *         - the currently set default time zone ID for floating date-times
     */
    fun getTzId(date: DateProperty): String =
            if (ICalendar.isDateTime(date)) {
            if (isDateTime(date)) {
                when {
                    date.isUtc ->
                        // DATE-TIME in UTC format
Loading