header, schmeader
[adiumx.git] / Source / ESAwayStatusWindowPlugin.m
blob5fd44f7d06ee40f1ce77cb57d2202c23a87ceced
1 //
2 //  ESAwayStatusWindowPlugin.m
3 //  Adium
4 //
5 //  Created by Evan Schoenberg on 4/12/05.
6 //  Copyright 2006 The Adium Team. All rights reserved.
7 //
9 #import "ESAwayStatusWindowPlugin.h"
10 #import "ESAwayStatusWindowController.h"
11 #import <Adium/AIContactControllerProtocol.h>
12 #import <Adium/AIPreferenceControllerProtocol.h>
13 #import "AISoundController.h"
14 #import "AIStatusController.h"
15 #import <Adium/AIAccount.h>
16 #import <Adium/AIListObject.h>
18 /*!
19  * @class ESAwayStatusWindowPlugin
20  * @brief Component to manage the status window optionally displayed when one or more accounts are away
21  *
22  * XXX - This comopnent should move to being an external, included, disabled by default plugin, with more
23  * options added when it is enabled.
24  */
25 @implementation ESAwayStatusWindowPlugin
27 /*!
28  * @brief Install
29  */
30 - (void)installPlugin
32         showStatusWindow = FALSE;
33         awayAccounts = [[NSMutableSet alloc] init];
34         
35         //Observe preference changes for updating if we should show the status window
36         [[adium preferenceController] registerPreferenceObserver:self 
37                                                                                                         forGroup:PREF_GROUP_STATUS_PREFERENCES];
40 - (void)uninstallPlugin
42         [[adium preferenceController] unregisterPreferenceObserver:self];
43         [[adium contactController] unregisterListObjectObserver:self];
46 /*!
47  * @brief Deallocate
48  */
49 - (void)dealloc
51         [awayAccounts release];
53         [super dealloc];
56 /*!
57  * @brief Preferences changed
58  *
59  * Note whether we are supposed to should show the status window, and toggle it if necessary
60  */
61 - (void)preferencesChangedForGroup:(NSString *)group key:(NSString *)key
62                                                         object:(AIListObject *)object preferenceDict:(NSDictionary *)prefDict firstTime:(BOOL)firstTime
64         BOOL oldShowStatusWindow = showStatusWindow;
65         
66         showStatusWindow = [[prefDict objectForKey:KEY_STATUS_SHOW_STATUS_WINDOW] boolValue];
67         
68         if (showStatusWindow != oldShowStatusWindow) {
69                 if (showStatusWindow) {
70                         /* Register as a list object observer, which will update all objects for us immediately leading to the proper
71                          * status window toggling. */
72                         [[adium contactController] registerListObjectObserver:self];
73                 } else {
74                         //Hide the status window if it is currently visible
75                         [ESAwayStatusWindowController updateStatusWindowWithVisibility:NO];
76                         
77                         //Clear our away account tracking
78                         [awayAccounts removeAllObjects];
79                         
80                         //Stop observing list objects
81                         [[adium contactController] unregisterListObjectObserver:self];
82                 }
83         }
85         if (showStatusWindow) {
86                 [ESAwayStatusWindowController setAlwaysOnTop:[[prefDict objectForKey:KEY_STATUS_STATUS_WINDOW_ON_TOP] boolValue]];
87                 [ESAwayStatusWindowController setHideInBackground:[[prefDict objectForKey:KEY_STATUS_STATUS_WINDOW_HIDE_IN_BACKGROUND] boolValue]];
88         }
91 /*!
92  * @brief Account status changed.
93  *
94  * Show or hide our status window as appropriate
95  */
96 - (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent
98         if ([inObject isKindOfClass:[AIAccount class]] &&
99            (!inModifiedKeys || [inModifiedKeys containsObject:@"StatusState"] || [inModifiedKeys containsObject:@"Online"])) {
100                 if ([inObject online] && ([inObject statusType] != AIAvailableStatusType)) {
101                         [awayAccounts addObject:inObject];
102                 } else {
103                         [awayAccounts removeObject:inObject];
104                 }
106                 /* We wait until the next run loop so we can have processed multiple changing accounts at once before updating
107                  * our display, preventing flickering through changes as the global state changes and thereby modifies multiple
108                  * account states in a single invocation.
109                  */
110                 [NSObject cancelPreviousPerformRequestsWithTarget:self
111                                                                                                  selector:@selector(processStatusUpdate)
112                                                                                                    object:nil];
113                 [self performSelector:@selector(processStatusUpdate)
114                                    withObject:nil
115                                    afterDelay:0];
116         }
118         //We don't modify any keys
119         return nil;
122 - (void)processStatusUpdate
124         //Tell the window to update, showing/hiding as necessary
125         [ESAwayStatusWindowController updateStatusWindowWithVisibility:([awayAccounts count] > 0)];     
128 @end