Add -[AIService pathForDefaultServiceIconOfType:], and use it for replacing %serviceIconImg% in headers. Fixes #12697.
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 <Adium/AIListObject.h>
18 #import <Adium/AIService.h>
19 #import <Adium/AIServiceIcons.h>
20 #import <Adium/AIAccountControllerProtocol.h>
22 static NSMutableDictionary *serviceIcons[NUMBER_OF_SERVICE_ICON_TYPES][NUMBER_OF_ICON_DIRECTIONS];
24 static NSString *serviceIconBasePath = nil;
25 static NSDictionary *serviceIconNames[NUMBER_OF_SERVICE_ICON_TYPES];
27 @interface AIServiceIcons ()
28 + (NSImage *)defaultServiceIconForType:(AIServiceIconType)type serviceID:(NSString *)serviceID;
31 @implementation AIServiceIcons
35 if (self == [AIServiceIcons class]) {
38 //Allocate our service icon cache
39 for (i = 0; i < NUMBER_OF_SERVICE_ICON_TYPES; i++) {
40 for (j = 0; j < NUMBER_OF_ICON_DIRECTIONS; j++) {
41 serviceIcons[i][j] = [[NSMutableDictionary alloc] init];
47 //Retrive the correct service icon for a contact
48 + (NSImage *)serviceIconForObject:(AIListObject *)inObject type:(AIServiceIconType)iconType direction:(AIIconDirection)iconDirection
50 return [self serviceIconForService:inObject.service type:iconType direction:iconDirection];
53 //Retrieve the correct service icon for a service
54 + (NSImage *)serviceIconForService:(AIService *)service type:(AIServiceIconType)iconType direction:(AIIconDirection)iconDirection
56 NSImage *serviceIcon = [self serviceIconForServiceID:service.serviceID type:iconType direction:iconDirection];
58 if (!serviceIcon && service) {
59 //If the icon pack doesn't supply a service icon, query the service itself
60 serviceIcon = [service defaultServiceIconOfType:iconType];
63 if (iconDirection == AIIconFlipped) [serviceIcon setFlipped:YES];
64 [serviceIcons[iconType][iconDirection] setObject:serviceIcon forKey:service.serviceID];
70 + (NSString *)pathForServiceIconForServiceID:(NSString *)serviceID type:(AIServiceIconType)iconType
72 NSString *iconName = [serviceIconNames[iconType] objectForKey:serviceID];
75 return [serviceIconBasePath stringByAppendingPathComponent:iconName];
77 AIService *service = [adium.accountController firstServiceWithServiceID:serviceID];
79 return [service pathForDefaultServiceIconOfType:iconType];
86 //Retrieve the correct service icon for a service by ID
87 + (NSImage *)serviceIconForServiceID:(NSString *)serviceID type:(AIServiceIconType)iconType direction:(AIIconDirection)iconDirection
91 //Retrieve the service icon from our cache
92 serviceIcon = [serviceIcons[iconType][iconDirection] objectForKey:serviceID];
94 //Load the service icon if necessary
96 NSString *path = [self pathForServiceIconForServiceID:serviceID type:iconType];
99 serviceIcon = [[NSImage alloc] initWithContentsOfFile:path];
101 AIService *service = [adium.accountController firstServiceWithServiceID:serviceID];
103 serviceIcon = [[service defaultServiceIconOfType:iconType] retain];
108 if (iconDirection == AIIconFlipped) [serviceIcon setFlipped:YES];
109 [serviceIcons[iconType][iconDirection] setObject:serviceIcon forKey:serviceID];
110 [serviceIcon release];
112 //Attempt to load the default service icon
113 serviceIcon = [self defaultServiceIconForType:iconType serviceID:serviceID];
115 //Cache the default service icon (until the pack is changed) so we have it immediately next time
116 if (iconDirection == AIIconFlipped) [serviceIcon setFlipped:YES];
117 [serviceIcons[iconType][iconDirection] setObject:serviceIcon forKey:serviceID];
125 //Set the active service icon pack
126 + (BOOL)setActiveServiceIconsFromPath:(NSString *)inPath
128 NSDictionary *serviceIconDict = [NSDictionary dictionaryWithContentsOfFile:[inPath stringByAppendingPathComponent:@"Icons.plist"]];
130 if (serviceIconDict && [[serviceIconDict objectForKey:@"AdiumSetVersion"] intValue] == 1) {
131 [serviceIconBasePath release];
132 serviceIconBasePath = [inPath retain];
134 [serviceIconNames[AIServiceIconSmall] release];
135 serviceIconNames[AIServiceIconSmall] = [[serviceIconDict objectForKey:@"Interface-Small"] retain];
137 [serviceIconNames[AIServiceIconLarge] release];
138 serviceIconNames[AIServiceIconLarge] = [[serviceIconDict objectForKey:@"Interface-Large"] retain];
140 [serviceIconNames[AIServiceIconList] release];
141 serviceIconNames[AIServiceIconList] = [[serviceIconDict objectForKey:@"List"] retain];
143 //Clear out the service icon cache
146 for (i = 0; i < NUMBER_OF_SERVICE_ICON_TYPES; i++) {
147 for (j = 0; j < NUMBER_OF_ICON_DIRECTIONS; j++) {
148 [serviceIcons[i][j] removeAllObjects];
152 [[NSNotificationCenter defaultCenter] postNotificationName:AIServiceIconSetDidChangeNotification
161 #define PREVIEW_MENU_IMAGE_SIZE 13
162 #define PREVIEW_MENU_IMAGE_MARGIN 2
164 + (NSImage *)previewMenuImageForIconPackAtPath:(NSString *)inPath
167 NSDictionary *iconDict;
169 image = [[NSImage alloc] initWithSize:NSMakeSize((PREVIEW_MENU_IMAGE_SIZE + PREVIEW_MENU_IMAGE_MARGIN) * 4,
170 PREVIEW_MENU_IMAGE_SIZE)];
172 iconDict = [NSDictionary dictionaryWithContentsOfFile:[inPath stringByAppendingPathComponent:@"Icons.plist"]];
174 if (iconDict && [[iconDict objectForKey:@"AdiumSetVersion"] intValue] == 1) {
175 NSDictionary *previewIconNames = [iconDict objectForKey:@"List"];
176 NSEnumerator *enumerator = [[NSArray arrayWithObjects:@"AIM",@"Jabber",@"MSN",@"Yahoo!",nil] objectEnumerator];
181 while ((iconID = [enumerator nextObject])) {
182 NSString *anIconPath = [inPath stringByAppendingPathComponent:[previewIconNames objectForKey:iconID]];
185 if ((anIcon = [[[NSImage alloc] initWithContentsOfFile:anIconPath] autorelease])) {
186 NSSize anIconSize = [anIcon size];
187 NSRect targetRect = NSMakeRect(xOrigin, 0, PREVIEW_MENU_IMAGE_SIZE, PREVIEW_MENU_IMAGE_SIZE);
189 if (anIconSize.width < targetRect.size.width) {
190 float difference = (targetRect.size.width - anIconSize.width)/2;
192 targetRect.size.width -= difference;
193 targetRect.origin.x += difference;
196 if (anIconSize.height < targetRect.size.height) {
197 float difference = (targetRect.size.height - anIconSize.height)/2;
199 targetRect.size.height -= difference;
200 targetRect.origin.y += difference;
203 [anIcon drawInRect:targetRect
204 fromRect:NSMakeRect(0,0,anIconSize.width,anIconSize.height)
205 operation:NSCompositeCopy
208 //Shift right in preparation for next image
209 xOrigin += PREVIEW_MENU_IMAGE_SIZE + PREVIEW_MENU_IMAGE_MARGIN;
215 return [image autorelease];
218 #pragma mark Default loading
220 #define PREF_GROUP_APPEARANCE @"Appearance"
221 #define KEY_SERVICE_ICON_PACK @"Service Icon Pack"
223 + (NSImage *)defaultServiceIconForType:(AIServiceIconType)type serviceID:(NSString *)serviceID
225 NSString *defaultName, *defaultPath;
226 NSDictionary *serviceIconDict;
227 NSImage *defaultServiceIcon = nil;
229 defaultName = [adium.preferenceController defaultPreferenceForKey:KEY_SERVICE_ICON_PACK
230 group:PREF_GROUP_APPEARANCE
232 defaultPath = [adium pathOfPackWithName:defaultName
233 extension:@"AdiumServiceIcons"
234 resourceFolderName:@"Service Icons"];
236 serviceIconDict = [NSDictionary dictionaryWithContentsOfFile:[defaultPath stringByAppendingPathComponent:@"Icons.plist"]];
237 if (serviceIconDict && [[serviceIconDict objectForKey:@"AdiumSetVersion"] intValue] == 1) {
238 NSString *nameKey = nil;
241 case AIServiceIconSmall:
242 nameKey = @"Interface-Small";
244 case AIServiceIconLarge:
245 nameKey = @"Interface-Large";
247 case AIServiceIconList:
253 NSDictionary *defaultServiceIconNames;
254 NSString *thisServiceIconImageName;
256 defaultServiceIconNames = [serviceIconDict objectForKey:nameKey];
257 if ((thisServiceIconImageName = [defaultServiceIconNames objectForKey:serviceID])) {
258 NSString *iconPath = [defaultPath stringByAppendingPathComponent:thisServiceIconImageName];
260 defaultServiceIcon = [[[NSImage alloc] initWithContentsOfFile:iconPath] autorelease];
265 return defaultServiceIcon;