adium 2131:0846c7e2b617: Contact list support for removing conta...

commits at adium.im commits at adium.im
Sun May 10 20:59:00 UTC 2009


details:	http://hg.adium.im/adium/rev/0846c7e2b617
revision:	2131:0846c7e2b617
author:		Zachary West <zacw at adium.im>
date:		Sun May 10 16:58:34 2009 -0400

Contact list support for removing contacts in multiple groups.

Deleting any particular instance of a contact only removes it from that group. Removes all instances when removing from the context menu for a tab.

The info inspector has been gutted of remove functionality, since all of that needs to be rewritten anyway.

diffstat:

 Frameworks/Adium Framework/Source/AIAccount.h                     |    2 +-
 Frameworks/Adium Framework/Source/AIAccount.m                     |   12 +-
 Frameworks/Adium Framework/Source/AIInterfaceControllerProtocol.h |   12 +
 Frameworks/Adium Framework/Source/AIListBookmark.m                |    2 +-
 Frameworks/Adium Framework/Source/AIListContact.m                 |    8 +-
 Frameworks/Adium Framework/Source/AIListGroup.m                   |    2 +-
 Frameworks/Adium Framework/Source/AIListObject.h                  |    6 +-
 Frameworks/Adium Framework/Source/AIListObject.m                  |    4 +-
 Frameworks/Adium Framework/Source/AIListOutlineView.m             |   11 +
 Frameworks/Adium Framework/Source/AIMetaContact.m                 |    7 +-
 Plugins/Bonjour/AWBonjourAccount.m                                |    2 +-
 Plugins/Purple Service/CBPurpleAccount.m                          |   10 +-
 Plugins/Purple Service/CBPurpleOscarAccount.m                     |   21 +-
 Plugins/Purple Service/ESPurpleGaduGaduAccount.m                  |    4 +-
 Plugins/Purple Service/ESPurpleJabberAccount.m                    |    9 +-
 Plugins/Twitter Plugin/AITwitterAccount.m                         |    2 +-
 Source/AIAdvancedInspectorPane.m                                  |    3 +-
 Source/AIApplication.m                                            |    7 +-
 Source/AIContactListEditorPlugin.m                                |  112 +++++---
 Source/AIInterfaceController.m                                    |    4 +
 20 files changed, 161 insertions(+), 79 deletions(-)

diffs (505 lines):

diff -r 1b9cd87159b9 -r 0846c7e2b617 Frameworks/Adium Framework/Source/AIAccount.h
--- a/Frameworks/Adium Framework/Source/AIAccount.h	Sun May 10 16:49:23 2009 -0400
+++ b/Frameworks/Adium Framework/Source/AIAccount.h	Sun May 10 16:58:34 2009 -0400
@@ -239,7 +239,7 @@
 //Presence Tracking
 @property (readonly, nonatomic) BOOL contactListEditable;
 - (void)addContact:(AIListContact *)contact toGroup:(AIListGroup *)group;
-- (void)removeContacts:(NSArray *)objects;
+- (void)removeContacts:(NSArray *)objects fromGroups:(NSArray *)groups;
 - (void)deleteGroup:(AIListGroup *)group;
 - (void)moveListObjects:(NSArray *)objects fromGroups:(NSSet *)oldGroups toGroups:(NSSet *)groups;
 - (void)renameGroup:(AIListGroup *)group to:(NSString *)newName;
diff -r 1b9cd87159b9 -r 0846c7e2b617 Frameworks/Adium Framework/Source/AIAccount.m
--- a/Frameworks/Adium Framework/Source/AIAccount.m	Sun May 10 16:49:23 2009 -0400
+++ b/Frameworks/Adium Framework/Source/AIAccount.m	Sun May 10 16:58:34 2009 -0400
@@ -17,6 +17,7 @@
 #import <Adium/AIAbstractAccount.h>
 #import <Adium/AIAccount.h>
 #import <Adium/AIListContact.h>
