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