diff --git a/ChangeLog b/ChangeLog index 0dcca9839..8be121787 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2012-06-19 Ludovic Marcotte + + * SoObjects/Appointments/SOGoAppointmentFolder.m (-importCalendar:): + We now handle correctly floating events by forcing the use of + the user's timezone. + + * SoObjects/Appointments/SOGoCalendarComponent.m (-expandGroupsInEvent:): + We now remove all attendees that are equal (email-based comparison) to + the event's organizer instead of only for decomposed groups. + 2012-06-12 Wolfgang Sourdeau * SoObjects/SOGo/SOGoGroup.m diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index d0b0b0969..0a2dd4b18 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -2764,7 +2764,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir iCalEvent *event; int imported, count, i; - + imported = 0; if (calendar) @@ -2799,6 +2799,41 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir tzId = [startDate value: 0 ofAttribute: @"tzid"]; if ([tzId length]) timezone = [timezones valueForKey: tzId]; + else + { + // If the start date is a "floating time", let's use the user's timezone + // during the import for both the start and end dates. + NSString *s; + + s = [[startDate valuesAtIndex: 0 forKey: @""] objectAtIndex: 0]; + + if ([element isKindOfClass: [iCalEvent class]] && + ![(iCalEvent *)element isAllDay] && + ![s hasSuffix: @"Z"] && + ![s hasSuffix: @"z"]) + { + iCalDateTime *endDate; + int delta; + + timezone = [iCalTimeZone timeZoneForName: [[[self->context activeUser] userDefaults] timeZoneName]]; + [calendar addTimeZone: timezone]; + + delta = [[timezone periodForDate: [startDate dateTime]] secondsOffsetFromGMT]; + event = (iCalEvent *)element; + + [event setStartDate: [[event startDate] dateByAddingYears: 0 months: 0 days: 0 hours: 0 minutes: 0 seconds: -delta]]; + [startDate setTimeZone: timezone]; + + endDate = (iCalDateTime *) [element uniqueChildWithTag: @"dtend"]; + + if (endDate) + { + [event setEndDate: [[event endDate] dateByAddingYears: 0 months: 0 days: 0 hours: 0 minutes: 0 seconds: -delta]]; + [endDate setTimeZone: timezone]; + } + } + } + if ([element isKindOfClass: [iCalEvent class]]) { event = (iCalEvent *)element; diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index 2bedbaa9d..9719dcab2 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -516,19 +516,23 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, // // Returs "YES" if a a group was decomposed among attendees. // +// It can also return yes if an attendee was found in the list +// matching the organizer. In which case, it was removed. +// - (BOOL) expandGroupsInEvent: (iCalEvent *) theEvent { - NSMutableArray *allAttendees; - NSEnumerator *enumerator; NSString *organizerEmail, *domain; + NSMutableArray *allAttendees; iCalPerson *currentAttendee; + NSEnumerator *enumerator; SOGoGroup *group; - BOOL doesIncludeGroup; + + BOOL eventWasModified; unsigned int i; domain = [[context activeUser] domain]; organizerEmail = [[theEvent organizer] rfc822Email]; - doesIncludeGroup = NO; + eventWasModified = NO; allAttendees = [NSMutableArray arrayWithArray: [theEvent attendees]]; enumerator = [[theEvent attendees] objectEnumerator]; while ((currentAttendee = [enumerator nextObject])) @@ -548,7 +552,7 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, for (i = 0; i < [members count]; i++) { user = [members objectAtIndex: i]; - doesIncludeGroup = YES; + eventWasModified = YES; // If the organizer is part of the group, we skip it from // the addition to the attendees' list @@ -565,12 +569,23 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, [allAttendees addObject: person]; } } - } + else + { + // We remove any attendees matching the organizer. Apple iCal will do that when + // you invite someone. It'll add the organizer in the attendee list, which will + // confuse itself! + if ([[currentAttendee rfc822Email] caseInsensitiveCompare: organizerEmail] == NSOrderedSame) + { + [allAttendees removeObject: currentAttendee]; + eventWasModified = YES; + } + } + } // while (currentAttendee ... - if (doesIncludeGroup) + if (eventWasModified) [theEvent setAttendees: allAttendees]; - return doesIncludeGroup; + return eventWasModified; } - (void) _updateRecurrenceIDsWithEvent: (iCalRepeatableEntityObject*) newEvent