+#import <Adium/AIListGroup.h>
 #import <Adium/AIContentMessage.h>
 #import <Adium/AIContentNotification.h>
 #import <Adium/AIService.h>
@@ -730,8 +731,9 @@
  *
  * Remove contacts from this account.
  * @param objects NSArray of AIListContact objects to remove
+ * @param groups NSArray of AIListGroup objects to remove from.
  */
-- (void)removeContacts:(NSArray *)objects
+- (void)removeContacts:(NSArray *)objects fromGroups:(NSArray *)groups
 {
 	
 }
@@ -1055,9 +1057,13 @@
 {
 	//Intentially unimplemented. This should never be called (contacts are created a different way), but is required for KVC-compliance.
 }
-- (void)removeObjectFromContactsAtIndex:(int)index
+- (void)removeObjectFromContactsAtIndex:(NSInteger)index
 {
-	[[self.contacts objectAtIndex:index] removeFromList];
+	AIListObject *object = [self.contacts objectAtIndex:index];
+	
+	for (AIListGroup *group in object.groups) {
+		[object removeFromGroup:group];
+	}
 }
 
 /**
diff -r 1b9cd87159b9 -r 0846c7e2b617 Frameworks/Adium Framework/Source/AIInterfaceControllerProtocol.h
--- a/Frameworks/Adium Framework/Source/AIInterfaceControllerProtocol.h	Sun May 10 16:49:23 2009 -0400
+++ b/Frameworks/Adium Framework/Source/AIInterfaceControllerProtocol.h	Sun May 10 16:58:34 2009 -0400
@@ -296,6 +296,18 @@
  */
 @property (readonly, nonatomic) NSArray *arrayOfSelectedListObjectsInContactList;
 
+/*!
+ * @brief Get the list objects currently selected in the contact list with their groups
+ *
+ * Each entry in the NSArray is an NSDictionary of the following layout:
+ *
+ * @"ListObject" => the AIListObject
+ * @"ContainingObject" => the containing object
+ *
+ * @result An NSArray of selected objects
+ */
+ at property (readonly, nonatomic) NSArray *arrayOfSelectedListObjectsWithGroupsInContactList;
+
 #pragma mark Message View
 /*!
  * @brief Register an object which can handle displaying messages
diff -r 1b9cd87159b9 -r 0846c7e2b617 Frameworks/Adium Framework/Source/AIListBookmark.m
--- a/Frameworks/Adium Framework/Source/AIListBookmark.m	Sun May 10 16:49:23 2009 -0400
+++ b/Frameworks/Adium Framework/Source/AIListBookmark.m	Sun May 10 16:58:34 2009 -0400
@@ -124,7 +124,7 @@
  *
  * We've been asked to be removed. Ask the contact controller to do so.
  */
-- (void)removeFromList
+- (void)removeFromGroup:(AIListObject <AIContainingObject> *)group
 {
 	[adium.contactController removeBookmark:self];
 }
diff -r 1b9cd87159b9 -r 0846c7e2b617 Frameworks/Adium Framework/Source/AIListContact.m
--- a/Frameworks/Adium Framework/Source/AIListContact.m	Sun May 10 16:49:23 2009 -0400
+++ b/Frameworks/Adium Framework/Source/AIListContact.m	Sun May 10 16:58:34 2009 -0400
@@ -705,10 +705,12 @@
 	return YES;
 }
 
-- (void) removeFromList
+- (void)removeFromGroup:(AIListObject <AIContainingObject> *)group
 {
-	if (self.account.online)
-		[self.account removeContacts:[NSArray arrayWithObject:self]];
+	if (self.account.online) {
+		[self.account removeContacts:[NSArray arrayWithObject:self]
+						  fromGroups:[NSArray arrayWithObject:group]];
+	}
 }
 
 #pragma mark Equality
diff -r 1b9cd87159b9 -r 0846c7e2b617 Frameworks/Adium Framework/Source/AIListGroup.m
--- a/Frameworks/Adium Framework/Source/AIListGroup.m	Sun May 10 16:49:23 2009 -0400
+++ b/Frameworks/Adium Framework/Source/AIListGroup.m	Sun May 10 16:58:34 2009 -0400
@@ -90,7 +90,7 @@
 	return self.groups.anyObject; //can only have one containing group, its contact list
 }
 
