mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-06-06 19:09:43 +00:00
Monotone-Parent: a1865313ff7142cbf139f7645dcbb299dd1acb92
Monotone-Revision: 06779f0bbfe40e7611b69790cf2eff4809382438 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2011-06-07T00:17:46 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -1,5 +1,16 @@
|
||||
2011-06-06 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/*:
|
||||
- (context) cached last requested folder and table
|
||||
- (context) open folders are now cached in an nsdictionary
|
||||
- getPrLastModificationTime and getPrCreationTime are now
|
||||
centralized in MAPIStoreObject and rely on mandator lastModificationTime
|
||||
and creationTime methods on individual subclasses.
|
||||
- openMessage now takes a "struct mapistore_message **" argument.
|
||||
- MAPIStoreFSFolder can now create subfolders
|
||||
- converted MAPIStoreFolder to the new property API, by
|
||||
implementing one method per property.
|
||||
|
||||
* OpenChange/MAPIStoreMailMessage.m: (-getPrExpiryTime:) removed
|
||||
method as we don't want the message to appear as "expired".
|
||||
(-getPrOriginalSensitivity:): uppercased the "o" in "getPrOriginal..."
|
||||
|
||||
@@ -25,12 +25,7 @@
|
||||
|
||||
#import "MAPIStoreGCSMessage.h"
|
||||
|
||||
@class iCalEvent;
|
||||
|
||||
@interface MAPIStoreCalendarMessage : MAPIStoreGCSMessage
|
||||
{
|
||||
iCalEvent *event;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -73,36 +73,17 @@ 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;
|
||||
@@ -124,6 +105,9 @@ static NSTimeZone *utcTZ;
|
||||
struct Binary_r *blob;
|
||||
struct AppointmentRecurrencePattern *pattern;
|
||||
NSMutableArray *otherEvents;
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
|
||||
/* cleanup */
|
||||
otherEvents = [[calendar events] mutableCopy];
|
||||
@@ -169,7 +153,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
struct SBinary_short *sBin;
|
||||
NSCalendarDate *firstStartDate;
|
||||
iCalRecurrenceRule *rule;
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
rule = [[event recurrenceRules] objectAtIndex: 0];
|
||||
|
||||
firstStartDate = [event firstRecurrenceStartDate];
|
||||
@@ -204,6 +190,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
- (int) getPrIconIndex: (void **) data // TODO
|
||||
{
|
||||
uint32_t longValue;
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
|
||||
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
|
||||
// *longValue = 0x00000401 for recurring event
|
||||
@@ -232,6 +221,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
- (int) getPrStartDate: (void **) data
|
||||
{
|
||||
NSCalendarDate *dateValue;
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
|
||||
if ([event isRecurrent])
|
||||
dateValue = [event firstRecurrenceStartDate];
|
||||
@@ -256,6 +248,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
- (int) getPrEndDate: (void **) data
|
||||
{
|
||||
NSCalendarDate *dateValue;
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
|
||||
if ([event isRecurrent])
|
||||
dateValue = [event firstRecurrenceStartDate];
|
||||
@@ -285,6 +280,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
- (int) getPidLidAppointmentDuration: (void **) data
|
||||
{
|
||||
NSTimeInterval timeValue;
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
|
||||
timeValue = [[event endDate] timeIntervalSinceDate: [event startDate]];
|
||||
*data = MAPILongValue (memCtx, (uint32_t) (timeValue / 60));
|
||||
@@ -294,6 +292,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
|
||||
- (int) getPidLidAppointmentSubType: (void **) data
|
||||
{
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
*data = MAPIBoolValue (memCtx, [event isAllDay]);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
@@ -308,6 +309,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
|
||||
- (int) getPrSubject: (void **) data // SUMMARY
|
||||
{
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
*data = [[event summary] asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
@@ -315,6 +319,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
|
||||
- (int) getPidLidLocation: (void **) data // LOCATION
|
||||
{
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
*data = [[event location] asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
@@ -331,17 +338,12 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
return [self getLongZero: data];
|
||||
}
|
||||
|
||||
- (int) getPrCreationTime: (void **) data
|
||||
{
|
||||
*data = [[event created] asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrImportance: (void **) data
|
||||
{
|
||||
uint32_t v;
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
if ([[event priority] isEqualToString: @"9"])
|
||||
v = 0x0;
|
||||
else if ([[event priority] isEqualToString: @"1"])
|
||||
@@ -356,6 +358,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
|
||||
- (int) getPidLidIsRecurring: (void **) data
|
||||
{
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
*data = MAPIBoolValue (memCtx, [event isRecurrent]);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
@@ -363,6 +368,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
|
||||
- (int) getPidLidRecurring: (void **) data
|
||||
{
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
*data = MAPIBoolValue (memCtx, [event isRecurrent]);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
@@ -371,6 +379,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
- (int) getPidLidAppointmentRecur: (void **) data
|
||||
{
|
||||
int rc = MAPISTORE_SUCCESS;
|
||||
iCalEvent *event;
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
|
||||
if ([event isRecurrent])
|
||||
*data = [self _computeAppointmentRecur];
|
||||
@@ -382,50 +393,57 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
|
||||
- (void) openMessage: (struct mapistore_message *) msg
|
||||
{
|
||||
NSString *name, *email;
|
||||
NSString *text;
|
||||
NSArray *attendees;
|
||||
iCalPerson *person;
|
||||
struct SRowSet *recipients;
|
||||
int count, max;
|
||||
iCalEvent *event;
|
||||
|
||||
[super openMessage: msg];
|
||||
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
attendees = [event attendees];
|
||||
max = [attendees count];
|
||||
|
||||
recipients = msg->recipients;
|
||||
recipients = talloc_zero (memCtx, struct SRowSet);
|
||||
recipients->cRows = max;
|
||||
recipients->aRow = talloc_array (recipients, struct SRow, max);
|
||||
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
recipients->aRow[count].ulAdrEntryPad = 0;
|
||||
recipients->aRow[count].cValues = 3;
|
||||
recipients->aRow[count].lpProps = talloc_array (recipients->aRow,
|
||||
struct SPropValue,
|
||||
3);
|
||||
4);
|
||||
|
||||
// TODO (0x01 = primary recipient)
|
||||
set_SPropValue_proptag (&(recipients->aRow[count].lpProps[0]),
|
||||
set_SPropValue_proptag (recipients->aRow[count].lpProps,
|
||||
PR_RECIPIENT_TYPE,
|
||||
MAPILongValue (memCtx, 0x01));
|
||||
|
||||
MAPILongValue (recipients->aRow[count].lpProps, 0x01));
|
||||
|
||||
set_SPropValue_proptag (recipients->aRow[count].lpProps + 1,
|
||||
PR_ADDRTYPE_UNICODE,
|
||||
[@"SMTP" asUnicodeInMemCtx: recipients->aRow]);
|
||||
|
||||
person = [attendees objectAtIndex: count];
|
||||
|
||||
name = [person cn];
|
||||
if (!name)
|
||||
name = @"";
|
||||
|
||||
email = [person email];
|
||||
if (!email)
|
||||
email = @"";
|
||||
|
||||
set_SPropValue_proptag (&(recipients->aRow[count].lpProps[1]),
|
||||
PR_DISPLAY_NAME,
|
||||
[name asUnicodeInMemCtx: recipients->aRow[count].lpProps]);
|
||||
set_SPropValue_proptag (&(recipients->aRow[count].lpProps[2]),
|
||||
PR_EMAIL_ADDRESS,
|
||||
[email asUnicodeInMemCtx: recipients->aRow[count].lpProps]);
|
||||
text = [person rfc822Email];
|
||||
if (!text)
|
||||
text = @"";
|
||||
set_SPropValue_proptag (recipients->aRow[count].lpProps + 2,
|
||||
PR_EMAIL_ADDRESS_UNICODE,
|
||||
[text asUnicodeInMemCtx: recipients->aRow]);
|
||||
|
||||
text = [person cn];
|
||||
if ([text length] > 0)
|
||||
{
|
||||
recipients->aRow[count].cValues++;
|
||||
set_SPropValue_proptag (recipients->aRow[count].lpProps + 3,
|
||||
PR_DISPLAY_NAME_UNICODE,
|
||||
[text asUnicodeInMemCtx: recipients->aRow]);
|
||||
}
|
||||
}
|
||||
msg->recipients = recipients;
|
||||
}
|
||||
|
||||
- (void) save
|
||||
@@ -446,28 +464,24 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
if (![content length])
|
||||
{
|
||||
newEvent = [sogoObject component: YES secure: NO];
|
||||
if (newEvent != event)
|
||||
ASSIGN (event, newEvent);
|
||||
vCalendar = [event parent];
|
||||
vCalendar = [newEvent parent];
|
||||
[vCalendar setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"];
|
||||
content = [vCalendar versitString];
|
||||
}
|
||||
|
||||
vCalendar = [iCalCalendar parseSingleFromSource: content];
|
||||
newEvent = [[vCalendar events] objectAtIndex: 0];
|
||||
if (newEvent != event)
|
||||
ASSIGN (event, newEvent);
|
||||
|
||||
// summary
|
||||
value = [newProperties
|
||||
objectForKey: MAPIPropertyKey (PR_NORMALIZED_SUBJECT_UNICODE)];
|
||||
if (value)
|
||||
[event setSummary: value];
|
||||
[newEvent setSummary: value];
|
||||
|
||||
// Location
|
||||
value = [newProperties objectForKey: MAPIPropertyKey (PidLidLocation)];
|
||||
if (value)
|
||||
[event setLocation: value];
|
||||
[newEvent setLocation: value];
|
||||
|
||||
tzName = [[self ownerTimeZone] name];
|
||||
tz = [iCalTimeZone timeZoneForName: tzName];
|
||||
@@ -479,7 +493,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
value = [newProperties objectForKey: MAPIPropertyKey (PidLidAppointmentStartWhole)];
|
||||
if (value)
|
||||
{
|
||||
start = (iCalDateTime *) [event uniqueChildWithTag: @"dtstart"];
|
||||
start = (iCalDateTime *) [newEvent uniqueChildWithTag: @"dtstart"];
|
||||
[start setTimeZone: tz];
|
||||
[start setDateTime: value];
|
||||
}
|
||||
@@ -490,7 +504,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
value = [newProperties objectForKey: MAPIPropertyKey (PidLidAppointmentEndWhole)];
|
||||
if (value)
|
||||
{
|
||||
end = (iCalDateTime *) [event uniqueChildWithTag: @"dtend"];
|
||||
end = (iCalDateTime *) [newEvent uniqueChildWithTag: @"dtend"];
|
||||
[end setTimeZone: tz];
|
||||
[end setDateTime: value];
|
||||
}
|
||||
@@ -498,9 +512,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
now = [NSCalendarDate date];
|
||||
if ([sogoObject isNew])
|
||||
{
|
||||
[event setCreated: now];
|
||||
[newEvent setCreated: now];
|
||||
}
|
||||
[event setTimeStampAsDate: now];
|
||||
[newEvent setTimeStampAsDate: now];
|
||||
|
||||
// Organizer and attendees
|
||||
value = [newProperties objectForKey: @"recipients"];
|
||||
@@ -517,7 +531,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
person = [iCalPerson new];
|
||||
[person setCn: [dict objectForKey: @"fullName"]];
|
||||
[person setEmail: [dict objectForKey: @"email"]];
|
||||
[event setOrganizer: person];
|
||||
[newEvent setOrganizer: person];
|
||||
[person release];
|
||||
|
||||
recipients = [value objectForKey: @"to"];
|
||||
@@ -534,8 +548,8 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
[person setRole: @"REQ-PARTICIPANT"];
|
||||
|
||||
// FIXME: We must NOT always rely on this
|
||||
if (![event isAttendee: [person rfc822Email]])
|
||||
[event addToAttendees: person];
|
||||
if (![newEvent isAttendee: [person rfc822Email]])
|
||||
[newEvent addToAttendees: person];
|
||||
|
||||
[person release];
|
||||
}
|
||||
@@ -549,7 +563,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
fromData: value];
|
||||
|
||||
// [sogoObject saveContentString: [vCalendar versitString]];
|
||||
[sogoObject saveComponent: event];
|
||||
[sogoObject saveComponent: newEvent];
|
||||
}
|
||||
|
||||
/* TODO: those are stubs meant to prevent OpenChange from crashing when a
|
||||
|
||||
@@ -62,6 +62,15 @@
|
||||
|
||||
/* for active messages (NSDictionary instances) */
|
||||
NSMutableDictionary *messages;
|
||||
|
||||
/* for active folders (NSDictionary instances) */
|
||||
NSMutableDictionary *folders;
|
||||
|
||||
/* hackish table cache */
|
||||
MAPIStoreTable *cachedTable;
|
||||
MAPIStoreFolder *cachedFolder;
|
||||
uint64_t cachedTableFID;
|
||||
uint8_t cachedTableType;
|
||||
}
|
||||
|
||||
+ (id) contextFromURI: (const char *) newUri
|
||||
|
||||
+137
-55
@@ -136,6 +136,8 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
|
||||
[context setupRequest];
|
||||
[context setupBaseFolder: url];
|
||||
[context->folders setObject: context->baseFolder
|
||||
forKey: [NSNumber numberWithUnsignedLongLong: fid]];
|
||||
[context tearDownRequest];
|
||||
|
||||
return context;
|
||||
@@ -192,14 +194,15 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
if ((self = [super init]))
|
||||
{
|
||||
messages = [NSMutableDictionary new];
|
||||
folders = [NSMutableDictionary new];
|
||||
woContext = [WOContext contextWithRequest: nil];
|
||||
[woContext retain];
|
||||
baseFolder = nil;
|
||||
contextUrl = nil;
|
||||
cachedTable = nil;
|
||||
cachedFolder = nil;
|
||||
}
|
||||
|
||||
[self logWithFormat: @"-init"];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -244,9 +247,10 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self logWithFormat: @"-dealloc"];
|
||||
|
||||
[messages release];
|
||||
[folders release];
|
||||
[cachedTable release];
|
||||
[cachedFolder release];
|
||||
|
||||
[baseFolder release];
|
||||
[woContext release];
|
||||
@@ -305,10 +309,78 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
[MAPIApp setMAPIStoreContext: nil];
|
||||
}
|
||||
|
||||
- (MAPIStoreFolder *) lookupFolder: (NSString *) folderURL
|
||||
- (MAPIStoreObject *) _lookupObjectWithParts: (NSArray *) parts
|
||||
{
|
||||
NSUInteger count, max;
|
||||
NSString *currentPart;
|
||||
MAPIStoreObject *currentObject;
|
||||
|
||||
currentObject = baseFolder;
|
||||
max = [parts count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentPart = [parts objectAtIndex: count];
|
||||
if ([currentPart length] > 0)
|
||||
currentObject = [currentObject lookupChild: currentPart];
|
||||
}
|
||||
|
||||
return currentObject;
|
||||
}
|
||||
|
||||
- (id) lookupObject: (NSString *) childURL
|
||||
{
|
||||
NSString *baseURL, *subURL;
|
||||
MAPIStoreObject *foundObject;
|
||||
NSArray *parts;
|
||||
|
||||
baseURL = [contextUrl absoluteString];
|
||||
if (![baseURL hasSuffix: @"/"])
|
||||
baseURL = [NSString stringWithFormat: @"%@/", baseURL];
|
||||
if (![childURL hasSuffix: @"/"])
|
||||
childURL = [NSString stringWithFormat: @"%@/", childURL];
|
||||
if ([childURL isEqualToString: baseURL])
|
||||
foundObject = baseFolder;
|
||||
else if ([childURL hasPrefix: baseURL])
|
||||
{
|
||||
subURL = [childURL substringFromIndex: [baseURL length]];
|
||||
parts = [subURL componentsSeparatedByString: @"/"];
|
||||
foundObject = [self _lookupObjectWithParts: parts];
|
||||
[self logWithFormat: @"returning object '%@'", childURL];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self errorWithFormat: @"url '%@' is not a child of this context (%@)",
|
||||
childURL, baseURL];
|
||||
foundObject = nil;
|
||||
}
|
||||
|
||||
/* TODO hierarchy */
|
||||
return baseFolder;
|
||||
return foundObject;
|
||||
}
|
||||
|
||||
- (id) lookupFolderWithFID: (uint64_t) fid
|
||||
{
|
||||
MAPIStoreFolder *folder;
|
||||
NSNumber *fidKey;
|
||||
NSString *folderURL;
|
||||
|
||||
fidKey = [NSNumber numberWithUnsignedLongLong: fid];
|
||||
folder = [folders objectForKey: fidKey];
|
||||
if (!folder)
|
||||
{
|
||||
/* TODO: should handle folder hierarchies */
|
||||
folderURL = [mapping urlFromID: fid];
|
||||
if (folderURL)
|
||||
{
|
||||
folder = [self lookupObject: folderURL];
|
||||
if (folder)
|
||||
[folders setObject: folder forKey: fidKey];
|
||||
}
|
||||
else
|
||||
[self errorWithFormat: @"folder with url '%@' not found", folderURL];
|
||||
}
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,8 +395,8 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
withFID: (uint64_t) fid
|
||||
inParentFID: (uint64_t) parentFID
|
||||
{
|
||||
NSString *folderURL, *folderKey, *parentFolderURL;
|
||||
MAPIStoreFolder *parentFolder;
|
||||
NSString *folderURL, *folderKey;
|
||||
MAPIStoreFolder *parentFolder, *newFolder;
|
||||
int rc;
|
||||
|
||||
[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
@@ -334,16 +406,22 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
rc = MAPISTORE_ERR_EXIST;
|
||||
else
|
||||
{
|
||||
parentFolderURL = [mapping urlFromID: parentFID];
|
||||
if (parentFolderURL)
|
||||
parentFolder = [self lookupFolderWithFID: parentFID];
|
||||
if (parentFolder)
|
||||
{
|
||||
parentFolder = [self lookupFolder: parentFolderURL];
|
||||
folderKey = [parentFolder createFolder: aRow];
|
||||
folderKey = [parentFolder createFolder: aRow withFID: fid];
|
||||
if (folderKey)
|
||||
{
|
||||
folderURL = [NSString stringWithFormat: @"%@%@/",
|
||||
parentFolderURL, folderKey];
|
||||
[parentFolder cleanupCaches];
|
||||
folderURL = [NSString stringWithFormat: @"%@%@",
|
||||
[parentFolder url], folderKey];
|
||||
[mapping registerURL: folderURL withID: fid];
|
||||
newFolder = [parentFolder lookupChild: folderKey];
|
||||
if (newFolder)
|
||||
[newFolder setProperties: aRow];
|
||||
else
|
||||
[NSException raise: @"MAPIStoreIOException"
|
||||
format: @"unable to fetch created folder"];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
@@ -413,13 +491,19 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
{
|
||||
MAPIStoreFolder *folder;
|
||||
MAPIStoreTable *table;
|
||||
NSString *folderURL;
|
||||
|
||||
/* TODO: should handle folder hierarchies */
|
||||
folderURL = [mapping urlFromID: fid];
|
||||
if (folderURL)
|
||||
if (fid == cachedTableFID && tableType == cachedTableType)
|
||||
table = cachedTable;
|
||||
else
|
||||
{
|
||||
folder = [self lookupFolder: folderURL];
|
||||
[cachedTable release];
|
||||
cachedTable = nil;
|
||||
[cachedFolder release];
|
||||
cachedFolder = nil;
|
||||
cachedTableFID = 0;
|
||||
cachedTableType = 0;
|
||||
|
||||
folder = [self lookupFolderWithFID: fid];
|
||||
if (folder)
|
||||
{
|
||||
if (tableType == MAPISTORE_MESSAGE_TABLE)
|
||||
@@ -432,21 +516,24 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
{
|
||||
table = nil;
|
||||
[NSException raise: @"MAPIStoreIOException"
|
||||
format: @"unsupported table type: %d", tableType];
|
||||
format: @"unsupported table type: %d", tableType];
|
||||
}
|
||||
|
||||
if (table)
|
||||
{
|
||||
cachedTableFID = fid;
|
||||
cachedTableType = tableType;
|
||||
ASSIGN (cachedTable, table);
|
||||
ASSIGN (cachedFolder, folder);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
table = nil;
|
||||
[self errorWithFormat: @"folder with url '%@' not found", folderURL];
|
||||
[self errorWithFormat: @"folder with fid %Lu not found",
|
||||
(unsigned long long) fid];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
table = nil;
|
||||
[self errorWithFormat: @"folder with fid %Lu not found",
|
||||
(unsigned long long) fid];
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
@@ -475,7 +562,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
url = [mapping urlFromID: fid];
|
||||
if (url)
|
||||
{
|
||||
folder = [self lookupFolder: url];
|
||||
folder = [self lookupFolderWithFID: fid];
|
||||
if (folder)
|
||||
{
|
||||
if (tableType == MAPISTORE_MESSAGE_TABLE)
|
||||
@@ -559,16 +646,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
const char *propName;
|
||||
int rc;
|
||||
|
||||
[self errorWithFormat: @"%s: obsolete method", __FUNCTION__];
|
||||
|
||||
// [self logWithFormat: @"METHOD '%s' (%d) -- proptag: %s (0x%.8x), pos: %.8x,"
|
||||
// @" tableType: %d, queryType: %d, fid: %.16x",
|
||||
// __FUNCTION__, __LINE__, propName, proptag, pos, tableType, queryType, fid];
|
||||
|
||||
// [self logWithFormat: @"context restriction state is: %@",
|
||||
// MAPIStringForRestrictionState (restrictionState)];
|
||||
// if (restriction)
|
||||
// [self logWithFormat: @" active qualifier: %@", restriction];
|
||||
// [self errorWithFormat: @"%s: obsolete method", __FUNCTION__];
|
||||
|
||||
folderURL = [mapping urlFromID: fid];
|
||||
if (folderURL)
|
||||
@@ -642,7 +720,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
withMID: (uint64_t) mid
|
||||
inFID: (uint64_t) fid
|
||||
{
|
||||
NSString *messageKey, *folderURL, *messageURL;
|
||||
NSString *messageKey, *messageURL;
|
||||
MAPIStoreMessage *message;
|
||||
MAPIStoreFolder *folder;
|
||||
NSNumber *midKey;
|
||||
@@ -659,9 +737,9 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
messageURL = [mapping urlFromID: mid];
|
||||
if (messageURL)
|
||||
{
|
||||
folder = [self lookupFolderWithFID: fid];
|
||||
messageKey = [self extractChildNameFromURL: messageURL
|
||||
andFolderURLAt: &folderURL];
|
||||
folder = [self lookupFolder: folderURL];
|
||||
andFolderURLAt: NULL];
|
||||
message = [folder lookupChild: messageKey];
|
||||
if (message)
|
||||
{
|
||||
@@ -681,7 +759,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
isAssociated: (BOOL) isAssociated
|
||||
{
|
||||
NSNumber *midKey;
|
||||
NSString *folderURL, *childURL;
|
||||
NSString *childURL;
|
||||
MAPIStoreMessage *message;
|
||||
MAPIStoreFolder *folder;
|
||||
int rc;
|
||||
@@ -695,17 +773,16 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
rc = MAPISTORE_ERR_EXIST;
|
||||
else
|
||||
{
|
||||
folderURL = [mapping urlFromID: fid];
|
||||
if (folderURL)
|
||||
folder = [self lookupFolderWithFID: fid];
|
||||
if (folder)
|
||||
{
|
||||
folder = [self lookupFolder: folderURL];
|
||||
message = [folder createMessage: isAssociated];
|
||||
if (message)
|
||||
{
|
||||
[messages setObject: message forKey: midKey];
|
||||
[message setMAPIRetainCount: [message mapiRetainCount] + 1];
|
||||
childURL = [NSString stringWithFormat: @"%@%@",
|
||||
folderURL, [message nameInContainer]];
|
||||
[folder url], [message nameInContainer]];
|
||||
[mapping registerURL: childURL withID: mid];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
@@ -749,6 +826,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
{
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
folder = (MAPIStoreFolder *) [message container];
|
||||
[self logWithFormat: @"folder for message is: %p", folder];
|
||||
if (isSave)
|
||||
{
|
||||
/* notifications */
|
||||
@@ -985,6 +1063,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
inRow: (struct SRow *) aRow
|
||||
{
|
||||
MAPIStoreMessage *message;
|
||||
MAPIStoreFolder *folder;
|
||||
NSMutableDictionary *properties;
|
||||
NSNumber *midKey;
|
||||
struct SPropValue *cValue;
|
||||
@@ -1023,9 +1102,11 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
}
|
||||
break;
|
||||
case MAPISTORE_FOLDER:
|
||||
[self logWithFormat: @"%s: ignored setting of props on folders",
|
||||
__FUNCTION__];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
folder = [self lookupFolderWithFID: fmid];
|
||||
if (folder)
|
||||
rc = [folder setProperties: aRow];
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
break;
|
||||
default:
|
||||
[self errorWithFormat: @"%s: value of tableType not handled: %d",
|
||||
@@ -1152,7 +1233,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
inFID: (uint64_t) fid
|
||||
withFlags: (uint8_t) flags
|
||||
{
|
||||
NSString *childURL, *folderURL, *childKey;
|
||||
NSString *childURL, *childKey;
|
||||
MAPIStoreFolder *folder;
|
||||
MAPIStoreMessage *message;
|
||||
NSArray *activeTables;
|
||||
@@ -1167,9 +1248,10 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
{
|
||||
[self logWithFormat: @"-deleteMessageWithMID: url (%@) found for object", childURL];
|
||||
|
||||
folder = [self lookupFolderWithFID: fid];
|
||||
|
||||
childKey = [self extractChildNameFromURL: childURL
|
||||
andFolderURLAt: &folderURL];
|
||||
folder = [self lookupFolder: folderURL];
|
||||
andFolderURLAt: NULL];
|
||||
message = [folder lookupChild: childKey];
|
||||
if (message)
|
||||
{
|
||||
@@ -1233,7 +1315,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
[[activeTables objectAtIndex: count]
|
||||
notifyChangesForChild: message];
|
||||
}
|
||||
[self logWithFormat: @"sucessfully deleted object at URL: %@", childURL];
|
||||
[self logWithFormat: @"successfully deleted object at URL: %@", childURL];
|
||||
[mapping unregisterURLWithID: mid];
|
||||
[folder cleanupCaches];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
@@ -1431,10 +1513,10 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
*count = [[message childKeysMatchingQualifier: nil
|
||||
andSortOrderings: nil] count];
|
||||
attTable = [message attachmentTable];
|
||||
*tablePtr = attTable;
|
||||
if (attTable)
|
||||
{
|
||||
[attTable retain];
|
||||
*tablePtr = attTable;
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -1463,10 +1545,10 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
if (aid < [keys count])
|
||||
{
|
||||
attachment = [message lookupChild: [keys objectAtIndex: aid]];
|
||||
*attachmentPtr = attachment;
|
||||
if (attachment)
|
||||
{
|
||||
[attachment retain];
|
||||
*attachmentPtr = attachment;
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
@implementation MAPIStoreDraftsMessage
|
||||
|
||||
@@ -51,6 +52,19 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (int) getPrMessageFlags: (void **) data
|
||||
{
|
||||
unsigned int v = MSGFLAG_FROMME;
|
||||
|
||||
if ([[self childKeysMatchingQualifier: nil
|
||||
andSortOrderings: nil] count] > 0)
|
||||
v |= MSGFLAG_HASATTACH;
|
||||
|
||||
*data = MAPILongValue (memCtx, v);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (void) _saveAttachment: (NSString *) attachmentKey
|
||||
{
|
||||
NSDictionary *properties, *metadata;
|
||||
@@ -233,4 +247,14 @@ e)
|
||||
[self logWithFormat: @"ignored scheduling message"];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) creationTime
|
||||
{
|
||||
return [newProperties objectForKey: MAPIPropertyKey (PR_CREATION_TIME)];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) lastModificationTime
|
||||
{
|
||||
return [newProperties objectForKey: MAPIPropertyKey (PR_LAST_MODIFICATION_TIME)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -24,4 +24,9 @@
|
||||
|
||||
@implementation MAPIStoreFAIMessage
|
||||
|
||||
- (int) getPrAssociated: (void **) data
|
||||
{
|
||||
return [self getYes: data];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import "MAPIStoreFolder.h"
|
||||
|
||||
#import "MAPIStoreFAIMessageTable.h"
|
||||
|
||||
#undef DEBUG
|
||||
@@ -37,4 +39,9 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSArray *) childKeys
|
||||
{
|
||||
return [(MAPIStoreFolder *) container faiMessageKeys];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -22,11 +22,14 @@
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import "EOQualifier+MAPIFS.h"
|
||||
#import "MAPIStoreFSMessage.h"
|
||||
#import "MAPIStoreFSMessageTable.h"
|
||||
#import "MAPIStoreFolderTable.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "SOGoMAPIFSFolder.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
|
||||
@@ -71,6 +74,22 @@ static Class MAPIStoreFSMessageK;
|
||||
return MAPIStoreFSMessageK;
|
||||
}
|
||||
|
||||
- (NSString *) createFolder: (struct SRow *) aRow
|
||||
withFID: (uint64_t) newFID
|
||||
{
|
||||
NSString *newKey, *urlString;
|
||||
SOGoMAPIFSFolder *childFolder;
|
||||
|
||||
newKey = [NSString stringWithFormat: @"0x%.16"PRIx64, (unsigned long long) newFID];
|
||||
|
||||
urlString = [NSString stringWithFormat: @"%@/%@", [self url], newKey];
|
||||
childFolder = [SOGoMAPIFSFolder folderWithURL: [NSURL URLWithString: urlString]
|
||||
andTableType: MAPISTORE_MESSAGE_TABLE];
|
||||
[childFolder ensureDirectory];
|
||||
|
||||
return newKey;
|
||||
}
|
||||
|
||||
- (MAPIStoreMessage *) createMessage
|
||||
{
|
||||
MAPIStoreMessage *newMessage;
|
||||
@@ -122,4 +141,63 @@ static Class MAPIStoreFSMessageK;
|
||||
return keys;
|
||||
}
|
||||
|
||||
- (NSArray *) folderKeys
|
||||
{
|
||||
if (!folderKeys)
|
||||
ASSIGN (folderKeys, [sogoObject toManyRelationshipKeys]);
|
||||
|
||||
return folderKeys;
|
||||
}
|
||||
|
||||
- (id) lookupChild: (NSString *) childKey
|
||||
{
|
||||
id childObject;
|
||||
SOGoMAPIFSFolder *childFolder;
|
||||
|
||||
[self folderKeys];
|
||||
if ([folderKeys containsObject: childKey])
|
||||
{
|
||||
childFolder = [sogoObject lookupName: childKey inContext: nil
|
||||
acquire: NO];
|
||||
childObject = [MAPIStoreFSFolder mapiStoreObjectWithSOGoObject: childFolder
|
||||
inContainer: self];
|
||||
}
|
||||
else
|
||||
childObject = [super lookupChild: childKey];
|
||||
|
||||
return childObject;
|
||||
}
|
||||
|
||||
- (MAPIStoreFAIMessageTable *) folderTable
|
||||
{
|
||||
return [MAPIStoreFolderTable tableForContainer: self];
|
||||
}
|
||||
|
||||
- (NSDate *) lastMessageModificationTime
|
||||
{
|
||||
NSUInteger count, max;
|
||||
NSDate *date, *fileDate;
|
||||
MAPIStoreFSMessage *msg;
|
||||
|
||||
[self messageKeys];
|
||||
|
||||
date = [NSCalendarDate date];
|
||||
[self logWithFormat: @"current date: %@", date];
|
||||
|
||||
max = [messageKeys count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
msg = [self lookupChild: [messageKeys objectAtIndex: count]];
|
||||
fileDate = [msg lastModificationTime];
|
||||
if ([date laterDate: fileDate] == fileDate)
|
||||
{
|
||||
[self logWithFormat: @"current date: %@", date];
|
||||
|
||||
date = fileDate;
|
||||
}
|
||||
}
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,16 +20,49 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
#import "MAPIStorePropertySelectors.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
|
||||
#import "MAPIStoreFSMessage.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
@implementation MAPIStoreFSMessage
|
||||
|
||||
+ (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
|
||||
{
|
||||
struct SPropTagArray *properties;
|
||||
NSUInteger count;
|
||||
enum MAPITAGS faiProperties[] = { 0x68350102, 0x683c0102, 0x683e0102,
|
||||
0x683f0102, 0x68410003, 0x68420102,
|
||||
0x68450102, 0x68460003 };
|
||||
|
||||
properties = talloc_zero (NULL, struct SPropTagArray);
|
||||
properties->cValues = MAPIStoreSupportedPropertiesCount + 8;
|
||||
properties->aulPropTag = talloc_array (NULL, enum MAPITAGS,
|
||||
MAPIStoreSupportedPropertiesCount + 8);
|
||||
|
||||
for (count = 0; count < MAPIStoreSupportedPropertiesCount; count++)
|
||||
properties->aulPropTag[count] = MAPIStoreSupportedProperties[count];
|
||||
|
||||
/* FIXME (hack): append a few undocumented properties that can be added to
|
||||
FAI messages */
|
||||
for (count = 0; count < 8; count++)
|
||||
properties->aulPropTag[MAPIStoreSupportedPropertiesCount+count] = faiProperties[count];
|
||||
|
||||
*propertiesP = properties;
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (enum MAPISTATUS) getProperty: (void **) data
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
@@ -45,10 +78,70 @@
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPrSubject: (void **) data
|
||||
{
|
||||
/* if we get here, it means that the properties file didn't contain a
|
||||
relevant value */
|
||||
return [self getEmptyString: data];
|
||||
}
|
||||
|
||||
- (int) getPrMessageClass: (void **) data
|
||||
{
|
||||
/* if we get here, it means that the properties file didn't contain a
|
||||
relevant value */
|
||||
|
||||
*data = [@"IPM.Note" asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
|
||||
{
|
||||
NSArray *keys;
|
||||
NSUInteger count, max;
|
||||
struct SPropTagArray *properties;
|
||||
|
||||
keys = [[sogoObject properties] allKeys];
|
||||
max = [keys count];
|
||||
|
||||
properties = talloc_zero (NULL, struct SPropTagArray);
|
||||
properties->cValues = max;
|
||||
properties->aulPropTag = talloc_array (properties, enum MAPITAGS, max);
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
// #if (GS_SIZEOF_LONG == 4)
|
||||
// return [NSNumber numberWithUnsignedLong: propTag];
|
||||
// #elif (GS_SIZEOF_INT == 4)
|
||||
// return [NSNumber numberWithUnsignedInt: propTag];
|
||||
// #else
|
||||
|
||||
#if (GS_SIZEOF_LONG == 4)
|
||||
properties->aulPropTag[count] = [[keys objectAtIndex: count] unsignedLongValue];
|
||||
#elif (GS_SIZEOF_INT == 4)
|
||||
properties->aulPropTag[count] = [[keys objectAtIndex: count] unsignedIntValue];
|
||||
#endif
|
||||
}
|
||||
|
||||
*propertiesP = properties;
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (void) save
|
||||
{
|
||||
[sogoObject appendProperties: newProperties];
|
||||
[sogoObject save];
|
||||
[self resetNewProperties];
|
||||
}
|
||||
|
||||
- (NSDate *) creationTime
|
||||
{
|
||||
return [sogoObject creationTime];
|
||||
}
|
||||
|
||||
- (NSDate *) lastModificationTime
|
||||
{
|
||||
return [sogoObject lastModificationTime];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
@class MAPIStoreFolderTable;
|
||||
@class MAPIStoreMessageTable;
|
||||
@class SOGoMAPIFSFolder;
|
||||
@class SOGoMAPIFSMessage;
|
||||
|
||||
#import "MAPIStoreObject.h"
|
||||
|
||||
@@ -49,10 +50,11 @@
|
||||
NSArray *faiMessageKeys;
|
||||
NSMutableArray *folderKeys;
|
||||
|
||||
SOGoMAPIFSFolder *faiFolder;
|
||||
NSDictionary *properties;
|
||||
|
||||
NSMutableArray *activeMessageTables;
|
||||
NSMutableArray *activeFAIMessageTables;
|
||||
SOGoMAPIFSFolder *faiFolder;
|
||||
SOGoMAPIFSFolder *propsFolder;
|
||||
SOGoMAPIFSMessage *propsMessage;
|
||||
}
|
||||
|
||||
+ (id) baseFolderWithURL: (NSURL *) newURL
|
||||
@@ -73,7 +75,8 @@
|
||||
- (NSArray *) folderKeys;
|
||||
|
||||
- (MAPIStoreMessage *) createMessage: (BOOL) isAssociated;
|
||||
- (NSString *) createFolder: (struct SRow *) aRow;
|
||||
- (NSString *) createFolder: (struct SRow *) aRow
|
||||
withFID: (uint64_t) newFID;
|
||||
|
||||
/* helpers */
|
||||
- (uint64_t) idForObjectWithKey: (NSString *) childKey;
|
||||
@@ -82,6 +85,8 @@
|
||||
- (Class) messageClass;
|
||||
- (MAPIStoreMessage *) createMessage;
|
||||
|
||||
- (NSCalendarDate *) lastMessageModificationTime;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* MAPISTOREFOLDER_H */
|
||||
|
||||
+189
-44
@@ -23,6 +23,7 @@
|
||||
/* TODO: main key arrays must be initialized */
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
@@ -36,7 +37,9 @@
|
||||
#import "MAPIStoreFolder.h"
|
||||
#import "MAPIStoreMessage.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSDate+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
#import "SOGoMAPIFSFolder.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
|
||||
@@ -45,7 +48,7 @@
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_nameid.h>
|
||||
// #include <mapistore/mapistore_errors.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStoreFolderTableK;
|
||||
|
||||
@@ -81,11 +84,14 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
|
||||
folderURL = nil;
|
||||
context = nil;
|
||||
|
||||
propsFolder = nil;
|
||||
propsMessage = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/* from context */
|
||||
- (id) initWithURL: (NSURL *) newURL
|
||||
inContext: (MAPIStoreContext *) newContext
|
||||
{
|
||||
@@ -96,13 +102,71 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
|
||||
ASSIGN (faiFolder,
|
||||
[SOGoMAPIFSFolder folderWithURL: newURL
|
||||
andTableType: MAPISTORE_FAI_TABLE]);
|
||||
ASSIGN (propsFolder,
|
||||
[SOGoMAPIFSFolder folderWithURL: newURL
|
||||
andTableType: MAPISTORE_FOLDER_TABLE]);
|
||||
ASSIGN (propsMessage,
|
||||
[SOGoMAPIFSMessage objectWithName: @"properties.plist"
|
||||
inContainer: propsFolder]);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/* from parent folder */
|
||||
- (id) initWithSOGoObject: (id) newSOGoObject
|
||||
inContainer: (MAPIStoreObject *) newContainer
|
||||
{
|
||||
NSURL *propsURL;
|
||||
|
||||
if ((self = [super initWithSOGoObject: newSOGoObject inContainer: newContainer]))
|
||||
{
|
||||
propsURL = [NSURL URLWithString: [self url]];
|
||||
ASSIGN (propsFolder,
|
||||
[SOGoMAPIFSFolder folderWithURL: propsURL
|
||||
andTableType: MAPISTORE_FOLDER_TABLE]);
|
||||
ASSIGN (propsMessage,
|
||||
[SOGoMAPIFSMessage objectWithName: @"properties.plist"
|
||||
inContainer: propsFolder]);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (int) setProperties: (struct SRow *) aRow
|
||||
{
|
||||
static enum MAPITAGS bannedProps[] = { PR_MID, PR_FID, PR_PARENT_FID,
|
||||
PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY,
|
||||
PR_CHANGE_NUM, PR_CHANGE_KEY,
|
||||
0x00000000 };
|
||||
enum MAPITAGS *currentProp;
|
||||
int rc;
|
||||
|
||||
rc = [super setProperties: aRow];
|
||||
|
||||
/* TODO: this should no longer be required once mapistore v2 API is in
|
||||
place, when we can then do this from -dealloc below */
|
||||
if ([newProperties count] > 0)
|
||||
{
|
||||
currentProp = bannedProps;
|
||||
while (*currentProp)
|
||||
{
|
||||
[newProperties removeObjectForKey: MAPIPropertyKey (*currentProp)];
|
||||
currentProp++;
|
||||
}
|
||||
|
||||
[propsMessage appendProperties: newProperties];
|
||||
[propsMessage save];
|
||||
[self resetNewProperties];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[propsMessage release];
|
||||
[propsFolder release];
|
||||
[folderURL release];
|
||||
[messageKeys release];
|
||||
[faiMessageKeys release];
|
||||
@@ -209,8 +273,8 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
|
||||
if ([faiMessageKeys containsObject: childKey])
|
||||
{
|
||||
msgObject = [faiFolder lookupName: childKey
|
||||
inContext: nil
|
||||
acquire: NO];
|
||||
inContext: nil
|
||||
acquire: NO];
|
||||
newChild
|
||||
= [MAPIStoreFAIMessage mapiStoreObjectWithSOGoObject: msgObject
|
||||
inContainer: self];
|
||||
@@ -218,8 +282,8 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
|
||||
else
|
||||
{
|
||||
msgObject = [sogoObject lookupName: childKey
|
||||
inContext: nil
|
||||
acquire: NO];
|
||||
inContext: nil
|
||||
acquire: NO];
|
||||
if ([msgObject isKindOfClass: NSExceptionK])
|
||||
msgObject = nil;
|
||||
|
||||
@@ -237,48 +301,111 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
|
||||
return newChild;
|
||||
}
|
||||
|
||||
- (enum MAPISTATUS) getProperty: (void **) data
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
- (int) getPrParentFid: (void **) data
|
||||
{
|
||||
*data = MAPILongLongValue (memCtx, [container objectId]);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrFid: (void **) data
|
||||
{
|
||||
*data = MAPILongLongValue (memCtx, [self objectId]);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrAccess: (void **) data
|
||||
{
|
||||
*data = MAPILongValue (memCtx, 0x63);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrAccessLevel: (void **) data
|
||||
{
|
||||
*data = MAPILongValue (memCtx, 0x01);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrAttrHidden: (void **) data
|
||||
{
|
||||
return [self getNo: data];
|
||||
}
|
||||
|
||||
- (int) getPrAttrSystem: (void **) data
|
||||
{
|
||||
return [self getNo: data];
|
||||
}
|
||||
|
||||
- (int) getPrAttrReadOnly: (void **) data
|
||||
{
|
||||
return [self getNo: data];
|
||||
}
|
||||
|
||||
- (int) getPrSubfolders: (void **) data
|
||||
{
|
||||
*data = MAPIBoolValue (memCtx, [folderKeys count] > 0);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrFolderChildCount: (void **) data;
|
||||
{
|
||||
*data = MAPILongValue (memCtx, [[self folderKeys] count]);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrContentCount: (void **) data
|
||||
{
|
||||
*data = MAPILongValue (memCtx, [[self messageKeys] count]);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrContentUnread: (void **) data
|
||||
{
|
||||
*data = MAPILongValue (memCtx, 0);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrAssocContentCount: (void **) data
|
||||
{
|
||||
*data = MAPILongValue (memCtx, [[self faiMessageKeys] count]);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrDeletedCountTotal: (void **) data
|
||||
{
|
||||
/* TODO */
|
||||
*data = MAPILongValue (memCtx, 0);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrLocalCommitTimeMax: (void **) data
|
||||
{
|
||||
*data = [[self lastMessageModificationTime] asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getProperty: (void **) data
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
int rc;
|
||||
id value;
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
switch (propTag)
|
||||
{
|
||||
case PR_FID:
|
||||
/* TODO: incomplete */
|
||||
*data = MAPILongValue (memCtx, [self objectId]);
|
||||
break;
|
||||
case PR_ACCESS: // TODO
|
||||
*data = MAPILongValue (memCtx, 0x63);
|
||||
break;
|
||||
case PR_ACCESS_LEVEL: // TODO
|
||||
*data = MAPILongValue (memCtx, 0x01);
|
||||
break;
|
||||
case PR_PARENT_FID:
|
||||
*data = MAPILongLongValue (memCtx, [container objectId]);
|
||||
break;
|
||||
case PR_ATTR_HIDDEN:
|
||||
case PR_ATTR_SYSTEM:
|
||||
case PR_ATTR_READONLY:
|
||||
*data = MAPIBoolValue (memCtx, NO);
|
||||
break;
|
||||
case PR_SUBFOLDERS:
|
||||
*data = MAPIBoolValue (memCtx, [folderKeys count]);
|
||||
// [[child toManyRelationshipKeys] count] > 0);
|
||||
break;
|
||||
case PR_CONTENT_COUNT:
|
||||
*data = MAPILongValue (memCtx, [messageKeys count]);
|
||||
break;
|
||||
// case PR_EXTENDED_FOLDER_FLAGS: // TODO: DOUBT: how to indicate the
|
||||
// // number of subresponses ?
|
||||
// binaryValue = talloc_zero(memCtx, struct Binary_r);
|
||||
// *data = binaryValue;
|
||||
// break;
|
||||
default:
|
||||
rc = [super getProperty: data
|
||||
withTag: propTag];
|
||||
}
|
||||
value = [[propsMessage properties]
|
||||
objectForKey: MAPIPropertyKey (propTag)];
|
||||
if (value)
|
||||
rc = [value getMAPIValue: data forTag: propTag inMemCtx: memCtx];
|
||||
else
|
||||
rc = [super getProperty: data withTag: propTag];
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -313,6 +440,7 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
|
||||
}
|
||||
|
||||
- (NSString *) createFolder: (struct SRow *) aRow
|
||||
withFID: (uint64_t) newFID
|
||||
{
|
||||
[self errorWithFormat: @"new folders cannot be created in this context"];
|
||||
|
||||
@@ -351,6 +479,16 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
|
||||
inFolderURL: [self url]];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) creationTime
|
||||
{
|
||||
return [propsMessage creationTime];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) lastModificationTime
|
||||
{
|
||||
return [propsMessage lastModificationTime];
|
||||
}
|
||||
|
||||
/* subclasses */
|
||||
|
||||
- (MAPIStoreMessageTable *) messageTable
|
||||
@@ -371,4 +509,11 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) lastMessageModificationTime
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
#import "NSDate+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreGCSFolder.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
@implementation MAPIStoreGCSFolder
|
||||
|
||||
@@ -60,7 +64,7 @@
|
||||
}
|
||||
else
|
||||
fetchQualifier = componentQualifier;
|
||||
|
||||
|
||||
ocsFolder = [sogoObject ocsFolder];
|
||||
fs = [EOFetchSpecification
|
||||
fetchSpecificationWithEntityName: [ocsFolder folderName]
|
||||
@@ -73,6 +77,11 @@
|
||||
return keys;
|
||||
}
|
||||
|
||||
- (NSDate *) lastMessageModificationTime
|
||||
{
|
||||
return [[sogoObject ocsFolder] lastModificationDate];
|
||||
}
|
||||
|
||||
/* subclasses */
|
||||
|
||||
- (EOQualifier *) componentQualifier
|
||||
|
||||
@@ -20,8 +20,25 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <SOGo/SOGoContentObject.h>
|
||||
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
||||
#import "MAPIStoreGCSMessage.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
@implementation MAPIStoreGCSMessage
|
||||
|
||||
- (NSCalendarDate *) creationTime
|
||||
{
|
||||
return [sogoObject creationDate];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) lastModificationTime
|
||||
{
|
||||
return [sogoObject lastModified];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -30,7 +30,12 @@
|
||||
@class SOGoMailAccount;
|
||||
@class SOGoMailFolder;
|
||||
|
||||
@class MAPIStoreMailMessageTable;
|
||||
|
||||
@interface MAPIStoreMailFolder : MAPIStoreFolder
|
||||
{
|
||||
MAPIStoreMailMessageTable *messageTable;
|
||||
}
|
||||
|
||||
/* subclasses */
|
||||
- (SOGoMailFolder *) specialFolderFromAccount: (SOGoMailAccount *) account
|
||||
|
||||
@@ -53,6 +53,7 @@ static Class SOGoMailFolderK;
|
||||
|
||||
#undef DEBUG
|
||||
#include <libmapi/libmapi.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
@implementation MAPIStoreMailFolder
|
||||
|
||||
@@ -108,6 +109,12 @@ static Class SOGoMailFolderK;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[messageTable release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (SOGoMailFolder *) specialFolderFromAccount: (SOGoMailAccount *) accountFolder
|
||||
inContext: (WOContext *) woContext
|
||||
{
|
||||
@@ -118,7 +125,13 @@ static Class SOGoMailFolderK;
|
||||
|
||||
- (MAPIStoreMessageTable *) messageTable
|
||||
{
|
||||
return [MAPIStoreMailMessageTable tableForContainer: self];
|
||||
if (!messageTable)
|
||||
{
|
||||
ASSIGN (messageTable, [MAPIStoreMailMessageTable tableForContainer: self]);
|
||||
[self logWithFormat: @"new message table"];
|
||||
}
|
||||
|
||||
return messageTable;
|
||||
}
|
||||
|
||||
- (Class) messageClass
|
||||
@@ -127,6 +140,7 @@ static Class SOGoMailFolderK;
|
||||
}
|
||||
|
||||
- (NSString *) createFolder: (struct SRow *) aRow
|
||||
withFID: (uint64_t) newFID
|
||||
{
|
||||
NSString *folderName, *nameInContainer;
|
||||
SOGoMailFolder *newFolder;
|
||||
@@ -156,42 +170,33 @@ static Class SOGoMailFolderK;
|
||||
return nameInContainer;
|
||||
}
|
||||
|
||||
- (enum MAPISTATUS) getProperty: (void **) data
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
- (int) getPrContentUnread: (void **) data
|
||||
{
|
||||
enum MAPISTATUS rc;
|
||||
EOQualifier *searchQualifier;
|
||||
uint32_t intValue;
|
||||
uint32_t longValue;
|
||||
|
||||
searchQualifier
|
||||
= [EOQualifier qualifierWithQualifierFormat: @"flags = %@", @"unseen"];
|
||||
longValue = [[sogoObject fetchUIDsMatchingQualifier: searchQualifier
|
||||
sortOrdering: nil]
|
||||
count];
|
||||
*data = MAPILongValue (memCtx, longValue);
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
switch (propTag)
|
||||
{
|
||||
case PR_CONTENT_UNREAD:
|
||||
searchQualifier
|
||||
= [EOQualifier qualifierWithQualifierFormat: @"flags = %@", @"unseen"];
|
||||
intValue = [[sogoObject fetchUIDsMatchingQualifier: searchQualifier
|
||||
sortOrdering: nil] count];
|
||||
*data = MAPILongValue (memCtx, intValue);
|
||||
break;
|
||||
case PR_CONTAINER_CLASS_UNICODE:
|
||||
*data = [@"IPF.Note" asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
default:
|
||||
{
|
||||
const char *propName;
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
propName = get_proptag_name (propTag);
|
||||
if (!propName)
|
||||
propName = "<unknown>";
|
||||
[self warnWithFormat: @"get folder tag: %s (0x%.8x)", propName,
|
||||
propTag];
|
||||
}
|
||||
|
||||
|
||||
rc = [super getProperty: data withTag: propTag];
|
||||
}
|
||||
- (int) getPrContainerClass: (void **) data
|
||||
{
|
||||
*data = [@"IPF.Note" asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return rc;
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrMessageClass: (void **) data
|
||||
{
|
||||
*data = [@"IPM.Note" asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (NSArray *) childKeysMatchingQualifier: (EOQualifier *) qualifier
|
||||
@@ -263,6 +268,16 @@ static Class SOGoMailFolderK;
|
||||
return childObject;
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) creationTime
|
||||
{
|
||||
return [NSCalendarDate dateWithTimeIntervalSince1970: 0x4dbb2dbe]; /* oc_version_time */
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) lastModificationTime
|
||||
{
|
||||
return [NSCalendarDate date];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MAPIStoreInboxFolder : MAPIStoreMailFolder
|
||||
|
||||
@@ -85,6 +85,11 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
|
||||
MAPIStoreDraftsFolderK = [MAPIStoreDraftsFolder class];
|
||||
}
|
||||
|
||||
+ (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
|
||||
{
|
||||
return [super getAvailableProperties: propertiesP];
|
||||
}
|
||||
|
||||
- (int) getPrIconIndex: (void **) data
|
||||
{
|
||||
uint32_t longValue;
|
||||
@@ -187,16 +192,14 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrCreationTime: (void **) data // DOUBT
|
||||
- (NSCalendarDate *) creationTime
|
||||
{
|
||||
*data = [[sogoObject date] asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
return [sogoObject date];
|
||||
}
|
||||
|
||||
- (int) getPrLastModificationTime: (void **) data // DOUBT
|
||||
- (NSCalendarDate *) lastModificationTime
|
||||
{
|
||||
return [self getPrCreationTime: data];
|
||||
return [sogoObject date];
|
||||
}
|
||||
|
||||
- (int) getPrLatestDeliveryTime: (void **) data // DOUBT
|
||||
@@ -651,7 +654,7 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
|
||||
NSArray *to;
|
||||
NSInteger count, max;
|
||||
NGImap4EnvelopeAddress *currentAddress;
|
||||
NSString *name;
|
||||
NSString *text;
|
||||
|
||||
[super openMessage: msg];
|
||||
/* Retrieve recipients from the message */
|
||||
@@ -663,25 +666,38 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
recipients->aRow[count].ulAdrEntryPad = 0;
|
||||
recipients->aRow[count].cValues = 2;
|
||||
recipients->aRow[count].cValues = 3;
|
||||
recipients->aRow[count].lpProps = talloc_array (recipients->aRow,
|
||||
struct SPropValue,
|
||||
2);
|
||||
4);
|
||||
|
||||
// TODO (0x01 = primary recipient)
|
||||
set_SPropValue_proptag (&(recipients->aRow[count].lpProps[0]),
|
||||
set_SPropValue_proptag (recipients->aRow[count].lpProps + 0,
|
||||
PR_RECIPIENT_TYPE,
|
||||
MAPILongValue (memCtx, 0x01));
|
||||
|
||||
MAPILongValue (recipients->aRow, 0x01));
|
||||
|
||||
set_SPropValue_proptag (recipients->aRow[count].lpProps + 1,
|
||||
PR_ADDRTYPE_UNICODE,
|
||||
[@"SMTP" asUnicodeInMemCtx: recipients->aRow]);
|
||||
|
||||
currentAddress = [to objectAtIndex: count];
|
||||
// name = [currentAddress personalName];
|
||||
// if (![name length])
|
||||
name = [currentAddress baseEMail];
|
||||
if (!name)
|
||||
name = @"";
|
||||
set_SPropValue_proptag (&(recipients->aRow[count].lpProps[1]),
|
||||
PR_DISPLAY_NAME,
|
||||
[name asUnicodeInMemCtx: recipients->aRow[count].lpProps]);
|
||||
// text = [currentAddress personalName];
|
||||
// if (![text length])
|
||||
text = [currentAddress baseEMail];
|
||||
if (!text)
|
||||
text = @"";
|
||||
set_SPropValue_proptag (recipients->aRow[count].lpProps + 2,
|
||||
PR_EMAIL_ADDRESS_UNICODE,
|
||||
[text asUnicodeInMemCtx: recipients->aRow]);
|
||||
|
||||
text = [currentAddress personalName];
|
||||
if ([text length] > 0)
|
||||
{
|
||||
recipients->aRow[count].cValues++;
|
||||
set_SPropValue_proptag (recipients->aRow[count].lpProps + 3,
|
||||
PR_DISPLAY_NAME_UNICODE,
|
||||
[text asUnicodeInMemCtx: recipients->aRow]);
|
||||
}
|
||||
}
|
||||
msg->recipients = recipients;
|
||||
}
|
||||
|
||||
@@ -180,15 +180,15 @@
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrViewStyle: (void **) data
|
||||
{
|
||||
return [self getLongZero: data];
|
||||
}
|
||||
// - (int) getPrViewStyle: (void **) data
|
||||
// {
|
||||
// return [self getLongZero: data];
|
||||
// }
|
||||
|
||||
- (int) getPrViewMajorversion: (void **) data
|
||||
{
|
||||
return [self getLongZero: data];
|
||||
}
|
||||
// - (int) getPrViewMajorversion: (void **) data
|
||||
// {
|
||||
// return [self getLongZero: data];
|
||||
// }
|
||||
|
||||
- (int) getPidLidSideEffects: (void **) data // TODO
|
||||
{
|
||||
@@ -281,35 +281,6 @@
|
||||
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;
|
||||
|
||||
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]
|
||||
asBinaryInMemCtx: memCtx];
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPrSubject: (void **) data
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
@@ -352,20 +323,20 @@
|
||||
return [self getEmptyString: data];
|
||||
}
|
||||
|
||||
- (int) getPrOriginalDisplayTo: (void **) data
|
||||
{
|
||||
return [self getPrDisplayTo: data];
|
||||
}
|
||||
// - (int) getPrOriginalDisplayTo: (void **) data
|
||||
// {
|
||||
// return [self getPrDisplayTo: data];
|
||||
// }
|
||||
|
||||
- (int) getPrOriginalDisplayCc: (void **) data
|
||||
{
|
||||
return [self getPrDisplayCc: data];
|
||||
}
|
||||
// - (int) getPrOriginalDisplayCc: (void **) data
|
||||
// {
|
||||
// return [self getPrDisplayCc: data];
|
||||
// }
|
||||
|
||||
- (int) getPrOriginalDisplayBcc: (void **) data
|
||||
{
|
||||
return [self getPrDisplayBcc: data];
|
||||
}
|
||||
// - (int) getPrOriginalDisplayBcc: (void **) data
|
||||
// {
|
||||
// return [self getPrDisplayBcc: data];
|
||||
// }
|
||||
|
||||
- (int) getPrLastModifierName: (void **) data
|
||||
{
|
||||
@@ -398,6 +369,11 @@
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrAssociated: (void **) data
|
||||
{
|
||||
return [self getNo: data];
|
||||
}
|
||||
|
||||
- (void) save
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
+ (id) mapiStoreObjectWithSOGoObject: (id) newSOGoObject
|
||||
inContainer: (MAPIStoreObject *) newContainer;
|
||||
+ (int) getAvailableProperties: (struct SPropTagArray **) properties;
|
||||
+ (int) getAvailableProperties: (struct SPropTagArray **) propertiesP;
|
||||
|
||||
- (id) initWithSOGoObject: (id) newSOGoObject
|
||||
inContainer: (MAPIStoreObject *) newFolder;
|
||||
@@ -69,7 +69,6 @@
|
||||
- (uint64_t) objectId;
|
||||
- (NSString *) url;
|
||||
|
||||
|
||||
/* properties */
|
||||
|
||||
- (void) addNewProperties: (NSDictionary *) newNewProperties;
|
||||
@@ -77,7 +76,7 @@
|
||||
- (void) resetNewProperties;
|
||||
|
||||
/* ops */
|
||||
- (int) getAvailableProperties: (struct SPropTagArray **) properties;
|
||||
- (int) getAvailableProperties: (struct SPropTagArray **) propertiesP;
|
||||
- (int) getProperties: (struct mapistore_property_data *) data
|
||||
withTags: (enum MAPITAGS *) tags
|
||||
andCount: (uint16_t) columnCount;
|
||||
@@ -92,8 +91,23 @@
|
||||
- (int) getLongZero: (void **) data;
|
||||
- (int) getYes: (void **) data;
|
||||
- (int) getNo: (void **) data;
|
||||
- (int) getReplicaKey: (void **) data
|
||||
fromGlobCnt: (uint64_t) objectCnt;
|
||||
|
||||
/* implemented getters */
|
||||
- (int) getPrDisplayName: (void **) data;
|
||||
- (int) getPrSearchKey: (void **) data;
|
||||
- (int) getPrGenerateExchangeViews: (void **) data;
|
||||
- (int) getPrParentSourceKey: (void **) data;
|
||||
- (int) getPrSourceKey: (void **) data;
|
||||
- (int) getPrChangeKey: (void **) data;
|
||||
- (int) getPrCreationTime: (void **) data;
|
||||
- (int) getPrLastModificationTime: (void **) data;
|
||||
|
||||
/* subclasses */
|
||||
- (NSDate *) creationTime;
|
||||
- (NSDate *) lastModificationTime;
|
||||
|
||||
- (id) lookupChild: (NSString *) childKey;
|
||||
- (NSArray *) childKeysMatchingQualifier: (EOQualifier *) qualifier
|
||||
andSortOrderings: (NSArray *) sortOrderings;
|
||||
|
||||
@@ -24,9 +24,11 @@
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <SOGo/SOGoObject.h>
|
||||
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreFolder.h"
|
||||
#import "MAPIStorePropertySelectors.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSDate+MAPIStore.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
||||
@@ -119,10 +121,10 @@ static Class NSExceptionK, MAPIStoreFolderK;
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[sogoObject release];
|
||||
[newProperties release];
|
||||
[parentContainersBag release];
|
||||
[container release];
|
||||
[sogoObject release];
|
||||
[newProperties dealloc];
|
||||
talloc_free (memCtx);
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -192,8 +194,6 @@ static Class NSExceptionK, MAPIStoreFolderK;
|
||||
containerURL, [self nameInContainer]];
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void) addNewProperties: (NSDictionary *) newNewProperties
|
||||
{
|
||||
[newProperties addEntriesFromDictionary: newNewProperties];
|
||||
@@ -233,12 +233,12 @@ static Class NSExceptionK, MAPIStoreFolderK;
|
||||
propName = get_proptag_name (propTag);
|
||||
if (!propName)
|
||||
propName = "<unknown>";
|
||||
[self warnWithFormat:
|
||||
@"unimplemented selector (%@) for %s (0x%.8x)",
|
||||
NSStringFromSelector (methodSel), propName, propTag];
|
||||
// [self warnWithFormat:
|
||||
// @"unimplemented selector (%@) for %s (0x%.8x)",
|
||||
// NSStringFromSelector (methodSel), propName, propTag];
|
||||
}
|
||||
else
|
||||
[self warnWithFormat: @"unsupported property tag: 0x%.8x", propTag];
|
||||
// else
|
||||
// [self warnWithFormat: @"unsupported property tag: 0x%.8x", propTag];
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -273,8 +273,34 @@ static Class NSExceptionK, MAPIStoreFolderK;
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getReplicaKey: (void **) data
|
||||
fromGlobCnt: (uint64_t) objectCnt
|
||||
{
|
||||
struct mapistore_connection_info *connInfo;
|
||||
NSMutableData *replicaKey;
|
||||
char buffer[6];
|
||||
NSUInteger count;
|
||||
|
||||
connInfo = [[self context] connectionInfo];
|
||||
|
||||
for (count = 0; count < 6; count++)
|
||||
{
|
||||
buffer[count] = objectCnt & 0xff;
|
||||
objectCnt >>= 8;
|
||||
}
|
||||
|
||||
replicaKey = [NSMutableData dataWithCapacity: 22];
|
||||
[replicaKey appendBytes: &connInfo->replica_guid
|
||||
length: sizeof (struct GUID)];
|
||||
[replicaKey appendBytes: buffer
|
||||
length: 6];
|
||||
*data = [replicaKey asBinaryInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
/* getters */
|
||||
- (int) getPrDisplayName: (void **) data
|
||||
- (int) getPrDisplayName: (void **) data
|
||||
{
|
||||
*data = [[sogoObject displayName] asUnicodeInMemCtx: memCtx];
|
||||
|
||||
@@ -297,6 +323,54 @@ static Class NSExceptionK, MAPIStoreFolderK;
|
||||
return [self getNo: data];
|
||||
}
|
||||
|
||||
- (int) getPrParentSourceKey: (void **) data
|
||||
{
|
||||
return [self getReplicaKey: data fromGlobCnt: [container objectId] >> 16];
|
||||
}
|
||||
|
||||
- (int) getPrSourceKey: (void **) data
|
||||
{
|
||||
return [self getReplicaKey: data fromGlobCnt: [self objectId] >> 16];
|
||||
}
|
||||
|
||||
- (uint64_t) objectVersion
|
||||
{
|
||||
uint32_t lmTime;
|
||||
|
||||
lmTime = (uint32_t) [[self lastModificationTime] timeIntervalSince1970];
|
||||
if (lmTime < 0x4dbb2dbe) /* oc_version_time */
|
||||
lmTime = 0x4dbb2dbe;
|
||||
|
||||
return ((([self objectId] & 0xffff000000000000LL) >> 16)
|
||||
| (exchange_globcnt((uint64_t) lmTime - 0x4dbb2dbe) >> 16));
|
||||
}
|
||||
|
||||
- (int) getPrChangeKey: (void **) data
|
||||
{
|
||||
return [self getReplicaKey: data fromGlobCnt: [self objectVersion]];
|
||||
}
|
||||
|
||||
- (int) getPrChangeNum: (void **) data
|
||||
{
|
||||
*data = MAPILongLongValue (memCtx, ([self objectVersion] << 16) | 0x0001);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrCreationTime: (void **) data
|
||||
{
|
||||
*data = [[self creationTime] asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrLastModificationTime: (void **) data
|
||||
{
|
||||
*data = [[self lastModificationTime] asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
|
||||
{
|
||||
return [isa getAvailableProperties: propertiesP];
|
||||
@@ -332,6 +406,20 @@ static Class NSExceptionK, MAPIStoreFolderK;
|
||||
}
|
||||
|
||||
/* subclasses */
|
||||
- (NSDate *) creationTime
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSDate *) lastModificationTime
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id) lookupChild: (NSString *) childKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
@@ -718,6 +718,9 @@ static Class NSDataK, NSStringK;
|
||||
case 6: state = [self evaluateBitmaskRestriction: &res->res.resBitmask
|
||||
intoQualifier: qualifier];
|
||||
break;
|
||||
|
||||
case 7: state = MAPIRestrictionStateAlwaysTrue; /* let's cheat a little */
|
||||
break;
|
||||
case 8: state = [self evaluateExistRestriction: &res->res.resExist
|
||||
intoQualifier: qualifier];
|
||||
break;
|
||||
@@ -727,7 +730,7 @@ static Class NSDataK, NSStringK;
|
||||
// case 10: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break;
|
||||
default:
|
||||
[NSException raise: @"MAPIStoreRestrictionException"
|
||||
format: @"unhandled restriction type"];
|
||||
format: @"unhandled restriction type: %.2x", res->rt];
|
||||
state = MAPIRestrictionStateAlwaysTrue;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,7 @@
|
||||
|
||||
#import "MAPIStoreGCSMessage.h"
|
||||
|
||||
@class iCalToDo;
|
||||
|
||||
@interface MAPIStoreTasksMessage : MAPIStoreGCSMessage
|
||||
{
|
||||
iCalToDo *task;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -49,24 +49,6 @@
|
||||
|
||||
@implementation MAPIStoreTasksMessage
|
||||
|
||||
- (id) initWithSOGoObject: (id) newSOGoObject
|
||||
inContainer: (MAPIStoreObject *) newContainer
|
||||
{
|
||||
if ((self = [super initWithSOGoObject: newSOGoObject
|
||||
inContainer: newContainer]))
|
||||
{
|
||||
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 */
|
||||
@@ -90,6 +72,9 @@
|
||||
|
||||
- (int) getPrSubject: (void **) data // SUMMARY
|
||||
{
|
||||
iCalToDo *task;
|
||||
|
||||
task = [sogoObject component: NO secure: NO];
|
||||
*data = [[task summary] asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
@@ -98,7 +83,9 @@
|
||||
- (int) getPrImportance: (void **) data
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
iCalToDo *task;
|
||||
|
||||
task = [sogoObject component: NO secure: NO];
|
||||
if ([[task priority] isEqualToString: @"9"])
|
||||
v = 0x0;
|
||||
else if ([[task priority] isEqualToString: @"1"])
|
||||
@@ -113,6 +100,9 @@
|
||||
|
||||
- (int) getPidLidTaskComplete: (void **) data
|
||||
{
|
||||
iCalToDo *task;
|
||||
|
||||
task = [sogoObject component: NO secure: NO];
|
||||
*data = MAPIBoolValue (memCtx,
|
||||
[[task status] isEqualToString: @"COMPLETED"]);
|
||||
|
||||
@@ -122,6 +112,9 @@
|
||||
- (int) getPidLidPercentComplete: (void **) data
|
||||
{
|
||||
double doubleValue;
|
||||
iCalToDo *task;
|
||||
|
||||
task = [sogoObject component: NO secure: NO];
|
||||
|
||||
doubleValue = ((double) [[task percentComplete] intValue] / 100);
|
||||
*data = MAPIDoubleValue (memCtx, doubleValue);
|
||||
@@ -131,8 +124,11 @@
|
||||
|
||||
- (int) getPidLidTaskDateCompleted: (void **) data
|
||||
{
|
||||
NSCalendarDate *dateValue;
|
||||
int rc = MAPISTORE_SUCCESS;
|
||||
NSCalendarDate *dateValue;
|
||||
iCalToDo *task;
|
||||
|
||||
task = [sogoObject component: NO secure: NO];
|
||||
|
||||
dateValue = [task completed];
|
||||
if (dateValue)
|
||||
@@ -182,52 +178,42 @@
|
||||
|
||||
- (int) getPidLidTaskDueDate: (void **) data
|
||||
{
|
||||
NSCalendarDate *dateValue;
|
||||
int rc = MAPISTORE_SUCCESS;
|
||||
NSCalendarDate *dateValue;
|
||||
iCalToDo *task;
|
||||
|
||||
task = [sogoObject component: NO secure: NO];
|
||||
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;
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPrMessageDeliveryTime: (void **) data
|
||||
{
|
||||
*data = [[task lastModified] asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
return [self getPrLastModificationTime: data];
|
||||
}
|
||||
|
||||
- (int) getClientSubmitTime: (void **) data
|
||||
{
|
||||
return [self getPrMessageDeliveryTime: data];
|
||||
return [self getPrLastModificationTime: data];
|
||||
}
|
||||
|
||||
- (int) getLocalCommitTime: (void **) data
|
||||
{
|
||||
return [self getPrMessageDeliveryTime: data];
|
||||
}
|
||||
|
||||
- (int) getLastModificationTime: (void **) data
|
||||
{
|
||||
return [self getPrMessageDeliveryTime: data];
|
||||
return [self getPrLastModificationTime: data];
|
||||
}
|
||||
|
||||
- (int) getPidLidTaskStatus: (void **) data // status
|
||||
{
|
||||
NSString *status;
|
||||
uint32_t longValue;
|
||||
iCalToDo *task;
|
||||
|
||||
task = [sogoObject component: NO secure: NO];
|
||||
status = [task status];
|
||||
if (![status length]
|
||||
|| [status isEqualToString: @"NEEDS-ACTION"])
|
||||
|
||||
Reference in New Issue
Block a user