5 // Created by Adam Iser on 5/19/05.
8 #import <Adium/AIServiceMenu.h>
9 #import <Adium/AIAccountControllerProtocol.h>
10 #import <Adium/AIService.h>
11 #import <Adium/AIServiceIcons.h>
12 #import <AIUtilities/AIMenuAdditions.h>
15 * @class AIServiceMenu
16 * @brief Class to provide a menu of services
18 * See menuOfServicesWithTarget:activeServicesOnly:longDescription:format:
20 @implementation AIServiceMenu
23 * @brief Sort menu items by title
25 int titleSort(NSMenuItem *itemA, NSMenuItem *itemB, void *context)
27 return [[itemA title] compare:[itemB title] options:NSLiteralSearch];
31 * @brief Returns a menu of services.
33 * Each menu item's represented object is the AIService it represents. Services are grouped by 'importance' and sorted alphabetically within groups.
35 * @param target Target on which @selector(selectAccount:) is called when the user makes a selection
36 * @param activeServicesOnly If YES, only services for enabled accounts are included. If NO, all possible services are included.
37 * @param longDescription If YES, use the service's longer (more verbose) description -- for example, AOL Instant Messenger rather than AIM
38 * @param format Allows the description to be placed within a format string. If it is nil, the description alone will be used.
40 + (NSMenu *)menuOfServicesWithTarget:(id)target activeServicesOnly:(BOOL)activeServicesOnly
41 longDescription:(BOOL)longDescription format:(NSString *)format
43 id<AIAccountController> accountController = [[AIObject sharedAdiumInstance] accountController];
44 AIServiceImportance importance;
45 unsigned numberOfItems = 0;
49 NSMenu *menu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
51 serviceArray = (activeServicesOnly ? (id)[accountController activeServicesIncludingCompatibleServices:YES] : (id)[accountController services]);
53 //Divide our menu into sections. This helps separate less important services from the others (sorry guys!)
54 for (importance = AIServicePrimary; importance <= AIServiceUnsupported; importance++) {
55 NSEnumerator *enumerator;
57 NSMutableArray *menuItemArray = [[NSMutableArray alloc] init];
59 unsigned currentNumberOfItems;
60 BOOL addedDivider = NO;
63 currentNumberOfItems = [menu numberOfItems];
64 if (currentNumberOfItems > numberOfItems) {
65 [menu addItem:[NSMenuItem separatorItem]];
66 numberOfItems = currentNumberOfItems + 1;
70 //Insert a menu item for each service of this importance
71 enumerator = [serviceArray objectEnumerator];
72 while ((service = [enumerator nextObject])) {
73 if ([service serviceImportance] == importance) {
74 NSString *description = (longDescription ?
75 [service longDescription] :
76 [service shortDescription]);
78 menuItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:(format ?
79 [NSString stringWithFormat:format,description] :
82 action:@selector(selectServiceType:)
84 [menuItem setRepresentedObject:service];
85 [menuItem setImage:[AIServiceIcons serviceIconForService:service
86 type:AIServiceIconSmall
87 direction:AIIconNormal]];
88 [menuItemArray addObject:menuItem];
93 [menuItemArray sortUsingFunction:titleSort context:NULL];
95 enumerator = [menuItemArray objectEnumerator];
96 while ((menuItem = [enumerator nextObject])) {
97 [menu addItem:menuItem];
100 [menuItemArray release];
102 //If we added a divider but didn't add any items, remove it
103 currentNumberOfItems = [menu numberOfItems];
104 if (addedDivider && (currentNumberOfItems <= numberOfItems) && (currentNumberOfItems > 0)) {
105 [menu removeItemAtIndex:(currentNumberOfItems-1)];
109 return [menu autorelease];