adium 2936:366008549f0c: Some fixes for moving contacts, especia...
commits at adium.im
commits at adium.im
Sun Nov 22 21:22:33 UTC 2009
details: http://hg.adium.im/adium/rev/366008549f0c
revision: 2936:366008549f0c
author: Evan Schoenberg
date: Sun Nov 22 15:25:36 2009 -0600
Some fixes for moving contacts, especially metacontacts, around. Refs #12156. This whole space is pretty complex, so I'm not sure if it fixes it or not; would appreciate further testing.
diffs (187 lines):
diff -r 7798683e54db -r 366008549f0c Frameworks/Adium Framework/Source/AIChat.m
--- a/Frameworks/Adium Framework/Source/AIChat.m Sun Nov 22 15:29:05 2009 -0500
+++ b/Frameworks/Adium Framework/Source/AIChat.m Sun Nov 22 15:25:36 2009 -0600
@@ -419,6 +419,14 @@
[adium.chatController chat:self addedListContacts:contacts notify:notify];
}
+- (BOOL)addObject:(AIListObject *)inObject
+{
+ NSParameterAssert([inObject isKindOfClass:[AIListContact class]]);
+
+ [self addParticipatingListObject:(AIListContact *)inObject notify:YES];
+ return YES;
+}
+
// Invite a list object to join the chat. Returns YES if the chat joins, NO otherwise
- (BOOL)inviteListContact:(AIListContact *)inContact withMessage:(NSString *)inviteMessage
{
diff -r 7798683e54db -r 366008549f0c Frameworks/Adium Framework/Source/AIListObject.h
--- a/Frameworks/Adium Framework/Source/AIListObject.h Sun Nov 22 15:29:05 2009 -0500
+++ b/Frameworks/Adium Framework/Source/AIListObject.h Sun Nov 22 15:25:36 2009 -0600
@@ -77,6 +77,9 @@
@property (readonly, nonatomic) NSUInteger visibleCount;
- (BOOL)canContainObject:(id)obj;
+- (BOOL)addObject:(AIListObject *)inObject;
+- (void)removeObject:(AIListObject *)inObject;
+
@end
@interface AIListObject : ESObjectWithProperties {
diff -r 7798683e54db -r 366008549f0c Frameworks/Adium Framework/Source/AIMetaContact.m
--- a/Frameworks/Adium Framework/Source/AIMetaContact.m Sun Nov 22 15:29:05 2009 -0500
+++ b/Frameworks/Adium Framework/Source/AIMetaContact.m Sun Nov 22 15:25:36 2009 -0600
@@ -151,7 +151,8 @@
[targetGroups addObject:adium.contactController.contactList];
}
- [adium.contactController _moveContactLocally:self fromGroups:self.groups toGroups:targetGroups];
+ if (self.groups.count || targetGroups.count)
+ [adium.contactController _moveContactLocally:self fromGroups:self.groups toGroups:targetGroups];
}
- (void)removeFromGroup:(AIListObject <AIContainingObject> *)group
diff -r 7798683e54db -r 366008549f0c Source/AIContactController.m
--- a/Source/AIContactController.m Sun Nov 22 15:29:05 2009 -0500
+++ b/Source/AIContactController.m Sun Nov 22 15:25:36 2009 -0600
@@ -274,7 +274,7 @@
#pragma mark Contact Grouping
-- (void)_addContactLocally:(AIListContact *)listContact toGroup:(AIListGroup *)localGroup
+- (void)_addContactLocally:(AIListContact *)listContact toGroup:(AIListObject<AIContainingObject> *)localGroup
{
BOOL performedGrouping = NO;
@@ -286,15 +286,20 @@
if (existingObject) {
//If an object exists in this group with the same UID and serviceID, create a MetaContact
//for the two.
- [self groupContacts:[NSArray arrayWithObjects:listContact,existingObject,nil]];
+ AIMetaContact *metaContact = [self groupContacts:[NSArray arrayWithObjects:listContact,existingObject,nil]];
+ AILogWithSignature(@"Grouping %@ with %@ because there was a sevice/UID match within %@, yielding %@ within %@",
+ listContact, existingObject, localGroup,
+ metaContact, metaContact.containingObjects);
performedGrouping = YES;
-
+
} else {
AIMetaContact *metaContact = [contactToMetaContactLookupDict objectForKey:listContact.internalObjectID];
//If no object exists in this group which matches, we should check if there is already
//a MetaContact holding a matching ListContact, since we should include this contact in it
//If we found a metaContact to which we should add, do it.
+ AILogWithSignature(@"Adding %@ to %@ because %@ already is within a known metacontact, which is in %@",
+ listContact, metaContact, listContact.internalObjectID, metaContact.containingObjects);
if (metaContact) {
[self addContact:listContact toMetaContact:metaContact];
performedGrouping = YES;
@@ -314,20 +319,30 @@
[listContact release];
}
+/*!
+ * @brief Handle a local move
+ *
+ * This will remove listContact from our local tracking within each of oldGroups, which must be AIListObject<AIContainingObject>
+ * objects. It will then add them to groups, which must also be AIListObject<AIContainingObject> objects.
+ *
+ * This does not make any changes serverside; that should be handled separately.
+ */
- (void)_moveContactLocally:(AIListContact *)listContact fromGroups:(NSSet *)oldGroups toGroups:(NSSet *)groups
{
//Protect with a retain while we are removing and adding the contact to our arrays
[listContact retain];
[contactPropertiesObserverManager delayListObjectNotifications];
-
+
+ AILogWithSignature(@"Removing %@ from %@ locally to add to %@", listContact, oldGroups, groups);
+
//Remove this object from any local groups we have it in currently
- for (AIListGroup *group in oldGroups) {
+ for (AIListObject<AIContainingObject> *group in oldGroups) {
[group removeObject:listContact];
[self _didChangeContainer:group object:listContact];
}
-
- for (AIListGroup *group in groups)
+
+ for (AIListObject<AIContainingObject> *group in groups)
[self _addContactLocally:listContact toGroup:group];
[contactPropertiesObserverManager endListObjectNotificationsDelay];
@@ -650,7 +665,8 @@
BOOL success;
//Remove the object from its previous containing groups
- [self _moveContactLocally:inContact fromGroups:inContact.groups toGroups:[NSSet set]];
+ if (inContact.groups.count)
+ [self _moveContactLocally:inContact fromGroups:inContact.groups toGroups:[NSSet set]];
//AIMetaContact will handle reassigning the list object's grouping to being itself
if ((success = [metaContact addObject:inContact])) {
@@ -847,6 +863,13 @@
*/
for (AIListContact *listContact in contactsToGroupArray) {
[self addContact:listContact toMetaContact:metaContact];
+
+ if ([listContact isKindOfClass:[AIMetaContact class]] && listContact != metaContact) {
+ /* If adding a metacontact to another metacontact, its contents will be recursively added.
+ * The original metacontact must then be destroyed lest it give rise to a zombie metacontact apocalypse.
+ */
+ [self explodeMetaContact:listContact];
+ }
}
return metaContact;
@@ -854,6 +877,8 @@
- (void)explodeMetaContact:(AIMetaContact *)metaContact
{
+ AILogWithSignature(@"Exploding %@", metaContact);
+
//Remove the objects within it from being inside it
[contactPropertiesObserverManager delayListObjectNotifications];
NSArray *containedObjects = metaContact.containedObjects;
@@ -862,7 +887,6 @@
group:PREF_GROUP_CONTACT_LIST] mutableCopy];
for (AIListContact *object in containedObjects) {
-
//Remove from the contactToMetaContactLookupDict first so we don't try to reinsert into this metaContact
[contactToMetaContactLookupDict removeObjectForKey:[object internalObjectID]];
@@ -1453,6 +1477,10 @@
- (void)moveContact:(AIListContact *)contact fromGroups:(NSSet *)oldGroups intoGroups:(NSSet *)groups
{
+ AILogWithSignature(@"Moving %@ (%@) from %@ into %@",
+ contact, (contact.existsServerside ? @"Serverside" : @"Not serverside"),
+ oldGroups, groups);
+
[contactPropertiesObserverManager delayListObjectNotifications];
if (contact.metaContact) {
AIMetaContact *meta = contact.metaContact;
diff -r 7798683e54db -r 366008549f0c Source/AIListController.m
--- a/Source/AIListController.m Sun Nov 22 15:29:05 2009 -0500
+++ b/Source/AIListController.m Sun Nov 22 15:25:36 2009 -0600
@@ -718,15 +718,12 @@
if ([NSEvent optionKey]) {
sourceGroups = [NSSet set];
} else {
- if ([proxyObject.containingObject isKindOfClass:[AIMetaContact class]] ||
- [proxyObject.containingObject isKindOfClass:[AIChat class]]) {
+ if ([proxyObject.containingObject isKindOfClass:[AIChat class]]) {
/* Passing an empty sourceGroups set is equivalent to a simple addition.
*
- * If we're dragging -from- a meta contact, just do an add;
- * the move performs the removal from the meta.
- *
* If we're dragging from a chat, just do an add; a move is nonsense.
*/
+ AILogWithSignature(@"Moving out of a meta or a chat");
sourceGroups = [NSSet set];
} else {
sourceGroups = [NSSet setWithObject:proxyObject.containingObject];
More information about the commits
mailing list