merged [21403]: Fixed an exception thrown when clearing all complete file transfers...
[adiumx.git] / Source / AdiumMessageEvents.m
blob0168aeb30397a6932fa6f6bd77f3af73220daef2
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 "AdiumMessageEvents.h"
18 #import <Adium/AIContactAlertsControllerProtocol.h>
19 #import <Adium/AIChatControllerProtocol.h>
20 #import <Adium/AIContentControllerProtocol.h>
21 #import <Adium/AIChat.h>
22 #import <Adium/AIListContact.h>
23 #import <AIUtilities/AIAttributedStringAdditions.h>
24 #import <AIUtilities/AIImageAdditions.h>
26 @implementation AdiumMessageEvents
28 - (id)init
30         if ((self = [super init])) {
31                 //Empty
32         }
33         
34         return self;
37 //Requires contactAlertController loaded
38 - (void)controllerDidLoad
40         //Register the events we generate
41         [[adium contactAlertsController] registerEventID:CONTENT_MESSAGE_SENT withHandler:self inGroup:AIMessageEventHandlerGroup globalOnly:NO];
42         [[adium contactAlertsController] registerEventID:CONTENT_MESSAGE_RECEIVED withHandler:self inGroup:AIMessageEventHandlerGroup globalOnly:NO];
43         [[adium contactAlertsController] registerEventID:CONTENT_MESSAGE_RECEIVED_FIRST withHandler:self inGroup:AIMessageEventHandlerGroup globalOnly:NO];
44         [[adium contactAlertsController] registerEventID:CONTENT_MESSAGE_RECEIVED_BACKGROUND withHandler:self inGroup:AIMessageEventHandlerGroup globalOnly:NO];
45         
46         //Observe chat changes
47         [[adium chatController] registerChatObserver:self];
50 - (void)dealloc
52         [[adium chatController] unregisterChatObserver:self];
53         
54         [super dealloc];
57 #pragma mark Message event handling
58 - (NSSet *)updateChat:(AIChat *)inChat keys:(NSSet *)inModifiedKeys silent:(BOOL)silent
60         if (inModifiedKeys == nil ||
61                 [inModifiedKeys containsObject:KEY_CHAT_TIMED_OUT] ||
62                 [inModifiedKeys containsObject:KEY_CHAT_CLOSED_WINDOW] ||
63                 [inModifiedKeys containsObject:KEY_CHAT_ERROR]) {
64                 
65                 NSString                *message = nil;
66                 NSString                *type = nil;
67                 AIListContact   *listObject = [inChat listObject];
68                 
69                 if ([inChat statusObjectForKey:KEY_CHAT_ERROR] != nil) {
70                         
71                         AIChatErrorType errorType = [inChat integerStatusObjectForKey:KEY_CHAT_ERROR];
72                         type = @"chat-error";
73                         
74                         switch (errorType) {
75                                 case AIChatUnknownError:
76                                         message = [NSString stringWithFormat:AILocalizedString(@"Unknown conversation error.",nil)];
77                                         break;
78                                         
79                                 case AIChatMessageSendingUserNotAvailable:
80                                         message = [NSString stringWithFormat:AILocalizedString(@"Could not send because %@ is not available.",nil),[listObject formattedUID]];
81                                         break;
82                                         
83                                 case AIChatMessageSendingUserIsBlocked:
84                                         message = [NSString stringWithFormat:AILocalizedString(@"Could not send because %@ is blocked.",nil),[listObject formattedUID]];
85                                         break;
86                                         
87                                 case AIChatMessageSendingTooLarge:
88                                         message = AILocalizedString(@"Could not send the last message because it was too large.",nil);
89                                         break;
90                                         
91                                 case AIChatMessageSendingTimeOutOccurred:
92                                         message = AILocalizedString(@"A message may not have been sent; a timeout occurred.",nil);
93                                         break;
94                                         
95                                 case AIChatMessageSendingMissedRateLimitExceeded:
96                                         message = AILocalizedString(@"Could not send the last message because the rate limit has been exceeded. Please wait a moment and then try again.",nil);
97                                         break;
99                                 case AIChatMessageReceivingMissedTooLarge:
100                                         message = AILocalizedString(@"Could not receive the last message because it was too large.",nil);
101                                         break;
102                                         
103                                 case AIChatMessageReceivingMissedInvalid:
104                                         message = AILocalizedString(@"Could not receive the last message because it was invalid.",nil);
105                                         break;
106                                         
107                                 case AIChatMessageReceivingMissedRateLimitExceeded:
108                                         message = AILocalizedString(@"Could not receive the last message because the rate limit has been exceeded. Please wait a moment and then try again.",nil);
109                                         break;
110                                         
111                                 case AIChatMessageReceivingMissedRemoteIsTooEvil:
112                                         message = [NSString stringWithFormat:AILocalizedString(@"Could not receive; %@ is too evil.",nil),[listObject formattedUID]];
113                                         
114                                         break;
115                                 case AIChatMessageReceivingMissedLocalIsTooEvil:
116                                         message = AILocalizedString(@"Could not receive: you are too evil.",nil);
117                                         break;
118                                         
119                                 case AIChatCommandFailed:
120                                         message = AILocalizedString(@"Command failed.",nil);
121                                         break;
122                                         
123                                 case AIChatInvalidNumberOfArguments:
124                                         message = AILocalizedString(@"Incorrect number of command argments.",nil);
125                                         break;
126                                         
127                                 case AIChatMessageSendingConnectionError:
128                                         message = AILocalizedString(@"Could not send; a connection error occurred.",nil);
129                                         break;
130                                         
131                                 case AIChatMessageSendingNotAllowedWhileInvisible:
132                                         message = AILocalizedString(@"Could not send; not allowed while invisible.",nil);
133                                         break;
134                         }
135                         
136                 } else if ([inChat integerStatusObjectForKey:KEY_CHAT_CLOSED_WINDOW] && listObject) {
137                         message = [NSString stringWithFormat:AILocalizedString(@"%@ closed the conversation window.",nil),[listObject displayName]];
138                         type = @"closed";
139                 } else if ([inChat integerStatusObjectForKey:KEY_CHAT_TIMED_OUT] && listObject) {
140                         message = [NSString stringWithFormat:AILocalizedString(@"The conversation with %@ timed out.",nil),[listObject displayName]];                   
141                         type = @"timed_out";
142                 }
143                 
144                 if (message) {
145                         [[adium contentController] displayEvent:message
146                                                                                          ofType:type
147                                                                                          inChat:inChat];
148                 }
149         }
150         
151         return nil;
154 #pragma mark Event descriptions
155 - (NSString *)shortDescriptionForEventID:(NSString *)eventID
157         NSString        *description;
158         
159         if ([eventID isEqualToString:CONTENT_MESSAGE_SENT]) {
160                 description = AILocalizedString(@"Is sent a message",nil);
161         } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED]) {
162                 description = AILocalizedString(@"Sends a message",nil);
163         } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_FIRST]) {
164                 description = AILocalizedString(@"Sends an initial message",nil);
165         } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_BACKGROUND]) {
166                 description = AILocalizedString(@"Sends a message in a background chat",nil);
167         } else {
168                 description = @"";
169         }
170         
171         return description;
174 - (NSString *)globalShortDescriptionForEventID:(NSString *)eventID
176         NSString        *description;
177         
178         if ([eventID isEqualToString:CONTENT_MESSAGE_SENT]) {
179                 description = AILocalizedString(@"Message sent",nil);
180         } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED]) {
181                 description = AILocalizedString(@"Message received",nil);
182         } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_FIRST]) {
183                 description = AILocalizedString(@"Message received (Initial)",nil);
184         } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_BACKGROUND]) {
185                 description = AILocalizedString(@"Message received (Background chat)",nil);
186         } else {
187                 description = @"";
188         }
189         
190         return description;
193 //Evan: This exists because old X(tras) relied upon matching the description of event IDs, and I don't feel like making
194 //a converter for old packs.  If anyone wants to fix this situation, please feel free :)
195 - (NSString *)englishGlobalShortDescriptionForEventID:(NSString *)eventID
197         NSString        *description;
198         
199         if ([eventID isEqualToString:CONTENT_MESSAGE_SENT]) {
200                 description = @"Message Sent";
201         } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED]) {
202                 description = @"Message Received";
203         } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_FIRST]) {
204                 description = @"Message Received (New)";
205         } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_BACKGROUND]) {
206                 description = @"Message Received (Background Chat)";
207         } else {
208                 description = @"";
209         }
210         
211         return description;
214 - (NSString *)longDescriptionForEventID:(NSString *)eventID forListObject:(AIListObject *)listObject
216         NSString        *description = nil;
217         
218         if (listObject) {
219                 NSString        *name;
220                 NSString        *format;
221                 
222                 if ([eventID isEqualToString:CONTENT_MESSAGE_SENT]) {
223                         format = AILocalizedString(@"When you send %@ a message",nil);
224                 } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED]) {
225                         format = AILocalizedString(@"When %@ sends a message to you",nil);
226                 } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_FIRST]) {
227                         format = AILocalizedString(@"When %@ sends an initial message to you",nil);
228                 } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_BACKGROUND]) {
229                         format = AILocalizedString(@"When %@ sends a message to you in a background chat",nil);
230                 } else {
231                         format = nil;
232                 }
233                 
234                 if (format) {
235                         name = ([listObject isKindOfClass:[AIListGroup class]] ?
236                                         [NSString stringWithFormat:AILocalizedString(@"a member of %@",nil),[listObject displayName]] :
237                                         [listObject displayName]);
238                         
239                         description = [NSString stringWithFormat:format, name];
240                 }
241                 
242         } else {
243                 if ([eventID isEqualToString:CONTENT_MESSAGE_SENT]) {
244                         description = AILocalizedString(@"When you send a message",nil);
245                 } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED]) {
246                         description = AILocalizedString(@"When you receive any message",nil);
247                 } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_FIRST]) {
248                         description = AILocalizedString(@"When you receive an initial message",nil);
249                 } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_BACKGROUND]) {
250                         description = AILocalizedString(@"When you receive a message in a background chat",nil);
251                 } else {
252                         description = @"";
253                 }
254         }
255         
256         return description;
259 - (NSString *)naturalLanguageDescriptionForEventID:(NSString *)eventID
260                                                                                 listObject:(AIListObject *)listObject
261                                                                                   userInfo:(id)userInfo
262                                                                         includeSubject:(BOOL)includeSubject
264         NSString                *description = nil;
265         AIContentObject *contentObject;
266         NSString                *messageText;
267         NSString                *displayName;
268         
269         NSParameterAssert([userInfo isKindOfClass:[NSDictionary class]]);
270         
271         contentObject = [(NSDictionary *)userInfo objectForKey:@"AIContentObject"];
272         messageText = [[[contentObject message] attributedStringByConvertingAttachmentsToStrings] string];
273         
274         if (includeSubject) {
275                 
276                 if ([eventID isEqualToString:CONTENT_MESSAGE_SENT]) {
277                         displayName = (listObject ? [listObject displayName] : [[contentObject chat] name]);
278                 
279                         if (messageText && [messageText length]) {
280                                 description = [NSString stringWithFormat:
281                                         AILocalizedString(@"You said %@ to %@","You said Message to Contact"),
282                                         messageText,
283                                         displayName];
285                         } else {
286                                 description = [NSString stringWithFormat:
287                                         AILocalizedString(@"You sent a message to %@","You sent a message to Contact"),
288                                         displayName];
289                         }
290                         
291                 } else if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED] ||
292                                    [eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_FIRST] ||
293                                    [eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_BACKGROUND]) {
294                         displayName = (listObject ? [listObject displayName] : [[contentObject source] displayName]);
295                         
296                         if (messageText && [messageText length]) {
297                                 description = [NSString stringWithFormat:
298                                         AILocalizedString(@"%@ said %@","Contact said Message"),
299                                         displayName,
300                                         messageText];
302                         } else {
303                                 description = [NSString stringWithFormat:
304                                         AILocalizedString(@"%@ sent you a message","Contact sent you a message"),
305                                         displayName];                           
306                         }
307                 }       
308                 
309         } else {
310                 if (messageText && [messageText length]) {
311                         description = messageText;
312                 } else {
313                         if ([eventID isEqualToString:CONTENT_MESSAGE_RECEIVED] ||
314                                 [eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_FIRST] ||
315                                 [eventID isEqualToString:CONTENT_MESSAGE_RECEIVED_BACKGROUND]) {
316                                 //Use the message received text for all message received events if we don't have a message
317                                 description = [self globalShortDescriptionForEventID:CONTENT_MESSAGE_RECEIVED];
318                         } else {
319                                 description = [self globalShortDescriptionForEventID:eventID];                          
320                         }
321                 }
322         }
323         
324         return description;
327 - (NSImage *)imageForEventID:(NSString *)eventID
329         static NSImage  *eventImage = nil;
330         //Use the message icon from the main bundle
331         if (!eventImage) eventImage = [[NSImage imageNamed:@"message"] retain];
332         return eventImage;
335 @end