2 Copyright (C) 2004-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "iCalRecurrenceCalculator.h"
23 #include <NGExtensions/NGCalendarDateRange.h>
24 #include "iCalRecurrenceRule.h"
30 @interface iCalDailyRecurrenceCalculator : iCalRecurrenceCalculator
36 @interface iCalWeeklyRecurrenceCalculator : iCalDailyRecurrenceCalculator
41 @interface iCalMonthlyRecurrenceCalculator : iCalRecurrenceCalculator
46 @interface iCalYearlyRecurrenceCalculator : iCalRecurrenceCalculator
53 @implementation iCalRecurrenceCalculator
55 static Class dailyCalcClass = Nil;
56 static Class weeklyCalcClass = Nil;
57 static Class monthlyCalcClass = Nil;
58 static Class yearlyCalcClass = Nil;
61 static BOOL didInit = NO;
66 dailyCalcClass = [iCalDailyRecurrenceCalculator class];
67 weeklyCalcClass = [iCalWeeklyRecurrenceCalculator class];
68 monthlyCalcClass = [iCalMonthlyRecurrenceCalculator class];
69 yearlyCalcClass = [iCalYearlyRecurrenceCalculator class];
72 + (id)recurrenceCalculatorForRecurrenceRule:(iCalRecurrenceRule *)_rrule
73 withFirstInstanceCalendarDateRange:(NGCalendarDateRange *)_range
75 return [[[self alloc] initWithRecurrenceRule:_rrule
76 firstInstanceCalendarDateRange:_range] autorelease];
79 - (id)initWithRecurrenceRule:(iCalRecurrenceRule *)_rrule
80 firstInstanceCalendarDateRange:(NGCalendarDateRange *)_range
82 iCalRecurrenceFrequency freq;
83 Class calcClass = Nil;
85 freq = [_rrule frequency];
86 if (freq == iCalRecurrenceFrequenceDaily)
87 calcClass = dailyCalcClass;
88 else if (freq == iCalRecurrenceFrequenceWeekly)
89 calcClass = weeklyCalcClass;
90 else if (freq == iCalRecurrenceFrequenceMonthly)
91 calcClass = monthlyCalcClass;
92 else if (freq == iCalRecurrenceFrequenceYearly)
93 calcClass = yearlyCalcClass;
99 self = [[calcClass alloc] init];
100 ASSIGN(self->rrule, _rrule);
101 ASSIGN(self->firstRange, _range);
108 - (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r {
109 return nil; /* subclass responsibility */
111 - (BOOL)doesRecurrWithinCalendarDateRange:(NGCalendarDateRange *)_range {
112 return NO; /* subclass responsibility */
115 @end /* iCalRecurrenceCalculator */
121 fuer all diese jeweils
122 differenz der julian numbers durch interval teilen, wenn ok, ...
124 @implementation iCalDailyRecurrenceCalculator
130 - (BOOL)doesRecurrWithinCalendarDateRange:(NGCalendarDateRange *)_range {
131 long i, jnFirst, jnStart, jnEnd, startEndCount;
134 jnFirst = [[self->firstRange startDate] julianNumber];
135 jnEnd = [[_range endDate] julianNumber];
140 jnStart = [[_range startDate] julianNumber];
141 interval = [self->rrule repeatInterval];
143 /* if rule is bound, check the bounds */
144 if (![self->rrule isInfinite]) {
145 NSCalendarDate *until;
148 until = [self->rrule untilDate];
150 if ([until compare:[_range startDate]] == NSOrderedAscending)
152 jnRuleLast = [until julianNumber];
155 jnRuleLast = (interval * [self->rrule repeatCount] * [self factor])
157 if (jnRuleLast < jnStart)
160 /* jnStart < jnRuleLast < jnEnd ? */
161 if (jnEnd > jnRuleLast)
165 startEndCount = (jnEnd - jnStart) + 1;
166 for (i = 0 ; i < startEndCount; i++) {
169 jnTest = (jnStart + i) - jnFirst;
170 if ((jnTest % interval) == 0)
176 @end /* iCalDailyRecurrenceCalculator */
181 wie taeglich, aber teilen durch interval*7
183 @implementation iCalWeeklyRecurrenceCalculator
189 @end /* iCalWeeklyRecurrenceCalculator */
194 monatlich: differenz der monate / interval
195 alle events mit korrektem tag.
196 dann differenz der monate durch interval teilen, wenn ok, ...
197 (diffrenz der monate = 12 * 'volle' jahre plus monate im start jahr und monate im ziel jahr
199 @implementation iCalMonthlyRecurrenceCalculator
201 - (BOOL)doesRecurrWithinCalendarDateRange:(NGCalendarDateRange *)_range {
205 @end /* iCalMonthlyRecurrenceCalculator */
210 alle events mit dem korrekten tag und monat.
211 fuer all diese jeweils
212 differenz in jahren durch interval teilen, wenn ok, dann event fuer den tag.
214 @implementation iCalYearlyRecurrenceCalculator
216 - (BOOL)doesRecurrWithinCalendarDateRange:(NGCalendarDateRange *)_range {
220 @end /* iCalYearlyRecurrenceCalculator */