See ChangeLog
Monotone-Parent: 8027e57cbf5cbb4ab2ee6bf9509fe2f571f150c1 Monotone-Revision: 0ffde732abb09a8e3d0382ed47a3ec787f25796e Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2011-09-14T18:33:44 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
8fb4411dd6
commit
057a38355b
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
||||||
|
2011-09-14 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||||
|
|
||||||
|
* SoObjects/Mailer/SOGoMailBaseObject.m: (imap4Connection):
|
||||||
|
Cache "corruption" bug fix that could lead us to using the
|
||||||
|
wrong IMAP connection for OpenChange users
|
||||||
|
|
||||||
|
* OpenChange/MAPIStoreMapping.m: (unregisterURLWithID:)
|
||||||
|
We also remove the keys/values from the indexing database
|
||||||
|
|
||||||
|
* OpenChange/MAPIStoreSOGo.m
|
||||||
|
RopMoveCopyMessages, RopCopyTo and messages move/copy
|
||||||
|
notifications support for messages
|
||||||
|
|
||||||
|
* OpenChange/MAPIStoreContactsMessage.m: massive improvements
|
||||||
|
to support many new properties
|
||||||
|
|
||||||
|
* OpenChange/MAPIStoreTasksMessage.m: massive improvements
|
||||||
|
to support many new properties
|
||||||
|
|
||||||
|
* OpenChange/MAPIStoreFolder.m: (getPrAccess:inMemCtx:) fixed
|
||||||
|
permissions issue - we were returning a wrong value leading to
|
||||||
|
IMAP subfolders not being "writable"
|
||||||
|
|
||||||
2011-09-04 Ludovic Marcotte <lmarcotte@inverse.ca>
|
2011-09-04 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||||
|
|
||||||
* OpenChange/MAPIStoreMapping.m: (MAPIStoreMappingTDBTraverse())
|
* OpenChange/MAPIStoreMapping.m: (MAPIStoreMappingTDBTraverse())
|
||||||
|
|
|
@ -100,7 +100,7 @@ static Class MAPIStoreCalendarMessageK;
|
||||||
return componentQualifier;
|
return componentQualifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MAPIStoreMessage *) createMessage
|
- (MAPIStoreMessage *) createMessageWithMID: (uint64_t) mid
|
||||||
{
|
{
|
||||||
MAPIStoreMessage *newMessage;
|
MAPIStoreMessage *newMessage;
|
||||||
SOGoAppointmentObject *newEntry;
|
SOGoAppointmentObject *newEntry;
|
||||||
|
|
|
@ -103,7 +103,7 @@ static Class MAPIStoreContactsMessageK;
|
||||||
return componentQualifier;
|
return componentQualifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MAPIStoreMessage *) createMessage
|
- (MAPIStoreMessage *) createMessageWithMID: (uint64_t) mid
|
||||||
{
|
{
|
||||||
MAPIStoreMessage *newMessage;
|
MAPIStoreMessage *newMessage;
|
||||||
SOGoContactGCSEntry *newEntry;
|
SOGoContactGCSEntry *newEntry;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* Copyright (C) 2011 Inverse inc
|
* Copyright (C) 2011 Inverse inc
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -50,6 +51,31 @@
|
||||||
|
|
||||||
@implementation MAPIStoreContactsMessage
|
@implementation MAPIStoreContactsMessage
|
||||||
|
|
||||||
|
// TODO: this should be combined with the version found
|
||||||
|
// in UIxContactEditor.m
|
||||||
|
- (CardElement *) _elementWithTag: (NSString *) tag
|
||||||
|
ofType: (NSString *) type
|
||||||
|
forCard: (NGVCard *) card
|
||||||
|
{
|
||||||
|
NSArray *elements;
|
||||||
|
CardElement *element;
|
||||||
|
|
||||||
|
elements = [card childrenWithTag: tag
|
||||||
|
andAttribute: @"type" havingValue: type];
|
||||||
|
if ([elements count] > 0)
|
||||||
|
element = [elements objectAtIndex: 0];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
element = [CardElement new];
|
||||||
|
[element autorelease];
|
||||||
|
[element setTag: tag];
|
||||||
|
[element addType: type];
|
||||||
|
[card addChild: element];
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
- (int) getPrIconIndex: (void **) data // TODO
|
- (int) getPrIconIndex: (void **) data // TODO
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
|
@ -352,6 +378,13 @@
|
||||||
atPos: 0 inData: data inMemCtx: memCtx];
|
atPos: 0 inData: data inMemCtx: memCtx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (int) getPrPagerTelephoneNumber: (void **) data
|
||||||
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
|
{
|
||||||
|
return [self _getElement: @"tel" ofType: @"pager" excluding: nil
|
||||||
|
atPos: 0 inData: data inMemCtx: memCtx];
|
||||||
|
}
|
||||||
|
|
||||||
- (int) getPrPrimaryTelephoneNumber: (void **) data
|
- (int) getPrPrimaryTelephoneNumber: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
|
@ -359,6 +392,13 @@
|
||||||
atPos: 0 inData: data inMemCtx: memCtx];
|
atPos: 0 inData: data inMemCtx: memCtx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (int) getPrBusinessFaxNumber: (void **) data
|
||||||
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
|
{
|
||||||
|
return [self _getElement: @"tel" ofType: @"fax" excluding: nil
|
||||||
|
atPos: 0 inData: data inMemCtx: memCtx];
|
||||||
|
}
|
||||||
|
|
||||||
- (int) getPrBusinessHomePage: (void **) data
|
- (int) getPrBusinessHomePage: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
|
@ -432,6 +472,10 @@
|
||||||
return MAPISTORE_SUCCESS;
|
return MAPISTORE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// getters when no address is selected as the Mailing Address
|
||||||
|
//
|
||||||
- (int) getPrPostalAddress: (void **) data
|
- (int) getPrPostalAddress: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
|
@ -481,6 +525,60 @@
|
||||||
atPos: 6 inData: data inMemCtx: memCtx];
|
atPos: 6 inData: data inMemCtx: memCtx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// home address getters
|
||||||
|
//
|
||||||
|
- (int) getPidLidHomeAddress: (void **) data
|
||||||
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
|
{
|
||||||
|
return [self _getElement: @"label" ofType: @"home" excluding: nil
|
||||||
|
atPos: 0 inData: data inMemCtx: memCtx];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) getPrHomeAddressPostOfficeBox: (void **) data
|
||||||
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
|
{
|
||||||
|
return [self _getElement: @"adr" ofType: @"home" excluding: nil
|
||||||
|
atPos: 0 inData: data inMemCtx: memCtx];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) getPrHomeAddressStreet: (void **) data
|
||||||
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
|
{
|
||||||
|
return [self _getElement: @"adr" ofType: @"home" excluding: nil
|
||||||
|
atPos: 2 inData: data inMemCtx: memCtx];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) getPrHomeAddressCity: (void **) data
|
||||||
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
|
{
|
||||||
|
return [self _getElement: @"adr" ofType: @"home" excluding: nil
|
||||||
|
atPos: 3 inData: data inMemCtx: memCtx];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) getPrHomeAddressStateOrProvince: (void **) data
|
||||||
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
|
{
|
||||||
|
return [self _getElement: @"adr" ofType: @"home" excluding: nil
|
||||||
|
atPos: 4 inData: data inMemCtx: memCtx];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) getPrHomeAddressPostalCode: (void **) data
|
||||||
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
|
{
|
||||||
|
return [self _getElement: @"adr" ofType: @"home" excluding: nil
|
||||||
|
atPos: 5 inData: data inMemCtx: memCtx];
|
||||||
|
}
|
||||||
|
- (int) getPrHomeAddressCountry: (void **) data
|
||||||
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
|
{
|
||||||
|
return [self _getElement: @"adr" ofType: @"home" excluding: nil
|
||||||
|
atPos: 6 inData: data inMemCtx: memCtx];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Work addresss
|
||||||
|
//
|
||||||
- (int) getPidLidWorkAddress: (void **) data
|
- (int) getPidLidWorkAddress: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
|
@ -530,6 +628,9 @@
|
||||||
atPos: 6 inData: data inMemCtx: memCtx];
|
atPos: 6 inData: data inMemCtx: memCtx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
- (int) getPrNickname: (void **) data
|
- (int) getPrNickname: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
|
@ -565,9 +666,10 @@
|
||||||
|
|
||||||
- (void) save
|
- (void) save
|
||||||
{
|
{
|
||||||
NGVCard *newCard;
|
NSArray *elements, *units;
|
||||||
NSArray *elements;
|
|
||||||
CardElement *element;
|
CardElement *element;
|
||||||
|
NGVCard *newCard;
|
||||||
|
|
||||||
int postalAddressId;
|
int postalAddressId;
|
||||||
id value;
|
id value;
|
||||||
|
|
||||||
|
@ -579,11 +681,23 @@
|
||||||
[newCard setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"];
|
[newCard setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"];
|
||||||
[newCard setProfile: @"vCard"];
|
[newCard setProfile: @"vCard"];
|
||||||
|
|
||||||
value = [newProperties
|
// Decomposed fullname
|
||||||
objectForKey: MAPIPropertyKey (PR_DISPLAY_NAME_UNICODE)];
|
[newCard setNWithFamily: [newProperties objectForKey: MAPIPropertyKey(PR_SURNAME_UNICODE)]
|
||||||
|
given: [newProperties objectForKey: MAPIPropertyKey(PR_GIVEN_NAME_UNICODE)]
|
||||||
|
additional: [newProperties objectForKey: MAPIPropertyKey(PR_MIDDLE_NAME_UNICODE)]
|
||||||
|
prefixes: [newProperties objectForKey: MAPIPropertyKey(PR_DISPLAY_NAME_PREFIX_UNICODE)]
|
||||||
|
suffixes: [newProperties objectForKey: MAPIPropertyKey(PR_GENERATION_UNICODE)]];
|
||||||
|
|
||||||
|
//
|
||||||
|
// display name
|
||||||
|
//
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_DISPLAY_NAME_UNICODE)];
|
||||||
if (value)
|
if (value)
|
||||||
[newCard setFn: value];
|
[newCard setFn: value];
|
||||||
|
|
||||||
|
//
|
||||||
|
// email addresses handling
|
||||||
|
//
|
||||||
elements = [newCard childrenWithTag: @"email"];
|
elements = [newCard childrenWithTag: @"email"];
|
||||||
value = [newProperties objectForKey: MAPIPropertyKey(PidLidEmail1EmailAddress)];
|
value = [newProperties objectForKey: MAPIPropertyKey(PidLidEmail1EmailAddress)];
|
||||||
if (value)
|
if (value)
|
||||||
|
@ -611,10 +725,20 @@
|
||||||
[newCard addEmail: value types: nil];
|
[newCard addEmail: value types: nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// work postal addresses handling
|
||||||
|
//
|
||||||
|
// Possible values for PidLidPostalAddressId are:
|
||||||
|
//
|
||||||
|
// 0x00000000 - No address is selected as the Mailing Address.
|
||||||
|
// 0x00000001 - The Home Address is the Mailing Address.
|
||||||
|
// 0x00000002 - The Work Address is the Mailing Address
|
||||||
|
// 0x00000003 - The Other Address is the Mailing Address.
|
||||||
|
//
|
||||||
|
//
|
||||||
postalAddressId = [[newProperties objectForKey: MAPIPropertyKey (PidLidPostalAddressId)]
|
postalAddressId = [[newProperties objectForKey: MAPIPropertyKey (PidLidPostalAddressId)]
|
||||||
intValue];
|
intValue];
|
||||||
|
|
||||||
/* Work address */
|
|
||||||
value = [newProperties objectForKey: MAPIPropertyKey(PidLidWorkAddress)];
|
value = [newProperties objectForKey: MAPIPropertyKey(PidLidWorkAddress)];
|
||||||
if ([value length])
|
if ([value length])
|
||||||
{
|
{
|
||||||
|
@ -671,6 +795,135 @@
|
||||||
if (value)
|
if (value)
|
||||||
[element setValue: 6 to: value];
|
[element setValue: 6 to: value];
|
||||||
|
|
||||||
|
//
|
||||||
|
// home postal addresses handling
|
||||||
|
//
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PidLidHomeAddress)];
|
||||||
|
if ([value length])
|
||||||
|
{
|
||||||
|
elements = [newCard childrenWithTag: @"label"
|
||||||
|
andAttribute: @"type"
|
||||||
|
havingValue: @"home"];
|
||||||
|
if ([elements count] > 0)
|
||||||
|
element = [elements objectAtIndex: 0];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
element = [CardElement elementWithTag: @"label"];
|
||||||
|
[element addAttribute: @"type" value: @"home"];
|
||||||
|
[newCard addChild: element];
|
||||||
|
}
|
||||||
|
if (postalAddressId == 1)
|
||||||
|
{
|
||||||
|
[element removeValue: @"pref"
|
||||||
|
fromAttribute: @"type"];
|
||||||
|
[element addAttribute: @"type"
|
||||||
|
value: @"pref"];
|
||||||
|
}
|
||||||
|
[element setValue: 0 to: value];
|
||||||
|
}
|
||||||
|
|
||||||
|
elements = [newCard childrenWithTag: @"adr"
|
||||||
|
andAttribute: @"type"
|
||||||
|
havingValue: @"home"];
|
||||||
|
if ([elements count] > 0)
|
||||||
|
element = [elements objectAtIndex: 0];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
element = [CardElement elementWithTag: @"adr"];
|
||||||
|
[element addAttribute: @"type" value: @"home"];
|
||||||
|
[newCard addChild: element];
|
||||||
|
}
|
||||||
|
if (postalAddressId == 1)
|
||||||
|
[element addAttribute: @"type" value: @"pref"];
|
||||||
|
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_POST_OFFICE_BOX_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 0 to: value];
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey( PR_HOME_ADDRESS_STREET_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 2 to: value];
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_CITY_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 3 to: value];
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_STATE_OR_PROVINCE_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 4 to: value];
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_POSTAL_CODE_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 5 to: value];
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_COUNTRY_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 6 to: value];
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// telephone numbers: work, home, fax, pager and mobile
|
||||||
|
//
|
||||||
|
element = [self _elementWithTag: @"tel" ofType: @"work" forCard: newCard];
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_OFFICE_TELEPHONE_NUMBER_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 0 to: value];
|
||||||
|
|
||||||
|
element = [self _elementWithTag: @"tel" ofType: @"home" forCard: newCard];
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_HOME_TELEPHONE_NUMBER_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 0 to: value];
|
||||||
|
|
||||||
|
element = [self _elementWithTag: @"tel" ofType: @"fax" forCard: newCard];
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_BUSINESS_FAX_NUMBER_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 0 to: value];
|
||||||
|
|
||||||
|
element = [self _elementWithTag: @"tel" ofType: @"pager" forCard: newCard];
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_PAGER_TELEPHONE_NUMBER_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 0 to: value];
|
||||||
|
|
||||||
|
element = [self _elementWithTag: @"tel" ofType: @"cell" forCard: newCard];
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_MOBILE_TELEPHONE_NUMBER_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[element setValue: 0 to: value];
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// job title, nickname, company name, deparment, work url, im address/screen name
|
||||||
|
//
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_TITLE_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[newCard setTitle: value];
|
||||||
|
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_NICKNAME_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[newCard setNickname: value];
|
||||||
|
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_DEPARTMENT_NAME_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
units = [NSArray arrayWithObject: value];
|
||||||
|
else
|
||||||
|
units = nil;
|
||||||
|
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_COMPANY_NAME_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
[newCard setOrg: value units: units];
|
||||||
|
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PR_BUSINESS_HOME_PAGE_UNICODE)];
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
[[self _elementWithTag: @"url" ofType: @"work" forCard: newCard]
|
||||||
|
setValue: 0 to: value];
|
||||||
|
}
|
||||||
|
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PidLidInstantMessagingAddress)];
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
[[newCard uniqueChildWithTag: @"x-aim"]
|
||||||
|
setValue: 0
|
||||||
|
to: value];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// we save the new/modified card
|
||||||
|
//
|
||||||
[sogoObject saveContentString: [newCard versitString]];
|
[sogoObject saveContentString: [newCard versitString]];
|
||||||
[(MAPIStoreContactsFolder *) container synchroniseCache];
|
[(MAPIStoreContactsFolder *) container synchroniseCache];
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ static Class EOKeyValueQualifierK, MAPIStoreFSMessageK;
|
||||||
return newKey;
|
return newKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MAPIStoreMessage *) createMessage
|
- (MAPIStoreMessage *) createMessageWithMID: (uint64_t) mid
|
||||||
{
|
{
|
||||||
MAPIStoreMessage *newMessage;
|
MAPIStoreMessage *newMessage;
|
||||||
SOGoMAPIFSMessage *fsObject;
|
SOGoMAPIFSMessage *fsObject;
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
@class SOGoMAPIFSFolder;
|
@class SOGoMAPIFSFolder;
|
||||||
@class SOGoMAPIFSMessage;
|
@class SOGoMAPIFSMessage;
|
||||||
|
|
||||||
|
|
||||||
#import "MAPIStoreObject.h"
|
#import "MAPIStoreObject.h"
|
||||||
|
|
||||||
@interface MAPIStoreFolder : MAPIStoreObject
|
@interface MAPIStoreFolder : MAPIStoreObject
|
||||||
|
@ -94,7 +95,8 @@
|
||||||
- (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier
|
- (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier
|
||||||
andSortOrderings: (NSArray *) sortOrderings;
|
andSortOrderings: (NSArray *) sortOrderings;
|
||||||
|
|
||||||
- (MAPIStoreMessage *) createMessage: (BOOL) isAssociated;
|
- (MAPIStoreMessage *) createMessageWithMID: (uint64_t) mid
|
||||||
|
isAssociated: (BOOL) isAssociated;
|
||||||
|
|
||||||
/* backend interface */
|
/* backend interface */
|
||||||
|
|
||||||
|
@ -110,12 +112,18 @@
|
||||||
- (int) createMessage: (MAPIStoreMessage **) messagePtr
|
- (int) createMessage: (MAPIStoreMessage **) messagePtr
|
||||||
withMID: (uint64_t) mid
|
withMID: (uint64_t) mid
|
||||||
isAssociated: (BOOL) isAssociated;
|
isAssociated: (BOOL) isAssociated;
|
||||||
|
|
||||||
|
|
||||||
- (int) openMessage: (MAPIStoreMessage **) messagePtr
|
- (int) openMessage: (MAPIStoreMessage **) messagePtr
|
||||||
andMessageData: (struct mapistore_message **) dataPtr
|
andMessageData: (struct mapistore_message **) dataPtr
|
||||||
withMID: (uint64_t) mid
|
withMID: (uint64_t) mid
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||||
- (int) deleteMessageWithMID: (uint64_t) mid
|
- (int) deleteMessageWithMID: (uint64_t) mid
|
||||||
andFlags: (uint8_t) flags;
|
andFlags: (uint8_t) flags;
|
||||||
|
- (int) moveCopyMessageWithMID: (uint64_t) mid
|
||||||
|
toFolder: (MAPIStoreFolder *) targetFolder
|
||||||
|
inMessage: (MAPIStoreMessage *) targetMessage
|
||||||
|
wantCopy: (uint8_t) want_copy;
|
||||||
- (int) getDeletedFMIDs: (struct I8Array_r **) fmidsPtr
|
- (int) getDeletedFMIDs: (struct I8Array_r **) fmidsPtr
|
||||||
andCN: (uint64_t *) cnPtr
|
andCN: (uint64_t *) cnPtr
|
||||||
fromChangeNumber: (uint64_t) changeNum
|
fromChangeNumber: (uint64_t) changeNum
|
||||||
|
@ -132,7 +140,7 @@
|
||||||
|
|
||||||
/* subclasses */
|
/* subclasses */
|
||||||
- (Class) messageClass;
|
- (Class) messageClass;
|
||||||
- (MAPIStoreMessage *) createMessage;
|
- (MAPIStoreMessage *) createMessageWithMID: (uint64_t) mid;
|
||||||
- (MAPIStoreMessageTable *) messageTable;
|
- (MAPIStoreMessageTable *) messageTable;
|
||||||
- (NSArray *) messageKeysMatchingQualifier: (EOQualifier *) qualifier
|
- (NSArray *) messageKeysMatchingQualifier: (EOQualifier *) qualifier
|
||||||
andSortOrderings: (NSArray *) sortOrderings;
|
andSortOrderings: (NSArray *) sortOrderings;
|
||||||
|
|
|
@ -437,7 +437,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
||||||
rc = MAPISTORE_ERR_EXIST;
|
rc = MAPISTORE_ERR_EXIST;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
message = [self createMessage: isAssociated];
|
message = [self createMessageWithMID: mid
|
||||||
|
isAssociated: isAssociated];
|
||||||
if (message)
|
if (message)
|
||||||
{
|
{
|
||||||
baseURL = [self url];
|
baseURL = [self url];
|
||||||
|
@ -551,6 +552,18 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (int) moveCopyMessageWithMID: (uint64_t) mid
|
||||||
|
toFolder: (MAPIStoreFolder *) targetFolder
|
||||||
|
inMessage: (MAPIStoreMessage *) targetMessage
|
||||||
|
wantCopy: (uint8_t) want_copy
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = MAPISTORE_SUCCESS;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
- (int) getDeletedFMIDs: (struct I8Array_r **) fmidsPtr
|
- (int) getDeletedFMIDs: (struct I8Array_r **) fmidsPtr
|
||||||
andCN: (uint64_t *) cnPtr
|
andCN: (uint64_t *) cnPtr
|
||||||
fromChangeNumber: (uint64_t) changeNum
|
fromChangeNumber: (uint64_t) changeNum
|
||||||
|
@ -814,14 +827,30 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
||||||
return MAPISTORE_SUCCESS;
|
return MAPISTORE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Possible values are:
|
||||||
|
|
||||||
|
0x00000001 Modify
|
||||||
|
0x00000002 Read
|
||||||
|
0x00000004 Delete
|
||||||
|
0x00000008 Create Hierarchy Table
|
||||||
|
0x00000010 Create Contents Table
|
||||||
|
0x00000020 Create Associated Contents Table
|
||||||
|
*/
|
||||||
- (int) getPrAccess: (void **) data
|
- (int) getPrAccess: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
*data = MAPILongValue (memCtx, 0x63);
|
*data = MAPILongValue (memCtx, 0x1|0x2|0x4|0x8|0x10|0x20);
|
||||||
|
|
||||||
return MAPISTORE_SUCCESS;
|
return MAPISTORE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Possible values are:
|
||||||
|
|
||||||
|
0x00000000 Read-Only
|
||||||
|
0x00000001 Modify
|
||||||
|
*/
|
||||||
- (int) getPrAccessLevel: (void **) data
|
- (int) getPrAccessLevel: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
|
@ -938,7 +967,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
||||||
return newMessage;
|
return newMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MAPIStoreMessage *) createMessage: (BOOL) isAssociated
|
- (MAPIStoreMessage *) createMessageWithMID: (uint64_t) mid
|
||||||
|
isAssociated: (BOOL) isAssociated
|
||||||
{
|
{
|
||||||
MAPIStoreMessage *newMessage;
|
MAPIStoreMessage *newMessage;
|
||||||
WOContext *woContext;
|
WOContext *woContext;
|
||||||
|
@ -946,7 +976,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
||||||
if (isAssociated)
|
if (isAssociated)
|
||||||
newMessage = [self _createAssociatedMessage];
|
newMessage = [self _createAssociatedMessage];
|
||||||
else
|
else
|
||||||
newMessage = [self createMessage];
|
newMessage = [self createMessageWithMID: mid];
|
||||||
[newMessage setIsNew: YES];
|
[newMessage setIsNew: YES];
|
||||||
woContext = [[self context] woContext];
|
woContext = [[self context] woContext];
|
||||||
[[newMessage sogoObject] setContext: woContext];
|
[[newMessage sogoObject] setContext: woContext];
|
||||||
|
@ -1038,7 +1068,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
||||||
return Nil;
|
return Nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MAPIStoreMessage *) createMessage
|
- (MAPIStoreMessage *) createMessageWithMID: (uint64_t) mid
|
||||||
{
|
{
|
||||||
[self logWithFormat: @"ignored method: %s", __PRETTY_FUNCTION__];
|
[self logWithFormat: @"ignored method: %s", __PRETTY_FUNCTION__];
|
||||||
return nil;
|
return nil;
|
||||||
|
|
|
@ -26,12 +26,14 @@
|
||||||
#import "MAPIStoreFolder.h"
|
#import "MAPIStoreFolder.h"
|
||||||
|
|
||||||
@class NSCalendarDate;
|
@class NSCalendarDate;
|
||||||
|
@class NSMutableDictionary;
|
||||||
@class NSNumber;
|
@class NSNumber;
|
||||||
@class NSString;
|
@class NSString;
|
||||||
|
|
||||||
@interface MAPIStoreGCSFolder : MAPIStoreFolder
|
@interface MAPIStoreGCSFolder : MAPIStoreFolder
|
||||||
{
|
{
|
||||||
SOGoMAPIFSMessage *versionsMessage;
|
SOGoMAPIFSMessage *versionsMessage;
|
||||||
|
NSMutableDictionary *initialVersions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* synchronisation */
|
/* synchronisation */
|
||||||
|
@ -42,6 +44,9 @@
|
||||||
/* subclasses */
|
/* subclasses */
|
||||||
- (EOQualifier *) componentQualifier;
|
- (EOQualifier *) componentQualifier;
|
||||||
|
|
||||||
|
- (void) setInitialVersion: (uint64_t) version
|
||||||
|
forMessage: (NSString *) theMessage;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif /* MAPISTOREGCSFOLDER_H */
|
#endif /* MAPISTOREGCSFOLDER_H */
|
||||||
|
|
|
@ -51,6 +51,8 @@
|
||||||
ASSIGN (versionsMessage,
|
ASSIGN (versionsMessage,
|
||||||
[SOGoMAPIFSMessage objectWithName: @"versions.plist"
|
[SOGoMAPIFSMessage objectWithName: @"versions.plist"
|
||||||
inContainer: propsFolder]);
|
inContainer: propsFolder]);
|
||||||
|
|
||||||
|
initialVersions = [[NSMutableDictionary alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -64,6 +66,8 @@
|
||||||
ASSIGN (versionsMessage,
|
ASSIGN (versionsMessage,
|
||||||
[SOGoMAPIFSMessage objectWithName: @"versions.plist"
|
[SOGoMAPIFSMessage objectWithName: @"versions.plist"
|
||||||
inContainer: propsFolder]);
|
inContainer: propsFolder]);
|
||||||
|
|
||||||
|
initialVersions = [[NSMutableDictionary alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -72,6 +76,7 @@
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
[versionsMessage release];
|
[versionsMessage release];
|
||||||
|
[initialVersions release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +252,14 @@
|
||||||
{
|
{
|
||||||
foundChange = YES;
|
foundChange = YES;
|
||||||
|
|
||||||
|
//if ([[messageEntry objectForKey: @"c_version"] intValue] == 0)
|
||||||
|
// newChangeNum = [[initialVersions objectForKey: cName] unsignedLongLongValue];
|
||||||
|
//else
|
||||||
|
{
|
||||||
newChangeNum = [[self context] getNewChangeNumber];
|
newChangeNum = [[self context] getNewChangeNumber];
|
||||||
|
[initialVersions removeObjectForKey: cName];
|
||||||
|
}
|
||||||
|
|
||||||
changeNumber = [NSNumber numberWithUnsignedLongLong: newChangeNum];
|
changeNumber = [NSNumber numberWithUnsignedLongLong: newChangeNum];
|
||||||
|
|
||||||
[messageEntry setObject: cLastModified forKey: @"c_lastmodified"];
|
[messageEntry setObject: cLastModified forKey: @"c_lastmodified"];
|
||||||
|
@ -398,4 +410,11 @@
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setInitialVersion: (uint64_t) version
|
||||||
|
forMessage: (NSString *) theMessage
|
||||||
|
{
|
||||||
|
[initialVersions setObject: [NSNumber numberWithUnsignedLongLong: version]
|
||||||
|
forKey: theMessage];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
#import "MAPIStoreMessage.h"
|
#import "MAPIStoreMessage.h"
|
||||||
|
|
||||||
@interface MAPIStoreGCSMessage : MAPIStoreMessage
|
@interface MAPIStoreGCSMessage : MAPIStoreMessage
|
||||||
|
{
|
||||||
|
@private
|
||||||
|
uint64_t _version;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif /* MAPISTOREGCSMESSAGE_H */
|
#endif /* MAPISTOREGCSMESSAGE_H */
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
#import <SOGo/SOGoContentObject.h>
|
#import <SOGo/SOGoContentObject.h>
|
||||||
|
|
||||||
|
#import "MAPIStoreContext.h"
|
||||||
#import "MAPIStoreGCSFolder.h"
|
#import "MAPIStoreGCSFolder.h"
|
||||||
#import "MAPIStoreTypes.h"
|
#import "MAPIStoreTypes.h"
|
||||||
|
|
||||||
|
@ -34,6 +35,16 @@
|
||||||
|
|
||||||
@implementation MAPIStoreGCSMessage
|
@implementation MAPIStoreGCSMessage
|
||||||
|
|
||||||
|
- (id) init
|
||||||
|
{
|
||||||
|
if ((self = [super init]))
|
||||||
|
{
|
||||||
|
_version = 0xffffffffffffffffLL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSCalendarDate *) creationTime
|
- (NSCalendarDate *) creationTime
|
||||||
{
|
{
|
||||||
return [sogoObject creationDate];
|
return [sogoObject creationDate];
|
||||||
|
@ -49,7 +60,19 @@
|
||||||
uint64_t version = 0xffffffffffffffffLL;
|
uint64_t version = 0xffffffffffffffffLL;
|
||||||
NSNumber *changeNumber;
|
NSNumber *changeNumber;
|
||||||
|
|
||||||
if (![sogoObject isNew])
|
if ([sogoObject isNew])
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (_version == 0xffffffffffffffffLL)
|
||||||
|
{
|
||||||
|
_version = [[self context] getNewChangeNumber];
|
||||||
|
[(MAPIStoreGCSFolder *)[self container] setInitialVersion: _version
|
||||||
|
forMessage: [self nameInContainer]];
|
||||||
|
}
|
||||||
|
version = _version;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
changeNumber = [(MAPIStoreGCSFolder *) container
|
changeNumber = [(MAPIStoreGCSFolder *) container
|
||||||
changeNumberForMessageWithKey: [self nameInContainer]];
|
changeNumberForMessageWithKey: [self nameInContainer]];
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#import <Mailer/SOGoMailAccount.h>
|
#import <Mailer/SOGoMailAccount.h>
|
||||||
#import <Mailer/SOGoMailAccounts.h>
|
#import <Mailer/SOGoMailAccounts.h>
|
||||||
#import <Mailer/SOGoMailFolder.h>
|
#import <Mailer/SOGoMailFolder.h>
|
||||||
|
#import <Mailer/SOGoMailObject.h>
|
||||||
#import <Mailer/SOGoSentFolder.h>
|
#import <Mailer/SOGoSentFolder.h>
|
||||||
#import <Mailer/SOGoTrashFolder.h>
|
#import <Mailer/SOGoTrashFolder.h>
|
||||||
#import <SOGo/NSArray+Utilities.h>
|
#import <SOGo/NSArray+Utilities.h>
|
||||||
|
@ -47,8 +48,10 @@
|
||||||
#import "MAPIStoreAppointmentWrapper.h"
|
#import "MAPIStoreAppointmentWrapper.h"
|
||||||
#import "MAPIStoreContext.h"
|
#import "MAPIStoreContext.h"
|
||||||
#import "MAPIStoreDraftsMessage.h"
|
#import "MAPIStoreDraftsMessage.h"
|
||||||
|
#import "MAPIStoreFAIMessage.h"
|
||||||
#import "MAPIStoreMailMessage.h"
|
#import "MAPIStoreMailMessage.h"
|
||||||
#import "MAPIStoreMailMessageTable.h"
|
#import "MAPIStoreMailMessageTable.h"
|
||||||
|
#import "MAPIStoreMapping.h"
|
||||||
#import "MAPIStoreTypes.h"
|
#import "MAPIStoreTypes.h"
|
||||||
#import "NSString+MAPIStore.h"
|
#import "NSString+MAPIStore.h"
|
||||||
#import "SOGoMAPIFSMessage.h"
|
#import "SOGoMAPIFSMessage.h"
|
||||||
|
@ -62,6 +65,7 @@ static Class SOGoMailFolderK;
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#include <libmapi/libmapi.h>
|
#include <libmapi/libmapi.h>
|
||||||
#include <mapistore/mapistore.h>
|
#include <mapistore/mapistore.h>
|
||||||
|
#include <mapistore/mapistore_errors.h>
|
||||||
|
|
||||||
@implementation MAPIStoreMailFolder
|
@implementation MAPIStoreMailFolder
|
||||||
|
|
||||||
|
@ -631,6 +635,187 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
return deletedKeys;
|
return deletedKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// We need to support creating "fake" emails for RopCopyTo and other
|
||||||
|
// other ROPs to function properly. We don't know what will be the
|
||||||
|
// object's name (as it's the IMAP's UID) until the message really
|
||||||
|
// is created in the mail store.
|
||||||
|
//
|
||||||
|
- (MAPIStoreMessage *) createMessageWithMID: (uint64_t) mid
|
||||||
|
{
|
||||||
|
MAPIStoreMessage *message;
|
||||||
|
SOGoMailObject *mail;
|
||||||
|
|
||||||
|
mail = [SOGoMailObject objectWithName: [NSString stringWithFormat: @"%llu", mid]
|
||||||
|
inContainer: sogoObject];
|
||||||
|
|
||||||
|
message = [MAPIStoreMailMessage mapiStoreObjectWithSOGoObject: mail
|
||||||
|
inContainer: self];
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Move (or eventually copy) the mail identified by
|
||||||
|
// "mid" within this current folder. The message is
|
||||||
|
// of course coming from an other folder
|
||||||
|
//
|
||||||
|
- (int) moveCopyMessageWithMID: (uint64_t) mid
|
||||||
|
toFolder: (MAPIStoreFolder *) targetFolder
|
||||||
|
inMessage: (MAPIStoreMessage *) targetMessage
|
||||||
|
wantCopy: (uint8_t) want_copy
|
||||||
|
{
|
||||||
|
NSString *folderName, *messageURL, *uid, *url, *v;
|
||||||
|
MAPIStoreMapping *mapping;
|
||||||
|
NSDictionary *result;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int new_uid;
|
||||||
|
uint64_t target_mid;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
mapping = [[self context] mapping];
|
||||||
|
|
||||||
|
messageURL = [mapping urlFromID: mid];
|
||||||
|
|
||||||
|
if (messageURL)
|
||||||
|
{
|
||||||
|
// We get the message UID from that folder by stripping the .eml
|
||||||
|
// This is the message we'll copy in the folder specified by targetURL
|
||||||
|
uid = [messageURL lastPathComponent];
|
||||||
|
uid = [uid substringToIndex: [uid length] - 4];
|
||||||
|
|
||||||
|
folderName = [[targetFolder sogoObject] relativeImap4Name];
|
||||||
|
|
||||||
|
if (uid && [folderName length] > 0)
|
||||||
|
{
|
||||||
|
struct mapistore_object_notification_parameters *notif_parameters;
|
||||||
|
struct mapistore_connection_info *connInfo;
|
||||||
|
NGImap4Client *client;
|
||||||
|
NSArray *a;
|
||||||
|
|
||||||
|
// We copy the message, get the new UID and set the old one as deleted
|
||||||
|
client = [[[self sogoObject] imap4Connection] client];
|
||||||
|
[client select: [[self sogoObject] relativeImap4Name]];
|
||||||
|
result = [client copyUid: [uid intValue] toFolder: folderName];
|
||||||
|
|
||||||
|
if (!want_copy)
|
||||||
|
[client storeUid: [uid intValue] add: [NSNumber numberWithBool: YES] flags: [NSArray arrayWithObject: @"Deleted"]];
|
||||||
|
|
||||||
|
//
|
||||||
|
// We use the UIDPLUS IMAP extension here in order to speedup UID retreival
|
||||||
|
// If supported by the server, we'll get something like: COPYUID 1315425789 1 8
|
||||||
|
//
|
||||||
|
// Sometimes COPYUID isn't returned at all by Cyrus or in case the server doesn't
|
||||||
|
// support the UIDPLUS IMAP extension, we fallback to a simple UID search.
|
||||||
|
//
|
||||||
|
v = [[[result objectForKey: @"RawResponse"] objectForKey: @"ResponseResult"] objectForKey: @"flag"];
|
||||||
|
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
unsigned int current_uid, uid_validity;
|
||||||
|
const char *s;
|
||||||
|
char tag[7];
|
||||||
|
|
||||||
|
s = [v cStringUsingEncoding: NSASCIIStringEncoding];
|
||||||
|
sscanf(s, "%s %u %u %u", tag, &uid_validity, ¤t_uid, &new_uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[client select: folderName];
|
||||||
|
a = [[client sort: @"ARRIVAL" qualifier: nil encoding: @"UTF-8"] objectForKey: @"sort"];
|
||||||
|
new_uid = [[[a sortedArrayUsingSelector: @selector(compare:)] lastObject] intValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
// We compute the URL of the move message and update our mapping
|
||||||
|
url = [NSString stringWithFormat: @"%@%d.eml", [targetFolder url], new_uid];
|
||||||
|
|
||||||
|
if (!want_copy)
|
||||||
|
[mapping unregisterURLWithID: mid];
|
||||||
|
|
||||||
|
// We adjust its name within the container with the newly obtained UID. This was previously the
|
||||||
|
// MID of the message and that value was temporary since we created a "fake" message
|
||||||
|
target_mid = strtoull([[[targetMessage sogoObject] nameInContainer] UTF8String], NULL, 10);
|
||||||
|
|
||||||
|
[[targetMessage sogoObject] setNameInContainer: [NSString stringWithFormat: @"%u.eml", new_uid]];
|
||||||
|
|
||||||
|
// We unregister the previously (and temporary) registered mid and register
|
||||||
|
// it again with its new and valid URL
|
||||||
|
[mapping unregisterURLWithID: target_mid];
|
||||||
|
[mapping registerURL: url withID: target_mid];
|
||||||
|
|
||||||
|
NSArray *activeTables;
|
||||||
|
NSUInteger count, max;
|
||||||
|
/* we ensure the table caches are loaded so that old and new state
|
||||||
|
can be compared */
|
||||||
|
MAPIStoreMessage *message;
|
||||||
|
|
||||||
|
message = [self lookupMessageByURL: messageURL];
|
||||||
|
activeTables = ([message isKindOfClass: [MAPIStoreFAIMessage class]]
|
||||||
|
? [self activeFAIMessageTables]
|
||||||
|
: [self activeMessageTables]);
|
||||||
|
max = [activeTables count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
[[activeTables objectAtIndex: count] restrictedChildKeys];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// We notify the client
|
||||||
|
notif_parameters = talloc_zero(NULL, struct mapistore_object_notification_parameters);
|
||||||
|
notif_parameters->object_id = [self objectId];
|
||||||
|
notif_parameters->tag_count = 5;
|
||||||
|
notif_parameters->tags = talloc_array (notif_parameters, enum MAPITAGS, 5);
|
||||||
|
notif_parameters->tags[0] = PR_CONTENT_COUNT;
|
||||||
|
notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL;
|
||||||
|
notif_parameters->tags[2] = PR_MESSAGE_SIZE;
|
||||||
|
notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE;
|
||||||
|
notif_parameters->tags[4] = PR_RECIPIENT_ON_NORMAL_MSG_COUNT;
|
||||||
|
notif_parameters->new_message_count = true;
|
||||||
|
notif_parameters->message_count = [[self messageKeys] count];
|
||||||
|
connInfo = [[self context] connectionInfo];
|
||||||
|
mapistore_push_notification (connInfo->mstore_ctx,
|
||||||
|
MAPISTORE_FOLDER,
|
||||||
|
MAPISTORE_OBJECT_MODIFIED,
|
||||||
|
notif_parameters);
|
||||||
|
talloc_free(notif_parameters);
|
||||||
|
|
||||||
|
/* move/copy notification */
|
||||||
|
notif_parameters = talloc_zero(NULL, struct mapistore_object_notification_parameters);
|
||||||
|
notif_parameters->tag_count = 0;
|
||||||
|
notif_parameters->new_message_count = true;
|
||||||
|
notif_parameters->message_count = 0;
|
||||||
|
notif_parameters->object_id = target_mid;
|
||||||
|
notif_parameters->folder_id = [targetFolder objectId];
|
||||||
|
notif_parameters->old_object_id = mid;
|
||||||
|
notif_parameters->old_folder_id = [self objectId];
|
||||||
|
|
||||||
|
mapistore_push_notification (connInfo->mstore_ctx,
|
||||||
|
MAPISTORE_MESSAGE,
|
||||||
|
(want_copy ? MAPISTORE_OBJECT_COPIED : MAPISTORE_OBJECT_MOVED),
|
||||||
|
notif_parameters);
|
||||||
|
talloc_free(notif_parameters);
|
||||||
|
|
||||||
|
/* table notification */
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
[[activeTables objectAtIndex: count]
|
||||||
|
notifyChangesForChild: message];
|
||||||
|
|
||||||
|
// We cleanup cache of our source and destionation folders
|
||||||
|
[self cleanupCaches];
|
||||||
|
[targetFolder cleanupCaches];
|
||||||
|
rc = MAPISTORE_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MAPIStoreInboxFolder : MAPIStoreMailFolder
|
@implementation MAPIStoreInboxFolder : MAPIStoreMailFolder
|
||||||
|
@ -781,6 +966,10 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
|
|
||||||
// @end
|
// @end
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
@implementation MAPIStoreOutboxFolder : MAPIStoreMailFolder
|
@implementation MAPIStoreOutboxFolder : MAPIStoreMailFolder
|
||||||
|
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
|
@ -799,7 +988,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
return MAPIStoreDraftsMessageK;
|
return MAPIStoreDraftsMessageK;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MAPIStoreMessage *) createMessage
|
- (MAPIStoreMessage *) createMessageWithMID: (uint64_t) mid
|
||||||
{
|
{
|
||||||
MAPIStoreDraftsMessage *newMessage;
|
MAPIStoreDraftsMessage *newMessage;
|
||||||
SOGoDraftObject *newDraft;
|
SOGoDraftObject *newDraft;
|
||||||
|
@ -809,7 +998,6 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
= [MAPIStoreDraftsMessage mapiStoreObjectWithSOGoObject: newDraft
|
= [MAPIStoreDraftsMessage mapiStoreObjectWithSOGoObject: newDraft
|
||||||
inContainer: self];
|
inContainer: self];
|
||||||
|
|
||||||
|
|
||||||
return newMessage;
|
return newMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
@class NSString;
|
@class NSString;
|
||||||
|
|
||||||
@class MAPIStoreAppointmentWrapper;
|
@class MAPIStoreAppointmentWrapper;
|
||||||
|
@class MAPIStoreMailFolder;
|
||||||
|
|
||||||
@interface MAPIStoreMailMessage : MAPIStoreMessage
|
@interface MAPIStoreMailMessage : MAPIStoreMessage
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* Copyright (C) 2011 Inverse inc
|
* Copyright (C) 2011 Inverse inc
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,6 +25,8 @@
|
||||||
#import <Foundation/NSDictionary.h>
|
#import <Foundation/NSDictionary.h>
|
||||||
#import <Foundation/NSException.h>
|
#import <Foundation/NSException.h>
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
#import <NGImap4/NGImap4Client.h>
|
||||||
|
#import <NGImap4/NGImap4Connection.h>
|
||||||
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
||||||
#import <NGCards/iCalCalendar.h>
|
#import <NGCards/iCalCalendar.h>
|
||||||
#import <SOGo/NSArray+Utilities.h>
|
#import <SOGo/NSArray+Utilities.h>
|
||||||
|
@ -40,6 +43,7 @@
|
||||||
#import "MAPIStoreFolder.h"
|
#import "MAPIStoreFolder.h"
|
||||||
#import "MAPIStoreMailAttachment.h"
|
#import "MAPIStoreMailAttachment.h"
|
||||||
#import "MAPIStoreMailFolder.h"
|
#import "MAPIStoreMailFolder.h"
|
||||||
|
#import "MAPIStoreMapping.h"
|
||||||
#import "MAPIStoreTypes.h"
|
#import "MAPIStoreTypes.h"
|
||||||
|
|
||||||
#import "MAPIStoreMailMessage.h"
|
#import "MAPIStoreMailMessage.h"
|
||||||
|
|
|
@ -55,7 +55,7 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
|
||||||
NSNumber *idNbr;
|
NSNumber *idNbr;
|
||||||
NSString *uri;
|
NSString *uri;
|
||||||
char *idStr, *uriStr;
|
char *idStr, *uriStr;
|
||||||
long long unsigned int idVal;
|
uint64_t idVal;
|
||||||
|
|
||||||
// get the key
|
// get the key
|
||||||
// key examples : key(18) = "0x6900000000000001"
|
// key examples : key(18) = "0x6900000000000001"
|
||||||
|
@ -239,13 +239,21 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
|
||||||
|
|
||||||
- (void) unregisterURLWithID: (uint64_t) idNbr
|
- (void) unregisterURLWithID: (uint64_t) idNbr
|
||||||
{
|
{
|
||||||
NSNumber *idKey;
|
|
||||||
NSString *urlString;
|
NSString *urlString;
|
||||||
|
NSNumber *idKey;
|
||||||
|
TDB_DATA key;
|
||||||
|
|
||||||
idKey = [NSNumber numberWithUnsignedLongLong: idNbr];
|
idKey = [NSNumber numberWithUnsignedLongLong: idNbr];
|
||||||
urlString = [mapping objectForKey: idKey];
|
urlString = [mapping objectForKey: idKey];
|
||||||
[reverseMapping removeObjectForKey: urlString];
|
[reverseMapping removeObjectForKey: urlString];
|
||||||
[mapping removeObjectForKey: idKey];
|
[mapping removeObjectForKey: idKey];
|
||||||
|
|
||||||
|
/* We hard-delete the entry from the indexing database */
|
||||||
|
key.dptr = (unsigned char *) talloc_asprintf(NULL, "0x%.16"PRIx64, idNbr);
|
||||||
|
key.dsize = strlen((const char *) key.dptr);
|
||||||
|
|
||||||
|
tdb_delete(indexing->tdb, key);
|
||||||
|
talloc_free(key.dptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -402,7 +402,8 @@ sogo_folder_create_message(void *folder_object,
|
||||||
folder = wrapper->MAPIStoreSOGoObject;
|
folder = wrapper->MAPIStoreSOGoObject;
|
||||||
pool = [NSAutoreleasePool new];
|
pool = [NSAutoreleasePool new];
|
||||||
rc = [folder createMessage: &message
|
rc = [folder createMessage: &message
|
||||||
withMID: mid isAssociated: associated];
|
withMID: mid
|
||||||
|
isAssociated: associated];
|
||||||
if (rc == MAPISTORE_SUCCESS)
|
if (rc == MAPISTORE_SUCCESS)
|
||||||
*message_object = [message tallocWrapper: mem_ctx];
|
*message_object = [message tallocWrapper: mem_ctx];
|
||||||
[pool release];
|
[pool release];
|
||||||
|
@ -441,6 +442,44 @@ sogo_folder_delete_message(void *folder_object, uint64_t mid, uint8_t flags)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sogo_folder_move_copy_message(void *folder_object, uint64_t mid, void *target_folder, void *target_message, uint8_t want_copy)
|
||||||
|
{
|
||||||
|
MAPIStoreFolder *sourceFolder, *targetFolder;
|
||||||
|
MAPIStoreMessage *targetMessage;
|
||||||
|
NSAutoreleasePool *pool;
|
||||||
|
|
||||||
|
struct MAPIStoreTallocWrapper *wrapper;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__));
|
||||||
|
|
||||||
|
if (folder_object)
|
||||||
|
{
|
||||||
|
wrapper = folder_object;
|
||||||
|
sourceFolder = wrapper->MAPIStoreSOGoObject;
|
||||||
|
|
||||||
|
wrapper = target_folder;
|
||||||
|
targetFolder = wrapper->MAPIStoreSOGoObject;
|
||||||
|
|
||||||
|
wrapper = target_message;
|
||||||
|
targetMessage = wrapper->MAPIStoreSOGoObject;
|
||||||
|
|
||||||
|
pool = [NSAutoreleasePool new];
|
||||||
|
rc = [sourceFolder moveCopyMessageWithMID: mid
|
||||||
|
toFolder: targetFolder
|
||||||
|
inMessage: targetMessage
|
||||||
|
wantCopy: want_copy];
|
||||||
|
[pool release];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = sogo_backend_unexpected_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sogo_folder_get_deleted_fmids(void *folder_object, TALLOC_CTX *mem_ctx,
|
sogo_folder_get_deleted_fmids(void *folder_object, TALLOC_CTX *mem_ctx,
|
||||||
uint8_t table_type, uint64_t change_num,
|
uint8_t table_type, uint64_t change_num,
|
||||||
|
@ -1031,6 +1070,7 @@ int mapistore_init_backend(void)
|
||||||
backend.folder.open_message = sogo_folder_open_message;
|
backend.folder.open_message = sogo_folder_open_message;
|
||||||
backend.folder.create_message = sogo_folder_create_message;
|
backend.folder.create_message = sogo_folder_create_message;
|
||||||
backend.folder.delete_message = sogo_folder_delete_message;
|
backend.folder.delete_message = sogo_folder_delete_message;
|
||||||
|
backend.folder.move_copy_message = sogo_folder_move_copy_message;
|
||||||
backend.folder.get_deleted_fmids = sogo_folder_get_deleted_fmids;
|
backend.folder.get_deleted_fmids = sogo_folder_get_deleted_fmids;
|
||||||
backend.folder.get_child_count = sogo_folder_get_child_count;
|
backend.folder.get_child_count = sogo_folder_get_child_count;
|
||||||
backend.folder.open_table = sogo_folder_open_table;
|
backend.folder.open_table = sogo_folder_open_table;
|
||||||
|
|
|
@ -100,7 +100,7 @@ static Class MAPIStoreTasksMessageK;
|
||||||
return componentQualifier;
|
return componentQualifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MAPIStoreMessage *) createMessage
|
- (MAPIStoreMessage *) createMessageWithMID: (uint64_t) mid
|
||||||
{
|
{
|
||||||
MAPIStoreMessage *newMessage;
|
MAPIStoreMessage *newMessage;
|
||||||
SOGoTaskObject *newEntry;
|
SOGoTaskObject *newEntry;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* Copyright (C) 2011 Inverse inc
|
* Copyright (C) 2011 Inverse inc
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -209,6 +210,24 @@
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (int) getPidLidTaskStartDate: (void **) data
|
||||||
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
|
{
|
||||||
|
int rc = MAPISTORE_SUCCESS;
|
||||||
|
NSCalendarDate *dateValue;
|
||||||
|
iCalToDo *task;
|
||||||
|
|
||||||
|
task = [sogoObject component: NO secure: NO];
|
||||||
|
dateValue = [task startDate];
|
||||||
|
if (dateValue)
|
||||||
|
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||||
|
else
|
||||||
|
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (int) getPrMessageDeliveryTime: (void **) data
|
- (int) getPrMessageDeliveryTime: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
|
@ -253,7 +272,11 @@
|
||||||
- (int) getPidLidTaskOwner: (void **) data
|
- (int) getPidLidTaskOwner: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
*data = [@"openchange@example.com" asUnicodeInMemCtx: memCtx];
|
NSString *owner;
|
||||||
|
|
||||||
|
owner = [sogoObject ownerInContext: nil];
|
||||||
|
|
||||||
|
*data = [owner asUnicodeInMemCtx: memCtx];
|
||||||
|
|
||||||
return MAPISTORE_SUCCESS;
|
return MAPISTORE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -292,17 +315,17 @@
|
||||||
if (value)
|
if (value)
|
||||||
[vToDo setComment: value];
|
[vToDo setComment: value];
|
||||||
|
|
||||||
// Location
|
// location
|
||||||
value = [newProperties objectForKey: MAPIPropertyKey (PidLidLocation)];
|
value = [newProperties objectForKey: MAPIPropertyKey (PidLidLocation)];
|
||||||
if (value)
|
if (value)
|
||||||
[vToDo setLocation: value];
|
[vToDo setLocation: value];
|
||||||
|
|
||||||
/* created */
|
// created
|
||||||
value = [newProperties objectForKey: MAPIPropertyKey (PR_CREATION_TIME)];
|
value = [newProperties objectForKey: MAPIPropertyKey (PR_CREATION_TIME)];
|
||||||
if (value)
|
if (value)
|
||||||
[vToDo setCreated: value];
|
[vToDo setCreated: value];
|
||||||
|
|
||||||
/* last-modified + dtstamp */
|
// last-modified + dtstamp
|
||||||
value = [newProperties objectForKey: MAPIPropertyKey (PR_LAST_MODIFICATION_TIME)];
|
value = [newProperties objectForKey: MAPIPropertyKey (PR_LAST_MODIFICATION_TIME)];
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
|
@ -322,6 +345,10 @@
|
||||||
[date setTimeZone: tz];
|
[date setTimeZone: tz];
|
||||||
[date setDateTime: value];
|
[date setDateTime: value];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[vToDo setStartDate: nil];
|
||||||
|
}
|
||||||
|
|
||||||
// due
|
// due
|
||||||
value = [newProperties objectForKey: MAPIPropertyKey (PidLidTaskDueDate)];
|
value = [newProperties objectForKey: MAPIPropertyKey (PidLidTaskDueDate)];
|
||||||
|
@ -331,6 +358,23 @@
|
||||||
[date setTimeZone: tz];
|
[date setTimeZone: tz];
|
||||||
[date setDateTime: value];
|
[date setDateTime: value];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[vToDo setDue: nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
// completed
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey (PidLidTaskDateCompleted)];
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
date = (iCalDateTime *) [vToDo uniqueChildWithTag: @"completed"];
|
||||||
|
[date setTimeZone: tz];
|
||||||
|
[date setDateTime: value];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[vToDo setCompleted: nil];
|
||||||
|
}
|
||||||
|
|
||||||
// status
|
// status
|
||||||
value = [newProperties objectForKey: MAPIPropertyKey (PidLidTaskStatus)];
|
value = [newProperties objectForKey: MAPIPropertyKey (PidLidTaskStatus)];
|
||||||
|
@ -365,6 +409,13 @@
|
||||||
priority = @"0"; // None
|
priority = @"0"; // None
|
||||||
[vToDo setPriority: priority];
|
[vToDo setPriority: priority];
|
||||||
|
|
||||||
|
// percent complete
|
||||||
|
// NOTE: this does not seem to work on Outlook 2003. PidLidPercentComplete's value
|
||||||
|
// is always set to 0, no matter what value is set in Outlook
|
||||||
|
value = [newProperties objectForKey: MAPIPropertyKey(PidLidPercentComplete)];
|
||||||
|
if (value)
|
||||||
|
[vToDo setPercentComplete: [value stringValue]];
|
||||||
|
|
||||||
now = [NSCalendarDate date];
|
now = [NSCalendarDate date];
|
||||||
if ([sogoObject isNew])
|
if ([sogoObject isNew])
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,11 +36,6 @@
|
||||||
@class iCalTimeZone;
|
@class iCalTimeZone;
|
||||||
|
|
||||||
@interface iCalRepeatableEntityObject : iCalEntityObject
|
@interface iCalRepeatableEntityObject : iCalEntityObject
|
||||||
// {
|
|
||||||
// NSMutableArray *rRules;
|
|
||||||
// NSMutableArray *exRules;
|
|
||||||
// NSMutableArray *exDates;
|
|
||||||
// }
|
|
||||||
|
|
||||||
- (void)removeAllRecurrenceRules;
|
- (void)removeAllRecurrenceRules;
|
||||||
- (void)addToRecurrenceRules:(id)_rrule;
|
- (void)addToRecurrenceRules:(id)_rrule;
|
||||||
|
|
|
@ -160,7 +160,13 @@ static BOOL debugOn = YES;
|
||||||
if (!imap4)
|
if (!imap4)
|
||||||
{
|
{
|
||||||
sogoCache = [SOGoCache sharedCache];
|
sogoCache = [SOGoCache sharedCache];
|
||||||
cacheKey = [[self mailAccountFolder] nameInContainer];
|
// The cacheKey *MUST* be prefixed by the username here as
|
||||||
|
// the cache is shared across OpenChange users and not necessarily
|
||||||
|
// flushed between requests. This could lead us to using the wrong
|
||||||
|
// IMAP connection.
|
||||||
|
cacheKey = [NSString stringWithFormat: @"%@+%@",
|
||||||
|
[[[self context] activeUser] login],
|
||||||
|
[[self mailAccountFolder] nameInContainer]];
|
||||||
imap4 = [sogoCache imap4ConnectionForKey: cacheKey];
|
imap4 = [sogoCache imap4ConnectionForKey: cacheKey];
|
||||||
if (!imap4)
|
if (!imap4)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,7 +87,9 @@
|
||||||
- (void) setContext: (WOContext *) newContext;
|
- (void) setContext: (WOContext *) newContext;
|
||||||
- (WOContext *) context;
|
- (WOContext *) context;
|
||||||
|
|
||||||
|
- (void) setNameInContainer: (NSString *) theName;
|
||||||
- (NSString *) nameInContainer;
|
- (NSString *) nameInContainer;
|
||||||
|
|
||||||
- (NSString *) displayName;
|
- (NSString *) displayName;
|
||||||
- (id) container;
|
- (id) container;
|
||||||
|
|
||||||
|
|
|
@ -209,6 +209,11 @@
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setNameInContainer: (NSString *) theName
|
||||||
|
{
|
||||||
|
ASSIGN(nameInContainer, theName);
|
||||||
|
}
|
||||||
|
|
||||||
- (NSString *) nameInContainer
|
- (NSString *) nameInContainer
|
||||||
{
|
{
|
||||||
return nameInContainer;
|
return nameInContainer;
|
||||||
|
|
Loading…
Reference in New Issue