Patch from Pietro Modi which resolves a localization issues with "(Copy)" which creat...
[adiumx.git] / Source / AIAppearancePreferences.m
blob2c0ed0fe25e456ba79ba8e8fd0b2682365e9730e
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:@" "] stringByAppendingString:AILocalizedString(@"(Copy)", nil)]
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                 //Reapply the selected theme
544                 [plugin applySetWithName:theme
545                                            extension:LIST_THEME_EXTENSION
546                                                 inFolder:LIST_THEME_FOLDER
547                            toPreferenceGroup:PREF_GROUP_LIST_THEME];
548                            
549                 //Revert back to the current theme name in popUp_colorTheme component
550                 [popUp_colorTheme selectItemWithTitle:[[adium preferenceController] preferenceForKey:KEY_LIST_THEME_NAME group:PREF_GROUP_APPEARANCE]];         
551         }
552         
554         //No longer allow alpha in our color pickers
555         [[NSColorPanel sharedColorPanel] setShowsAlpha:NO];
559  * @brief Manage available themes
560  */
561 - (void)manageListThemes:(id)sender
563         _listThemes = [plugin availableThemeSets];
564         [ESPresetManagementController managePresets:_listThemes
565                                                                          namedByKey:@"name"
566                                                                            onWindow:[[self view] window]
567                                                                    withDelegate:self];
568         
569         [popUp_colorTheme selectItemWithRepresentedObject:[[adium preferenceController] preferenceForKey:KEY_LIST_THEME_NAME
570                                                                                                                                                                                            group:PREF_GROUP_APPEARANCE]];               
574  * @brief Create a new layout
575  */
576 - (IBAction)createListLayout:(id)sender
578         NSString *layout = [[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME group:PREF_GROUP_APPEARANCE];
579         
580         [ESPresetNameSheetController showPresetNameSheetWithDefaultName:[[layout stringByAppendingString:@" "] stringByAppendingString:AILocalizedString(@"(Copy)",nil)]
581                                                                                                         explanatoryText:AILocalizedString(@"Enter a unique name for this new layout.",nil)
582                                                                                                                    onWindow:[[self view] window]
583                                                                                                         notifyingTarget:self
584                                                                                                                    userInfo:@"layout"];
588  * @brief Customize the active layout
589  */
590 - (IBAction)customizeListLayout:(id)sender
592         NSString *theme = [[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME group:PREF_GROUP_APPEARANCE];     
593         
594         //Allow alpha in our color pickers
595         [[NSColorPanel sharedColorPanel] setShowsAlpha:YES];    
597         [AIListLayoutWindowController editListLayoutWithName:theme
598                                                                                           onWindow:[[self view] window]
599                                                                            notifyingTarget:self];
603  * @brief Save (or revert) changes made when editing a layout
604  */
605 - (void)listLayoutEditorWillCloseWithChanges:(BOOL)saveChanges forLayoutNamed:(NSString *)name
607         if (saveChanges) {
608                 //Update the modified layout
609                 if ([plugin createSetFromPreferenceGroup:PREF_GROUP_LIST_LAYOUT
610                                                                                 withName:name
611                                                                            extension:LIST_LAYOUT_EXTENSION
612                                                                                 inFolder:LIST_LAYOUT_FOLDER]) {
613                         
614                         [[adium preferenceController] setPreference:name
615                                                                                                  forKey:KEY_LIST_LAYOUT_NAME
616                                                                                                   group:PREF_GROUP_APPEARANCE];
617                 }
618                 
619         } else {
620                 //Revert back to selected layout
621                 NSString *layout = [[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME group:PREF_GROUP_APPEARANCE];    
623                 //Reapply the selected layout
624                 [plugin applySetWithName:layout
625                                            extension:LIST_LAYOUT_EXTENSION
626                                                 inFolder:LIST_LAYOUT_FOLDER
627                            toPreferenceGroup:PREF_GROUP_LIST_LAYOUT];
628                            
629                 //Revert back to the current layout name in popUp_listLayout component
630                 [popUp_listLayout selectItemWithTitle:[[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME group:PREF_GROUP_APPEARANCE]];
631         }
632         
633         //No longer allow alpha in our color pickers
634         [[NSColorPanel sharedColorPanel] setShowsAlpha:NO];
638  * @brief Manage available layouts
639  */
640 - (void)manageListLayouts:(id)sender
642         _listLayouts = [plugin availableLayoutSets];
643         [ESPresetManagementController managePresets:_listLayouts
644                                                                          namedByKey:@"name"
645                                                                            onWindow:[[self view] window]
646                                                                    withDelegate:self];
648         [popUp_listLayout selectItemWithRepresentedObject:[[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME
649                                                                                                                                                                                            group:PREF_GROUP_APPEARANCE]];               
653  * @brief Validate a layout or theme name to ensure it is unique
654  */
655 - (BOOL)presetNameSheetController:(ESPresetNameSheetController *)controller
656                           shouldAcceptNewName:(NSString *)newName
657                                                  userInfo:(id)userInfo
659         NSEnumerator    *enumerator;
660         NSDictionary    *presetDict;
662         //Scan the correct presets to ensure this name doesn't already exist
663         if ([userInfo isEqualToString:@"theme"]) {
664                 enumerator = [[plugin availableThemeSets] objectEnumerator];
665         } else {
666                 enumerator = [[plugin availableLayoutSets] objectEnumerator];
667         }
668         
669         while ((presetDict = [enumerator nextObject])) {
670                 if ([newName isEqualToString:[presetDict objectForKey:@"name"]]) return NO;
671         }
672         
673         return YES;
677  * @brief Create a new theme with the user supplied name, activate and edit it
678  */
679 - (void)presetNameSheetControllerDidEnd:(ESPresetNameSheetController *)controller 
680                                                          returnCode:(ESPresetNameSheetReturnCode)returnCode
681                                                                 newName:(NSString *)newName
682                                                            userInfo:(id)userInfo
684         switch (returnCode) {
685                 case ESPresetNameSheetOkayReturn:
686                         //User has created a new theme/layout   : show the editor
687                         if ([userInfo isEqualToString:@"theme"]) {
688                                 [self performSelector:@selector(_editListThemeWithName:) withObject:newName afterDelay:0.00001];
689                         } else {
690                                 [self performSelector:@selector(_editListLayoutWithName:) withObject:newName afterDelay:0.00001];
691                         }
692                 break;
693                         
694                 case ESPresetNameSheetCancelReturn:
695                         //User has canceled the operation       : revert back to the current theme 
696                         if ([userInfo isEqualToString:@"theme"]) {
697                                 [popUp_colorTheme selectItemWithTitle:[[adium preferenceController] preferenceForKey:KEY_LIST_THEME_NAME group:PREF_GROUP_APPEARANCE]];
698                         } else {
699                                 [popUp_listLayout selectItemWithTitle:[[adium preferenceController] preferenceForKey:KEY_LIST_LAYOUT_NAME group:PREF_GROUP_APPEARANCE]];
700                         }                       
701                 break;  
702         }
704 - (void)_editListThemeWithName:(NSString *)name{
705         [AIListThemeWindowController editListThemeWithName:name
706                                                                                           onWindow:[[self view] window]
707                                                                            notifyingTarget:self];
709 - (void)_editListLayoutWithName:(NSString *)name{
710         [AIListLayoutWindowController editListLayoutWithName:name
711                                                                                                 onWindow:[[self view] window]
712                                                                                  notifyingTarget:self];
716  * 
717  */
718 - (NSArray *)renamePreset:(NSDictionary *)preset toName:(NSString *)newName inPresets:(NSArray *)presets renamedPreset:(id *)renamedPreset
720         NSArray         *newPresets;
721         
722         if (presets == _listLayouts) {
723                 [plugin renameSetWithName:[preset objectForKey:@"name"]
724                                                 extension:LIST_LAYOUT_EXTENSION
725                                                  inFolder:LIST_LAYOUT_FOLDER
726                                                    toName:newName];             
727                 _listLayouts = [plugin availableLayoutSets];
728                 newPresets = _listLayouts;
729                 
730         } else if (presets == _listThemes) {
731                 [plugin renameSetWithName:[preset objectForKey:@"name"]
732                                                 extension:LIST_THEME_EXTENSION
733                                                  inFolder:LIST_THEME_FOLDER
734                                                    toName:newName];             
735                 _listThemes = [plugin availableThemeSets];
736                 newPresets = _listThemes;
737                 
738         } else {
739                 newPresets = nil;
740         }
741         
742         //Return the new duplicate by reference for the preset controller
743         if (renamedPreset) {
744                 NSEnumerator    *enumerator = [newPresets objectEnumerator];
745                 NSDictionary    *aPreset;
746                 
747                 while ((aPreset = [enumerator nextObject])) {
748                         if ([newName isEqualToString:[aPreset objectForKey:@"name"]]) {
749                                 *renamedPreset = aPreset;
750                                 break;
751                         }
752                 }
753         }
754         
755         return newPresets;
759  * 
760  */
761 - (NSArray *)duplicatePreset:(NSDictionary *)preset inPresets:(NSArray *)presets createdDuplicate:(id *)duplicatePreset
763         NSString        *newName = [NSString stringWithFormat:@"%@ (%@)", [preset objectForKey:@"name"], AILocalizedString(@"Copy",nil)];
764         NSArray         *newPresets = nil;
765         
766         if (presets == _listLayouts) {
767                 [plugin duplicateSetWithName:[preset objectForKey:@"name"]
768                                                    extension:LIST_LAYOUT_EXTENSION
769                                                         inFolder:LIST_LAYOUT_FOLDER
770                                                          newName:newName];              
771                 _listLayouts = [plugin availableLayoutSets];
772                 newPresets = _listLayouts;
773                 
774         } else if (presets == _listThemes) {
775                 [plugin duplicateSetWithName:[preset objectForKey:@"name"]
776                                                    extension:LIST_THEME_EXTENSION
777                                                         inFolder:LIST_THEME_FOLDER
778                                                          newName:newName];
779                 _listThemes = [plugin availableThemeSets];
780                 newPresets = _listThemes;
781         }
782         
783         //Return the new duplicate by reference for the preset controller
784         if (duplicatePreset) {
785                 NSEnumerator    *enumerator = [newPresets objectEnumerator];
786                 NSDictionary    *aPreset;
787                 
788                 while ((aPreset = [enumerator nextObject])) {
789                         if ([newName isEqualToString:[aPreset objectForKey:@"name"]]) {
790                                 *duplicatePreset = aPreset;
791                                 break;
792                         }
793                 }
794         }
796         return newPresets;
800  * 
801  */
802 - (NSArray *)deletePreset:(NSDictionary *)preset inPresets:(NSArray *)presets
804         if (presets == _listLayouts) {
805                 [plugin deleteSetWithName:[preset objectForKey:@"name"]
806                                                 extension:LIST_LAYOUT_EXTENSION
807                                                  inFolder:LIST_LAYOUT_FOLDER];          
808                 _listLayouts = [plugin availableLayoutSets];
809                 
810                 return _listLayouts;
811                 
812         } else if (presets == _listThemes) {
813                 [plugin deleteSetWithName:[preset objectForKey:@"name"]
814                                                 extension:LIST_THEME_EXTENSION
815                                                  inFolder:LIST_THEME_FOLDER];           
816                 _listThemes = [plugin availableThemeSets];
817                 
818                 return _listThemes;
819                 
820         } else {
821                 return nil;
822         }
827  */
828 - (NSMenu *)_listLayoutMenu
830         NSMenu                  *menu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
831         NSEnumerator    *enumerator = [[plugin availableLayoutSets] objectEnumerator];
832         NSDictionary    *set;
833         NSMenuItem              *menuItem;
834         NSString                *name;
835         
836         //Available Layouts
837         while ((set = [enumerator nextObject])) {
838                 name = [set objectForKey:@"name"];
839                 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:name
840                                                                                                                                                  target:nil
841                                                                                                                                                  action:nil
842                                                                                                                                   keyEquivalent:@""] autorelease];
843                 [menuItem setRepresentedObject:name];
844                 [menu addItem:menuItem];
845         }
846         
847         //Divider
848         [menu addItem:[NSMenuItem separatorItem]];
850         //Preset management     
851         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:[AILocalizedString(@"Add New Layout",nil) stringByAppendingEllipsis]
852                                                                                                                                          target:self
853                                                                                                                                          action:@selector(createListLayout:)
854                                                                                                                           keyEquivalent:@""] autorelease];
855         [menu addItem:menuItem];
856         
857         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:[AILocalizedString(@"Edit Layouts",nil) stringByAppendingEllipsis]
858                                                                                                                                          target:self
859                                                                                                                                          action:@selector(manageListLayouts:)
860                                                                                                                           keyEquivalent:@""] autorelease];
861         [menu addItem:menuItem];
862         
863         return menu;    
868  */
869 - (NSMenu *)_colorThemeMenu
871         NSMenu                  *menu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
872         NSEnumerator    *enumerator = [[plugin availableThemeSets] objectEnumerator];
873         NSDictionary    *set;
874         NSMenuItem              *menuItem;
875         NSString                *name;
876         
877         //Available themes
878         while ((set = [enumerator nextObject])) {
879                 name = [set objectForKey:@"name"];
880                 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:name
881                                                                                                                                                  target:nil
882                                                                                                                                                  action:nil
883                                                                                                                                   keyEquivalent:@""] autorelease];
884                 [menuItem setRepresentedObject:name];
885                 [menu addItem:menuItem];
886         }
888         //Divider
889         [menu addItem:[NSMenuItem separatorItem]];
890         
891         //Preset management     
892         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:[AILocalizedString(@"Add New Theme",nil) stringByAppendingEllipsis]
893                                                                                                                                          target:self
894                                                                                                                                          action:@selector(createListTheme:)
895                                                                                                                           keyEquivalent:@""] autorelease];
896         [menu addItem:menuItem];
897         
898         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:[AILocalizedString(@"Edit Themes",nil) stringByAppendingEllipsis]
899                                                                                                                                          target:self
900                                                                                                                                          action:@selector(manageListThemes:)
901                                                                                                                           keyEquivalent:@""] autorelease];
902         [menu addItem:menuItem];
903         
904         return menu;    
908 //Dock icons -----------------------------------------------------------------------------------------------------------
909 #pragma mark Dock icons
912  */
913 - (IBAction)showAllDockIcons:(id)sender
915         [AIDockIconSelectionSheet showDockIconSelectorOnWindow:[[self view] window]];
919  * @brief Return the menu item for a dock icon
920  */
921 - (NSMenuItem *)meuItemForDockIconPackAtPath:(NSString *)packPath
923         NSMenuItem      *menuItem;
924         NSString        *name = nil;
925         NSString        *packName = [[packPath lastPathComponent] stringByDeletingPathExtension];
926         AIIconState     *preview = nil;
927         
928         [[adium dockController] getName:&name
929                                            previewState:&preview
930                                   forIconPackAtPath:packPath];
931         
932         if (!name) {
933                 name = packName;
934         }
935         
936         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:name
937                                                                                                                                          target:nil
938                                                                                                                                          action:nil
939                                                                                                                           keyEquivalent:@""] autorelease];
940         [menuItem setRepresentedObject:packName];
941         [menuItem setImage:[[preview image] imageByScalingForMenuItem]];
942         
943         return menuItem;
947  * @brief Returns an array of menu items of all dock icon packs
948  */
949 - (NSArray *)_dockIconMenuArray
951         NSMutableArray          *menuItemArray = [NSMutableArray array];
952         NSEnumerator            *enumerator;
953         NSString                        *packPath;
955         enumerator = [[[adium dockController] availableDockIconPacks] objectEnumerator];
956         while ((packPath = [enumerator nextObject])) {
957                 [menuItemArray addObject:[self meuItemForDockIconPackAtPath:packPath]];
958         }
960         [menuItemArray sortUsingSelector:@selector(titleCompare:)];
962         return menuItemArray;
966  * @brief Configure the dock icon meu initially or after the xtras change
968  * Initially, the dock icon menu just has the currently selected icon; the others will be generated lazily if the icon is displayed, in menuNeedsUpdate:
969  */
970 - (void)configureDockIconMenu
972         NSMenu          *tempMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
973         NSString        *iconPath;
974         NSString        *activePackName = [[adium preferenceController] preferenceForKey:KEY_ACTIVE_DOCK_ICON
975                                                                                                                                                    group:PREF_GROUP_APPEARANCE];
976         iconPath = [adium pathOfPackWithName:activePackName
977                                                            extension:@"AdiumIcon"
978                                           resourceFolderName:FOLDER_DOCK_ICONS];
979         
980         [tempMenu addItem:[self meuItemForDockIconPackAtPath:iconPath]];
981         [tempMenu setDelegate:self];
982         [tempMenu setTitle:@"Temporary Dock Icon Menu"];
984         [popUp_dockIcon setMenu:tempMenu];
985         [popUp_dockIcon selectItemWithRepresentedObject:activePackName];
988 //Status, Service and Menu Bar icons ---------------------------------------------------------------------------------------------
989 #pragma mark Status, service and menu bar icons
990 - (NSMenuItem *)menuItemForIconPackAtPath:(NSString *)packPath class:(Class)iconClass
992         NSString        *name = [[packPath lastPathComponent] stringByDeletingPathExtension];
993         NSMenuItem      *menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:name
994                                                                                                                                                                   target:nil
995                                                                                                                                                                   action:nil
996                                                                                                                                                    keyEquivalent:@""] autorelease];
997         [menuItem setRepresentedObject:name];
998         [menuItem setImage:[iconClass previewMenuImageForIconPackAtPath:packPath]];     
1000         return menuItem;
1004  * @brief Builds and returns an icon pack menu
1006  * @param packs NSArray of icon pack file paths
1007  * @param iconClass The controller class (AIStatusIcons, AIServiceIcons) for icon pack previews
1008  */
1009 - (NSArray *)_iconPackMenuArrayForPacks:(NSArray *)packs class:(Class)iconClass
1011         NSMutableArray  *menuItemArray = [NSMutableArray array];
1012         NSEnumerator    *enumerator = [packs objectEnumerator];
1013         NSString                *packPath;
1015         while ((packPath = [enumerator nextObject])) {
1016                 [menuItemArray addObject:[self menuItemForIconPackAtPath:packPath class:iconClass]];
1017         }
1018         
1019         [menuItemArray sortUsingSelector:@selector(titleCompare:)];
1021         return menuItemArray;   
1024 - (void)configureStatusIconsMenu
1026         NSMenu          *tempMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
1027         NSString        *iconPath;
1028         NSString        *activePackName = [[adium preferenceController] preferenceForKey:KEY_STATUS_ICON_PACK
1029                                                                                                                                                    group:PREF_GROUP_APPEARANCE];
1030         iconPath = [adium pathOfPackWithName:activePackName
1031                                                            extension:@"AdiumStatusIcons"
1032                                           resourceFolderName:@"Status Icons"];
1033         
1034         if (!iconPath) {
1035                 activePackName = [[adium preferenceController] defaultPreferenceForKey:KEY_STATUS_ICON_PACK
1036                                                                                                                                                  group:PREF_GROUP_APPEARANCE
1037                                                                                                                                                 object:nil];
1038                 
1039                 iconPath = [adium pathOfPackWithName:activePackName
1040                                                                    extension:@"AdiumStatusIcons"
1041                                                   resourceFolderName:@"Status Icons"];          
1042         }
1043         [tempMenu addItem:[self menuItemForIconPackAtPath:iconPath class:[AIStatusIcons class]]];
1044         [tempMenu setDelegate:self];
1045         [tempMenu setTitle:@"Temporary Status Icons Menu"];
1046         
1047         [popUp_statusIcons setMenu:tempMenu];
1048         [popUp_statusIcons selectItemWithRepresentedObject:activePackName];
1051 - (void)configureServiceIconsMenu
1053         NSMenu          *tempMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
1054         NSString        *iconPath;
1055         NSString        *activePackName = [[adium preferenceController] preferenceForKey:KEY_SERVICE_ICON_PACK
1056                                                                                                                                                    group:PREF_GROUP_APPEARANCE];
1057         iconPath = [adium pathOfPackWithName:activePackName
1058                                                            extension:@"AdiumServiceIcons"
1059                                           resourceFolderName:@"Service Icons"];
1060         
1061         if (!iconPath) {
1062                 activePackName = [[adium preferenceController] defaultPreferenceForKey:KEY_SERVICE_ICON_PACK
1063                                                                                                                                                  group:PREF_GROUP_APPEARANCE
1064                                                                                                                                                 object:nil];
1065                 
1066                 iconPath = [adium pathOfPackWithName:activePackName
1067                                                                    extension:@"AdiumServiceIcons"
1068                                                   resourceFolderName:@"Service Icons"];         
1069         }
1070         [tempMenu addItem:[self menuItemForIconPackAtPath:iconPath class:[AIServiceIcons class]]];
1071         [tempMenu setDelegate:self];
1072         [tempMenu setTitle:@"Temporary Service Icons Menu"];
1073         
1074         [popUp_serviceIcons setMenu:tempMenu];
1075         [popUp_serviceIcons selectItemWithRepresentedObject:activePackName];
1078 - (void)configureMenuBarIconsMenu
1080         NSMenu          *tempMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
1081         NSString        *iconPath;
1082         NSString        *activePackName = [[adium preferenceController] preferenceForKey:KEY_MENU_BAR_ICONS
1083                                                                                                                                                    group:PREF_GROUP_APPEARANCE];
1084         iconPath = [adium pathOfPackWithName:activePackName
1085                                                            extension:@"AdiumMenuBarIcons"
1086                                           resourceFolderName:@"Menu Bar Icons"];
1087         
1088         if (!iconPath) {
1089                 activePackName = [[adium preferenceController] defaultPreferenceForKey:KEY_MENU_BAR_ICONS
1090                                                                                                                                                  group:PREF_GROUP_APPEARANCE
1091                                                                                                                                                 object:nil];
1092                 
1093                 iconPath = [adium pathOfPackWithName:activePackName
1094                                                                    extension:@"AdiumMenuBarIcons"
1095                                                   resourceFolderName:@"Menu Bar Icons"];                
1096         }
1097         [tempMenu addItem:[self menuItemForIconPackAtPath:iconPath class:[AIMenuBarIcons class]]];
1098         [tempMenu setDelegate:self];
1099         [tempMenu setTitle:@"Temporary Menu Bar Icons Menu"];
1100         
1101         [popUp_menuBarIcons setMenu:tempMenu];
1102         [popUp_menuBarIcons selectItemWithRepresentedObject:activePackName];
1105 #pragma mark Menu delegate
1106 - (void)menuNeedsUpdate:(NSMenu *)menu
1108         NSString                *title =[menu title];
1109         NSString                *repObject = nil;
1110         NSArray                 *menuItemArray = nil;
1111         NSPopUpButton   *popUpButton;
1112         
1113         if ([title isEqualToString:@"Temporary Dock Icon Menu"]) {
1114                 //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
1115                 menuItemArray = [self _dockIconMenuArray];
1116                 repObject = [[adium preferenceController] preferenceForKey:KEY_ACTIVE_DOCK_ICON
1117                                                                                                                          group:PREF_GROUP_APPEARANCE];
1118                 popUpButton = popUp_dockIcon;
1119                 
1120         } else if ([title isEqualToString:@"Temporary Status Icons Menu"]) {            
1121                 menuItemArray = [self _iconPackMenuArrayForPacks:[adium allResourcesForName:@"Status Icons" 
1122                                                                                                                                          withExtensions:@"AdiumStatusIcons"] 
1123                                                                                                    class:[AIStatusIcons class]];
1124                 repObject = [[adium preferenceController] preferenceForKey:KEY_STATUS_ICON_PACK
1125                                                                                                                          group:PREF_GROUP_APPEARANCE];
1126                 popUpButton = popUp_statusIcons;
1127                 
1128         } else if ([title isEqualToString:@"Temporary Service Icons Menu"]) {           
1129                 menuItemArray = [self _iconPackMenuArrayForPacks:[adium allResourcesForName:@"Service Icons" 
1130                                                                                                                                          withExtensions:@"AdiumServiceIcons"] 
1131                                                                                                    class:[AIServiceIcons class]];
1132                 repObject = [[adium preferenceController] preferenceForKey:KEY_SERVICE_ICON_PACK
1133                                                                                                                          group:PREF_GROUP_APPEARANCE];
1134                 popUpButton = popUp_serviceIcons;
1135                 
1136         } else if ([title isEqualToString:@"Temporary Menu Bar Icons Menu"]) {
1137                 menuItemArray = [self _iconPackMenuArrayForPacks:[adium allResourcesForName:@"Menu Bar Icons" 
1138                                                                                                                                          withExtensions:@"AdiumMenuBarIcons"] 
1139                                                                                                    class:[AIMenuBarIcons class]];
1140                 repObject = [[adium preferenceController] preferenceForKey:KEY_MENU_BAR_ICONS
1141                                                                                                                          group:PREF_GROUP_APPEARANCE];
1142                 popUpButton = popUp_menuBarIcons;       
1143         }
1144         
1145         if (menuItemArray) {
1146                 NSEnumerator    *enumerator;
1147                 NSMenuItem              *menuItem;
1148                 
1149                 //Remove existing items
1150                 [menu removeAllItems];
1151                 
1152                 //Clear the title so we know we don't need to do this again
1153                 [menu setTitle:@""];
1154                 
1155                 //Add the items
1156                 enumerator = [menuItemArray objectEnumerator];
1157                 while ((menuItem = [enumerator nextObject])) {
1158                         [menu addItem:menuItem];
1159                 }
1160                 
1161                 //Clear the title so we know we don't need to do this again
1162                 [menu setTitle:@""];
1163                 
1164                 //Put a checkmark by the appropriate menu item
1165                 [popUpButton selectItemWithRepresentedObject:repObject];
1166         }       
1169 @end