From: znek Date: Tue, 15 Feb 2005 21:11:00 +0000 (+0000) Subject: bugfixes for cycle calculation, modified implementations with future extensions in... X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5739d6ba997c509b01a59d17ec90a048eadc8087;p=sope bugfixes for cycle calculation, modified implementations with future extensions in mind git-svn-id: http://svn.opengroupware.org/SOPE/trunk@563 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/sope-ical/NGiCal/ChangeLog b/sope-ical/NGiCal/ChangeLog index 45fe292c..1ac9c871 100644 --- a/sope-ical/NGiCal/ChangeLog +++ b/sope-ical/NGiCal/ChangeLog @@ -1,5 +1,14 @@ 2005-02-15 Marcus Mueller + * v4.5.43 + + * iCalRecurrenceRule.[hm]: exposed some more of the API + + * iCalRecurrenceCalculator.m: some bugfixes. Split the code and gave + iCalWeeklyRecurrenceCalculator its own calculation - there are a + number of foreseeable differences to daily calculation that make + this necessary in the near future anyways. + * v4.5.42 * iCalRepeatableEntityObject.[hm]: added ability to properly calculate diff --git a/sope-ical/NGiCal/NGiCal.xcode/project.pbxproj b/sope-ical/NGiCal/NGiCal.xcode/project.pbxproj index f7365484..fffebc1d 100644 --- a/sope-ical/NGiCal/NGiCal.xcode/project.pbxproj +++ b/sope-ical/NGiCal/NGiCal.xcode/project.pbxproj @@ -164,7 +164,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 4.5.42; + DYLIB_CURRENT_VERSION = 4.5.43; FRAMEWORK_SEARCH_PATHS = "\"$(USER_LIBRARY_DIR)/EmbeddedFrameworks\""; FRAMEWORK_VERSION = A; GCC_PRECOMPILE_PREFIX_HEADER = NO; @@ -578,7 +578,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 4.5.42; + DYLIB_CURRENT_VERSION = 4.5.43; FRAMEWORK_SEARCH_PATHS = "$(LOCAL_LIBRARY_DIR)/Frameworks"; FRAMEWORK_VERSION = A; GCC_PRECOMPILE_PREFIX_HEADER = YES; diff --git a/sope-ical/NGiCal/Version b/sope-ical/NGiCal/Version index 03d46ce9..116461db 100644 --- a/sope-ical/NGiCal/Version +++ b/sope-ical/NGiCal/Version @@ -2,7 +2,7 @@ MAJOR_VERSION=4 MINOR_VERSION=5 -SUBMINOR_VERSION:=42 +SUBMINOR_VERSION:=43 # v4.5.40 requires NGExtensions v4.5.145 # v4.5.37 requires NGExtensions v4.5.140 diff --git a/sope-ical/NGiCal/iCalRecurrenceCalculator.m b/sope-ical/NGiCal/iCalRecurrenceCalculator.m index 83b57d8d..7878d45b 100644 --- a/sope-ical/NGiCal/iCalRecurrenceCalculator.m +++ b/sope-ical/NGiCal/iCalRecurrenceCalculator.m @@ -30,10 +30,9 @@ @interface iCalDailyRecurrenceCalculator : iCalRecurrenceCalculator { } -- (unsigned)factor; @end -@interface iCalWeeklyRecurrenceCalculator : iCalDailyRecurrenceCalculator +@interface iCalWeeklyRecurrenceCalculator : iCalRecurrenceCalculator { } @end @@ -179,7 +178,7 @@ static Class yearlyCalcClass = Nil; jnRuleLast = [until julianNumber]; } else { - jnRuleLast = (interval * [self->rrule repeatCount] * [self factor]) + jnRuleLast = (interval * [self->rrule repeatCount]) + jnFirst; if (jnRuleLast < jnStart) return nil; @@ -189,27 +188,31 @@ static Class yearlyCalcClass = Nil; jnEnd = jnRuleLast; } - ranges = [NSMutableArray arrayWithCapacity:5]; startEndCount = (jnEnd - jnStart) + 1; + ranges = [NSMutableArray arrayWithCapacity:startEndCount]; for (i = 0 ; i < startEndCount; i++) { - long jnTest; - - jnTest = (jnStart + i) - jnFirst; - if ((jnTest % interval) == 0) { - NSCalendarDate *start, *end; - NGCalendarDateRange *r; + long jnCurrent; - start = [NSCalendarDate dateForJulianNumber:jnStart + i]; - start = [start hour: [firStart hourOfDay] - minute:[firStart minuteOfHour] - second:[firStart secondOfMinute]]; - end = [start addTimeInterval:[self->firstRange duration]]; - r = [NGCalendarDateRange calendarDateRangeWithStartDate:start - endDate:end]; - [ranges addObject:r]; + jnCurrent = jnStart + i; + if (jnCurrent >= jnFirst) { + long jnTest; + + jnTest = jnCurrent - jnFirst; + if ((jnTest % interval) == 0) { + NSCalendarDate *start, *end; + NGCalendarDateRange *r; + + start = [NSCalendarDate dateForJulianNumber:jnCurrent]; + start = [start hour: [firStart hourOfDay] + minute:[firStart minuteOfHour] + second:[firStart secondOfMinute]]; + end = [start addTimeInterval:[self->firstRange duration]]; + r = [NGCalendarDateRange calendarDateRangeWithStartDate:start + endDate:end]; + [ranges addObject:r]; + } } } - return ranges; } @@ -221,8 +224,7 @@ static Class yearlyCalcClass = Nil; firStart = [self->firstRange startDate]; jnFirst = [firStart julianNumber]; jnRuleLast = ([self->rrule repeatInterval] * - [self->rrule repeatCount] * - [self factor]) + + [self->rrule repeatCount]) + jnFirst; until = [NSCalendarDate dateForJulianNumber:jnRuleLast]; until = [until hour: [firStart hourOfDay] @@ -233,10 +235,6 @@ static Class yearlyCalcClass = Nil; return [super lastInstanceStartDate]; } -- (unsigned)factor { - return 1; -} - @end /* iCalDailyRecurrenceCalculator */ @@ -246,8 +244,95 @@ static Class yearlyCalcClass = Nil; */ @implementation iCalWeeklyRecurrenceCalculator -- (unsigned)factor { - return 7; +- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r { + NSMutableArray *ranges; + NSCalendarDate *firStart; + long i, jnFirst, jnStart, jnEnd, startEndCount; + unsigned interval, byDayMask; + + firStart = [self->firstRange startDate]; + jnFirst = [firStart julianNumber]; + jnEnd = [[_r endDate] julianNumber]; + + if (jnFirst > jnEnd) + return nil; + + jnStart = [[_r startDate] julianNumber]; + interval = [self->rrule repeatInterval]; + + /* if rule is bound, check the bounds */ + if (![self->rrule isInfinite]) { + NSCalendarDate *until; + long jnRuleLast; + + until = [self->rrule untilDate]; + if (until) { + if ([until compare:[_r startDate]] == NSOrderedAscending) + return nil; + jnRuleLast = [until julianNumber]; + } + else { + jnRuleLast = (interval * [self->rrule repeatCount] * 7) + + jnFirst; + if (jnRuleLast < jnStart) + return nil; + } + /* jnStart < jnRuleLast < jnEnd ? */ + if (jnEnd > jnRuleLast) + jnEnd = jnRuleLast; + } + + startEndCount = (jnEnd - jnStart) + 1; + ranges = [NSMutableArray arrayWithCapacity:startEndCount]; + byDayMask = [self->rrule byDayMask]; + if (!byDayMask) { + for (i = 0 ; i < startEndCount; i++) { + long jnCurrent; + + jnCurrent = jnStart + i; + if (jnCurrent >= jnFirst) { + long jnDiff; + + jnDiff = jnCurrent - jnFirst; /* difference in days */ + if ((jnDiff % (interval * 7)) == 0) { + NSCalendarDate *start, *end; + NGCalendarDateRange *r; + + start = [NSCalendarDate dateForJulianNumber:jnCurrent]; + start = [start hour: [firStart hourOfDay] + minute:[firStart minuteOfHour] + second:[firStart secondOfMinute]]; + end = [start addTimeInterval:[self->firstRange duration]]; + r = [NGCalendarDateRange calendarDateRangeWithStartDate:start + endDate:end]; + [ranges addObject:r]; + } + } + } + } + else { + [self errorWithFormat:@"Cannot calculate rules with byDayMask, yet!"]; + } + return ranges; +} + +- (NSCalendarDate *)lastInstanceStartDate { + if ([self->rrule repeatCount] > 0) { + long jnFirst, jnRuleLast; + NSCalendarDate *firStart, *until; + + firStart = [self->firstRange startDate]; + jnFirst = [firStart julianNumber]; + jnRuleLast = ([self->rrule repeatInterval] * + [self->rrule repeatCount] * 7) + + jnFirst; + until = [NSCalendarDate dateForJulianNumber:jnRuleLast]; + until = [until hour: [firStart hourOfDay] + minute:[firStart minuteOfHour] + second:[firStart secondOfMinute]]; + return until; + } + return [super lastInstanceStartDate]; } @end /* iCalWeeklyRecurrenceCalculator */ diff --git a/sope-ical/NGiCal/iCalRecurrenceRule.h b/sope-ical/NGiCal/iCalRecurrenceRule.h index eb1a5bf9..96e77e94 100644 --- a/sope-ical/NGiCal/iCalRecurrenceRule.h +++ b/sope-ical/NGiCal/iCalRecurrenceRule.h @@ -76,7 +76,11 @@ typedef enum { - (iCalRecurrenceFrequency)frequency; - (void)setRepeatInterval:(int)_repeatInterval; - (int)repeatInterval; - +- (void)setWeekStart:(iCalWeekDay)_weekStart; +- (iCalWeekDay)weekStart; +- (void)setByDayMask:(unsigned)_mask; +- (unsigned)byDayMask; + /* count and untilDate are mutually exclusive */ - (void)setRepeatCount:(unsigned)_repeatCount; - (unsigned)repeatCount; diff --git a/sope-ical/NGiCal/iCalRecurrenceRule.m b/sope-ical/NGiCal/iCalRecurrenceRule.m index 9278888f..4665b064 100644 --- a/sope-ical/NGiCal/iCalRecurrenceRule.m +++ b/sope-ical/NGiCal/iCalRecurrenceRule.m @@ -127,6 +127,13 @@ return self->byDay.weekStart; } +- (void)setByDayMask:(unsigned)_mask { + self->byDay.mask = _mask; +} +- (unsigned)byDayMask { + return self->byDay.mask; +} + - (BOOL)isInfinite { return (self->repeatCount != 0 || self->untilDate) ? NO : YES; }