diff --git a/OpenChange/MAPIStoreDBMessage.m b/OpenChange/MAPIStoreDBMessage.m index 7c208b2f8..bb5acbb57 100644 --- a/OpenChange/MAPIStoreDBMessage.m +++ b/OpenChange/MAPIStoreDBMessage.m @@ -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 { diff --git a/OpenChange/MAPIStoreGCSFolder.h b/OpenChange/MAPIStoreGCSFolder.h index ecf9cee18..de2b9692b 100644 --- a/OpenChange/MAPIStoreGCSFolder.h +++ b/OpenChange/MAPIStoreGCSFolder.h @@ -41,6 +41,7 @@ /* synchronisation */ - (BOOL) synchroniseCache; +- (BOOL) synchroniseCacheFor: (NSString *) nameInContainer; - (void) updateVersionsForMessageWithKey: (NSString *) messageKey withChangeKey: (NSData *) oldChangeKey andPredecessorChangeList: (NSData *) pcl; diff --git a/OpenChange/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m index 8781ef22b..2dacdb4cf 100644 --- a/OpenChange/MAPIStoreGCSFolder.m +++ b/OpenChange/MAPIStoreGCSFolder.m @@ -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 diff --git a/OpenChange/MAPIStoreGCSMessage.m b/OpenChange/MAPIStoreGCSMessage.m index 747bb783a..2f7afeada 100644 --- a/OpenChange/MAPIStoreGCSMessage.m +++ b/OpenChange/MAPIStoreGCSMessage.m @@ -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; diff --git a/OpenChange/MAPIStoreMailContext.m b/OpenChange/MAPIStoreMailContext.m index 7ec79ad50..c1f39565f 100644 --- a/OpenChange/MAPIStoreMailContext.m +++ b/OpenChange/MAPIStoreMailContext.m @@ -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; diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 9373bb0e5..7c8e4f8ac 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -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) { diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m index 7ae2bd1d9..55ad92bd0 100644 --- a/OpenChange/MAPIStoreMailMessage.m +++ b/OpenChange/MAPIStoreMailMessage.m @@ -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]; diff --git a/OpenChange/MAPIStoreMailVolatileMessage.m b/OpenChange/MAPIStoreMailVolatileMessage.m index 8a7ba2c58..d6154c8e8 100644 --- a/OpenChange/MAPIStoreMailVolatileMessage.m +++ b/OpenChange/MAPIStoreMailVolatileMessage.m @@ -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]; diff --git a/Scripts/openchange_user_cleanup b/Scripts/openchange_user_cleanup index e67289480..93a91c8ea 100755 --- a/Scripts/openchange_user_cleanup +++ b/Scripts/openchange_user_cleanup @@ -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]) diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 9b465655f..c85e79eb2 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -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) diff --git a/SoObjects/Contacts/SOGoContactSourceFolder.m b/SoObjects/Contacts/SOGoContactSourceFolder.m index 6aad3e625..829aad15a 100644 --- a/SoObjects/Contacts/SOGoContactSourceFolder.m +++ b/SoObjects/Contacts/SOGoContactSourceFolder.m @@ -48,6 +48,7 @@ #import #import #import +#import #import #import @@ -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) diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index 6216ee2c7..286d695c4 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -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 diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m index 2fe050107..f9ba2f3c2 100644 --- a/SoObjects/Mailer/SOGoMailFolder.m +++ b/SoObjects/Mailer/SOGoMailFolder.m @@ -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]]) { diff --git a/UI/MailerUI/UIxMailFolderActions.m b/UI/MailerUI/UIxMailFolderActions.m index e3edf3873..9ed02d74a 100644 --- a/UI/MailerUI/UIxMailFolderActions.m +++ b/UI/MailerUI/UIxMailFolderActions.m @@ -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) { diff --git a/UI/MailerUI/UIxMailMainFrame.m b/UI/MailerUI/UIxMailMainFrame.m index 848b2e57c..bc5d6930f 100644 --- a/UI/MailerUI/UIxMailMainFrame.m +++ b/UI/MailerUI/UIxMailMainFrame.m @@ -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: @"/"]; } diff --git a/UI/Scheduler/SpanishSpain.lproj/Localizable.strings b/UI/Scheduler/SpanishSpain.lproj/Localizable.strings index 99397e321..aed9f2908 100644 --- a/UI/Scheduler/SpanishSpain.lproj/Localizable.strings +++ b/UI/Scheduler/SpanishSpain.lproj/Localizable.strings @@ -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";