Monotone-Parent: 23072776516ad7ec761501356d062052d748d8c7

Monotone-Revision: 0803c3f82523e76024a78031ba0e71fce02404eb

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2011-02-24T20:40:07
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Wolfgang Sourdeau 2011-02-24 20:40:07 +00:00
parent c96ae87f5b
commit 1feee33aa2
18 changed files with 218 additions and 2120 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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
{

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -28,9 +28,6 @@
@class EOQualifier;
@interface MAPIStoreGCSMessageTable : MAPIStoreMessageTable
{
NSMutableArray *sortOrderings;
}
- (EOQualifier *) componentQualifier;
- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property;

View File

@ -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

View File

@ -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

View File

@ -26,9 +26,6 @@
#import "MAPIStoreMessageTable.h"
@interface MAPIStoreMailMessageTable : MAPIStoreMessageTable
{
NSString *sortOrdering;
}
@end

View File

@ -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

View File

@ -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)];

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;