-- (void) removeFromList
+- (void)removeFromGroup:(AIListObject <AIContainingObject> *)group
 {
 	[adium.contactController removeListGroup:self];
 }
diff -r 1b9cd87159b9 -r 0846c7e2b617 Frameworks/Adium Framework/Source/AIListObject.h
--- a/Frameworks/Adium Framework/Source/AIListObject.h	Sun May 10 16:49:23 2009 -0400
+++ b/Frameworks/Adium Framework/Source/AIListObject.h	Sun May 10 16:58:34 2009 -0400
@@ -112,9 +112,9 @@
 //Not recommended for most uses. Use -groups and -metaContact instead unless you really need both
 @property (readonly, nonatomic) NSSet *containingObjects;
 @property (readonly, copy, nonatomic) NSSet *groups;
-- (void) removeContainingGroup:(AIListGroup *)group;
-- (void) addContainingGroup:(AIListGroup *)group;
-- (void) removeFromList;
+- (void)removeContainingGroup:(AIListGroup *)group;
+- (void)addContainingGroup:(AIListGroup *)group;
+- (void)removeFromGroup:(AIListObject <AIContainingObject> *)group;
 
 //Display
 @property (readonly, nonatomic) NSString *formattedUID;
diff -r 1b9cd87159b9 -r 0846c7e2b617 Frameworks/Adium Framework/Source/AIListObject.m
--- a/Frameworks/Adium Framework/Source/AIListObject.m	Sun May 10 16:49:23 2009 -0400
+++ b/Frameworks/Adium Framework/Source/AIListObject.m	Sun May 10 16:58:34 2009 -0400
@@ -207,9 +207,9 @@
 	return self.groups;
 }
 
-- (void) removeFromList
+- (void)removeFromGroup:(AIListObject <AIContainingObject> *)group
 {
-	NSString *error = [NSString stringWithFormat:@"%@ needs an implementation of -removeFromList", NSStringFromClass([self class])];
+	NSString *error = [NSString stringWithFormat:@"%@ needs an implementation of -removeFromGroup:", NSStringFromClass([self class])];
 	NSAssert(NO, error);
 }
 
diff -r 1b9cd87159b9 -r 0846c7e2b617 Frameworks/Adium Framework/Source/AIListOutlineView.m
--- a/Frameworks/Adium Framework/Source/AIListOutlineView.m	Sun May 10 16:49:23 2009 -0400
+++ b/Frameworks/Adium Framework/Source/AIListOutlineView.m	Sun May 10 16:58:34 2009 -0400
@@ -197,6 +197,17 @@
 	return array;
 }
 
+- (NSArray *)arrayOfListObjectsWithGroups
+{
+	NSMutableArray *array = [NSMutableArray array];
+	for (AIProxyListObject *proxyObject in self.arrayOfSelectedItems) {
+		[array addObject:[NSDictionary dictionaryWithObjectsAndKeys:proxyObject.listObject, @"ListObject",
+						  proxyObject.containingObject, @"ContainingObject", nil]];
+	}
+	
+	return array;
+}
+
 - (AIListContact *)firstVisibleListContact
 {
 	unsigned int numberOfRows = [self numberOfRows];
diff -r 1b9cd87159b9 -r 0846c7e2b617 Frameworks/Adium Framework/Source/AIMetaContact.m
--- a/Frameworks/Adium Framework/Source/AIMetaContact.m	Sun May 10 16:49:23 2009 -0400
+++ b/Frameworks/Adium Framework/Source/AIMetaContact.m	Sun May 10 16:58:34 2009 -0400
@@ -160,7 +160,7 @@
 	[adium.contactController _moveContactLocally:self fromGroups:self.groups toGroups:targetGroups];
 }
 
