From 30f832a3754c108edbecc844433a63fe174dc431 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 5 Dec 2008 16:11:41 +0000 Subject: [PATCH] Monotone-Parent: 13af0049df662f524304f42aacc2ca3dda868fc6 Monotone-Revision: 9644df847f3d64262029a478a7508355366a0d57 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2008-12-05T16:11:41 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 24 ++++++++- .../Appointments/SOGoAppointmentObject.m | 38 ++++++++----- .../Appointments/SOGoCalendarComponent.m | 53 ++++++++++++++----- .../Appointments/SOGoComponentOccurence.m | 39 +++++++++++--- 4 files changed, 120 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index e0e014cf1..16fad2a19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2008-12-05 Francis Lachapelle + + * SoObjects/Appointments/SOGoCalendarComponent.m + ([SOGoCalendarComponent -_updateRecurrenceIDsWithEvent:]): fixed + modification of the new event and added adjustement of the + exception dates. + + * SoObjects/Appointments/SOGoAppointmentObject.m + ([SOGoAppointmentObject + _removeEventFromUID:owner:withRecurrenceId:]): for a repeating + event, the occurrence was not properly removed. + + * SoObjects/Appointments/SOGoComponentOccurence.m + ([SOGoComponentOccurence prepareDelete]): for a repeating event, + the exception date was not added and the occurence was not + properly deleted. + + * UI/MailPartViewers/UIxMailPartICalViewer.m + ([UIxMailPartICalViewer isEventStoredInCalendar]): when dealing + with an occurence of a repeating event, the function now properly + verify the presence of the occurence and not only the event. + 2008-12-05 Ludovic Marcotte * SOPE/NGCards/NSString+NGCards.m @@ -13,7 +35,7 @@ 2008-12-03 Francis Lachapelle * UI/MailPartViewers/UIxMailPartICalViewer.m - ([UIxMailPartICalViewer -storedEvent): returns the occurence of + ([UIxMailPartICalViewer -storedEvent]): returns the occurence of the repeating event if recurrenceId is defined. * UI/MailPartViewers/UIxMailPartICalActions.m diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index 5163f0a7e..d1fa4a833 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -205,7 +205,6 @@ } } -#warning what about occurences? - (void) _removeEventFromUID: (NSString *) theUID owner: (NSString *) theOwner withRecurrenceId: (NSCalendarDate *) recurrenceId @@ -214,10 +213,13 @@ { SOGoAppointmentFolder *folder; SOGoAppointmentObject *object; - iCalEntityObject *occurence; + iCalEntityObject *currentOccurence; iCalRepeatableEntityObject *event; iCalCalendar *calendar; - NSString *recurrenceTime, *calendarContent; + NSMutableArray *occurences; + NSCalendarDate *currentId; + NSString *calendarContent; + int max, count; folder = [container lookupCalendarFolderForUID: theUID]; object = [folder lookupName: nameInContainer @@ -228,22 +230,31 @@ [object delete]; else { - // If recurrenceId is defined, find the specified occurence - // within the repeating vEvent. - recurrenceTime = [NSString stringWithFormat: @"%f", [recurrenceId timeIntervalSince1970]]; - occurence = [object lookupOccurence: recurrenceTime]; - if (occurence != nil) + calendar = [object calendar: NO secure: NO]; + + // If recurrenceId is defined, remove the occurence from + // the repeating event. + occurences = [calendar events]; + max = [occurences count]; + count = 1; + while (count < max) { - // The occurence is defined -- remove it. - calendar = [occurence parent]; - [[calendar children] removeObject: occurence]; + currentOccurence = [occurences objectAtIndex: count]; + currentId = [currentOccurence recurrenceId]; + if ([currentId compare: recurrenceId] == NSOrderedSame) + { + [[calendar children] removeObject: currentOccurence]; + break; + } + count++; } - // Add an date exception - calendar = [object calendar: NO secure: NO]; + // Add an date exception. event = (iCalRepeatableEntityObject*)[calendar firstChildWithTag: [object componentTag]]; [event addToExceptionDates: recurrenceId]; + [event increaseSequence]; + // We generate the updated iCalendar file and we save it // in the database. calendarContent = [calendar versitString]; @@ -431,6 +442,7 @@ else { // Event is modified -- sent update status to all attendees + // and modify their calendars. recurrenceId = [newEvent recurrenceId]; if (recurrenceId == nil) oldEvent = [self component: NO secure: NO]; diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index 0b06535f0..9c97303d4 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -33,6 +33,7 @@ #import #import #import +#import #import #import #import @@ -384,26 +385,52 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID) firstChildWithTag: [self componentTag]]; } -- (void) _updateRecurrenceIDs +- (void) _updateRecurrenceIDsWithEvent: (iCalRepeatableEntityObject*) newEvent { - iCalRepeatableEntityObject *master, *oldMaster, *currentComponent; + iCalRepeatableEntityObject *oldMaster, *currentComponent; + iCalDateTime *currentDate; int deltaSecs; - NSArray *components; + NSArray *components, *dates; + NSMutableArray *newDates; unsigned int count, max; - NSCalendarDate *recID; + NSCalendarDate *recID, *newDate; - master = [self component: NO secure: NO]; + // Compute time interval from previous event definition. oldMaster = (iCalRepeatableEntityObject *) [originalCalendar firstChildWithTag: [self componentTag]]; - deltaSecs = [[master startDate] + deltaSecs = [[newEvent startDate] timeIntervalSinceDate: [oldMaster startDate]]; - components = [fullCalendar allObjects]; + + components = [[newEvent parent] events]; max = [components count]; - for (count = 1; count < max; count++) + + if (max > 0) { - currentComponent = [components objectAtIndex: count]; - recID = [[currentComponent recurrenceId] addTimeInterval: deltaSecs]; - [currentComponent setRecurrenceId: recID]; + // Update recurrence-id attribute of occurences. + for (count = 1; count < max; count++) + { + currentComponent = [components objectAtIndex: count]; + recID = [[currentComponent recurrenceId] addTimeInterval: deltaSecs]; + [currentComponent setRecurrenceId: recID]; + } + + // Update exception dates in master vEvent. + currentComponent = [components objectAtIndex: 0]; + dates = [currentComponent childrenWithTag: @"exdate"]; + max = [dates count]; + if (max > 0) + { + newDates = [NSMutableArray arrayWithCapacity: max]; + for (count = 0; count < max; count++) + { + currentDate = [dates objectAtIndex: count]; + newDate = [[currentDate dateTime] addTimeInterval: deltaSecs]; + [newDates addObject: newDate]; + } + [currentComponent removeAllExceptionDates]; + for (count = 0; count < max; count++) + [currentComponent addToExceptionDates: [newDates objectAtIndex: count]]; + } } } @@ -413,7 +440,9 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID) if (!isNew && [newObject isRecurrent]) - [self _updateRecurrenceIDs]; + // We update an repeating event -- update exception dates + // and recurrence-ids. + [self _updateRecurrenceIDsWithEvent: newObject]; // As much as we can, we try to use c_name == c_uid in order // to avoid tricky scenarios with some CalDAV clients. For example, diff --git a/SoObjects/Appointments/SOGoComponentOccurence.m b/SoObjects/Appointments/SOGoComponentOccurence.m index bf6b111ee..58d65eb2b 100644 --- a/SoObjects/Appointments/SOGoComponentOccurence.m +++ b/SoObjects/Appointments/SOGoComponentOccurence.m @@ -139,8 +139,13 @@ - (NSException *) prepareDelete; { + NSMutableArray *occurences; + NSCalendarDate *recurrenceId, *currentId; NSException *error; - iCalCalendar *parent; + NSString *newContent; + iCalCalendar *calendar; + iCalEntityObject *currentOccurence; + int max, count; if (component == master) error = [container delete]; @@ -149,14 +154,32 @@ if ([container respondsToSelector: @selector (prepareDeleteOccurence:)]) [container prepareDeleteOccurence: component]; - [master addToExceptionDates: [component startDate]]; - parent = [component parent]; - [[parent children] removeObject: component]; - - // changes participant status & send invitation email - as if it was a new event! :( - [container saveComponent: master]; + // Add an date exception + recurrenceId = [component recurrenceId]; + [master addToExceptionDates: recurrenceId]; + [master increaseSequence]; - error = nil; + // Remove the specified occurence within the repeating vEvent. + calendar = [master parent]; + occurences = [calendar events]; + max = [occurences count]; + count = 1; + while (count < max) + { + currentOccurence = [occurences objectAtIndex: count]; + currentId = [currentOccurence recurrenceId]; + if ([currentId compare: recurrenceId] == NSOrderedSame) + { + [[calendar children] removeObject: currentOccurence]; + break; + } + count++; + } + + // We generate the updated iCalendar file and we save it + // in the database. + newContent = [calendar versitString]; + error = [container saveContentString: newContent]; } return error;