2 * Adium is the legal property of its developers, whose names are listed in the copyright file included
3 * with this source distribution.
5 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * General Public License as published by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
11 * Public License for more details.
13 * You should have received a copy of the GNU General Public License along with this program; if not,
14 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 #import "AIStatusChangedMessagesPlugin.h"
18 #import <Adium/AIChatControllerProtocol.h>
19 #import <Adium/AIContentControllerProtocol.h>
20 #import <Adium/AIContactAlertsControllerProtocol.h>
21 #import <Adium/AIListContact.h>
22 #import <Adium/AIChat.h>
23 #import <Adium/AIContentStatus.h>
25 @interface AIStatusChangedMessagesPlugin (PRIVATE)
26 - (void)statusMessage:(NSString *)message forContact:(AIListContact *)contact
27 withType:(NSString *)type
28 phraseWithoutSubject:(NSString *)statusPhrase
29 loggedMessage:(NSAttributedString *)loggedMessage
30 inChats:(NSSet *)inChats;
34 * @class AIStatusChangedMessagesPlugin
35 * @brief Generate <tt>AIContentStatus</tt> messages in open chats in response to contact status changes
37 @implementation AIStatusChangedMessagesPlugin
39 static NSDictionary *statusTypeDict = nil;
46 statusTypeDict = [[NSDictionary dictionaryWithObjectsAndKeys:
47 @"away",CONTACT_STATUS_AWAY_YES,
48 @"return_away",CONTACT_STATUS_AWAY_NO,
49 @"online",CONTACT_STATUS_ONLINE_YES,
50 @"offline",CONTACT_STATUS_ONLINE_NO,
51 @"idle",CONTACT_STATUS_IDLE_YES,
52 @"return_idle",CONTACT_STATUS_IDLE_NO,
53 @"away_message",CONTACT_STATUS_MESSAGE,
56 previousStatusChangedMessages = [[NSMutableDictionary alloc] init];
58 //Observe contact status changes
59 [[adium notificationCenter] addObserver:self selector:@selector(contactStatusChanged:) name:CONTACT_STATUS_ONLINE_YES object:nil];
60 [[adium notificationCenter] addObserver:self selector:@selector(contactStatusChanged:) name:CONTACT_STATUS_ONLINE_NO object:nil];
61 [[adium notificationCenter] addObserver:self selector:@selector(contactStatusChanged:) name:CONTACT_STATUS_IDLE_YES object:nil];
62 [[adium notificationCenter] addObserver:self selector:@selector(contactStatusChanged:) name:CONTACT_STATUS_IDLE_NO object:nil];
64 [[adium notificationCenter] addObserver:self selector:@selector(contactAwayChanged:) name:CONTACT_STATUS_AWAY_YES object:nil];
65 [[adium notificationCenter] addObserver:self selector:@selector(contactAwayChanged:) name:CONTACT_STATUS_AWAY_NO object:nil];
66 [[adium notificationCenter] addObserver:self selector:@selector(contact_statusMessage:) name:CONTACT_STATUS_MESSAGE object:nil];
68 [[adium notificationCenter] addObserver:self
69 selector:@selector(chatWillClose:)
74 - (void)uninstallPlugin
76 [previousStatusChangedMessages release];
80 * @brief Notification a changed status message
82 * @param notification <tt>NSNotification</tt> whose object is the AIListContact
84 - (void)contact_statusMessage:(NSNotification *)notification{
86 AIListContact *contact = [notification object];
88 allChats = [[adium chatController] allChatsWithContact:contact];
89 AILog(@"Status message for %@ changed (%@)",contact,allChats);
90 if ([allChats count]) {
91 if ([contact statusType] != AIAvailableStatusType) {
92 NSAttributedString *statusMessage = [contact statusMessage];
93 NSString *statusMessageString = [statusMessage string];
94 NSString *statusType = [statusTypeDict objectForKey:CONTACT_STATUS_MESSAGE];
96 if (statusMessage && [statusMessage length] != 0) {
97 [self statusMessage:[NSString stringWithFormat:AILocalizedString(@"Away Message: %@",nil),statusMessageString]
100 phraseWithoutSubject:statusMessageString
101 loggedMessage:statusMessage
109 * @brief Contact status changed notification
111 * @param notification <tt>NSNotification</tt> whose object is the AIListContact and whose name is the eventID
113 - (void)contactStatusChanged:(NSNotification *)notification{
115 AIListContact *contact = [notification object];
117 allChats = [[adium chatController] allChatsWithContact:contact];
118 if ([allChats count]) {
119 NSString *description, *phraseWithoutSubject;
120 NSString *name = [notification name];
121 NSDictionary *userInfo = [notification userInfo];
123 description = [[adium contactAlertsController] naturalLanguageDescriptionForEventID:name
127 phraseWithoutSubject = [[adium contactAlertsController] naturalLanguageDescriptionForEventID:name
131 [self statusMessage:description
133 withType:[statusTypeDict objectForKey:name]
134 phraseWithoutSubject:phraseWithoutSubject
141 * @brief Special handling for away changes
143 * We only display the "Went away" message if a status message for the away hasn't already been printed
145 - (void)contactAwayChanged:(NSNotification *)notification
147 NSDictionary *userInfo = [notification userInfo];
149 if (![[userInfo objectForKey:@"Already Posted StatusMessage"] boolValue]) {
150 [self contactStatusChanged:notification];
155 * @brief Post a status message on all active chats for this object
157 - (void)statusMessage:(NSString *)message forContact:(AIListContact *)contact
158 withType:(NSString *)type
159 phraseWithoutSubject:(NSString *)statusPhrase
160 loggedMessage:(NSAttributedString *)loggedMessage
161 inChats:(NSSet *)inChats
163 NSEnumerator *enumerator;
165 NSAttributedString *attributedMessage = [[[NSAttributedString alloc] initWithString:message
166 attributes:[[adium contentController] defaultFormattingAttributes]] autorelease];
168 enumerator = [inChats objectEnumerator];
169 while ((chat = [enumerator nextObject])) {
170 //Don't do anything if the message is the same as the last message displayed for this chat
171 if ([[previousStatusChangedMessages objectForKey:[chat uniqueChatID]] isEqualToString:message])
174 AIContentStatus *content;
176 //Create our content object
177 content = [AIContentStatus statusInChat:chat
179 destination:[chat account]
181 message:attributedMessage
185 NSDictionary *userInfo = [NSDictionary dictionaryWithObject:statusPhrase
186 forKey:@"Status Phrase"];
187 [content setUserInfo:userInfo];
191 [content setLoggedMessage:loggedMessage];
195 [[adium contentController] receiveContentObject:content];
197 //Keep track of this message for this chat so we don't display it again sequentially
198 [previousStatusChangedMessages setObject:message
199 forKey:[chat uniqueChatID]];
203 - (void)chatWillClose:(NSNotification *)inNotification
205 AIChat *chat = [inNotification object];
206 [previousStatusChangedMessages removeObjectForKey:[chat uniqueChatID]];