Updating svn:mergeinfo
[adiumx.git] / Source / AIDockAccountStatusPlugin.m
blob09baf0798f4502041c0b625424d60211d8bd69c8
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 "AIDockAccountStatusPlugin.h"
19 #import <Adium/AIAccountControllerProtocol.h>
20 #import <Adium/AIContactControllerProtocol.h>
21 #import <Adium/AIDockControllerProtocol.h>
22 #import <Adium/AIStatusControllerProtocol.h>
23 #import <Adium/AIPreferenceControllerProtocol.h>
24 #import <Adium/AIAccount.h>
25 #import <Adium/AIListObject.h>
26 #import <Adium/AIStatus.h>
28 @interface AIDockAccountStatusPlugin (PRIVATE)
29 - (BOOL)_accountsWithBoolKey:(NSString *)inKey;
30 - (BOOL)_accountsWithKey:(NSString *)inKey;
31 - (void)_updateIconForKey:(NSString *)key;
32 @end
34 /*!
35  * @class AIDockAccountStatusPlugin
36  * @brief Maintain the dock icon state in relation to global account status
37  *
38  * This class manages the dock icon state via the dockController.  It specifies the icon which should be shown based
39  * on an aggregated, global account status.
40  */
41 @implementation AIDockAccountStatusPlugin
43 /*!
44  * @brief Install plugin
45  */
46 - (void)installPlugin
48         //Observe account status changes
49         [[adium contactController] registerListObjectObserver:self];
51     //Observer preference changes
52         [[adium preferenceController] registerPreferenceObserver:self forGroup:PREF_GROUP_GENERAL];
55 /*!
56  * @brief Uninstall plugin
57  */
58 - (void)uninstallPlugin
60     //Remove observers
61         [[adium contactController] unregisterListObjectObserver:self];
62         [[adium preferenceController] unregisterPreferenceObserver:self];
63     [[NSNotificationCenter defaultCenter] removeObserver:self];
66 /*!
67  * @brief Handle preference changes
68  *
69  * When the active dock icon changes, call updateListObject:keys:silent: to update its state to the global account state
70  */
71 - (void)preferencesChangedForGroup:(NSString *)group key:(NSString *)key
72                                                         object:(AIListObject *)object preferenceDict:(NSDictionary *)prefDict firstTime:(BOOL)firstTime
74         if (!key || [key isEqualToString:KEY_ACTIVE_DOCK_ICON]) {
75                 [self updateListObject:nil keys:nil silent:NO];
76         }
79 /*!
80  * @brief Update the dock icon state in response to an account changing status
81  *
82  * If one or more accounts are online, set the Online icon state.  Similarly, handle the Connecting, Away, and Idle
83  * dock icon states.
84  */
85 - (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent
87         if (inObject == nil || [inObject isKindOfClass:[AIAccount class]]) {
88                 id<AIDockController>    dockController = [adium dockController];
89                 BOOL                                    shouldUpdateStatus = NO;
90                 
91                 if (inObject == nil || [inModifiedKeys containsObject:@"Online"]) {
92                         if ([self _accountsWithBoolKey:@"Online"] > 0) {
93                                 [dockController setIconStateNamed:@"Online"];
94                         } else {
95                                 [dockController removeIconStateNamed:@"Online"];
96                         }
97                         shouldUpdateStatus = YES;
98                 }
100                 if (inObject == nil || [inModifiedKeys containsObject:@"Connecting"]) {
101                         if ([self _accountsWithBoolKey:@"Connecting"] > 0) {
102                                 [dockController setIconStateNamed:@"Connecting"];
103                         } else {
104                                 [dockController removeIconStateNamed:@"Connecting"];
105                         }
106                         shouldUpdateStatus = YES;
107                 }
108                 
109                 if (inObject == nil || [inModifiedKeys containsObject:@"IdleSince"]) {
110                         if ([self _accountsWithKey:@"IdleSince"] > 0) {
111                                 [dockController setIconStateNamed:@"Idle"];
112                         } else {
113                                 [dockController removeIconStateNamed:@"Idle"];
114                         }       
115                 }
116                 
117                 if (shouldUpdateStatus || [inModifiedKeys containsObject:@"StatusState"]) {
118                         BOOL                    iconSupportsInvisible = [[adium dockController] currentIconSupportsIconStateNamed:@"Invisible"];
119                         AIStatusType    activeStatusType = [[adium statusController] activeStatusTypeTreatingInvisibleAsAway:!iconSupportsInvisible];
121                         if (activeStatusType == AIAwayStatusType) {
122                                 [dockController setIconStateNamed:@"Away"];
123                         } else {
124                                 [dockController removeIconStateNamed:@"Away"];
125                         }
127                         if (activeStatusType == AIInvisibleStatusType) {
128                                 [dockController setIconStateNamed:@"Invisible"];
129                         } else {
130                                 [dockController removeIconStateNamed:@"Invisible"];
131                         }
132                 }
133         }
135         return nil;
139  * @brief Return if any accounts have a TRUE value for the specified key
141  * @param inKey The status key to search on
142  * @result YES if any account returns TRUE for the boolean status object for inKey
143  */
144 - (BOOL)_accountsWithBoolKey:(NSString *)inKey
146     NSEnumerator    *enumerator = [[[adium accountController] accounts] objectEnumerator];
147     AIAccount       *account;
149     while ((account = [enumerator nextObject])) {
150                 if ([account integerStatusObjectForKey:inKey]) return YES;
151     }
153     return NO;
157  * @brief Return if any accounts have a non-nil value for the specified key
159  * @param inKey The status key to search on
160  * @result YES if any account returns a non-nil value for the status object for inKey
161  */
162 - (BOOL)_accountsWithKey:(NSString *)inKey
164     NSEnumerator    *enumerator = [[[adium accountController] accounts] objectEnumerator];
165     AIAccount       *account;
167     while ((account = [enumerator nextObject])) {
168                 if ([account statusObjectForKey:inKey]) return YES;
169     }
171     return NO;
174 @end