mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-04-03 12:28:51 +00:00
fix(calendar): properly store the vevent is the correct order for reccurence and reccurence-id
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import <NGCards/iCalEvent.h>
|
||||
#import <NGCards/iCalDateTime.h>
|
||||
#import <NGCards/iCalRepeatableEntityObject.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user