Adding loads of neato registration stuff!
[MenuTunes.git] / MenuController.m
1 //
2 //  MenuController.m
3 //  MenuTunes
4 //
5 //  Created by Joseph Spiros on Wed Apr 30 2003.
6 //  Copyright (c) 2003 iThink Software. All rights reserved.
7 //
8
9 #import "MenuController.h"
10 #import "MainController.h"
11 #import <ITFoundation/ITDebug.h>
12 #import <ITKit/ITHotKeyCenter.h>
13 #import <ITKit/ITHotKey.h>
14 #import <ITKit/ITKeyCombo.h>
15 #import <ITKit/ITCategory-NSMenu.h>
16
17 @interface MenuController (SubmenuMethods)
18 - (NSMenu *)ratingMenu;
19 - (NSMenu *)upcomingSongsMenu;
20 - (NSMenu *)playlistsMenu;
21 - (NSMenu *)eqMenu;
22 - (void)setKeyEquivalentForCode:(short)code andModifiers:(long)modifiers
23         onItem:(NSMenuItem *)item;
24 @end
25
26 @implementation MenuController
27
28 - (id)init
29 {
30     if ( (self = [super init]) ) {
31         _menuLayout = [[NSMutableArray alloc] initWithCapacity:0];
32     }
33     return self;
34 }
35
36 - (NSMenu *)menu
37 {
38     NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
39     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
40     NSArray *menuArray = [defaults arrayForKey:@"menu"];
41     NSEnumerator *enumerator = [menuArray objectEnumerator];
42     NSString *nextObject;
43     NSMenuItem *tempItem;
44     NSEnumerator *itemEnum;
45     ITHotKey *hotKey;
46     NSArray *hotKeys = [[ITHotKeyCenter sharedCenter] allHotKeys];
47     
48     //Get the information
49     _currentPlaylist = [currentRemote currentPlaylistIndex];
50     _playingRadio = ([currentRemote currentPlaylistClass] == ITMTRemotePlayerRadioPlaylist);
51     
52     ITDebugLog(@"Reset menu if required.");
53     
54     //Kill the old submenu items
55     if ( (tempItem = [_currentMenu itemWithTag:1]) ) {
56         ITDebugLog(@"Removing \"Song Rating\" submenu.");
57         [tempItem setSubmenu:nil];
58     }
59     
60     if ( (tempItem = [_currentMenu itemWithTag:2]) ) {
61         ITDebugLog(@"Removing \"Upcoming Songs\" submenu.");
62         [tempItem setSubmenu:nil];
63     }
64     
65     if ( (tempItem = [_currentMenu itemWithTag:3]) ) {
66         ITDebugLog(@"Removing \"EQ Presets\" submenu.");
67         [tempItem setSubmenu:nil];
68     }
69     
70     if ( (tempItem = [_currentMenu itemWithTag:4]) ) {
71         ITDebugLog(@"Removing \"Playlists\" submenu.");
72         [tempItem setSubmenu:nil];
73     }
74     
75     ITDebugLog(@"Begin building menu.");
76     
77     //create our menu
78     while ( (nextObject = [enumerator nextObject]) ) {
79         //Main menu items
80         if ([nextObject isEqualToString:@"playPause"]) {
81             ITDebugLog(@"Add \"Play\"/\"Pause\" menu item.");
82             tempItem = [menu addItemWithTitle:NSLocalizedString(@"play", @"Play")
83                     action:@selector(performMainMenuAction:)
84                     keyEquivalent:@""];
85             [tempItem setTag:MTMenuPlayPauseItem];
86             [tempItem setTarget:self];
87             
88             itemEnum = [hotKeys objectEnumerator];
89             while ( (hotKey = [itemEnum nextObject]) ) {
90                 if ([[hotKey name] isEqualToString:@"PlayPause"]) {
91                     ITKeyCombo *combo = [hotKey keyCombo];
92                     [self setKeyEquivalentForCode:[combo keyCode]
93                           andModifiers:[combo modifiers]
94                           onItem:tempItem];
95                 }
96             }
97             
98             ITDebugLog(@"Set \"Play\"/\"Pause\" menu item's title to correct state.");
99             switch ([currentRemote playerPlayingState]) {
100                 case ITMTRemotePlayerPlaying:
101                     [tempItem setTitle:NSLocalizedString(@"pause", @"Pause")];
102                 break;
103                 case ITMTRemotePlayerRewinding:
104                 case ITMTRemotePlayerForwarding:
105                     [tempItem setTitle:NSLocalizedString(@"resume", @"Resume")];
106                 break;
107                 default:
108                 break;
109             }
110         } else if ([nextObject isEqualToString:@"nextTrack"]) {
111             ITDebugLog(@"Add \"Next Track\" menu item.");
112             tempItem = [menu addItemWithTitle:NSLocalizedString(@"nextTrack", @"Next Track")
113                     action:@selector(performMainMenuAction:)
114                     keyEquivalent:@""];
115             
116             itemEnum = [hotKeys objectEnumerator];
117             while ( (hotKey = [itemEnum nextObject]) ) {
118                 if ([[hotKey name] isEqualToString:@"NextTrack"]) {
119                     ITKeyCombo *combo = [hotKey keyCombo];
120                     [self setKeyEquivalentForCode:[combo keyCode]
121                           andModifiers:[combo modifiers]
122                           onItem:tempItem];
123                 }
124             }
125             
126             if (_currentPlaylist) {
127                 [tempItem setTag:MTMenuNextTrackItem];
128                 [tempItem setTarget:self];
129             }
130         } else if ([nextObject isEqualToString:@"prevTrack"]) {
131             ITDebugLog(@"Add \"Previous Track\" menu item.");
132             tempItem = [menu addItemWithTitle:NSLocalizedString(@"prevTrack", @"Previous Track")
133                     action:@selector(performMainMenuAction:)
134                     keyEquivalent:@""];
135             
136             itemEnum = [hotKeys objectEnumerator];
137             while ( (hotKey = [itemEnum nextObject]) ) {
138                 if ([[hotKey name] isEqualToString:@"PrevTrack"]) {
139                     ITKeyCombo *combo = [hotKey keyCombo];
140                     [self setKeyEquivalentForCode:[combo keyCode]
141                           andModifiers:[combo modifiers]
142                           onItem:tempItem];
143                 }
144             }
145             
146             if (_currentPlaylist) {
147                 [tempItem setTag:MTMenuPreviousTrackItem];
148                 [tempItem setTarget:self];
149             }
150         } else if ([nextObject isEqualToString:@"fastForward"]) {
151             ITDebugLog(@"Add \"Fast Forward\" menu item.");
152             tempItem = [menu addItemWithTitle:NSLocalizedString(@"fastForward", @"Fast Forward")
153                     action:@selector(performMainMenuAction:)
154                     keyEquivalent:@""];
155             if (_currentPlaylist) {
156                 [tempItem setTag:MTMenuFastForwardItem];
157                 [tempItem setTarget:self];
158             }
159         } else if ([nextObject isEqualToString:@"rewind"]) {
160             ITDebugLog(@"Add \"Rewind\" menu item.");
161             tempItem = [menu addItemWithTitle:NSLocalizedString(@"rewind", @"Rewind")
162                     action:@selector(performMainMenuAction:)
163                     keyEquivalent:@""];
164             if (_currentPlaylist) {
165                 [tempItem setTag:MTMenuRewindItem];
166                 [tempItem setTarget:self];
167             }
168         } else if ([nextObject isEqualToString:@"showPlayer"]) {
169             ITDebugLog(@"Add \"Show Player\" menu item.");
170             tempItem = [menu addItemWithTitle:[NSString stringWithFormat:@"%@ %@",
171                             NSLocalizedString(@"show", @"Show"),
172                             [[[MainController sharedController] currentRemote] playerSimpleName]]
173                     action:@selector(performMainMenuAction:)
174                     keyEquivalent:@""];
175             
176             itemEnum = [hotKeys objectEnumerator];
177             while ( (hotKey = [itemEnum nextObject]) ) {
178                 if ([[hotKey name] isEqualToString:@"ShowPlayer"]) {
179                     ITKeyCombo *combo = [hotKey keyCombo];
180                     [self setKeyEquivalentForCode:[combo keyCode]
181                           andModifiers:[combo modifiers]
182                           onItem:tempItem];
183                 }
184             }
185             
186             [tempItem setTarget:self];
187             [tempItem setTag:MTMenuShowPlayerItem];
188         } else if ([nextObject isEqualToString:@"preferences"]) {
189             ITDebugLog(@"Add \"Preferences...\" menu item.");
190             tempItem = [menu addItemWithTitle:NSLocalizedString(@"preferences", @"Preferences...")
191                     action:@selector(performMainMenuAction:)
192                     keyEquivalent:@""];
193             [tempItem setTag:MTMenuPreferencesItem];
194             [tempItem setTarget:self];
195         } else if ([nextObject isEqualToString:@"quit"]) {
196             ITDebugLog(@"Add \"Quit\" menu item.");
197             tempItem = [menu addItemWithTitle:NSLocalizedString(@"quit", @"Quit")
198                     action:@selector(performMainMenuAction:)
199                     keyEquivalent:@""];
200             [tempItem setTag:MTMenuQuitItem];
201             [tempItem setTarget:self];
202             if ([[MainController sharedController] blingBling] == NO) {
203                 ITDebugLog(@"Add \"Register MenuTunes...\" menu item.");
204                 tempItem = [menu addItemWithTitle:NSLocalizedString(@"register", @"Register MenuTunes...") action:@selector(performMainMenuAction:) keyEquivalent:@""];
205                 [tempItem setTag:MTMenuRegisterItem];
206                 [tempItem setTarget:self];
207             }
208         } else if ([nextObject isEqualToString:@"trackInfo"]) {
209             ITDebugLog(@"Check to see if a Track is playing...");
210             //Handle playing radio too
211             if (_currentPlaylist) {
212                 NSString *title = [currentRemote currentSongTitle];
213                 
214                 ITDebugLog(@"A Track is Playing, Add \"Track Info\" menu items.");
215                 ITDebugLog(@"Add \"Now Playing\" menu item.");
216                 [menu addItemWithTitle:NSLocalizedString(@"nowPlaying", @"Now Playing") action:NULL keyEquivalent:@""];
217                 
218                 if ([title length] > 0) {
219                     ITDebugLog(@"Add Track Title (\"%@\") menu item.", title);
220                     [menu indentItem:
221                         [menu addItemWithTitle:title action:nil keyEquivalent:@""]];
222                 }
223                 
224                 if ([defaults boolForKey:@"showAlbum"]) {
225                     NSString *curAlbum = [currentRemote currentSongAlbum];
226                     ITDebugLog(@"Add Track Album (\"%@\") menu item.", curAlbum);
227                     if ([curAlbum length]) {
228                         [menu indentItem:
229                             [menu addItemWithTitle:curAlbum action:nil keyEquivalent:@""]];
230                     }
231                 }
232                 
233                 if ([defaults boolForKey:@"showArtist"]) {
234                     NSString *curArtist = [currentRemote currentSongArtist];
235                     ITDebugLog(@"Add Track Artist (\"%@\") menu item.", curArtist);
236                     if ([curArtist length]) {
237                         [menu indentItem:
238                             [menu addItemWithTitle:curArtist action:nil keyEquivalent:@""]];
239                     }
240                 }
241                 
242                 if ([defaults boolForKey:@"showTrackNumber"]) {
243                     int track = [currentRemote currentSongTrack];
244                     ITDebugLog(@"Add Track Number (\"Track %i\") menu item.", track);
245                     if (track) {
246                         [menu indentItem:
247                             [menu addItemWithTitle:[NSString stringWithFormat:@"%@ %i", NSLocalizedString(@"track", @"Track"), track] action:nil keyEquivalent:@""]];
248                     }
249                 }
250                 
251                 if ([defaults boolForKey:@"showTime"]) {
252                     int left = [[currentRemote currentSongRemaining] intValue];
253                     NSString *remaining = [NSString stringWithFormat:@"%i:%02i", left / 60, left % 60];
254                     ITDebugLog(@"Add Track Remaining (\"%@/%@\") menu item.", remaining, [currentRemote currentSongLength]);
255                     [menu indentItem:[menu addItemWithTitle:[NSString stringWithFormat:@"%@/%@", remaining, [currentRemote currentSongLength]] action:nil keyEquivalent:@""]];
256                 }
257                 
258                 if ([defaults boolForKey:@"showTrackRating"]) {
259                     NSString *string = nil;
260                     switch ((int)([currentRemote currentSongRating] * 5)) {
261                         case 0:
262                             string = [NSString stringWithUTF8String:"☆☆☆☆☆"];
263                         break;
264                         case 1:
265                             string = [NSString stringWithUTF8String:"★☆☆☆☆"];
266                         break;
267                         case 2:
268                             string = [NSString stringWithUTF8String:"★★☆☆☆"];
269                         break;
270                         case 3:
271                             string = [NSString stringWithUTF8String:"★★★☆☆"];
272                         break;
273                         case 4:
274                             string = [NSString stringWithUTF8String:"★★★★☆"];
275                         break;
276                         case 5:
277                             string = [NSString stringWithUTF8String:"★★★★★"];
278                         break;
279                     }
280                     ITDebugLog(@"Add Track Rating (\"%@\") menu item.", string);
281                     [menu indentItem:[menu addItemWithTitle:string action:nil keyEquivalent:@""]];
282                 }
283             } else {
284                 ITDebugLog(@"No Track is Playing, Add \"No Song\" menu item.");
285                 [menu addItemWithTitle:NSLocalizedString(@"noSong", @"No Song") action:NULL keyEquivalent:@""];
286             }
287         } else if ([nextObject isEqualToString:@"separator"]) {
288             ITDebugLog(@"Add a separator menu item.");
289             [menu addItem:[NSMenuItem separatorItem]];
290         //Submenu items
291         } else if ([nextObject isEqualToString:@"songRating"]) {
292             ITDebugLog(@"Add \"Song Rating\" submenu.");
293             tempItem = [menu addItemWithTitle:NSLocalizedString(@"songRating", @"Song Rating")
294                     action:nil
295                     keyEquivalent:@""];
296             [tempItem setSubmenu:_ratingMenu];
297             [tempItem setTag:1];
298             if (_playingRadio || !_currentPlaylist) {
299                 [tempItem setEnabled:NO];
300             }
301             
302             itemEnum = [[_ratingMenu itemArray] objectEnumerator];
303             while ( (tempItem = [itemEnum nextObject]) ) {
304                 [tempItem setState:NSOffState];
305             }
306             
307             [[_ratingMenu itemAtIndex:([currentRemote currentSongRating] * 5)] setState:NSOnState];
308         } else if ([nextObject isEqualToString:@"upcomingSongs"]) {
309             ITDebugLog(@"Add \"Upcoming Songs\" submenu.");
310             tempItem = [menu addItemWithTitle:NSLocalizedString(@"upcomingSongs", @"Upcoming Songs")
311                     action:nil
312                     keyEquivalent:@""];
313             [tempItem setSubmenu:_upcomingSongsMenu];
314             [tempItem setTag:2];
315             if (_playingRadio || !_currentPlaylist) {
316                 [tempItem setEnabled:NO];
317             }
318         } else if ([nextObject isEqualToString:@"playlists"]) {
319             ITDebugLog(@"Add \"Playlists\" submenu.");
320             tempItem = [menu addItemWithTitle:NSLocalizedString(@"playlists", @"Playlists")
321                     action:nil
322                     keyEquivalent:@""];
323             [tempItem setSubmenu:_playlistsMenu];
324             [tempItem setTag:3];
325         } else if ([nextObject isEqualToString:@"eqPresets"]) {
326             ITDebugLog(@"Add \"EQ Presets\" submenu.");
327             tempItem = [menu addItemWithTitle:NSLocalizedString(@"eqPresets", @"EQ Presets")
328                     action:nil
329                     keyEquivalent:@""];
330             [tempItem setSubmenu:_eqMenu];
331             [tempItem setTag:4];
332             
333             itemEnum = [[_eqMenu itemArray] objectEnumerator];
334             while ( (tempItem = [itemEnum nextObject]) ) {
335                 [tempItem setState:NSOffState];
336             }
337             [[_eqMenu itemAtIndex:([currentRemote currentEQPresetIndex] - 1)] setState:NSOnState];
338         }
339     }
340     ITDebugLog(@"Finished building menu.");
341     [_currentMenu release];
342     _currentMenu = menu;
343     return _currentMenu;
344 }
345
346 - (NSMenu *)menuForNoPlayer
347 {
348     NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
349     NSMenuItem *tempItem;
350     ITDebugLog(@"Creating menu for when player isn't running.");
351     ITDebugLog(@"Add \"Open %@\" menu item.", [[[MainController sharedController] currentRemote] playerSimpleName]);
352     tempItem = [menu addItemWithTitle:[NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"open", @"Open"), [[[MainController sharedController] currentRemote] playerSimpleName]] action:@selector(performMainMenuAction:) keyEquivalent:@""];
353     [tempItem setTag:MTMenuShowPlayerItem];
354     [tempItem setTarget:self];
355     ITDebugLog(@"Add a separator menu item.");
356     [menu addItem:[NSMenuItem separatorItem]];
357     ITDebugLog(@"Add \"Preferences...\" menu item.");
358     tempItem = [menu addItemWithTitle:NSLocalizedString(@"preferences", @"Preferences...") action:@selector(performMainMenuAction:) keyEquivalent:@""];
359     [tempItem setTag:MTMenuPreferencesItem];
360     [tempItem setTarget:self];
361     if ([[MainController sharedController] blingBling] == NO) {
362         ITDebugLog(@"Add \"Register MenuTunes...\" menu item.");
363         tempItem = [menu addItemWithTitle:NSLocalizedString(@"register", @"Register MenuTunes...") action:@selector(performMainMenuAction:) keyEquivalent:@""];
364         [tempItem setTag:MTMenuRegisterItem];
365         [tempItem setTarget:self];
366     }
367     ITDebugLog(@"Add \"Quit\" menu item.");
368     tempItem = [menu addItemWithTitle:NSLocalizedString(@"quit", @"Quit") action:@selector(performMainMenuAction:) keyEquivalent:@""];
369     [tempItem setTag:MTMenuQuitItem];
370     [tempItem setTarget:self];
371     return [menu autorelease];
372 }
373
374 - (void)rebuildSubmenus
375 {
376     ITDebugLog(@"Rebuilding all of the submenus.");
377     
378     currentRemote = [[MainController sharedController] currentRemote];
379     _currentPlaylist = [currentRemote currentPlaylistIndex];
380     _currentTrack = [currentRemote currentSongIndex];
381     _playingRadio = ([currentRemote currentPlaylistClass] == ITMTRemotePlayerRadioPlaylist);
382     
383     [_ratingMenu release];
384     [_upcomingSongsMenu release];
385     [_playlistsMenu release];
386     [_eqMenu release];
387     ITDebugLog(@"Beginning Rebuild of \"Song Rating\" submenu.");
388     _ratingMenu = [self ratingMenu];
389     ITDebugLog(@"Beginning Rebuild of \"Upcoming Songs\" submenu.");
390     _upcomingSongsMenu = [self upcomingSongsMenu];
391     ITDebugLog(@"Beginning Rebuild of \"Playlists\" submenu.");
392     _playlistsMenu = [self playlistsMenu];
393     ITDebugLog(@"Beginning Rebuild of \"EQ Presets\" submenu.");
394     _eqMenu = [self eqMenu];
395     ITDebugLog(@"Done rebuilding all of the submenus.");
396 }
397
398 - (NSMenu *)ratingMenu
399 {
400     NSMenu *ratingMenu = [[NSMenu alloc] initWithTitle:@""];
401     NSEnumerator *itemEnum;
402     id  anItem;
403     int itemTag = 0;
404     SEL itemSelector = @selector(performRatingMenuAction:);
405     
406     ITDebugLog(@"Building \"Song Rating\" menu.");
407     
408     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"☆☆☆☆☆"] action:nil keyEquivalent:@""];
409     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★☆☆☆☆"] action:nil keyEquivalent:@""];
410     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★☆☆☆"] action:nil keyEquivalent:@""];
411     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★★☆☆"] action:nil keyEquivalent:@""];
412     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★★★☆"] action:nil keyEquivalent:@""];
413     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★★★★"] action:nil keyEquivalent:@""];
414     
415     itemEnum = [[ratingMenu itemArray] objectEnumerator];
416     while ( (anItem = [itemEnum nextObject]) ) {
417         ITDebugLog(@"Setting up \"%@\" menu item.", [anItem title]);
418         [anItem setAction:itemSelector];
419         [anItem setTarget:self];
420         [anItem setTag:itemTag];
421         itemTag += 20;
422     }
423     ITDebugLog(@"Done Building \"Song Rating\" menu.");
424     return ratingMenu;
425 }
426
427 - (NSMenu *)upcomingSongsMenu
428 {
429     NSMenu *upcomingSongsMenu = [[NSMenu alloc] initWithTitle:@""];
430     int numSongs = [currentRemote numberOfSongsInPlaylistAtIndex:_currentPlaylist];
431     int numSongsInAdvance = [[NSUserDefaults standardUserDefaults] integerForKey:@"SongsInAdvance"];
432     
433     ITDebugLog(@"Building \"Upcoming Songs\" menu.");
434     
435     if (_currentPlaylist && !_playingRadio) {
436         if (numSongs > 0) {
437             int i;
438
439             for (i = _currentTrack + 1; i <= _currentTrack + numSongsInAdvance; i++) {
440                 if (i <= numSongs) {
441                     NSString *curSong = [currentRemote songTitleAtIndex:i];
442                     NSMenuItem *songItem;
443                     ITDebugLog(@"Adding song: %@", curSong);
444                     songItem = [upcomingSongsMenu addItemWithTitle:curSong action:@selector(performUpcomingSongsMenuAction:) keyEquivalent:@""];
445                     [songItem setTag:i];
446                     [songItem setTarget:self];
447                 } else {
448                     break;
449                 }
450             }
451         }
452     }
453     ITDebugLog(@"Done Building \"Upcoming Songs\" menu.");
454     return upcomingSongsMenu;
455 }
456
457 - (NSMenu *)playlistsMenu
458 {
459     NSMenu *playlistsMenu = [[NSMenu alloc] initWithTitle:@""];
460     NSArray *playlists = [currentRemote playlists];
461     NSMenuItem *tempItem;
462     int i;
463     
464     ITDebugLog(@"Building \"Playlists\" menu.");
465     
466     for (i = 0; i < [playlists count]; i++) {
467         NSString *curPlaylist = [playlists objectAtIndex:i];
468         ITDebugLog(@"Adding playlist: %@", curPlaylist);
469         tempItem = [playlistsMenu addItemWithTitle:curPlaylist action:@selector(performPlaylistMenuAction:) keyEquivalent:@""];
470         [tempItem setTag:i + 1];
471         [tempItem setTarget:self];
472     }
473     
474     if (!_playingRadio && _currentPlaylist) {
475         [[playlistsMenu itemAtIndex:_currentPlaylist - 1] setState:NSOnState];
476     }
477     ITDebugLog(@"Done Building \"Playlists\" menu");
478     return playlistsMenu;
479 }
480
481 - (NSMenu *)eqMenu
482 {
483     NSMenu *eqMenu = [[NSMenu alloc] initWithTitle:@""];
484     NSArray *eqPresets = [currentRemote eqPresets];
485     NSMenuItem *tempItem;
486     int i;
487     
488     ITDebugLog(@"Building \"EQ Presets\" menu.");
489     
490     for (i = 0; i < [eqPresets count]; i++) {
491         NSString *name;
492            if ( ( name = [eqPresets objectAtIndex:i] ) ) {
493             ITDebugLog(@"Adding EQ Preset: %@", name);
494             tempItem = [eqMenu addItemWithTitle:name
495                     action:@selector(performEqualizerMenuAction:)
496                     keyEquivalent:@""];
497             [tempItem setTag:i];
498             [tempItem setTarget:self];
499            }
500     }
501     ITDebugLog(@"Done Building \"EQ Presets\" menu");
502     return eqMenu;
503 }
504
505 - (void)performMainMenuAction:(id)sender
506 {
507     switch ( [sender tag] )
508     {
509         case MTMenuPlayPauseItem:
510             ITDebugLog(@"Performing Menu Action: Play/Pause");
511             [[MainController sharedController] playPause];
512             break;
513         case MTMenuFastForwardItem:
514             ITDebugLog(@"Performing Menu Action: Fast Forward");
515             [[MainController sharedController] fastForward];
516             break;
517         case MTMenuRewindItem:
518             ITDebugLog(@"Performing Menu Action: Rewind");
519             [[MainController sharedController] rewind];
520             break;
521         case MTMenuPreviousTrackItem:
522             ITDebugLog(@"Performing Menu Action: Previous Track");
523             [[MainController sharedController] prevSong];
524             break;
525         case MTMenuNextTrackItem:
526             ITDebugLog(@"Performing Menu Action: Next Track");
527             [[MainController sharedController] nextSong];
528             break;
529         case MTMenuShowPlayerItem:
530             ITDebugLog(@"Performing Menu Action: Show Main Interface");
531             [[MainController sharedController] showPlayer];
532             break;
533         case MTMenuPreferencesItem:
534             ITDebugLog(@"Performing Menu Action: Preferences...");
535             [[MainController sharedController] showPreferences];
536             break;
537         case MTMenuQuitItem:
538             ITDebugLog(@"Performing Menu Action: Quit");
539             [[MainController sharedController] quitMenuTunes];
540             break;
541         case MTMenuRegisterItem:
542             ITDebugLog(@"Performing Menu Action: Register");
543             [[MainController sharedController] blingNow];
544             break;
545         default:
546             ITDebugLog(@"Performing Menu Action: Unimplemented Menu Item OR Child-bearing Menu Item");
547             break;
548     }
549 }
550
551 - (void)performRatingMenuAction:(id)sender
552 {
553     ITDebugLog(@"Rating action selected on item with tag %i", [sender tag]);
554     [[MainController sharedController] selectSongRating:[sender tag]];
555 }
556
557 - (void)performPlaylistMenuAction:(id)sender
558 {
559     ITDebugLog(@"Playlist action selected on item with tag %i", [sender tag]);
560     [[MainController sharedController] selectPlaylistAtIndex:[sender tag]];
561 }
562
563 - (void)performEqualizerMenuAction:(id)sender
564 {
565     ITDebugLog(@"EQ action selected on item with tag %i", [sender tag]);
566     [[MainController sharedController] selectEQPresetAtIndex:[sender tag]];
567 }
568
569 - (void)performUpcomingSongsMenuAction:(id)sender
570 {
571     ITDebugLog(@"Song action selected on item with tag %i", [sender tag]);
572     [[MainController sharedController] selectSongAtIndex:[sender tag]];
573 }
574
575 - (void)updateMenu
576 {
577     ITDebugLog(@"Update Menu");
578     [_currentMenu update];
579 }
580
581 - (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem
582 {
583     return YES;
584 }
585
586 //This is never used I know, keep it though
587 - (NSString *)systemUIColor
588 {
589     NSDictionary *tmpDict;
590     NSNumber *tmpNumber;
591     if ( (tmpDict = [NSDictionary dictionaryWithContentsOfFile:[@"~/Library/Preferences/.GlobalPreferences.plist" stringByExpandingTildeInPath]]) ) {
592         if ( (tmpNumber = [tmpDict objectForKey:@"AppleAquaColorVariant"]) ) {
593             if ( ([tmpNumber intValue] == 1) ) {
594                 return @"Aqua";
595             } else {
596                 return @"Graphite";
597             }
598         } else {
599             return @"Aqua";
600         }
601     } else {
602         return @"Aqua";
603     }
604 }
605
606 - (void)setKeyEquivalentForCode:(short)code andModifiers:(long)modifiers
607         onItem:(NSMenuItem *)item
608 {
609     unichar charcode = 'a';
610     int i;
611     long cocoaModifiers = 0;
612     static long carbonToCocoa[6][2] = 
613     {
614         { cmdKey, NSCommandKeyMask },
615         { optionKey, NSAlternateKeyMask },
616         { controlKey, NSControlKeyMask },
617         { shiftKey, NSShiftKeyMask },
618     };
619     
620     ITDebugLog(@"Setting Key Equivelent on menu item \"%@\".", [item title]);
621     
622     for (i = 0; i < 6; i++) {
623         if (modifiers & carbonToCocoa[i][0]) {
624             cocoaModifiers += carbonToCocoa[i][1];
625         }
626     }
627     [item setKeyEquivalentModifierMask:cocoaModifiers];
628     
629     //Missing key combos for some keys. Must find them later.
630     switch (code)
631     {
632         case 36:
633             ITDebugLog(@"Keycode for menu item \"%@\": 36 (Return)", [item title]);
634             charcode = '\r';
635         break;
636         
637         case 48:
638             ITDebugLog(@"Keycode for menu item \"%@\": 48 (Tab)", [item title]);
639             charcode = '\t';
640         break;
641         
642         //Space -- ARGH!
643         case 49:
644         {
645             ITDebugLog(@"Keycode for menu item \"%@\": 49 (Space)", [item title]);
646             // Haven't tested this, though it should work.
647             // This doesn't work. :'(
648             //unichar buffer;
649             //[[NSString stringWithString:@"Space"] getCharacters:&buffer];
650             //charcode = buffer;
651             /*MenuRef menuRef = _NSGetCarbonMenu([item menu]);
652             ITDebugLog(@"%@", menuRef);
653             SetMenuItemCommandKey(menuRef, 0, NO, 49);
654             SetMenuItemModifiers(menuRef, 0, kMenuNoCommandModifier);
655             SetMenuItemKeyGlyph(menuRef, 0, kMenuBlankGlyph);
656             charcode = 'b';*/
657             unichar buffer;
658             [[NSString stringWithString:@"_"] getCharacters:&buffer]; // this will have to do for now :(
659             charcode = buffer;
660         }
661         break;
662         
663         case 51:
664             ITDebugLog(@"Keycode for menu item \"%@\": 51 (Delete)", [item title]);
665             charcode = NSDeleteFunctionKey;
666         break;
667         
668         case 53:
669             ITDebugLog(@"Keycode for menu item \"%@\": 53 (Escape)", [item title]);
670             charcode = '\e';
671         break;
672         
673         case 71:
674             ITDebugLog(@"Keycode for menu item \"%@\": 71 (Escape)", [item title]);
675             charcode = '\e';
676         break;
677         
678         case 76:
679             ITDebugLog(@"Keycode for menu item \"%@\": 76 (Return)", [item title]);
680             charcode = '\r';
681         break;
682         
683         case 96:
684             ITDebugLog(@"Keycode for menu item \"%@\": 96 (F5)", [item title]);
685             charcode = NSF5FunctionKey;
686         break;
687         
688         case 97:
689             ITDebugLog(@"Keycode for menu item \"%@\": 97 (F6)", [item title]);
690             charcode = NSF6FunctionKey;
691         break;
692         
693         case 98:
694             ITDebugLog(@"Keycode for menu item \"%@\": 98 (F7)", [item title]);
695             charcode = NSF7FunctionKey;
696         break;
697         
698         case 99:
699             ITDebugLog(@"Keycode for menu item \"%@\": 99 (F3)", [item title]);
700             charcode = NSF3FunctionKey;
701         break;
702         
703         case 100:
704             ITDebugLog(@"Keycode for menu item \"%@\": 100 (F8)", [item title]);
705             charcode = NSF8FunctionKey;
706         break;
707         
708         case 101:
709             ITDebugLog(@"Keycode for menu item \"%@\": 101 (F9)", [item title]);
710             charcode = NSF9FunctionKey;
711         break;
712         
713         case 103:
714             ITDebugLog(@"Keycode for menu item \"%@\": 103 (F11)", [item title]);
715             charcode = NSF11FunctionKey;
716         break;
717         
718         case 105:
719             ITDebugLog(@"Keycode for menu item \"%@\": 105 (F3)", [item title]);
720             charcode = NSF3FunctionKey;
721         break;
722         
723         case 107:
724             ITDebugLog(@"Keycode for menu item \"%@\": 107 (F14)", [item title]);
725             charcode = NSF14FunctionKey;
726         break;
727         
728         case 109:
729             ITDebugLog(@"Keycode for menu item \"%@\": 109 (F10)", [item title]);
730             charcode = NSF10FunctionKey;
731         break;
732         
733         case 111:
734             ITDebugLog(@"Keycode for menu item \"%@\": 111 (F12)", [item title]);
735             charcode = NSF12FunctionKey;
736         break;
737         
738         case 113:
739             ITDebugLog(@"Keycode for menu item \"%@\": 113 (F13)", [item title]);
740             charcode = NSF13FunctionKey;
741         break;
742         
743         case 114:
744             ITDebugLog(@"Keycode for menu item \"%@\": 114 (Insert)", [item title]);
745             charcode = NSInsertFunctionKey;
746         break;
747         
748         case 115:
749             ITDebugLog(@"Keycode for menu item \"%@\": 115 (Home)", [item title]);
750             charcode = NSHomeFunctionKey;
751         break;
752         
753         case 116:
754             ITDebugLog(@"Keycode for menu item \"%@\": 116 (PgUp)", [item title]);
755             charcode = NSPageUpFunctionKey;
756         break;
757         
758         case 117:
759             ITDebugLog(@"Keycode for menu item \"%@\": 117 (Delete)", [item title]);
760             charcode = NSDeleteFunctionKey;
761         break;
762         
763         case 118:
764             ITDebugLog(@"Keycode for menu item \"%@\": 118 (F4)", [item title]);
765             charcode = NSF4FunctionKey;
766         break;
767         
768         case 119:
769             ITDebugLog(@"Keycode for menu item \"%@\": 119 (End)", [item title]);
770             charcode = NSEndFunctionKey;
771         break;
772         
773         case 120:
774             ITDebugLog(@"Keycode for menu item \"%@\": 120 (F2)", [item title]);
775             charcode = NSF2FunctionKey;
776         break;
777         
778         case 121:
779             ITDebugLog(@"Keycode for menu item \"%@\": 121 (PgDown)", [item title]);
780             charcode = NSPageDownFunctionKey;
781         break;
782         
783         case 122:
784             ITDebugLog(@"Keycode for menu item \"%@\": 122 (F1)", [item title]);
785             charcode = NSF1FunctionKey;
786         break;
787         
788         case 123:
789             ITDebugLog(@"Keycode for menu item \"%@\": 123 (Left Arrow)", [item title]);
790             charcode = NSLeftArrowFunctionKey;
791         break;
792         
793         case 124:
794             ITDebugLog(@"Keycode for menu item \"%@\": 124 (Right Arrow)", [item title]);
795             charcode = NSRightArrowFunctionKey;
796         break;
797         
798         case 125:
799             ITDebugLog(@"Keycode for menu item \"%@\": 125 (Down Arrow)", [item title]);
800             charcode = NSDownArrowFunctionKey;
801         break;
802         
803         case 126:
804             ITDebugLog(@"Keycode for menu item \"%@\": 126 (Up Arrow)", [item title]);
805             charcode = NSUpArrowFunctionKey;
806         break;
807     }
808     
809     if (charcode == 'a') {
810         unsigned long state;
811         long keyTrans;
812         char charCode;
813         Ptr kchr;
814         state = 0;
815         kchr = (Ptr) GetScriptVariable(smCurrentScript, smKCHRCache);
816         keyTrans = KeyTranslate(kchr, code, &state);
817         charCode = keyTrans;
818         ITDebugLog(@"Keycode for menu item \"%@\": %i (%c)", [item title], code, charCode);
819         [item setKeyEquivalent:[NSString stringWithCString:&charCode length:1]];
820     } else if (charcode != 'b') {
821         [item setKeyEquivalent:[NSString stringWithCharacters:&charcode length:1]];
822     }
823     ITDebugLog(@"Done setting key equivalent on menu item: %@", [item title]);
824 }
825
826 @end