Monotone-Parent: 5b4e61e92b3d68b92ea25f1513eb120e502250a1
Monotone-Revision: 1e529d97ad640de07982d342ce216985cba625f7 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-07-20T15:44:25 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
965cd9379e
commit
1476b93a45
|
@ -115,6 +115,30 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) _setupAttachmentParts
|
||||||
|
{
|
||||||
|
NSUInteger count, max;
|
||||||
|
NSArray *events;
|
||||||
|
NSString *newKey;
|
||||||
|
MAPIStoreCalendarAttachment *attachment;
|
||||||
|
NSUInteger aid;
|
||||||
|
|
||||||
|
events = [calendar events];
|
||||||
|
max = [events count];
|
||||||
|
for (count = 1; count < max; count++)
|
||||||
|
{
|
||||||
|
attachment = [MAPIStoreCalendarAttachment
|
||||||
|
mapiStoreObjectInContainer: self];
|
||||||
|
/* we now that there are no attachments yet, so we can assume that the
|
||||||
|
right AID is 0 from the start */
|
||||||
|
aid = count - 1;
|
||||||
|
[attachment setAID: aid];
|
||||||
|
[attachment setEvent: [events objectAtIndex: count]];
|
||||||
|
newKey = [NSString stringWithFormat: @"%ul", aid];
|
||||||
|
[attachmentParts setObject: attachment forKey: newKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (id) initWithSOGoObject: (id) newSOGoObject
|
- (id) initWithSOGoObject: (id) newSOGoObject
|
||||||
inContainer: (MAPIStoreObject *) newFolder
|
inContainer: (MAPIStoreObject *) newFolder
|
||||||
{
|
{
|
||||||
|
@ -140,6 +164,7 @@
|
||||||
origCalendar = [sogoObject calendar: YES secure: YES];
|
origCalendar = [sogoObject calendar: YES secure: YES];
|
||||||
calendar = [origCalendar mutableCopy];
|
calendar = [origCalendar mutableCopy];
|
||||||
masterEvent = [[calendar events] objectAtIndex: 0];
|
masterEvent = [[calendar events] objectAtIndex: 0];
|
||||||
|
[self _setupAttachmentParts];
|
||||||
}
|
}
|
||||||
context = [self context];
|
context = [self context];
|
||||||
userContext = [self userContext];
|
userContext = [self userContext];
|
||||||
|
@ -397,9 +422,51 @@
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) _updateAttachedEvent: (MAPIStoreCalendarAttachment *) attachment
|
||||||
|
withUID: (NSString *) uid
|
||||||
{
|
{
|
||||||
iCalEvent *newEvent;
|
iCalEvent *newEvent;
|
||||||
|
SOGoUser *activeUser;
|
||||||
|
|
||||||
|
newEvent = [iCalEvent groupWithTag: @"vevent"];
|
||||||
|
[calendar addToEvents: newEvent];
|
||||||
|
activeUser = [[self context] activeUser];
|
||||||
|
[newEvent setUid: uid];
|
||||||
|
[newEvent updateFromMAPIProperties: [attachment properties]
|
||||||
|
inUserContext: [self userContext]
|
||||||
|
withActiveUser: activeUser];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _updateAttachedEvents
|
||||||
|
{
|
||||||
|
NSMutableArray *otherEvents;
|
||||||
|
NSArray *allAttachments;
|
||||||
|
NSUInteger count, max;
|
||||||
|
NSString *uid;
|
||||||
|
|
||||||
|
/* cleanup all recurring events */
|
||||||
|
otherEvents = [[calendar events] mutableCopy];
|
||||||
|
[otherEvents removeObject: masterEvent];
|
||||||
|
[calendar removeChildren: otherEvents];
|
||||||
|
[otherEvents release];
|
||||||
|
|
||||||
|
uid = [masterEvent uid];
|
||||||
|
|
||||||
|
allAttachments = [attachmentParts allValues];
|
||||||
|
max = [allAttachments count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
[self _updateAttachedEvent: [allAttachments objectAtIndex: count]
|
||||||
|
withUID: uid];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) save
|
||||||
|
{
|
||||||
|
// iCalCalendar *vCalendar;
|
||||||
|
// NSCalendarDate *now;
|
||||||
|
NSString *uid;
|
||||||
|
// iCalEvent *newEvent;
|
||||||
// iCalPerson *userPerson;
|
// iCalPerson *userPerson;
|
||||||
|
SOGoUser *activeUser;
|
||||||
|
|
||||||
if (isNew)
|
if (isNew)
|
||||||
{
|
{
|
||||||
|
@ -429,6 +496,7 @@
|
||||||
[masterEvent updateFromMAPIProperties: properties
|
[masterEvent updateFromMAPIProperties: properties
|
||||||
inUserContext: [self userContext]
|
inUserContext: [self userContext]
|
||||||
withActiveUser: activeUser];
|
withActiveUser: activeUser];
|
||||||
|
[self _updateAttachedEvents];
|
||||||
[sogoObject updateContentWithCalendar: calendar
|
[sogoObject updateContentWithCalendar: calendar
|
||||||
fromRequest: nil];
|
fromRequest: nil];
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#import <Foundation/NSArray.h>
|
#import <Foundation/NSArray.h>
|
||||||
#import <Foundation/NSCalendarDate.h>
|
#import <Foundation/NSCalendarDate.h>
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
#import <Foundation/NSURL.h>
|
#import <Foundation/NSURL.h>
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
@ -45,7 +46,7 @@
|
||||||
#include <mapistore/mapistore.h>
|
#include <mapistore/mapistore.h>
|
||||||
#include <mapistore/mapistore_errors.h>
|
#include <mapistore/mapistore_errors.h>
|
||||||
|
|
||||||
static Class EOKeyValueQualifierK;
|
static Class EOKeyValueQualifierK, SOGoMAPIDBFolderK;
|
||||||
|
|
||||||
static NSString *MAPIStoreRightReadItems = @"RightsReadItems";
|
static NSString *MAPIStoreRightReadItems = @"RightsReadItems";
|
||||||
static NSString *MAPIStoreRightCreateItems = @"RightsCreateItems";
|
static NSString *MAPIStoreRightCreateItems = @"RightsCreateItems";
|
||||||
|
@ -62,6 +63,7 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
EOKeyValueQualifierK = [EOKeyValueQualifier class];
|
EOKeyValueQualifierK = [EOKeyValueQualifier class];
|
||||||
|
SOGoMAPIDBFolderK = [SOGoMAPIDBFolder class];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setupAuxiliaryObjects
|
- (void) setupAuxiliaryObjects
|
||||||
|
@ -84,9 +86,40 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
|
||||||
withFID: (uint64_t) newFID
|
withFID: (uint64_t) newFID
|
||||||
andKey: (NSString **) newKeyP
|
andKey: (NSString **) newKeyP
|
||||||
{
|
{
|
||||||
*newKeyP = [NSString stringWithFormat: @"0x%.16"PRIx64, (unsigned long long) newFID];
|
enum mapistore_error rc;
|
||||||
|
NSString *folderName, *nameInContainer;
|
||||||
|
SOGoMAPIDBFolder *newFolder;
|
||||||
|
struct SPropValue *value;
|
||||||
|
|
||||||
return MAPISTORE_SUCCESS;
|
value = get_SPropValue_SRow (aRow, PidTagDisplayName);
|
||||||
|
if (value)
|
||||||
|
folderName = [NSString stringWithUTF8String: value->value.lpszW];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = get_SPropValue_SRow (aRow, PidTagDisplayName_string8);
|
||||||
|
if (value)
|
||||||
|
folderName = [NSString stringWithUTF8String: value->value.lpszA];
|
||||||
|
else
|
||||||
|
folderName = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (folderName)
|
||||||
|
{
|
||||||
|
nameInContainer = [NSString stringWithFormat: @"0x%.16"PRIx64,
|
||||||
|
(unsigned long long) newFID];
|
||||||
|
newFolder = [SOGoMAPIDBFolderK objectWithName: nameInContainer
|
||||||
|
inContainer: sogoObject];
|
||||||
|
[newFolder setIsNew: YES];
|
||||||
|
[[newFolder properties] setObject: folderName
|
||||||
|
forKey: MAPIPropertyKey (PidTagDisplayName)];
|
||||||
|
[newFolder save];
|
||||||
|
*newKeyP = nameInContainer;
|
||||||
|
rc = MAPISTORE_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = MAPISTORE_ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MAPIStoreMessage *) createMessage
|
- (MAPIStoreMessage *) createMessage
|
||||||
|
@ -134,6 +167,15 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
|
||||||
andSortOrderings: sortOrderings];
|
andSortOrderings: sortOrderings];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: now that we are DB-based, this method can easily be implemented
|
||||||
|
|
||||||
|
- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum
|
||||||
|
andCN: (NSNumber **) cnNbrs
|
||||||
|
inTableType: (enum mapistore_table_type) tableType
|
||||||
|
{
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
- (NSDate *) lastMessageModificationTime
|
- (NSDate *) lastMessageModificationTime
|
||||||
{
|
{
|
||||||
NSUInteger count, max;
|
NSUInteger count, max;
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include <mapistore/mapistore_errors.h>
|
#include <mapistore/mapistore_errors.h>
|
||||||
|
|
||||||
static NSString *resourcesDir = nil;
|
static NSString *resourcesDir = nil;
|
||||||
|
static Class MAPIStoreFolderK = nil;
|
||||||
|
|
||||||
/* rtf conversion via unrtf */
|
/* rtf conversion via unrtf */
|
||||||
static int
|
static int
|
||||||
|
@ -130,6 +131,7 @@ rtf2html (NSData *compressedRTF)
|
||||||
resourcesDir = [[NSBundle bundleForClass: self] resourcePath];
|
resourcesDir = [[NSBundle bundleForClass: self] resourcePath];
|
||||||
[resourcesDir retain];
|
[resourcesDir retain];
|
||||||
}
|
}
|
||||||
|
MAPIStoreFolderK = [MAPIStoreFolder class];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) init
|
- (id) init
|
||||||
|
@ -442,6 +444,8 @@ rtf2html (NSData *compressedRTF)
|
||||||
|| (!isNew && [self subscriberCanModifyMessage])))
|
|| (!isNew && [self subscriberCanModifyMessage])))
|
||||||
{
|
{
|
||||||
/* notifications */
|
/* notifications */
|
||||||
|
if ([container isKindOfClass: MAPIStoreFolderK])
|
||||||
|
{
|
||||||
folderId = [(MAPIStoreFolder *) container objectId];
|
folderId = [(MAPIStoreFolder *) container objectId];
|
||||||
mstoreCtx = [[self context] connectionInfo]->mstore_ctx;
|
mstoreCtx = [[self context] connectionInfo]->mstore_ctx;
|
||||||
|
|
||||||
|
@ -462,7 +466,8 @@ rtf2html (NSData *compressedRTF)
|
||||||
= [[(MAPIStoreFolder *) container messageKeys] count] + 1;
|
= [[(MAPIStoreFolder *) container messageKeys] count] + 1;
|
||||||
}
|
}
|
||||||
mapistore_push_notification (mstoreCtx,
|
mapistore_push_notification (mstoreCtx,
|
||||||
MAPISTORE_FOLDER, MAPISTORE_OBJECT_MODIFIED,
|
MAPISTORE_FOLDER,
|
||||||
|
MAPISTORE_OBJECT_MODIFIED,
|
||||||
notif_parameters);
|
notif_parameters);
|
||||||
talloc_free (notif_parameters);
|
talloc_free (notif_parameters);
|
||||||
|
|
||||||
|
@ -488,15 +493,19 @@ rtf2html (NSData *compressedRTF)
|
||||||
max = [containerTables count];
|
max = [containerTables count];
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
[[containerTables objectAtIndex: count] restrictedChildKeys];
|
[[containerTables objectAtIndex: count] restrictedChildKeys];
|
||||||
|
}
|
||||||
|
|
||||||
[self save];
|
[self save];
|
||||||
|
|
||||||
|
if ([container isKindOfClass: MAPIStoreFolderK])
|
||||||
|
{
|
||||||
/* table modified */
|
/* table modified */
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
[[containerTables objectAtIndex: count]
|
[[containerTables objectAtIndex: count]
|
||||||
notifyChangesForChild: self];
|
notifyChangesForChild: self];
|
||||||
[self setIsNew: NO];
|
|
||||||
[container cleanupCaches];
|
[container cleanupCaches];
|
||||||
|
}
|
||||||
|
[self setIsNew: NO];
|
||||||
rc = MAPISTORE_SUCCESS;
|
rc = MAPISTORE_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -645,9 +654,19 @@ rtf2html (NSData *compressedRTF)
|
||||||
- (int) getPidTagMid: (void **) data
|
- (int) getPidTagMid: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
*data = MAPILongLongValue (memCtx, [self objectId]);
|
int rc;
|
||||||
|
uint64_t obId;
|
||||||
|
|
||||||
return MAPISTORE_SUCCESS;
|
obId = [self objectId];
|
||||||
|
if (obId == ULLONG_MAX)
|
||||||
|
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*data = MAPILongLongValue (memCtx, obId);
|
||||||
|
rc = MAPISTORE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) getPidTagMessageLocaleId: (void **) data
|
- (int) getPidTagMessageLocaleId: (void **) data
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "MAPIStorePropertySelectors.h"
|
#import "MAPIStorePropertySelectors.h"
|
||||||
|
#import "NSString+MAPIStore.h"
|
||||||
|
|
||||||
#import "MAPIStoreObjectProxy.h"
|
#import "MAPIStoreObjectProxy.h"
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#import <Foundation/NSArray.h>
|
#import <Foundation/NSArray.h>
|
||||||
#import <Foundation/NSCalendarDate.h>
|
#import <Foundation/NSCalendarDate.h>
|
||||||
|
#import <Foundation/NSSet.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
|
|
||||||
#import <NGExtensions/NSCalendarDate+misc.h>
|
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||||
|
@ -50,11 +51,13 @@
|
||||||
{
|
{
|
||||||
NSCalendarDate *startDate, *olEndDate, *untilDate, *exDate;
|
NSCalendarDate *startDate, *olEndDate, *untilDate, *exDate;
|
||||||
NSString *monthDay, *month;
|
NSString *monthDay, *month;
|
||||||
|
NSMutableSet *exceptionDates;
|
||||||
|
NSArray *realExDates;
|
||||||
iCalRecurrenceRule *rule;
|
iCalRecurrenceRule *rule;
|
||||||
iCalByDayMask *byDayMask;
|
iCalByDayMask *byDayMask;
|
||||||
iCalWeekOccurrence weekOccurrence;
|
iCalWeekOccurrence weekOccurrence;
|
||||||
iCalWeekOccurrences dayMaskDays;
|
iCalWeekOccurrences dayMaskDays;
|
||||||
NSUInteger count;
|
NSUInteger count, max;
|
||||||
NSInteger bySetPos;
|
NSInteger bySetPos;
|
||||||
unsigned char maskValue;
|
unsigned char maskValue;
|
||||||
|
|
||||||
|
@ -209,7 +212,12 @@
|
||||||
rp->EndType];
|
rp->EndType];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* exception dates */
|
/* exception dates:
|
||||||
|
- take all deleted instances
|
||||||
|
- remove all modified instances from the above set
|
||||||
|
- add remaining instances, in chronological order
|
||||||
|
*/
|
||||||
|
exceptionDates = [NSMutableSet set];
|
||||||
for (count = 0; count < rp->DeletedInstanceCount; count++)
|
for (count = 0; count < rp->DeletedInstanceCount; count++)
|
||||||
{
|
{
|
||||||
exDate
|
exDate
|
||||||
|
@ -217,8 +225,23 @@
|
||||||
exDate = [exDate hour: [startDate hourOfDay]
|
exDate = [exDate hour: [startDate hourOfDay]
|
||||||
minute: [startDate minuteOfHour]
|
minute: [startDate minuteOfHour]
|
||||||
second: [startDate secondOfMinute]];
|
second: [startDate secondOfMinute]];
|
||||||
[entity addToExceptionDates: exDate];
|
[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]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -233,11 +256,14 @@
|
||||||
iCalRecurrenceFrequency freq;
|
iCalRecurrenceFrequency freq;
|
||||||
iCalByDayMask *byDayMask;
|
iCalByDayMask *byDayMask;
|
||||||
NSString *byMonthDay, *bySetPos;
|
NSString *byMonthDay, *bySetPos;
|
||||||
NSCalendarDate *startDate, *endDate, *untilDate, *beginOfWeek, *minimumDate, *moduloDate, *midnight;
|
NSCalendarDate *startDate, *endDate, *untilDate, *beginOfWeek, *minimumDate,
|
||||||
|
*moduloDate, *midnight;
|
||||||
iCalWeekOccurrences *days;
|
iCalWeekOccurrences *days;
|
||||||
NSInteger dayOfWeek, repeatInterval, repeatCount, count, firstOccurrence, max;
|
NSInteger dayOfWeek, repeatInterval, repeatCount, count, firstOccurrence,
|
||||||
|
max;
|
||||||
uint32_t nbrMonths, mask;
|
uint32_t nbrMonths, mask;
|
||||||
NSArray *exDates;
|
NSArray *events;
|
||||||
|
NSMutableArray *deletedDates, *modifiedDates;
|
||||||
|
|
||||||
startDate = [event firstRecurrenceStartDate];
|
startDate = [event firstRecurrenceStartDate];
|
||||||
[startDate setTimeZone: timeZone];
|
[startDate setTimeZone: timeZone];
|
||||||
|
@ -394,16 +420,37 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
events = [[event parent] events];
|
||||||
|
max = [events count];
|
||||||
|
modifiedDates = [NSMutableArray arrayWithCapacity: max];
|
||||||
|
for (count = 1; count < max; count++)
|
||||||
|
{
|
||||||
|
startDate = [[events objectAtIndex: count] recurrenceId];
|
||||||
|
[modifiedDates addObject: startDate];
|
||||||
|
}
|
||||||
|
max = [modifiedDates count];
|
||||||
|
rp->ModifiedInstanceCount = max;
|
||||||
|
rp->ModifiedInstanceDates = talloc_array (memCtx, uint32_t, max);
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
startDate = [[modifiedDates objectAtIndex: count]
|
||||||
|
hour: 0 minute: 0 second: 0];
|
||||||
|
*(rp->ModifiedInstanceDates + count) = [startDate asMinutesSince1601];
|
||||||
|
}
|
||||||
|
|
||||||
exDates = [[event exceptionDatesWithTimeZone: utcTZ]
|
deletedDates = [modifiedDates mutableCopy];
|
||||||
sortedArrayUsingFunction: NSDateCompare
|
[deletedDates autorelease];
|
||||||
context: NULL];
|
[deletedDates
|
||||||
max = [exDates count];
|
addObjectsFromArray: [event exceptionDatesWithTimeZone: utcTZ]];
|
||||||
|
[deletedDates sortUsingFunction: NSDateCompare context: NULL];
|
||||||
|
|
||||||
|
max = [deletedDates count];
|
||||||
rp->DeletedInstanceCount = max;
|
rp->DeletedInstanceCount = max;
|
||||||
rp->DeletedInstanceDates = talloc_array (memCtx, uint32_t, max);
|
rp->DeletedInstanceDates = talloc_array (memCtx, uint32_t, max);
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
{
|
{
|
||||||
startDate = [[exDates objectAtIndex: count] hour: 0 minute: 0 second: 0];
|
startDate = [[deletedDates objectAtIndex: count]
|
||||||
|
hour: 0 minute: 0 second: 0];
|
||||||
*(rp->DeletedInstanceDates + count) = [startDate asMinutesSince1601];
|
*(rp->DeletedInstanceDates + count) = [startDate asMinutesSince1601];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue