diff --git a/SoObjects/Appointments/iCalCalendar+SOGo.m b/SoObjects/Appointments/iCalCalendar+SOGo.m index 1b0d493e6..585a69d4f 100644 --- a/SoObjects/Appointments/iCalCalendar+SOGo.m +++ b/SoObjects/Appointments/iCalCalendar+SOGo.m @@ -25,6 +25,7 @@ #import #import +#import #import #import "iCalCalendar+SOGo.h" @@ -97,7 +98,29 @@ elements = [self allObjects]; count = [elements count]; if (count) + { element = [elements objectAtIndex: 0]; + if(count >1) + { + //If there more than one event, it may because there is the main reccurent event and some exceptions with reccurenceId + //It's important to fetch the "main" vevent and not the other. + NSEnumerator *elementEnum; + NSCalendarDate *recurrenceId; + CardGroup *elem; + elementEnum = [elements objectEnumerator]; + while((elem = [elementEnum nextObject])) + { + recurrenceId = [(iCalDateTime *) [elem uniqueChildWithTag: @"recurrence-id"] dateTime]; + if(recurrenceId) + continue; + else + { + element = elem; + break; + } + } + } + } else { //NSLog(@"ERROR: given calendar contains no elements: %@", self); diff --git a/UI/MailPartViewers/UIxMailPartICalActions.m b/UI/MailPartViewers/UIxMailPartICalActions.m index e3d5fa1fa..d886f034f 100644 --- a/UI/MailPartViewers/UIxMailPartICalActions.m +++ b/UI/MailPartViewers/UIxMailPartICalActions.m @@ -170,60 +170,95 @@ emailEvent = [self _emailEvent]; if (emailEvent) + { + *eventObject = [self _eventObjectWithUID: [emailEvent uid]]; + if ([*eventObject isNew]) { - *eventObject = [self _eventObjectWithUID: [emailEvent uid]]; - if ([*eventObject isNew]) - { - chosenEvent = emailEvent; - [*eventObject saveCalendar: [emailEvent parent]]; - } - else - { - if ([emailEvent recurrenceId]) - { - // Event attached to email is not complete -- retrieve it - // from the database. - NSString *recurrenceTime; - - recurrenceTime = [NSString stringWithFormat: @"%f", - [[emailEvent recurrenceId] timeIntervalSince1970]]; - calendarEvent = (iCalEvent *)[*eventObject lookupOccurrence: recurrenceTime]; - } - else - calendarEvent = (iCalEvent *) [*eventObject component: NO secure: NO]; - - if (calendarEvent != nil) - { - // Calendar event still exists -- verify which of the calendar - // and email events is the most recent. We must also update - // the event (or recurrence-id) with the email's content, otherwise - // we would never get major properties updates - if ([calendarEvent compare: emailEvent] == NSOrderedAscending) - { - iCalCalendar *parent; - - parent = [calendarEvent parent]; - [parent removeChild: calendarEvent]; - [parent addChild: emailEvent]; - [*eventObject saveCalendar: parent]; - [*eventObject flush]; - chosenEvent = emailEvent; - } - else - { - chosenEvent = calendarEvent; - if (![[[chosenEvent parent] method] length]) - [[chosenEvent parent] setMethod: [[emailEvent parent] method]]; - } - } - else - chosenEvent = emailEvent; - } - - organizer = [chosenEvent organizer]; - if (![[organizer rfc822Email] length]) - [self _fixOrganizerInEvent: chosenEvent]; + chosenEvent = emailEvent; + [*eventObject saveCalendar: [emailEvent parent]]; } + else + { + if ([emailEvent recurrenceId]) + { + // Event attached to email is not complete -- retrieve it + // from the database. + NSString *recurrenceTime; + + recurrenceTime = [NSString stringWithFormat: @"%f", + [[emailEvent recurrenceId] timeIntervalSince1970]]; + calendarEvent = (iCalEvent *)[*eventObject lookupOccurrence: recurrenceTime]; + } + else + calendarEvent = (iCalEvent *) [*eventObject component: NO secure: NO]; + + if (calendarEvent != nil) + { + // Calendar event still exists -- verify which of the calendar + // and email events is the most recent. We must also update + // the event (or recurrence-id) with the email's content, otherwise + // we would never get major properties updates + if ([calendarEvent compare: emailEvent] == NSOrderedAscending) + { + iCalCalendar *parent; + parent = [calendarEvent parent]; + + //careful, sogo vcalendar objets for reccurent event needs to have the main event first, then all the vevent with reccurence-id + if(![emailEvent hasRecurrenceRules] || [emailEvent recurrenceId]) + { + [parent removeChild: calendarEvent]; + [parent addChild: emailEvent]; + } + else + { + //The main recurrent event has been changed, put it first and also change all the exception with the correct reccurence-id + NSMutableArray *childrenNew; + NSEnumerator *childrenOldEnum, *childrenNewEnum; + iCalEvent *child; + NSCalendarDate *oldStartDate, *newStartDate, *recId; + NSTimeInterval interval; + + oldStartDate = [calendarEvent startDate]; + newStartDate = [emailEvent startDate]; + interval = [newStartDate timeIntervalSinceDate: oldStartDate]; + + [parent removeChild: calendarEvent]; + childrenNew = [NSMutableArray array]; + childrenOldEnum = [[parent childrenWithTag:@"vevent"] objectEnumerator]; + while((child = [childrenOldEnum nextObject])) + { + [parent removeChild: child]; + if((recId = [child recurrenceId])) + [child setRecurrenceId: [recId dateByAddingTimeInterval: interval]]; + [childrenNew addObject: child]; + } + [parent addChild: emailEvent]; + childrenNewEnum = [childrenNew objectEnumerator]; + while((child = [childrenNewEnum nextObject])) + { + [parent addChild: child]; + } + } + + [*eventObject saveCalendar: parent]; + [*eventObject flush]; + chosenEvent = emailEvent; + } + else + { + chosenEvent = calendarEvent; + if (![[[chosenEvent parent] method] length]) + [[chosenEvent parent] setMethod: [[emailEvent parent] method]]; + } + } + else + chosenEvent = emailEvent; + } + + organizer = [chosenEvent organizer]; + if (![[organizer rfc822Email] length]) + [self _fixOrganizerInEvent: chosenEvent]; + } else chosenEvent = nil;