Merge pull request #101 from Zentyal/ejhernandez/recurrence-exceptions-fixes

Two fixes on recurring events
pull/65/head
Jesús García Sáez 2015-03-18 18:05:06 +01:00
commit b0ba6f4a22
4 changed files with 68 additions and 34 deletions

2
NEWS
View File

@ -5,6 +5,8 @@ Enhancements
- Improve sync speed from Outlook by non-reprocessing already downloaded unread mails
Bug fixes
- Weekly recurring events created in SOGo web interface are now shown in Outlook
- Fix exception modifications import in recurrence series
- Sent mails are not longer in Drafts folder using Outlook
- Fix server side crash parsing rtf emails with images (with word97 format)

View File

@ -25,6 +25,8 @@
#include <talloc.h>
#import <Foundation/NSTimeZone.h>
#import <NGCards/iCalCalendar.h>
#import <NGCards/iCalRecurrenceRule.h>
@ -41,7 +43,10 @@
@interface iCalCalendar (MAPIStoreRecurrence)
- (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity
fromRecurrencePattern: (struct RecurrencePattern *) rp;
fromRecurrencePattern: (struct RecurrencePattern *) rp
withExceptions: (struct ExceptionInfo *) exInfos
andExceptionCount: (uint16_t) exInfoCount
inTimeZone: (NSTimeZone *) tz;
@end

View File

@ -24,6 +24,7 @@
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>
#import <NGExtensions/NSCalendarDate+misc.h>
#import <NGExtensions/NSObject+Logs.h>
@ -48,6 +49,10 @@
- (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity
fromRecurrencePattern: (struct RecurrencePattern *) rp
withExceptions: (struct ExceptionInfo *) exInfos
andExceptionCount: (uint16_t) exInfoCount
inTimeZone: (NSTimeZone *) tz
{
NSCalendarDate *startDate, *olEndDate, *untilDate, *exDate;
NSString *monthDay, *month;
@ -214,34 +219,42 @@
/* exception dates:
- take all deleted instances
- remove all modified instances from the above set
- remove all modified instances available in ExceptionInfo from the above set
- add remaining instances, in chronological order
*/
exceptionDates = [NSMutableSet set];
for (count = 0; count < rp->DeletedInstanceCount; count++)
{
exDate
= [NSDate dateFromMinutesSince1601: rp->DeletedInstanceDates[count]];
exDate = [exDate hour: [startDate hourOfDay]
minute: [startDate minuteOfHour]
second: [startDate secondOfMinute]];
[exceptionDates addObject: exDate];
}
for (count = 0; count < rp->ModifiedInstanceCount; count++)
{
exDate
= [NSDate dateFromMinutesSince1601: rp->ModifiedInstanceDates[count]];
exDate = [exDate hour: [startDate hourOfDay]
minute: [startDate minuteOfHour]
second: [startDate secondOfMinute]];
[exceptionDates removeObject: exDate];
}
realExDates = [[exceptionDates allObjects]
sortedArrayUsingSelector: @selector (compare:)];
max = [realExDates count];
for (count = 0; count < max; count++)
[entity addToExceptionDates: [realExDates objectAtIndex: count]];
/* Heuristic to avoid these loops */
if (rp->DeletedInstanceCount != rp->ModifiedInstanceCount) {
exceptionDates = [NSMutableSet set];
for (count = 0; count < rp->DeletedInstanceCount; count++)
{
exDate
= [NSDate dateFromMinutesSince1601: rp->DeletedInstanceDates[count]];
exDate = [exDate hour: [startDate hourOfDay]
minute: [startDate minuteOfHour]
second: [startDate secondOfMinute]];
[exceptionDates addObject: exDate];
}
/* Read the exceptions to remove the instances that are modified and not deleted */
if (exInfos && exInfoCount > 0)
{
for (count = 0; count < exInfoCount; count++)
{
/* The OriginalStartDate is in local time */
exDate = [NSDate dateFromMinutesSince1601: exInfos[count].OriginalStartDate];
exDate = [exDate dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0
seconds: - [tz secondsFromGMT]];
[exceptionDates removeObject: exDate];
}
}
realExDates = [[exceptionDates allObjects]
sortedArrayUsingSelector: @selector (compare:)];
max = [realExDates count];
for (count = 0; count < max; count++)
[entity addToExceptionDates: [realExDates objectAtIndex: count]];
}
}
@end
@ -312,15 +325,25 @@
rp->RecurFrequency = RecurFrequency_Weekly;
rp->PatternType = PatternType_Week;
rp->Period = repeatInterval;
dayOfWeek = [startDate dayOfWeek];
mask = 0;
byDayMask = [self byDayMask];
for (count = 0; count < 7; count++)
if ([byDayMask occursOnDay: count])
mask |= 1 << count;
if (byDayMask)
{
for (count = 0; count < 7; count++)
if ([byDayMask occursOnDay: count])
mask |= 1 << count;
}
else
{
/* Set the recurrence pattern using start date */
mask |= 1 << dayOfWeek;
}
rp->PatternTypeSpecific.WeekRecurrencePattern = mask;
/* FirstDateTime */
dayOfWeek = [startDate dayOfWeek];
if (dayOfWeek)
beginOfWeek = [startDate dateByAddingYears: 0 months: 0
days: -dayOfWeek

View File

@ -74,6 +74,7 @@
@implementation iCalEvent (MAPIStoreProperties)
- (void) _setupEventRecurrence: (NSData *) mapiRecurrenceData
inTimeZone: (NSTimeZone *) tz
inMemCtx: (TALLOC_CTX *) memCtx
{
struct Binary_r *blob;
@ -87,9 +88,12 @@
return;
}
[(iCalCalendar *) parent
setupRecurrenceWithMasterEntity: self
fromRecurrencePattern: &pattern->RecurrencePattern];
[(iCalCalendar *) parent setupRecurrenceWithMasterEntity: self
fromRecurrencePattern: &pattern->RecurrencePattern
withExceptions: pattern->ExceptionInfo
andExceptionCount: pattern->ExceptionCount
inTimeZone: tz
];
//talloc_free (blob);
}
@ -362,7 +366,7 @@
value = [properties
objectForKey: MAPIPropertyKey (PidLidAppointmentRecur)];
if (value)
[self _setupEventRecurrence: value inMemCtx: memCtx];
[self _setupEventRecurrence: value inTimeZone: userTimeZone inMemCtx: memCtx];
/* alarm */
[self _setupEventAlarmFromProperties: properties];