French updates
[adiumx.git] / Source / AIExtendedStatusPlugin.m
blob453312901ffa160e05e6475b1f5fdf21391160b2
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 "AIContactController.h"
18 #import "AIContentController.h"
19 #import "AIExtendedStatusPlugin.h"
20 #import "AIPreferenceController.h"
21 #import <AIUtilities/AIMutableOwnerArray.h>
22 #import <AIUtilities/AIAttributedStringAdditions.h>
23 #import <Adium/AIAbstractListController.h>
24 #import <Adium/AIListObject.h>
26 #define STATUS_MAX_LENGTH       100
28 @interface AIExtendedStatusPlugin (PRIVATE)
29 - (void)preferencesChanged:(NSNotification *)notification;
30 @end
32 /*!
33  * @class AIExtendedStatusPlugin
34  * @brief Manage the 'extended status' shown in the contact list
35  *
36  * If the contact list layout calls for displaying a status message or idle time (or both), this component manages
37  * generating the appropriate string, storing it in the @"ExtendedStatus" status object, and updating it as necessary.
38  */
39 @implementation AIExtendedStatusPlugin
41 /*!
42  * @brief Install
43  */
44 - (void)installPlugin
46         [[adium preferenceController] registerPreferenceObserver:self forGroup:PREF_GROUP_LIST_LAYOUT];
47         
48         whitespaceAndNewlineCharacterSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] retain];
51 /*!
52  * @brief Uninstall
53  */
54 - (void)uninstallPlugin
56         [[adium preferenceController] unregisterPreferenceObserver:self];
57         [[adium contactController] unregisterListObjectObserver:self];
60 /*!
61  * @brief Preferences changes
62  *
63  * PREF_GROUP_LIST_LAYOUT changed; update our list objects if needed.
64  */
65 - (void)preferencesChangedForGroup:(NSString *)group key:(NSString *)key
66                                                         object:(AIListObject *)object preferenceDict:(NSDictionary *)prefDict firstTime:(BOOL)firstTime
68         BOOL oldShowStatus = showStatus;
69         BOOL oldShowIdle = showIdle;
70         
71         EXTENDED_STATUS_STYLE statusStyle = [[prefDict objectForKey:KEY_LIST_LAYOUT_EXTENDED_STATUS_STYLE] intValue];
72         showStatus = ((statusStyle == STATUS_ONLY) || (statusStyle == IDLE_AND_STATUS));
73         showIdle = ((statusStyle == IDLE_ONLY) || (statusStyle == IDLE_AND_STATUS));
74         
75         if(firstTime){
76                 [[adium contactController] registerListObjectObserver:self];
77         }else{
78                 if((oldShowStatus != showStatus) || (oldShowIdle != showIdle)){
79                         [[adium contactController] updateAllListObjectsForObserver:self];
80                 }
81         }
84 /*!
85  * @brief Update list object's extended status messages
86  */
87 - (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent
89         NSSet           *modifiedAttributes = nil;
91         //Idle time
92     if(inModifiedKeys == nil || 
93            (showIdle && [inModifiedKeys containsObject:@"Idle"]) ||
94            (showStatus && ([inModifiedKeys containsObject:@"StatusMessage"] ||
95                                            [inModifiedKeys containsObject:@"ContactListStatusMessage"] ||
96                                            [inModifiedKeys containsObject:@"StatusName"]))){
97                 NSMutableString *statusMessage = nil;
98                 NSString                *finalMessage = nil;
99                 int                             idle;
100                 
101                 if (showStatus) {
102                         NSAttributedString      *attributedStatusMessage = [[adium contentController] filterAttributedString:[(AIListContact *)inObject contactListStatusMessage]
103                                                                                                                                                                                          usingFilterType:AIFilterDisplay
104                                                                                                                                                                                                    direction:AIFilterIncoming
105                                                                                                                                                                                                          context:inObject];
106                         //Convert attachments to strings so emoticons become their text equivalents, etc.
107                         attributedStatusMessage = [attributedStatusMessage attributedStringByConvertingAttachmentsToStrings];
108                         
109                         statusMessage = [[[[attributedStatusMessage string] stringByTrimmingCharactersInSet:whitespaceAndNewlineCharacterSet] mutableCopy] autorelease];
110                         
111                         //Incredibly long status messages are slow to size, so we crop them to a reasonable length
112                         if([statusMessage length] > STATUS_MAX_LENGTH){
113                                 [statusMessage deleteCharactersInRange:NSMakeRange(STATUS_MAX_LENGTH,
114                                                                                                                                    [statusMessage length] - STATUS_MAX_LENGTH)];
115                         }
116                         
117                         /* Linebreaks in the status message cause vertical alignment issues.
118                          * We will replace line breaks with '/' as is done with multiple lines of a poem displayed on a single line.
119                          * 
120                          * First, we remove duplicate linebreaks. */
121                         while([statusMessage replaceOccurrencesOfString:@"\r\r"
122                                                                                                  withString:@"\r"
123                                                                                                         options:NSLiteralSearch
124                                                                                                           range:NSMakeRange(0,[statusMessage length])]);
125                         while([statusMessage replaceOccurrencesOfString:@"\n\n"
126                                                                                                  withString:@"\n"
127                                                                                                         options:NSLiteralSearch
128                                                                                                           range:NSMakeRange(0,[statusMessage length])]);
129                         while([statusMessage replaceOccurrencesOfString:@"\r\n"
130                                                                                                  withString:@"\n"
131                                                                                                         options:NSLiteralSearch
132                                                                                                           range:NSMakeRange(0,[statusMessage length])]);
133                         
134                         [statusMessage replaceOccurrencesOfString:@"\r"
135                                                                                    withString:@" / "
136                                                                                           options:NSLiteralSearch
137                                                                                                 range:NSMakeRange(0,[statusMessage length])];
138                         [statusMessage replaceOccurrencesOfString:@"\n"
139                                                                                    withString:@" / "
140                                                                                           options:NSLiteralSearch
141                                                                                                 range:NSMakeRange(0,[statusMessage length])];
142                 }
144                 idle = (showIdle ? [inObject integerStatusObjectForKey:@"Idle"] : 0);
146                 //
147                 if(idle > 0 && statusMessage){
148                         finalMessage = [NSString stringWithFormat:@"(%@) %@",[self idleStringForSeconds:idle], statusMessage];
149                 }else if(idle > 0){
150                         finalMessage = [NSString stringWithFormat:@"(%@)",[self idleStringForSeconds:idle]];
151                 }else{
152                         finalMessage = statusMessage;
153                 }
155                 [[inObject displayArrayForKey:@"ExtendedStatus"] setObject:finalMessage withOwner:self];
156                 modifiedAttributes = [NSSet setWithObject:@"ExtendedStatus"];
157         }
158         
159    return(modifiedAttributes);
164  * @brief Determine the idle string
166  * @param seconds Number of seconds idle
167  * @result A localized string to display for the idle time
168  */
169 - (NSString *)idleStringForSeconds:(int)seconds
171         NSString        *idleString;
172         
173         //Create the idle string
174         if(seconds > 599400){//Cap idle at 999 Hours (999*60*60 seconds)
175                 idleString = AILocalizedString(@"Idle",nil);
176         }else if(seconds >= 600){
177                 idleString = [NSString stringWithFormat:@"%ih",seconds / 60];
178         }else if(seconds >= 60){
179                 idleString = [NSString stringWithFormat:@"%i:%02i",seconds / 60, seconds % 60];
180         }else{
181                 idleString = [NSString stringWithFormat:@"%i",seconds];
182         }
183         
184         return(idleString);
187 @end