adium 5157:8b5d2cdd6d3d: Moved all group chat related code from ...
commits at adium.im
commits at adium.im
Sun Oct 21 22:00:54 UTC 2012
details: http://hg.adium.im/adium/rev/8b5d2cdd6d3d
revision: 5157:8b5d2cdd6d3d
branch: adium-1.6
author: Thijs Alkemade <thijsalkemade at gmail.com>
date: Sun Oct 21 23:57:17 2012 +0200
Moved all group chat related code from AIChat into a subclass AIGroupChat.
This should improve memory usage for normal chats, and make the code somewhat cleaner.
Subject: adium 5158:2a996beac083: This change was unnecessary. Restore the ability to spam filetransfers.
details: http://hg.adium.im/adium/rev/2a996beac083
revision: 5158:2a996beac083
branch: adium-1.6
author: Thijs Alkemade <thijsalkemade at gmail.com>
date: Sun Oct 21 23:59:42 2012 +0200
This change was unnecessary. Restore the ability to spam filetransfers.
diffs (truncated from 2250 to 1000 lines):
diff -r 960761c3597b -r 2a996beac083 Adium.xcodeproj/project.pbxproj
--- a/Adium.xcodeproj/project.pbxproj Sun Oct 21 20:07:44 2012 +0200
+++ b/Adium.xcodeproj/project.pbxproj Sun Oct 21 23:59:42 2012 +0200
@@ -1371,6 +1371,8 @@
767870E51634139600BD0E4D /* AIAccountSelectionTopBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = 767870E71634139600BD0E4D /* AIAccountSelectionTopBar.xib */; };
76889DEB12D3CA17007AEF00 /* get-info.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 76889DEA12D3CA17007AEF00 /* get-info.tiff */; };
76889DEF12D3CA40007AEF00 /* Profile.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 76889DEE12D3CA40007AEF00 /* Profile.tiff */; };
+ 76A79E0B16349477007A0497 /* AIGroupChat.h in Headers */ = {isa = PBXBuildFile; fileRef = 76A79E0916349477007A0497 /* AIGroupChat.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 76A79E0C16349477007A0497 /* AIGroupChat.m in Sources */ = {isa = PBXBuildFile; fileRef = 76A79E0A16349477007A0497 /* AIGroupChat.m */; };
76C1AF9C125A906A00D269A9 /* AIAdiumURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 76C1AF9B125A906A00D269A9 /* AIAdiumURLProtocol.m */; };
76FF925A14B524B40043E23B /* AIIRCConsoleController.h in Headers */ = {isa = PBXBuildFile; fileRef = 76FF925814B524B40043E23B /* AIIRCConsoleController.h */; };
76FF925B14B524B40043E23B /* AIIRCConsoleController.m in Sources */ = {isa = PBXBuildFile; fileRef = 76FF925914B524B40043E23B /* AIIRCConsoleController.m */; };
@@ -4402,6 +4404,8 @@
767870E61634139600BD0E4D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/AIAccountSelectionTopBar.xib; sourceTree = "<group>"; };
76889DEA12D3CA17007AEF00 /* get-info.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = "get-info.tiff"; path = "Resources/get-info.tiff"; sourceTree = "<group>"; };
76889DEE12D3CA40007AEF00 /* Profile.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = Profile.tiff; path = Resources/Profile.tiff; sourceTree = "<group>"; };
+ 76A79E0916349477007A0497 /* AIGroupChat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIGroupChat.h; path = "Frameworks/Adium Framework/Source/AIGroupChat.h"; sourceTree = "<group>"; };
+ 76A79E0A16349477007A0497 /* AIGroupChat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIGroupChat.m; path = "Frameworks/Adium Framework/Source/AIGroupChat.m"; sourceTree = "<group>"; };
76C1AF9A125A906A00D269A9 /* AIAdiumURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIAdiumURLProtocol.h; path = "Plugins/WebKit Message View/AIAdiumURLProtocol.h"; sourceTree = "<group>"; };
76C1AF9B125A906A00D269A9 /* AIAdiumURLProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIAdiumURLProtocol.m; path = "Plugins/WebKit Message View/AIAdiumURLProtocol.m"; sourceTree = "<group>"; };
76FF925814B524B40043E23B /* AIIRCConsoleController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIIRCConsoleController.h; path = "Plugins/Purple Service/AIIRCConsoleController.h"; sourceTree = "<group>"; };
@@ -8569,6 +8573,8 @@
63B0EC9A0F8FBB660062476B /* AIProxyListObject.m */,
34111A5D06BE1B370005AF5C /* ESObjectWithProperties.h */,
34111A5E06BE1B370005AF5C /* ESObjectWithProperties.m */,
+ 76A79E0916349477007A0497 /* AIGroupChat.h */,
+ 76A79E0A16349477007A0497 /* AIGroupChat.m */,
);
name = "Contacts & Chats";
sourceTree = "<group>";
@@ -9064,6 +9070,7 @@
112B47670F82E0FC00690E84 /* AIXtraInfo.h in Headers */,
34F17FCE0F8EAC34009C5A39 /* AIListOutlineView+Drawing.h in Headers */,
63B0EC9D0F8FBB660062476B /* AIProxyListObject.h in Headers */,
+ 76A79E0B16349477007A0497 /* AIGroupChat.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -10548,6 +10555,7 @@
63B0EC9C0F8FBB660062476B /* AIProxyListObject.m in Sources */,
76FF926814B62AB80043E23B /* AIConsoleController.m in Sources */,
5AEE60011602BAE200304672 /* AIBoolToControlTextColorTransformer.m in Sources */,
+ 76A79E0C16349477007A0497 /* AIGroupChat.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff -r 960761c3597b -r 2a996beac083 Frameworks/Adium Framework/Source/AIAbstractAccount.m
--- a/Frameworks/Adium Framework/Source/AIAbstractAccount.m Sun Oct 21 20:07:44 2012 +0200
+++ b/Frameworks/Adium Framework/Source/AIAbstractAccount.m Sun Oct 21 23:59:42 2012 +0200
@@ -24,6 +24,7 @@
#import <Adium/AIInterfaceControllerProtocol.h>
#import <Adium/AIStatusControllerProtocol.h>
#import <Adium/AIChat.h>
+#import <Adium/AIGroupChat.h>
#import <Adium/AIContentEvent.h>
#import <Adium/AIListContact.h>
#import <Adium/AIService.h>
@@ -1356,7 +1357,7 @@
[adium.contentController receiveContentObject:newStatusMessage];
if (chat.isGroupChat)
- [chat removeAllParticipatingContactsSilently];
+ [(AIGroupChat *)chat removeAllParticipatingContactsSilently];
}
}
diff -r 960761c3597b -r 2a996beac083 Frameworks/Adium Framework/Source/AIChat.h
--- a/Frameworks/Adium Framework/Source/AIChat.h Sun Oct 21 20:07:44 2012 +0200
+++ b/Frameworks/Adium Framework/Source/AIChat.h Sun Oct 21 23:59:42 2012 +0200
@@ -97,22 +97,14 @@
AIChatInvalidNumberOfArguments
} AIChatErrorType;
- at interface AIChat : ESObjectWithProperties <AIContainingObject> {
+ at interface AIChat : ESObjectWithProperties {
AIAccount *account;
NSDate *dateOpened;
BOOL isOpen;
- BOOL isGroupChat;
BOOL hasSentOrReceivedContent;
NSMutableArray *pendingOutgoingContentObjects;
- BOOL hideUserIconAndStatus;
- BOOL showJoinLeave;
-
- NSMutableDictionary *participatingContactsFlags;
- NSMutableDictionary *participatingContactsAliases;
- NSMutableArray *participatingContacts;
-
AIListContact *preferredContact;
NSString *name;
NSString *uniqueChatID;
@@ -120,14 +112,10 @@
NSMutableSet *ignoredListContacts;
- BOOL expanded;
-
BOOL enableTypingNotifications;
NSMutableSet *customEmoticons;
- NSDate *lastMessageDate;
-
// Former properties
NSImage *tabStateIcon;
@@ -141,12 +129,12 @@
NSInteger ourTypingState;
NSDictionary *securityDetails;
-
- NSString *topic;
- AIListContact *topicSetter;
+
+ AIListContact *_listObject;
}
+ (id)chatForAccount:(AIAccount *)inAccount;
+- (id)initForAccount:(AIAccount *)inAccount;
@property (readwrite, nonatomic, retain) AIAccount *account;
@@ -167,25 +155,9 @@
- (void)setDisplayName:(NSString *)inDisplayName;
-// Group chat participants.
-- (NSString *)displayNameForContact:(AIListObject *)contact;
-- (AIGroupChatFlags)flagsForContact:(AIListObject *)contact;
-- (NSString *)aliasForContact:(AIListObject *)contact;
-- (void)setFlags:(AIGroupChatFlags)flags forContact:(AIListObject *)contact;
-- (void)setAlias:(NSString *)alias forContact:(AIListObject *)contact;
-- (void)removeSavedValuesForContactUID:(NSString *)contactUID;
-
-- (void)resortParticipants;
-
-- (void)addParticipatingListObject:(AIListContact *)inObject notify:(BOOL)notify;
-- (void)addParticipatingListObjects:(NSArray *)inObjects notify:(BOOL)notify;
-- (void)removeAllParticipatingContactsSilently;
-- (void)removeObject:(AIListObject *)inObject;
-
//
@property (readwrite, nonatomic, retain) AIListContact *listObject;
@property (readwrite, nonatomic, assign) AIListContact *preferredListObject;
-- (BOOL)inviteListContact:(AIListContact *)inObject withMessage:(NSString *)inviteMessage;
- (BOOL)shouldBeginSendingContentObject:(AIContentObject *)inObject;
- (void)finishedSendingContentObject:(AIContentObject *)inObject;
@@ -209,15 +181,6 @@
- (BOOL)isListContactIgnored:(AIListObject *)inContact;
- (void)setListContact:(AIListContact *)inContact isIgnored:(BOOL)isIgnored;
- at property (readwrite, nonatomic) BOOL isGroupChat;
- at property (readwrite, nonatomic) BOOL showJoinLeave;
-
- at property (readwrite, nonatomic) BOOL hideUserIconAndStatus;
- at property (readonly, nonatomic) BOOL supportsTopic;
-
-- (void)updateTopic:(NSString *)inTopic withSource:(AIListContact *)contact;
-- (void)setTopic:(NSString *)inTopic;
-
- (void)addCustomEmoticon:(AIEmoticon *)inEmoticon;
@property (readonly, nonatomic) NSMutableSet *customEmoticons;
@@ -229,6 +192,8 @@
@property (readonly, nonatomic) BOOL shouldLog;
- at property (readwrite, copy, nonatomic) NSDate *lastMessageDate;
+// Compatibility. I don't like this here.
+- (NSArray *)containedObjects;
+- (BOOL)isGroupChat;
@end
diff -r 960761c3597b -r 2a996beac083 Frameworks/Adium Framework/Source/AIChat.m
--- a/Frameworks/Adium Framework/Source/AIChat.m Sun Oct 21 20:07:44 2012 +0200
+++ b/Frameworks/Adium Framework/Source/AIChat.m Sun Oct 21 23:59:42 2012 +0200
@@ -43,18 +43,18 @@
@interface AIChat ()
- (id)initForAccount:(AIAccount *)inAccount;
-- (void)contentObjectAdded:(NSNotification *)notification;
- (void)clearUniqueChatID;
- (void)clearListObjectStatuses;
-- (AIListContact *)visibleObjectAtIndex:(NSUInteger)idx;
@end
@implementation AIChat
static int nextChatNumber = 0;
+ at synthesize listObject = _listObject;
+
+ (id)chatForAccount:(AIAccount *)inAccount
{
return [[[self alloc] initForAccount:inAccount] autorelease];
@@ -65,38 +65,20 @@
if ((self = [super init])) {
name = nil;
account = [inAccount retain];
- participatingContacts = [[NSMutableArray alloc] init];
- participatingContactsFlags = [[NSMutableDictionary alloc] init];
- participatingContactsAliases = [[NSMutableDictionary alloc] init];
dateOpened = [[NSDate date] retain];
uniqueChatID = nil;
ignoredListContacts = nil;
isOpen = NO;
- isGroupChat = NO;
- expanded = YES;
customEmoticons = nil;
hasSentOrReceivedContent = NO;
- showJoinLeave = YES;
pendingOutgoingContentObjects = [[NSMutableArray alloc] init];
AILog(@"[AIChat: %p initForAccount]",self);
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(contentObjectAdded:)
- name:Content_ContentObjectAdded
- object:self];
}
return self;
}
-- (void)contentObjectAdded:(NSNotification *)notification
-{
- AIContentMessage *content = [[notification userInfo] objectForKey:@"AIContentObject"];
-
- self.lastMessageDate = [content date];
-}
-
/*!
* @brief Deallocate
*/
@@ -105,22 +87,17 @@
AILog(@"[%@ dealloc]",self);
[account release];
- [self removeAllParticipatingContactsSilently];
- [participatingContacts release];
- [participatingContactsFlags release];
- [participatingContactsAliases release];
[dateOpened release];
+ [_listObject release];
[ignoredListContacts release];
[pendingOutgoingContentObjects release];
[uniqueChatID release]; uniqueChatID = nil;
[customEmoticons release]; customEmoticons = nil;
- [topic release]; [topicSetter release];
[tabStateIcon release]; tabStateIcon = nil;
[chatCreationInfo release]; chatCreationInfo = nil;
[enteredTextTimer release]; enteredTextTimer = nil;
[securityDetails release]; securityDetails = nil;
- [lastMessageDate release]; lastMessageDate = nil;
[super dealloc];
}
@@ -131,11 +108,7 @@
AIListContact *listObject = nil;
NSImage *image = nil;
- if (self.isGroupChat) {
- listObject = (AIListContact *)[adium.contactController existingBookmarkForChat:self];
- } else {
- listObject = self.listObject;
- }
+ listObject = self.listObject;
if (listObject) {
image = listObject.parentContact.userIcon;
@@ -153,11 +126,7 @@
AIListObject *listObject = nil;
NSImage *chatMenuImage = nil;
- if (self.isGroupChat) {
- listObject = (AIListContact *)[adium.contactController existingBookmarkForChat:self];
- } else {
- listObject = self.listObject;
- }
+ listObject = self.listObject;
if (listObject) {
chatMenuImage = [AIUserIcons menuUserIconForObject:listObject];
@@ -224,12 +193,8 @@
if ([key isEqualToString:KEY_UNVIEWED_CONTENT] ||
[key isEqualToString:KEY_TYPING]) {
AIListObject *listObject = nil;
-
- if (self.isGroupChat) {
- listObject = (AIListContact *)[adium.contactController existingBookmarkForChat:self];
- } else {
- listObject = self.listObject;
- }
+
+ listObject = self.listObject;
if (listObject) [listObject setValue:[self valueForProperty:key] forProperty:key notify:notify];
}
@@ -322,167 +287,14 @@
silent:NO];
}
-//Participating ListObjects --------------------------------------------------------------------------------------------
-#pragma mark Participating ListObjects
-
-/*!
- * @brief The display name for the contact in this chat.
- *
- * @param contact The AIListObject whose display name should be created
- *
- * If the user has an alias set, the alias is used, otherwise the display name.
- *
- * @returns Display name
- */
-- (NSString *)displayNameForContact:(AIListObject *)contact
-{
- return [self aliasForContact:contact] ?: contact.displayName;
-}
-
-/*!
- * @brief The flags for a given contact.
- */
-- (AIGroupChatFlags)flagsForContact:(AIListObject *)contact
-{
- return [(NSNumber *)[participatingContactsFlags objectForKey:contact.UID] intValue];
-}
-
-/*!
- * @brief The alias for a given contact
- */
-- (NSString *)aliasForContact:(AIListObject *)contact
-{
- NSString *alias = [participatingContactsAliases objectForKey:contact.UID];
-
- if (!alias && self.isGroupChat) {
- alias = [self.account fallbackAliasForContact:(AIListContact *)contact inChat:self];
- }
-
- return alias;
-}
-
-/*!
- * @brief Set the flags for a contact
- *
- * Note that this doesn't set the bitwise or; this directly sets the value passed.
- */
-- (void)setFlags:(AIGroupChatFlags)flags forContact:(AIListObject *)contact
-{
- [participatingContactsFlags setObject:[NSNumber numberWithInteger:flags]
- forKey:contact.UID];
-}
-
-/*!
- * @brief Set the alias for a contact.
- */
-- (void)setAlias:(NSString *)alias forContact:(AIListObject *)contact
-{
- [participatingContactsAliases setObject:alias
- forKey:contact.UID];
-}
-
-AIGroupChatFlags highestFlag(AIGroupChatFlags flags)
-{
- if ((flags & AIGroupChatFounder) == AIGroupChatFounder)
- return AIGroupChatFounder;
-
- if ((flags & AIGroupChatOp) == AIGroupChatOp)
- return AIGroupChatOp;
-
- if ((flags & AIGroupChatHalfOp) == AIGroupChatHalfOp)
- return AIGroupChatHalfOp;
-
- if ((flags & AIGroupChatVoice) == AIGroupChatVoice)
- return AIGroupChatVoice;
-
- return AIGroupChatNone;
-}
-
-/*!
- * @brief Resorts our participants
- *
- * This is called when our list objects change.
- */
-- (void)resortParticipants
-{
- [participatingContacts sortUsingComparator:^(id objectA, id objectB){
- AIGroupChatFlags flagA = highestFlag([self flagsForContact:objectA]), flagB = highestFlag([self flagsForContact:objectB]);
-
- if(flagA > flagB) {
- return (NSComparisonResult)NSOrderedAscending;
- } else if (flagA < flagB) {
- return (NSComparisonResult)NSOrderedDescending;
- } else {
- return [[self displayNameForContact:objectA] localizedCaseInsensitiveCompare:[self displayNameForContact:objectB]];
- }
- }];
-}
-
-/*!
- * @brief Remove the saved values for a contact
- *
- * Removes any values which are dependent upon the contact, such as
- * its flags or alias.
-*/
-- (void)removeSavedValuesForContactUID:(NSString *)contactUID
-{
- [participatingContactsFlags removeObjectForKey:contactUID];
- [participatingContactsAliases removeObjectForKey:contactUID];
-}
-
-- (void)addParticipatingListObject:(AIListContact *)inObject notify:(BOOL)notify
-{
- [self addParticipatingListObjects:[NSArray arrayWithObject:inObject] notify:notify];
-}
-
-- (void)addParticipatingListObjects:(NSArray *)inObjects notify:(BOOL)notify
-{
- NSMutableArray *contacts = [inObjects mutableCopy];
-
- for (AIListObject *obj in inObjects) {
- if ([self containsObject:obj] || ![self canContainObject:obj])
- [contacts removeObject:obj];
- }
-
- [participatingContacts addObjectsFromArray:contacts];
- [adium.chatController chat:self addedListContacts:contacts notify:notify];
- [contacts release];
-}
-
-- (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
-{
- return ([self.account inviteContact:inContact toChat:self withMessage:inviteMessage]);
-}
-
@synthesize preferredListObject = preferredContact;
-//If this chat only has one participating list object, it is returned. Otherwise, nil is returned
-- (AIListContact *)listObject
-{
- if (self.countOfContainedObjects == 1 && !self.isGroupChat) {
- return (AIListContact *)[self visibleObjectAtIndex:0];
- }
-
- return nil;
-}
-
- (void)setListObject:(AIListContact *)inListObject
{
if (inListObject != self.listObject) {
- if (self.countOfContainedObjects) {
- [participatingContacts removeObjectAtIndex:0];
- }
- [self addParticipatingListObject:inListObject notify:YES];
-
+ [_listObject release];
+ _listObject = [inListObject retain];
+
//Clear any local caches relying on the list object
[self clearListObjectStatuses];
[self clearUniqueChatID];
@@ -495,11 +307,7 @@
- (NSString *)uniqueChatID
{
if (!uniqueChatID) {
- if (self.isGroupChat) {
- uniqueChatID = [[NSString alloc] initWithFormat:@"%@.%i", self.name, nextChatNumber++];
- } else {
- uniqueChatID = [self.listObject.internalObjectID retain];
- }
+ uniqueChatID = [self.listObject.internalObjectID retain];
if (!uniqueChatID) {
uniqueChatID = [[NSString alloc] initWithFormat:@"UnknownChat.%i", nextChatNumber++];
@@ -524,8 +332,6 @@
//Content --------------------------------------------------------------------------------------------------------------
#pragma mark Content
- at synthesize lastMessageDate;
-
/*!
* @brief Informs the chat that the core and the account are ready to begin filtering and sending a content object
*
@@ -568,33 +374,23 @@
- (AIChatSendingAbilityType)messageSendingAbility
{
AIChatSendingAbilityType sendingAbilityType;
-
- if (self.isGroupChat) {
- if (self.account.online) {
- //XXX Liar!
- sendingAbilityType = AIChatCanSendMessageNow;
- } else {
- sendingAbilityType = AIChatCanNotSendMessage;
- }
-
- } else {
- if (self.account.online) {
- AIListContact *listObject = self.listObject;
-
- if (listObject.online || listObject.isStranger) {
- sendingAbilityType = AIChatCanSendMessageNow;
- } else if ([self.account canSendOfflineMessageToContact:listObject]) {
- sendingAbilityType = AIChatCanSendViaServersideOfflineMessage;
- } else if ([self.account maySendMessageToInvisibleContact:listObject]) {
- sendingAbilityType = AIChatMayNotBeAbleToSendMessage;
- } else {
- sendingAbilityType = AIChatCanNotSendMessage;
- }
-
- } else {
- sendingAbilityType = AIChatCanNotSendMessage;
- }
- }
+
+ if (self.account.online) {
+ AIListContact *listObject = self.listObject;
+
+ if (listObject.online || listObject.isStranger) {
+ sendingAbilityType = AIChatCanSendMessageNow;
+ } else if ([self.account canSendOfflineMessageToContact:listObject]) {
+ sendingAbilityType = AIChatCanSendViaServersideOfflineMessage;
+ } else if ([self.account maySendMessageToInvisibleContact:listObject]) {
+ sendingAbilityType = AIChatMayNotBeAbleToSendMessage;
+ } else {
+ sendingAbilityType = AIChatCanNotSendMessage;
+ }
+
+ } else {
+ sendingAbilityType = AIChatCanNotSendMessage;
+ }
return sendingAbilityType;
}
@@ -651,128 +447,6 @@
return shouldLog;
}
-#pragma mark AIContainingObject protocol
-- (NSArray *)visibleContainedObjects
-{
- return self.containedObjects;
-}
-- (NSArray *)containedObjects
-{
- return participatingContacts;
-}
-- (NSUInteger)countOfContainedObjects
-{
- return [participatingContacts count];
-}
-
-- (BOOL)containsObject:(AIListObject *)inObject
-{
- return [participatingContacts containsObjectIdenticalTo:inObject];
-}
-
-- (AIListContact *)visibleObjectAtIndex:(NSUInteger)idx
-{
- return [participatingContacts objectAtIndex:idx];
-}
-
-- (NSUInteger)visibleIndexOfObject:(AIListObject *)obj
-{
- if(![[AIContactHidingController sharedController] visibilityOfListObject:obj inContainer:self])
- return NSNotFound;
- return [participatingContacts indexOfObject:obj];
-}
-
-//Retrieve a specific object by service and UID
-- (AIListObject *)objectWithService:(AIService *)inService UID:(NSString *)inUID
-{
- for (AIListContact *object in self) {
- if ([inUID isEqualToString:object.UID] && object.service == inService)
- return object;
- }
-
- return nil;
-}
-
-- (NSArray *)uniqueContainedObjects
-{
- return self.containedObjects;
-}
-
-- (void)removeObject:(AIListObject *)inObject
-{
- if ([self containsObject:inObject]) {
- AIListContact *contact = (AIListContact *)inObject; //if we contain it, it has to be an AIListContact
-
- //make sure removing it from the array doesn't deallocate it immediately, since we need it for -chat:removedListContact:
- [inObject retain];
-
- [participatingContacts removeObject:inObject];
-
- [self removeSavedValuesForContactUID:inObject.UID];
-
- [adium.chatController chat:self removedListContact:contact];
-
- if (contact.isStranger &&
- ![adium.chatController allGroupChatsContainingContact:contact.parentContact].count &&
- ![adium.chatController existingChatWithContact:contact.parentContact]) {
-
- [[AIContactObserverManager sharedManager] delayListObjectNotifications];
- [adium.contactController accountDidStopTrackingContact:contact];
- [[AIContactObserverManager sharedManager] endListObjectNotificationsDelaysImmediately];
- }
-
- [inObject release];
- }
-}
-
-- (void)removeObjectAfterAccountStopsTracking:(AIListObject *)object
-{
- [self removeObject:object]; //does nothing if we've already removed it
-}
-
-- (void)removeAllParticipatingContactsSilently
-{
- /* Note that allGroupChatsContainingContact won't count this chat if it's already marked as not open */
- for (AIListContact *listContact in self) {
- if (listContact.isStranger &&
- ![adium.chatController existingChatWithContact:listContact.parentContact] &&
- ([adium.chatController allGroupChatsContainingContact:listContact.parentContact].count == 0)) {
- [adium.contactController accountDidStopTrackingContact:listContact];
- }
- }
-
- [participatingContacts removeAllObjects];
- [participatingContactsFlags removeAllObjects];
- [participatingContactsAliases removeAllObjects];
-
- [[NSNotificationCenter defaultCenter] postNotificationName:Chat_ParticipatingListObjectsChanged
- object:self];
-}
-
- at synthesize expanded;
-
-- (BOOL)isExpandable
-{
- return NO;
-}
-
-- (NSUInteger)visibleCount
-{
- return self.countOfContainedObjects;
-}
-
-- (NSString *)contentsBasedIdentifier
-{
- return [NSString stringWithFormat:@"%@-%@.%@",self.name, self.account.service.serviceID, self.account.UID];
-}
-
-//Not used
-- (float)smallestOrder { return 0; }
-- (float)largestOrder { return 1E10f; }
-- (float)orderIndexForObject:(AIListObject *)listObject { return 0; }
-- (void)listObject:(AIListObject *)listObject didSetOrderIndex:(float)inOrderIndex {};
-
-
#pragma mark Ignoring
/*!
* @brief Set the ignored state of a contact
@@ -827,62 +501,6 @@
(uniqueChatID ? uniqueChatID : @"<new>")];
}
-#pragma mark Group Chats
-
- at synthesize isGroupChat, showJoinLeave, hideUserIconAndStatus;
-
-/*!
- * @brief Does this chat support topics?
- */
-- (BOOL)supportsTopic
-{
- return account.groupChatsSupportTopic;
-}
-
-/*!
- * @brief Update the topic.
- */
-- (void)updateTopic:(NSString *)inTopic withSource:(AIListContact *)contact
-{
- [self setValue:inTopic forProperty:KEY_TOPIC notify:NotifyNow];
-
- [self setValue:contact forProperty:KEY_TOPIC_SETTER notify:NotifyNow];
-
- // Apply the new topic to the message view
- AIContentTopic *contentTopic = [AIContentTopic topicInChat:self
- withSource:contact
- destination:nil
- date:[NSDate date]
- message:[NSAttributedString stringWithString:[self valueForProperty:KEY_TOPIC] ?: @""]];
-
- // The content controller has huge problems with blank messages being let through.
- if (![[self valueForProperty:KEY_TOPIC] length]) {
- contentTopic.message = CONTENT_TOPIC_MESSAGE_ACTUALLY_EMPTY;
- contentTopic.actuallyBlank = YES;
- }
-
- [adium.contentController receiveContentObject:contentTopic];
-}
-
-/*!
- * @brief Set the chat's topic, telling the account to update it.
- */
-- (void)setTopic:(NSString *)inTopic
-{
- if (self.supportsTopic) {
- // We mess with the topic, replacing nbsp with spaces; make sure we're not setting an identical one other than this.
- NSString *tempTopic = [[self valueForProperty:KEY_TOPIC] stringByReplacingOccurrencesOfString:@"\u00A0" withString:@" "];
- if ([tempTopic isEqualToString:inTopic]) {
- AILogWithSignature(@"Not setting topic for %@, already the same.", self);
- } else {
- AILogWithSignature(@"Setting %@ topic to: %@", self, [self valueForProperty:KEY_TOPIC]);
- [account setTopic:inTopic forChat:self];
- }
- } else {
- AILogWithSignature(@"Attempt to topic when account doesn't support it.");
- }
-}
-
#pragma mark Custom emoticons
- (void)addCustomEmoticon:(AIEmoticon *)inEmoticon
@@ -1033,20 +651,20 @@
//Send any file we were told to send to every participating list object (anyone remember the AOL mass mailing zareW scene?)
if (fileURL && fileURL.path.length) {
- for (AIListContact *listContact in self) {
+ for (AIListContact *listContact in self.containedObjects) {
AIListContact *targetFileTransferContact;
//Make sure we know where we are sending the file by finding the best contact for
//sending CONTENT_FILE_TRANSFER_TYPE.
if ((targetFileTransferContact = [adium.contactController preferredContactForContentType:CONTENT_FILE_TRANSFER_TYPE
- forListContact:listContact])) {
+ forListContact:listContact])) {
[adium.fileTransferController sendFile:[fileURL path]
- toListContact:targetFileTransferContact];
+ toListContact:targetFileTransferContact];
} else {
- AILogWithSignature(@"No contact available to receive files to %@", listContact);
+ AILogWithSignature(@"No contact available to receive files to %@", self.listObject);
NSBeep();
- }
- }
+ }
+ }
}
return nil;
@@ -1061,15 +679,14 @@
return nil;
}
-
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len
+- (NSArray *)containedObjects
{
- return [self.containedObjects countByEnumeratingWithState:state objects:stackbuf count:len];
+ return [NSArray arrayWithObject:self.listObject];
}
-- (BOOL) canContainObject:(id)obj
+- (BOOL)isGroupChat
{
- return [obj isKindOfClass:[AIListContact class]];
+ return NO;
}
@end
diff -r 960761c3597b -r 2a996beac083 Frameworks/Adium Framework/Source/AIChatControllerProtocol.h
--- a/Frameworks/Adium Framework/Source/AIChatControllerProtocol.h Sun Oct 21 20:07:44 2012 +0200
+++ b/Frameworks/Adium Framework/Source/AIChatControllerProtocol.h Sun Oct 21 23:59:42 2012 +0200
@@ -15,6 +15,7 @@
*/
#import <Adium/AIControllerProtocol.h>
+#import <Adium/AIGroupChat.h>
@protocol AIChatController_Private;
@class AIChat, AIAccount, AIListContact;
@@ -32,13 +33,13 @@
- (AIChat *)chatWithContact:(AIListContact *)inContact;
- (AIChat *)existingChatWithContact:(AIListContact *)inContact;
- (AIChat *)existingChatWithUniqueChatID:(NSString *)uniqueChatID;
-- (AIChat *)chatWithName:(NSString *)inName
+- (AIGroupChat *)chatWithName:(NSString *)inName
identifier:(id)identifier
onAccount:(AIAccount *)account
chatCreationInfo:(NSDictionary *)chatCreationInfo;
-- (AIChat *)existingChatWithIdentifier:(id)identifier onAccount:(AIAccount *)account;
-- (AIChat *)existingChatWithName:(NSString *)name onAccount:(AIAccount *)account;
+- (AIGroupChat *)existingChatWithIdentifier:(id)identifier onAccount:(AIAccount *)account;
+- (AIGroupChat *)existingChatWithName:(NSString *)name onAccount:(AIAccount *)account;
- (BOOL)closeChat:(AIChat *)inChat;
- (void)accountDidCloseChat:(AIChat *)inChat;
diff -r 960761c3597b -r 2a996beac083 Frameworks/Adium Framework/Source/AIContentMessage.m
--- a/Frameworks/Adium Framework/Source/AIContentMessage.m Sun Oct 21 20:07:44 2012 +0200
+++ b/Frameworks/Adium Framework/Source/AIContentMessage.m Sun Oct 21 23:59:42 2012 +0200
@@ -19,6 +19,7 @@
#import <Adium/AIContentObject.h>
#import <Adium/AIListContact.h>
#import <Adium/AIChat.h>
+#import <Adium/AIGroupChat.h>
@implementation AIContentMessage
@@ -77,7 +78,7 @@
[classes addObject:@"message"];
if(isAutoreply) [classes addObject:@"autoreply"];
if(self.chat.isGroupChat) {
- AIGroupChatFlags flags = [self.chat flagsForContact:(AIListContact *)self.source];
+ AIGroupChatFlags flags = [(AIGroupChat *)self.chat flagsForContact:(AIListContact *)self.source];
if (flags & AIGroupChatOp)
[classes addObject:@"op"];
if (flags & AIGroupChatHalfOp)
@@ -92,7 +93,9 @@
- (NSString *)senderPrefix
{
- AIGroupChatFlags flags = [self.chat flagsForContact:(AIListContact *)self.source];
+ if (!self.chat.isGroupChat) return @"";
+
+ AIGroupChatFlags flags = [(AIGroupChat *)self.chat flagsForContact:(AIListContact *)self.source];
if ((flags & AIGroupChatFounder) == AIGroupChatFounder) {
return @"~";
diff -r 960761c3597b -r 2a996beac083 Frameworks/Adium Framework/Source/AIGroupChat.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Frameworks/Adium Framework/Source/AIGroupChat.h Sun Oct 21 23:59:42 2012 +0200
@@ -0,0 +1,53 @@
+//
+// AIGroupChat.h
+// Adium
+//
+// Created by Thijs Alkemade on 21-10-12.
+// Copyright (c) 2012 The Adium Team. All rights reserved.
+//
+
+#import "AIChat.h"
+
+ at interface AIGroupChat : AIChat <AIContainingObject> {
+ NSString *topic;
+ AIListContact *topicSetter;
+
+ NSMutableDictionary *participatingContactsFlags;
+ NSMutableDictionary *participatingContactsAliases;
+ NSMutableArray *participatingContacts;
+
+ BOOL hideUserIconAndStatus;
+ BOOL showJoinLeave;
+ BOOL expanded;
+
+ NSDate *lastMessageDate;
+}
+
+ at property (readwrite, nonatomic) BOOL showJoinLeave;
+
+ at property (readwrite, nonatomic) BOOL hideUserIconAndStatus;
+ at property (readonly, nonatomic) BOOL supportsTopic;
+
+- (void)updateTopic:(NSString *)inTopic withSource:(AIListContact *)contact;
+- (void)setTopic:(NSString *)inTopic;
+
+ at property (readwrite, copy, nonatomic) NSDate *lastMessageDate;
+
+// Group chat participants.
+- (NSString *)displayNameForContact:(AIListObject *)contact;
+- (AIGroupChatFlags)flagsForContact:(AIListObject *)contact;
+- (NSString *)aliasForContact:(AIListObject *)contact;
+- (void)setFlags:(AIGroupChatFlags)flags forContact:(AIListObject *)contact;
+- (void)setAlias:(NSString *)alias forContact:(AIListObject *)contact;
+- (void)removeSavedValuesForContactUID:(NSString *)contactUID;
+
+- (void)addParticipatingListObject:(AIListContact *)inObject notify:(BOOL)notify;
+- (void)addParticipatingListObjects:(NSArray *)inObjects notify:(BOOL)notify;
+- (void)removeAllParticipatingContactsSilently;
+- (void)removeObject:(AIListObject *)inObject;
+
+- (BOOL)inviteListContact:(AIListContact *)inObject withMessage:(NSString *)inviteMessage;
+
+- (void)resortParticipants;
+
+ at end
diff -r 960761c3597b -r 2a996beac083 Frameworks/Adium Framework/Source/AIGroupChat.m
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Frameworks/Adium Framework/Source/AIGroupChat.m Sun Oct 21 23:59:42 2012 +0200
@@ -0,0 +1,497 @@
+//
+// AIGroupChat.m
+// Adium
+//
+// Created by Thijs Alkemade on 21-10-12.
+// Copyright (c) 2012 The Adium Team. All rights reserved.
+//
+
+#import "AIGroupChat.h"
+#import "AIContactControllerProtocol.h"
+#import "AIListContact.h"
+#import "AIListObject.h"
+#import "AIServiceIcons.h"
+#import "AIUserIcons.h"
+#import "AIContentTopic.h"
+#import "AIContentControllerProtocol.h"
+#import "AIAttributedStringAdditions.h"
+#import "AIChatControllerProtocol.h"
+#import "AIContactObserverManager.h"
+#import "AIContactHidingController.h"
+#import "AIArrayAdditions.h"
+#import "AIService.h"
+
+ at interface AIGroupChat ()
+
+- (void)contentObjectAdded:(NSNotification *)notification;
+- (AIListContact *)visibleObjectAtIndex:(NSUInteger)idx;
+
+ at end
+
+ at implementation AIGroupChat
+
+static int nextChatNumber = 0;
+
+ at synthesize lastMessageDate, showJoinLeave, hideUserIconAndStatus;
+
+- (id)initForAccount:(AIAccount *)inAccount
+{
+ if ((self = [super initForAccount:inAccount])) {
+ showJoinLeave = YES;
+ expanded = YES;
+ participatingContacts = [[NSMutableArray alloc] init];
+ participatingContactsFlags = [[NSMutableDictionary alloc] init];
+ participatingContactsAliases = [[NSMutableDictionary alloc] init];
+
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(contentObjectAdded:)
+ name:Content_ContentObjectAdded
+ object:self];
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [topic release]; [topicSetter release];
+
+ [self removeAllParticipatingContactsSilently];
+
+ [lastMessageDate release];
+ [participatingContacts release];
+ [participatingContactsFlags release];
+ [participatingContactsAliases release];
+
+ [super dealloc];
+}
+
+- (NSImage *)chatImage
+{
+ AIListContact *listObject = nil;
+ NSImage *image = nil;
+
+ listObject = (AIListContact *)[adium.contactController existingBookmarkForChat:self];
+
+ if (listObject) {
+ image = listObject.parentContact.userIcon;
+ if (!image) image = [AIServiceIcons serviceIconForObject:listObject type:AIServiceIconLarge direction:AIIconNormal];
+ } else {
+ image = [AIServiceIcons serviceIconForObject:self.account type:AIServiceIconLarge direction:AIIconNormal];
+ }
+
+ return image;
+}
+
+//lil image
+- (NSImage *)chatMenuImage
+{
+ AIListObject *listObject = nil;
+ NSImage *chatMenuImage = nil;
+
+ listObject = (AIListContact *)[adium.contactController existingBookmarkForChat:self];
More information about the commits
mailing list