Merged [13645] and [13646]: Fixed one of the longest-standing Adium bugs: The Color...
[adiumx.git] / Source / AIStatusChangedMessagesPlugin.m
blob23787ed5e480e99f345a054d2c943932fecf5f86
1 /* 
2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
3  * with this source distribution.
4  * 
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.
8  * 
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.
12  * 
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.
15  */
17 #import "AIStatusChangedMessagesPlugin.h"
18 #import "AIContentController.h"
19 #import "ESContactAlertsController.h"
20 #import <Adium/AIListContact.h>
21 #import <Adium/AIChat.h>
22 #import <Adium/AIContentStatus.h>
24 @interface AIStatusChangedMessagesPlugin (PRIVATE)
25 - (void)statusMessage:(NSString *)message forContact:(AIListContact *)contact 
26                          withType:(NSString *)type
27  phraseWithoutSubject:(NSString *)statusPhrase
28                           inChats:(NSSet *)inChats;
29 @end
31 /*!
32  * @class AIStatusChangedMessagesPlugin
33  * @brief Generate <tt>AIContentStatus</tt> messages in open chats in response to contact status changes
34  */
35 @implementation AIStatusChangedMessagesPlugin
37 static  NSDictionary    *statusTypeDict = nil;
39 /*!
40  * @brief Install
41  */
42 - (void)installPlugin
44         statusTypeDict = [[NSDictionary dictionaryWithObjectsAndKeys:
45                 @"away",CONTACT_STATUS_AWAY_YES,
46                 @"return_away",CONTACT_STATUS_AWAY_NO,
47                 @"online",CONTACT_STATUS_ONLINE_YES,
48                 @"offline",CONTACT_STATUS_ONLINE_NO,
49                 @"idle",CONTACT_STATUS_IDLE_YES,
50                 @"return_idle",CONTACT_STATUS_IDLE_NO,
51                 @"away_message",CONTACT_STATUS_MESSAGE,
52                 nil] retain];
53                 
54     //Observe contact status changes
55     [[adium notificationCenter] addObserver:self selector:@selector(contactStatusChanged:) name:CONTACT_STATUS_ONLINE_YES object:nil];
56     [[adium notificationCenter] addObserver:self selector:@selector(contactStatusChanged:) name:CONTACT_STATUS_ONLINE_NO object:nil];
57     [[adium notificationCenter] addObserver:self selector:@selector(contactStatusChanged:) name:CONTACT_STATUS_IDLE_YES object:nil];
58     [[adium notificationCenter] addObserver:self selector:@selector(contactStatusChanged:) name:CONTACT_STATUS_IDLE_NO object:nil];
60         [[adium notificationCenter] addObserver:self selector:@selector(contactAwayChanged:) name:CONTACT_STATUS_AWAY_YES object:nil];
61     [[adium notificationCenter] addObserver:self selector:@selector(contactAwayChanged:) name:CONTACT_STATUS_AWAY_NO object:nil];
62     [[adium notificationCenter] addObserver:self selector:@selector(contact_statusMessage:) name:CONTACT_STATUS_MESSAGE object:nil];
65 /*!
66  * @brief Notification a changed status message
67  *
68  * @param notification <tt>NSNotification</tt> whose object is the AIListContact
69  */
70 - (void)contact_statusMessage:(NSNotification *)notification{
71         NSSet                   *allChats;
72         AIListContact   *contact = [notification object];
73         
74         allChats = [[adium contentController] allChatsWithContact:contact];
75         if([allChats count]){   
76                 if([contact statusType] != AIAvailableStatusType){
77                         NSString                *statusMessage = [[contact statusMessage] string];
78                         NSString                *statusType = [statusTypeDict objectForKey:CONTACT_STATUS_MESSAGE];
79                         
80                         if(statusMessage && [statusMessage length] != 0){
81                                 [self statusMessage:[NSString stringWithFormat:AILocalizedString(@"Away Message: %@",nil),statusMessage] 
82                                                  forContact:contact
83                                                    withType:statusType
84                            phraseWithoutSubject:statusMessage
85                                                         inChats:allChats];
86                         }
87                 }
88         }
91 /*!
92  * @brief Contact status changed notification
93  *
94  * @param notification <tt>NSNotification</tt> whose object is the AIListContact and whose name is the eventID
95  */
96 - (void)contactStatusChanged:(NSNotification *)notification{
97         NSSet                   *allChats;
98         AIListContact   *contact = [notification object];
99         
100         allChats = [[adium contentController] allChatsWithContact:contact];
101         if([allChats count]){
102                 NSString                *description, *phraseWithoutSubject;
103                 NSString                *name = [notification name];
104                 NSDictionary    *userInfo = [notification userInfo];
105                 
106                 description = [[adium contactAlertsController] naturalLanguageDescriptionForEventID:name
107                                                                                                                                                                  listObject:contact
108                                                                                                                                                                    userInfo:userInfo
109                                                                                                                                                          includeSubject:YES];
110                 phraseWithoutSubject = [[adium contactAlertsController] naturalLanguageDescriptionForEventID:name
111                                                                                                                                                                                   listObject:contact
112                                                                                                                                                                                         userInfo:userInfo
113                                                                                                                                                                           includeSubject:NO];           
114                 [self statusMessage:description
115                                  forContact:contact
116                                    withType:[statusTypeDict objectForKey:name]
117            phraseWithoutSubject:phraseWithoutSubject
118                                         inChats:allChats];
119         }
123  * @brief Special handling for away changes
125  * We only display the "Went away" message if a status message for the away hasn't already been printed
126  */
127 - (void)contactAwayChanged:(NSNotification *)notification
129         NSDictionary    *userInfo = [notification userInfo];
130         
131         if(![[userInfo objectForKey:@"Already Posted StatusMessage"] boolValue]){
132                 [self contactStatusChanged:notification];
133         }
137  * @brief Post a status message on all active chats for this object
138  */
139 - (void)statusMessage:(NSString *)message forContact:(AIListContact *)contact 
140                          withType:(NSString *)type
141  phraseWithoutSubject:(NSString *)statusPhrase
142                           inChats:(NSSet *)inChats
144     NSEnumerator                *enumerator;
145     AIChat                              *chat;
146         NSAttributedString      *attributedMessage = [[[NSAttributedString alloc] initWithString:message
147                                                                                                                                                           attributes:[[adium contentController] defaultFormattingAttributes]] autorelease];
149         enumerator = [inChats objectEnumerator];
150         while((chat = [enumerator nextObject])){
151                 AIContentStatus *content;
152                 
153                 //Create our content object
154                 content = [AIContentStatus statusInChat:chat
155                                                                          withSource:contact
156                                                                         destination:[chat account]
157                                                                                    date:[NSDate date]
158                                                                                 message:attributedMessage
159                                                                            withType:type];
160                 
161                 if(statusPhrase){
162                         NSDictionary    *userInfo = [NSDictionary dictionaryWithObject:statusPhrase
163                                                                                                                                         forKey:@"Status Phrase"];
164                         [content setUserInfo:userInfo];
165                 }
167                 //Add the object
168                 [[adium contentController] receiveContentObject:content];
169         }
172 @end