Added Australian English translation to adium-0.8
[adiumx.git] / Source / ESFastUserSwitchingSupportPlugin.m
blob7e860f025e77134af634d5f74b23ffd993252091
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 "AIAccountController.h"
18 //#import "AIContentController.h"
19 #import "AIPreferenceController.h"
20 #import "AISoundController.h"
21 #import "AIStatusController.h"
22 #import "ESFastUserSwitchingSupportPlugin.h"
23 #import <AIUtilities/AIAttributedStringAdditions.h>
24 #import <AIUtilities/CBApplicationAdditions.h>
25 #import <Adium/AIAccount.h>
27 #define FAST_USER_SWITCH_AWAY_STRING AILocalizedString(@"I have switched logged in users. Someone else may be using the computer.","Fast user switching away message")
29 @interface ESFastUserSwitchingSupportPlugin (PRIVATE)
30 -(void)switchHandler:(NSNotification*) notification;
31 @end
33 extern NSString *NSWorkspaceSessionDidBecomeActiveNotification __attribute__((weak_import));
34 extern NSString *NSWorkspaceSessionDidResignActiveNotification __attribute__((weak_import));
36 /*!
37  * @class ESFastUserSwitchingSupportPlugin
38  * @brief Handle Fast User Switching with a changed status and sound muting
39  *
40  * When another user logs in via Fast User Switching (OS X 10.3 and above), this plugin sets a status state if an away
41  * state is not already set.  It also mutes sounds as per the HIG.
42  *
43  * At present, this plugin uses a hardcoded away message.
44  */
45 @implementation ESFastUserSwitchingSupportPlugin
47 /*!
48  * @brief Install plugin
49  *
50  * Has no effect on Jaguar
51  */
52 - (void)installPlugin
54         //only install on Panther.
55         if([NSApp isOnPantherOrBetter]) {
56                 setAwayThroughFastUserSwitch = NO;
57                 setMuteThroughFastUserSwitch = NO;
58                 monitoringFastUserSwitch = NO;
60                 NSNotificationCenter *workspaceCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
61                 [workspaceCenter addObserver:self
62                                     selector:@selector(switchHandler:)
63                                         name:NSWorkspaceSessionDidBecomeActiveNotification
64                                       object:nil];
66                 [workspaceCenter addObserver:self
67                                     selector:@selector(switchHandler:)
68                                         name:NSWorkspaceSessionDidResignActiveNotification
69                                       object:nil];
71                 //Observe preference changes for updating when and how we should automatically change our state
72                 [[adium preferenceController] registerPreferenceObserver:self
73                                                                                                                 forGroup:PREF_GROUP_STATUS_PREFERENCES];
74         }
77 /*!
78  * @brief Preferences changed
79  *
80  * Note whether we are supposed to change states on FUS.
81  */
82 - (void)preferencesChangedForGroup:(NSString *)group key:(NSString *)key
83                                                         object:(AIListObject *)object preferenceDict:(NSDictionary *)prefDict firstTime:(BOOL)firstTime
85         fastUserSwitchStatusID = [prefDict objectForKey:KEY_STATUS_FUS_STATUS_STATE_ID];
87         monitoringFastUserSwitch = (fastUserSwitchStatusID ?
88                                                                 [[prefDict objectForKey:KEY_STATUS_FUS] boolValue] :
89                                                                 NO);
92 /*!
93  * @brief Uninstall plugin
94  *
95  * Has no effect on Jaguar
96  */
97 - (void)uninstallPlugin
99         //only uninstall on Panther
100         if([NSApp isOnPantherOrBetter]) {
101                 //Clear the fast switch away if we had it up before
102                 [self switchHandler:nil];
104                 [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
105                 [[adium preferenceController] unregisterPreferenceObserver:self];
106         }
109 - (void)dealloc
111         [previousStatusStateDict release];
112         [accountsToReconnect release];
113         
114         [super dealloc];
118  * @brief Handle a fast user switch event
120  * Calling this with (notification == nil) is the same as when the user switches back.
121  * Do not call this method in OS X 10.2.x.
123  * @param notification The notification has a name NSWorkspaceSessionDidResignActiveNotification when the user switches away and NSWorkspaceSessionDidBecomeActiveNotification when the user switches back.
124  */
125 -(void)switchHandler:(NSNotification*) notification
127         if (notification &&
128                 [[notification name] isEqualToString:NSWorkspaceSessionDidResignActiveNotification]) {
129                 //Deactivation - go away
131                 //Go away if we aren't already away, noting the current status states for restoration later
132                 NSEnumerator    *enumerator;
133                 AIAccount               *account;
134                 AIStatus                *targetStatusState;
136                 if(!previousStatusStateDict) previousStatusStateDict = [[NSMutableDictionary alloc] init];
138                 targetStatusState = [[adium statusController] statusStateWithUniqueStatusID:fastUserSwitchStatusID];
140                 if(targetStatusState){
141                         enumerator = [[[adium accountController] accountArray] objectEnumerator];
142                         while(account = [enumerator nextObject]){
143                                 AIStatus        *currentStatusState = [account statusState];
144                                 if([currentStatusState statusType] == AIAvailableStatusType){
145                                         //Store the state the account is in at present
146                                         [previousStatusStateDict setObject:currentStatusState
147                                                                                                 forKey:[NSNumber numberWithUnsignedInt:[account hash]]];
149                                         if([account online]){
150                                                 //If online, set the state
151                                                 [account setStatusState:targetStatusState];
152                                                 
153                                                 //If we just brought the account offline, note that it will need to be reconnected later
154                                                 if([targetStatusState statusType] == AIOfflineStatusType){
155                                                         if(!accountsToReconnect) accountsToReconnect = [[NSMutableSet alloc] init];
156                                                         [accountsToReconnect addObject:account];
157                                                 }
158                                         }else{
159                                                 //If offline, set the state without coming online
160                                                 [account setStatusStateAndRemainOffline:targetStatusState];
161                                         }
162                                 }
163                         }
164                 }
166                 //Set a temporary mute if none already exists
167                 NSNumber *oldTempMute = [[adium preferenceController] preferenceForKey:KEY_SOUND_TEMPORARY_MUTE
168                                                                                                                                                  group:PREF_GROUP_SOUNDS];
169                 if (!oldTempMute || ![oldTempMute boolValue]) {
170                         [[adium preferenceController] setPreference:[NSNumber numberWithBool:YES]
171                                                                                                  forKey:KEY_SOUND_TEMPORARY_MUTE
172                                                                                                   group:PREF_GROUP_SOUNDS];
173                         setMuteThroughFastUserSwitch = YES;
174                 }
175         } else {
176                 //Activation - return from away
178                 //Remove the away status flag if we set it originally
179                 NSEnumerator    *enumerator;
180                 AIAccount               *account;
182                 enumerator = [[[adium accountController] accountArray] objectEnumerator];
183                 while(account = [enumerator nextObject]){
184                         AIStatus                *targetStatusState;
185                         NSNumber                *accountHash = [NSNumber numberWithUnsignedInt:[account hash]];
187                         targetStatusState = [previousStatusStateDict objectForKey:accountHash];
188                         if(targetStatusState){
189                                 if([account online] || [accountsToReconnect containsObject:account]){
190                                         //If online or needs to be reconnected, set the previous state, going online if necessary
191                                         [account setStatusState:targetStatusState];
192                                 }else{
193                                         //If offline, set the state without coming online
194                                         [account setStatusStateAndRemainOffline:targetStatusState];
195                                 }
196                         }
197                 }
199                 //Clear the temporary mute if necessary
200                 if (setMuteThroughFastUserSwitch) {
201                         [[adium preferenceController] setPreference:nil
202                                                                                                  forKey:KEY_SOUND_TEMPORARY_MUTE
203                                                                                                   group:PREF_GROUP_SOUNDS];
204                 }
205                 
206                 [previousStatusStateDict release]; previousStatusStateDict = nil;
207                 [accountsToReconnect release]; accountsToReconnect = nil;
208         }
211 @end