2 * Adium is the legal property of its developers, whose names are listed in the copyright file included
3 * with this source distribution.
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.
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.
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.
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;
35 * @class AIDockAccountStatusPlugin
36 * @brief Maintain the dock icon state in relation to global account status
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.
41 @implementation AIDockAccountStatusPlugin
44 * @brief Install plugin
48 //Observe account status changes
49 [[adium contactController] registerListObjectObserver:self];
51 //Observer preference changes
52 [[adium preferenceController] registerPreferenceObserver:self forGroup:PREF_GROUP_GENERAL];
56 * @brief Uninstall plugin
58 - (void)uninstallPlugin
61 [[adium contactController] unregisterListObjectObserver:self];
62 [[adium preferenceController] unregisterPreferenceObserver:self];
63 [[NSNotificationCenter defaultCenter] removeObserver:self];
67 * @brief Handle preference changes
69 * When the active dock icon changes, call updateListObject:keys:silent: to update its state to the global account state
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];
80 * @brief Update the dock icon state in response to an account changing status
82 * If one or more accounts are online, set the Online icon state. Similarly, handle the Connecting, Away, and Idle
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;
91 if (inObject == nil || [inModifiedKeys containsObject:@"Online"]) {
92 if ([self _accountsWithBoolKey:@"Online"]) {
93 [dockController setIconStateNamed:@"Online"];
95 [dockController removeIconStateNamed:@"Online"];
97 shouldUpdateStatus = YES;
100 if (inObject == nil || ([inModifiedKeys containsObject:@"Connecting"] || [inModifiedKeys containsObject:@"Waiting to Reconnect"])) {
101 if ([self _accountsWithBoolKey:@"Connecting"] || [self _accountsWithKey:@"Waiting to Reconnect"]) {
102 [dockController setIconStateNamed:@"Connecting"];
104 [dockController removeIconStateNamed:@"Connecting"];
106 shouldUpdateStatus = YES;
109 if (inObject == nil || [inModifiedKeys containsObject:@"IdleSince"]) {
110 if ([self _accountsWithKey:@"IdleSince"]) {
111 [dockController setIconStateNamed:@"Idle"];
113 [dockController removeIconStateNamed:@"Idle"];
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"];
124 [dockController removeIconStateNamed:@"Away"];
127 if (activeStatusType == AIInvisibleStatusType) {
128 [dockController setIconStateNamed:@"Invisible"];
130 [dockController removeIconStateNamed:@"Invisible"];
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
144 - (BOOL)_accountsWithBoolKey:(NSString *)inKey
146 NSEnumerator *enumerator = [[[adium accountController] accounts] objectEnumerator];
149 while ((account = [enumerator nextObject])) {
150 if ([account integerStatusObjectForKey:inKey] && [account enabled]) return YES;
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
162 - (BOOL)_accountsWithKey:(NSString *)inKey
164 NSEnumerator *enumerator = [[[adium accountController] accounts] objectEnumerator];
167 while ((account = [enumerator nextObject])) {
168 if ([account statusObjectForKey:inKey] && [account enabled]) return YES;