Prevent dragging groups into groups. Fixes #8706
[adiumx.git] / Source / AIAppearancePreferences.m
blob18660d1cc502381e6dd63e3472f2d0d803d89df0
1 /* 
2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
3  * with this source distribution.
4  * 
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.
8  * 
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.
12  * 
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.
15  */
17 #import "AIAppearancePreferences.h"
18 #import "AIAppearancePreferencesPlugin.h"
19 #import "AIDockIconSelectionSheet.h"
20 #import "AIEmoticonPack.h"
21 #import "AIEmoticonPreferences.h"
22 #import "AIListLayoutWindowController.h"
23 #import "AIListThemeWindowController.h"
24 #import <AIUtilities/AIMenuAdditions.h>
25 #import <AIUtilities/AIImageAdditions.h>
26 #import <AIUtilities/AIPopUpButtonAdditions.h>
27 #import <AIUtilities/AIStringAdditions.h>
28 #import <Adium/AIAbstractListController.h>
29 #import <Adium/AIDockControllerProtocol.h>
30 #import <Adium/AIEmoticonControllerProtocol.h>
31 #import <Adium/AIIconState.h>
32 #import <Adium/AIServiceIcons.h>
33 #import <Adium/AIStatusIcons.h>
34 #import <Adium/ESPresetManagementController.h>
35 #import <Adium/ESPresetNameSheetController.h>
36 #import <AIMenuBarIcons.h>
38 #define OLD_LIST_SETTINGS_PATH [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"OldListXtras"]
40 typedef enum {
41         AIEmoticonMenuNone = 1,
42         AIEmoticonMenuMultiple
43 } AIEmoticonMenuTag;
45 @interface AIAppearancePreferences (PRIVATE)
46 - (NSMenu *)_windowStyleMenu;
47 - (NSMenu *)_dockIconMenu;
48 - (NSMenu *)_emoticonPackMenu;
49 - (NSMenu *)_statusIconsMenu;
50 - (NSMenu *)_serviceIconsMenu;
51 - (NSMenu *)_listLayoutMenu;
52 - (NSMenu *)_colorThemeMenu;
53 - (void)_rebuildEmoticonMenuAndSelectActivePack;
54 - (NSMenu *)_iconPackMenuForPacks:(NSArray *)packs class:(Class)iconClass;
55 - (void)_addWindowStyleOption:(NSString *)option withTag:(int)tag toMenu:(NSMenu *)menu;
56 - (void)_updateSliderValues;
57 - (void)xtrasChanged:(NSNotification *)notification;
59 - (void)configureDockIconMenu;
60 - (void)configureStatusIconsMenu;
61 - (void)configureServiceIconsMenu;
62 - (void)configureMenuBarIconsMenu;
63 @end
65 @implementation AIAppearancePreferences
67 /*!
68  * @brief Preference pane properties
69  */
70 - (NSString *)paneIdentifier
72         return @"Appearance";
74 - (NSString *)paneName{
75     return AILocalizedString(@"Appearance","Appearance preferences label");
77 - (NSString *)nibName{
78     return @"AppearancePrefs";
80 - (NSImage *)paneIcon
82         return [NSImage imageNamed:@"pref-appearance" forClass:[self class]];
85 /*!
86  * @brief Configure the preference view
87  */
88 - (void)viewDidLoad
89 {       
90         //Other list options
91         [popUp_windowStyle setMenu:[self _windowStyleMenu]];
92                 
93         //Observe preference changes
94         [[adium preferenceController] registerPreferenceObserver:self forGroup:PREF_GROUP_EMOTICONS];
95         [[adium preferenceController] registerPreferenceObserver:self forGroup:PREF_GROUP_APPEARANCE];
97         //Observe xtras changes
98         [[adium notificationCenter] addObserver:self
99                                                                    selector:@selector(xtrasChanged:)
100                                                                            name:AIXtrasDidChangeNotification
101                                                                          object:nil];   
102         [self xtrasChanged:nil];
106  * @brief View will close
107  */
108 - (void)viewWillClose
110         [[adium preferenceController] unregisterPreferenceObserver:self];
111         
112         [[adium notificationCenter] removeObserver:self];
116  * @brief Xtras changed, update our menus to reflect the new Xtras
117  */
118 - (void)xtrasChanged:(NSNotification *)notification
120         NSString                *type = [[notification object] lowercaseString];
122         if (!type || [type isEqualToString:@"adiumemoticonset"]) {
123                 [self _rebuildEmoticonMenuAndSelectActivePack];
124         }
125         
126         if (!type || [type isEqualToString:@"adiumicon"]) {
127                 [self configureDockIconMenu];
128         }
129         
130         if (!type || [type isEqualToString:@"adiumserviceicons"]) {
131                 [self configureServiceIconsMenu];
132         }
133         
134         if (!type || [type isEqualToString:@"adiumstatusicons"]) {
135                 [self configureStatusIconsMenu];
136         }
137         
138         if (!type || [type isEqualToString:@"adiummenubaricons"]) {
139                 [self configureMenuBarIconsMenu];
140         }
141         
142         if (!type || [type isEqualToString:@"listtheme"]) {
143                 [popUp_colorTheme setMenu:[self _colorThemeMenu]];
144                 [popUp_colorTheme selectItemWithRepresentedObject:[[adium preferenceController] preferenceForKey:KEY_LIST_THEME_NAME
145                                                                                                                                                                                                    group:PREF_GROUP_APPEARANCE]];
146         }
148         if (!type || [type isEqualToString:@"listlayout"]) {
149                 [popUp_listLayout setMenu:[self _listLayoutMenu]];
150                 [popUp_listLayout selectItemWithRepresentedObject:[[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME
151                                                                                                                                                                                                    group:PREF_GROUP_APPEARANCE]];
152         }
156  * @brief Preferences changed
158  * Update controls in our view to reflect the changed preferences
159  */
160 - (void)preferencesChangedForGroup:(NSString *)group key:(NSString *)key object:(AIListObject *)object
161                                         preferenceDict:(NSDictionary *)prefDict firstTime:(BOOL)firstTime
163         //Emoticons
164         if ([group isEqualToString:PREF_GROUP_EMOTICONS] && !firstTime) {
165                 [self _rebuildEmoticonMenuAndSelectActivePack];
166         }
167         
168         //Appearance
169         if ([group isEqualToString:PREF_GROUP_APPEARANCE]) {
170                 
171                 //Horizontal resizing label
172                 if (firstTime || 
173                    [key isEqualToString:KEY_LIST_LAYOUT_WINDOW_STYLE] ||
174                    [key isEqualToString:KEY_LIST_LAYOUT_HORIZONTAL_AUTOSIZE]) {
175                         
176                         int windowMode = [[prefDict objectForKey:KEY_LIST_LAYOUT_WINDOW_STYLE] intValue];
177                         BOOL horizontalAutosize = [[prefDict objectForKey:KEY_LIST_LAYOUT_HORIZONTAL_AUTOSIZE] boolValue];
178                         
179                         if (windowMode == AIContactListWindowStyleStandard) {
180                                 //In standard mode, disable the horizontal autosizing slider if horiztonal autosizing is off
181                                 [textField_horizontalWidthText setLocalizedString:AILocalizedString(@"Maximum Width:",nil)];
182                                 [slider_horizontalWidth setEnabled:horizontalAutosize];
183                                 
184                         } else {
185                                 //In all the borderless transparent modes, the horizontal autosizing slider becomes the
186                                 //horizontal sizing slider when autosizing is off
187                                 if (horizontalAutosize) {
188                                         [textField_horizontalWidthText setLocalizedString:AILocalizedString(@"Maximum Width:",nil)];
189                                 } else {
190                                         [textField_horizontalWidthText setLocalizedString:AILocalizedString(@"Width:",nil)];                    
191                                 }
192                                 [slider_horizontalWidth setEnabled:YES];
193                         }
194                         
195                 }
197                 //Selected menu items
198                 if (firstTime || [key isEqualToString:KEY_STATUS_ICON_PACK]) {
199                         [popUp_statusIcons selectItemWithTitle:[prefDict objectForKey:KEY_STATUS_ICON_PACK]];
200                         
201                         //If the prefDict's item isn't present, we're using the default, so select that one
202                         if (![popUp_statusIcons selectedItem]) {
203                                 [popUp_statusIcons selectItemWithTitle:[[adium preferenceController] defaultPreferenceForKey:KEY_STATUS_ICON_PACK
204                                                                                                                                                                                                                 group:PREF_GROUP_APPEARANCE
205                                                                                                                                                                                                            object:nil]];
206                         }                       
207                 }
208                 if (firstTime || [key isEqualToString:KEY_SERVICE_ICON_PACK]) {
209                         [popUp_serviceIcons selectItemWithTitle:[prefDict objectForKey:KEY_SERVICE_ICON_PACK]];
210                         
211                         //If the prefDict's item isn't present, we're using the default, so select that one
212                         if (![popUp_serviceIcons selectedItem]) {
213                                 [popUp_serviceIcons selectItemWithTitle:[[adium preferenceController] defaultPreferenceForKey:KEY_SERVICE_ICON_PACK
214                                                                                                                                                                                                                 group:PREF_GROUP_APPEARANCE
215                                                                                                                                                                                                            object:nil]];
216                         }
217                 }
218                 if (firstTime || [key isEqualToString:KEY_MENU_BAR_ICONS]) {
219                         [popUp_menuBarIcons selectItemWithTitle:[prefDict objectForKey:KEY_MENU_BAR_ICONS]];
220                         
221                         //If the prefDict's item isn't present, we're using the default, so select that one
222                         if (![popUp_menuBarIcons selectedItem]) {
223                                 [popUp_menuBarIcons selectItemWithTitle:[[adium preferenceController] defaultPreferenceForKey:KEY_MENU_BAR_ICONS
224                                                                                                                                                                                                                 group:PREF_GROUP_APPEARANCE
225                                                                                                                                                                                                            object:nil]];
226                         }
227                 }
228                 if (firstTime || [key isEqualToString:KEY_LIST_LAYOUT_NAME]) {
229                         [popUp_listLayout selectItemWithRepresentedObject:[prefDict objectForKey:KEY_LIST_LAYOUT_NAME]];
230                 }
231                 if (firstTime || [key isEqualToString:KEY_LIST_THEME_NAME]) {
232                         [popUp_colorTheme selectItemWithRepresentedObject:[prefDict objectForKey:KEY_LIST_THEME_NAME]]; 
233                 }       
234                 if (firstTime || [key isEqualToString:KEY_ACTIVE_DOCK_ICON]) {
235                         [popUp_dockIcon selectItemWithRepresentedObject:[prefDict objectForKey:KEY_ACTIVE_DOCK_ICON]];
236                 }
237                 if (firstTime) {
238                         [popUp_windowStyle compatibleSelectItemWithTag:[[prefDict objectForKey:KEY_LIST_LAYOUT_WINDOW_STYLE] intValue]];        
239                         [checkBox_verticalAutosizing setState:[[prefDict objectForKey:KEY_LIST_LAYOUT_VERTICAL_AUTOSIZE] boolValue]];
240                         [checkBox_horizontalAutosizing setState:[[prefDict objectForKey:KEY_LIST_LAYOUT_HORIZONTAL_AUTOSIZE] boolValue]];
241                         [slider_windowOpacity setFloatValue:([[prefDict objectForKey:KEY_LIST_LAYOUT_WINDOW_OPACITY] floatValue] * 100.0)];
242                         [slider_horizontalWidth setIntValue:[[prefDict objectForKey:KEY_LIST_LAYOUT_HORIZONTAL_WIDTH] intValue]];
243                         [self _updateSliderValues];
244                 }
245         }
249  * @brief Rebuild the emoticon menu
250  */
251 - (void)_rebuildEmoticonMenuAndSelectActivePack
253         [popUp_emoticons setMenu:[self _emoticonPackMenu]];
254         
255         //Update the selected pack
256         NSArray *activeEmoticonPacks = [[adium emoticonController] activeEmoticonPacks];
257         int             numActivePacks = [activeEmoticonPacks count];
258         
259         if (numActivePacks == 0) {
260                 [popUp_emoticons compatibleSelectItemWithTag:AIEmoticonMenuNone];
261         } else if (numActivePacks > 1) {
262                 [popUp_emoticons compatibleSelectItemWithTag:AIEmoticonMenuMultiple];
263         } else {
264                 [popUp_emoticons selectItemWithRepresentedObject:[activeEmoticonPacks objectAtIndex:0]];
265         }
269  * @brief Save changed preferences
270  */
271 - (IBAction)changePreference:(id)sender
273         if (sender == popUp_statusIcons) {
274         [[adium preferenceController] setPreference:[[sender selectedItem] title]
275                                              forKey:KEY_STATUS_ICON_PACK
276                                               group:PREF_GROUP_APPEARANCE];
277                 
278         } else if (sender == popUp_serviceIcons) {
279         [[adium preferenceController] setPreference:[[sender selectedItem] title]
280                                              forKey:KEY_SERVICE_ICON_PACK
281                                               group:PREF_GROUP_APPEARANCE];
282         } else if (sender == popUp_menuBarIcons) {
283         [[adium preferenceController] setPreference:[[sender selectedItem] title]
284                                              forKey:KEY_MENU_BAR_ICONS
285                                               group:PREF_GROUP_APPEARANCE];     
286         } else if (sender == popUp_dockIcon) {
287         [[adium preferenceController] setPreference:[[sender selectedItem] representedObject]
288                                              forKey:KEY_ACTIVE_DOCK_ICON
289                                               group:PREF_GROUP_APPEARANCE];
290                 
291         } else if (sender == popUp_listLayout) {
292         [[adium preferenceController] setPreference:[[sender selectedItem] title]
293                                              forKey:KEY_LIST_LAYOUT_NAME
294                                               group:PREF_GROUP_APPEARANCE];             
295                 
296         } else if (sender == popUp_colorTheme) {
297                 [[adium preferenceController] setPreference:[[sender selectedItem] title]
298                                                                                          forKey:KEY_LIST_THEME_NAME
299                                                                                           group:PREF_GROUP_APPEARANCE];
301         } else if (sender == popUp_windowStyle) {
302                 [[adium preferenceController] setPreference:[NSNumber numberWithInt:[[sender selectedItem] tag]]
303                                                                                          forKey:KEY_LIST_LAYOUT_WINDOW_STYLE
304                                                                                           group:PREF_GROUP_APPEARANCE];
305                 
306     } else if (sender == checkBox_verticalAutosizing) {
307         [[adium preferenceController] setPreference:[NSNumber numberWithBool:[sender state]]
308                                              forKey:KEY_LIST_LAYOUT_VERTICAL_AUTOSIZE
309                                               group:PREF_GROUP_APPEARANCE];
310                 
311     } else if (sender == checkBox_horizontalAutosizing) {
312         [[adium preferenceController] setPreference:[NSNumber numberWithBool:[sender state]]
313                                              forKey:KEY_LIST_LAYOUT_HORIZONTAL_AUTOSIZE
314                                               group:PREF_GROUP_APPEARANCE];
316     } else if (sender == slider_windowOpacity) {
317         [[adium preferenceController] setPreference:[NSNumber numberWithFloat:([sender floatValue] / 100.0)]
318                                              forKey:KEY_LIST_LAYOUT_WINDOW_OPACITY
319                                               group:PREF_GROUP_APPEARANCE];
320                 [self _updateSliderValues];
321                 
322         } else if (sender == slider_horizontalWidth) {
323                 int newValue = [sender intValue];
324                 int oldValue = [[[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_HORIZONTAL_WIDTH
325                                                                                                                                  group:PREF_GROUP_APPEARANCE] intValue];
326                 if (newValue != oldValue) { 
327                         [[adium preferenceController] setPreference:[NSNumber numberWithInt:newValue]
328                                                                                                  forKey:KEY_LIST_LAYOUT_HORIZONTAL_WIDTH
329                                                                                                   group:PREF_GROUP_APPEARANCE];
330                         [self _updateSliderValues];
331                 }
332                 
333         } else if (sender == popUp_emoticons) {
334                 if ([[sender selectedItem] tag] != AIEmoticonMenuMultiple) {
335                         //Disable all active emoticons
336                         NSArray                 *activePacks = [[[[adium emoticonController] activeEmoticonPacks] mutableCopy] autorelease];
337                         NSEnumerator    *enumerator = [activePacks objectEnumerator];
338                         AIEmoticonPack  *pack, *selectedPack;
339                         
340                         selectedPack = [[sender selectedItem] representedObject];
341                         
342                         [[adium preferenceController] delayPreferenceChangedNotifications:YES];
344                         while ((pack = [enumerator nextObject])) {
345                                 [[adium emoticonController] setEmoticonPack:pack enabled:NO];
346                         }
347                         
348                         //Enable the selected pack
349                         if (selectedPack) [[adium emoticonController] setEmoticonPack:selectedPack enabled:YES];
351                         [[adium preferenceController] delayPreferenceChangedNotifications:NO];
352                 }
353         }
358  */
359 - (void)_updateSliderValues
361         [textField_windowOpacity setStringValue:[NSString stringWithFormat:@"%i%%", (int)[slider_windowOpacity floatValue]]];
362         [textField_horizontalWidthIndicator setStringValue:[NSString stringWithFormat:@"%ipx",[slider_horizontalWidth intValue]]];
366 //Emoticons ------------------------------------------------------------------------------------------------------------
367 #pragma mark Emoticons
370  */
371 - (IBAction)customizeEmoticons:(id)sender
373         [AIEmoticonPreferences showEmoticionCustomizationOnWindow:[[self view] window]];
378  */
379 - (NSMenu *)_emoticonPackMenu
381         NSMenu                  *menu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
382         NSEnumerator    *enumerator = [[[adium emoticonController] availableEmoticonPacks] objectEnumerator];
383         AIEmoticonPack  *pack;
384         NSMenuItem              *menuItem;
385                 
386         //Add the "No Emoticons" option
387         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:AILocalizedString(@"None",nil)
388                                                                                                                                          target:nil
389                                                                                                                                          action:nil
390                                                                                                                           keyEquivalent:@""] autorelease];
391         [menuItem setImage:[NSImage imageNamed:@"emoticonBlank" forClass:[self class]]];
392         [menuItem setTag:AIEmoticonMenuNone];
393         [menu addItem:menuItem];
394         
395         //Add the "Multiple packs selected" option
396         if ([[[adium emoticonController] activeEmoticonPacks] count] > 1) {
397                 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:AILocalizedString(@"Multiple Packs Selected",nil)
398                                                                                                                                                  target:nil
399                                                                                                                                                  action:nil
400                                                                                                                                   keyEquivalent:@""] autorelease];
401                 [menuItem setImage:[NSImage imageNamed:@"emoticonBlank" forClass:[self class]]];
402                 [menuItem setTag:AIEmoticonMenuMultiple];
403                 [menu addItem:menuItem];
404         }
406         //Divider
407         [menu addItem:[NSMenuItem separatorItem]];
409         //Emoticon Packs
410         while ((pack = [enumerator nextObject])) {
411                 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:[pack name]
412                                                                                                                                                  target:nil
413                                                                                                                                                  action:nil
414                                                                                                                                   keyEquivalent:@""] autorelease];
415                 [menuItem setRepresentedObject:pack];
416                 [menuItem setImage:[pack menuPreviewImage]];
417                 [menu addItem:menuItem];
418         }
420         return [menu autorelease];
424 //Contact list options -------------------------------------------------------------------------------------------------
425 #pragma mark Contact list options
428  */
429 - (NSMenu *)_windowStyleMenu
431         NSMenu  *menu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
433         [self _addWindowStyleOption:AILocalizedString(@"Regular Window",nil)
434                                                 withTag:AIContactListWindowStyleStandard
435                                                  toMenu:menu];
436         [menu addItem:[NSMenuItem separatorItem]];
437         [self _addWindowStyleOption:AILocalizedString(@"Borderless Window",nil)
438                                                 withTag:AIContactListWindowStyleBorderless
439                                                  toMenu:menu];
440         [self _addWindowStyleOption:AILocalizedString(@"Group Bubbles",nil)
441                                                 withTag:AIContactListWindowStyleGroupBubbles
442                                                  toMenu:menu];
443         [self _addWindowStyleOption:AILocalizedString(@"Contact Bubbles",nil)
444                                                 withTag:AIContactListWindowStyleContactBubbles
445                                                  toMenu:menu];
446         [self _addWindowStyleOption:AILocalizedString(@"Contact Bubbles (To Fit)",nil)
447                                                 withTag:AIContactListWindowStyleContactBubbles_Fitted
448                                                  toMenu:menu];
450         return [menu autorelease];
452 - (void)_addWindowStyleOption:(NSString *)option withTag:(int)tag toMenu:(NSMenu *)menu{
453     NSMenuItem  *menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:option
454                                                                                                                                                                   target:nil
455                                                                                                                                                                   action:nil
456                                                                                                                                                    keyEquivalent:@""] autorelease];
457         [menuItem setTag:tag];
458         [menu addItem:menuItem];
462 //Contact list layout & theme ----------------------------------------------------------------------------------------
463 #pragma mark Contact list layout & theme
465 + (void) migrateOldListSettingsIfNeeded
467         id<AIPreferenceController> prefController = [[AIObject sharedAdiumInstance] preferenceController];
468         NSFileManager *manager = [NSFileManager defaultManager];
469         NSString *theme = [NSString stringWithFormat:@"%@/%@/%@.%@", 
470                                                         [[NSBundle mainBundle] resourcePath], 
471                                                         LIST_THEME_FOLDER,
472                                                         [prefController preferenceForKey:KEY_LIST_THEME_NAME group:PREF_GROUP_APPEARANCE],
473                                                         LIST_THEME_EXTENSION];
474         if(![manager fileExistsAtPath:theme])
475         {
476                 NSString *oldTheme = [OLD_LIST_SETTINGS_PATH stringByAppendingPathComponent:[theme lastPathComponent]];
477                 if([manager fileExistsAtPath:oldTheme])
478                         [manager movePath:oldTheme toPath:theme handler:nil];
479         }
480         NSString *layout = [NSString stringWithFormat:@"%@/%@/%@.%@", 
481                                                         [[NSBundle mainBundle] resourcePath], 
482                                                         LIST_THEME_FOLDER, 
483                                                         [prefController preferenceForKey:KEY_LIST_LAYOUT_NAME group:PREF_GROUP_APPEARANCE],
484                                                         @"ListLayout"];
485         if(![manager fileExistsAtPath:layout])
486         {
487                 NSString *oldLayout = [OLD_LIST_SETTINGS_PATH stringByAppendingPathComponent:[layout lastPathComponent]];
488                 if([manager fileExistsAtPath:oldLayout])
489                         [manager movePath:oldLayout toPath:layout handler:nil];
490         }
494  * @brief Create a new theme
495  */
496 - (IBAction)createListTheme:(id)sender
498         NSString *theme = [[adium preferenceController] preferenceForKey:KEY_LIST_THEME_NAME group:PREF_GROUP_APPEARANCE];      
499         
500         [ESPresetNameSheetController showPresetNameSheetWithDefaultName:[theme stringByAppendingString:@" Copy"]
501                                                                                                         explanatoryText:AILocalizedString(@"Enter a unique name for this new theme.",nil)
502                                                                                                                    onWindow:[[self view] window]
503                                                                                                         notifyingTarget:self
504                                                                                                                    userInfo:@"theme"];
508  * @brief Customize the active theme
509  */
510 - (IBAction)customizeListTheme:(id)sender
512         NSString *theme = [[adium preferenceController] preferenceForKey:KEY_LIST_THEME_NAME group:PREF_GROUP_APPEARANCE];      
513         
514         //Allow alpha in our color pickers
515         [[NSColorPanel sharedColorPanel] setShowsAlpha:YES];
517         [AIListThemeWindowController editListThemeWithName:theme
518                                                                                           onWindow:[[self view] window]
519                                                                            notifyingTarget:self];
523  * @brief Save (or revert) changes made when editing a theme
524  */
525 - (void)listThemeEditorWillCloseWithChanges:(BOOL)saveChanges forThemeNamed:(NSString *)name
527         if (saveChanges) {
528                 //Update the modified theme
529                 if ([plugin createSetFromPreferenceGroup:PREF_GROUP_LIST_THEME
530                                                                                 withName:name
531                                                                            extension:LIST_THEME_EXTENSION
532                                                                                 inFolder:LIST_THEME_FOLDER]) {
533                         
534                         [[adium preferenceController] setPreference:name
535                                                                                                  forKey:KEY_LIST_THEME_NAME
536                                                                                                   group:PREF_GROUP_APPEARANCE];
537                 }
538                 
539         } else {
540                 //Revert back to selected theme
541                 NSString *theme = [[adium preferenceController] preferenceForKey:KEY_LIST_THEME_NAME group:PREF_GROUP_APPEARANCE];      
542                 
543                 [plugin applySetWithName:theme
544                                            extension:LIST_THEME_EXTENSION
545                                                 inFolder:LIST_THEME_FOLDER
546                            toPreferenceGroup:PREF_GROUP_LIST_THEME];
547         }
548         
550         //No longer allow alpha in our color pickers
551         [[NSColorPanel sharedColorPanel] setShowsAlpha:NO];
555  * @brief Manage available themes
556  */
557 - (void)manageListThemes:(id)sender
559         _listThemes = [plugin availableThemeSets];
560         [ESPresetManagementController managePresets:_listThemes
561                                                                          namedByKey:@"name"
562                                                                            onWindow:[[self view] window]
563                                                                    withDelegate:self];
564         
565         [popUp_colorTheme selectItemWithRepresentedObject:[[adium preferenceController] preferenceForKey:KEY_LIST_THEME_NAME
566                                                                                                                                                                                            group:PREF_GROUP_APPEARANCE]];               
570  * @brief Create a new layout
571  */
572 - (IBAction)createListLayout:(id)sender
574         NSString *layout = [[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME group:PREF_GROUP_APPEARANCE];
575         
576         [ESPresetNameSheetController showPresetNameSheetWithDefaultName:[layout stringByAppendingString:@" Copy"]
577                                                                                                         explanatoryText:AILocalizedString(@"Enter a unique name for this new layout.",nil)
578                                                                                                                    onWindow:[[self view] window]
579                                                                                                         notifyingTarget:self
580                                                                                                                    userInfo:@"layout"];
584  * @brief Customize the active layout
585  */
586 - (IBAction)customizeListLayout:(id)sender
588         NSString *theme = [[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME group:PREF_GROUP_APPEARANCE];     
589         
590         //Allow alpha in our color pickers
591         [[NSColorPanel sharedColorPanel] setShowsAlpha:YES];    
593         [AIListLayoutWindowController editListLayoutWithName:theme
594                                                                                           onWindow:[[self view] window]
595                                                                            notifyingTarget:self];
599  * @brief Save (or revert) changes made when editing a layout
600  */
601 - (void)listLayoutEditorWillCloseWithChanges:(BOOL)saveChanges forLayoutNamed:(NSString *)name
603         if (saveChanges) {
604                 //Update the modified layout
605                 if ([plugin createSetFromPreferenceGroup:PREF_GROUP_LIST_LAYOUT
606                                                                                 withName:name
607                                                                            extension:LIST_LAYOUT_EXTENSION
608                                                                                 inFolder:LIST_LAYOUT_FOLDER]) {
609                         
610                         [[adium preferenceController] setPreference:name
611                                                                                                  forKey:KEY_LIST_LAYOUT_NAME
612                                                                                                   group:PREF_GROUP_APPEARANCE];
613                 }
614                 
615         } else {
616                 //Revert back to selected layout
617                 NSString *layout = [[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME group:PREF_GROUP_APPEARANCE];    
618                 
619                 [plugin applySetWithName:layout
620                                            extension:LIST_LAYOUT_EXTENSION
621                                                 inFolder:LIST_LAYOUT_FOLDER
622                            toPreferenceGroup:PREF_GROUP_LIST_LAYOUT];
623         }
624         
625         //No longer allow alpha in our color pickers
626         [[NSColorPanel sharedColorPanel] setShowsAlpha:NO];
630  * @brief Manage available layouts
631  */
632 - (void)manageListLayouts:(id)sender
634         _listLayouts = [plugin availableLayoutSets];
635         [ESPresetManagementController managePresets:_listLayouts
636                                                                          namedByKey:@"name"
637                                                                            onWindow:[[self view] window]
638                                                                    withDelegate:self];
640         [popUp_listLayout selectItemWithRepresentedObject:[[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME
641                                                                                                                                                                                            group:PREF_GROUP_APPEARANCE]];               
645  * @brief Validate a layout or theme name to ensure it is unique
646  */
647 - (BOOL)presetNameSheetController:(ESPresetNameSheetController *)controller
648                           shouldAcceptNewName:(NSString *)newName
649                                                  userInfo:(id)userInfo
651         NSEnumerator    *enumerator;
652         NSDictionary    *presetDict;
654         //Scan the correct presets to ensure this name doesn't already exist
655         if ([userInfo isEqualToString:@"theme"]) {
656                 enumerator = [[plugin availableThemeSets] objectEnumerator];
657         } else {
658                 enumerator = [[plugin availableLayoutSets] objectEnumerator];
659         }
660         
661         while ((presetDict = [enumerator nextObject])) {
662                 if ([newName isEqualToString:[presetDict objectForKey:@"name"]]) return NO;
663         }
664         
665         return YES;
669  * @brief Create a new theme with the user supplied name, activate and edit it
670  */
671 - (void)presetNameSheetControllerDidEnd:(ESPresetNameSheetController *)controller 
672                                                          returnCode:(ESPresetNameSheetReturnCode)returnCode
673                                                                 newName:(NSString *)newName
674                                                            userInfo:(id)userInfo
676         switch (returnCode) {
677                 case ESPresetNameSheetOkayReturn:
678                         if ([userInfo isEqualToString:@"theme"]) {
679                                 [self performSelector:@selector(_editListThemeWithName:) withObject:newName afterDelay:0.00001];
680                         } else {
681                                 [self performSelector:@selector(_editListLayoutWithName:) withObject:newName afterDelay:0.00001];
682                         }
683                 break;
684                         
685                 case ESPresetNameSheetCancelReturn:
686                         //Do nothing
687                 break;
688         }
690 - (void)_editListThemeWithName:(NSString *)name{
691         [AIListThemeWindowController editListThemeWithName:name
692                                                                                           onWindow:[[self view] window]
693                                                                            notifyingTarget:self];
695 - (void)_editListLayoutWithName:(NSString *)name{
696         [AIListLayoutWindowController editListLayoutWithName:name
697                                                                                                 onWindow:[[self view] window]
698                                                                                  notifyingTarget:self];
702  * 
703  */
704 - (NSArray *)renamePreset:(NSDictionary *)preset toName:(NSString *)newName inPresets:(NSArray *)presets renamedPreset:(id *)renamedPreset
706         NSArray         *newPresets;
707         
708         if (presets == _listLayouts) {
709                 [plugin renameSetWithName:[preset objectForKey:@"name"]
710                                                 extension:LIST_LAYOUT_EXTENSION
711                                                  inFolder:LIST_LAYOUT_FOLDER
712                                                    toName:newName];             
713                 _listLayouts = [plugin availableLayoutSets];
714                 newPresets = _listLayouts;
715                 
716         } else if (presets == _listThemes) {
717                 [plugin renameSetWithName:[preset objectForKey:@"name"]
718                                                 extension:LIST_THEME_EXTENSION
719                                                  inFolder:LIST_THEME_FOLDER
720                                                    toName:newName];             
721                 _listThemes = [plugin availableThemeSets];
722                 newPresets = _listThemes;
723                 
724         } else {
725                 newPresets = nil;
726         }
727         
728         //Return the new duplicate by reference for the preset controller
729         if (renamedPreset) {
730                 NSEnumerator    *enumerator = [newPresets objectEnumerator];
731                 NSDictionary    *aPreset;
732                 
733                 while ((aPreset = [enumerator nextObject])) {
734                         if ([newName isEqualToString:[aPreset objectForKey:@"name"]]) {
735                                 *renamedPreset = aPreset;
736                                 break;
737                         }
738                 }
739         }
740         
741         return newPresets;
745  * 
746  */
747 - (NSArray *)duplicatePreset:(NSDictionary *)preset inPresets:(NSArray *)presets createdDuplicate:(id *)duplicatePreset
749         NSString        *newName = [NSString stringWithFormat:@"%@ (%@)", [preset objectForKey:@"name"], AILocalizedString(@"Copy",nil)];
750         NSArray         *newPresets = nil;
751         
752         if (presets == _listLayouts) {
753                 [plugin duplicateSetWithName:[preset objectForKey:@"name"]
754                                                    extension:LIST_LAYOUT_EXTENSION
755                                                         inFolder:LIST_LAYOUT_FOLDER
756                                                          newName:newName];              
757                 _listLayouts = [plugin availableLayoutSets];
758                 newPresets = _listLayouts;
759                 
760         } else if (presets == _listThemes) {
761                 [plugin duplicateSetWithName:[preset objectForKey:@"name"]
762                                                    extension:LIST_THEME_EXTENSION
763                                                         inFolder:LIST_THEME_FOLDER
764                                                          newName:newName];
765                 _listThemes = [plugin availableThemeSets];
766                 newPresets = _listThemes;
767         }
768         
769         //Return the new duplicate by reference for the preset controller
770         if (duplicatePreset) {
771                 NSEnumerator    *enumerator = [newPresets objectEnumerator];
772                 NSDictionary    *aPreset;
773                 
774                 while ((aPreset = [enumerator nextObject])) {
775                         if ([newName isEqualToString:[aPreset objectForKey:@"name"]]) {
776                                 *duplicatePreset = aPreset;
777                                 break;
778                         }
779                 }
780         }
782         return newPresets;
786  * 
787  */
788 - (NSArray *)deletePreset:(NSDictionary *)preset inPresets:(NSArray *)presets
790         if (presets == _listLayouts) {
791                 [plugin deleteSetWithName:[preset objectForKey:@"name"]
792                                                 extension:LIST_LAYOUT_EXTENSION
793                                                  inFolder:LIST_LAYOUT_FOLDER];          
794                 _listLayouts = [plugin availableLayoutSets];
795                 
796                 return _listLayouts;
797                 
798         } else if (presets == _listThemes) {
799                 [plugin deleteSetWithName:[preset objectForKey:@"name"]
800                                                 extension:LIST_THEME_EXTENSION
801                                                  inFolder:LIST_THEME_FOLDER];           
802                 _listThemes = [plugin availableThemeSets];
803                 
804                 return _listThemes;
805                 
806         } else {
807                 return nil;
808         }
813  */
814 - (NSMenu *)_listLayoutMenu
816         NSMenu                  *menu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
817         NSEnumerator    *enumerator = [[plugin availableLayoutSets] objectEnumerator];
818         NSDictionary    *set;
819         NSMenuItem              *menuItem;
820         NSString                *name;
821         
822         //Available Layouts
823         while ((set = [enumerator nextObject])) {
824                 name = [set objectForKey:@"name"];
825                 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:name
826                                                                                                                                                  target:nil
827                                                                                                                                                  action:nil
828                                                                                                                                   keyEquivalent:@""] autorelease];
829                 [menuItem setRepresentedObject:name];
830                 [menu addItem:menuItem];
831         }
832         
833         //Divider
834         [menu addItem:[NSMenuItem separatorItem]];
836         //Preset management     
837         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:[AILocalizedString(@"Add New Layout",nil) stringByAppendingEllipsis]
838                                                                                                                                          target:self
839                                                                                                                                          action:@selector(createListLayout:)
840                                                                                                                           keyEquivalent:@""] autorelease];
841         [menu addItem:menuItem];
842         
843         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:[AILocalizedString(@"Edit Layouts",nil) stringByAppendingEllipsis]
844                                                                                                                                          target:self
845                                                                                                                                          action:@selector(manageListLayouts:)
846                                                                                                                           keyEquivalent:@""] autorelease];
847         [menu addItem:menuItem];
848         
849         return menu;    
854  */
855 - (NSMenu *)_colorThemeMenu
857         NSMenu                  *menu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
858         NSEnumerator    *enumerator = [[plugin availableThemeSets] objectEnumerator];
859         NSDictionary    *set;
860         NSMenuItem              *menuItem;
861         NSString                *name;
862         
863         //Available themes
864         while ((set = [enumerator nextObject])) {
865                 name = [set objectForKey:@"name"];
866                 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:name
867                                                                                                                                                  target:nil
868                                                                                                                                                  action:nil
869                                                                                                                                   keyEquivalent:@""] autorelease];
870                 [menuItem setRepresentedObject:name];
871                 [menu addItem:menuItem];
872         }
874         //Divider
875         [menu addItem:[NSMenuItem separatorItem]];
876         
877         //Preset management     
878         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:[AILocalizedString(@"Add New Theme",nil) stringByAppendingEllipsis]
879                                                                                                                                          target:self
880                                                                                                                                          action:@selector(createListTheme:)
881                                                                                                                           keyEquivalent:@""] autorelease];
882         [menu addItem:menuItem];
883         
884         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:[AILocalizedString(@"Edit Themes",nil) stringByAppendingEllipsis]
885                                                                                                                                          target:self
886                                                                                                                                          action:@selector(manageListThemes:)
887                                                                                                                           keyEquivalent:@""] autorelease];
888         [menu addItem:menuItem];
889         
890         return menu;    
894 //Dock icons -----------------------------------------------------------------------------------------------------------
895 #pragma mark Dock icons
898  */
899 - (IBAction)showAllDockIcons:(id)sender
901         [AIDockIconSelectionSheet showDockIconSelectorOnWindow:[[self view] window]];
905  * @brief Return the menu item for a dock icon
906  */
907 - (NSMenuItem *)meuItemForDockIconPackAtPath:(NSString *)packPath
909         NSMenuItem      *menuItem;
910         NSString        *name = nil;
911         NSString        *packName = [[packPath lastPathComponent] stringByDeletingPathExtension];
912         AIIconState     *preview = nil;
913         
914         [[adium dockController] getName:&name
915                                            previewState:&preview
916                                   forIconPackAtPath:packPath];
917         
918         if (!name) {
919                 name = packName;
920         }
921         
922         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:name
923                                                                                                                                          target:nil
924                                                                                                                                          action:nil
925                                                                                                                           keyEquivalent:@""] autorelease];
926         [menuItem setRepresentedObject:packName];
927         [menuItem setImage:[[preview image] imageByScalingForMenuItem]];
928         
929         return menuItem;
933  * @brief Returns an array of menu items of all dock icon packs
934  */
935 - (NSArray *)_dockIconMenuArray
937         NSMutableArray          *menuItemArray = [NSMutableArray array];
938         NSEnumerator            *enumerator;
939         NSString                        *packPath;
941         enumerator = [[[adium dockController] availableDockIconPacks] objectEnumerator];
942         while ((packPath = [enumerator nextObject])) {
943                 [menuItemArray addObject:[self meuItemForDockIconPackAtPath:packPath]];
944         }
946         [menuItemArray sortUsingSelector:@selector(titleCompare:)];
948         return menuItemArray;
952  * @brief Configure the dock icon meu initially or after the xtras change
954  * Initially, the dock icon menu just has the currently selected icon; the others will be generated lazily if the icon is displayed, in menuNeedsUpdate:
955  */
956 - (void)configureDockIconMenu
958         NSMenu          *tempMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
959         NSString        *iconPath;
960         NSString        *activePackName = [[adium preferenceController] preferenceForKey:KEY_ACTIVE_DOCK_ICON
961                                                                                                                                                    group:PREF_GROUP_APPEARANCE];
962         iconPath = [adium pathOfPackWithName:activePackName
963                                                            extension:@"AdiumIcon"
964                                           resourceFolderName:FOLDER_DOCK_ICONS];
965         
966         [tempMenu addItem:[self meuItemForDockIconPackAtPath:iconPath]];
967         [tempMenu setDelegate:self];
968         [tempMenu setTitle:@"Temporary Dock Icon Menu"];
970         [popUp_dockIcon setMenu:tempMenu];
971         [popUp_dockIcon selectItemWithRepresentedObject:activePackName];
974 //Status, Service and Menu Bar icons ---------------------------------------------------------------------------------------------
975 #pragma mark Status, service and menu bar icons
976 - (NSMenuItem *)menuItemForIconPackAtPath:(NSString *)packPath class:(Class)iconClass
978         NSString        *name = [[packPath lastPathComponent] stringByDeletingPathExtension];
979         NSMenuItem      *menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:name
980                                                                                                                                                                   target:nil
981                                                                                                                                                                   action:nil
982                                                                                                                                                    keyEquivalent:@""] autorelease];
983         [menuItem setRepresentedObject:name];
984         [menuItem setImage:[iconClass previewMenuImageForIconPackAtPath:packPath]];     
986         return menuItem;
990  * @brief Builds and returns an icon pack menu
992  * @param packs NSArray of icon pack file paths
993  * @param iconClass The controller class (AIStatusIcons, AIServiceIcons) for icon pack previews
994  */
995 - (NSArray *)_iconPackMenuArrayForPacks:(NSArray *)packs class:(Class)iconClass
997         NSMutableArray  *menuItemArray = [NSMutableArray array];
998         NSEnumerator    *enumerator = [packs objectEnumerator];
999         NSString                *packPath;
1001         while ((packPath = [enumerator nextObject])) {
1002                 [menuItemArray addObject:[self menuItemForIconPackAtPath:packPath class:iconClass]];
1003         }
1004         
1005         [menuItemArray sortUsingSelector:@selector(titleCompare:)];
1007         return menuItemArray;   
1010 - (void)configureStatusIconsMenu
1012         NSMenu          *tempMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
1013         NSString        *iconPath;
1014         NSString        *activePackName = [[adium preferenceController] preferenceForKey:KEY_STATUS_ICON_PACK
1015                                                                                                                                                    group:PREF_GROUP_APPEARANCE];
1016         iconPath = [adium pathOfPackWithName:activePackName
1017                                                            extension:@"AdiumStatusIcons"
1018                                           resourceFolderName:@"Status Icons"];
1019         
1020         if (!iconPath) {
1021                 activePackName = [[adium preferenceController] defaultPreferenceForKey:KEY_STATUS_ICON_PACK
1022                                                                                                                                                  group:PREF_GROUP_APPEARANCE
1023                                                                                                                                                 object:nil];
1024                 
1025                 iconPath = [adium pathOfPackWithName:activePackName
1026                                                                    extension:@"AdiumStatusIcons"
1027                                                   resourceFolderName:@"Status Icons"];          
1028         }
1029         [tempMenu addItem:[self menuItemForIconPackAtPath:iconPath class:[AIStatusIcons class]]];
1030         [tempMenu setDelegate:self];
1031         [tempMenu setTitle:@"Temporary Status Icons Menu"];
1032         
1033         [popUp_statusIcons setMenu:tempMenu];
1034         [popUp_statusIcons selectItemWithRepresentedObject:activePackName];
1037 - (void)configureServiceIconsMenu
1039         NSMenu          *tempMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
1040         NSString        *iconPath;
1041         NSString        *activePackName = [[adium preferenceController] preferenceForKey:KEY_SERVICE_ICON_PACK
1042                                                                                                                                                    group:PREF_GROUP_APPEARANCE];
1043         iconPath = [adium pathOfPackWithName:activePackName
1044                                                            extension:@"AdiumServiceIcons"
1045                                           resourceFolderName:@"Service Icons"];
1046         
1047         if (!iconPath) {
1048                 activePackName = [[adium preferenceController] defaultPreferenceForKey:KEY_SERVICE_ICON_PACK
1049                                                                                                                                                  group:PREF_GROUP_APPEARANCE
1050                                                                                                                                                 object:nil];
1051                 
1052                 iconPath = [adium pathOfPackWithName:activePackName
1053                                                                    extension:@"AdiumServiceIcons"
1054                                                   resourceFolderName:@"Service Icons"];         
1055         }
1056         [tempMenu addItem:[self menuItemForIconPackAtPath:iconPath class:[AIServiceIcons class]]];
1057         [tempMenu setDelegate:self];
1058         [tempMenu setTitle:@"Temporary Service Icons Menu"];
1059         
1060         [popUp_serviceIcons setMenu:tempMenu];
1061         [popUp_serviceIcons selectItemWithRepresentedObject:activePackName];
1064 - (void)configureMenuBarIconsMenu
1066         NSMenu          *tempMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
1067         NSString        *iconPath;
1068         NSString        *activePackName = [[adium preferenceController] preferenceForKey:KEY_MENU_BAR_ICONS
1069                                                                                                                                                    group:PREF_GROUP_APPEARANCE];
1070         iconPath = [adium pathOfPackWithName:activePackName
1071                                                            extension:@"AdiumMenuBarIcons"
1072                                           resourceFolderName:@"Menu Bar Icons"];
1073         
1074         if (!iconPath) {
1075                 activePackName = [[adium preferenceController] defaultPreferenceForKey:KEY_MENU_BAR_ICONS
1076                                                                                                                                                  group:PREF_GROUP_APPEARANCE
1077                                                                                                                                                 object:nil];
1078                 
1079                 iconPath = [adium pathOfPackWithName:activePackName
1080                                                                    extension:@"AdiumMenuBarIcons"
1081                                                   resourceFolderName:@"Menu Bar Icons"];                
1082         }
1083         [tempMenu addItem:[self menuItemForIconPackAtPath:iconPath class:[AIMenuBarIcons class]]];
1084         [tempMenu setDelegate:self];
1085         [tempMenu setTitle:@"Temporary Menu Bar Icons Menu"];
1086         
1087         [popUp_menuBarIcons setMenu:tempMenu];
1088         [popUp_menuBarIcons selectItemWithRepresentedObject:activePackName];
1091 #pragma mark Menu delegate
1092 - (void)menuNeedsUpdate:(NSMenu *)menu
1094         NSString                *title =[menu title];
1095         NSString                *repObject = nil;
1096         NSArray                 *menuItemArray = nil;
1097         NSPopUpButton   *popUpButton;
1098         
1099         if ([title isEqualToString:@"Temporary Dock Icon Menu"]) {
1100                 //If the menu has @"Temporary Dock Icon Menu" as its title, we should update it to have all dock icons, not just our selected one
1101                 menuItemArray = [self _dockIconMenuArray];
1102                 repObject = [[adium preferenceController] preferenceForKey:KEY_ACTIVE_DOCK_ICON
1103                                                                                                                          group:PREF_GROUP_APPEARANCE];
1104                 popUpButton = popUp_dockIcon;
1105                 
1106         } else if ([title isEqualToString:@"Temporary Status Icons Menu"]) {            
1107                 menuItemArray = [self _iconPackMenuArrayForPacks:[adium allResourcesForName:@"Status Icons" 
1108                                                                                                                                          withExtensions:@"AdiumStatusIcons"] 
1109                                                                                                    class:[AIStatusIcons class]];
1110                 repObject = [[adium preferenceController] preferenceForKey:KEY_STATUS_ICON_PACK
1111                                                                                                                          group:PREF_GROUP_APPEARANCE];
1112                 popUpButton = popUp_statusIcons;
1113                 
1114         } else if ([title isEqualToString:@"Temporary Service Icons Menu"]) {           
1115                 menuItemArray = [self _iconPackMenuArrayForPacks:[adium allResourcesForName:@"Service Icons" 
1116                                                                                                                                          withExtensions:@"AdiumServiceIcons"] 
1117                                                                                                    class:[AIServiceIcons class]];
1118                 repObject = [[adium preferenceController] preferenceForKey:KEY_SERVICE_ICON_PACK
1119                                                                                                                          group:PREF_GROUP_APPEARANCE];
1120                 popUpButton = popUp_serviceIcons;
1121                 
1122         } else if ([title isEqualToString:@"Temporary Menu Bar Icons Menu"]) {
1123                 menuItemArray = [self _iconPackMenuArrayForPacks:[adium allResourcesForName:@"Menu Bar Icons" 
1124                                                                                                                                          withExtensions:@"AdiumMenuBarIcons"] 
1125                                                                                                    class:[AIMenuBarIcons class]];
1126                 repObject = [[adium preferenceController] preferenceForKey:KEY_MENU_BAR_ICONS
1127                                                                                                                          group:PREF_GROUP_APPEARANCE];
1128                 popUpButton = popUp_menuBarIcons;       
1129         }
1130         
1131         if (menuItemArray) {
1132                 NSEnumerator    *enumerator;
1133                 NSMenuItem              *menuItem;
1134                 
1135                 //Remove existing items
1136                 [menu removeAllItems];
1137                 
1138                 //Clear the title so we know we don't need to do this again
1139                 [menu setTitle:@""];
1140                 
1141                 //Add the items
1142                 enumerator = [menuItemArray objectEnumerator];
1143                 while ((menuItem = [enumerator nextObject])) {
1144                         [menu addItem:menuItem];
1145                 }
1146                 
1147                 //Clear the title so we know we don't need to do this again
1148                 [menu setTitle:@""];
1149                 
1150                 //Put a checkmark by the appropriate menu item
1151                 [popUpButton selectItemWithRepresentedObject:repObject];
1152         }       
1155 @end