-- (void) removeFromList
+- (void)removeFromGroup:(AIListObject <AIContainingObject> *)group
 {
 	NSSet	*objectsToRemove = nil;
 	
@@ -169,8 +169,9 @@
 		AIListContact	*listContact = [self.uniqueContainedObjects objectAtIndex:0];
 		
 		objectsToRemove = [adium.contactController allContactsWithService:listContact.service UID:listContact.UID];
-		for (AIListContact *contact in objectsToRemove)
-			[contact removeFromList];
+		for (AIListContact *contact in objectsToRemove) {
+			[contact removeFromGroup:group];
+		}
 	}
 	
 	//Now break the metaContact down, taking out all contacts and putting them back in the main list
diff -r 1b9cd87159b9 -r 0846c7e2b617 Plugins/Bonjour/AWBonjourAccount.m
--- a/Plugins/Bonjour/AWBonjourAccount.m	Sun May 10 16:49:23 2009 -0400
+++ b/Plugins/Bonjour/AWBonjourAccount.m	Sun May 10 16:58:34 2009 -0400
@@ -111,7 +111,7 @@
 	[libezv logout];
 }
 
-- (void)removeContacts:(NSArray *)objects
+- (void)removeContacts:(NSArray *)objects fromGroups:(NSArray *)groups
 {
 
 }
diff -r 1b9cd87159b9 -r 0846c7e2b617 Plugins/Purple Service/CBPurpleAccount.m
--- a/Plugins/Purple Service/CBPurpleAccount.m	Sun May 10 16:49:23 2009 -0400
+++ b/Plugins/Purple Service/CBPurpleAccount.m	Sun May 10 16:58:34 2009 -0400
@@ -603,12 +603,12 @@
 /*********************/
 #pragma mark Contact List Editing
 
