See ChangeLog.
Monotone-Parent: d6ace8d3429bf9ad569fff969474bd5aa01214ae Monotone-Revision: ae85556f790a11b8a40593a88822bee09e847d96 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-06-04T15:29:38maint-2.0.2
parent
33bb7e5556
commit
939eeba1f7
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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,6 +813,8 @@ 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.
|
||||||
|
@ -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,6 +927,7 @@ 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"];
|
||||||
|
@ -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];
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue