From d2321642bf30c5d87bf95422de07104986d9c591 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Thu, 16 Aug 2012 16:32:52 +0000 Subject: [PATCH] Monotone-Parent: 8dee72c8fdafae92791aa552c3705e9c68f5c59e Monotone-Revision: d50a947c2bfbadd4649b083ee3432fbdd28180c2 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-08-16T16:32:52 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 5 ++ OpenChange/MAPIStoreCalendarMessage.m | 94 +++++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index f030d098f..3fd14b8b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2012-08-16 Wolfgang Sourdeau + * OpenChange/MAPIStoreCalendarMessage.m + (-getMessageData:inMemCtx:): when a "recipients" records is + available in the properties, we must return that list instead of + the list of attendees since it will be the most recent one. + * OpenChange/MAPIStoreMapping.m (_updateFolderWithURL:withURL:): we retain and release "oldURL" to avoid releasing it when it is replaced in the list of urls to modify. diff --git a/OpenChange/MAPIStoreCalendarMessage.m b/OpenChange/MAPIStoreCalendarMessage.m index 7900135f1..3cc5af4f9 100644 --- a/OpenChange/MAPIStoreCalendarMessage.m +++ b/OpenChange/MAPIStoreCalendarMessage.m @@ -44,6 +44,7 @@ #import #import #import +#import #import #import #import @@ -222,13 +223,91 @@ - (void) getMessageData: (struct mapistore_message **) dataPtr inMemCtx: (TALLOC_CTX *) memCtx { + static NSString *recTypes[] = {@"orig", @"to", @"cc", @"bcc"}; + static NSInteger recTypesValue[] = {MAPI_ORIG, MAPI_TO, MAPI_CC, MAPI_BCC}; struct mapistore_message *msgData; + NSDictionary *recipients, *contactInfos; + NSString *email; + NSArray *attendees; + NSDictionary *attendee; + SOGoUserManager *mgr; + struct mapistore_message_recipient *recipient; + NSUInteger nRecType, maxRecTypes, count, max, propCount; + NSObject *currentValue; [super getMessageData: &msgData inMemCtx: memCtx]; - /* HACK: we know the first (and only) proxy is our appointment wrapper - instance, but this might not always be true */ - [[proxies objectAtIndex: 0] fillMessageData: msgData - inMemCtx: memCtx]; + + /* The presence of the "recipients" meta-property means that our most recent + list of recipients has not been saved yet and that we must return that + one instead of the one stored in the event. */ + recipients = [properties objectForKey: @"recipients"]; + if (recipients) + { + mgr = [SOGoUserManager sharedUserManager]; + + /* TODO: this code might need to be moved into MAPIStoreMessage */ + msgData->columns = set_SPropTagArray (msgData, 9, + PR_OBJECT_TYPE, + PR_DISPLAY_TYPE, + PR_7BIT_DISPLAY_NAME_UNICODE, + PR_SMTP_ADDRESS_UNICODE, + PR_SEND_INTERNET_ENCODING, + PR_RECIPIENT_DISPLAY_NAME_UNICODE, + PR_RECIPIENT_FLAGS, + PR_RECIPIENT_ENTRYID, + PR_RECIPIENT_TRACKSTATUS); + + maxRecTypes = sizeof(recTypes) / sizeof(recTypes[0]); + for (nRecType = 0; nRecType < maxRecTypes; nRecType++) + { + attendees = [recipients objectForKey: recTypes[nRecType]]; + max = [attendees count]; + if (max > 0) + { + msgData->recipients_count += max; + msgData->recipients = talloc_realloc(msgData, + msgData->recipients, struct + mapistore_message_recipient, msgData->recipients_count); + recipient = msgData->recipients; + for (count = 0; count < max; count++) + { + attendee = [attendees objectAtIndex: count]; + recipient->type = recTypesValue[nRecType]; + email = [attendee objectForKey: @"email"]; + if (email) + { + contactInfos + = [mgr contactInfosForUserWithUIDorEmail: email]; + recipient->username = [[contactInfos + objectForKey: @"c_uid"] + asUnicodeInMemCtx: msgData]; + } + else + recipient->username = NULL; + + recipient->data = talloc_array(msgData, void *, + msgData->columns->cValues); + for (propCount = 0; + propCount < msgData->columns->cValues; + propCount++) + { + currentValue = [attendee objectForKey: MAPIPropertyKey (msgData->columns->aulPropTag[propCount])]; + [currentValue getValue: recipient->data + propCount + forTag: msgData->columns->aulPropTag[propCount] + inMemCtx: msgData]; + } + recipient++; + } + } + } + } + else + { + /* HACK: we know the first (and only) proxy is our appointment wrapper + instance, but this might not always be true */ + [[proxies objectAtIndex: 0] fillMessageData: msgData + inMemCtx: memCtx]; + } *dataPtr = msgData; } @@ -368,8 +447,11 @@ /* reinstantiate the old sogo object and attach it to self */ woContext = [[self userContext] woContext]; if (isNew) - newObject = [SOGoAppointmentObject objectWithName: cname - inContainer: folder]; + { + newObject = [SOGoAppointmentObject objectWithName: cname + inContainer: folder]; + [newObject setIsNew: YES]; + } else { /* dissociate the object url from the old object's id */