From 76307cfaafd886f053b4f5f6436f1412f7148c83 Mon Sep 17 00:00:00 2001 From: Alexandre Cloutier Date: Mon, 24 Mar 2014 13:41:57 -0400 Subject: [PATCH 1/6] New feature : 1496; Unknown outgoing email addresses can now be automatically be added to your address books. --- .../English.lproj/Localizable.strings | 1 + SoObjects/Contacts/SOGoContactFolders.h | 8 + SoObjects/Contacts/SOGoContactFolders.m | 193 +++++++++++++++++- SoObjects/Mailer/SOGoDraftObject.h | 2 + SoObjects/Mailer/SOGoDraftObject.m | 73 ++++++- SoObjects/SOGo/SOGoDefaults.plist | 1 + SoObjects/SOGo/SOGoParentFolder.m | 31 +-- SoObjects/SOGo/SOGoUserDefaults.h | 6 + SoObjects/SOGo/SOGoUserDefaults.m | 25 ++- UI/Contacts/UIxContactFoldersView.m | 83 +------- .../English.lproj/Localizable.strings | 2 + UI/PreferencesUI/UIxPreferences.m | 64 ++++++ UI/Templates/PreferencesUI/UIxPreferences.wox | 10 + 13 files changed, 405 insertions(+), 94 deletions(-) diff --git a/SoObjects/Contacts/English.lproj/Localizable.strings b/SoObjects/Contacts/English.lproj/Localizable.strings index 56404b013..0d040749c 100644 --- a/SoObjects/Contacts/English.lproj/Localizable.strings +++ b/SoObjects/Contacts/English.lproj/Localizable.strings @@ -1 +1,2 @@ "Personal Address Book" = "Personal Address Book"; +"Collected Address Book" = "Collected Address Book"; diff --git a/SoObjects/Contacts/SOGoContactFolders.h b/SoObjects/Contacts/SOGoContactFolders.h index 1b685c85b..584fab024 100644 --- a/SoObjects/Contacts/SOGoContactFolders.h +++ b/SoObjects/Contacts/SOGoContactFolders.h @@ -25,12 +25,20 @@ @interface SOGoContactFolders : SOGoParentFolder +- (NSString *) defaultFolderName; +- (NSString *) collectedFolderName; + +- (NSException *) appendCollectedSources; - (NSException *) renameLDAPAddressBook: (NSString *) sourceID withDisplayName: (NSString *) newDisplayName; - (NSException *) removeLDAPAddressBook: (NSString *) sourceID; - (NSDictionary *) systemSources; +- (NSArray *) allContactsFromFilter: (NSString *) theFilter + excludeGroups: (BOOL) excludeGroups + excludeLists: (BOOL) excludeLists; + @end #endif /* SOGOCONTACTFOLDERS_H */ diff --git a/SoObjects/Contacts/SOGoContactFolders.m b/SoObjects/Contacts/SOGoContactFolders.m index 3c3e938f0..183d47e32 100644 --- a/SoObjects/Contacts/SOGoContactFolders.m +++ b/SoObjects/Contacts/SOGoContactFolders.m @@ -22,12 +22,18 @@ #import #import #import +#import #import #import #import #import +#import +#import +#import +#import + #import #import #import @@ -40,10 +46,17 @@ #import "SOGoContactFolders.h" +Class SOGoContactSourceFolderK; + #define XMLNS_INVERSEDAV @"urn:inverse:params:xml:ns:inverse-dav" @implementation SOGoContactFolders ++ (void) initialize +{ + SOGoContactSourceFolderK = [SOGoContactSourceFolder class]; +} + + (NSString *) gcsFolderType { return @"Contact"; @@ -110,6 +123,92 @@ return result; } +- (void) _createCollectedFolder +{ + NSArray *roles; + SOGoGCSFolder *folder; + SOGoUser *folderOwner; + + roles = [[context activeUser] rolesForObject: self inContext: context]; + folderOwner = [SOGoUser userWithLogin: [self ownerInContext: context]]; + + if (folderOwner && [folderOwner isResource]) + { + folder = [subFolderClass objectWithName: @"collected" inContainer: self]; + [folder setDisplayName: [self collectedFolderName]]; + [folder setOCSPath: [NSString stringWithFormat: @"%@/collected", OCSPath]]; + if ([folder create]) + [subFolders setObject: folder forKey: @"collected"]; + } +} + +- (NSException *) _fetchCollectedFolders: (NSString *) sql + withChannel: (EOAdaptorChannel *) fc +{ + NSArray *attrs; + NSDictionary *row; + SOGoGCSFolder *folder; + NSString *key; + NSException *error; + + if (!subFolderClass) + subFolderClass = [[self class] subFolderClass]; + + error = [fc evaluateExpressionX: sql]; + if (!error) + { + attrs = [fc describeResults: NO]; + while ((row = [fc fetchAttributes: attrs withZone: NULL])) + { + key = [row objectForKey: @"c_path4"]; + if ([key isKindOfClass: [NSString class]]) + { + folder = [subFolderClass objectWithName: key inContainer: self]; + [folder setOCSPath: [NSString stringWithFormat: @"%@/%@", + OCSPath, key]]; + [subFolders setObject: folder forKey: key]; + } + } + + if (![subFolders objectForKey: @"collected"]) + [self _createCollectedFolder]; + } + + return error; +} + +- (NSException *) appendCollectedSources +{ + GCSChannelManager *cm; + EOAdaptorChannel *fc; + NSURL *folderLocation; + NSString *sql, *gcsFolderType; + NSException *error; + + cm = [GCSChannelManager defaultChannelManager]; + folderLocation = [[GCSFolderManager defaultFolderManager] folderInfoLocation]; + fc = [cm acquireOpenChannelForURL: folderLocation]; + if ([fc isOpen]) + { + gcsFolderType = [[self class] gcsFolderType]; + + sql = [NSString stringWithFormat: (@"SELECT c_path4 FROM %@" + @" WHERE c_path2 = '%@'" + @" AND c_folder_type = '%@'"), + [folderLocation gcsTableName], + owner, + gcsFolderType]; + error = [self _fetchCollectedFolders: sql withChannel: fc]; + [cm releaseChannel: fc]; + } + else + error = [NSException exceptionWithName: @"SOGoDBException" + reason: @"database connection could not be open" + userInfo: nil]; + + return error; +} + - (NSDictionary *) systemSources { NSMutableDictionary *systemSources; @@ -223,9 +322,9 @@ SOGoUser *currentUser; id source; - if ([sourceID isEqualToString: @"personal"]) + if ([sourceID isEqualToString: @"personal"] || [sourceID isEqualToString: @"collected"]) result = [NSException exceptionWithHTTPStatus: 403 - reason: @"folder 'personal' cannot be deleted"]; + reason: (@"folder '%@' cannot be deleted", sourceID)]; else { result = nil; @@ -250,6 +349,11 @@ return [self labelForKey: @"Personal Address Book"]; } +- (NSString *) collectedFolderName +{ + return [self labelForKey: @"Collected Address Book"]; +} + - (NSArray *) toManyRelationshipKeys { NSMutableArray *keys; @@ -371,4 +475,89 @@ asWebDAVValue]; } +- (NSArray *) allContactsFromFilter: (NSString *) theFilter + excludeGroups: (BOOL) excludeGroups + excludeLists: (BOOL) excludeLists +{ + SOGoFolder *folder; + NSString *mail, *domain; + NSArray *folders, *contacts, *descriptors, *sortedContacts; + NSMutableArray *sortedFolders; + NSMutableDictionary *contact, *uniqueContacts; + unsigned int i, j, max; + NSSortDescriptor *commonNameDescriptor; + + // NSLog(@"Search all contacts: %@", searchText); + + domain = [[context activeUser] domain]; + folders = nil; + NS_DURING + folders = [self subFolders]; + NS_HANDLER + /* We need to specifically test for @"SOGoDBException", which is + raised explicitly in SOGoParentFolder. Any other exception should + be re-raised. */ + if ([[localException name] isEqualToString: @"SOGoDBException"]) + folders = nil; + else + [localException raise]; + NS_ENDHANDLER; + max = [folders count]; + sortedFolders = [NSMutableArray arrayWithCapacity: max]; + uniqueContacts = [NSMutableDictionary dictionary]; + for (i = 0; i < max; i++) + { + folder = [folders objectAtIndex: i]; + /* We first search in LDAP folders (in case of duplicated entries in GCS folders) */ + if ([folder isKindOfClass: SOGoContactSourceFolderK]) + [sortedFolders insertObject: folder atIndex: 0]; + else + [sortedFolders addObject: folder]; + } + for (i = 0; i < max; i++) + { + folder = [sortedFolders objectAtIndex: i]; + //NSLog(@" Address book: %@ (%@)", [folder displayName], [folder class]); + contacts = [folder lookupContactsWithFilter: theFilter + onCriteria: @"name_or_address" + sortBy: @"c_cn" + ordering: NSOrderedAscending + inDomain: domain]; + for (j = 0; j < [contacts count]; j++) + { + contact = [contacts objectAtIndex: j]; + mail = [contact objectForKey: @"c_mail"]; + //NSLog(@" found %@ (%@) ? %@", [contact objectForKey: @"c_name"], mail, + // [contact description]); + if (!excludeLists && [[contact objectForKey: @"c_component"] + isEqualToString: @"vlist"]) + { + [contact setObject: [folder nameInContainer] + forKey: @"container"]; + [uniqueContacts setObject: contact + forKey: [contact objectForKey: @"c_name"]]; + } + else if ([mail length] + && [uniqueContacts objectForKey: mail] == nil + && !(excludeGroups && [contact objectForKey: @"isGroup"])) + [uniqueContacts setObject: contact forKey: mail]; + } + } + if ([uniqueContacts count] > 0) + { + // Sort the contacts by display name + commonNameDescriptor = [[NSSortDescriptor alloc] initWithKey: @"c_cn" + ascending:YES]; + descriptors = [NSArray arrayWithObjects: commonNameDescriptor, nil]; + [commonNameDescriptor release]; + sortedContacts = [[uniqueContacts allValues] + sortedArrayUsingDescriptors: descriptors]; + } + else + sortedContacts = [NSArray array]; + + return sortedContacts; +} + + @end diff --git a/SoObjects/Mailer/SOGoDraftObject.h b/SoObjects/Mailer/SOGoDraftObject.h index 94c5d2888..4004d32a9 100644 --- a/SoObjects/Mailer/SOGoDraftObject.h +++ b/SoObjects/Mailer/SOGoDraftObject.h @@ -102,6 +102,8 @@ - (NSData *) mimeMessageAsData; /* operations */ +- (NSArray *) allRecipients; +- (NSArray *) allBareRecipients; - (NSException *) delete; - (NSException *) sendMail; diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index bd5a0d469..9c6b0a120 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -45,6 +45,7 @@ #import #import #import +#import #import #import #import @@ -63,6 +64,11 @@ #import #import +#import + +#import +#import + #import "NSData+Mail.h" #import "NSString+Mail.h" #import "SOGoMailAccount.h" @@ -1660,7 +1666,7 @@ static NSString *userAgent = nil; { recipients = [headers objectForKey: fieldNames[count]]; if ([recipients count] > 0) - [allRecipients addObjectsFromArray: recipients]; + [allRecipients addObjectsFromArray: recipients]; } return allRecipients; @@ -1689,6 +1695,71 @@ static NSString *userAgent = nil; // - (NSException *) sendMail { + SOGoUserDefaults *ud; + ud = [[context activeUser] userDefaults]; + + if ([ud mailAddOutgoingAddresses]) { + NSMutableArray *recipients; + SOGoMailAccounts *folder; + NGMailAddressParser *parser; + SOGoContactFolders *contactFolders; + NSArray *contacts; + NSString *address, *mail, *name; + int i; + id parsedAddress; + + contactFolders = [[[context activeUser] homeFolderInContext: context] + lookupName: @"Contacts" + inContext: context + acquire: NO]; + + recipients = [self allRecipients]; + + for (i = 0; i < [recipients count]; i++) + { + // The address contains a string. ex: "John Doe " + address = [recipients objectAtIndex: i]; + + parser = [NGMailAddressParser mailAddressParserWithString: address]; + parsedAddress = [parser parse]; + + mail = [parsedAddress address]; + name = [parsedAddress displayName]; + + contacts = [contactFolders allContactsFromFilter: mail + excludeGroups: YES + excludeLists: YES]; + + // If we don't get any results from the autocompletion code, we add it.. + if ([contacts count] == 0) + { + SOGoContactFolder *folder; + Class c; + SOGoContactGCSEntry *contact; + NSString *uid; + NGVCard *card; + + /* Here I want the selected address book on the preferences. */ + NSString *addressBook; + addressBook = [ud selectedAddressBook]; + + folder = [contactFolders lookupName: addressBook inContext: context acquire: NO]; + uid = [folder globallyUniqueObjectId]; + + card = [NGVCard cardWithUid: uid]; + [card addEmail: mail types: nil]; + + c = NSClassFromString(@"SOGoContactGCSEntry"); + contact = [c objectWithName: uid + inContainer: folder]; + [contact setIsNew: YES]; + + [contact saveContentString: [card versitString]]; + + } + } + } + return [self sendMailAndCopyToSent: YES]; } diff --git a/SoObjects/SOGo/SOGoDefaults.plist b/SoObjects/SOGo/SOGoDefaults.plist index f9bb2fef0..5f13a4a70 100644 --- a/SoObjects/SOGo/SOGoDefaults.plist +++ b/SoObjects/SOGo/SOGoDefaults.plist @@ -52,6 +52,7 @@ SOGoIMAPServer = "localhost"; SOGoMailDomain = "localhost"; + SOGoSelectedAddressBook = "collected"; SOGoMailMessageCheck = "manually"; SOGoMailMessageForwarding = "inline"; SOGoMailReplyPlacement = "below"; diff --git a/SoObjects/SOGo/SOGoParentFolder.m b/SoObjects/SOGo/SOGoParentFolder.m index da5a1c5b5..330a186eb 100644 --- a/SoObjects/SOGo/SOGoParentFolder.m +++ b/SoObjects/SOGo/SOGoParentFolder.m @@ -221,20 +221,17 @@ static SoSecurityManager *sm = nil; NSException *error; cm = [GCSChannelManager defaultChannelManager]; - folderLocation - = [[GCSFolderManager defaultFolderManager] folderInfoLocation]; + folderLocation = [[GCSFolderManager defaultFolderManager] folderInfoLocation]; fc = [cm acquireOpenChannelForURL: folderLocation]; if ([fc isOpen]) { gcsFolderType = [[self class] gcsFolderType]; - sql - = [NSString stringWithFormat: (@"SELECT c_path4 FROM %@" - @" WHERE c_path2 = '%@'" - @" AND c_folder_type = '%@'"), - [folderLocation gcsTableName], - owner, - gcsFolderType]; + sql = [NSString stringWithFormat: (@"SELECT c_path4 FROM %@" + @" WHERE c_path2 = '%@'" + @" AND c_folder_type = '%@'"), + [folderLocation gcsTableName], owner, gcsFolderType]; + error = [self _fetchPersonalFolders: sql withChannel: fc]; [cm releaseChannel: fc]; // sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'", @@ -248,6 +245,7 @@ static SoSecurityManager *sm = nil; return error; } + - (NSException *) appendSystemSources { return nil; @@ -386,14 +384,17 @@ static SoSecurityManager *sm = nil; if (!subFolders) { subFolders = [NSMutableDictionary new]; - error = [self appendPersonalSources]; + error = [self appendPersonalSources]; if (!error) - error = [self appendSystemSources]; + if ([self respondsToSelector:@selector(appendCollectedSources)]) + error = [self appendCollectedSources]; + if (!error) + error = [self appendSystemSources]; // TODO : Not really a testcase, see function if (error) - { - [subFolders release]; - subFolders = nil; - } + { + [subFolders release]; + subFolders = nil; + } } else error = nil; diff --git a/SoObjects/SOGo/SOGoUserDefaults.h b/SoObjects/SOGo/SOGoUserDefaults.h index 83d6c18bb..b8df5621b 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.h +++ b/SoObjects/SOGo/SOGoUserDefaults.h @@ -87,6 +87,9 @@ extern NSString *SOGoWeekStartFirstFullWeek; - (NSString *) language; /* mail */ +- (void) setMailAddOutgoingAddresses: (BOOL) newValue; +- (BOOL) mailAddOutgoingAddresses; + - (void) setMailShowSubscribedFoldersOnly: (BOOL) newValue; - (BOOL) mailShowSubscribedFoldersOnly; @@ -111,6 +114,9 @@ extern NSString *SOGoWeekStartFirstFullWeek; - (void) setMailListViewColumnsOrder: (NSArray *) newValue; - (NSArray *) mailListViewColumnsOrder; +- (void) setSelectedAddressBook: (NSString *) newValue; +- (NSString *) selectedAddressBook; + - (void) setMailMessageCheck: (NSString *) newValue; - (NSString *) mailMessageCheck; diff --git a/SoObjects/SOGo/SOGoUserDefaults.m b/SoObjects/SOGo/SOGoUserDefaults.m index b862c5523..d6d1c3999 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.m +++ b/SoObjects/SOGo/SOGoUserDefaults.m @@ -185,8 +185,8 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; { migratedKeys = [NSDictionary dictionaryWithObjectsAndKeys: - @"SOGoLoginModule", @"SOGoUIxDefaultModule", - @"SOGoLoginModule", @"SOGoDefaultModule", + @"SOGoLoginModule", @"SOGoUIxDefaultModule", + @"SOGoLoginModule", @"SOGoDefaultModule", @"SOGoTimeFormat", @"TimeFormat", @"SOGoShortDateFormat", @"ShortDateFormat", @"SOGoLongDateFormat", @"LongDateFormat", @@ -197,6 +197,7 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; @"SOGoLanguage", @"SOGoDefaultLanguage", @"SOGoLanguage", @"Language", @"SOGoMailComposeMessageType", @"ComposeMessagesType", + @"SOGoSelectedAddressBook", @"SelectedAddressBook", @"SOGoMailMessageCheck", @"MessageCheck", @"SOGoMailMessageForwarding", @"MessageForwarding", @"SOGoMailSignature", @"MailSignature", @@ -384,6 +385,16 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; return userLanguage; } +- (void) setMailAddOutgoingAddresses: (BOOL) newValue +{ + [self setBool: newValue forKey: @"SOGoMailAddOutgoingAddresses"]; +} + +- (BOOL) mailAddOutgoingAddresses +{ + return [self boolForKey: @"SOGoMailAddOutgoingAddresses"]; +} + - (void) setMailShowSubscribedFoldersOnly: (BOOL) newValue { [self setBool: newValue forKey: @"SOGoMailShowSubscribedFoldersOnly"]; @@ -467,6 +478,16 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; return [self stringArrayForKey: @"SOGoMailListViewColumnsOrder"]; } +- (void) setSelectedAddressBook:(NSString *) newValue +{ + [self setObject: newValue forKey: @"SOGoSelectedAddressBook"]; +} + +- (NSString *) selectedAddressBook +{ + return [self stringForKey: @"SOGoSelectedAddressBook"]; +} + - (void) setMailMessageCheck: (NSString *) newValue { [self setObject: newValue forKey: @"SOGoMailMessageCheck"]; diff --git a/UI/Contacts/UIxContactFoldersView.m b/UI/Contacts/UIxContactFoldersView.m index f38a3532f..aaf35d6c2 100644 --- a/UI/Contacts/UIxContactFoldersView.m +++ b/UI/Contacts/UIxContactFoldersView.m @@ -158,88 +158,23 @@ Class SOGoContactSourceFolderK, SOGoGCSFolderK; - (id ) allContactSearchAction { id result; - SOGoFolder *folder; - NSString *searchText, *mail, *domain; + NSString *searchText; NSDictionary *data; - NSArray *folders, *contacts, *descriptors, *sortedContacts; - NSMutableArray *sortedFolders; - NSMutableDictionary *contact, *uniqueContacts; - unsigned int i, j, max; - NSSortDescriptor *commonNameDescriptor; + NSArray *sortedContacts; + BOOL excludeGroups, excludeLists; searchText = [self queryParameterForKey: @"search"]; if ([searchText length] > 0) { - // NSLog(@"Search all contacts: %@", searchText); excludeGroups = [[self queryParameterForKey: @"excludeGroups"] boolValue]; excludeLists = [[self queryParameterForKey: @"excludeLists"] boolValue]; - domain = [[context activeUser] domain]; - folders = nil; - NS_DURING - folders = [[self clientObject] subFolders]; - NS_HANDLER - /* We need to specifically test for @"SOGoDBException", which is - raised explicitly in SOGoParentFolder. Any other exception should - be re-raised. */ - if ([[localException name] isEqualToString: @"SOGoDBException"]) - folders = nil; - else - [localException raise]; - NS_ENDHANDLER; - max = [folders count]; - sortedFolders = [NSMutableArray arrayWithCapacity: max]; - uniqueContacts = [NSMutableDictionary dictionary]; - for (i = 0; i < max; i++) - { - folder = [folders objectAtIndex: i]; - /* We first search in LDAP folders (in case of duplicated entries in GCS folders) */ - if ([folder isKindOfClass: SOGoContactSourceFolderK]) - [sortedFolders insertObject: folder atIndex: 0]; - else - [sortedFolders addObject: folder]; - } - for (i = 0; i < max; i++) - { - folder = [sortedFolders objectAtIndex: i]; - //NSLog(@" Address book: %@ (%@)", [folder displayName], [folder class]); - contacts = [folder lookupContactsWithFilter: searchText - onCriteria: @"name_or_address" - sortBy: @"c_cn" - ordering: NSOrderedAscending - inDomain: domain]; - for (j = 0; j < [contacts count]; j++) - { - contact = [contacts objectAtIndex: j]; - mail = [contact objectForKey: @"c_mail"]; - //NSLog(@" found %@ (%@) ? %@", [contact objectForKey: @"c_name"], mail, - // [contact description]); - if (!excludeLists && [[contact objectForKey: @"c_component"] - isEqualToString: @"vlist"]) - { - [contact setObject: [folder nameInContainer] - forKey: @"container"]; - [uniqueContacts setObject: contact - forKey: [contact objectForKey: @"c_name"]]; - } - else if ([mail length] - && [uniqueContacts objectForKey: mail] == nil - && !(excludeGroups && [contact objectForKey: @"isGroup"])) - [uniqueContacts setObject: contact forKey: mail]; - } - } - if ([uniqueContacts count] > 0) - { - // Sort the contacts by display name - commonNameDescriptor = [[NSSortDescriptor alloc] initWithKey: @"c_cn" - ascending:YES]; - descriptors = [NSArray arrayWithObjects: commonNameDescriptor, nil]; - [commonNameDescriptor release]; - sortedContacts = [[uniqueContacts allValues] - sortedArrayUsingDescriptors: descriptors]; - } - else - sortedContacts = [NSArray array]; + + sortedContacts = [[self clientObject] allContactsFromFilter: searchText + excludeGroups: excludeGroups + excludeLists: excludeLists]; + + data = [NSDictionary dictionaryWithObjectsAndKeys: searchText, @"searchText", sortedContacts, @"contacts", nil]; diff --git a/UI/PreferencesUI/English.lproj/Localizable.strings b/UI/PreferencesUI/English.lproj/Localizable.strings index afa832c3e..cc5afde74 100644 --- a/UI/PreferencesUI/English.lproj/Localizable.strings +++ b/UI/PreferencesUI/English.lproj/Localizable.strings @@ -139,6 +139,8 @@ "messagecheck_every_20_minutes" = "Every 20 minutes"; "messagecheck_every_30_minutes" = "Every 30 minutes"; "messagecheck_once_per_hour" = "Once per hour"; +"PersonalAddressBook" = "Personal address book"; +"CollectedAddressBook" = "Collected addresses"; "Forward messages:" = "Forward messages:"; "messageforward_inline" = "Inline"; diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index 7ba612cac..92a813061 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -50,6 +50,8 @@ #import #import +#import + #import "UIxPreferences.h" #warning this class is not finished @@ -656,6 +658,16 @@ static NSArray *reminderValues = nil; } /* Mailer */ +- (void) setAddOutgoingAddresses: (BOOL) addOutgoingAddresses +{ + [userDefaults setMailAddOutgoingAddresses: addOutgoingAddresses]; +} + +- (BOOL) addOutgoingAddresses +{ + return [userDefaults mailAddOutgoingAddresses]; +} + - (void) setShowSubscribedFoldersOnly: (BOOL) showSubscribedFoldersOnly { [userDefaults setMailShowSubscribedFoldersOnly: showSubscribedFoldersOnly]; @@ -676,6 +688,58 @@ static NSArray *reminderValues = nil; return [userDefaults mailSortByThreads]; } +- (NSArray *) addressBookList +{ + /* We want all the SourceIDS */ + NSMutableArray *folders; + NSMutableArray *contactFolders; + + contactFolders = [[[context activeUser] homeFolderInContext: context] + lookupName: @"Contacts" + inContext: context + acquire: NO]; + + folders = [NSMutableArray arrayWithArray: [contactFolders subFolders]]; + + int i, count; + + count = [folders count]-1; + + // Inside this loop we remove all the public or shared addressbooks + for (count; count >= 0; count--) + { + if (![[folders objectAtIndex: count] isKindOfClass: [SOGoContactGCSFolder class]]) + [folders removeObjectAtIndex: count]; + } + + // Parse the objects in order to have only the displayName of the addressbooks to be displayed on the preferences interface + NSMutableArray *availableAddressBooks = [NSMutableArray new]; + NSMutableArray *availableAddressBooksName = [NSMutableArray new]; + + count = [folders count]-1; + for (i=0; i <= count ; i++) { + [availableAddressBooks addObject:[[folders objectAtIndex:i] realNameInContainer]]; + [availableAddressBooksName addObject:[[folders objectAtIndex:i] displayName]]; + } + + return availableAddressBooks; + +} +- (NSString *) itemAddressBookText +{ + return [self labelForKey:[NSString stringWithFormat: item]]; +} + +- (NSString *) userAddressBook +{ + return [userDefaults selectedAddressBook]; +} + +- (void) setUserAddressBook: (NSString *) newSelectedAddressBook +{ + [userDefaults setSelectedAddressBook: newSelectedAddressBook]; +} + - (NSArray *) messageCheckList { NSArray *intervalsList; diff --git a/UI/Templates/PreferencesUI/UIxPreferences.wox b/UI/Templates/PreferencesUI/UIxPreferences.wox index 66f69b6a9..4c2a85f71 100644 --- a/UI/Templates/PreferencesUI/UIxPreferences.wox +++ b/UI/Templates/PreferencesUI/UIxPreferences.wox @@ -294,6 +294,16 @@ const:id="sortByThreads" var:checked="sortByThreads" /> +
+ +
+
Date: Tue, 25 Mar 2014 14:53:42 -0400 Subject: [PATCH 2/6] Added the modifications specified by extrafu --- SoObjects/Contacts/SOGoContactFolders.h | 2 - SoObjects/Contacts/SOGoContactFolders.m | 73 ++------------ SoObjects/Mailer/SOGoDraftObject.m | 73 ++++++-------- SoObjects/SOGo/SOGoConstants.h | 6 ++ SoObjects/SOGo/SOGoParentFolder.h | 1 + SoObjects/SOGo/SOGoParentFolder.m | 98 ++++++++++++------- .../English.lproj/Localizable.strings | 4 +- UI/PreferencesUI/UIxPreferences.m | 41 +++++--- 8 files changed, 137 insertions(+), 161 deletions(-) diff --git a/SoObjects/Contacts/SOGoContactFolders.h b/SoObjects/Contacts/SOGoContactFolders.h index 584fab024..79f12e217 100644 --- a/SoObjects/Contacts/SOGoContactFolders.h +++ b/SoObjects/Contacts/SOGoContactFolders.h @@ -26,9 +26,7 @@ @interface SOGoContactFolders : SOGoParentFolder - (NSString *) defaultFolderName; -- (NSString *) collectedFolderName; -- (NSException *) appendCollectedSources; - (NSException *) renameLDAPAddressBook: (NSString *) sourceID withDisplayName: (NSString *) newDisplayName; - (NSException *) removeLDAPAddressBook: (NSString *) sourceID; diff --git a/SoObjects/Contacts/SOGoContactFolders.m b/SoObjects/Contacts/SOGoContactFolders.m index 183d47e32..dfb91f45c 100644 --- a/SoObjects/Contacts/SOGoContactFolders.m +++ b/SoObjects/Contacts/SOGoContactFolders.m @@ -123,60 +123,6 @@ Class SOGoContactSourceFolderK; return result; } -- (void) _createCollectedFolder -{ - NSArray *roles; - SOGoGCSFolder *folder; - SOGoUser *folderOwner; - - roles = [[context activeUser] rolesForObject: self inContext: context]; - folderOwner = [SOGoUser userWithLogin: [self ownerInContext: context]]; - - if (folderOwner && [folderOwner isResource]) - { - folder = [subFolderClass objectWithName: @"collected" inContainer: self]; - [folder setDisplayName: [self collectedFolderName]]; - [folder setOCSPath: [NSString stringWithFormat: @"%@/collected", OCSPath]]; - if ([folder create]) - [subFolders setObject: folder forKey: @"collected"]; - } -} - -- (NSException *) _fetchCollectedFolders: (NSString *) sql - withChannel: (EOAdaptorChannel *) fc -{ - NSArray *attrs; - NSDictionary *row; - SOGoGCSFolder *folder; - NSString *key; - NSException *error; - - if (!subFolderClass) - subFolderClass = [[self class] subFolderClass]; - - error = [fc evaluateExpressionX: sql]; - if (!error) - { - attrs = [fc describeResults: NO]; - while ((row = [fc fetchAttributes: attrs withZone: NULL])) - { - key = [row objectForKey: @"c_path4"]; - if ([key isKindOfClass: [NSString class]]) - { - folder = [subFolderClass objectWithName: key inContainer: self]; - [folder setOCSPath: [NSString stringWithFormat: @"%@/%@", - OCSPath, key]]; - [subFolders setObject: folder forKey: key]; - } - } - - if (![subFolders objectForKey: @"collected"]) - [self _createCollectedFolder]; - } - - return error; -} - - (NSException *) appendCollectedSources { GCSChannelManager *cm; @@ -195,16 +141,16 @@ Class SOGoContactSourceFolderK; sql = [NSString stringWithFormat: (@"SELECT c_path4 FROM %@" @" WHERE c_path2 = '%@'" @" AND c_folder_type = '%@'"), - [folderLocation gcsTableName], - owner, - gcsFolderType]; - error = [self _fetchCollectedFolders: sql withChannel: fc]; + [folderLocation gcsTableName], owner, gcsFolderType]; + + error = [super fetchSpecialFolders: sql withChannel: fc andFolderType: SOGoCollectedFolder]; + [cm releaseChannel: fc]; } else - error = [NSException exceptionWithName: @"SOGoDBException" - reason: @"database connection could not be open" - userInfo: nil]; + error = [NSException exceptionWithName: @"SOGoDBException" + reason: @"database connection could not be open" + userInfo: nil]; return error; } @@ -349,11 +295,6 @@ Class SOGoContactSourceFolderK; return [self labelForKey: @"Personal Address Book"]; } -- (NSString *) collectedFolderName -{ - return [self labelForKey: @"Collected Address Book"]; -} - - (NSArray *) toManyRelationshipKeys { NSMutableArray *keys; diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index 9c6b0a120..203d390c5 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -1698,68 +1698,59 @@ static NSString *userAgent = nil; SOGoUserDefaults *ud; ud = [[context activeUser] userDefaults]; - if ([ud mailAddOutgoingAddresses]) { - NSMutableArray *recipients; - SOGoMailAccounts *folder; - NGMailAddressParser *parser; + if ([ud mailAddOutgoingAddresses]) + { SOGoContactFolders *contactFolders; - NSArray *contacts; - NSString *address, *mail, *name; + NGMailAddressParser *parser; + id parsedRecipient; + SOGoContactFolder *folder; + SOGoContactGCSEntry *newContact; + NGVCard *card; + Class contactGCSEntry; + NSMutableArray *recipients; + NSString *recipient, *emailAddress, *displayName, *addressBook, *uid; + NSArray *matchingContacts; int i; - id parsedAddress; + // Get all the addressbooks contactFolders = [[[context activeUser] homeFolderInContext: context] - lookupName: @"Contacts" - inContext: context - acquire: NO]; - + lookupName: @"Contacts" + inContext: context + acquire: NO]; + // Get all the recipients from the current email recipients = [self allRecipients]; - for (i = 0; i < [recipients count]; i++) { // The address contains a string. ex: "John Doe " - address = [recipients objectAtIndex: i]; + recipient = [recipients objectAtIndex: i]; + parser = [NGMailAddressParser mailAddressParserWithString: recipient]; + parsedRecipient = [parser parse]; + emailAddress = [parsedRecipient address]; + displayName = [parsedRecipient displayName]; - parser = [NGMailAddressParser mailAddressParserWithString: address]; - parsedAddress = [parser parse]; - - mail = [parsedAddress address]; - name = [parsedAddress displayName]; - - contacts = [contactFolders allContactsFromFilter: mail - excludeGroups: YES - excludeLists: YES]; + matchingContacts = [contactFolders allContactsFromFilter: emailAddress + excludeGroups: YES + excludeLists: YES]; // If we don't get any results from the autocompletion code, we add it.. - if ([contacts count] == 0) + if ([matchingContacts count] == 0) { - SOGoContactFolder *folder; - Class c; - SOGoContactGCSEntry *contact; - NSString *uid; - NGVCard *card; - - /* Here I want the selected address book on the preferences. */ - NSString *addressBook; + /* Get the selected addressbook from the user preferences where the new address will be added */ addressBook = [ud selectedAddressBook]; - folder = [contactFolders lookupName: addressBook inContext: context acquire: NO]; uid = [folder globallyUniqueObjectId]; card = [NGVCard cardWithUid: uid]; - [card addEmail: mail types: nil]; + [card addEmail: emailAddress types: nil]; - c = NSClassFromString(@"SOGoContactGCSEntry"); - contact = [c objectWithName: uid - inContainer: folder]; - [contact setIsNew: YES]; - - [contact saveContentString: [card versitString]]; - + contactGCSEntry = NSClassFromString(@"SOGoContactGCSEntry"); + newContact = [contactGCSEntry objectWithName: uid + inContainer: folder]; + [newContact setIsNew: YES]; + [newContact saveContentString: [card versitString]]; } } } - return [self sendMailAndCopyToSent: YES]; } diff --git a/SoObjects/SOGo/SOGoConstants.h b/SoObjects/SOGo/SOGoConstants.h index 433760346..830d2bea4 100644 --- a/SoObjects/SOGo/SOGoConstants.h +++ b/SoObjects/SOGo/SOGoConstants.h @@ -51,4 +51,10 @@ typedef enum EventUpdated = 2, } SOGoEventOperation; +typedef enum +{ + SOGoPersonalFolder = 0, + SOGoCollectedFolder = 1, +} SOGoFolderType; + #endif /* _SOGOCONSTANTS_H_ */ diff --git a/SoObjects/SOGo/SOGoParentFolder.h b/SoObjects/SOGo/SOGoParentFolder.h index 0413faafd..ce7504428 100644 --- a/SoObjects/SOGo/SOGoParentFolder.h +++ b/SoObjects/SOGo/SOGoParentFolder.h @@ -22,6 +22,7 @@ #define SOGOPARENTFOLDERS_H #import "SOGoFolder.h" +#import "SOGoConstants.h" @class NSMutableDictionary; @class NSString; diff --git a/SoObjects/SOGo/SOGoParentFolder.m b/SoObjects/SOGo/SOGoParentFolder.m index 330a186eb..2d900396b 100644 --- a/SoObjects/SOGo/SOGoParentFolder.m +++ b/SoObjects/SOGo/SOGoParentFolder.m @@ -153,9 +153,15 @@ static SoSecurityManager *sm = nil; return @"Personal"; } -- (void) _createPersonalFolder +- (NSString *) collectedFolderName +{ + return @"Collected"; +} + +- (void) createSpecialFolder: (SOGoFolderType) folderType { NSArray *roles; + NSString *folderName; SOGoGCSFolder *folder; SOGoUser *folderOwner; @@ -165,20 +171,32 @@ static SoSecurityManager *sm = nil; // We autocreate the calendars if the user is the owner, a superuser or // if it's a resource as we won't necessarily want to login as a resource // in order to create its database tables. + // FolderType is an Enum where 0 = Personal and 1 = collected if ([roles containsObject: SoRole_Owner] || (folderOwner && [folderOwner isResource])) { - folder = [subFolderClass objectWithName: @"personal" inContainer: self]; - [folder setDisplayName: [self defaultFolderName]]; - [folder - setOCSPath: [NSString stringWithFormat: @"%@/personal", OCSPath]]; + folder = [subFolderClass objectWithName: folderName inContainer: self]; + if (folderType == 0) + { + folderName = @"personal"; + [folder setDisplayName: [self defaultFolderName]]; + } + else if (folderType == 1) + { + folderName = @"Collected Address Book"; + [folder setDisplayName: [self collectedFolderName]]; + } + + [folder setOCSPath: [NSString stringWithFormat: @"%@/%@", OCSPath, folderName]]; + if ([folder create]) - [subFolders setObject: folder forKey: @"personal"]; + [subFolders setObject: folder forKey: folderName]; } } -- (NSException *) _fetchPersonalFolders: (NSString *) sql - withChannel: (EOAdaptorChannel *) fc +- (NSException *) fetchSpecialFolders: (NSString *) sql + withChannel: (EOAdaptorChannel *) fc + andFolderType: (SOGoFolderType) folderType { NSArray *attrs; NSDictionary *row; @@ -191,24 +209,29 @@ static SoSecurityManager *sm = nil; error = [fc evaluateExpressionX: sql]; if (!error) + { + attrs = [fc describeResults: NO]; + while ((row = [fc fetchAttributes: attrs withZone: NULL])) { - attrs = [fc describeResults: NO]; - while ((row = [fc fetchAttributes: attrs withZone: NULL])) - { - key = [row objectForKey: @"c_path4"]; - if ([key isKindOfClass: [NSString class]]) - { - folder = [subFolderClass objectWithName: key inContainer: self]; - [folder setOCSPath: [NSString stringWithFormat: @"%@/%@", - OCSPath, key]]; - [subFolders setObject: folder forKey: key]; - } - } - - if (![subFolders objectForKey: @"personal"]) - [self _createPersonalFolder]; + key = [row objectForKey: @"c_path4"]; + if ([key isKindOfClass: [NSString class]]) + { + folder = [subFolderClass objectWithName: key inContainer: self]; + [folder setOCSPath: [NSString stringWithFormat: @"%@/%@", OCSPath, key]]; + [subFolders setObject: folder forKey: key]; + } } - + if (folderType == 0) + { + if (![subFolders objectForKey: @"personal"]) + [self createSpecialFolder: SOGoPersonalFolder]; + } + else if (folderType == 1) + { + if (![subFolders objectForKey: @"collected"]) + [self createSpecialFolder: SOGoCollectedFolder]; + } + } return error; } @@ -224,19 +247,18 @@ static SoSecurityManager *sm = nil; folderLocation = [[GCSFolderManager defaultFolderManager] folderInfoLocation]; fc = [cm acquireOpenChannelForURL: folderLocation]; if ([fc isOpen]) - { - gcsFolderType = [[self class] gcsFolderType]; - - sql = [NSString stringWithFormat: (@"SELECT c_path4 FROM %@" - @" WHERE c_path2 = '%@'" - @" AND c_folder_type = '%@'"), - [folderLocation gcsTableName], owner, gcsFolderType]; - - error = [self _fetchPersonalFolders: sql withChannel: fc]; - [cm releaseChannel: fc]; -// sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'", -// uidColumnName, [self uid]]; - } + { + gcsFolderType = [[self class] gcsFolderType]; + + sql = [NSString stringWithFormat: (@"SELECT c_path4 FROM %@" + @" WHERE c_path2 = '%@'" + @" AND c_folder_type = '%@'"), + [folderLocation gcsTableName], owner, gcsFolderType]; + + error = [self fetchSpecialFolders: sql withChannel: fc andFolderType: SOGoPersonalFolder]; + + [cm releaseChannel: fc]; + } else error = [NSException exceptionWithName: @"SOGoDBException" reason: @"database connection could not be open" @@ -384,7 +406,7 @@ static SoSecurityManager *sm = nil; if (!subFolders) { subFolders = [NSMutableDictionary new]; - error = [self appendPersonalSources]; + error = [self appendPersonalSources]; if (!error) if ([self respondsToSelector:@selector(appendCollectedSources)]) error = [self appendCollectedSources]; diff --git a/UI/PreferencesUI/English.lproj/Localizable.strings b/UI/PreferencesUI/English.lproj/Localizable.strings index cc5afde74..1bac4a169 100644 --- a/UI/PreferencesUI/English.lproj/Localizable.strings +++ b/UI/PreferencesUI/English.lproj/Localizable.strings @@ -139,8 +139,8 @@ "messagecheck_every_20_minutes" = "Every 20 minutes"; "messagecheck_every_30_minutes" = "Every 30 minutes"; "messagecheck_once_per_hour" = "Once per hour"; -"PersonalAddressBook" = "Personal address book"; -"CollectedAddressBook" = "Collected addresses"; +"personal" = "Personal addressbook"; +"collected" = "Collected addresses"; "Forward messages:" = "Forward messages:"; "messageforward_inline" = "Inline"; diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index 92a813061..a066fd1f5 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -691,18 +691,14 @@ static NSArray *reminderValues = nil; - (NSArray *) addressBookList { /* We want all the SourceIDS */ - NSMutableArray *folders; - NSMutableArray *contactFolders; + NSMutableArray *folders, *contactFolders, *availableAddressBooks; + int i, count; contactFolders = [[[context activeUser] homeFolderInContext: context] lookupName: @"Contacts" inContext: context acquire: NO]; - folders = [NSMutableArray arrayWithArray: [contactFolders subFolders]]; - - int i, count; - count = [folders count]-1; // Inside this loop we remove all the public or shared addressbooks @@ -713,21 +709,42 @@ static NSArray *reminderValues = nil; } // Parse the objects in order to have only the displayName of the addressbooks to be displayed on the preferences interface - NSMutableArray *availableAddressBooks = [NSMutableArray new]; - NSMutableArray *availableAddressBooksName = [NSMutableArray new]; - + availableAddressBooks = [[NSMutableArray alloc] initWithCapacity: [folders count]]; count = [folders count]-1; for (i=0; i <= count ; i++) { [availableAddressBooks addObject:[[folders objectAtIndex:i] realNameInContainer]]; - [availableAddressBooksName addObject:[[folders objectAtIndex:i] displayName]]; } return availableAddressBooks; - } - (NSString *) itemAddressBookText { - return [self labelForKey:[NSString stringWithFormat: item]]; + NSString *displayNameAddressBookItem, *test; + NSMutableArray *folders, *contactFolders; + int count, i; + + if ([item isEqualToString: @"personal"] || [item isEqualToString: @"collected"]) + displayNameAddressBookItem = [self labelForKey:[NSString stringWithFormat: item]]; + + else + { + contactFolders = [[[context activeUser] homeFolderInContext: context] + lookupName: @"Contacts" + inContext: context + acquire: NO]; + folders = [NSMutableArray arrayWithArray: [contactFolders subFolders]]; + count = [folders count]-1; + for (i=0; i <= count ; i++) + { + if ([item isEqualToString:[[folders objectAtIndex:i] realNameInContainer]]) + { + displayNameAddressBookItem = [[folders objectAtIndex:i] displayName]; + break; + }; + } + } + + return displayNameAddressBookItem; } - (NSString *) userAddressBook From 1da1764aaec713a44a1e633db7e156cdb5ae5db1 Mon Sep 17 00:00:00 2001 From: Alexandre Cloutier Date: Thu, 27 Mar 2014 15:27:48 -0400 Subject: [PATCH 3/6] The collected address book will be created only if the user select it in the preferences. Fix labels. --- .../Contacts/French.lproj/Localizable.strings | 1 + SoObjects/Contacts/SOGoContactFolders.h | 1 + SoObjects/Contacts/SOGoContactFolders.m | 7 ++- SoObjects/SOGo/SOGoParentFolder.h | 1 + SoObjects/SOGo/SOGoParentFolder.m | 21 ++++--- .../English.lproj/Localizable.strings | 9 +-- .../French.lproj/Localizable.strings | 4 ++ UI/PreferencesUI/UIxPreferences.h | 3 + UI/PreferencesUI/UIxPreferences.m | 59 ++++++++----------- 9 files changed, 59 insertions(+), 47 deletions(-) diff --git a/SoObjects/Contacts/French.lproj/Localizable.strings b/SoObjects/Contacts/French.lproj/Localizable.strings index af4d87c3a..8a5848a76 100644 --- a/SoObjects/Contacts/French.lproj/Localizable.strings +++ b/SoObjects/Contacts/French.lproj/Localizable.strings @@ -1 +1,2 @@ "Personal Address Book" = "Carnet d'adresses personnel"; +"Collected Address Book" = "Carnet d'adresses recueilli"; diff --git a/SoObjects/Contacts/SOGoContactFolders.h b/SoObjects/Contacts/SOGoContactFolders.h index 79f12e217..bb984f0b6 100644 --- a/SoObjects/Contacts/SOGoContactFolders.h +++ b/SoObjects/Contacts/SOGoContactFolders.h @@ -26,6 +26,7 @@ @interface SOGoContactFolders : SOGoParentFolder - (NSString *) defaultFolderName; +- (NSString *) collectedFolderName; - (NSException *) renameLDAPAddressBook: (NSString *) sourceID withDisplayName: (NSString *) newDisplayName; diff --git a/SoObjects/Contacts/SOGoContactFolders.m b/SoObjects/Contacts/SOGoContactFolders.m index dfb91f45c..b0428f7f4 100644 --- a/SoObjects/Contacts/SOGoContactFolders.m +++ b/SoObjects/Contacts/SOGoContactFolders.m @@ -268,7 +268,7 @@ Class SOGoContactSourceFolderK; SOGoUser *currentUser; id source; - if ([sourceID isEqualToString: @"personal"] || [sourceID isEqualToString: @"collected"]) + if ([sourceID isEqualToString: @"personal"]) result = [NSException exceptionWithHTTPStatus: 403 reason: (@"folder '%@' cannot be deleted", sourceID)]; else @@ -295,6 +295,11 @@ Class SOGoContactSourceFolderK; return [self labelForKey: @"Personal Address Book"]; } +- (NSString *) collectedFolderName +{ + return [self labelForKey: @"Collected Address Book"]; +} + - (NSArray *) toManyRelationshipKeys { NSMutableArray *keys; diff --git a/SoObjects/SOGo/SOGoParentFolder.h b/SoObjects/SOGo/SOGoParentFolder.h index ce7504428..323e71d61 100644 --- a/SoObjects/SOGo/SOGoParentFolder.h +++ b/SoObjects/SOGo/SOGoParentFolder.h @@ -40,6 +40,7 @@ + (Class) subFolderClass; - (NSString *) defaultFolderName; +- (NSString *) collectedFolderName; - (NSException *) appendPersonalSources; - (void) removeSubFolder: (NSString *) subfolderName; diff --git a/SoObjects/SOGo/SOGoParentFolder.m b/SoObjects/SOGo/SOGoParentFolder.m index 2d900396b..8d55adbb0 100644 --- a/SoObjects/SOGo/SOGoParentFolder.m +++ b/SoObjects/SOGo/SOGoParentFolder.m @@ -38,7 +38,7 @@ #import #import #import - +#import #import #import "NSObject+DAV.h" @@ -175,18 +175,18 @@ static SoSecurityManager *sm = nil; if ([roles containsObject: SoRole_Owner] || (folderOwner && [folderOwner isResource])) { - folder = [subFolderClass objectWithName: folderName inContainer: self]; - if (folderType == 0) + if (folderType == SOGoPersonalFolder) { folderName = @"personal"; + folder = [subFolderClass objectWithName: folderName inContainer: self]; [folder setDisplayName: [self defaultFolderName]]; } - else if (folderType == 1) + else if (folderType == SOGoCollectedFolder) { - folderName = @"Collected Address Book"; + folderName = @"collected"; + folder = [subFolderClass objectWithName: folderName inContainer: self]; [folder setDisplayName: [self collectedFolderName]]; } - [folder setOCSPath: [NSString stringWithFormat: @"%@/%@", OCSPath, folderName]]; if ([folder create]) @@ -203,6 +203,8 @@ static SoSecurityManager *sm = nil; SOGoGCSFolder *folder; NSString *key; NSException *error; + SOGoUserDefaults *ud; + ud = [[context activeUser] userDefaults]; if (!subFolderClass) subFolderClass = [[self class] subFolderClass]; @@ -221,15 +223,16 @@ static SoSecurityManager *sm = nil; [subFolders setObject: folder forKey: key]; } } - if (folderType == 0) + if (folderType == SOGoPersonalFolder) { if (![subFolders objectForKey: @"personal"]) [self createSpecialFolder: SOGoPersonalFolder]; } - else if (folderType == 1) + else if (folderType == SOGoCollectedFolder) { if (![subFolders objectForKey: @"collected"]) - [self createSpecialFolder: SOGoCollectedFolder]; + if ([[ud selectedAddressBook] isEqualToString:@"collected"]) + [self createSpecialFolder: SOGoCollectedFolder]; } } return error; diff --git a/UI/PreferencesUI/English.lproj/Localizable.strings b/UI/PreferencesUI/English.lproj/Localizable.strings index 1bac4a169..1f6649d26 100644 --- a/UI/PreferencesUI/English.lproj/Localizable.strings +++ b/UI/PreferencesUI/English.lproj/Localizable.strings @@ -97,8 +97,7 @@ "Show time as busy outside working hours" = "Show time as busy outside working hours"; "First week of year :" = "First week of year:"; "Enable reminders for Calendar items" = "Enable reminders for Calendar items"; -"Play a sound when a reminder comes due" -= "Play a sound when a reminder comes due"; +"Play a sound when a reminder comes due" = "Play a sound when a reminder comes due"; "Default reminder :" = "Default reminder:"; "firstWeekOfYear_January1" = "Starts on january 1"; @@ -139,8 +138,6 @@ "messagecheck_every_20_minutes" = "Every 20 minutes"; "messagecheck_every_30_minutes" = "Every 30 minutes"; "messagecheck_once_per_hour" = "Once per hour"; -"personal" = "Personal addressbook"; -"collected" = "Collected addresses"; "Forward messages:" = "Forward messages:"; "messageforward_inline" = "Inline"; @@ -159,6 +156,10 @@ "displayremoteinlineimages_never" = "Never"; "displayremoteinlineimages_always" = "Always"; +/* Contact */ +"Personal Address Book" = "Personal Address Book"; +"Collected Address Book" = "Collected Address Book"; + /* IMAP Accounts */ "New Mail Account" = "New Mail Account"; diff --git a/UI/PreferencesUI/French.lproj/Localizable.strings b/UI/PreferencesUI/French.lproj/Localizable.strings index b3d49aab2..b65a727f1 100644 --- a/UI/PreferencesUI/French.lproj/Localizable.strings +++ b/UI/PreferencesUI/French.lproj/Localizable.strings @@ -157,6 +157,10 @@ "displayremoteinlineimages_never" = "Jamais"; "displayremoteinlineimages_always" = "Toujours"; +/* Contact */ +"Personal Address Book" = "Carnet d'adresses personnel"; +"Collected Address Book" = "Carnet d'adresses recueilli"; + /* IMAP Accounts */ "New Mail Account" = "Nouveau compte"; diff --git a/UI/PreferencesUI/UIxPreferences.h b/UI/PreferencesUI/UIxPreferences.h index 3040e67ae..9c8a3483f 100644 --- a/UI/PreferencesUI/UIxPreferences.h +++ b/UI/PreferencesUI/UIxPreferences.h @@ -33,6 +33,9 @@ id item; SOGoUser *user; + // Addressbook + NSMutableDictionary *addressBooksIDWithDisplayName; + // Calendar categories NSString *category; NSArray *calendarCategories; diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index a066fd1f5..9e9adb1e2 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -116,6 +116,7 @@ static NSArray *reminderValues = nil; if ((self = [super init])) { item = nil; + addressBooksIDWithDisplayName = nil; #warning user should be the owner rather than the activeUser ASSIGN (user, [context activeUser]); ASSIGN (today, [NSCalendarDate date]); @@ -691,8 +692,9 @@ static NSArray *reminderValues = nil; - (NSArray *) addressBookList { /* We want all the SourceIDS */ - NSMutableArray *folders, *contactFolders, *availableAddressBooks; + NSMutableArray *folders, *contactFolders, *availableAddressBooksID, *availableAddressBooksName; int i, count; + BOOL collectedAlreadyExist; contactFolders = [[[context activeUser] homeFolderInContext: context] lookupName: @"Contacts" @@ -702,49 +704,40 @@ static NSArray *reminderValues = nil; count = [folders count]-1; // Inside this loop we remove all the public or shared addressbooks - for (count; count >= 0; count--) + for(count; count>=0; count--) { if (![[folders objectAtIndex: count] isKindOfClass: [SOGoContactGCSFolder class]]) [folders removeObjectAtIndex: count]; } // Parse the objects in order to have only the displayName of the addressbooks to be displayed on the preferences interface - availableAddressBooks = [[NSMutableArray alloc] initWithCapacity: [folders count]]; + availableAddressBooksID = [NSMutableArray arrayWithCapacity: [folders count]]; + availableAddressBooksName = [NSMutableArray arrayWithCapacity: [folders count]]; count = [folders count]-1; - for (i=0; i <= count ; i++) { - [availableAddressBooks addObject:[[folders objectAtIndex:i] realNameInContainer]]; - } + collectedAlreadyExist = false; - return availableAddressBooks; + for (i=0; i <= count ; i++) { + [availableAddressBooksID addObject:[[folders objectAtIndex:i] realNameInContainer]]; + [availableAddressBooksName addObject:[[folders objectAtIndex:i] displayName]]; + + if ([[availableAddressBooksID objectAtIndex:i] isEqualToString: @"collected"]) + collectedAlreadyExist = true; + } + // Create the dictionary for the next function : itemAddressBookText. + if (!addressBooksIDWithDisplayName) + addressBooksIDWithDisplayName = [NSMutableDictionary dictionaryWithObjects:availableAddressBooksName + forKeys:availableAddressBooksID]; + if (!collectedAlreadyExist) + { + [availableAddressBooksID addObject: @"collected"]; + [addressBooksIDWithDisplayName setObject: [self labelForKey: @"Collected Address Book"] forKey: @"collected"]; + } + + return availableAddressBooksID; } - (NSString *) itemAddressBookText { - NSString *displayNameAddressBookItem, *test; - NSMutableArray *folders, *contactFolders; - int count, i; - - if ([item isEqualToString: @"personal"] || [item isEqualToString: @"collected"]) - displayNameAddressBookItem = [self labelForKey:[NSString stringWithFormat: item]]; - - else - { - contactFolders = [[[context activeUser] homeFolderInContext: context] - lookupName: @"Contacts" - inContext: context - acquire: NO]; - folders = [NSMutableArray arrayWithArray: [contactFolders subFolders]]; - count = [folders count]-1; - for (i=0; i <= count ; i++) - { - if ([item isEqualToString:[[folders objectAtIndex:i] realNameInContainer]]) - { - displayNameAddressBookItem = [[folders objectAtIndex:i] displayName]; - break; - }; - } - } - - return displayNameAddressBookItem; + return [addressBooksIDWithDisplayName objectForKey: item]; } - (NSString *) userAddressBook From 03d5975be357b6cce4d74e90d4fb1069b9ff92ae Mon Sep 17 00:00:00 2001 From: Alexandre Cloutier Date: Fri, 28 Mar 2014 10:28:33 -0400 Subject: [PATCH 4/6] Changed strings in french and change the instanciation of dictionary(addressBooksIDWithDisplayName) to release it manually --- .gitignore | 1 + SoObjects/Contacts/French.lproj/Localizable.strings | 2 +- UI/PreferencesUI/French.lproj/Localizable.strings | 2 +- UI/PreferencesUI/UIxPreferences.m | 7 ++++--- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 88becdaa6..16bc03de4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ config.make tags +*._* */obj/ */*/obj/ */*/*/obj/ diff --git a/SoObjects/Contacts/French.lproj/Localizable.strings b/SoObjects/Contacts/French.lproj/Localizable.strings index 8a5848a76..2b0358694 100644 --- a/SoObjects/Contacts/French.lproj/Localizable.strings +++ b/SoObjects/Contacts/French.lproj/Localizable.strings @@ -1,2 +1,2 @@ "Personal Address Book" = "Carnet d'adresses personnel"; -"Collected Address Book" = "Carnet d'adresses recueilli"; +"Collected Address Book" = "Carnet d'adresses collectés"; diff --git a/UI/PreferencesUI/French.lproj/Localizable.strings b/UI/PreferencesUI/French.lproj/Localizable.strings index b65a727f1..774199a7b 100644 --- a/UI/PreferencesUI/French.lproj/Localizable.strings +++ b/UI/PreferencesUI/French.lproj/Localizable.strings @@ -159,7 +159,7 @@ /* Contact */ "Personal Address Book" = "Carnet d'adresses personnel"; -"Collected Address Book" = "Carnet d'adresses recueilli"; +"Collected Address Book" = "Carnet d'adresses collectés"; /* IMAP Accounts */ "New Mail Account" = "Nouveau compte"; diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index 9e9adb1e2..02adf2ff6 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -177,6 +177,7 @@ static NSArray *reminderValues = nil; [contactsCategories release]; [forwardOptions release]; [daysOfWeek release]; + [addressBooksIDWithDisplayName release]; [super dealloc]; } @@ -704,7 +705,7 @@ static NSArray *reminderValues = nil; count = [folders count]-1; // Inside this loop we remove all the public or shared addressbooks - for(count; count>=0; count--) + for (count; count >= 0; count--) { if (![[folders objectAtIndex: count] isKindOfClass: [SOGoContactGCSFolder class]]) [folders removeObjectAtIndex: count]; @@ -725,8 +726,8 @@ static NSArray *reminderValues = nil; } // Create the dictionary for the next function : itemAddressBookText. if (!addressBooksIDWithDisplayName) - addressBooksIDWithDisplayName = [NSMutableDictionary dictionaryWithObjects:availableAddressBooksName - forKeys:availableAddressBooksID]; + addressBooksIDWithDisplayName = [[NSMutableDictionary alloc] initWithObjects:availableAddressBooksName + forKeys:availableAddressBooksID]; if (!collectedAlreadyExist) { [availableAddressBooksID addObject: @"collected"]; From 09bcd2aee27b3ab2fa80c5b21b50b2fa3c9b655e Mon Sep 17 00:00:00 2001 From: Alexandre Cloutier Date: Mon, 7 Apr 2014 10:59:38 -0400 Subject: [PATCH 5/6] fix code --- SoObjects/Mailer/SOGoDraftObject.m | 18 ++++++++++-------- SoObjects/SOGo/SOGoParentFolder.m | 2 +- UI/PreferencesUI/UIxPreferences.m | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index 203d390c5..eb590adb6 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -1731,18 +1731,20 @@ static NSString *userAgent = nil; matchingContacts = [contactFolders allContactsFromFilter: emailAddress excludeGroups: YES excludeLists: YES]; + } + // If we don't get any results from the autocompletion code, we add it.. + if ([matchingContacts count] == 0) + { + /* Get the selected addressbook from the user preferences where the new address will be added */ + addressBook = [ud selectedAddressBook]; + folder = [contactFolders lookupName: addressBook inContext: context acquire: NO]; + uid = [folder globallyUniqueObjectId]; - // If we don't get any results from the autocompletion code, we add it.. - if ([matchingContacts count] == 0) + if (!(folder == nil || uid == nil)) { - /* Get the selected addressbook from the user preferences where the new address will be added */ - addressBook = [ud selectedAddressBook]; - folder = [contactFolders lookupName: addressBook inContext: context acquire: NO]; - uid = [folder globallyUniqueObjectId]; - card = [NGVCard cardWithUid: uid]; [card addEmail: emailAddress types: nil]; - + contactGCSEntry = NSClassFromString(@"SOGoContactGCSEntry"); newContact = [contactGCSEntry objectWithName: uid inContainer: folder]; diff --git a/SoObjects/SOGo/SOGoParentFolder.m b/SoObjects/SOGo/SOGoParentFolder.m index 8d55adbb0..4c7c7c31a 100644 --- a/SoObjects/SOGo/SOGoParentFolder.m +++ b/SoObjects/SOGo/SOGoParentFolder.m @@ -171,7 +171,7 @@ static SoSecurityManager *sm = nil; // We autocreate the calendars if the user is the owner, a superuser or // if it's a resource as we won't necessarily want to login as a resource // in order to create its database tables. - // FolderType is an Enum where 0 = Personal and 1 = collected + // FolderType is an enum where 0 = Personal and 1 = collected if ([roles containsObject: SoRole_Owner] || (folderOwner && [folderOwner isResource])) { diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index 02adf2ff6..9328084c3 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -717,7 +717,7 @@ static NSArray *reminderValues = nil; count = [folders count]-1; collectedAlreadyExist = false; - for (i=0; i <= count ; i++) { + for (i = 0; i <= count ; i++) { [availableAddressBooksID addObject:[[folders objectAtIndex:i] realNameInContainer]]; [availableAddressBooksName addObject:[[folders objectAtIndex:i] displayName]]; From c9cbcf256691491fd78dad77b9601df36a3ecb25 Mon Sep 17 00:00:00 2001 From: Alexandre Cloutier Date: Mon, 7 Apr 2014 16:40:44 -0400 Subject: [PATCH 6/6] applied Morgan's law --- SoObjects/Mailer/SOGoDraftObject.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index eb590adb6..1f1391ef7 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -1740,7 +1740,7 @@ static NSString *userAgent = nil; folder = [contactFolders lookupName: addressBook inContext: context acquire: NO]; uid = [folder globallyUniqueObjectId]; - if (!(folder == nil || uid == nil)) + if (folder && uid) { card = [NGVCard cardWithUid: uid]; [card addEmail: emailAddress types: nil];