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 "AIContactController.h"
18 #import "AIMenuController.h"
19 #import "AIOfflineContactHidingPlugin.h"
20 #import "AIPreferenceController.h"
21 #import "AIToolbarController.h"
22 #import <AIUtilities/AIMenuAdditions.h>
23 #import <AIUtilities/AIToolbarUtilities.h>
24 #import <AIUtilities/ESImageAdditions.h>
25 #import <Adium/AIListGroup.h>
26 #import <Adium/AIListObject.h>
27 #import <Adium/AIMetaContact.h>
29 #define PREF_GROUP_CONTACT_LIST_DISPLAY @"Contact List Display"
30 #define SHOW_OFFLINE_MENU_TITLE AILocalizedString(@"Show Offline Contacts",nil)
31 #define KEY_SHOW_OFFLINE_CONTACTS @"Show Offline Contacts"
32 #define OFFLINE_CONTACTS_IDENTIFER @"OfflineContacts"
33 #define KEY_HIDE_CONTACT_LIST_GROUPS @"Hide Contact List Groups"
35 @interface AIOfflineContactHidingPlugin (PRIVATE)
36 - (void)configureOfflineContactHiding;
37 - (void)configurePreferences;
41 * @class AIOfflineContactHidingPlugin
42 * @brief Component to handle showing or hiding offline contacts and hiding empty groups
44 @implementation AIOfflineContactHidingPlugin
51 //Show offline contacts menu item
52 showOfflineMenuItem = [[NSMenuItem alloc] initWithTitle:SHOW_OFFLINE_MENU_TITLE
54 action:@selector(toggleOfflineContactsMenu:)
56 [[adium menuController] addMenuItem:showOfflineMenuItem toLocation:LOC_View_Toggles];
58 //Register preference observer first so values will be correct for the following calls
59 [[adium preferenceController] registerPreferenceObserver:self forGroup:PREF_GROUP_CONTACT_LIST_DISPLAY];
62 NSToolbarItem *toolbarItem;
63 toolbarItem = [AIToolbarUtilities toolbarItemWithIdentifier:OFFLINE_CONTACTS_IDENTIFER
64 label:AILocalizedString(@"Offline Contacts",nil)
65 paletteLabel:AILocalizedString(@"Toggle Offline Contacts",nil)
66 toolTip:AILocalizedString(@"Toggle display of offline contacts",nil)
68 settingSelector:@selector(setImage:)
69 itemContent:[NSImage imageNamed:@"offlinecontacts"
70 forClass:[self class]]
71 action:@selector(toggleOfflineContactsToolbar:)
73 [[adium toolbarController] registerToolbarItem:toolbarItem forToolbarType:@"ContactList"];
75 //Toolbar item registration
76 [[NSNotificationCenter defaultCenter] addObserver:self
77 selector:@selector(toolbarWillAddItem:)
78 name:NSToolbarWillAddItemNotification
85 - (void)uninstallPlugin
87 [[adium contactController] unregisterListObjectObserver:self];
88 [[adium preferenceController] unregisterPreferenceObserver:self];
96 [showOfflineMenuItem release]; showOfflineMenuItem = nil;
97 [[NSNotificationCenter defaultCenter] removeObserver:self];
103 * @brief Preferences changed
105 - (void)preferencesChangedForGroup:(NSString *)group key:(NSString *)key
106 object:(AIListObject *)object preferenceDict:(NSDictionary *)prefDict firstTime:(BOOL)firstTime
108 showOfflineContacts = [[prefDict objectForKey:KEY_SHOW_OFFLINE_CONTACTS] boolValue];
109 useContactListGroups = ![[prefDict objectForKey:KEY_HIDE_CONTACT_LIST_GROUPS] boolValue];
112 //Observe contact and preference changes
113 [[adium contactController] registerListObjectObserver:self];
115 //Refresh visibility of all contacts
116 [[adium contactController] updateAllListObjectsForObserver:self];
118 //Resort the entire list, forcing the visibility changes to hae an immediate effect (we return nil in the
119 //updateListObject: method call, so the contact controller doesn't know we changed anything)
120 [[adium contactController] sortContactList];
123 //Update our menu to reflect the current preferences
124 [showOfflineMenuItem setState:showOfflineContacts];
128 * @brief Toggle the display of offline contacts
130 - (IBAction)toggleOfflineContactsMenu:(id)sender
132 [[adium preferenceController] setPreference:[NSNumber numberWithBool:!showOfflineContacts]
133 forKey:KEY_SHOW_OFFLINE_CONTACTS
134 group:PREF_GROUP_CONTACT_LIST_DISPLAY];
137 - (IBAction)toggleOfflineContactsToolbar:(id)sender
139 [self toggleOfflineContactsMenu:sender];
141 [sender setImage:[NSImage imageNamed:(showOfflineContacts ?
142 @"offlinecontacts_transparent" :
144 forClass:[self class]]];
148 * @brief After the toolbar has added the item we can set up the submenus
150 - (void)toolbarWillAddItem:(NSNotification *)notification
152 NSToolbarItem *item = [[notification userInfo] objectForKey:@"item"];
154 if([[item itemIdentifier] isEqualToString:OFFLINE_CONTACTS_IDENTIFER]){
155 [item setImage:[NSImage imageNamed:(showOfflineContacts ?
156 @"offlinecontacts_transparent" :
158 forClass:[self class]]];
163 * @brief Update visibility of a list object
165 - (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent
167 if (inModifiedKeys == nil ||
168 [inModifiedKeys containsObject:@"Online"] ||
169 [inModifiedKeys containsObject:@"Signed Off"] ||
170 [inModifiedKeys containsObject:@"VisibleObjectCount"]) {
172 if ([inObject isKindOfClass:[AIListContact class]]) {
173 BOOL visible = (showOfflineContacts ||
175 [inObject integerStatusObjectForKey:@"Signed Off"]);
177 if ([inObject isKindOfClass:[AIMetaContact class]]) {
178 //A metaContact must meet the criteria for a contact to be visible and also have at least 1 contained contact
179 [inObject setVisible:(visible &&
180 ([(AIMetaContact *)inObject visibleCount] > 0))];
183 [inObject setVisible:visible];
186 } else if([inObject isKindOfClass:[AIListGroup class]]) {
187 [inObject setVisible:((useContactListGroups) &&
188 (showOfflineContacts || [(AIListGroup *)inObject visibleCount] > 0))];