adium 3174:7e558d594125: Cleaned up and fixed up addition to the...
commits at adium.im
commits at adium.im
Mon Apr 26 23:55:49 UTC 2010
details: http://hg.adium.im/adium/rev/7e558d594125
revision: 3174:7e558d594125
author: Evan Schoenberg
date: Mon Apr 26 18:55:40 2010 -0500
Cleaned up and fixed up addition to the address book from contextual menus.
* Don't allow selecting 'Add to Address Book' if the contact isn't address-bookable (e.g. a Facebook contact)
* Properly handle (without crashing) a metacontact which can be added by virtue of one of its contained contacts but which has one or more contacts ineligible. Fixes #13609
* When adding a metacontact, add all contacts on each supported service, not just the last
* Documentation
diffs (160 lines):
diff -r 4619e314673e -r 7e558d594125 Frameworks/Adium Framework/Source/AIAddressBookController.m
--- a/Frameworks/Adium Framework/Source/AIAddressBookController.m Mon Apr 26 17:42:33 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIAddressBookController.m Mon Apr 26 18:55:40 2010 -0500
@@ -1234,18 +1234,46 @@
}
#pragma mark AB contextual menu
+
+/*!
+ * @brief Does the specified listObject have information valid to be added to the address book?
+ *
+ * Specifically, this requires one or more contacts in the listObject to be on a service we know how
+ * to parse into an ABPerson.
+ */
+- (BOOL)contactMayBeAddedToAddressBook:(AIListObject *)contact
+{
+ BOOL mayBeAdded = NO;
+ if ([contact isKindOfClass:[AIMetaContact class]]) {
+ for (AIListObject *c in [(AIMetaContact *)contact uniqueContainedObjects]) {
+ if ([AIAddressBookController propertyFromService:c.service] != nil) {
+ mayBeAdded = YES;
+ break;
+ }
+ }
+
+ } else {
+ mayBeAdded = ([AIAddressBookController propertyFromService:contact.service] != nil);
+ }
+
+ return mayBeAdded;
+}
+
+
+
/*!
* @brief Validate menu item
*/
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
- BOOL hasABEntry = ([[self class] personForListObject:adium.menuController.currentContextMenuObject] != nil);
- BOOL result = NO;
+ AIListObject *listObject = adium.menuController.currentContextMenuObject;
+ BOOL hasABEntry = ([[self class] personForListObject:listObject] != nil);
+ BOOL result = NO;
if ([menuItem tag] == AIRequiresAddressBookEntry) {
result = hasABEntry;
} else if ([menuItem tag] == AIRequiresNoAddressBookEntry) {
- result = !hasABEntry;
+ result = (!hasABEntry && [self contactMayBeAddedToAddressBook:listObject]);
}
return result;
@@ -1271,35 +1299,48 @@
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
}
+/*!
+ * @brief Adds the selected contact to the Address Book
+ */
- (void)addToAddressBook
{
- AIListObject *contact = adium.menuController.currentContextMenuObject;
- NSString *serviceProperty = [AIAddressBookController propertyFromService:contact.service];
+ AIListObject *contact = adium.menuController.currentContextMenuObject;
+ ABPerson *person = [[ABPerson alloc] init];
+ NSArray *contacts = ([contact isKindOfClass:[AIMetaContact class]] ?
+ [(AIMetaContact *)contact uniqueContainedObjects] :
+ [NSArray arrayWithObject:contact]);
+ BOOL validForAddition = NO;
+ BOOL success = NO;
- if (serviceProperty) {
- ABPerson *person = [[ABPerson alloc] init];
+ //Set the name
+ [person setValue:contact.displayName forKey:kABFirstNameProperty];
+ if (![[contact phoneticName] isEqualToString:contact.displayName])
+ [person setValue:[contact phoneticName] forKey:kABFirstNamePhoneticProperty];
+
+ for (AIListObject *c in contacts) {
+ NSString *UID = c.formattedUID;
+ NSString *serviceProperty = [AIAddressBookController propertyFromService:c.service];
- //Set the name
- [person setValue:contact.displayName forKey:kABFirstNameProperty];
- if (![[contact phoneticName] isEqualToString:contact.displayName])
- [person setValue:[contact phoneticName] forKey:kABFirstNamePhoneticProperty];
-
- NSString *UID = contact.formattedUID;
+ /* We may get here with a metacontact which contains one or more contacts ineligible for addition to the Address
+ * Book; skip these entries.
+ */
+ if (!UID || !serviceProperty)
+ continue;
- NSArray *contacts = [contact isKindOfClass:[AIMetaContact class]] ? [(AIMetaContact *)contact uniqueContainedObjects] : [NSArray arrayWithObject:contact];
+ /* Reuse a previously added multivalue for this property if present;
+ * this happens if a metacontact has multiple UIDs for a single service, e.g. multiple AIM names
+ */
+ ABMutableMultiValue *multiValue = [person valueForKey:serviceProperty];
+ if (!multiValue)
+ multiValue = [[[ABMutableMultiValue alloc] init] autorelease];
- for (AIListObject *c in contacts) {
- ABMutableMultiValue *multiValue = [[ABMutableMultiValue alloc] init];
- UID = c.formattedUID;
- serviceProperty = [AIAddressBookController propertyFromService:c.service];
-
- //Set the IM property
- [multiValue addValue:UID withLabel:serviceProperty];
- [person setValue:multiValue forKey:serviceProperty];
-
- [multiValue release];
- }
-
+ [multiValue addValue:UID withLabel:serviceProperty];
+ [person setValue:multiValue forKey:serviceProperty];
+
+ validForAddition = YES;
+ }
+
+ if (validForAddition) {
//Set the image
[person setImageData:[contact userIconData]];
@@ -1315,22 +1356,26 @@
//Ask the user whether it would like to edit the new contact
NSInteger result = NSRunAlertPanel(CONTACT_ADDED_SUCCESS_TITLE,
- CONTACT_ADDED_SUCCESS_Message,
- AILocalizedString(@"Yes", nil),
- AILocalizedString(@"No", nil), nil, UID);
+ CONTACT_ADDED_SUCCESS_Message,
+ AILocalizedString(@"Yes", nil),
+ AILocalizedString(@"No", nil), nil, contact.displayName);
if (result == NSOKButton) {
NSString *url = [[NSString alloc] initWithFormat:@"addressbook://%@?edit", [person uniqueId]];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
[url release];
}
- } else {
- NSRunAlertPanel(CONTACT_ADDED_ERROR_TITLE, CONTACT_ADDED_ERROR_Message, nil, nil, nil);
+
+ success = YES;
}
-
- //Clean up
- [person release];
}
+
+
+ if (!success)
+ NSRunAlertPanel(CONTACT_ADDED_ERROR_TITLE, CONTACT_ADDED_ERROR_Message, nil, nil, nil);
+
+ //Clean up
+ [person release];
}
@end
More information about the commits
mailing list