-- (void)removeContacts:(NSArray *)objects
+- (void)removeContacts:(NSArray *)objects fromGroups:(NSArray *)groups
 {	
-	for (AIListContact *object in objects) {
-		for (NSString *remoteGroupName in object.remoteGroupNames) {
-			NSString	*groupName = [self _mapOutgoingGroupName:remoteGroupName];
-			
+	for (AIListGroup *group in groups) {
+		NSString *groupName = [self _mapOutgoingGroupName:group.UID];
+	
+		for (AIListContact *object in objects) {
 			//Have the purple thread perform the serverside actions
 			[purpleAdapter removeUID:object.UID onAccount:self fromGroup:groupName];
 			
diff -r 1b9cd87159b9 -r 0846c7e2b617 Plugins/Purple Service/CBPurpleOscarAccount.m
--- a/Plugins/Purple Service/CBPurpleOscarAccount.m	Sun May 10 16:49:23 2009 -0400
+++ b/Plugins/Purple Service/CBPurpleOscarAccount.m	Sun May 10 16:58:34 2009 -0400
@@ -374,12 +374,25 @@
 	}
 }
 
-- (void)removeContacts:(NSArray *)objects
+- (void)removeContacts:(NSArray *)objects fromGroups:(NSArray *)groups
 {
-	//Stop any pending delayed updates for these objects
-	[arrayOfContactsForDelayedUpdates removeObjectsInArray:objects];
+	for (AIListObject *object in objects) {
+		BOOL completelyRemoving = YES;
+		
+		for (AIListGroup *group in object.groups) {
+			if (![groups containsObject:group]) {
+				completelyRemoving = NO;
+				break;
+			}
+		}
+		
+		if (completelyRemoving) {
+			//Stop any pending delayed updates for these objects
+			[arrayOfContactsForDelayedUpdates removeObjectsInArray:objects];
+		}
+	}
 
-	[super removeContacts:objects];
+	[super removeContacts:objects fromGroups:groups];
 }
 
 #pragma mark File transfer
diff -r 1b9cd87159b9 -r 0846c7e2b617 Plugins/Purple Service/ESPurpleGaduGaduAccount.m
--- a/Plugins/Purple Service/ESPurpleGaduGaduAccount.m	Sun May 10 16:49:23 2009 -0400
+++ b/Plugins/Purple Service/ESPurpleGaduGaduAccount.m	Sun May 10 16:58:34 2009 -0400
@@ -90,9 +90,9 @@
 	[self uploadContactListToServer];
 }
 
-- (void)removeContacts:(NSArray *)objects
+- (void)removeContacts:(NSArray *)objects fromGroups:(NSArray *)groups
 {
-	[super removeContacts:objects];
+	[super removeContacts:objects fromGroups:groups];
 	
 	[self uploadContactListToServer];
 }
diff -r 1b9cd87159b9 -r 0846c7e2b617 Plugins/Purple Service/ESPurpleJabberAccount.m
--- a/Plugins/Purple Service/ESPurpleJabberAccount.m	Sun May 10 16:49:23 2009 -0400
+++ b/Plugins/Purple Service/ESPurpleJabberAccount.m	Sun May 10 16:58:34 2009 -0400
@@ -874,12 +874,17 @@
 		NSString *jid = gateway.UID;
 		NSString *pattern = [@"@" stringByAppendingString:jid];
 		NSMutableArray *gatewayContacts = [[NSMutableArray alloc] init];
+		NSMutableSet *removeGroups = [NSMutableSet set];
 		for (AIListContact *contact in self.contacts) {
-			if([contact.UID hasSuffix:pattern])
+			if([contact.UID hasSuffix:pattern]) {
 				[gatewayContacts addObject:contact];
+				[removeGroups unionSet:contact.groups];
+			}
 		}
 		// now, remove them from the roster
-		[self removeContacts:gatewayContacts];
+		[self removeContacts:gatewayContacts
+				  fromGroups:removeGroups.allObjects];
+		
 		[gatewayContacts release];
 		
 		// finally, remove the gateway itself
diff -r 1b9cd87159b9 -r 0846c7e2b617 Plugins/Twitter Plugin/AITwitterAccount.m
--- a/Plugins/Twitter Plugin/AITwitterAccount.m	Sun May 10 16:49:23 2009 -0400
+++ b/Plugins/Twitter Plugin/AITwitterAccount.m	Sun May 10 16:58:34 2009 -0400
@@ -882,7 +882,7 @@
 /*!
  * @brief Unfollow the requested contacts.
  */
-- (void)removeContacts:(NSArray *)objects
+- (void)removeContacts:(NSArray *)objects fromGroups:(NSArray *)groups
 {	
 	for (AIListContact *object in objects) {
 		NSString *requestID = [twitterEngine disableUpdatesFor:object.UID];
diff -r 1b9cd87159b9 -r 0846c7e2b617 Source/AIAdvancedInspectorPane.m
--- a/Source/AIAdvancedInspectorPane.m	Sun May 10 16:49:23 2009 -0400
+++ b/Source/AIAdvancedInspectorPane.m	Sun May 10 16:58:34 2009 -0400
@@ -426,7 +426,8 @@
 
 			} else {
 				//User selected not listed, so we'll remove that contact
-				[exactContact removeFromList];
+				// XXX multiple containers
+				//[exactContact removeFromList];
 			}
 		}
 	}
diff -r 1b9cd87159b9 -r 0846c7e2b617 Source/AIApplication.m
--- a/Source/AIApplication.m	Sun May 10 16:49:23 2009 -0400
+++ b/Source/AIApplication.m	Sun May 10 16:58:34 2009 -0400
@@ -18,6 +18,7 @@
 #import "AIChatControllerProtocol.h"
 #import "AIContactControllerProtocol.h"
 #import <Adium/AIListContact.h>
+#import <Adium/AIListGroup.h>
 
 @implementation AIApplication
 /*!
@@ -94,7 +95,11 @@
 }
 - (void)removeObjectFromContactsAtIndex:(NSInteger)index
 {
-	[[self.contacts objectAtIndex:index] removeFromList];
+	AIListObject *object = [self.contacts objectAtIndex:index];
+	
+	for (AIListGroup *group in object.groups) {
+		[object removeFromGroup:group];
+	}
 }
 
 - (NSArray *)statuses
diff -r 1b9cd87159b9 -r 0846c7e2b617 Source/AIContactListEditorPlugin.m
--- a/Source/AIContactListEditorPlugin.m	Sun May 10 16:49:23 2009 -0400
+++ b/Source/AIContactListEditorPlugin.m	Sun May 10 16:58:34 2009 -0400
@@ -277,7 +277,7 @@
  */
 - (IBAction)deleteSelection:(id)sender
 {	
-	[self deleteFromArray:[adium.interfaceController arrayOfSelectedListObjectsInContactList]];
+	[self deleteFromArray:[adium.interfaceController arrayOfSelectedListObjectsWithGroupsInContactList]];
 }
 
 /*!
@@ -285,68 +285,90 @@
  */
 - (IBAction)deleteSelectionFromTab:(id)sender
 {
-	AIListObject   *currentContextMenuObject;
-	if ((currentContextMenuObject = adium.menuController.currentContextMenuObject)) {
-		[self deleteFromArray:[NSArray arrayWithObject:currentContextMenuObject]];
+	NSArray *selectedObjects = [adium.interfaceController arrayOfSelectedListObjectsWithGroupsInContactList];
+	
+	if (selectedObjects) {
+		[self deleteFromArray:selectedObjects];
+	} else {
+		AIListObject   *currentContextMenuObject;
+		if ((currentContextMenuObject = adium.menuController.currentContextMenuObject)) {
+			NSMutableArray *contactInstances = [NSMutableArray array];
+			
+			for (AIListGroup *group in currentContextMenuObject.groups) {
+				[contactInstances addObject:[NSDictionary dictionaryWithObjectsAndKeys:currentContextMenuObject, @"ListObject",
+											 group, @"ContainingObject", nil]];
+			}
+
+			[self deleteFromArray:contactInstances];
+		}
 	}
 }
 
 /*!
- * @brief Delete an array of <tt>AIListObject</tt>s
+ * @brief Delete an array of contacts
  *
  * After a modal confirmation prompt, the objects in the array are deleted.
  *
- * @param array An <tt>NSArray</tt> of <tt>AIListObject</tt>s.
+ * @param array An NSArray of NSDictionarys describing the AIListObjects
  */
 - (void)deleteFromArray:(NSArray *)array
 {
-	if (array) {
-		NSString	*message;
-		NSUInteger count = array.count;
+	if (!array) {
+		NSBeep();
+		return;
+	}
+	
+	NSString *message = nil;
 
-		if (count == 1) {
-			AIListObject	*listObject = [array objectAtIndex:0];
-			NSString		*name = listObject.displayName;
-			if ([listObject isKindOfClass:[AIListGroup class]]) {
-				message = [NSString stringWithFormat:AILocalizedString(@"This will remove the group \"%@\" from the contact lists of your online accounts. The %lu contacts within this group will also be removed.\n\nThis action can not be undone.",nil),
-					name,
-					[(AIListGroup *)listObject countOfContainedObjects]];
-				
+	if (array.count == 1) {
+		AIListObject *listObject = [[array objectAtIndex:0] objectForKey:@"ListObject"];
+		AIListObject <AIContainingObject> *containingObject = [[array objectAtIndex:0] objectForKey:@"ContainingObject"];
+		
+		if ([listObject isKindOfClass:[AIListGroup class]]) {
+			message = [NSString stringWithFormat:AILocalizedString(@"This will remove the group \"%@\" from the contact lists of your online accounts. The %lu contacts within this group will also be removed.\n\nThis action can not be undone.", nil),
+					   listObject.displayName,
+					   ((AIListGroup *)listObject).countOfContainedObjects];
+		} else {
+			if (listObject.containingObjects.count == 1) {
+				message = [NSString stringWithFormat:AILocalizedString(@"This will remove %@ from the contact lists of your online accounts.",nil), listObject.displayName];
 			} else {
-				message = [NSString stringWithFormat:AILocalizedString(@"This will remove %@ from the contact lists of your online accounts.",nil), name];
+				message = [NSString stringWithFormat:AILocalizedString(@"This will remove %@ from the group \"%@\" of your online accounts.",nil),
+						   listObject.displayName,
+						   containingObject.displayName];
 			}
-		} else {
-			BOOL		containsGroup = NO;
-			
-			for (AIListObject *obj in array)
-			{
-				if([obj isKindOfClass:[AIListGroup class]]) {
-					containsGroup = YES;
-					break;
-				}
-			}
-
-			if (containsGroup) {
-				message = [NSString stringWithFormat:AILocalizedString(@"This will remove %lu items from the contact lists of your online accounts. Contacts in any deleted groups will also be removed.\n\nThis action can not be undone.",nil), count];
-			} else {
-				message = [NSString stringWithFormat:AILocalizedString(@"This will remove %lu contacts from the contact lists of your online accounts.",nil), count];
+		}
+	} else {
+		BOOL		containsGroup = NO;
+		
+		for (NSDictionary *dict in array) {
+			if ([[dict objectForKey:@"ListObject"] isKindOfClass:[AIListGroup class]]) {
+				containsGroup = YES;
+				break;
 			}
 		}
 		
-		//Make sure we're in the front so our prompt is visible
-		[NSApp activateIgnoringOtherApps:YES];
-		
-		//Guard deletion with a warning prompt		
-		NSInteger result = NSRunAlertPanel(AILocalizedString(@"Remove from list?",nil),
-									 @"%@",
-									 AILocalizedString(@"Remove",nil),
-									 AILocalizedString(@"Cancel",nil),
-									 nil, message);
+		if (containsGroup) {
+			message = [NSString stringWithFormat:AILocalizedString(@"This will remove %lu items from the contact lists of your online accounts. Contacts in any deleted groups will also be removed.\n\nThis action can not be undone.",nil), array.count];
+		} else {
+			message = [NSString stringWithFormat:AILocalizedString(@"This will remove %lu contacts from the contact lists of your online accounts.\n\nThis action cannot be undone.",nil), array.count];
+		}	
+	}
 
-		if (result == NSAlertDefaultReturn) {
-			[array makeObjectsPerformSelector:@selector(removeFromList)];
+	//Make sure we're in the front so our prompt is visible
+	[NSApp activateIgnoringOtherApps:YES];
+	
+	//Guard deletion with a warning prompt		
+	NSInteger result = NSRunAlertPanel(AILocalizedString(@"Remove from list?",nil),
+								 AILocalizedString(@"Removing any contacts from their last group will permanently remove them from your contact list.\n\n%@", nil),
+								 AILocalizedString(@"Remove",nil),
+								 AILocalizedString(@"Cancel",nil),
+								 nil, message);
+
+	if (result == NSAlertDefaultReturn) {
+		for (NSDictionary *dict in array) {
+			[[dict objectForKey:@"ListObject"] removeFromGroup:[dict objectForKey:@"ContainingObject"]];
 		}
-	}	
+	}
 }
 
 @end
diff -r 1b9cd87159b9 -r 0846c7e2b617 Source/AIInterfaceController.m
--- a/Source/AIInterfaceController.m	Sun May 10 16:49:23 2009 -0400
+++ b/Source/AIInterfaceController.m	Sun May 10 16:58:34 2009 -0400
@@ -1178,6 +1178,10 @@
 {
 	return [self _performSelectorOnFirstAvailableResponder:@selector(arrayOfListObjects) conformingToProtocol:@protocol(ContactListOutlineView)];
 }
+- (NSArray *)arrayOfSelectedListObjectsWithGroupsInContactList
+{
+	return [self _performSelectorOnFirstAvailableResponder:@selector(arrayOfListObjectsWithGroups) conformingToProtocol:@protocol(ContactListOutlineView)];
+}
 
 //Message View ---------------------------------------------------------------------------------------------------------
 //Message view is abstracted from the containing interface, since they're not directly related to eachother




More information about the commits mailing list