See ChangeLog.

Monotone-Parent: d6ace8d3429bf9ad569fff969474bd5aa01214ae
Monotone-Revision: ae85556f790a11b8a40593a88822bee09e847d96

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2012-06-04T15:29:38
maint-2.0.2
Francis Lachapelle 2012-06-04 15:29:38 +00:00
parent 33bb7e5556
commit 939eeba1f7
7 changed files with 60 additions and 35 deletions

View File

@ -1,3 +1,10 @@
2012-06-04 Francis Lachapelle <flachapelle@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentFolder.m
(-_appendCycleException:firstInstanceCalendarDateRange:fromRow:forRange:withTimeZone:toArray:):
adjust recurrence id according to timezone when dealing with a
floating all-day event.
2012-06-01 Francis Lachapelle <flachapelle@inverse.ca> 2012-06-01 Francis Lachapelle <flachapelle@inverse.ca>
* SoObjects/SOGo/NSString+Utilities.m * SoObjects/SOGo/NSString+Utilities.m

View File

@ -60,7 +60,7 @@
- (BOOL)isRecurrent; - (BOOL)isRecurrent;
- (BOOL)isWithinCalendarDateRange:(NGCalendarDateRange *)_range - (BOOL)isWithinCalendarDateRange:(NGCalendarDateRange *)_range
firstInstanceCalendarDateRange:(NGCalendarDateRange *)_fir; firstInstanceCalendarDateRange:(NGCalendarDateRange *)_fir;
- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r - (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r
firstInstanceCalendarDateRange:(NGCalendarDateRange *)_fir; firstInstanceCalendarDateRange:(NGCalendarDateRange *)_fir;

View File

@ -268,6 +268,8 @@
} }
else else
{ {
// Example: timezone is -0400, date is 2012-05-24 (00:00:00 +0000),
// and changes to 2012-05-24 04:00:00 +0000
exDate = [dateString asCalendarDate]; exDate = [dateString asCalendarDate];
offset = [(NSTimeZone *) theTimeZone secondsFromGMTForDate: exDate]; offset = [(NSTimeZone *) theTimeZone secondsFromGMTForDate: exDate];
exDate = (NSCalendarDate *) [exDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 exDate = (NSCalendarDate *) [exDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0

View File

@ -270,6 +270,8 @@ static NSArray *knownTimeZones;
/** /**
* Adjust a date with respect to this vTimeZone. * Adjust a date with respect to this vTimeZone.
* Example: Timezone is -0400, the date is 2012-05-23 13:00:00 +0000:
* it returns 2012-05-23 09:00:00 +0000
* @param theDate the string representing a date. * @param theDate the string representing a date.
* @return a new GMT date adjusted with the offset of this timezone. * @return a new GMT date adjusted with the offset of this timezone.
*/ */

View File

@ -744,7 +744,7 @@ static NSNumber *sharedYes = nil;
{ {
currentRecord = [recordArray objectAtIndex: count]; currentRecord = [recordArray objectAtIndex: count];
if ([[currentRecord objectForKey: @"startDate"] if ([[currentRecord objectForKey: @"startDate"]
isEqual: matchDate]) compare: matchDate] == NSOrderedSame)
recordIndex = count; recordIndex = count;
else else
count++; count++;
@ -773,18 +773,32 @@ static NSNumber *sharedYes = nil;
firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
fromRow: (NSDictionary *) row fromRow: (NSDictionary *) row
forRange: (NGCalendarDateRange *) dateRange forRange: (NGCalendarDateRange *) dateRange
withTimeZone: (NSTimeZone *) tz
toArray: (NSMutableArray *) ma toArray: (NSMutableArray *) ma
{ {
NSCalendarDate *startDate, *recurrenceId; NSCalendarDate *startDate, *recurrenceId;
NSMutableDictionary *newRecord; NSMutableDictionary *newRecord;
NSDictionary *oldRecord; NSDictionary *oldRecord;
NGCalendarDateRange *newRecordRange; NGCalendarDateRange *newRecordRange;
int recordIndex; NSComparisonResult compare;
int recordIndex, secondsOffsetFromGMT;
newRecord = nil; newRecord = nil;
recurrenceId = [component recurrenceId]; recurrenceId = [component recurrenceId];
if ([dateRange containsDate: recurrenceId]) if (tz)
{
// The following adjustment is necessary for floating all-day events.
// For example, the recurrence-id 20120523T000000Z for timezone -0400
// will become 20120523T000400Z
secondsOffsetFromGMT = [tz secondsFromGMTForDate: recurrenceId];
recurrenceId = (NSCalendarDate *) [recurrenceId dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
seconds:-secondsOffsetFromGMT];
}
compare = [[dateRange startDate] compare: recurrenceId];
if ((compare == NSOrderedAscending || compare == NSOrderedSame) &&
[[dateRange endDate] compare: recurrenceId] == NSOrderedDescending)
{ {
recordIndex = [self _indexOfRecordMatchingDate: recurrenceId recordIndex = [self _indexOfRecordMatchingDate: recurrenceId
inArray: ma]; inArray: ma];
@ -799,7 +813,9 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
oldRecord = [ma objectAtIndex: recordIndex]; oldRecord = [ma objectAtIndex: recordIndex];
[newRecord setObject: [oldRecord objectForKey: @"c_recurrence_id"] [newRecord setObject: [oldRecord objectForKey: @"c_recurrence_id"]
forKey: @"c_recurrence_id"]; forKey: @"c_recurrence_id"];
// [newRecord setObject: [NSNumber numberWithInt: [recurrenceId timeIntervalSince1970]]
// forKey: @"c_recurrence_id"];
// The first instance date is added to the dictionary so it can // The first instance date is added to the dictionary so it can
// be used by UIxCalListingActions to compute the DST offset. // be used by UIxCalListingActions to compute the DST offset.
[newRecord setObject: [fir startDate] forKey: @"cycleStartDate"]; [newRecord setObject: [fir startDate] forKey: @"cycleStartDate"];
@ -838,6 +854,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
- (void) _appendCycleExceptionsFromRow: (NSDictionary *) row - (void) _appendCycleExceptionsFromRow: (NSDictionary *) row
firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
forRange: (NGCalendarDateRange *) dateRange forRange: (NGCalendarDateRange *) dateRange
withTimeZone: (NSTimeZone *) tz
toArray: (NSMutableArray *) ma toArray: (NSMutableArray *) ma
{ {
NSArray *elements, *components; NSArray *elements, *components;
@ -859,6 +876,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
firstInstanceCalendarDateRange: fir firstInstanceCalendarDateRange: fir
fromRow: row fromRow: row
forRange: dateRange forRange: dateRange
withTimeZone: tz
toArray: ma]; toArray: ma];
} }
} }
@ -877,20 +895,19 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
intoArray: (NSMutableArray *) theRecords intoArray: (NSMutableArray *) theRecords
{ {
NSMutableDictionary *row, *fixedRow; NSMutableDictionary *row, *fixedRow;
NSMutableArray *records, *newExDates; NSMutableArray *records;
NSDictionary *cycleinfo; NSDictionary *cycleinfo;
NSEnumerator *exDatesList;
NGCalendarDateRange *firstRange, *recurrenceRange, *oneRange; NGCalendarDateRange *firstRange, *recurrenceRange, *oneRange;
NSArray *rules, *exRules, *exDates, *ranges; NSArray *rules, *exRules, *exDates, *ranges;
NSArray *elements, *components; NSArray *elements, *components;
NSString *content; NSString *content;
NSCalendarDate *checkStartDate, *checkEndDate, *firstStartDate, NSCalendarDate *checkStartDate, *checkEndDate, *firstStartDate, *firstEndDate;
*firstEndDate; NSTimeZone *allDayTimeZone;
iCalDateTime *dtstart; iCalDateTime *dtstart;
iCalEvent *component; iCalEvent *component;
iCalTimeZone *eventTimeZone; iCalTimeZone *eventTimeZone;
unsigned count, max, offset; unsigned count, max, offset;
id exDate; id tz;
content = [theRecord objectForKey: @"c_cycleinfo"]; content = [theRecord objectForKey: @"c_cycleinfo"];
if (![content isNotNull]) if (![content isNotNull])
@ -910,7 +927,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
rules = [cycleinfo objectForKey: @"rules"]; rules = [cycleinfo objectForKey: @"rules"];
exRules = [cycleinfo objectForKey: @"exRules"]; exRules = [cycleinfo objectForKey: @"exRules"];
exDates = [cycleinfo objectForKey: @"exDates"]; exDates = [cycleinfo objectForKey: @"exDates"];
eventTimeZone = allDayTimeZone = tz = nil;
row = [self fixupRecord: theRecord]; row = [self fixupRecord: theRecord];
[row removeObjectForKey: @"c_cycleinfo"]; [row removeObjectForKey: @"c_cycleinfo"];
[row setObject: sharedYes forKey: @"isRecurrentEvent"]; [row setObject: sharedYes forKey: @"isRecurrentEvent"];
@ -945,12 +963,6 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
recurrenceRange = [NGCalendarDateRange calendarDateRangeWithStartDate: checkStartDate recurrenceRange = [NGCalendarDateRange calendarDateRangeWithStartDate: checkStartDate
endDate: checkEndDate]; endDate: checkEndDate];
// Adjust the exception dates
exDates = [eventTimeZone computedDatesForStrings: exDates];
// Adjust the recurrence rules "until" dates
rules = [component recurrenceRulesWithTimeZone: eventTimeZone];
exRules = [component exceptionRulesWithTimeZone: eventTimeZone];
} }
else else
{ {
@ -959,29 +971,30 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
{ {
// The event lasts all-day and has no timezone (floating); we convert the range of the first event // The event lasts all-day and has no timezone (floating); we convert the range of the first event
// to the user's timezone // to the user's timezone
offset = [timeZone secondsFromGMTForDate: [firstRange startDate]]; allDayTimeZone = timeZone;
offset = [allDayTimeZone secondsFromGMTForDate: [firstRange startDate]];
firstStartDate = [[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 firstStartDate = [[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
seconds:-offset]; seconds:-offset];
firstEndDate = [[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 firstEndDate = [[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
seconds:-offset]; seconds:-offset];
[firstStartDate setTimeZone: timeZone]; [firstStartDate setTimeZone: allDayTimeZone];
[firstEndDate setTimeZone: timeZone]; [firstEndDate setTimeZone: allDayTimeZone];
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
endDate: firstEndDate]; endDate: firstEndDate];
// Adjust the exception dates
exDatesList = [exDates objectEnumerator];
newExDates = [NSMutableArray arrayWithCapacity: [exDates count]];
while ((exDate = [exDatesList nextObject]))
{
exDate = [[exDate asCalendarDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
seconds:-offset];
[newExDates addObject: exDate];
}
exDates = newExDates;
} }
} }
tz = eventTimeZone? eventTimeZone : allDayTimeZone;
if (tz)
{
// Adjust the exception dates
exDates = [component exceptionDatesWithTimeZone: tz];
// Adjust the recurrence rules "until" dates
rules = [component recurrenceRulesWithTimeZone: tz];
exRules = [component exceptionRulesWithTimeZone: tz];
}
// Calculate the occurrences for the given range // Calculate the occurrences for the given range
records = [NSMutableArray array]; records = [NSMutableArray array];
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: recurrenceRange ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: recurrenceRange
@ -1004,6 +1017,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
[self _appendCycleExceptionsFromRow: row [self _appendCycleExceptionsFromRow: row
firstInstanceCalendarDateRange: firstRange firstInstanceCalendarDateRange: firstRange
forRange: theRange forRange: theRange
withTimeZone: allDayTimeZone
toArray: records]; toArray: records];
[theRecords addObjectsFromArray: records]; [theRecords addObjectsFromArray: records];

View File

@ -399,8 +399,8 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence,
recID = [lookupName substringFromIndex: 9]; recID = [lookupName substringFromIndex: 9];
occurence = [self lookupOccurence: recID]; occurence = [self lookupOccurence: recID];
if (occurence) if (occurence)
isNewOccurence = NO; isNewOccurence = NO;
else else
{ {
occurence = [self newOccurenceWithID: recID]; occurence = [self newOccurenceWithID: recID];
isNewOccurence = YES; isNewOccurence = YES;

View File

@ -513,7 +513,7 @@
[dateFormatter formattedTime: eventStartDate], @"startTime", [dateFormatter formattedTime: eventStartDate], @"startTime",
[dateFormatter formattedDate: eventEndDate], @"endDate", [dateFormatter formattedDate: eventEndDate], @"endDate",
[dateFormatter formattedTime: eventEndDate], @"endTime", [dateFormatter formattedTime: eventEndDate], @"endTime",
([event hasRecurrenceRules] ? @"1": @"0"), @"isRecurring", //([event hasRecurrenceRules] ? @"1": @"0"), @"isRecurring",
([event isAllDay] ? @"1": @"0"), @"isAllDay", ([event isAllDay] ? @"1": @"0"), @"isAllDay",
[event summary], @"summary", [event summary], @"summary",
[event location], @"location", [event location], @"location",