(fix) manually added fixes from PR#120
parent
edebdf1171
commit
5f82d3fb37
|
@ -45,16 +45,28 @@
|
|||
|
||||
@implementation MAPIStoreDBMessage
|
||||
|
||||
+ (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
+ (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
struct SPropTagArray *properties;
|
||||
NSUInteger count;
|
||||
enum MAPITAGS faiProperties[] = { 0x68350102, 0x683c0102, 0x683e0102,
|
||||
0x683f0102, 0x68410003, 0x68420102,
|
||||
0x68450102, 0x68460003,
|
||||
// PR_VD_NAME_W, PR_VD_FLAGS, PR_VD_VERSION, PR_VIEW_CLSID
|
||||
0x7006001F, 0x70030003, 0x70070003, 0x68330048 };
|
||||
|
||||
enum MAPITAGS faiProperties[] = {
|
||||
0x68330048, /* PR_VIEW_CLSID */
|
||||
0x68350102, /* PR_VIEW_STATE */
|
||||
0x683c0102,
|
||||
0x683d0040,
|
||||
0x683e0102,
|
||||
0x683f0102, /* PR_VIEW_VIEWTYPE_KEY */
|
||||
0x68410003,
|
||||
0x68420102,
|
||||
0x68450102,
|
||||
0x68460003,
|
||||
0x7006001F, /* PR_VD_NAME_W */
|
||||
0x70030003, /* PR_VD_FLAGS */
|
||||
0x70070003 /* PR_VD_VERSION */
|
||||
};
|
||||
|
||||
size_t faiSize = sizeof(faiProperties) / sizeof(enum MAPITAGS);
|
||||
|
||||
properties = talloc_zero (memCtx, struct SPropTagArray);
|
||||
|
@ -76,6 +88,13 @@
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [[self class] getAvailableProperties: propertiesP
|
||||
inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (id) initWithSOGoObject: (id) newSOGoObject
|
||||
inContainer: (MAPIStoreObject *) newContainer
|
||||
{
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
/* synchronisation */
|
||||
- (BOOL) synchroniseCache;
|
||||
- (BOOL) synchroniseCacheFor: (NSString *) nameInContainer;
|
||||
- (void) updateVersionsForMessageWithKey: (NSString *) messageKey
|
||||
withChangeKey: (NSData *) oldChangeKey
|
||||
andPredecessorChangeList: (NSData *) pcl;
|
||||
|
|
|
@ -548,6 +548,115 @@ static Class NSNumberK;
|
|||
return rc;
|
||||
}
|
||||
|
||||
- (BOOL) synchroniseCacheFor: (NSString *) nameInContainer
|
||||
{
|
||||
/* Try to synchronise old messages in versions.plist cache using an
|
||||
specific c_name. It returns a boolean indicating if the
|
||||
synchronisation was carried out succesfully.
|
||||
|
||||
It should be used as last resort, keeping synchroniseCache as the
|
||||
main sync entry point. */
|
||||
|
||||
uint64_t changeNumber;
|
||||
NSString *changeNumberStr;
|
||||
NSData *changeKey;
|
||||
NSNumber *cLastModified, *cDeleted, *cVersion;
|
||||
EOFetchSpecification *fs;
|
||||
EOQualifier *searchQualifier, *fetchQualifier;
|
||||
NSArray *fetchResults;
|
||||
NSDictionary *result;
|
||||
NSMutableDictionary *currentProperties, *messages, *mapping, *messageEntry;
|
||||
GCSFolder *ocsFolder;
|
||||
static NSArray *fields;
|
||||
|
||||
[versionsMessage reloadIfNeeded];
|
||||
currentProperties = [versionsMessage properties];
|
||||
|
||||
messages = [currentProperties objectForKey: @"Messages"];
|
||||
if (!messages)
|
||||
{
|
||||
messages = [NSMutableDictionary new];
|
||||
[currentProperties setObject: messages forKey: @"Messages"];
|
||||
[messages release];
|
||||
}
|
||||
|
||||
messageEntry = [messages objectForKey: nameInContainer];
|
||||
if (!messageEntry)
|
||||
{
|
||||
/* Fetch the message by its name */
|
||||
if (!fields)
|
||||
fields = [[NSArray alloc]
|
||||
initWithObjects: @"c_name", @"c_version", @"c_lastmodified",
|
||||
@"c_deleted", nil];
|
||||
|
||||
searchQualifier = [[EOKeyValueQualifier alloc] initWithKey: @"c_name"
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: nameInContainer];
|
||||
fetchQualifier = [[EOAndQualifier alloc]
|
||||
initWithQualifiers: searchQualifier,
|
||||
[self contentComponentQualifier],
|
||||
nil];
|
||||
[fetchQualifier autorelease];
|
||||
[searchQualifier release];
|
||||
|
||||
ocsFolder = [sogoObject ocsFolder];
|
||||
fs = [EOFetchSpecification
|
||||
fetchSpecificationWithEntityName: [ocsFolder folderName]
|
||||
qualifier: fetchQualifier
|
||||
sortOrderings: nil];
|
||||
fetchResults = [ocsFolder fetchFields: fields
|
||||
fetchSpecification: fs
|
||||
ignoreDeleted: NO];
|
||||
|
||||
if ([fetchResults count] == 1)
|
||||
{
|
||||
result = [fetchResults objectAtIndex: 0];
|
||||
cLastModified = [result objectForKey: @"c_lastmodified"];
|
||||
cDeleted = [result objectForKey: @"c_deleted"];
|
||||
if ([cDeleted isKindOfClass: NSNumberK] && [cDeleted intValue])
|
||||
cVersion = [NSNumber numberWithInt: -1];
|
||||
else
|
||||
cVersion = [result objectForKey: @"c_version"];
|
||||
|
||||
changeNumber = [[self context] getNewChangeNumber];
|
||||
changeNumberStr = [NSString stringWithUnsignedLongLong: changeNumber];
|
||||
|
||||
/* Create new message entry in Messages dict */
|
||||
messageEntry = [NSMutableDictionary new];
|
||||
[messages setObject: messageEntry forKey: nameInContainer];
|
||||
[messageEntry release];
|
||||
|
||||
/* Store cLastModified, cVersion and the change number */
|
||||
[messageEntry setObject: cLastModified forKey: @"c_lastmodified"];
|
||||
[messageEntry setObject: cVersion forKey: @"c_version"];
|
||||
[messageEntry setObject: changeNumberStr forKey: @"version"];
|
||||
|
||||
/* Store the change key */
|
||||
changeKey = [self getReplicaKeyFromGlobCnt: changeNumber >> 16];
|
||||
[self _setChangeKey: changeKey forMessageEntry: messageEntry];
|
||||
|
||||
/* Store the changeNumber -> cLastModified mapping */
|
||||
mapping = [currentProperties objectForKey: @"VersionMapping"];
|
||||
if (!mapping)
|
||||
{
|
||||
mapping = [NSMutableDictionary new];
|
||||
[currentProperties setObject: mapping forKey: @"VersionMapping"];
|
||||
[mapping release];
|
||||
}
|
||||
[mapping setObject: cLastModified forKey: changeNumberStr];
|
||||
|
||||
/* Save the message */
|
||||
[versionsMessage save];
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* If message entry exists, then synchroniseCache did its job */
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) updateVersionsForMessageWithKey: (NSString *) messageKey
|
||||
withChangeKey: (NSData *) oldChangeKey
|
||||
andPredecessorChangeList: (NSData *) pcl
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
{
|
||||
uint64_t version = ULLONG_MAX;
|
||||
NSString *changeNumber;
|
||||
|
||||
BOOL synced;
|
||||
|
||||
if (!isNew)
|
||||
{
|
||||
changeNumber = [(MAPIStoreGCSFolder *) container
|
||||
|
@ -189,16 +190,28 @@
|
|||
{
|
||||
[self warnWithFormat: @"attempting to get change number"
|
||||
@" by synchronising folder..."];
|
||||
[(MAPIStoreGCSFolder *) container synchroniseCache];
|
||||
changeNumber = [(MAPIStoreGCSFolder *) container
|
||||
changeNumberForMessageWithKey: [self nameInContainer]];
|
||||
|
||||
if (changeNumber)
|
||||
[self logWithFormat: @"got one"];
|
||||
else
|
||||
synced = [(MAPIStoreGCSFolder *) container synchroniseCache];
|
||||
if (synced)
|
||||
{
|
||||
[self errorWithFormat: @"still nothing. We crash!"];
|
||||
abort();
|
||||
changeNumber = [(MAPIStoreGCSFolder *) container
|
||||
changeNumberForMessageWithKey: [self nameInContainer]];
|
||||
}
|
||||
if (!changeNumber)
|
||||
{
|
||||
[self warnWithFormat: @"attempting to get change number"
|
||||
@" by synchronising this specific message..."];
|
||||
synced = [(MAPIStoreGCSFolder *) container
|
||||
synchroniseCacheFor: [self nameInContainer]];
|
||||
if (synced)
|
||||
{
|
||||
changeNumber = [(MAPIStoreGCSFolder *) container
|
||||
changeNumberForMessageWithKey: [self nameInContainer]];
|
||||
}
|
||||
if (!changeNumber)
|
||||
{
|
||||
[self errorWithFormat: @"still nothing. We crash!"];
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
version = [changeNumber unsignedLongLongValue] >> 16;
|
||||
|
|
|
@ -160,23 +160,25 @@ MakeDisplayFolderName (NSString *folderName)
|
|||
for (count = 0; count < max; count++)
|
||||
{
|
||||
context = talloc_zero (memCtx, struct mapistore_contexts_list);
|
||||
// secondaryFolders has the names (1) Imap4Encoded and (2) asCSSIdentifier
|
||||
// e.g.: Probl&AOg-mes_SP_de_SP_synchronisation
|
||||
// secondaryFolders has the names (1) Imap4Encoded ,(2) asCSSIdentifier and (3) "folder"-prefixed
|
||||
// e.g.: folderProbl&AOg-mes_SP_de_SP_synchronisation
|
||||
currentName = [secondaryFolders objectAtIndex: count];
|
||||
// To get the real name we have to revert that (applying the decode functions)
|
||||
// in reverse order
|
||||
// To get the real name we have to revert that (applying the decode functions
|
||||
// in reverse order)
|
||||
// e.g.: Problèmes de synchronisation
|
||||
realName = [[currentName fromCSSIdentifier]
|
||||
stringByDecodingImap4FolderName];
|
||||
realName = [[[currentName substringFromIndex: 6]
|
||||
fromCSSIdentifier]
|
||||
stringByDecodingImap4FolderName];
|
||||
// And finally to represent that as URI we have to (1) asCSSIdentifier,
|
||||
// (2) Imap4Encode and (3) AddPercentEscapes
|
||||
// e.g.: Probl&AOg-mes_SP_de_SP_synchronisation
|
||||
// (2) Imap4Encode (3) AddPercentEscapes and (4) add the "folder" prefix
|
||||
// e.g.: folderProbl&AOg-mes_SP_de_SP_synchronisation
|
||||
// In the example there are no percent escapes added because is already ok
|
||||
stringData = [[[realName asCSSIdentifier]
|
||||
stringByEncodingImap4FolderName]
|
||||
stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
|
||||
stringData = [NSString stringWithFormat: @"folder%@", stringData];
|
||||
context->url = [[NSString stringWithFormat: @"%@%@", urlBase, stringData] asUnicodeInMemCtx: context];
|
||||
context->name = [[realName substringFromIndex: 6] asUnicodeInMemCtx: context];
|
||||
context->name = [realName asUnicodeInMemCtx: context];
|
||||
context->main_folder = false;
|
||||
context->role = MAPISTORE_MAIL_ROLE;
|
||||
context->tag = "tag";
|
||||
|
@ -200,7 +202,7 @@ MakeDisplayFolderName (NSString *folderName)
|
|||
andTDBIndexing: NULL];
|
||||
accountFolder = [[userContext rootFolders] objectForKey: @"mail"];
|
||||
folderName = [NSString stringWithFormat: @"folder%@",
|
||||
[newFolderName asCSSIdentifier]];
|
||||
[[newFolderName stringByEncodingImap4FolderName] asCSSIdentifier]];
|
||||
newFolder = [SOGoMailFolder objectWithName: folderName
|
||||
inContainer: accountFolder];
|
||||
if ([newFolder create])
|
||||
|
@ -209,7 +211,7 @@ MakeDisplayFolderName (NSString *folderName)
|
|||
withString: @"%40"],
|
||||
[userName stringByReplacingOccurrencesOfString: @"@"
|
||||
withString: @"%40"],
|
||||
[[folderName stringByEncodingImap4FolderName] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
|
||||
[folderName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
|
||||
else
|
||||
mapistoreURI = nil;
|
||||
|
||||
|
|
|
@ -594,8 +594,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
{
|
||||
BOOL rc = YES;
|
||||
uint64_t newChangeNum;
|
||||
NSNumber *ti, *modseq, *initialLastModseq, *lastModseq,
|
||||
*nextModseq;
|
||||
NSNumber *ti, *modseq, *lastModseq, *nextModseq;
|
||||
NSString *changeNumber, *uid, *messageKey;
|
||||
uint64_t lastModseqNbr;
|
||||
EOQualifier *searchQualifier;
|
||||
|
@ -634,7 +633,6 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
}
|
||||
|
||||
lastModseq = [currentProperties objectForKey: @"SyncLastModseq"];
|
||||
initialLastModseq = lastModseq;
|
||||
if (lastModseq)
|
||||
{
|
||||
lastModseqNbr = [lastModseq unsignedLongLongValue];
|
||||
|
@ -718,40 +716,37 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
}
|
||||
|
||||
/* 2. we synchronise expunged UIDs */
|
||||
if (initialLastModseq)
|
||||
fetchResults = [(SOGoMailFolder *) sogoObject
|
||||
fetchUIDsOfVanishedItems: lastModseqNbr];
|
||||
|
||||
max = [fetchResults count];
|
||||
|
||||
changeNumber = nil;
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
fetchResults = [(SOGoMailFolder *) sogoObject
|
||||
fetchUIDsOfVanishedItems: lastModseqNbr];
|
||||
|
||||
max = [fetchResults count];
|
||||
|
||||
changeNumber = nil;
|
||||
for (count = 0; count < max; count++)
|
||||
uid = [[fetchResults objectAtIndex: count] stringValue];
|
||||
if ([messages objectForKey: uid])
|
||||
{
|
||||
uid = [[fetchResults objectAtIndex: count] stringValue];
|
||||
if ([messages objectForKey: uid])
|
||||
if (!changeNumber)
|
||||
{
|
||||
if (!changeNumber)
|
||||
{
|
||||
newChangeNum = [[self context] getNewChangeNumber];
|
||||
changeNumber = [NSString stringWithUnsignedLongLong: newChangeNum];
|
||||
}
|
||||
[messages removeObjectForKey: uid];
|
||||
[self logWithFormat: @"Removed message entry for UID %@", uid];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self logWithFormat:@"Message entry not found for UID %@", uid];
|
||||
newChangeNum = [[self context] getNewChangeNumber];
|
||||
changeNumber = [NSString stringWithUnsignedLongLong: newChangeNum];
|
||||
}
|
||||
[messages removeObjectForKey: uid];
|
||||
[self logWithFormat: @"Removed message entry for UID %@", uid];
|
||||
}
|
||||
if (changeNumber)
|
||||
else
|
||||
{
|
||||
[currentProperties setObject: changeNumber
|
||||
forKey: @"SyncLastDeleteChangeNumber"];
|
||||
[mapping setObject: lastModseq forKey: changeNumber];
|
||||
foundChange = YES;
|
||||
[self logWithFormat:@"Message entry not found for UID %@", uid];
|
||||
}
|
||||
}
|
||||
if (changeNumber)
|
||||
{
|
||||
[currentProperties setObject: changeNumber
|
||||
forKey: @"SyncLastDeleteChangeNumber"];
|
||||
[mapping setObject: lastModseq forKey: changeNumber];
|
||||
foundChange = YES;
|
||||
}
|
||||
|
||||
if (foundChange)
|
||||
{
|
||||
|
|
|
@ -1645,27 +1645,11 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
|
||||
- (enum mapistore_error) setReadFlag: (uint8_t) flag
|
||||
{
|
||||
BOOL modified = NO;
|
||||
BOOL alreadyRead = NO;
|
||||
NSString *imapFlag = @"\\Seen";
|
||||
|
||||
alreadyRead = [[[sogoObject fetchCoreInfos] objectForKey: @"flags"]
|
||||
containsObject: @"seen"];
|
||||
|
||||
/* TODO: notifications should probably be emitted from here */
|
||||
if (flag & CLEAR_READ_FLAG)
|
||||
{
|
||||
[sogoObject removeFlags: imapFlag];
|
||||
modified = alreadyRead;
|
||||
}
|
||||
[properties setObject: [NSNumber numberWithBool: NO] forKey: @"read_flag_set"];
|
||||
else
|
||||
{
|
||||
[sogoObject addFlags: imapFlag];
|
||||
modified = !alreadyRead;
|
||||
}
|
||||
|
||||
if (modified)
|
||||
[(MAPIStoreMailFolder *)[self container] synchroniseCache];
|
||||
[properties setObject: [NSNumber numberWithBool: YES] forKey: @"read_flag_set"];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -1708,7 +1692,10 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
|
||||
- (void) save: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
BOOL modified = NO;
|
||||
BOOL seen, storedSeenFlag;
|
||||
NSNumber *value;
|
||||
NSString *imapFlag = @"\\Seen";
|
||||
|
||||
value = [properties objectForKey: MAPIPropertyKey (PR_FLAG_STATUS)];
|
||||
if (value)
|
||||
|
@ -1718,8 +1705,35 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
[sogoObject addFlags: @"\\Flagged"];
|
||||
else /* 0: unflagged, 1: follow up complete */
|
||||
[sogoObject removeFlags: @"\\Flagged"];
|
||||
|
||||
modified = YES;
|
||||
}
|
||||
|
||||
/* Manage seen flag on save */
|
||||
value = [properties objectForKey: @"read_flag_set"];
|
||||
if (value)
|
||||
{
|
||||
seen = [value boolValue];
|
||||
storedSeenFlag = [[[sogoObject fetchCoreInfos] objectForKey: @"flags"] containsObject: @"seen"];
|
||||
/* We modify the flags anyway to generate a new change number */
|
||||
if (seen)
|
||||
{
|
||||
if (storedSeenFlag)
|
||||
[sogoObject removeFlags: imapFlag];
|
||||
[sogoObject addFlags: imapFlag];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!storedSeenFlag)
|
||||
[sogoObject addFlags: imapFlag];
|
||||
[sogoObject removeFlags: imapFlag];
|
||||
}
|
||||
modified = YES;
|
||||
}
|
||||
|
||||
if (modified)
|
||||
[(MAPIStoreMailFolder *)[self container] synchroniseCache];
|
||||
|
||||
if (mailIsSharingObject)
|
||||
[[self _sharingObject] saveWithMessage: self
|
||||
andSOGoObject: sogoObject];
|
||||
|
|
|
@ -167,9 +167,9 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
|
|||
|
||||
- (BOOL) hasContentId
|
||||
{
|
||||
return ([properties
|
||||
objectForKey: MAPIPropertyKey (PR_ATTACH_CONTENT_ID_UNICODE)]
|
||||
!= nil);
|
||||
NSString *contentId = [properties
|
||||
objectForKey: MAPIPropertyKey (PR_ATTACH_CONTENT_ID_UNICODE)];
|
||||
return contentId && [contentId length] > 0;
|
||||
}
|
||||
|
||||
- (NGMimeBodyPart *) asMIMEBodyPart
|
||||
|
@ -233,7 +233,7 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
|
|||
[map addObject: contentDisposition forKey: @"content-disposition"];
|
||||
contentId = [properties
|
||||
objectForKey: MAPIPropertyKey (PR_ATTACH_CONTENT_ID_UNICODE)];
|
||||
if (contentId)
|
||||
if (contentId && [contentId length] > 0)
|
||||
[map setObject: [NSString stringWithFormat: @"<%@>", contentId]
|
||||
forKey: @"content-id"];
|
||||
bodyPart = [NGMimeBodyPart bodyPartWithHeader: map];
|
||||
|
|
|
@ -268,6 +268,9 @@ def asCSSIdentifier(inputString):
|
|||
|
||||
newChars = []
|
||||
|
||||
if str.isdigit(inputString[0]):
|
||||
newChars.append("_")
|
||||
|
||||
for c in inputString:
|
||||
if c in cssEscapingCharMap:
|
||||
newChars.append(cssEscapingCharMap[c])
|
||||
|
|
|
@ -1013,7 +1013,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
{
|
||||
if ([dateRange containsDate: [component startDate]])
|
||||
{
|
||||
// We must pass nill to :container here in order to avoid re-entrancy issues.
|
||||
// We must pass nil to :container here in order to avoid re-entrancy issues.
|
||||
newRecord = [self _fixupRecord: [component quickRecordFromContent: nil container: nil]];
|
||||
[ma replaceObjectAtIndex: recordIndex withObject: newRecord];
|
||||
}
|
||||
|
@ -1030,15 +1030,20 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
{
|
||||
// The recurrence id of the exception is outside the date range;
|
||||
// simply add the exception to the records array.
|
||||
// We must pass nill to :container here in order to avoid re-entrancy issues.
|
||||
// We must pass nil to :container here in order to avoid re-entrancy issues.
|
||||
newRecord = [self _fixupRecord: [component quickRecordFromContent: nil container: nil]];
|
||||
newRecordRange = [NGCalendarDateRange
|
||||
calendarDateRangeWithStartDate: [newRecord objectForKey: @"startDate"]
|
||||
endDate: [newRecord objectForKey: @"endDate"]];
|
||||
if ([dateRange doesIntersectWithDateRange: newRecordRange])
|
||||
if ([newRecord objectForKey: @"startDate"] && [newRecord objectForKey: @"endDate"]) {
|
||||
newRecordRange = [NGCalendarDateRange
|
||||
calendarDateRangeWithStartDate: [newRecord objectForKey: @"startDate"]
|
||||
endDate: [newRecord objectForKey: @"endDate"]];
|
||||
if ([dateRange doesIntersectWithDateRange: newRecordRange])
|
||||
[ma addObject: newRecord];
|
||||
else
|
||||
else
|
||||
newRecord = nil;
|
||||
} else {
|
||||
[self warnWithFormat: @"Recurrence %@ without dtstart or dtend. Ignoring", recurrenceId];
|
||||
newRecord = nil;
|
||||
}
|
||||
}
|
||||
|
||||
if (newRecord)
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <SOGo/SOGoSource.h>
|
||||
#import <SOGo/SOGoUserSettings.h>
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
#import <SOGo/WORequest+SOGo.h>
|
||||
#import <SOGo/WOResponse+SOGo.h>
|
||||
|
||||
|
@ -248,6 +249,13 @@
|
|||
data = @"";
|
||||
[newRecord setObject: data forKey: @"c_cn"];
|
||||
|
||||
if ([[SOGoSystemDefaults sharedSystemDefaults] enableDomainBasedUID])
|
||||
{
|
||||
data = [oldRecord objectForKey: @"c_domain"];
|
||||
if (data)
|
||||
[newRecord setObject: data forKey: @"c_domain"];
|
||||
}
|
||||
|
||||
// mail => emails[]
|
||||
data = [oldRecord objectForKey: @"c_emails"];
|
||||
if (data)
|
||||
|
|
|
@ -206,8 +206,8 @@ static NSString *inboxFolderName = @"INBOX";
|
|||
[folders removeObjectsInArray: nss];
|
||||
}
|
||||
|
||||
return [[folders stringsWithFormat: @"folder%@"]
|
||||
resultsOfSelector: @selector (asCSSIdentifier)];
|
||||
return [[folders resultsOfSelector: @selector (asCSSIdentifier)]
|
||||
stringsWithFormat: @"folder%@"];
|
||||
}
|
||||
|
||||
- (NSArray *) toManyRelationshipKeys
|
||||
|
|
|
@ -199,9 +199,9 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
{
|
||||
NSArray *subfolders;
|
||||
|
||||
subfolders = [[self subfolders] stringsWithFormat: @"folder%@"];
|
||||
subfolders = [[self subfolders] resultsOfSelector: @selector (asCSSIdentifier)];
|
||||
|
||||
return [subfolders resultsOfSelector: @selector (asCSSIdentifier)];
|
||||
return [subfolders stringsWithFormat: @"folder%@"];
|
||||
}
|
||||
|
||||
- (NSArray *) subfolders
|
||||
|
@ -634,7 +634,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
inContext: (id) localContext
|
||||
{
|
||||
NSArray *folders;
|
||||
NSString *currentFolderName, *currentAccountName;
|
||||
NSString *currentFolderName, *currentAccountName, *destinationAccountName;
|
||||
NSMutableString *imapDestinationFolder;
|
||||
NGImap4Client *client;
|
||||
id result;
|
||||
|
@ -642,24 +642,24 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
|
||||
#warning this code will fail on implementation using something else than '/' as delimiter
|
||||
imapDestinationFolder = [NSMutableString string];
|
||||
folders = [[destinationFolder componentsSeparatedByString: @"/"]
|
||||
resultsOfSelector: @selector (fromCSSIdentifier)];
|
||||
folders = [destinationFolder componentsSeparatedByString: @"/"];
|
||||
max = [folders count];
|
||||
if (max > 1)
|
||||
{
|
||||
currentAccountName = [[self mailAccountFolder] nameInContainer];
|
||||
client = [[self imap4Connection] client];
|
||||
[imap4 selectFolder: [self imap4URL]];
|
||||
destinationAccountName = [[folders objectAtIndex: 1] fromCSSIdentifier];
|
||||
|
||||
for (count = 2; count < max; count++)
|
||||
{
|
||||
currentFolderName = [[folders objectAtIndex: count] substringFromIndex: 6];
|
||||
currentFolderName = [[[folders objectAtIndex: count] substringFromIndex: 6] fromCSSIdentifier];
|
||||
[imapDestinationFolder appendFormat: @"/%@", currentFolderName];
|
||||
}
|
||||
|
||||
if (client)
|
||||
{
|
||||
if ([[folders objectAtIndex: 1] isEqualToString: currentAccountName])
|
||||
if ([destinationAccountName isEqualToString: currentAccountName])
|
||||
{
|
||||
// We make sure the destination IMAP folder exist, if not, we create it.
|
||||
result = [[client status: imapDestinationFolder
|
||||
|
@ -688,7 +688,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
|
||||
userFolder = [[context activeUser] homeFolderInContext: context];
|
||||
accounts = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
|
||||
account = [accounts lookupName: [folders objectAtIndex: 1] inContext: localContext acquire: NO];
|
||||
account = [accounts lookupName: destinationAccountName inContext: localContext acquire: NO];
|
||||
|
||||
if ([account isKindOfClass: [NSException class]])
|
||||
{
|
||||
|
|
|
@ -156,7 +156,7 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
newKeyForMsgUIDs = [[NSString stringWithFormat:@"/%@/folder%@", currentAccount, newFolderName] asCSSIdentifier];
|
||||
newKeyForMsgUIDs = [NSString stringWithFormat:@"/%@/folder%@", [currentAccount asCSSIdentifier], [newFolderName asCSSIdentifier]];
|
||||
error = [co renameTo: newFolderName];
|
||||
if (error)
|
||||
{
|
||||
|
|
|
@ -726,8 +726,8 @@
|
|||
|
||||
for (k = 0; k < [pathComponents count]; k++)
|
||||
{
|
||||
component = [NSString stringWithFormat: @"folder%@", [pathComponents objectAtIndex: k]];
|
||||
[path appendString: [component asCSSIdentifier]];
|
||||
component = [[pathComponents objectAtIndex: k] asCSSIdentifier];
|
||||
[path appendString: [NSString stringWithFormat: @"folder%@", component]];
|
||||
if (k < [pathComponents count] - 1)
|
||||
[path appendString: @"/"];
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@
|
|||
|
||||
/* Searching */
|
||||
|
||||
"view_all" = "Todos los eventos";
|
||||
"view_all" = "Todos";
|
||||
"view_today" = "Hoy";
|
||||
"view_next7" = "Próximos 7 días";
|
||||
"view_next14" = "Próximos 14 días";
|
||||
|
|
Loading…
Reference in New Issue