mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-06-07 11:29:43 +00:00
See ChangeLog.
Monotone-Parent: 5768aec2a733241a4cb94db69e98b57603adb638 Monotone-Revision: 553f303f1f7a6910069af8e49e3926e86bece4b7 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2011-03-29T23:25:40 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -1,3 +1,21 @@
|
||||
2011-03-29 francis <flachapelle@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/iCalEvent+SOGo.m
|
||||
(-updateRecurrenceRulesUntilDate:): shifts the "until dates" of
|
||||
the recurrence rules of the event with respect to the previous end
|
||||
date of the event.
|
||||
|
||||
* SoObjects/Appointments/SOGoCalendarComponent.m
|
||||
(-updateComponent: ): splitted method "saveComponent:" to avoid
|
||||
saving the component multiple times during the same session.
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentObject.m (-saveComponent):
|
||||
make use of the new "updateComponent" method mentioned above.
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
(-_flattenCycleRecord:forRange:intoArray:): when the event has a
|
||||
timezone, the "until dates" of recurrence rules must be adjusted.
|
||||
|
||||
2011-03-28 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* Tools/SOGoToolRemoveDoubles.m
|
||||
@@ -134,7 +152,7 @@
|
||||
* SoObjects/Appointments/iCalEvent+SOGo.m (-quickRecord): an all-day
|
||||
event usually doesn't have a timezone. However, if it does, we must
|
||||
convert its dates to GMT. All-day events are "floating", in the
|
||||
sense that are timezone-independant.
|
||||
sense that they are timezone-independant.
|
||||
|
||||
2011-03-17 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#import <NGCards/iCalDateTime.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
#import <NGCards/iCalRecurrenceCalculator.h>
|
||||
#import <NGCards/iCalRecurrenceRule.h>
|
||||
#import <NGCards/iCalTimeZone.h>
|
||||
#import <NGCards/iCalTimeZonePeriod.h>
|
||||
#import <NGCards/NSString+NGCards.h>
|
||||
@@ -748,24 +749,14 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
NSDictionary *oldRecord;
|
||||
NGCalendarDateRange *newRecordRange;
|
||||
int recordIndex;
|
||||
signed int daylightOffset;
|
||||
|
||||
newRecord = nil;
|
||||
recurrenceId = [component recurrenceId];
|
||||
|
||||
if ([timeZone isDaylightSavingTimeForDate: recurrenceId] != [timeZone isDaylightSavingTimeForDate: [fir startDate]])
|
||||
{
|
||||
// For the event's recurrence id, compute the daylight saving time
|
||||
// offset with respect to the first occurrence of the recurring event.
|
||||
daylightOffset = (signed int)[timeZone secondsFromGMTForDate: [fir startDate]]
|
||||
- (signed int)[timeZone secondsFromGMTForDate: recurrenceId];
|
||||
recurrenceId = [recurrenceId dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:daylightOffset];
|
||||
}
|
||||
|
||||
if ([dateRange containsDate: recurrenceId])
|
||||
{
|
||||
recordIndex = [self _indexOfRecordMatchingDate: recurrenceId
|
||||
inArray: ma];
|
||||
inArray: ma];
|
||||
if (recordIndex > -1)
|
||||
{
|
||||
startDate = [component startDate];
|
||||
@@ -793,8 +784,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
}
|
||||
else
|
||||
[self errorWithFormat:
|
||||
@"missing exception record for recurrence-id: %@",
|
||||
recurrenceId];
|
||||
@"missing exception record for recurrence-id %@ (uid %@)",
|
||||
recurrenceId, [component uid]];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -822,6 +813,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
content = [row objectForKey: @"c_content"];
|
||||
if ([content length])
|
||||
{
|
||||
// TODO : c_content could have already been parsed.
|
||||
// @see _flattenCycleRecord:forRange:intoArray:
|
||||
elements = [iCalCalendar parseFromSource: content];
|
||||
if ([elements count])
|
||||
{
|
||||
@@ -830,9 +823,9 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
for (count = 1; count < max; count++)
|
||||
[self _appendCycleException: [components objectAtIndex: count]
|
||||
firstInstanceCalendarDateRange: fir
|
||||
fromRow: row
|
||||
forRange: dateRange
|
||||
toArray: ma];
|
||||
fromRow: row
|
||||
forRange: dateRange
|
||||
toArray: ma];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -852,7 +845,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
NSMutableDictionary *row, *fixedRow;
|
||||
NSMutableArray *records;
|
||||
NSDictionary *cycleinfo;
|
||||
NGCalendarDateRange *firstRange, *oneRange;
|
||||
NGCalendarDateRange *firstRange, *recurrenceRange, *oneRange;
|
||||
NSArray *rules, *exRules, *exDates, *ranges;
|
||||
NSArray *elements, *components;
|
||||
NSString *content;
|
||||
@@ -860,7 +853,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
id firstStartDate, firstEndDate;
|
||||
NSCalendarDate *checkStartDate, *checkEndDate;
|
||||
iCalTimeZone *eventTimeZone;
|
||||
unsigned i, count, offset;
|
||||
unsigned count, max, offset;
|
||||
|
||||
records = [NSMutableArray array];
|
||||
ranges = nil;
|
||||
@@ -883,7 +876,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
rules = [cycleinfo objectForKey: @"rules"];
|
||||
exRules = [cycleinfo objectForKey: @"exRules"];
|
||||
exDates = [cycleinfo objectForKey: @"exDates"];
|
||||
|
||||
|
||||
row = [self fixupRecord: theRecord];
|
||||
[row removeObjectForKey: @"c_cycleinfo"];
|
||||
[row setObject: sharedYes forKey: @"isRecurrentEvent"];
|
||||
@@ -897,7 +890,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
components = [[elements objectAtIndex: 0] events];
|
||||
if ([components count])
|
||||
{
|
||||
// Retrieve the range of the first event
|
||||
// Retrieve the range of the first/master event
|
||||
component = [components objectAtIndex: 0];
|
||||
firstStartDate = [component uniqueChildWithTag: @"dtstart"];
|
||||
firstEndDate = [component uniqueChildWithTag: @"dtend"];
|
||||
@@ -910,27 +903,37 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
// Adjust the range to check with respect to the event timezone (extracted from the start date)
|
||||
checkStartDate = [eventTimeZone computedDateForDate: [theRange startDate]];
|
||||
checkEndDate = [eventTimeZone computedDateForDate: [theRange endDate]];
|
||||
theRange = [NGCalendarDateRange calendarDateRangeWithStartDate: checkStartDate
|
||||
endDate: checkEndDate];
|
||||
recurrenceRange = [NGCalendarDateRange calendarDateRangeWithStartDate: checkStartDate
|
||||
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 if ([[theRecord objectForKey: @"c_isallday"] boolValue])
|
||||
else
|
||||
{
|
||||
// The event lasts all-day and has no timezone (floating); we convert the range of the first event
|
||||
// to the user's timezone
|
||||
offset = [timeZone secondsFromGMTForDate: [firstRange startDate]];
|
||||
firstStartDate = (NSCalendarDate*)[[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
recurrenceRange = theRange;
|
||||
if ([[theRecord objectForKey: @"c_isallday"] boolValue])
|
||||
{
|
||||
// The event lasts all-day and has no timezone (floating); we convert the range of the first event
|
||||
// to the user's timezone
|
||||
offset = [timeZone secondsFromGMTForDate: [firstRange startDate]];
|
||||
firstStartDate = (NSCalendarDate*)[[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
firstEndDate = (NSCalendarDate*)[[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
firstEndDate = (NSCalendarDate*)[[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
[firstStartDate setTimeZone: timeZone];
|
||||
[firstEndDate setTimeZone: timeZone];
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
|
||||
endDate: firstEndDate];
|
||||
[firstStartDate setTimeZone: timeZone];
|
||||
[firstEndDate setTimeZone: timeZone];
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
|
||||
endDate: firstEndDate];
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the occurrences for the given range
|
||||
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: theRange
|
||||
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: recurrenceRange
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
recurrenceRules: rules
|
||||
exceptionRules: exRules
|
||||
@@ -939,10 +942,10 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
}
|
||||
}
|
||||
|
||||
count = [ranges count];
|
||||
for (i = 0; i < count; i++)
|
||||
max = [ranges count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
oneRange = [ranges objectAtIndex: i];
|
||||
oneRange = [ranges objectAtIndex: count];
|
||||
fixedRow = [self fixupCycleRecord: row
|
||||
cycleRange: oneRange
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
|
||||
@@ -564,9 +564,9 @@
|
||||
|
||||
[self expandGroupsInEvent: newEvent];
|
||||
|
||||
// We first save the event. It is important to this initially
|
||||
// as the event's UID might get modified in SOGoCalendarComponent: -saveComponent:
|
||||
[super saveComponent: newEvent];
|
||||
// We first update the event. It is important to this initially
|
||||
// as the event's UID might get modified.
|
||||
[super updateComponent: newEvent];
|
||||
|
||||
if ([self isNew])
|
||||
{
|
||||
@@ -606,15 +606,12 @@
|
||||
hasOrganizer = [[[oldMasterEvent organizer] email] length];
|
||||
|
||||
if (!hasOrganizer || [oldMasterEvent userIsOrganizer: ownerUser])
|
||||
{
|
||||
// The owner is the organizer of the event; handle the modifications
|
||||
[self _handleUpdatedEvent: newEvent fromOldEvent: oldEvent];
|
||||
|
||||
// The sequence has possibly been increased -- resave the event.
|
||||
[super saveComponent: newEvent];
|
||||
}
|
||||
// The owner is the organizer of the event; handle the modifications
|
||||
[self _handleUpdatedEvent: newEvent fromOldEvent: oldEvent];
|
||||
}
|
||||
|
||||
[super saveComponent: newEvent];
|
||||
|
||||
[fullCalendar release];
|
||||
fullCalendar = nil;
|
||||
[safeCalendar release];
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/* SOGoCalendarComponent.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2009 Inverse inc.
|
||||
* Copyright (C) 2006-2011 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Francis Lachapelle <flachapelle@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -58,6 +59,7 @@
|
||||
- (NSException *) copyComponent: (iCalCalendar *) calendar
|
||||
toFolder: (SOGoGCSFolder *) newFolder;
|
||||
|
||||
- (void) updateComponent: (iCalRepeatableEntityObject *) newObject;
|
||||
- (void) saveComponent: (iCalRepeatableEntityObject *) newObject;
|
||||
|
||||
/* mail notifications */
|
||||
|
||||
@@ -593,9 +593,9 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence,
|
||||
}
|
||||
}
|
||||
|
||||
- (void) saveComponent: (iCalRepeatableEntityObject *) newObject
|
||||
- (void) updateComponent: (iCalRepeatableEntityObject *) newObject
|
||||
{
|
||||
NSString *newiCalString, *newUid;
|
||||
NSString *newUid;
|
||||
|
||||
if (!isNew
|
||||
&& [newObject isRecurrent])
|
||||
@@ -625,6 +625,11 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence,
|
||||
[eaMgr handleAlarmsInCalendar: [newObject parent]
|
||||
fromComponent: self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) saveComponent: (iCalRepeatableEntityObject *) newObject
|
||||
{
|
||||
NSString *newiCalString;
|
||||
|
||||
newiCalString = [[newObject parent] versitString];
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/* iCalEvent+SOGo.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2009 Inverse inc.
|
||||
* Copyright (C) 2007-2011 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Francis Lachapelle <flachapelle@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -31,6 +32,7 @@
|
||||
|
||||
- (BOOL) isStillRelevant;
|
||||
- (NSMutableDictionary *) quickRecord;
|
||||
- (void) updateRecurrenceRulesUntilDate: (NSCalendarDate *) previousEndDate;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import <NGExtensions/NGCalendarDateRange.h>
|
||||
@@ -35,6 +36,7 @@
|
||||
#import <NGCards/iCalTimeZone.h>
|
||||
#import <NGCards/iCalEvent.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
#import <NGCards/iCalRecurrenceRule.h>
|
||||
#import <NGCards/iCalTrigger.h>
|
||||
#import <NGCards/NSString+NGCards.h>
|
||||
|
||||
@@ -286,4 +288,55 @@
|
||||
return [[self endDate] timeIntervalSinceDate: [self startDate]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift the "until dates" of the recurrence rules of the event
|
||||
* with respect to the previous end date of the event.
|
||||
* @param previousEndDate the previous end date of the event
|
||||
*/
|
||||
- (void) updateRecurrenceRulesUntilDate: (NSCalendarDate *) previousEndDate
|
||||
{
|
||||
iCalRecurrenceRule *rule;
|
||||
NSEnumerator *rules;
|
||||
NSCalendarDate *untilDate;
|
||||
int offset;
|
||||
|
||||
// Recurrence rules
|
||||
rules = [[self recurrenceRules] objectEnumerator];
|
||||
while ((rule = [rules nextObject]))
|
||||
{
|
||||
untilDate = [rule untilDate];
|
||||
if (untilDate)
|
||||
{
|
||||
// The until date must match the time of the end date
|
||||
offset = [[self endDate] timeIntervalSinceDate: previousEndDate];
|
||||
untilDate = [untilDate dateByAddingYears:0
|
||||
months:0
|
||||
days:0
|
||||
hours:0
|
||||
minutes:0
|
||||
seconds:offset];
|
||||
[rule setUntilDate: untilDate];
|
||||
}
|
||||
}
|
||||
|
||||
// Exception rules
|
||||
rules = [[self exceptionRules] objectEnumerator];
|
||||
while ((rule = [rules nextObject]))
|
||||
{
|
||||
untilDate = [rule untilDate];
|
||||
if (untilDate)
|
||||
{
|
||||
// The until date must match the time of the end date
|
||||
offset = [[self endDate] timeIntervalSinceDate: previousEndDate];
|
||||
untilDate = [untilDate dateByAddingYears:0
|
||||
months:0
|
||||
days:0
|
||||
hours:0
|
||||
minutes:0
|
||||
seconds:offset];
|
||||
[rule setUntilDate: untilDate];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -161,9 +161,9 @@
|
||||
// Calculate the occurrences for the given date
|
||||
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: checkRange
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
recurrenceRules: [self recurrenceRules]
|
||||
exceptionRules: [self exceptionRules]
|
||||
exceptionDates: [self exceptionDatesWithEventTimeZone: eventTimeZone]];
|
||||
recurrenceRules: [self recurrenceRulesWithTimeZone: eventTimeZone]
|
||||
exceptionRules: [self exceptionRulesWithTimeZone: eventTimeZone]
|
||||
exceptionDates: [self exceptionDatesWithTimeZone: eventTimeZone]];
|
||||
doesOccur = [ranges dateRangeArrayContainsDate: startDate];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user