Monotone-Parent: a33d1b8b23cf8d9468c7f693a1087950524e9ebc

Monotone-Revision: cb0ecd99fcf222060f6e3bc248d2e9a9c47624c1

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2011-04-13T19:59:04
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Wolfgang Sourdeau 2011-04-13 19:59:04 +00:00
parent dd79e0b182
commit a9806e6b6d
13 changed files with 1806 additions and 1435 deletions

View File

@ -1,5 +1,11 @@
2011-04-13 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/MAPIStoreObject.m: make use of the IMP cache methods
available in MAPIStorePropertySelectors to query object
properties.
* OpenChange/*{Message,Folder}.m: replaced the implementations of
-getProperty:withTag: with equivalent property getter methods.
* OpenChange/MAPIStoreContext.m (-url): new method that returns
the context url.

View File

@ -25,7 +25,13 @@
#import "MAPIStoreGCSMessage.h"
@class iCalEvent;
@interface MAPIStoreCalendarMessage : MAPIStoreGCSMessage
{
iCalEvent *event;
}
@end
#endif /* MAPISTORECALENDARMESSAGE_H */

View File

@ -73,17 +73,36 @@ static NSTimeZone *utcTZ;
[utcTZ retain];
}
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer
{
if ((self = [super initWithSOGoObject: newSOGoObject
inContainer: newContainer]))
{
ASSIGN (event, [newSOGoObject component: NO secure: NO]);
}
return self;
}
- (id) init
{
if ((self = [super init]))
{
attachmentKeys = [NSMutableArray new];
attachmentParts = [NSMutableDictionary new];
event = nil;
}
return self;
}
- (void) dealloc
{
[event release];
[super dealloc];
}
- (NSTimeZone *) ownerTimeZone
{
NSString *owner;
@ -100,7 +119,6 @@ static NSTimeZone *utcTZ;
}
- (void) _setupRecurrenceInCalendar: (iCalCalendar *) calendar
withMasterEvent: (iCalEvent *) vEvent
fromData: (NSData *) mapiRecurrenceData
{
struct Binary_r *blob;
@ -109,13 +127,13 @@ static NSTimeZone *utcTZ;
/* cleanup */
otherEvents = [[calendar events] mutableCopy];
[otherEvents removeObject: vEvent];
[otherEvents removeObject: event];
[calendar removeChildren: otherEvents];
[otherEvents release];
blob = [mapiRecurrenceData asBinaryInMemCtx: memCtx];
pattern = get_AppointmentRecurrencePattern (memCtx, blob);
[calendar setupRecurrenceWithMasterEntity: vEvent
[calendar setupRecurrenceWithMasterEntity: event
fromRecurrencePattern: &pattern->RecurrencePattern];
talloc_free (pattern);
talloc_free (blob);
@ -150,21 +168,19 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
struct Binary_r *bin;
struct SBinary_short *sBin;
NSCalendarDate *firstStartDate;
iCalEvent *vEvent;
iCalRecurrenceRule *rule;
vEvent = [sogoObject component: NO secure: NO];
rule = [[vEvent recurrenceRules] objectAtIndex: 0];
rule = [[event recurrenceRules] objectAtIndex: 0];
firstStartDate = [vEvent firstRecurrenceStartDate];
firstStartDate = [event firstRecurrenceStartDate];
if (firstStartDate)
{
[firstStartDate setTimeZone: [self ownerTimeZone]];
arp = talloc_zero (memCtx, struct AppointmentRecurrencePattern);
_fillAppointmentRecurrencePattern (arp, firstStartDate,
[vEvent durationAsTimeInterval],
[vEvent lastPossibleRecurrenceStartDate],
[event durationAsTimeInterval],
[event lastPossibleRecurrenceStartDate],
rule);
sBin = talloc_zero (memCtx, struct SBinary_short);
bin = set_AppointmentRecurrencePattern (sBin, arp);
@ -184,146 +200,182 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
return sBin;
}
- (enum MAPISTATUS) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
/* getters */
- (int) getPrIconIndex: (void **) data // TODO
{
uint32_t longValue;
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
// *longValue = 0x00000401 for recurring event
// *longValue = 0x00000402 for meeting
// *longValue = 0x00000403 for recurring meeting
// *longValue = 0x00000404 for invitation
longValue = 0x0400;
if ([event isRecurrent])
longValue |= 0x0001;
if ([[event attendees] count] > 0)
longValue |= 0x0002;
*data = MAPILongValue (memCtx, longValue);
return MAPISTORE_SUCCESS;
}
- (int) getPrMessageClass: (void **) data
{
*data = talloc_strdup(memCtx, "IPM.Appointment");
return MAPISTORE_SUCCESS;
}
- (int) getPrStartDate: (void **) data
{
NSCalendarDate *dateValue;
if ([event isRecurrent])
dateValue = [event firstRecurrenceStartDate];
else
dateValue = [event startDate];
[dateValue setTimeZone: utcTZ];
*data = [dateValue asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidLidAppointmentStartWhole: (void **) data
{
return [self getPrStartDate: data];
}
- (int) getPidLidCommonStart: (void **) data
{
return [self getPrStartDate: data];
}
- (int) getPrEndDate: (void **) data
{
NSCalendarDate *dateValue;
if ([event isRecurrent])
dateValue = [event firstRecurrenceStartDate];
else
dateValue = [event startDate];
dateValue
= [dateValue dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0
seconds: (NSInteger) [event
durationAsTimeInterval]];
[dateValue setTimeZone: utcTZ];
*data = [dateValue asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidLidAppointmentEndWhole: (void **) data
{
return [self getPrEndDate: data];
}
- (int) getPidLidCommonEnd: (void **) data
{
return [self getPrEndDate: data];
}
- (int) getPidLidAppointmentDuration: (void **) data
{
NSTimeInterval timeValue;
id event;
uint32_t longValue;
NSCalendarDate *dateValue;
int rc;
rc = MAPI_E_SUCCESS;
switch ((uint32_t) propTag)
{
case PR_ICON_INDEX: // TODO
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
// *longValue = 0x00000401 for recurring event
// *longValue = 0x00000402 for meeting
// *longValue = 0x00000403 for recurring meeting
// *longValue = 0x00000404 for invitation
timeValue = [[event endDate] timeIntervalSinceDate: [event startDate]];
*data = MAPILongValue (memCtx, (uint32_t) (timeValue / 60));
event = [sogoObject component: NO secure: NO];
longValue = 0x0400;
if ([event isRecurrent])
longValue |= 0x0001;
if ([[event attendees] count] > 0)
longValue |= 0x0002;
return MAPISTORE_SUCCESS;
}
*data = MAPILongValue (memCtx, longValue);
break;
case PR_MESSAGE_CLASS_UNICODE:
*data = talloc_strdup(memCtx, "IPM.Appointment");
break;
case PR_START_DATE:
case PidLidAppointmentStartWhole:
case PidLidCommonStart:
event = [sogoObject component: NO secure: NO];
if ([event isRecurrent])
dateValue = [event firstRecurrenceStartDate];
else
dateValue = [event startDate];
[dateValue setTimeZone: utcTZ];
*data = [dateValue asFileTimeInMemCtx: memCtx];
break;
case PR_END_DATE:
case PidLidAppointmentEndWhole:
case PidLidCommonEnd:
event = [sogoObject component: NO secure: NO];
if ([event isRecurrent])
dateValue = [event firstRecurrenceStartDate];
else
dateValue = [event startDate];
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0
seconds:
(NSInteger) [event durationAsTimeInterval]];
[dateValue setTimeZone: utcTZ];
*data = [dateValue asFileTimeInMemCtx: memCtx];
break;
case PidLidAppointmentDuration:
event = [sogoObject component: NO secure: NO];
timeValue = [[event endDate] timeIntervalSinceDate: [event startDate]];
*data = MAPILongValue (memCtx, (uint32_t) (timeValue / 60));
break;
case PidLidAppointmentSubType:
event = [sogoObject component: NO secure: NO];
*data = MAPIBoolValue (memCtx, [event isAllDay]);
break;
case PidLidBusyStatus: // TODO
*data = MAPILongValue (memCtx, 0x02);
break;
- (int) getPidLidAppointmentSubType: (void **) data
{
*data = MAPIBoolValue (memCtx, [event isAllDay]);
// case 0x82410003: // TODO
// *data = MAPILongValue (memCtx, 0);
// break;
case PR_SUBJECT_UNICODE: // SUMMARY
event = [sogoObject component: NO secure: NO];
*data = [[event summary] asUnicodeInMemCtx: memCtx];
break;
case PidLidLocation: // LOCATION
event = [sogoObject component: NO secure: NO];
*data = [[event location] asUnicodeInMemCtx: memCtx];
break;
case PidLidPrivate: // private (bool), should depend on CLASS and permissions
*data = MAPIBoolValue (memCtx, NO);
break;
case PR_SENSITIVITY: // not implemented, depends on CLASS
// normal = 0, personal?? = 1, private = 2, confidential = 3
*data = MAPILongValue (memCtx, 0);
break;
case PR_CREATION_TIME:
event = [sogoObject component: NO secure: NO];
*data = [[event created] asFileTimeInMemCtx: memCtx];
break;
return MAPISTORE_SUCCESS;
}
case PR_IMPORTANCE:
{
unsigned int v;
- (int) getPidLidBusyStatus: (void **) data // TODO
{
*data = MAPILongValue (memCtx, 0x02);
event = [sogoObject component: NO secure: NO];
return MAPISTORE_SUCCESS;
}
if ([[event priority] isEqualToString: @"9"])
v = 0x0;
else if ([[event priority] isEqualToString: @"1"])
v = 0x2;
else
v = 0x1;
- (int) getPrSubject: (void **) data // SUMMARY
{
*data = [[event summary] asUnicodeInMemCtx: memCtx];
*data = MAPILongValue (memCtx, v);
}
break;
return MAPISTORE_SUCCESS;
}
- (int) getPidLidLocation: (void **) data // LOCATION
{
*data = [[event location] asUnicodeInMemCtx: memCtx];
/* Recurrence */
case PidLidIsRecurring:
case PidLidRecurring:
event = [sogoObject component: NO secure: NO];
*data = MAPIBoolValue (memCtx, [event isRecurrent]);
break;
case PidLidAppointmentRecur:
event = [sogoObject component: NO secure: NO];
if ([event isRecurrent])
*data = [self _computeAppointmentRecur];
else
rc = MAPISTORE_ERR_NOT_FOUND;
break;
return MAPISTORE_SUCCESS;
}
// case PidLidTimeZoneStruct:
// case PR_VD_NAME_UNICODE:
// *data = talloc_strdup(memCtx, "PR_VD_NAME_UNICODE");
// break;
// case PR_EMS_AB_DXA_REMOTE_CLIENT_UNICODE: "Home:" ???
// *data = talloc_strdup(memCtx, "PR_EMS...");
// break;
default:
rc = [super getProperty: data
withTag: propTag];
}
- (int) getPidLidPrivate: (void **) data // private (bool), should depend on CLASS and permissions
{
return [self getNo: data];
}
// #define PR_REPLY_TIME PROP_TAG(PT_SYSTIME , 0x0030) /* 0x00300040 */
// #define PR_INTERNET_MESSAGE_ID_UNICODE PROP_TAG(PT_UNICODE , 0x1035) /* 0x1035001f */
// #define PR_FLAG_STATUS PROP_TAG(PT_LONG , 0x1090) /* 0x10900003 */
- (int) getPrSensitivity: (void **) data // not implemented, depends on CLASS
{
// normal = 0, personal?? = 1, private = 2, confidential = 3
return [self getLongZero: data];
}
- (int) getPrCreationTime: (void **) data
{
*data = [[event created] asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrImportance: (void **) data
{
uint32_t v;
if ([[event priority] isEqualToString: @"9"])
v = 0x0;
else if ([[event priority] isEqualToString: @"1"])
v = 0x2;
else
v = 0x1;
*data = MAPILongValue (memCtx, v);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidIsRecurring: (void **) data
{
*data = MAPIBoolValue (memCtx, [event isRecurrent]);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidRecurring: (void **) data
{
*data = MAPIBoolValue (memCtx, [event isRecurrent]);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidAppointmentRecur: (void **) data
{
int rc = MAPISTORE_SUCCESS;
if ([event isRecurrent])
*data = [self _computeAppointmentRecur];
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
@ -333,12 +385,10 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
NSString *name, *email;
NSArray *attendees;
iCalPerson *person;
id event;
struct SRowSet *recipients;
int count, max;
[super openMessage: msg];
event = [sogoObject component: NO secure: NO];
attendees = [event attendees];
max = [attendees count];
@ -382,11 +432,11 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
{
WOContext *woContext;
iCalCalendar *vCalendar;
iCalEvent *vEvent;
iCalDateTime *start, *end;
iCalTimeZone *tz;
NSCalendarDate *now;
NSString *content, *tzName;
iCalEvent *newEvent;
id value;
[self logWithFormat: @"-save, event props:"];
@ -395,25 +445,29 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
content = [sogoObject contentAsString];
if (![content length])
{
vEvent = [sogoObject component: YES secure: NO];
vCalendar = [vEvent parent];
newEvent = [sogoObject component: YES secure: NO];
if (newEvent != event)
ASSIGN (event, newEvent);
vCalendar = [event parent];
[vCalendar setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"];
content = [vCalendar versitString];
}
vCalendar = [iCalCalendar parseSingleFromSource: content];
vEvent = [[vCalendar events] objectAtIndex: 0];
newEvent = [[vCalendar events] objectAtIndex: 0];
if (newEvent != event)
ASSIGN (event, newEvent);
// summary
value = [newProperties
objectForKey: MAPIPropertyKey (PR_NORMALIZED_SUBJECT_UNICODE)];
if (value)
[vEvent setSummary: value];
[event setSummary: value];
// Location
value = [newProperties objectForKey: MAPIPropertyKey (PidLidLocation)];
if (value)
[vEvent setLocation: value];
[event setLocation: value];
tzName = [[self ownerTimeZone] name];
tz = [iCalTimeZone timeZoneForName: tzName];
@ -425,7 +479,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
value = [newProperties objectForKey: MAPIPropertyKey (PidLidAppointmentStartWhole)];
if (value)
{
start = (iCalDateTime *) [vEvent uniqueChildWithTag: @"dtstart"];
start = (iCalDateTime *) [event uniqueChildWithTag: @"dtstart"];
[start setTimeZone: tz];
[start setDateTime: value];
}
@ -436,7 +490,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
value = [newProperties objectForKey: MAPIPropertyKey (PidLidAppointmentEndWhole)];
if (value)
{
end = (iCalDateTime *) [vEvent uniqueChildWithTag: @"dtend"];
end = (iCalDateTime *) [event uniqueChildWithTag: @"dtend"];
[end setTimeZone: tz];
[end setDateTime: value];
}
@ -444,9 +498,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
now = [NSCalendarDate date];
if ([sogoObject isNew])
{
[vEvent setCreated: now];
[event setCreated: now];
}
[vEvent setTimeStampAsDate: now];
[event setTimeStampAsDate: now];
// Organizer and attendees
value = [newProperties objectForKey: @"recipients"];
@ -463,7 +517,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
person = [iCalPerson new];
[person setCn: [dict objectForKey: @"fullName"]];
[person setEmail: [dict objectForKey: @"email"]];
[vEvent setOrganizer: person];
[event setOrganizer: person];
[person release];
recipients = [value objectForKey: @"to"];
@ -480,8 +534,8 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
[person setRole: @"REQ-PARTICIPANT"];
// FIXME: We must NOT always rely on this
if (![vEvent isAttendee: [person rfc822Email]])
[vEvent addToAttendees: person];
if (![event isAttendee: [person rfc822Email]])
[event addToAttendees: person];
[person release];
}
@ -492,11 +546,10 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
objectForKey: MAPIPropertyKey (PidLidAppointmentRecur)];
if (value)
[self _setupRecurrenceInCalendar: vCalendar
withMasterEvent: vEvent
fromData: value];
// [sogoObject saveContentString: [vCalendar versitString]];
[sogoObject saveComponent: vEvent];
[sogoObject saveComponent: event];
}
/* TODO: those are stubs meant to prevent OpenChange from crashing when a

View File

@ -29,6 +29,7 @@
#import <SOGo/SOGoUserDefaults.h>
#import <Contacts/SOGoContactGCSEntry.h>
#import "MAPIStorePropertySelectors.h"
#import "MAPIStoreTypes.h"
#import "NSArray+MAPIStore.h"
#import "NSCalendarDate+MAPIStore.h"
@ -46,461 +47,466 @@
@implementation MAPIStoreContactsMessage
- (CardElement *) _element: (NSString *) elementTag
ofType: (NSString *) aType
excluding: (NSString *) aTypeToExclude
inCard: (NGVCard *) card
- (int) getPrIconIndex: (void **) data // TODO
{
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
*data = MAPILongValue (memCtx, 0x00000200);
return MAPISTORE_SUCCESS;
}
- (int) getPrMessageClass: (void **) data
{
*data = talloc_strdup (memCtx, "IPM.Contact");
return MAPISTORE_SUCCESS;
}
- (int) getPrOabName: (void **) data
{
*data = talloc_strdup (memCtx, "PR_OAB_NAME_UNICODE");
return MAPISTORE_SUCCESS;
}
- (int) getPrOabLangid: (void **) data
{
/* see http://msdn.microsoft.com/en-us/goglobal/bb895996.asxp */
/* English US */
*data = MAPILongValue (memCtx, 0x0409);
return MAPISTORE_SUCCESS;
}
- (int) getPrTitle: (void **) data
{
NSString *stringValue;
stringValue = [[sogoObject vCard] title];
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrCompanyName: (void **) data
{
NSArray *values;
NSString *stringValue;
values = [[sogoObject vCard] org];
stringValue = nil;
if ([values count] > 0)
stringValue = [values objectAtIndex: 0];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrDepartmentName: (void **) data
{
NSArray *values;
NSString *stringValue;
values = [[sogoObject vCard] org];
stringValue = nil;
if ([values count] > 1)
stringValue = [values objectAtIndex: 1];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrSendInternetEncoding: (void **) data
{
*data = MAPILongValue (memCtx, 0x00065001);
return MAPISTORE_SUCCESS;
}
- (int) getPrSubject: (void **) data
{
return [self getPrDisplayName: data];
}
- (int) getPidLidFileUnder: (void **) data
{
return [self getPrDisplayName: data];
}
- (int) getPidLidFileUnderId: (void **) data
{
*data = MAPILongValue (memCtx, 0xffffffff);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidEmail1DisplayName: (void **) data
{
NGVCard *vCard;
NSString *fn, *email;
vCard = [sogoObject vCard];
fn = [vCard fn];
email = [vCard preferredEMail];
*data = [[NSString stringWithFormat: @"%@ <%@>", fn, email]
asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidLidEmail1OriginalDisplayName: (void **) data
{
return [self getPidLidEmail1DisplayName: data];
}
- (int) getPidLidEmail1EmailAddress: (void **) data
{
NSString *stringValue;
stringValue = [[sogoObject vCard] preferredEMail];
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrAccount: (void **) data
{
return [self getPidLidEmail1EmailAddress: data];
}
- (int) getPrContactEmailAddresses: (void **) data
{
NSString *stringValue;
stringValue = [[sogoObject vCard] preferredEMail];
if (!stringValue)
stringValue = @"";
*data = [[NSArray arrayWithObject: stringValue]
asArrayOfUnicodeStringsInCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrEmsAbTargetAddress: (void **) data
{
NSString *stringValue;
stringValue = [[sogoObject vCard] preferredEMail];
*data = [[NSString stringWithFormat: @"SMTP:%@", stringValue]
asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrSearchKey: (void **) data // TODO
{
NSString *stringValue;
stringValue = [[sogoObject vCard] preferredEMail];
*data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding]
asBinaryInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrMailPermission: (void **) data
{
return [self getYes: data];
}
- (int) getPidLidEmail2EmailAddress: (void **) data
{
NSMutableArray *emails;
NSString *email, *stringValue;
NGVCard *card;
NSUInteger count, max;
emails = [NSMutableArray array];
stringValue = nil;
card = [sogoObject vCard];
[emails addObjectsFromArray: [card childrenWithTag: @"email"]];
[emails removeObjectsInArray: [card childrenWithTag: @"email"
andAttribute: @"type"
havingValue: @"pref"]];
max = [emails count];
for (count = 0; !stringValue && count < max; count++)
{
email = [[emails objectAtIndex: count] value: 0];
if ([email caseInsensitiveCompare: [card preferredEMail]] != NSOrderedSame)
stringValue = email;
}
if (!stringValue)
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidLidEmail2OriginalDisplayName: (void **) data // Other email
{
return [self getPidLidEmail2EmailAddress: data];
}
- (int) getPrBody: (void **) data
{
NSString *stringValue;
stringValue = [[sogoObject vCard] note];
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) _getElement: (NSString *) elementTag
ofType: (NSString *) aType
excluding: (NSString *) aTypeToExclude
atPos: (NSUInteger) pos
inData: (void **) data
{
NSArray *elements;
CardElement *ce, *found;
CardElement *ce;
NSUInteger count, max;
NGVCard *vCard;
NSString *stringValue;
found = nil;
stringValue = nil;
elements = [[card childrenWithTag: elementTag]
vCard = [sogoObject vCard];
elements = [[vCard childrenWithTag: elementTag]
cardElementsWithAttribute: @"type"
havingValue: aType];
max = [elements count];
for (count = 0; !found && count < max; count++)
for (count = 0; !stringValue && count < max; count++)
{
ce = [elements objectAtIndex: count];
if (!aTypeToExclude
|| ![ce hasAttribute: @"type" havingValue: aTypeToExclude])
found = ce;
stringValue = [ce value: pos];
}
return found;
if (!stringValue)
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (enum MAPISTATUS) getProperty: (void **) data
withTag: (enum MAPITAGS) proptag
- (int) getPrOfficeTelephoneNumber: (void **) data
{
NSString *stringValue, *stringValue2;
return [self _getElement: @"tel" ofType: @"work" excluding: @"fax"
atPos: 0 inData: data];
}
- (int) getPrHomeTelephoneNumber: (void **) data
{
return [self _getElement: @"tel" ofType: @"home" excluding: @"fax"
atPos: 0 inData: data];
}
- (int) getPrMobileTelephoneNumber: (void **) data
{
return [self _getElement: @"tel" ofType: @"cell" excluding: nil
atPos: 0 inData: data];
}
- (int) getPrPrimaryTelephoneNumber: (void **) data
{
return [self _getElement: @"tel" ofType: @"pref" excluding: nil
atPos: 0 inData: data];
}
- (int) getPrBusinessHomePage: (void **) data
{
return [self _getElement: @"url" ofType: @"work" excluding: nil
atPos: 0 inData: data];
}
- (int) getPrPersonalHomePage: (void **) data
{
return [self _getElement: @"url" ofType: @"home" excluding: nil
atPos: 0 inData: data];
}
- (int) getPidLidEmail1AddressType: (void **) data
{
return [self getSMTPAddrType: data];
}
- (int) getPidLidEmail2AddressType: (void **) data
{
return [self getSMTPAddrType: data];
}
- (int) getPidLidEmail3AddressType: (void **) data
{
return [self getSMTPAddrType: data];
}
- (int) getPidLidInstantMessagingAddress: (void **) data
{
NSString *stringValue;
stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-aim"]
value: 0];
if (!stringValue)
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidLidPostalAddressId: (void **) data
{
NSArray *elements;
CardElement *element;
uint32_t longValue;
uint32_t longValue = 0;
NGVCard *vCard;
enum MAPISTATUS rc;
rc = MAPISTORE_SUCCESS;
switch ((uint32_t) proptag)
vCard = [sogoObject vCard];
elements = [[vCard childrenWithTag: @"adr"]
cardElementsWithAttribute: @"type"
havingValue: @"pref"];
if ([elements count] > 0)
{
case PR_ICON_INDEX: // TODO
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
*data = MAPILongValue (memCtx, 0x00000200);
break;
case PR_MESSAGE_CLASS_UNICODE:
*data = talloc_strdup (memCtx, "IPM.Contact");
break;
// case PR_VD_NAME_UNICODE:
// *data = talloc_strdup (memCtx, "PR_VD_NAME_UNICODE");
// break;
// case PR_EMS_AB_DXA_REMOTE_CLIENT_UNICODE: "Home:" ???
// *data = talloc_strdup (memCtx, "PR_EMS...");
// break;
case PR_OAB_NAME_UNICODE:
*data = talloc_strdup (memCtx, "PR_OAB_NAME_UNICODE");
break;
case PR_OAB_LANGID:
/* see http://msdn.microsoft.com/en-us/goglobal/bb895996.asxp */
/* English US */
*data = MAPILongValue (memCtx, 0x0409);
break;
case PR_TITLE_UNICODE:
stringValue = [[sogoObject vCard] title];
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_COMPANY_NAME_UNICODE:
case PR_DEPARTMENT_NAME_UNICODE:
{
NSArray *values;
values = [[sogoObject vCard] org];
stringValue = nil;
if (proptag == PR_COMPANY_NAME_UNICODE && [values count] > 0)
stringValue = [values objectAtIndex: 0];
else if (proptag == PR_DEPARTMENT_NAME_UNICODE && [values count] > 1)
stringValue = [values objectAtIndex: 1];
if (!stringValue)
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
}
break;
case PR_SEND_INTERNET_ENCODING:
*data = MAPILongValue (memCtx, 0x00065001);
break;
case PR_SUBJECT_UNICODE:
case PR_DISPLAY_NAME_UNICODE: // Full Name
case PidLidFileUnder: // contact block title name
rc = [super getProperty: data
withTag: PR_DISPLAY_NAME_UNICODE];
break;
case PidLidFileUnderId:
*data = MAPILongValue (memCtx, 0xffffffff);
break;
case PidLidEmail1OriginalDisplayName:
case PidLidEmail1DisplayName:
vCard = [sogoObject vCard];
stringValue = [vCard fn];
stringValue2 = [vCard preferredEMail];
*data = [[NSString stringWithFormat: @"%@ <%@>",
stringValue, stringValue2]
asUnicodeInMemCtx: memCtx];
break;
case PidLidEmail1EmailAddress:
case PR_ACCOUNT_UNICODE:
stringValue = [[sogoObject vCard] preferredEMail];
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_CONTACT_EMAIL_ADDRESSES_UNICODE:
stringValue = [[sogoObject vCard] preferredEMail];
if (!stringValue)
stringValue = @"";
*data = [[NSArray arrayWithObject: stringValue]
asArrayOfUnicodeStringsInCtx: memCtx];
break;
case PR_EMS_AB_TARGET_ADDRESS_UNICODE:
stringValue = [[sogoObject vCard] preferredEMail];
*data = [[NSString stringWithFormat: @"SMTP:%@", stringValue]
asUnicodeInMemCtx: memCtx];
break;
case PR_SEARCH_KEY: // TODO
stringValue = [[sogoObject vCard] preferredEMail];
*data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding]
asBinaryInMemCtx: memCtx];
break;
case PR_MAIL_PERMISSION:
*data = MAPIBoolValue (memCtx, YES);
break;
//
// TODO - same logic as -secondaryEmail in UI/Contacts/UIxContactView.m
// We should eventually merge that in order to not duplicate the code.
// We should also eventually handle PidLidEmail3OriginalDisplayName in
// SOGo, Thunderbird, etc.
//
case PidLidEmail2EmailAddress:
case PidLidEmail2OriginalDisplayName: // Other email
{
NSMutableArray *emails;
NSString *email;
NGVCard *card;
emails = [NSMutableArray array];
stringValue = nil;
card = [sogoObject vCard];
[emails addObjectsFromArray: [card childrenWithTag: @"email"]];
[emails removeObjectsInArray: [card childrenWithTag: @"email"
andAttribute: @"type"
havingValue: @"pref"]];
if ([emails count] > 0)
{
int i;
for (i = 0; i < [emails count]; i++)
{
email = [[emails objectAtIndex: i] value: 0];
if ([email caseInsensitiveCompare: [card preferredEMail]] != NSOrderedSame)
{
stringValue = email;
break;
}
}
}
if (!stringValue)
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
}
break;
// FIXME: this property does NOT work
case PR_BODY_UNICODE:
stringValue = [[sogoObject vCard] note];
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_OFFICE_TELEPHONE_NUMBER_UNICODE:
element = [self _element: @"tel" ofType: @"work"
excluding: @"fax"
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 0];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_HOME_TELEPHONE_NUMBER_UNICODE:
element = [self _element: @"tel" ofType: @"home"
excluding: @"fax"
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 0];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_MOBILE_TELEPHONE_NUMBER_UNICODE:
element = [self _element: @"tel" ofType: @"cell"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 0];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_PRIMARY_TELEPHONE_NUMBER_UNICODE:
element = [self _element: @"tel" ofType: @"pref"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 0];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_BUSINESS_HOME_PAGE_UNICODE:
case PR_PERSONAL_HOME_PAGE_UNICODE:
{
NSString *type;
type = (proptag == PR_BUSINESS_HOME_PAGE_UNICODE ? @"work" : @"home");
element = [self _element: @"url" ofType: type
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 0];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
}
break;
case PidLidEmail1AddressType:
case PidLidEmail2AddressType:
case PidLidEmail3AddressType:
*data = [@"SMTP" asUnicodeInMemCtx: memCtx];
break;
case PidLidInstantMessagingAddress:
stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-aim"] value: 0];
if (!stringValue)
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
//
// We don't handle 0x00000003 - The Other Address is the mailing address.
// See: http://msdn.microsoft.com/en-us/library/cc815430.aspx
//
case PidLidPostalAddressId:
element = [self _element: @"adr" ofType: @"pref"
excluding: nil
inCard: [sogoObject vCard]];
element = [elements objectAtIndex: 0];
if ([element hasAttribute: @"type"
havingValue: @"home"])
longValue = 1; // The Home Address is the mailing address.
havingValue: @"home"])
longValue = 1; // The Home Address is the mailing address.
else if ([element hasAttribute: @"type"
havingValue: @"work"])
longValue = 2; // The Work Address is the mailing address.
else
longValue = 0; // No address is selected as the mailing address.
*data = MAPILongValue (memCtx, longValue);
break;
/* preferred address */
case PR_POSTAL_ADDRESS_UNICODE:
element = [self _element: @"label" ofType: @"pref"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 0];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_POST_OFFICE_BOX_UNICODE:
element = [self _element: @"adr" ofType: @"pref"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 0];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_STREET_ADDRESS_UNICODE:
element = [self _element: @"adr" ofType: @"pref"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 2];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_LOCALITY_UNICODE:
element = [self _element: @"adr" ofType: @"pref"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 3];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_STATE_OR_PROVINCE_UNICODE:
element = [self _element: @"adr" ofType: @"pref"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 4];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_POSTAL_CODE_UNICODE:
element = [self _element: @"adr" ofType: @"pref"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 5];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_COUNTRY_UNICODE:
element = [self _element: @"adr" ofType: @"pref"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 6];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
// case PidLidAddressCountryCode:
case PidLidWorkAddress:
element = [self _element: @"label" ofType: @"work"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 0];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PidLidWorkAddressPostOfficeBox:
element = [self _element: @"adr" ofType: @"work"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 0];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PidLidWorkAddressStreet:
element = [self _element: @"adr" ofType: @"work"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 2];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PidLidWorkAddressCity:
element = [self _element: @"adr" ofType: @"work"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 3];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PidLidWorkAddressState:
element = [self _element: @"adr" ofType: @"work"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 4];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PidLidWorkAddressPostalCode:
element = [self _element: @"adr" ofType: @"work"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 5];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PidLidWorkAddressCountry:
element = [self _element: @"adr" ofType: @"work"
excluding: nil
inCard: [sogoObject vCard]];
if (element)
stringValue = [element value: 6];
else
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
// PidTagNickname
case PR_NICKNAME_UNICODE:
stringValue = [[sogoObject vCard] nickname];
*data = [stringValue asUnicodeInMemCtx: memCtx];
break;
case PR_BIRTHDAY:
{
NSCalendarDate *dateValue;
stringValue = [[sogoObject vCard] bday];
if (stringValue)
{
dateValue = [NSCalendarDate dateWithString: stringValue
calendarFormat: @"%Y-%m-%d"];
// FIXME: We add a day, otherwise Outlook 2003 will display at day earlier
dateValue = [dateValue addYear: 0 month: 0 day: 1 hour: 0 minute: 0 second: 0];
*data = [dateValue asFileTimeInMemCtx: memCtx];
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
}
break;
default:
rc = [super getProperty: data withTag: proptag];
havingValue: @"work"])
longValue = 2; // The Work Address is the mailing address.
}
*data = MAPILongValue (memCtx, longValue);
return MAPISTORE_SUCCESS;
}
- (int) getPrPostalAddress: (void **) data
{
return [self _getElement: @"label" ofType: @"pref" excluding: nil
atPos: 0 inData: data];
}
- (int) getPrPostOfficeBox: (void **) data
{
return [self _getElement: @"adr" ofType: @"pref" excluding: nil
atPos: 0 inData: data];
}
- (int) getPrStreetAddress: (void **) data
{
return [self _getElement: @"adr" ofType: @"pref" excluding: nil
atPos: 2 inData: data];
}
- (int) getPrLocality: (void **) data
{
return [self _getElement: @"adr" ofType: @"pref" excluding: nil
atPos: 3 inData: data];
}
- (int) getPrStateOrProvince: (void **) data
{
return [self _getElement: @"adr" ofType: @"pref" excluding: nil
atPos: 4 inData: data];
}
- (int) getPrPostalCode: (void **) data
{
return [self _getElement: @"adr" ofType: @"pref" excluding: nil
atPos: 5 inData: data];
}
- (int) getPrCountry: (void **) data
{
return [self _getElement: @"adr" ofType: @"pref" excluding: nil
atPos: 6 inData: data];
}
- (int) getPidLidWorkAddress: (void **) data
{
return [self _getElement: @"label" ofType: @"work" excluding: nil
atPos: 0 inData: data];
}
- (int) getPidLidWorkAddressPostOfficeBox: (void **) data
{
return [self _getElement: @"adr" ofType: @"work" excluding: nil
atPos: 0 inData: data];
}
- (int) getPidLidWorkAddressStreet: (void **) data
{
return [self _getElement: @"adr" ofType: @"work" excluding: nil
atPos: 2 inData: data];
}
- (int) getPidLidWorkAddressCity: (void **) data
{
return [self _getElement: @"adr" ofType: @"work" excluding: nil
atPos: 3 inData: data];
}
- (int) getPidLidWorkAddressState: (void **) data
{
return [self _getElement: @"adr" ofType: @"work" excluding: nil
atPos: 4 inData: data];
}
- (int) getPidLidWorkAddressPostalCode: (void **) data
{
return [self _getElement: @"adr" ofType: @"work" excluding: nil
atPos: 5 inData: data];
}
- (int) getPidLidWorkAddressCountry: (void **) data
{
return [self _getElement: @"adr" ofType: @"work" excluding: nil
atPos: 6 inData: data];
}
- (int) getPrNickname: (void **) data
{
NSString *stringValue;
stringValue = [[sogoObject vCard] nickname];
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrBirthday: (void **) data
{
NSCalendarDate *dateValue;
NSString *stringValue;
int rc = MAPISTORE_SUCCESS;
stringValue = [[sogoObject vCard] bday];
if (stringValue)
{
dateValue = [NSCalendarDate dateWithString: stringValue
calendarFormat: @"%Y-%m-%d"];
// FIXME: We add a day, otherwise Outlook 2003 will display at day earlier
dateValue = [dateValue addYear: 0 month: 0 day: 1 hour: 0 minute: 0 second: 0];
*data = [dateValue asFileTimeInMemCtx: memCtx];
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}

View File

@ -35,7 +35,7 @@
{
id value;
enum MAPISTATUS rc;
value = [[sogoObject properties] objectForKey: MAPIPropertyKey (propTag)];
if (value)
rc = [value getMAPIValue: data forTag: propTag inMemCtx: memCtx];

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,9 @@
- (void) openMessage: (struct mapistore_message *) msg;
/* helper getters */
- (int) getSMTPAddrType: (void **) data;
/* subclasses */
- (void) submit;
- (void) save;

View File

@ -22,9 +22,11 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <NGExtensions/NSObject+Logs.h>
#import <SOGo/SOGoObject.h>
#import "MAPIStoreContext.h"
#import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h"
#import "NSString+MAPIStore.h"
@ -127,146 +129,274 @@
msg->properties = properties;
}
- (int) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
/* helper getters */
- (int) getSMTPAddrType: (void **) data
{
int rc;
*data = [@"SMTP" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
/* getters */
- (int) getPrInstId: (void **) data // TODO: DOUBT
{
/* we return a unique id based on the key */
*data = MAPILongLongValue (memCtx, [[sogoObject nameInContainer] hash]);
return MAPISTORE_SUCCESS;
}
- (int) getPrInstanceNum: (void **) data // TODO: DOUBT
{
return [self getLongZero: data];
}
- (int) getPrRowType: (void **) data // TODO: DOUBT
{
*data = MAPILongValue (memCtx, TBL_LEAF_ROW);
return MAPISTORE_SUCCESS;
}
- (int) getPrDepth: (void **) data // TODO: DOUBT
{
*data = MAPILongLongValue (memCtx, 0);
return MAPISTORE_SUCCESS;
}
- (int) getPrAccess: (void **) data // TODO
{
*data = MAPILongValue (memCtx, 0x03);
return MAPISTORE_SUCCESS;
}
- (int) getPrAccessLevel: (void **) data // TODO
{
*data = MAPILongValue (memCtx, 0x01);
return MAPISTORE_SUCCESS;
}
- (int) getPrViewStyle: (void **) data
{
return [self getLongZero: data];
}
- (int) getPrViewMajorversion: (void **) data
{
return [self getLongZero: data];
}
- (int) getPidLidSideEffects: (void **) data // TODO
{
return [self getLongZero: data];
}
- (int) getPidLidCurrentVersion: (void **) data
{
*data = MAPILongValue (memCtx, 115608); // Outlook 11.5608
return MAPISTORE_SUCCESS;
}
- (int) getPidLidCurrentVersionName: (void **) data
{
*data = [@"11.0" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidLidAutoProcessState: (void **) data
{
*data = MAPILongValue (memCtx, 0x00000000);
return MAPISTORE_SUCCESS;
}
- (int) getPidNameContentClass: (void **) data
{
*data = [@"Sharing" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrFid: (void **) data
{
*data = MAPILongLongValue (memCtx, [container objectId]);
return MAPISTORE_SUCCESS;
}
- (int) getPrMid: (void **) data
{
*data = MAPILongLongValue (memCtx, [self objectId]);
return MAPISTORE_SUCCESS;
}
- (int) getPrMessageLocaleId: (void **) data
{
*data = MAPILongValue (memCtx, 0x0409);
return MAPISTORE_SUCCESS;
}
- (int) getPrMessageFlags: (void **) data // TODO
{
*data = MAPILongValue (memCtx, MSGFLAG_FROMME | MSGFLAG_READ | MSGFLAG_UNMODIFIED);
return MAPISTORE_SUCCESS;
}
- (int) getPrMessageSize: (void **) data // TODO
{
/* TODO: choose another name in SOGo for that method */
*data = MAPILongValue (memCtx, [[sogoObject davContentLength] intValue]);
return MAPISTORE_SUCCESS;
}
- (int) getPrMsgStatus: (void **) data // TODO
{
return [self getLongZero: data];
}
- (int) getPrImportance: (void **) data // TODO -> subclass?
{
*data = MAPILongValue (memCtx, 1);
return MAPISTORE_SUCCESS;
}
- (int) getPrPriority: (void **) data // TODO -> subclass?
{
return [self getLongZero: data];
}
- (int) getPrSensitivity: (void **) data // TODO -> subclass in calendar
{
return [self getLongZero: data];
}
// TODO: PR_CHANGE_KEY is a GID based on the ReplGUID
- (int) getPrChangeKey: (void **) data
{
int rc = MAPISTORE_SUCCESS;
NSString *stringValue;
NSUInteger length;
rc = MAPI_E_SUCCESS;
switch ((uint32_t) propTag)
stringValue = [sogoObject davEntityTag];
if (stringValue)
{
case PR_INST_ID: // TODO: DOUBT
/* we return a unique id based on the key */
*data = MAPILongLongValue (memCtx, [[sogoObject nameInContainer] hash]);
break;
case PR_INSTANCE_NUM: // TODO: DOUBT
*data = MAPILongValue (memCtx, 0);
break;
case PR_ROW_TYPE: // TODO: DOUBT
*data = MAPILongValue (memCtx, TBL_LEAF_ROW);
break;
case PR_DEPTH: // TODO: DOUBT
*data = MAPILongLongValue (memCtx, 0);
break;
case PR_ACCESS: // TODO
*data = MAPILongValue (memCtx, 0x03);
break;
case PR_ACCESS_LEVEL: // TODO
*data = MAPILongValue (memCtx, 0x01);
break;
case PR_VIEW_STYLE:
case PR_VIEW_MAJORVERSION:
*data = MAPILongValue (memCtx, 0);
break;
case PidLidSideEffects: // TODO
*data = MAPILongValue (memCtx, 0x00000000);
break;
case PidLidCurrentVersion:
*data = MAPILongValue (memCtx, 115608); // Outlook 11.5608
break;
case PidLidCurrentVersionName:
*data = [@"11.0" asUnicodeInMemCtx: memCtx];
break;
case PidLidAutoProcessState:
*data = MAPILongValue (memCtx, 0x00000000);
break;
case PidNameContentClass:
*data = [@"Sharing" asUnicodeInMemCtx: memCtx];
break;
case PR_FID:
*data = MAPILongLongValue (memCtx, [container objectId]);
break;
case PR_MID:
*data = MAPILongLongValue (memCtx, [self objectId]);
break;
case PR_MESSAGE_LOCALE_ID:
*data = MAPILongValue (memCtx, 0x0409);
break;
case PR_MESSAGE_FLAGS: // TODO
*data = MAPILongValue (memCtx, MSGFLAG_FROMME | MSGFLAG_READ | MSGFLAG_UNMODIFIED);
break;
case PR_MESSAGE_SIZE: // TODO
/* TODO: choose another name in SOGo for that method */
*data = MAPILongValue (memCtx, [[sogoObject davContentLength] intValue]);
break;
case PR_MSG_STATUS: // TODO
*data = MAPILongValue (memCtx, 0);
break;
case PR_IMPORTANCE: // TODO -> subclass?
*data = MAPILongValue (memCtx, 1);
break;
case PR_PRIORITY: // TODO -> subclass?
*data = MAPILongValue (memCtx, 0);
break;
case PR_SENSITIVITY: // TODO -> subclass in calendar
*data = MAPILongValue (memCtx, 0);
break;
case PR_CHANGE_KEY:
stringValue = [sogoObject davEntityTag];
if (stringValue)
{
stringValue = @"-1";
length = [stringValue length];
if (length < 6) /* guid = 16 bytes */
{
length += 6;
stringValue = [NSString stringWithFormat: @"000000%@",
stringValue];
}
if (length > 6)
stringValue = [stringValue substringFromIndex: length - 6];
stringValue = [NSString stringWithFormat: @"SOGo%@%@%@",
stringValue, stringValue, stringValue];
*data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding]
asShortBinaryInMemCtx: memCtx];
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
break;
case PR_ORIGINAL_SUBJECT_UNICODE:
case PR_CONVERSATION_TOPIC_UNICODE:
rc = [self getProperty: data withTag: PR_NORMALIZED_SUBJECT_UNICODE];
break;
case PR_SUBJECT_PREFIX_UNICODE:
*data = [@"" asUnicodeInMemCtx: memCtx];
break;
case PR_NORMALIZED_SUBJECT_UNICODE:
rc = [self getProperty: data withTag: PR_SUBJECT_UNICODE];
break;
case PR_DISPLAY_TO_UNICODE:
case PR_DISPLAY_CC_UNICODE:
case PR_DISPLAY_BCC_UNICODE:
case PR_ORIGINAL_DISPLAY_TO_UNICODE:
case PR_ORIGINAL_DISPLAY_CC_UNICODE:
case PR_ORIGINAL_DISPLAY_BCC_UNICODE:
*data = [@"" asUnicodeInMemCtx: memCtx];
break;
case PR_LAST_MODIFIER_NAME_UNICODE:
*data = [@"openchange" asUnicodeInMemCtx: memCtx];
break;
case PR_ORIG_MESSAGE_CLASS_UNICODE:
rc = [self getProperty: data withTag: PR_MESSAGE_CLASS_UNICODE];
break;
case PR_HASATTACH:
*data = MAPIBoolValue (memCtx,
[[self childKeysMatchingQualifier: nil
andSortOrderings: nil] count] > 0);
break;
default:
rc = [super getProperty: data withTag: propTag];
stringValue = @"-1";
length = [stringValue length];
if (length < 6) /* guid = 16 bytes */
length += 6;
stringValue = [NSString stringWithFormat: @"000000%@",
stringValue];
if (length > 6)
stringValue = [stringValue substringFromIndex: length - 6];
stringValue = [NSString stringWithFormat: @"SOGo%@%@%@",
stringValue, stringValue, stringValue];
*data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding]
asShortBinaryInMemCtx: memCtx];
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (int) getPrSubject: (void **) data
{
[self subclassResponsibility: _cmd];
return MAPISTORE_ERR_NOT_FOUND;
}
- (int) getPrNormalizedSubject: (void **) data
{
return [self getPrSubject: data];
}
- (int) getPrOriginalSubject: (void **) data
{
return [self getPrNormalizedSubject: data];
}
- (int) getPrConversationTopic: (void **) data
{
return [self getPrNormalizedSubject: data];
}
- (int) getPrSubjectPrefix: (void **) data
{
return [self getEmptyString: data];
}
- (int) getPrDisplayTo: (void **) data
{
return [self getEmptyString: data];
}
- (int) getPrDisplayCc: (void **) data
{
return [self getEmptyString: data];
}
- (int) getPrDisplayBcc: (void **) data
{
return [self getEmptyString: data];
}
- (int) getPrOriginalDisplayTo: (void **) data
{
return [self getPrDisplayTo: data];
}
- (int) getPrOriginalDisplayCc: (void **) data
{
return [self getPrDisplayCc: data];
}
- (int) getPrOriginalDisplayBcc: (void **) data
{
return [self getPrDisplayBcc: data];
}
- (int) getPrLastModifierName: (void **) data
{
NSURL *contextUrl;
contextUrl = [[self context] url];
*data = [[contextUrl user] asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrMessageClass: (void **) data
{
[self subclassResponsibility: _cmd];
return MAPISTORE_ERR_NOT_FOUND;
}
- (int) getPrOrigMessageClass: (void **) data
{
return [self getPrMessageClass: data];
}
- (int) getPrHasattach: (void **) data
{
*data = MAPIBoolValue (memCtx,
[[self childKeysMatchingQualifier: nil
andSortOrderings: nil] count] > 0);
return MAPISTORE_SUCCESS;
}
- (void) save
{
[self subclassResponsibility: _cmd];

View File

@ -24,35 +24,27 @@
#import "MAPIStoreNotesMessage.h"
#include <mapistore/mapistore_errors.h>
@implementation MAPIStoreNotesMessage
- (enum MAPISTATUS) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
- (int) getPrIconIndex: (void **) data // TODO
{
int rc;
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
// *longValue = 0x00000300 for blue
// *longValue = 0x00000301 for green
// *longValue = 0x00000302 for pink
// *longValue = 0x00000303 for yellow
// *longValue = 0x00000304 for white
*data = MAPILongValue (memCtx, 0x00000303);
return MAPISTORE_SUCCESS;
}
rc = MAPI_E_SUCCESS;
switch (propTag)
{
case PR_ICON_INDEX: // TODO
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
// *longValue = 0x00000300 for blue
// *longValue = 0x00000301 for green
// *longValue = 0x00000302 for pink
// *longValue = 0x00000303 for yellow
// *longValue = 0x00000304 for white
*data = MAPILongValue (memCtx, 0x00000303);
break;
case PR_SUBJECT_UNICODE:
rc = [super getProperty: data
withTag: PR_NORMALIZED_SUBJECT_UNICODE];
break;
default:
rc = [super getProperty: data withTag: propTag];
}
return rc;
- (int) getPrSubject: (void **) data
{
return [self getProperty: data
withTag: PR_NORMALIZED_SUBJECT_UNICODE];
}
@end

View File

@ -36,6 +36,8 @@
@interface MAPIStoreObject : NSObject
{
const IMP *classGetters;
NSMutableArray *parentContainersBag;
MAPIStoreObject *container;
id sogoObject;
@ -83,6 +85,12 @@
- (int) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag;
/* helper getters */
- (int) getEmptyString: (void **) data;
- (int) getLongZero: (void **) data;
- (int) getYes: (void **) data;
- (int) getNo: (void **) data;
/* subclasses */
- (id) lookupChild: (NSString *) childKey;
- (NSArray *) childKeysMatchingQualifier: (EOQualifier *) qualifier

View File

@ -25,6 +25,7 @@
#import <SOGo/SOGoObject.h>
#import "MAPIStoreFolder.h"
#import "MAPIStorePropertySelectors.h"
#import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h"
#import "NSString+MAPIStore.h"
@ -64,6 +65,7 @@ static Class NSExceptionK, MAPIStoreFolderK;
{
if ((self = [super init]))
{
classGetters = (IMP *) MAPIStorePropertyGettersForClass (isa);
parentContainersBag = [NSMutableArray new];
container = nil;
sogoObject = nil;
@ -190,52 +192,83 @@ static Class NSExceptionK, MAPIStoreFolderK;
- (int) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
{
NSString *stringValue;
int rc;
MAPIStorePropertyGetter method = NULL;
uint16_t propValue;
const char *propName;
/* TODO: handle unsaved properties */
rc = MAPISTORE_SUCCESS;
switch (propTag)
int rc = MAPISTORE_ERR_NOT_FOUND;
propValue = (propTag & 0xffff0000) >> 16;
method = (MAPIStorePropertyGetter) classGetters[propValue];
if (method)
rc = method (self, NULL, data);
else
{
case PR_DISPLAY_NAME_UNICODE:
*data = [[sogoObject displayName] asUnicodeInMemCtx: memCtx];
break;
case PR_SEARCH_KEY: // TODO
stringValue = [sogoObject nameInContainer];
*data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding]
asBinaryInMemCtx: memCtx];
break;
case PR_GENERATE_EXCHANGE_VIEWS: // TODO
*data = MAPIBoolValue (memCtx, NO);
break;
default:
propName = get_proptag_name (propTag);
if (!propName)
propName = "<unknown>";
propName = "<unknown>";
*data = NULL;
[self warnWithFormat:
@"unhandled or NULL value: %s (0x%.8x), childKey: %@",
propName, propTag, [sogoObject nameInContainer]];
// if ((propTag & 0x001F) == 0x001F)
// {
// stringValue = [NSString stringWithFormat: @"fake %s (0x.8x) value",
// propName, propTag];
// *data = [stringValue asUnicodeInMemCtx: memCtx];
// rc = MAPISTORE_SUCCESS;
// }
// else
// {
*data = NULL;
rc = MAPISTORE_ERR_NOT_FOUND;
// }
break;
@"unimplemented property: %s (0x%.8x) in class '%@'",
propName, propTag, NSStringFromClass (isa)];
}
return rc;
}
/* helper getters */
- (int) getEmptyString: (void **) data
{
*data = [@"" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getLongZero: (void **) data
{
*data = MAPILongValue (memCtx, 0);
return MAPISTORE_SUCCESS;
}
- (int) getYes: (void **) data
{
*data = MAPIBoolValue (memCtx, YES);
return MAPISTORE_SUCCESS;
}
- (int) getNo: (void **) data
{
*data = MAPIBoolValue (memCtx, NO);
return MAPISTORE_SUCCESS;
}
/* getters */
- (int) getPrDisplayName: (void **) data
{
*data = [[sogoObject displayName] asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrSearchKey: (void **) data
{
NSString *stringValue;
stringValue = [sogoObject nameInContainer];
*data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding]
asBinaryInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrGenerateExchangeViews: (void **) data
{
return [self getNo: data];
}
/* MAPIStoreProperty protocol */
- (int) getProperties: (struct mapistore_property_data *) data
withTags: (enum MAPITAGS *) tags
@ -277,8 +310,6 @@ static Class NSExceptionK, MAPIStoreFolderK;
- (NSArray *) childKeysMatchingQualifier: (EOQualifier *) qualifier
andSortOrderings: (NSArray *) sortOrderings
{
[self subclassResponsibility: _cmd];
return nil;
}

View File

@ -25,7 +25,12 @@
#import "MAPIStoreGCSMessage.h"
@class iCalToDo;
@interface MAPIStoreTasksMessage : MAPIStoreGCSMessage
{
iCalToDo *task;
}
@end

View File

@ -49,221 +49,212 @@
@implementation MAPIStoreTasksMessage
- (enum MAPISTATUS) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer
{
NSString *status;
iCalToDo *task;
int32_t statusValue;
NSCalendarDate *dateValue;
int rc;
double doubleValue;
rc = MAPI_E_SUCCESS;
switch ((uint32_t) propTag)
if ((self = [super initWithSOGoObject: newSOGoObject
inContainer: newContainer]))
{
case PR_ICON_INDEX: // TODO
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
// Unassigned recurring task 0x00000501
// Assignee's task 0x00000502
// Assigner's task 0x00000503
// Task request 0x00000504
// Task acceptance 0x00000505
// Task rejection 0x00000506
*data = MAPILongValue (memCtx, 0x00000500);
break;
case PR_MESSAGE_CLASS_UNICODE:
*data = talloc_strdup(memCtx, "IPM.Task");
break;
case PR_SUBJECT_UNICODE: // SUMMARY
task = [sogoObject component: NO secure: NO];
*data = [[task summary] asUnicodeInMemCtx: memCtx];
break;
//
// Not to be confused with PR_PRIORITY
//
// IMPORTANCE_LOW = 0x0, IMPORTANCE_NORMAL = 0x1 and IMPORTANCE_HIGH = 0x2
//
case PR_IMPORTANCE:
{
unsigned int v;
task = [sogoObject component: NO secure: NO];
if ([[task priority] isEqualToString: @"9"])
v = 0x0;
else if ([[task priority] isEqualToString: @"1"])
v = 0x2;
else
v = 0x1;
*data = MAPILongValue (memCtx, v);
}
break;
case PidLidTaskComplete:
task = [sogoObject component: NO secure: NO];
*data = MAPIBoolValue (memCtx,
[[task status] isEqualToString: @"COMPLETED"]);
break;
case PidLidPercentComplete:
task = [sogoObject component: NO secure: NO];
doubleValue = ((double) [[task percentComplete] intValue] / 100);
*data = MAPIDoubleValue (memCtx, doubleValue);
break;
case PidLidTaskDateCompleted:
task = [sogoObject component: NO secure: NO];
dateValue = [task completed];
if (dateValue)
*data = [dateValue asFileTimeInMemCtx: memCtx];
else
rc = MAPISTORE_ERR_NOT_FOUND;
break;
// http://msdn.microsoft.com/en-us/library/cc765590.aspx
// It's important to have a proper value for PidLidTaskState
// as it'll affect the UI options of Outlook - making the
// task non-editable in some cases.
case PidLidTaskState:
*data = MAPILongValue (memCtx, 0x1); // not assigned
break;
case PidLidTaskMode: // TODO
*data = MAPILongValue (memCtx, 0x0);
break;
case PidLidTaskFRecurring:
case PidLidTaskAccepted: // TODO
*data = MAPIBoolValue (memCtx, NO);
break;
case PidLidTaskActualEffort: // TODO
case PidLidTaskEstimatedEffort: // TODO
*data = MAPILongValue (memCtx, 0);
break;
case PR_HASATTACH:
*data = MAPIBoolValue (memCtx, NO);
break;
case PidLidTaskDueDate:
task = [sogoObject component: NO secure: NO];
dateValue = [task due];
if (dateValue)
*data = [dateValue asFileTimeInMemCtx: memCtx];
else
rc = MAPISTORE_ERR_NOT_FOUND;
break;
case PR_CREATION_TIME:
task = [sogoObject component: NO secure: NO];
*data = [[task created] asFileTimeInMemCtx: memCtx];
break;
case PR_MESSAGE_DELIVERY_TIME:
case PR_CLIENT_SUBMIT_TIME:
case PR_LOCAL_COMMIT_TIME:
case PR_LAST_MODIFICATION_TIME:
task = [sogoObject component: NO secure: NO];
*data = [[task lastModified] asFileTimeInMemCtx: memCtx];
break;
case PidLidTaskStatus: // status
task = [sogoObject component: NO secure: NO];
status = [task status];
if (![status length]
|| [status isEqualToString: @"NEEDS-ACTION"])
statusValue = 0;
else if ([status isEqualToString: @"IN-PROCESS"])
statusValue = 1;
else if ([status isEqualToString: @"COMPLETED"])
statusValue = 2;
else
statusValue = 0xff;
*data = MAPILongValue (memCtx, statusValue);
break;
/* Completed */
// - 0x81380003 = -2000
// + 0x81380003 = -4000
// 68330048
// 68420102
case 0x68340003:
case 0x683a0003:
case 0x68410003:
*data = MAPILongValue (memCtx, 0);
break;
// FIXME - use the current user
case PidLidTaskOwner:
*data = [@"openchange@example.com" asUnicodeInMemCtx: memCtx];
break;
// See http://msdn.microsoft.com/en-us/library/cc842113.aspx
case PidLidTaskOwnership:
*data = MAPILongValue (memCtx, 0x0); // not assigned
break;
// #define PidLidFlagRequest 0x9027001f
// #define PidNameContentType 0x905a001f
// #define PidLidBillingInformation 0x908b001f
// #define PidLidTaskStartDate 0x911e0040
// #define PidLidTaskOwner 0x9122001f
// #define PidLidTaskDeadOccurrence 0x9127000b
// #define PidLidTaskMultipleRecipients 0x912a0003
// #define PidLidTaskHistory 0x912b0003
// #define PidLidAcceptanceState 0x912c0003
// #define PidLidTaskLastUser 0x912d001f
// #define PidLidTaskLastUpdate 0x912e0040
// #define PidLidTaskOwnership 0x912f0003
// #define PidLidTaskNoCompute 0x9130000b
// #define PidLidTaskFFixOffline 0x9131000b
// #define PidLidTaskRole 0x9132001f
// #define PidLidTaskVersion 0x91330003
// #define PidLidTaskAssigner 0x9134001f
// #define PidLidTeamTask 0x9135000b
// #define PidLidTaskRecurrence 0x91360102
// #define PidLidTaskResetReminder 0x9137000b
// #define PidLidTaskOrdinal 0x91380003
// #define PidLidMileage 0x914a001f
// #define PidLidAgingDontAgeMe 0x9185000b
// #define PidLidCommonEnd 0x91980040
// #define PidLidCommonStart 0x91990040
// #define PidLidNonSendableBcc 0x91d7001f
// #define PidLidNonSendableCc 0x91d8001f
// #define PidLidNonSendtableTo 0x91d9001f
// #define PidLidNonSendBccTrackStatus 0x91da1003
// #define PidLidNonSendCcTrackStatus 0x91db1003
// #define PidLidNonSendToTrackStatus 0x91dc1003
// #define PidLidReminderDelta 0x91e90003
// #define PidLidReminderFileParameter 0x91ea001f
// #define PidLidReminderSignalTime 0x91eb0040
// #define PidLidReminderOverride 0x91ec000b
// #define PidLidReminderPlaySound 0x91ed000b
// #define PidLidReminderSet 0x91ee000b
// #define PidLidReminderTime 0x91ef0040
// #define PidLidReminderType 0x91f20003
// #define PidLidRemoteStatus 0x91f30003
// #define PidLidSmartNoAttach 0x91fa000b
// #define PidLidTaskGlobalId 0x91fe0102
// #define PidLidVerbResponse 0x9203001f
// #define PidLidVerbStream 0x92040102
// #define PidLidPrivate 0x9224000b
// #define PidLidInternetAccountName 0x9225001f
// #define PidLidInternetAccountStamp 0x9226001f
// #define PidLidUseTnef 0x9227000b
// #define PidLidContactLinkName 0x9229001f
// #define PidLidContactLinkEntry 0x922a0102
// #define PidLidContactLinkSearchKey 0x922b0102
// #define PidLidSpamOriginalFolder 0x92370102
// #define PidLidTaskUpdates 0x9345000b
// #define PidLidTaskStatusOnComplete 0x9346000b
// #define PidLidTaskLastDelegate 0x9347001f
// #define PidLidTaskAssigners 0x934a0102
// #define PidLidTaskFCreator 0x934c000b
// #define PidLidImapDeleted 0x94e50003
// #define PidLidHeaderItem 0x94e60003
default:
rc = [super getProperty: data withTag: propTag];
ASSIGN (task, [newSOGoObject component: NO secure: NO]);
}
return self;
}
- (void) dealloc
{
[task release];
[super dealloc];
}
- (int) getPrIconIndex: (void **) data // TODO
{
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
// Unassigned recurring task 0x00000501
// Assignee's task 0x00000502
// Assigner's task 0x00000503
// Task request 0x00000504
// Task acceptance 0x00000505
// Task rejection 0x00000506
*data = MAPILongValue (memCtx, 0x00000500);
return MAPISTORE_SUCCESS;
}
- (int) getPrMessageClass: (void **) data
{
*data = talloc_strdup(memCtx, "IPM.Task");
return MAPISTORE_SUCCESS;
}
- (int) getPrSubject: (void **) data // SUMMARY
{
*data = [[task summary] asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrImportance: (void **) data
{
uint32_t v;
if ([[task priority] isEqualToString: @"9"])
v = 0x0;
else if ([[task priority] isEqualToString: @"1"])
v = 0x2;
else
v = 0x1;
*data = MAPILongValue (memCtx, v);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidTaskComplete: (void **) data
{
*data = MAPIBoolValue (memCtx,
[[task status] isEqualToString: @"COMPLETED"]);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidPercentComplete: (void **) data
{
double doubleValue;
doubleValue = ((double) [[task percentComplete] intValue] / 100);
*data = MAPIDoubleValue (memCtx, doubleValue);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidTaskDateCompleted: (void **) data
{
NSCalendarDate *dateValue;
int rc = MAPISTORE_SUCCESS;
dateValue = [task completed];
if (dateValue)
*data = [dateValue asFileTimeInMemCtx: memCtx];
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (int) getPidLidTaskState: (void **) data
{
*data = MAPILongValue (memCtx, 0x1); // not assigned
return MAPISTORE_SUCCESS;
}
- (int) getPidLidTaskMode: (void **) data // TODO
{
return [self getLongZero: data];
}
- (int) getPidLidTaskFRecurring: (void **) data
{
return [self getNo: data];
}
- (int) getPidLidTaskAccepted: (void **) data // TODO
{
return [self getNo: data];
}
- (int) getPidLidTaskActualEffort: (void **) data // TODO
{
return [self getLongZero: data];
}
- (int) getPidLidTaskEstimatedEffort: (void **) data // TODO
{
return [self getLongZero: data];
}
- (int) getPrHasattach: (void **) data
{
return [self getNo: data];
}
- (int) getPidLidTaskDueDate: (void **) data
{
NSCalendarDate *dateValue;
int rc = MAPISTORE_SUCCESS;
dateValue = [task due];
if (dateValue)
*data = [dateValue asFileTimeInMemCtx: memCtx];
else
rc = MAPISTORE_ERR_NOT_FOUND;
return MAPISTORE_SUCCESS;
}
- (int) getPrCreationTime: (void **) data
{
*data = [[task created] asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrMessageDeliveryTime: (void **) data
{
*data = [[task lastModified] asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getClientSubmitTime: (void **) data
{
return [self getPrMessageDeliveryTime: data];
}
- (int) getLocalCommitTime: (void **) data
{
return [self getPrMessageDeliveryTime: data];
}
- (int) getLastModificationTime: (void **) data
{
return [self getPrMessageDeliveryTime: data];
}
- (int) getPidLidTaskStatus: (void **) data // status
{
NSString *status;
uint32_t longValue;
status = [task status];
if (![status length]
|| [status isEqualToString: @"NEEDS-ACTION"])
longValue = 0;
else if ([status isEqualToString: @"IN-PROCESS"])
longValue = 1;
else if ([status isEqualToString: @"COMPLETED"])
longValue = 2;
else
longValue = 0xff;
*data = MAPILongValue (memCtx, longValue);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidTaskOwner: (void **) data
{
*data = [@"openchange@example.com" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidLidTaskOwnership: (void **) data
{
return [self getLongZero: data];
}
- (void) save
{
iCalCalendar *vCalendar;