Monotone-Parent: 23072776516ad7ec761501356d062052d748d8c7
Monotone-Revision: 0803c3f82523e76024a78031ba0e71fce02404eb Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2011-02-24T20:40:07 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
c96ae87f5b
commit
1feee33aa2
|
@ -1,5 +1,11 @@
|
|||
2011-02-24 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreTable.m: refactored class to be used as an
|
||||
accessor on MAPIStoreFolder or other MAPIStoreObject derivatives
|
||||
based on a defined set of methods. Now strictly handle the sorting
|
||||
and filtering of folder entries, the getting of properties having
|
||||
been moved to the MAPIStoreMessage classes.
|
||||
|
||||
* OpenChange/SOGoMAPIFSMessage.m (-appendProperties:): new name
|
||||
for "setMAPIProperties:"
|
||||
(-save): new name for "MAPISave", since those were methods
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFAIMessageTable.h - this file is part of SOGo
|
||||
/* MAPIStoreAttachmentTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -20,13 +20,12 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef MAPISTOREFAIMESSAGETABLE_H
|
||||
#define MAPISTOREFAIMESSAGETABLE_H
|
||||
#ifndef MAPISTOREATTACHMENTTABLE_H
|
||||
#define MAPISTOREATTACHMENTTABLE_H
|
||||
|
||||
#import "MAPIStoreFSMessageTable.h"
|
||||
|
||||
@interface MAPIStoreFAIMessageTable : MAPIStoreFSMessageTable
|
||||
#import "MAPIStoreTable.h"
|
||||
|
||||
@interface MAPIStoreAttachmentTable : MAPIStoreTable
|
||||
@end
|
||||
|
||||
#endif /* MAPISTOREFAIMESSAGETABLE_H */
|
||||
#endif /* MAPISTOREATTACHMENTTABLE_H */
|
|
@ -1,12 +1,12 @@
|
|||
/* MAPIStoreFAIMessageTable.m - this file is part of SOGo
|
||||
/* MAPIStoreAttachmentTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
|
@ -20,8 +20,8 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import "MAPIStoreFAIMessageTable.h"
|
||||
#import "MAPIStoreAttachmentTable.h"
|
||||
|
||||
@implementation MAPIStoreFAIMessageTable
|
||||
@implementation MAPIStoreAttachmentTable
|
||||
|
||||
@end
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
#import <EOControl/EOQualifier.h>
|
||||
|
||||
#import <Appointments/SOGoAppointmentObject.h>
|
||||
|
||||
#import <NGCards/iCalEvent.h>
|
||||
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
@ -39,125 +37,6 @@
|
|||
|
||||
@implementation MAPIStoreCalendarMessageTable
|
||||
|
||||
- (EOQualifier *) componentQualifier
|
||||
{
|
||||
static EOQualifier *componentQualifier = nil;
|
||||
|
||||
if (!componentQualifier)
|
||||
componentQualifier
|
||||
= [[EOKeyValueQualifier alloc] initWithKey: @"c_component"
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: @"vevent"];
|
||||
|
||||
return componentQualifier;
|
||||
}
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
NSTimeInterval timeValue;
|
||||
id event;
|
||||
int rc;
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
switch (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
|
||||
*data = MAPILongValue (memCtx, 0x00000400);
|
||||
break;
|
||||
case PR_MESSAGE_CLASS_UNICODE:
|
||||
*data = talloc_strdup(memCtx, "IPM.Appointment");
|
||||
break;
|
||||
case PidLidAppointmentStartWhole: // DTSTART
|
||||
event = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
*data = [[event startDate] asFileTimeInMemCtx: memCtx];
|
||||
break;
|
||||
case PidLidAppointmentEndWhole: // DTEND
|
||||
event = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
*data = [[event endDate] asFileTimeInMemCtx: memCtx];
|
||||
break;
|
||||
case PidLidAppointmentDuration:
|
||||
event = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
timeValue = [[event endDate] timeIntervalSinceDate: [event startDate]];
|
||||
*data = MAPILongValue (memCtx, (uint32_t) (timeValue / 60));
|
||||
break;
|
||||
case PidLidAppointmentSubType:
|
||||
event = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
*data = MAPIBoolValue (memCtx, [event isAllDay]);
|
||||
break;
|
||||
case PidLidBusyStatus: // TODO
|
||||
*data = MAPILongValue (memCtx, 0x02);
|
||||
break;
|
||||
case PidLidRecurring: // TODO
|
||||
*data = MAPIBoolValue (memCtx, NO);
|
||||
break;
|
||||
|
||||
// case 0x82410003: // TODO
|
||||
// *data = MAPILongValue (memCtx, 0);
|
||||
// break;
|
||||
case PR_SUBJECT_UNICODE: // SUMMARY
|
||||
event = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
*data = [[event summary] asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PidLidLocation: // LOCATION
|
||||
event = [[self lookupChild: childKey] 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 = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
*data = [[event created] asFileTimeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PR_IMPORTANCE:
|
||||
{
|
||||
unsigned int v;
|
||||
|
||||
event = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
|
||||
if ([[event priority] isEqualToString: @"9"])
|
||||
v = 0x0;
|
||||
else if ([[event priority] isEqualToString: @"1"])
|
||||
v = 0x2;
|
||||
else
|
||||
v = 0x1;
|
||||
|
||||
*data = MAPILongValue (memCtx, v);
|
||||
}
|
||||
break;
|
||||
|
||||
// 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 getChildProperty: data
|
||||
forKey: childKey
|
||||
withTag: propTag];
|
||||
}
|
||||
|
||||
// #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 */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
|
|
|
@ -42,515 +42,6 @@
|
|||
|
||||
@implementation MAPIStoreContactsMessageTable
|
||||
|
||||
- (EOQualifier *) componentQualifier
|
||||
{
|
||||
static EOQualifier *componentQualifier = nil;
|
||||
|
||||
/* TODO: we need to support vlist as well */
|
||||
if (!componentQualifier)
|
||||
componentQualifier
|
||||
= [[EOKeyValueQualifier alloc] initWithKey: @"c_component"
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: @"vcard"];
|
||||
|
||||
return componentQualifier;
|
||||
}
|
||||
|
||||
- (CardElement *) _element: (NSString *) elementTag
|
||||
ofType: (NSString *) aType
|
||||
excluding: (NSString *) aTypeToExclude
|
||||
inCard: (NGVCard *) card
|
||||
{
|
||||
NSArray *elements;
|
||||
CardElement *ce, *found;
|
||||
NSUInteger count, max;
|
||||
|
||||
found = nil;
|
||||
|
||||
elements = [[card childrenWithTag: elementTag]
|
||||
cardElementsWithAttribute: @"type"
|
||||
havingValue: aType];
|
||||
max = [elements count];
|
||||
for (count = 0; !found && count < max; count++)
|
||||
{
|
||||
ce = [elements objectAtIndex: count];
|
||||
if (!aTypeToExclude
|
||||
|| ![ce hasAttribute: @"type" havingValue: aTypeToExclude])
|
||||
found = ce;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) proptag
|
||||
{
|
||||
NSString *stringValue, *stringValue2;
|
||||
SOGoContactGCSEntry *child;
|
||||
CardElement *element;
|
||||
uint32_t longValue;
|
||||
NGVCard *vCard;
|
||||
enum MAPISTATUS rc;
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
switch (proptag)
|
||||
{
|
||||
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:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [[child vCard] title];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PR_COMPANY_NAME_UNICODE:
|
||||
case PR_DEPARTMENT_NAME_UNICODE:
|
||||
{
|
||||
NSArray *values;
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
values = [[child 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 getChildProperty: data
|
||||
forKey: childKey
|
||||
withTag: PR_DISPLAY_NAME_UNICODE];
|
||||
break;
|
||||
case PidLidFileUnderId:
|
||||
*data = MAPILongValue (memCtx, 0xffffffff);
|
||||
break;
|
||||
|
||||
case PidLidEmail1OriginalDisplayName:
|
||||
case PidLidEmail1DisplayName:
|
||||
child = [self lookupChild: childKey];
|
||||
vCard = [child vCard];
|
||||
stringValue = [vCard fn];
|
||||
stringValue2 = [vCard preferredEMail];
|
||||
*data = [[NSString stringWithFormat: @"%@ <%@>",
|
||||
stringValue, stringValue2]
|
||||
asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PidLidEmail1EmailAddress:
|
||||
case PR_ACCOUNT_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [[child vCard] preferredEMail];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PR_CONTACT_EMAIL_ADDRESSES_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [[child vCard] preferredEMail];
|
||||
*data = [[NSArray arrayWithObject: stringValue]
|
||||
asArrayOfUnicodeStringsInCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PR_EMS_AB_TARGET_ADDRESS_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [[child vCard] preferredEMail];
|
||||
*data = [[NSString stringWithFormat: @"SMTP:%@", stringValue]
|
||||
asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PR_SEARCH_KEY: // TODO
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [[child 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 = [[self lookupChild: childKey] 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:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [[child vCard] note];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PR_OFFICE_TELEPHONE_NUMBER_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"tel" ofType: @"work"
|
||||
excluding: @"fax"
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 0];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_HOME_TELEPHONE_NUMBER_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"tel" ofType: @"home"
|
||||
excluding: @"fax"
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 0];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_MOBILE_TELEPHONE_NUMBER_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"tel" ofType: @"cell"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 0];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_PRIMARY_TELEPHONE_NUMBER_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"tel" ofType: @"pref"
|
||||
excluding: nil
|
||||
inCard: [child 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");
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
|
||||
element = [self _element: @"url" ofType: type
|
||||
excluding: nil
|
||||
inCard: [child 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:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [[[child 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:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"pref"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if ([element hasAttribute: @"type"
|
||||
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:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"label" ofType: @"pref"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 0];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_POST_OFFICE_BOX_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"pref"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 0];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_STREET_ADDRESS_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"pref"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 2];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_LOCALITY_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"pref"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 3];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_STATE_OR_PROVINCE_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"pref"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 4];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_POSTAL_CODE_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"pref"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 5];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_COUNTRY_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"pref"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 6];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
// case PidLidAddressCountryCode:
|
||||
|
||||
case PidLidWorkAddress:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"label" ofType: @"work"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 0];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PidLidWorkAddressPostOfficeBox:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"work"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 0];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PidLidWorkAddressStreet:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"work"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 2];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PidLidWorkAddressCity:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"work"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 3];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PidLidWorkAddressState:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"work"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 4];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PidLidWorkAddressPostalCode:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"work"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 5];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PidLidWorkAddressCountry:
|
||||
child = [self lookupChild: childKey];
|
||||
element = [self _element: @"adr" ofType: @"work"
|
||||
excluding: nil
|
||||
inCard: [child vCard]];
|
||||
if (element)
|
||||
stringValue = [element value: 6];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
// PidTagNickname
|
||||
case PR_NICKNAME_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [[child vCard] nickname];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PR_BIRTHDAY:
|
||||
{
|
||||
NSCalendarDate *dateValue;
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
|
||||
stringValue = [[child 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 = MAPI_E_NOT_FOUND;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
rc = [super getChildProperty: data
|
||||
forKey: childKey
|
||||
withTag: proptag];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
static NSMutableDictionary *knownProperties = nil;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#import "EOQualifier+MAPIFS.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "MAPIStoreFSMessage.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
#import "SOGoMAPIFSFolder.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
|
@ -38,69 +39,9 @@
|
|||
|
||||
@implementation MAPIStoreFSMessageTable
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
NSDictionary *properties;
|
||||
SOGoMAPIFSMessage *child;
|
||||
id value;
|
||||
enum MAPISTATUS rc;
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
properties = [child properties];
|
||||
value = [properties objectForKey: MAPIPropertyKey (propTag)];
|
||||
if (value)
|
||||
rc = [value getMAPIValue: data forTag: propTag inMemCtx: memCtx];
|
||||
else
|
||||
rc = [super getChildProperty: data forKey: childKey withTag: propTag];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
return [NSString stringWithFormat: @"%@", MAPIPropertyKey (property)];
|
||||
}
|
||||
|
||||
- (NSArray *) childKeys
|
||||
{
|
||||
return [folder toOneRelationshipKeys];
|
||||
}
|
||||
|
||||
- (NSArray *) restrictedChildKeys
|
||||
{
|
||||
NSMutableArray *keys;
|
||||
NSArray *allKeys;
|
||||
NSUInteger count, max;
|
||||
NSString *messageKey;
|
||||
|
||||
allKeys = [self cachedChildKeys];
|
||||
if (restrictionState == MAPIRestrictionStateAlwaysTrue)
|
||||
keys = (NSMutableArray *) allKeys;
|
||||
else if (restrictionState == MAPIRestrictionStateAlwaysFalse)
|
||||
keys = (NSMutableArray *) [NSArray array];
|
||||
else
|
||||
{
|
||||
[self logWithFormat: @"%s: getting restricted keys", __PRETTY_FUNCTION__];
|
||||
max = [allKeys count];
|
||||
keys = [NSMutableArray arrayWithCapacity: max];
|
||||
if (restrictionState == MAPIRestrictionStateNeedsEval)
|
||||
{
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
messageKey = [allKeys objectAtIndex: count];
|
||||
if ([restriction evaluateMAPIFSMessage:
|
||||
[folder lookupName: messageKey
|
||||
inContext: nil
|
||||
acquire: NO]])
|
||||
[keys addObject: messageKey];
|
||||
}
|
||||
}
|
||||
[self logWithFormat: @" resulting keys: $$$%@$$$", keys];
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -20,12 +20,9 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import <SOGo/SOGoFolder.h>
|
||||
|
||||
#import "MAPIStoreFolder.h"
|
||||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
||||
|
@ -47,83 +44,13 @@ static MAPIStoreMapping *mapping;
|
|||
|
||||
- (NSArray *) childKeys
|
||||
{
|
||||
return [NSArray array];
|
||||
// return [folder toManyRelationshipKeys];
|
||||
return [(MAPIStoreFolder *) container folderKeys];
|
||||
}
|
||||
|
||||
- (NSArray *) restrictedChildKeys
|
||||
{
|
||||
[self errorWithFormat: @"restrictions are ignored on mail folder tables"];
|
||||
return [folder toManyRelationshipKeys];
|
||||
}
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
SOGoFolder *child;
|
||||
// id child;
|
||||
// struct Binary_r *binaryValue;
|
||||
NSString *childURL;
|
||||
uint32_t contextId;
|
||||
uint64_t mappingId;
|
||||
int rc;
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
switch (propTag)
|
||||
{
|
||||
case PR_FID:
|
||||
childURL = [NSString stringWithFormat: @"%@%@", folderURL, childKey];
|
||||
mappingId = [mapping idFromURL: childURL];
|
||||
if (mappingId == NSNotFound)
|
||||
{
|
||||
openchangedb_get_new_folderID (ldbCtx, &mappingId);
|
||||
[mapping registerURL: childURL withID: mappingId];
|
||||
contextId = 0;
|
||||
mapistore_search_context_by_uri (memCtx, [folderURL UTF8String] + 7,
|
||||
&contextId);
|
||||
mapistore_indexing_record_add_mid (memCtx, contextId, mappingId);
|
||||
}
|
||||
*data = MAPILongLongValue (memCtx, mappingId);
|
||||
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, fid);
|
||||
break;
|
||||
case PR_ATTR_HIDDEN:
|
||||
case PR_ATTR_SYSTEM:
|
||||
case PR_ATTR_READONLY:
|
||||
*data = MAPIBoolValue (memCtx, NO);
|
||||
break;
|
||||
case PR_SUBFOLDERS:
|
||||
child = [self lookupChild: childKey];
|
||||
*data = MAPIBoolValue (memCtx, 0);
|
||||
// [[child toManyRelationshipKeys] count] > 0);
|
||||
// *data = MAPIBoolValue (memCtx,
|
||||
// [[child toManyRelationshipKeys] count] > 0);
|
||||
break;
|
||||
case PR_CONTENT_COUNT:
|
||||
child = [self lookupChild: childKey];
|
||||
*data = MAPILongValue (memCtx,
|
||||
[[child toOneRelationshipKeys] 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 getChildProperty: data
|
||||
forKey: childKey
|
||||
withTag: propTag];
|
||||
}
|
||||
|
||||
return rc;
|
||||
[self errorWithFormat: @"restrictions are ignored on folder tables"];
|
||||
return [self childKeys];
|
||||
}
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
@class EOQualifier;
|
||||
|
||||
@interface MAPIStoreGCSMessageTable : MAPIStoreMessageTable
|
||||
{
|
||||
NSMutableArray *sortOrderings;
|
||||
}
|
||||
|
||||
- (EOQualifier *) componentQualifier;
|
||||
- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSAutoreleasePool+MAPIStore.h"
|
||||
#import "MAPIStoreFolder.h"
|
||||
|
||||
#import "MAPIStoreGCSMessageTable.h"
|
||||
|
||||
|
@ -61,66 +62,6 @@
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSArray *) _childKeysUsingRestrictions: (BOOL) useRestrictions
|
||||
{
|
||||
static NSArray *fields = nil;
|
||||
NSArray *records;
|
||||
EOQualifier *componentQualifier, *fetchQualifier;
|
||||
GCSFolder *ocsFolder;
|
||||
EOFetchSpecification *fs;
|
||||
NSArray *keys;
|
||||
|
||||
if (!fields)
|
||||
fields = [[NSArray alloc]
|
||||
initWithObjects: @"c_name", @"c_version", nil];
|
||||
|
||||
componentQualifier = [self componentQualifier];
|
||||
|
||||
if (useRestrictions
|
||||
&& restrictionState != MAPIRestrictionStateAlwaysTrue)
|
||||
{
|
||||
if (restrictionState == MAPIRestrictionStateNeedsEval)
|
||||
{
|
||||
fetchQualifier = [[EOAndQualifier alloc]
|
||||
initWithQualifiers:
|
||||
componentQualifier,
|
||||
restriction,
|
||||
nil];
|
||||
[fetchQualifier autorelease];
|
||||
}
|
||||
else
|
||||
fetchQualifier = nil;
|
||||
}
|
||||
else
|
||||
fetchQualifier = componentQualifier;
|
||||
|
||||
if (fetchQualifier)
|
||||
{
|
||||
ocsFolder = [folder ocsFolder];
|
||||
fs = [EOFetchSpecification
|
||||
fetchSpecificationWithEntityName: [ocsFolder folderName]
|
||||
qualifier: fetchQualifier
|
||||
sortOrderings: sortOrderings];
|
||||
records = [ocsFolder fetchFields: fields fetchSpecification: fs];
|
||||
keys = [records objectsForKey: @"c_name"
|
||||
notFoundMarker: nil];
|
||||
}
|
||||
else
|
||||
keys = [NSArray array];
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
- (NSArray *) childKeys
|
||||
{
|
||||
return [self _childKeysUsingRestrictions: NO];
|
||||
}
|
||||
|
||||
- (NSArray *) restrictedChildKeys
|
||||
{
|
||||
return [self _childKeysUsingRestrictions: YES];
|
||||
}
|
||||
|
||||
- (struct mapi_SPropertyRestriction *) _fixedDatePropertyRestriction: (struct mapi_SPropertyRestriction *) res
|
||||
{
|
||||
struct mapi_SPropertyRestriction *translatedRes;
|
||||
|
@ -204,13 +145,6 @@
|
|||
|
||||
/* sorting */
|
||||
|
||||
- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (EOSortOrdering *) _sortOrderingFromSortOrder: (struct SSortOrder *) sortOrder
|
||||
{
|
||||
EOSortOrdering *newSortOrdering;
|
||||
|
@ -295,4 +229,12 @@
|
|||
[self logWithFormat: @"new sort orderings: %@", sortOrderings];
|
||||
}
|
||||
|
||||
/* subclasses */
|
||||
- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -36,38 +36,4 @@
|
|||
|
||||
@implementation MAPIStoreMailFolderTable
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
enum MAPISTATUS rc;
|
||||
SOGoMailFolder *child;
|
||||
EOQualifier *searchQualifier;
|
||||
uint32_t intValue;
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
switch (propTag)
|
||||
{
|
||||
case PR_CONTENT_UNREAD:
|
||||
child = [self lookupChild: childKey];
|
||||
searchQualifier
|
||||
= [EOQualifier qualifierWithQualifierFormat: @"flags = %@ AND not flags = %@",
|
||||
@"unseen", @"deleted"];
|
||||
intValue = [[child fetchUIDsMatchingQualifier: searchQualifier
|
||||
sortOrdering: nil] count];
|
||||
[self logWithFormat: @"unread count for %@: %u\n", childKey, intValue];
|
||||
*data = MAPILongValue (memCtx, intValue);
|
||||
break;
|
||||
case PR_CONTAINER_CLASS_UNICODE:
|
||||
*data = [@"IPF.Note" asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
default:
|
||||
rc = [super getChildProperty: data
|
||||
forKey: childKey
|
||||
withTag: propTag];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
#import "MAPIStoreMessageTable.h"
|
||||
|
||||
@interface MAPIStoreMailMessageTable : MAPIStoreMessageTable
|
||||
{
|
||||
NSString *sortOrdering;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -25,11 +25,8 @@
|
|||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSRange.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import <EOControl/EOQualifier.h>
|
||||
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
|
||||
#import <Mailer/NSData+Mail.h>
|
||||
|
@ -37,6 +34,7 @@
|
|||
#import <Mailer/SOGoMailObject.h>
|
||||
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreMailFolder.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSCalendarDate+MAPIStore.h"
|
||||
|
@ -48,33 +46,6 @@
|
|||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_nameid.h>
|
||||
|
||||
@interface NSString (MAPIStoreMIME)
|
||||
|
||||
- (NSString *) _strippedBodyKey;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSString (MAPIStoreMIME)
|
||||
|
||||
- (NSString *) _strippedBodyKey
|
||||
{
|
||||
NSRange bodyRange;
|
||||
NSString *strippedKey;
|
||||
|
||||
bodyRange = [self rangeOfString: @"body["];
|
||||
if (bodyRange.length > 0)
|
||||
{
|
||||
strippedKey = [self substringFromIndex: NSMaxRange (bodyRange)];
|
||||
strippedKey = [strippedKey substringToIndex: [strippedKey length] - 1];
|
||||
}
|
||||
else
|
||||
strippedKey = nil;
|
||||
|
||||
return strippedKey;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MAPIStoreMailMessageTable
|
||||
|
||||
static Class NSDataK, NSStringK;
|
||||
|
@ -89,503 +60,12 @@ static Class NSDataK, NSStringK;
|
|||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
sortOrdering = @"ARRIVAL";
|
||||
ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[sortOrdering release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSArray *) childKeys
|
||||
{
|
||||
return [[folder fetchUIDsMatchingQualifier: nil
|
||||
sortOrdering: sortOrdering]
|
||||
stringsWithFormat: @"%@.eml"];
|
||||
}
|
||||
|
||||
- (NSArray *) restrictedChildKeys
|
||||
{
|
||||
NSArray *keys;
|
||||
|
||||
if (restrictionState == MAPIRestrictionStateAlwaysTrue)
|
||||
keys = [self cachedChildKeys];
|
||||
else if (restrictionState == MAPIRestrictionStateAlwaysFalse)
|
||||
keys = [NSArray array];
|
||||
else
|
||||
{
|
||||
keys = [[folder fetchUIDsMatchingQualifier: restriction
|
||||
sortOrdering: sortOrdering]
|
||||
stringsWithFormat: @"%@.eml"];
|
||||
[self logWithFormat: @" restricted keys: %@", keys];
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
SOGoMailObject *child;
|
||||
NSString *subject, *stringValue;
|
||||
NSInteger colIdx;
|
||||
uint32_t intValue;
|
||||
enum MAPISTATUS rc;
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
switch (propTag)
|
||||
{
|
||||
case PR_ICON_INDEX:
|
||||
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
|
||||
child = [self lookupChild: childKey];
|
||||
if ([child isNewMail])
|
||||
intValue = 0xffffffff;
|
||||
else if ([child replied])
|
||||
intValue = 0x105;
|
||||
else if ([child forwarded])
|
||||
intValue = 0x106;
|
||||
else if ([child read])
|
||||
intValue = 0x100;
|
||||
else
|
||||
intValue = 0x101;
|
||||
*data = MAPILongValue (memCtx, intValue);
|
||||
break;
|
||||
case PidLidImapDeleted:
|
||||
child = [self lookupChild: childKey];
|
||||
if ([child deleted])
|
||||
intValue = 1;
|
||||
else
|
||||
intValue = 0;
|
||||
*data = MAPILongValue (memCtx, intValue);
|
||||
break;
|
||||
case PR_SUBJECT_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [child decodedSubject];
|
||||
if (!stringValue)
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_SUBJECT_PREFIX_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
subject = [child decodedSubject];
|
||||
colIdx = [subject rangeOfString: @":"].location;
|
||||
if (colIdx != NSNotFound && colIdx < 4)
|
||||
stringValue = [NSString stringWithFormat: @"%@: ",
|
||||
[subject substringToIndex: colIdx]];
|
||||
else
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_NORMALIZED_SUBJECT_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
subject = [child decodedSubject];
|
||||
colIdx = [subject rangeOfString: @":"].location;
|
||||
if (colIdx != NSNotFound && colIdx < 4)
|
||||
stringValue = [[subject substringFromIndex: colIdx + 1]
|
||||
stringByTrimmingLeadSpaces];
|
||||
else
|
||||
stringValue = subject;
|
||||
if (!stringValue)
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PR_MESSAGE_CLASS_UNICODE:
|
||||
case PR_ORIG_MESSAGE_CLASS_UNICODE:
|
||||
*data = talloc_strdup (memCtx, "IPM.Note");
|
||||
break;
|
||||
case PidLidRemoteAttachment: // TODO
|
||||
case PR_HASATTACH: // TODO
|
||||
case PR_REPLY_REQUESTED: // TODO
|
||||
case PR_RESPONSE_REQUESTED: // TODO
|
||||
*data = MAPIBoolValue (memCtx, NO);
|
||||
break;
|
||||
// case PidLidHeaderItem:
|
||||
// *data = MAPILongValue (memCtx, 0x00000001);
|
||||
// break;
|
||||
// case PidLidRemoteTransferSize:
|
||||
// rc = [self getChildProperty: data
|
||||
// forKey: childKey
|
||||
// withTag: PR_MESSAGE_SIZE];
|
||||
// break;
|
||||
case PR_CREATION_TIME: // DOUBT
|
||||
case PR_LAST_MODIFICATION_TIME: // DOUBT
|
||||
case PR_LATEST_DELIVERY_TIME: // DOUBT
|
||||
case PR_ORIGINAL_SUBMIT_TIME:
|
||||
case PR_CLIENT_SUBMIT_TIME:
|
||||
case PR_MESSAGE_DELIVERY_TIME:
|
||||
child = [self lookupChild: childKey];
|
||||
// offsetDate = [[child date] addYear: -1 month: 0 day: 0
|
||||
// hour: 0 minute: 0 second: 0];
|
||||
// *data = [offsetDate asFileTimeInMemCtx: memCtx];
|
||||
*data = [[child date] asFileTimeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_MESSAGE_FLAGS: // TODO
|
||||
{
|
||||
NSDictionary *coreInfos;
|
||||
NSArray *flags;
|
||||
unsigned int v;
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
coreInfos = [child fetchCoreInfos];
|
||||
|
||||
flags = [coreInfos objectForKey: @"flags"];
|
||||
v = MSGFLAG_FROMME;
|
||||
|
||||
if ([flags containsObject: @"seen"])
|
||||
v |= MSGFLAG_READ;
|
||||
|
||||
*data = MAPILongValue (memCtx, v);
|
||||
}
|
||||
break;
|
||||
|
||||
case PR_FLAG_STATUS:
|
||||
{
|
||||
NSDictionary *coreInfos;
|
||||
NSArray *flags;
|
||||
unsigned int v;
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
coreInfos = [child fetchCoreInfos];
|
||||
|
||||
flags = [coreInfos objectForKey: @"flags"];
|
||||
if ([flags containsObject: @"flagged"])
|
||||
v = 2;
|
||||
else
|
||||
v = 0;
|
||||
|
||||
*data = MAPILongValue (memCtx, v);
|
||||
}
|
||||
break;
|
||||
|
||||
case PR_FOLLOWUP_ICON:
|
||||
{
|
||||
NSDictionary *coreInfos;
|
||||
NSArray *flags;
|
||||
unsigned int v;
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
coreInfos = [child fetchCoreInfos];
|
||||
|
||||
flags = [coreInfos objectForKey: @"flags"];
|
||||
if ([flags containsObject: @"flagged"])
|
||||
v = 6;
|
||||
else
|
||||
v = 0;
|
||||
|
||||
*data = MAPILongValue (memCtx, v);
|
||||
}
|
||||
break;
|
||||
|
||||
case PR_SENSITIVITY: // TODO
|
||||
case PR_ORIGINAL_SENSITIVITY: // TODO
|
||||
*data = MAPILongValue (memCtx, 0);
|
||||
break;
|
||||
|
||||
case PR_EXPIRY_TIME: // TODO
|
||||
case PR_REPLY_TIME:
|
||||
*data = [[NSCalendarDate date] asFileTimeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PR_SENT_REPRESENTING_ADDRTYPE_UNICODE:
|
||||
case PR_RCVD_REPRESENTING_ADDRTYPE_UNICODE:
|
||||
case PR_RECEIVED_BY_ADDRTYPE_UNICODE:
|
||||
case PR_SENDER_ADDRTYPE_UNICODE:
|
||||
*data = [@"SMTP" asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_ORIGINAL_AUTHOR_NAME_UNICODE:
|
||||
case PR_SENDER_NAME_UNICODE:
|
||||
case PR_SENDER_EMAIL_ADDRESS_UNICODE:
|
||||
case PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE:
|
||||
case PR_SENT_REPRESENTING_NAME_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
*data = [[child from] asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
/* TODO: some of the following are supposed to be display names, separated by a semicolumn */
|
||||
case PR_RECEIVED_BY_NAME_UNICODE:
|
||||
case PR_RECEIVED_BY_EMAIL_ADDRESS_UNICODE:
|
||||
case PR_RCVD_REPRESENTING_NAME_UNICODE:
|
||||
case PR_RCVD_REPRESENTING_EMAIL_ADDRESS_UNICODE:
|
||||
case PR_DISPLAY_TO_UNICODE:
|
||||
case PR_ORIGINAL_DISPLAY_TO_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [child to];
|
||||
if (!stringValue)
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_DISPLAY_CC_UNICODE:
|
||||
case PR_ORIGINAL_DISPLAY_CC_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [child cc];
|
||||
if (!stringValue)
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_DISPLAY_BCC_UNICODE:
|
||||
case PR_ORIGINAL_DISPLAY_BCC_UNICODE:
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PidNameContentType:
|
||||
*data = [@"message/rfc822" asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
|
||||
//
|
||||
// TODO: Merge with the code in UI/MailerUI/UIxMailListActions.m: -messagePriority
|
||||
// to avoid the duplication of the logic
|
||||
//
|
||||
case PR_IMPORTANCE:
|
||||
{
|
||||
unsigned int v;
|
||||
NSString *s;
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
s = [[child mailHeaders] objectForKey: @"x-priority"];
|
||||
v = 0x1;
|
||||
|
||||
|
||||
if ([s hasPrefix: @"1"]) v = 0x2;
|
||||
else if ([s hasPrefix: @"2"]) v = 0x2;
|
||||
else if ([s hasPrefix: @"4"]) v = 0x0;
|
||||
else if ([s hasPrefix: @"5"]) v = 0x0;
|
||||
|
||||
*data = MAPILongValue (memCtx, v);
|
||||
}
|
||||
break;
|
||||
|
||||
case PR_BODY_UNICODE:
|
||||
{
|
||||
NSMutableArray *keys;
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
|
||||
keys = [NSMutableArray array];
|
||||
[child addRequiredKeysOfStructure: [child bodyStructure]
|
||||
path: @"" toArray: keys
|
||||
acceptedTypes: [NSArray arrayWithObject:
|
||||
@"text/html"]];
|
||||
if ([keys count] > 0)
|
||||
{
|
||||
*data = NULL;
|
||||
rc = MAPI_E_NOT_FOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
[keys removeAllObjects];
|
||||
[child addRequiredKeysOfStructure: [child bodyStructure]
|
||||
path: @"" toArray: keys
|
||||
acceptedTypes: [NSArray arrayWithObject:
|
||||
@"text/plain"]];
|
||||
if ([keys count] > 0)
|
||||
{
|
||||
id result;
|
||||
NSData *content;
|
||||
NSDictionary *partHeaderData;
|
||||
NSString *key, *encoding, *charset;
|
||||
|
||||
result = [child fetchParts: [keys objectsForKey: @"key"
|
||||
notFoundMarker: nil]];
|
||||
result = [[result valueForKey: @"RawResponse"] objectForKey: @"fetch"];
|
||||
key = [[keys objectAtIndex: 0] objectForKey: @"key"];
|
||||
content = [[result objectForKey: key] objectForKey: @"data"];
|
||||
|
||||
partHeaderData
|
||||
= [child lookupInfoForBodyPart: [key _strippedBodyKey]];
|
||||
encoding = [partHeaderData objectForKey: @"encoding"];
|
||||
charset = [[partHeaderData objectForKey: @"parameterList"]
|
||||
objectForKey: @"charset"];
|
||||
stringValue = [[content bodyDataFromEncoding: encoding]
|
||||
bodyStringFromCharset: charset];
|
||||
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
if (strlen (*data) > 16384)
|
||||
{
|
||||
[context registerValue: stringValue
|
||||
asProperty: propTag
|
||||
forURL: [NSString stringWithFormat: @"%@%@", folderURL, childKey]];
|
||||
*data = NULL;
|
||||
rc = MAPI_E_NOT_ENOUGH_MEMORY;
|
||||
[self logWithFormat: @"PR_BODY data too wide"];
|
||||
}
|
||||
}
|
||||
else
|
||||
rc = MAPI_E_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PR_INTERNET_CPID:
|
||||
/* ref:
|
||||
http://msdn.microsoft.com/en-us/library/dd317756%28v=vs.85%29.aspx
|
||||
|
||||
minimal list that should be handled:
|
||||
us-ascii: 20127
|
||||
iso-8859-1: 28591
|
||||
iso-8859-15: 28605
|
||||
utf-8: 65001 */
|
||||
*data = MAPILongValue(memCtx, 65001);
|
||||
break;
|
||||
|
||||
case PR_HTML:
|
||||
{
|
||||
NSMutableArray *keys;
|
||||
NSArray *acceptedTypes;
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
|
||||
acceptedTypes = [NSArray arrayWithObject: @"text/html"];
|
||||
keys = [NSMutableArray array];
|
||||
[child addRequiredKeysOfStructure: [child bodyStructure]
|
||||
path: @"" toArray: keys acceptedTypes: acceptedTypes];
|
||||
if ([keys count] > 0)
|
||||
{
|
||||
id result;
|
||||
NSData *content;
|
||||
NSDictionary *partHeaderData;
|
||||
NSString *key, *encoding;
|
||||
|
||||
result = [child fetchParts: [keys objectsForKey: @"key"
|
||||
notFoundMarker: nil]];
|
||||
result = [[result valueForKey: @"RawResponse"] objectForKey:
|
||||
@"fetch"];
|
||||
key = [[keys objectAtIndex: 0] objectForKey: @"key"];
|
||||
content = [[result objectForKey: key] objectForKey: @"data"];
|
||||
|
||||
partHeaderData
|
||||
= [child lookupInfoForBodyPart: [key _strippedBodyKey]];
|
||||
encoding = [partHeaderData objectForKey: @"encoding"];
|
||||
content = [content bodyDataFromEncoding: encoding];
|
||||
|
||||
if ([content length] > 16384)
|
||||
{
|
||||
[context registerValue: content
|
||||
asProperty: propTag
|
||||
forURL: [NSString stringWithFormat: @"%@%@", folderURL, childKey]];
|
||||
*data = NULL;
|
||||
rc = MAPI_E_NOT_ENOUGH_MEMORY;
|
||||
[self logWithFormat: @"PR_HTML data too wide"];
|
||||
}
|
||||
else
|
||||
*data = [content asBinaryInMemCtx: memCtx];
|
||||
}
|
||||
else
|
||||
{
|
||||
*data = NULL;
|
||||
rc = MAPI_E_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* We don't handle any RTF content. */
|
||||
case PR_RTF_COMPRESSED:
|
||||
*data = NULL;
|
||||
rc = MAPI_E_NOT_FOUND;
|
||||
break;
|
||||
case PR_RTF_IN_SYNC:
|
||||
*data = MAPIBoolValue (memCtx, NO);
|
||||
break;
|
||||
case PR_INTERNET_MESSAGE_ID_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
*data = [[child messageId] asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_READ_RECEIPT_REQUESTED: // TODO
|
||||
case PR_DELETE_AFTER_SUBMIT: // TODO
|
||||
*data = MAPIBoolValue (memCtx, NO);
|
||||
break;
|
||||
case PidLidPrivate:
|
||||
*data = MAPIBoolValue (memCtx, NO);
|
||||
break;
|
||||
|
||||
case PR_MSG_EDITOR_FORMAT:
|
||||
{
|
||||
NSMutableArray *keys;
|
||||
NSArray *acceptedTypes;
|
||||
uint32_t format;
|
||||
|
||||
child = [self lookupChild: childKey];
|
||||
|
||||
format = 0; /* EDITOR_FORMAT_DONTKNOW */
|
||||
|
||||
acceptedTypes = [NSArray arrayWithObject: @"text/plain"];
|
||||
keys = [NSMutableArray array];
|
||||
[child addRequiredKeysOfStructure: [child bodyStructure]
|
||||
path: @"" toArray: keys
|
||||
acceptedTypes: acceptedTypes];
|
||||
if ([keys count] == 1)
|
||||
format = EDITOR_FORMAT_PLAINTEXT;
|
||||
|
||||
acceptedTypes = [NSArray arrayWithObject: @"text/html"];
|
||||
[keys removeAllObjects];
|
||||
[child addRequiredKeysOfStructure: [child bodyStructure]
|
||||
path: @"" toArray: keys
|
||||
acceptedTypes: acceptedTypes];
|
||||
if ([keys count] == 1)
|
||||
format = EDITOR_FORMAT_HTML;
|
||||
|
||||
*data = MAPILongValue (memCtx, format);
|
||||
}
|
||||
break;
|
||||
|
||||
case PidLidReminderSet: // TODO
|
||||
case PidLidUseTnef: // TODO
|
||||
*data = MAPIBoolValue (memCtx, NO);
|
||||
break;
|
||||
case PidLidRemoteStatus: // TODO
|
||||
*data = MAPILongValue (memCtx, 0);
|
||||
break;
|
||||
case PidLidSmartNoAttach: // TODO
|
||||
case PidLidAgingDontAgeMe: // TODO
|
||||
*data = MAPIBoolValue (memCtx, YES);
|
||||
break;
|
||||
|
||||
// PidLidFlagRequest
|
||||
// PidLidBillingInformation
|
||||
// PidLidMileage
|
||||
// PidLidCommonEnd
|
||||
// PidLidCommonStart
|
||||
// PidLidNonSendableBcc
|
||||
// PidLidNonSendableCc
|
||||
// PidLidNonSendtableTo
|
||||
// PidLidNonSendBccTrackStatus
|
||||
// PidLidNonSendCcTrackStatus
|
||||
// PidLidNonSendToTrackStatus
|
||||
// PidLidReminderDelta
|
||||
// PidLidReminderFileParameter
|
||||
// PidLidReminderSignalTime
|
||||
// PidLidReminderOverride
|
||||
// PidLidReminderPlaySound
|
||||
// PidLidReminderTime
|
||||
// PidLidReminderType
|
||||
// PidLidSmartNoAttach
|
||||
// PidLidTaskGlobalId
|
||||
// PidLidTaskMode
|
||||
// PidLidVerbResponse
|
||||
// PidLidVerbStream
|
||||
// PidLidInternetAccountName
|
||||
// PidLidInternetAccountStamp
|
||||
// PidLidContactLinkName
|
||||
// PidLidContactLinkEntry
|
||||
// PidLidContactLinkSearchKey
|
||||
// PidLidSpamOriginalFolder
|
||||
|
||||
default:
|
||||
rc = [super getChildProperty: data
|
||||
forKey: childKey
|
||||
withTag: propTag];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
static NSMutableDictionary *knownProperties = nil;
|
||||
|
@ -606,11 +86,6 @@ static Class NSDataK, NSStringK;
|
|||
|
||||
/* restrictions */
|
||||
|
||||
- (void) setRestrictions: (const struct mapi_SRestriction *) res
|
||||
{
|
||||
[super setRestrictions: res];
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
|
@ -760,6 +235,7 @@ static Class NSDataK, NSStringK;
|
|||
|
||||
- (void) setSortOrder: (const struct SSortOrderSet *) set
|
||||
{
|
||||
NSMutableArray *newSortOrderings;
|
||||
NSMutableString *newSortOrdering;
|
||||
struct SSortOrder *sortOrder;
|
||||
NSString *sortIdentifier;
|
||||
|
@ -772,7 +248,7 @@ static Class NSDataK, NSStringK;
|
|||
if (set->cCategories > 0)
|
||||
[self errorWithFormat: @"we don't handle sort categories yet"];
|
||||
|
||||
newSortOrdering = [NSMutableString string];
|
||||
newSortOrderings = [NSMutableArray array];
|
||||
|
||||
for (count = 0; count < set->cSorts; count++)
|
||||
{
|
||||
|
@ -781,11 +257,13 @@ static Class NSDataK, NSStringK;
|
|||
= [self _sortIdentifierForProperty: sortOrder->ulPropTag];
|
||||
if (sortIdentifier)
|
||||
{
|
||||
newSortOrdering = [NSMutableString string];
|
||||
if (sortOrder->ulOrder == TABLE_SORT_DESCEND)
|
||||
[newSortOrdering appendString: @" REVERSE"];
|
||||
else if (sortOrder->ulOrder == TABLE_SORT_MAXIMUM_CATEGORY)
|
||||
[self errorWithFormat: @"TABLE_SORT_MAXIMUM_CATEGORY is not handled"];
|
||||
[newSortOrdering appendFormat: @" %@", sortIdentifier];
|
||||
[newSortOrderings addObject: [newSortOrdering substringFromIndex: 1]];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -797,15 +275,16 @@ static Class NSDataK, NSStringK;
|
|||
propName, sortOrder->ulPropTag];
|
||||
}
|
||||
}
|
||||
if ([newSortOrdering length] > 0)
|
||||
ASSIGN (sortOrdering, [newSortOrdering substringFromIndex: 1]);
|
||||
if ([newSortOrderings count] > 0)
|
||||
ASSIGN (sortOrderings, newSortOrderings);
|
||||
else
|
||||
ASSIGN (sortOrdering, @"ARRIVAL");
|
||||
[self cleanupCaches];
|
||||
[self logWithFormat: @"new sort ordering: '%@'", sortOrdering];
|
||||
ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]);
|
||||
[self logWithFormat: @"new sort orderings: '%@'", sortOrderings];
|
||||
}
|
||||
else
|
||||
ASSIGN (sortOrdering, @"ARRIVAL");
|
||||
ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]);
|
||||
|
||||
[self cleanupCaches];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#import <SOGo/SOGoFolder.h>
|
||||
#import <SOGo/SOGoObject.h>
|
||||
|
||||
#import "MAPIStoreFolder.h"
|
||||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
|
@ -32,21 +33,6 @@
|
|||
|
||||
#import "MAPIStoreMessageTable.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <stdbool.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
#include <libmapiproxy.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_nameid.h>
|
||||
#include <talloc.h>
|
||||
|
||||
@interface SOGoObject (MAPIStoreProtocol)
|
||||
|
||||
- (NSString *) davEntityTag;
|
||||
- (NSString *) davContentLength;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MAPIStoreMessageTable
|
||||
|
||||
static MAPIStoreMapping *mapping;
|
||||
|
@ -56,169 +42,6 @@ static MAPIStoreMapping *mapping;
|
|||
mapping = [MAPIStoreMapping sharedMapping];
|
||||
}
|
||||
|
||||
- (NSArray *) childKeys
|
||||
{
|
||||
return [folder toOneRelationshipKeys];
|
||||
}
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
int rc;
|
||||
uint32_t contextId;
|
||||
uint64_t mappingId;
|
||||
NSString *stringValue, *childURL;
|
||||
NSUInteger length;
|
||||
id child;
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
switch (propTag)
|
||||
{
|
||||
case PR_INST_ID: // TODO: DOUBT
|
||||
/* we return a unique id based on the key */
|
||||
*data = MAPILongLongValue (memCtx, [childKey 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_VD_NAME_UNICODE:
|
||||
// *data = [@"PR_VD_NAME_UNICODE fake value" asUnicodeInMemCtx: memCtx];
|
||||
// break;
|
||||
// case PR_VD_VERSION:
|
||||
// /* mandatory value... wtf? */g
|
||||
// *data = MAPILongValue (memCtx, 8);
|
||||
// break;
|
||||
case PR_FID:
|
||||
*data = MAPILongLongValue (memCtx, fid);
|
||||
break;
|
||||
case PR_MID:
|
||||
childURL = [NSString stringWithFormat: @"%@%@", folderURL, childKey];
|
||||
mappingId = [mapping idFromURL: childURL];
|
||||
if (mappingId == NSNotFound)
|
||||
{
|
||||
openchangedb_get_new_folderID (ldbCtx, &mappingId);
|
||||
[mapping registerURL: childURL withID: mappingId];
|
||||
contextId = 0;
|
||||
mapistore_search_context_by_uri (memCtx, [folderURL UTF8String] + 7,
|
||||
&contextId);
|
||||
mapistore_indexing_record_add_mid (memCtx, contextId, mappingId);
|
||||
}
|
||||
*data = MAPILongLongValue (memCtx, mappingId);
|
||||
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
|
||||
child = [self lookupChild: childKey];
|
||||
/* TODO: choose another name in SOGo for that method */
|
||||
*data = MAPILongValue (memCtx, [[child 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:
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [child davEntityTag];
|
||||
length = [stringValue length];
|
||||
if (length < 6) /* guid = 16 bytes */
|
||||
{
|
||||
length += 6;
|
||||
stringValue = [NSString stringWithFormat: @"000000%@",
|
||||
stringValue];
|
||||
}
|
||||
if (length > 6)
|
||||
stringValue = [stringValue substringFromIndex: length - 7];
|
||||
stringValue = [NSString stringWithFormat: @"SOGo%@%@%@",
|
||||
stringValue, stringValue, stringValue];
|
||||
*data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding]
|
||||
asShortBinaryInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
case PR_ORIGINAL_SUBJECT_UNICODE:
|
||||
case PR_CONVERSATION_TOPIC_UNICODE:
|
||||
rc = [self getChildProperty: data forKey: childKey
|
||||
withTag: PR_NORMALIZED_SUBJECT_UNICODE];
|
||||
break;
|
||||
|
||||
case PR_SUBJECT_PREFIX_UNICODE:
|
||||
*data = [@"" asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_NORMALIZED_SUBJECT_UNICODE:
|
||||
rc = [self getChildProperty: data forKey: childKey
|
||||
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 getChildProperty: data forKey: childKey
|
||||
withTag: PR_MESSAGE_CLASS_UNICODE];
|
||||
break;
|
||||
|
||||
default:
|
||||
rc = [super getChildProperty: data
|
||||
forKey: childKey
|
||||
withTag: propTag];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (void) setSortOrder: (const struct SSortOrderSet *) set
|
||||
{
|
||||
[self logWithFormat: @"unimplemented method: %@", NSStringFromSelector (_cmd)];
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/* MAPIStoreNotesMessageTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
*
|
||||
* Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef MAPISTORENOTESMESSAGETABLE_H
|
||||
#define MAPISTORENOTESMESSAGETABLE_H
|
||||
|
||||
#import "MAPIStoreFSMessageTable.h"
|
||||
|
||||
@interface MAPIStoreNotesMessageTable : MAPIStoreFSMessageTable
|
||||
@end
|
||||
|
||||
#endif /* MAPISTORENOTESMESSAGETABLE_H */
|
|
@ -1,77 +0,0 @@
|
|||
/* MAPIStoreNotesMessageTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
*
|
||||
* Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <SOGo/SOGoFolder.h>
|
||||
#import <SOGo/SOGoObject.h>
|
||||
|
||||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreNotesMessageTable.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <stdbool.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
#include <libmapiproxy.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_nameid.h>
|
||||
#include <talloc.h>
|
||||
|
||||
|
||||
@implementation MAPIStoreNotesMessageTable
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
int rc;
|
||||
|
||||
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 = [self getChildProperty: data
|
||||
forKey: childKey
|
||||
withTag: PR_NORMALIZED_SUBJECT_UNICODE];
|
||||
break;
|
||||
default:
|
||||
rc = [super getChildProperty: data
|
||||
forKey: childKey
|
||||
withTag: propTag];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@end
|
|
@ -30,11 +30,6 @@
|
|||
#define SENSITIVITY_PRIVATE 2
|
||||
#define SENSITIVITY_COMPANY_CONFIDENTIAL 3
|
||||
|
||||
#define TBL_LEAF_ROW 0x00000001
|
||||
#define TBL_EMPTY_CATEGORY 0x00000002
|
||||
#define TBL_EXPANDED_CATEGORY 0x00000003
|
||||
#define TBL_COLLAPSED_CATEGORY 0x00000004
|
||||
|
||||
typedef enum {
|
||||
MAPIRestrictionStateAlwaysFalse = NO,
|
||||
MAPIRestrictionStateAlwaysTrue = YES,
|
||||
|
@ -43,48 +38,49 @@ typedef enum {
|
|||
} MAPIRestrictionState;
|
||||
|
||||
@class NSArray;
|
||||
@class NSMutableArray;
|
||||
@class NSString;
|
||||
@class EOQualifier;
|
||||
|
||||
@class MAPIStoreObject;
|
||||
|
||||
@interface MAPIStoreTable : NSObject
|
||||
{
|
||||
id context;
|
||||
struct mapistore_context *memCtx;
|
||||
void *ldbCtx;
|
||||
MAPIStoreObject *container;
|
||||
|
||||
id folder;
|
||||
NSString *folderURL;
|
||||
uint64_t fid;
|
||||
NSArray *childKeys;
|
||||
NSArray *restrictedChildKeys;
|
||||
|
||||
id lastChild;
|
||||
NSString *lastChildKey;
|
||||
|
||||
NSArray *cachedKeys;
|
||||
NSArray *cachedRestrictedKeys;
|
||||
EOQualifier *restriction; /* should probably be a dictionary too */
|
||||
MAPIRestrictionState restrictionState;
|
||||
NSMutableArray *sortOrderings;
|
||||
|
||||
uint32_t currentRow;
|
||||
MAPIStoreObject *currentChild;
|
||||
|
||||
/* proof of concept */
|
||||
uint16_t columnsCount;
|
||||
enum MAPITAGS *columns;
|
||||
}
|
||||
|
||||
- (id) folder;
|
||||
+ (id) tableForContainer: (MAPIStoreObject *) newContainer;
|
||||
|
||||
- (void) setContext: (id) newContext
|
||||
withMemCtx: (struct mapistore_context *) newMemCtx;
|
||||
- (void) setFolder: (id) newFolder
|
||||
withURL: (NSString *) newFolderURL
|
||||
andFID: (uint64_t) newFid;
|
||||
- (id) initForContainer: (MAPIStoreObject *) newContainer;
|
||||
|
||||
- (void) setRestrictions: (const struct mapi_SRestriction *) res;
|
||||
- (NSArray *) childKeys;
|
||||
- (NSArray *) restrictedChildKeys;
|
||||
|
||||
- (NSArray *) cachedChildKeys;
|
||||
- (NSArray *) cachedRestrictedChildKeys;
|
||||
|
||||
- (id) lookupChild: (NSString *) childKey;
|
||||
- (id) childAtRowID: (uint32_t) rowId
|
||||
forQueryType: (enum table_query_type) queryType;
|
||||
|
||||
- (void) cleanupCaches;
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) proptag;
|
||||
- (void) setRestrictions: (const struct mapi_SRestriction *) res;
|
||||
- (int) setColumns: (enum MAPITAGS *) newColumns
|
||||
withCount: (uint16_t) newColumCount;
|
||||
- (int) getRow: (struct mapistore_property_data *) data
|
||||
withRowID: (uint32_t) rowId
|
||||
andQueryType: (enum table_query_type) queryType;
|
||||
|
||||
/* helpers */
|
||||
|
||||
|
@ -92,9 +88,7 @@ typedef enum {
|
|||
inFunction: (const char *) function;
|
||||
|
||||
/* subclasses */
|
||||
|
||||
- (NSArray *) childKeys;
|
||||
- (NSArray *) restrictedChildKeys;
|
||||
- (void) setSortOrder: (const struct SSortOrderSet *) set;
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property;
|
||||
- (MAPIRestrictionState) evaluateContentRestriction: (const struct mapi_SContentRestriction *) res
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
|
||||
#import <SOGo/SOGoFolder.h>
|
||||
|
||||
#import "EOBitmaskQualifier.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreObject.h"
|
||||
|
||||
#import "MAPIStoreTable.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
@ -249,23 +249,41 @@ static Class NSDataK, NSStringK;
|
|||
NSStringK = [NSString class];
|
||||
}
|
||||
|
||||
+ (id) tableForContainer: (MAPIStoreObject *) newContainer
|
||||
{
|
||||
MAPIStoreTable *newTable;
|
||||
|
||||
newTable = [[self alloc] initForContainer: newContainer];
|
||||
[newTable autorelease];
|
||||
|
||||
return newTable;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
context = nil;
|
||||
memCtx = NULL;
|
||||
container = nil;
|
||||
|
||||
folder = nil;
|
||||
folderURL = nil;
|
||||
childKeys = nil;
|
||||
restrictedChildKeys = nil;
|
||||
|
||||
lastChild = nil;
|
||||
lastChildKey = nil;
|
||||
currentRow = (uint32_t) -1;
|
||||
currentChild = nil;
|
||||
|
||||
cachedKeys = nil;
|
||||
cachedRestrictedKeys = nil;
|
||||
restriction = nil;
|
||||
restrictionState = MAPIRestrictionStateAlwaysTrue;
|
||||
sortOrderings = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initForContainer: (MAPIStoreObject *) newContainer
|
||||
{
|
||||
if ((self = [self init]))
|
||||
{
|
||||
container = newContainer;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -273,95 +291,57 @@ static Class NSDataK, NSStringK;
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[folder release];
|
||||
[folderURL release];
|
||||
[lastChildKey release];
|
||||
[lastChild release];
|
||||
[cachedKeys release];
|
||||
[cachedRestrictedKeys release];
|
||||
[currentChild release];
|
||||
[childKeys release];
|
||||
[restrictedChildKeys release];
|
||||
[restriction release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setContext: (id) newContext
|
||||
withMemCtx: (struct mapistore_context *) newMemCtx
|
||||
- (NSArray *) childKeys
|
||||
{
|
||||
struct loadparm_context *lpCtx;
|
||||
|
||||
context = newContext;
|
||||
|
||||
memCtx = newMemCtx;
|
||||
lpCtx = loadparm_init (newMemCtx);
|
||||
ldbCtx = mapiproxy_server_openchange_ldb_init (lpCtx);
|
||||
}
|
||||
|
||||
- (void) setFolder: (id) newFolder
|
||||
withURL: (NSString *) newFolderURL
|
||||
andFID: (uint64_t) newFid
|
||||
{
|
||||
ASSIGN (folder, newFolder);
|
||||
ASSIGN (folderURL, newFolderURL);
|
||||
fid = newFid;
|
||||
}
|
||||
|
||||
- (id) folder
|
||||
{
|
||||
if (!folder)
|
||||
[self warnWithFormat: @"returning nil folder"];
|
||||
return folder;
|
||||
}
|
||||
|
||||
- (NSArray *) cachedChildKeys
|
||||
{
|
||||
if (!cachedKeys)
|
||||
if (!childKeys)
|
||||
{
|
||||
cachedKeys = [self childKeys];
|
||||
[cachedKeys retain];
|
||||
childKeys = [container childKeysMatchingQualifier: nil
|
||||
andSortOrderings: sortOrderings];
|
||||
[childKeys retain];
|
||||
}
|
||||
|
||||
return cachedKeys;
|
||||
return childKeys;
|
||||
}
|
||||
|
||||
- (NSArray *) cachedRestrictedChildKeys
|
||||
- (NSArray *) restrictedChildKeys
|
||||
{
|
||||
if (!cachedRestrictedKeys)
|
||||
NSArray *keys;
|
||||
|
||||
if (!restrictedChildKeys)
|
||||
{
|
||||
cachedRestrictedKeys = [self restrictedChildKeys];
|
||||
[cachedRestrictedKeys retain];
|
||||
if (restrictionState != MAPIRestrictionStateAlwaysTrue)
|
||||
{
|
||||
if (restrictionState == MAPIRestrictionStateNeedsEval)
|
||||
keys = [container childKeysMatchingQualifier: restriction
|
||||
andSortOrderings: sortOrderings];
|
||||
else
|
||||
keys = [NSArray array];
|
||||
}
|
||||
else
|
||||
keys = [self childKeys];
|
||||
|
||||
ASSIGN (restrictedChildKeys, keys);
|
||||
}
|
||||
|
||||
return cachedRestrictedKeys;
|
||||
return restrictedChildKeys;
|
||||
}
|
||||
|
||||
- (void) cleanupCaches
|
||||
{
|
||||
[cachedRestrictedKeys release];
|
||||
cachedRestrictedKeys = nil;
|
||||
[cachedKeys release];
|
||||
cachedKeys = nil;
|
||||
[lastChildKey release];
|
||||
lastChildKey = nil;
|
||||
[lastChild release];
|
||||
lastChild = nil;
|
||||
}
|
||||
|
||||
- (id) lookupChild: (NSString *) childKey
|
||||
{
|
||||
id newChild;
|
||||
|
||||
if ([lastChildKey isEqualToString: childKey])
|
||||
newChild = lastChild;
|
||||
else
|
||||
{
|
||||
[self logWithFormat: @"child key is now '%@'", childKey];
|
||||
newChild = [folder lookupName: childKey
|
||||
inContext: nil
|
||||
acquire: NO];
|
||||
ASSIGN (lastChildKey, childKey);
|
||||
ASSIGN (lastChild, newChild);
|
||||
}
|
||||
|
||||
return newChild;
|
||||
[restrictedChildKeys release];
|
||||
restrictedChildKeys = nil;
|
||||
[childKeys release];
|
||||
childKeys = nil;
|
||||
[currentChild release];
|
||||
currentChild = nil;
|
||||
currentRow = (uint32_t) -1;
|
||||
}
|
||||
|
||||
- (void) setRestrictions: (const struct mapi_SRestriction *) res
|
||||
|
@ -385,8 +365,7 @@ static Class NSDataK, NSStringK;
|
|||
restriction = nil;
|
||||
|
||||
// FIXME: we should not flush the caches if the restrictions matches
|
||||
[cachedRestrictedKeys release];
|
||||
cachedRestrictedKeys = nil;
|
||||
[self cleanupCaches];
|
||||
|
||||
if (restriction)
|
||||
[self logWithFormat: @"restriction set to EOQualifier: %@",
|
||||
|
@ -395,59 +374,6 @@ static Class NSDataK, NSStringK;
|
|||
[self logWithFormat: @"restriction unset (was %@)", oldRestriction];
|
||||
}
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
NSString *stringValue;
|
||||
id child;
|
||||
// uint64_t *llongValue;
|
||||
// uint32_t *longValue;
|
||||
int rc;
|
||||
const char *propName;
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
switch (propTag)
|
||||
{
|
||||
case PR_DISPLAY_NAME_UNICODE:
|
||||
child = [self lookupChild: childKey];
|
||||
*data = [[child displayName] asUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_SEARCH_KEY: // TODO
|
||||
child = [self lookupChild: childKey];
|
||||
stringValue = [child 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>";
|
||||
[self warnWithFormat:
|
||||
@"unhandled or NULL value: %s (0x%.8x), childKey: %@",
|
||||
propName, propTag, childKey];
|
||||
// if ((propTag & 0x001F) == 0x001F)
|
||||
// {
|
||||
// stringValue = [NSString stringWithFormat: @"fake %s (0x.8x) value",
|
||||
// propName, propTag];
|
||||
// *data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
// rc = MAPI_E_SUCCESS;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
*data = NULL;
|
||||
rc = MAPI_E_NOT_FOUND;
|
||||
// }
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluateNotRestriction: (struct mapi_SNotRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifierPtr
|
||||
{
|
||||
|
@ -555,13 +481,6 @@ static Class NSDataK, NSStringK;
|
|||
return state;
|
||||
}
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) warnUnhandledProperty: (enum MAPITAGS) property
|
||||
inFunction: (const char *) function
|
||||
{
|
||||
|
@ -781,18 +700,97 @@ static Class NSDataK, NSStringK;
|
|||
return state;
|
||||
}
|
||||
|
||||
- (NSArray *) childKeys
|
||||
/* proof of concept */
|
||||
- (int) setColumns: (enum MAPITAGS *) newColumns
|
||||
withCount: (uint16_t) newColumnsCount
|
||||
{
|
||||
NSUInteger count;
|
||||
|
||||
if (columns)
|
||||
NSZoneFree (NULL, columns);
|
||||
columns = NSZoneMalloc (NULL, newColumnsCount * sizeof (enum MAPITAGS));
|
||||
for (count = 0; count < newColumnsCount; count++)
|
||||
columns[count] = newColumns[count];
|
||||
columnsCount = newColumnsCount;
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (id) childAtRowID: (uint32_t) rowId
|
||||
forQueryType: (enum table_query_type) queryType
|
||||
{
|
||||
id child;
|
||||
NSArray *children, *restrictedChildren;
|
||||
NSString *childKey;
|
||||
|
||||
if (rowId == currentRow)
|
||||
child = currentChild;
|
||||
else
|
||||
{
|
||||
child = nil;
|
||||
|
||||
if (queryType == MAPISTORE_PREFILTERED_QUERY)
|
||||
{
|
||||
children = [self restrictedChildKeys];
|
||||
restrictedChildren = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
children = [self childKeys];
|
||||
restrictedChildren = [self restrictedChildKeys];
|
||||
}
|
||||
|
||||
if ([children count] > rowId)
|
||||
{
|
||||
childKey = [children objectAtIndex: rowId];
|
||||
|
||||
if (queryType == MAPISTORE_PREFILTERED_QUERY
|
||||
|| [restrictedChildren containsObject: childKey])
|
||||
child = [container lookupChild: childKey];
|
||||
}
|
||||
|
||||
currentChild = child;
|
||||
[currentChild retain];
|
||||
currentRow = rowId;
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
- (int) getRow: (struct mapistore_property_data *) data
|
||||
withRowID: (uint32_t) rowId
|
||||
andQueryType: (enum table_query_type) queryType
|
||||
{
|
||||
NSUInteger count;
|
||||
MAPIStoreObject *child;
|
||||
enum MAPISTATUS rc;
|
||||
|
||||
child = [self childAtRowID: rowId
|
||||
forQueryType: queryType];
|
||||
if (child)
|
||||
{
|
||||
rc = MAPI_E_SUCCESS;
|
||||
for (count = 0; count < columnsCount; count++)
|
||||
data[count].error = [child getProperty: &data[count].data
|
||||
withTag: columns[count]];
|
||||
}
|
||||
else
|
||||
rc = MAPI_E_INVALID_OBJECT;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* subclasses */
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray *) restrictedChildKeys
|
||||
- (void) setSortOrder: (const struct SSortOrderSet *) set
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -39,239 +39,6 @@
|
|||
|
||||
@implementation MAPIStoreTasksMessageTable
|
||||
|
||||
- (enum MAPISTATUS) getChildProperty: (void **) data
|
||||
forKey: (NSString *) childKey
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
{
|
||||
NSString *status;
|
||||
// id child;
|
||||
iCalToDo *task;
|
||||
int32_t statusValue;
|
||||
NSCalendarDate *dateValue;
|
||||
int rc;
|
||||
double doubleValue;
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
switch (propTag)
|
||||
{
|
||||
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 = [[self lookupChild: childKey] 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 = [[self lookupChild: childKey] 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 = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
*data = MAPIBoolValue (memCtx,
|
||||
[[task status] isEqualToString: @"COMPLETED"]);
|
||||
break;
|
||||
case PidLidPercentComplete:
|
||||
task = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
doubleValue = ((double) [[task percentComplete] intValue] / 100);
|
||||
*data = MAPIDoubleValue (memCtx, doubleValue);
|
||||
break;
|
||||
case PidLidTaskDateCompleted:
|
||||
task = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
dateValue = [task completed];
|
||||
if (dateValue)
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
else
|
||||
rc = MAPI_E_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 = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
dateValue = [task due];
|
||||
if (dateValue)
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
else
|
||||
rc = MAPI_E_NOT_FOUND;
|
||||
break;
|
||||
|
||||
case PR_CREATION_TIME:
|
||||
task = [[self lookupChild: childKey] 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 = [[self lookupChild: childKey] component: NO secure: NO];
|
||||
*data = [[task lastModified] asFileTimeInMemCtx: memCtx];
|
||||
break;
|
||||
case PidLidTaskStatus: // status
|
||||
task = [[self lookupChild: childKey] 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 getChildProperty: data
|
||||
forKey: childKey
|
||||
withTag: propTag];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (EOQualifier *) componentQualifier
|
||||
{
|
||||
static EOQualifier *componentQualifier = nil;
|
||||
|
||||
/* TODO: we need to support vlist as well */
|
||||
if (!componentQualifier)
|
||||
componentQualifier
|
||||
= [[EOKeyValueQualifier alloc] initWithKey: @"c_component"
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: @"vtodo"];
|
||||
|
||||
return componentQualifier;
|
||||
}
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
static NSMutableDictionary *knownProperties = nil;
|
||||
|
|
Loading…
Reference in New Issue