Key combos will now show up as key equivalents in the menu, using the new
[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 <ITKit/ITHotKeyCenter.h>
12 #import <ITKit/ITHotKey.h>
13 #import <ITKit/ITKeyCombo.h>
14
15 @interface MenuController (SubmenuMethods)
16 - (NSMenu *)ratingMenu;
17 - (NSMenu *)upcomingSongsMenu;
18 - (NSMenu *)playlistsMenu;
19 - (NSMenu *)eqMenu;
20 - (void)setKeyEquivalentForCode:(short)code andModifiers:(long)modifiers
21         onItem:(NSMenuItem *)item;
22 @end
23
24 @implementation MenuController
25
26 - (id)init
27 {
28     if ( (self = [super init]) ) {
29         _menuLayout = [[NSMutableArray alloc] initWithCapacity:0];
30     }
31     return self;
32 }
33
34 - (NSMenu *)menu
35 {
36     NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
37     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
38     NSArray *menuArray = [defaults arrayForKey:@"menu"];
39     NSEnumerator *enumerator = [menuArray objectEnumerator];
40     NSString *nextObject;
41     NSMenuItem *tempItem;
42     NSEnumerator *itemEnum;
43     ITHotKey *hotKey;
44     NSArray *hotKeys = [[ITHotKeyCenter sharedCenter] allHotKeys];
45     
46     //Get the information
47     _currentPlaylist = [currentRemote currentPlaylistIndex];
48     _playingRadio = ([currentRemote currentPlaylistClass] == ITMTRemotePlayerRadioPlaylist);
49     
50     //Kill the old submenu items
51     if ( (tempItem = [_currentMenu itemWithTag:1]) ) {
52         [tempItem setSubmenu:nil];
53     }
54     
55     if ( (tempItem = [_currentMenu itemWithTag:2]) ) {
56         [tempItem setSubmenu:nil];
57     }
58     
59     if ( (tempItem = [_currentMenu itemWithTag:3]) ) {
60         [tempItem setSubmenu:nil];
61     }
62     
63     if ( (tempItem = [_currentMenu itemWithTag:4]) ) {
64         [tempItem setSubmenu:nil];
65     }
66     
67     //create our menu
68     while ( (nextObject = [enumerator nextObject]) ) {
69         //Main menu items
70         if ([nextObject isEqualToString:@"playPause"]) {
71             tempItem = [menu addItemWithTitle:NSLocalizedString(@"play", @"Play")
72                     action:@selector(performMainMenuAction:)
73                     keyEquivalent:@""];
74             [tempItem setTag:MTMenuPlayPauseItem];
75             [tempItem setTarget:self];
76             
77             itemEnum = [hotKeys objectEnumerator];
78             while ( (hotKey = [itemEnum nextObject]) ) {
79                 if ([[hotKey name] isEqualToString:@"PlayPause"]) {
80                     ITKeyCombo *combo = [hotKey keyCombo];
81                     [self setKeyEquivalentForCode:[combo keyCode]
82                           andModifiers:[combo modifiers]
83                           onItem:tempItem];
84                 }
85             }
86             
87             switch ([currentRemote playerPlayingState]) {
88                 case ITMTRemotePlayerPlaying:
89                     [tempItem setTitle:NSLocalizedString(@"pause", @"Pause")];
90                 break;
91                 case ITMTRemotePlayerRewinding:
92                 case ITMTRemotePlayerForwarding:
93                     [tempItem setTitle:NSLocalizedString(@"resume", @"Resume")];
94                 break;
95                 default:
96                 break;
97             }
98         } else if ([nextObject isEqualToString:@"nextTrack"]) {
99             tempItem = [menu addItemWithTitle:NSLocalizedString(@"nextTrack", @"Next Track")
100                     action:@selector(performMainMenuAction:)
101                     keyEquivalent:@""];
102             
103             itemEnum = [hotKeys objectEnumerator];
104             while ( (hotKey = [itemEnum nextObject]) ) {
105                 if ([[hotKey name] isEqualToString:@"NextTrack"]) {
106                     ITKeyCombo *combo = [hotKey keyCombo];
107                     [self setKeyEquivalentForCode:[combo keyCode]
108                           andModifiers:[combo modifiers]
109                           onItem:tempItem];
110                 }
111             }
112             
113             if (_currentPlaylist) {
114                 [tempItem setTag:MTMenuNextTrackItem];
115                 [tempItem setTarget:self];
116             }
117         } else if ([nextObject isEqualToString:@"prevTrack"]) {
118             tempItem = [menu addItemWithTitle:NSLocalizedString(@"prevTrack", @"Previous Track")
119                     action:@selector(performMainMenuAction:)
120                     keyEquivalent:@""];
121             
122             itemEnum = [hotKeys objectEnumerator];
123             while ( (hotKey = [itemEnum nextObject]) ) {
124                 if ([[hotKey name] isEqualToString:@"PrevTrack"]) {
125                     ITKeyCombo *combo = [hotKey keyCombo];
126                     [self setKeyEquivalentForCode:[combo keyCode]
127                           andModifiers:[combo modifiers]
128                           onItem:tempItem];
129                 }
130             }
131             
132             if (_currentPlaylist) {
133                 [tempItem setTag:MTMenuPreviousTrackItem];
134                 [tempItem setTarget:self];
135             }
136         } else if ([nextObject isEqualToString:@"fastForward"]) {
137             tempItem = [menu addItemWithTitle:NSLocalizedString(@"fastForward", @"Fast Forward")
138                     action:@selector(performMainMenuAction:)
139                     keyEquivalent:@""];
140             if (_currentPlaylist) {
141                 [tempItem setTag:MTMenuFastForwardItem];
142                 [tempItem setTarget:self];
143             }
144         } else if ([nextObject isEqualToString:@"rewind"]) {
145             tempItem = [menu addItemWithTitle:NSLocalizedString(@"rewind", @"Rewind")
146                     action:@selector(performMainMenuAction:)
147                     keyEquivalent:@""];
148             if (_currentPlaylist) {
149                 [tempItem setTag:MTMenuRewindItem];
150                 [tempItem setTarget:self];
151             }
152         } else if ([nextObject isEqualToString:@"showPlayer"]) {
153             tempItem = [menu addItemWithTitle:[NSString stringWithFormat:@"%@ %@",
154                             NSLocalizedString(@"show", @"Show"),
155                             [[[MainController sharedController] currentRemote] playerSimpleName]]
156                     action:@selector(performMainMenuAction:)
157                     keyEquivalent:@""];
158             
159             itemEnum = [hotKeys objectEnumerator];
160             while ( (hotKey = [itemEnum nextObject]) ) {
161                 if ([[hotKey name] isEqualToString:@"ShowPlayer"]) {
162                     ITKeyCombo *combo = [hotKey keyCombo];
163                     [self setKeyEquivalentForCode:[combo keyCode]
164                           andModifiers:[combo modifiers]
165                           onItem:tempItem];
166                 }
167             }
168             
169             [tempItem setTarget:self];
170             [tempItem setTag:MTMenuShowPlayerItem];
171         } else if ([nextObject isEqualToString:@"preferences"]) {
172             tempItem = [menu addItemWithTitle:NSLocalizedString(@"preferences", @"Preferences...")
173                     action:@selector(performMainMenuAction:)
174                     keyEquivalent:@""];
175             [tempItem setTag:MTMenuPreferencesItem];
176             [tempItem setTarget:self];
177         } else if ([nextObject isEqualToString:@"quit"]) {
178             tempItem = [menu addItemWithTitle:NSLocalizedString(@"quit", @"Quit")
179                     action:@selector(performMainMenuAction:)
180                     keyEquivalent:@""];
181             [tempItem setTag:MTMenuQuitItem];
182             [tempItem setTarget:self];
183         } else if ([nextObject isEqualToString:@"trackInfo"]) {
184             //Handle playing radio too
185             if (_currentPlaylist) {
186                 NSString *title = [currentRemote currentSongTitle];
187                 
188                 [menu addItemWithTitle:NSLocalizedString(@"nowPlaying", @"Now Playing") action:NULL keyEquivalent:@""];
189                 
190                 if ([title length] > 0) {
191                     [menu addItemWithTitle:[NSString stringWithFormat:@"         %@", title]
192                             action:nil
193                             keyEquivalent:@""];
194                 }
195                 
196                 if ([defaults boolForKey:@"showAlbum"]) {
197                     NSString *curAlbum = [currentRemote currentSongAlbum];
198                     if ([curAlbum length]) {
199                         [menu addItemWithTitle:[NSString stringWithFormat:@"     %@", curAlbum]
200                                 action:nil
201                                 keyEquivalent:@""];
202                     }
203                 }
204                 
205                 if ([defaults boolForKey:@"showArtist"]) {
206                     NSString *curArtist = [currentRemote currentSongArtist];
207                     if ([curArtist length]) {
208                         [menu addItemWithTitle:[NSString stringWithFormat:@"     %@", curArtist]
209                                 action:nil
210                                 keyEquivalent:@""];
211                     }
212                 }
213                 
214                 if ([defaults boolForKey:@"showTrackNumber"]) {
215                     int track = [currentRemote currentSongTrack];
216                     if (track) {
217                         [menu addItemWithTitle:[NSString stringWithFormat:@"     %@ %i", NSLocalizedString(@"track", @"Track"), track]
218                             action:nil
219                             keyEquivalent:@""];
220                     }
221                 }
222                 
223                 if ([defaults boolForKey:@"showTime"]) {
224                     int left = [[currentRemote currentSongRemaining] intValue];
225                     NSString *remaining = [NSString stringWithFormat:@"%i:%02i", left / 60, left % 60];
226                     [menu addItemWithTitle:[NSString stringWithFormat:@"         %@/%@", remaining, [currentRemote currentSongLength]]
227                             action:nil
228                             keyEquivalent:@""];
229                 }
230             } else {
231                 [menu addItemWithTitle:NSLocalizedString(@"noSong", @"No Song") action:NULL keyEquivalent:@""];
232             }
233         } else if ([nextObject isEqualToString:@"separator"]) {
234             [menu addItem:[NSMenuItem separatorItem]];
235         //Submenu items
236         } else if ([nextObject isEqualToString:@"songRating"]) {
237             tempItem = [menu addItemWithTitle:NSLocalizedString(@"songRating", @"Song Rating")
238                     action:nil
239                     keyEquivalent:@""];
240             [tempItem setSubmenu:_ratingMenu];
241             [tempItem setTag:1];
242             if (_playingRadio || !_currentPlaylist) {
243                 [tempItem setEnabled:NO];
244             }
245             
246             itemEnum = [[_ratingMenu itemArray] objectEnumerator];
247             while ( (tempItem = [itemEnum nextObject]) ) {
248                 [tempItem setState:NSOffState];
249             }
250             
251             [[_ratingMenu itemAtIndex:([currentRemote currentSongRating] * 5)] setState:NSOnState];
252         } else if ([nextObject isEqualToString:@"upcomingSongs"]) {
253             tempItem = [menu addItemWithTitle:NSLocalizedString(@"upcomingSongs", @"Upcoming Songs")
254                     action:nil
255                     keyEquivalent:@""];
256             [tempItem setSubmenu:_upcomingSongsMenu];
257             [tempItem setTag:2];
258             if (_playingRadio || !_currentPlaylist) {
259                 [tempItem setEnabled:NO];
260             }
261         } else if ([nextObject isEqualToString:@"playlists"]) {
262             tempItem = [menu addItemWithTitle:NSLocalizedString(@"playlists", @"Playlists")
263                     action:nil
264                     keyEquivalent:@""];
265             [tempItem setSubmenu:_playlistsMenu];
266             [tempItem setTag:3];
267         } else if ([nextObject isEqualToString:@"eqPresets"]) {
268             tempItem = [menu addItemWithTitle:NSLocalizedString(@"eqPresets", @"EQ Presets")
269                     action:nil
270                     keyEquivalent:@""];
271             [tempItem setSubmenu:_eqMenu];
272             [tempItem setTag:4];
273             
274             itemEnum = [[_eqMenu itemArray] objectEnumerator];
275             while ( (tempItem = [itemEnum nextObject]) ) {
276                 [tempItem setState:NSOffState];
277             }
278             [[_eqMenu itemAtIndex:([currentRemote currentEQPresetIndex] - 1)] setState:NSOnState];
279         }
280     }
281     [_currentMenu release];
282     _currentMenu = menu;
283     return _currentMenu;
284 }
285
286 - (NSMenu *)menuForNoPlayer
287 {
288     NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
289     NSMenuItem *tempItem;
290     tempItem = [menu addItemWithTitle:[NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"open", @"Open"), [[[MainController sharedController] currentRemote] playerSimpleName]] action:@selector(performMainMenuAction:) keyEquivalent:@""];
291     [tempItem setTag:MTMenuShowPlayerItem];
292     [tempItem setTarget:self];
293     [menu addItem:[NSMenuItem separatorItem]];
294     tempItem = [menu addItemWithTitle:NSLocalizedString(@"preferences", @"Preferences...") action:@selector(performMainMenuAction:) keyEquivalent:@""];
295     [tempItem setTag:MTMenuPreferencesItem];
296     [tempItem setTarget:self];
297     tempItem = [menu addItemWithTitle:NSLocalizedString(@"quit", @"Quit") action:@selector(performMainMenuAction:) keyEquivalent:@""];
298     [tempItem setTag:MTMenuQuitItem];
299     [tempItem setTarget:self];
300     return [menu autorelease];
301 }
302
303 - (void)rebuildSubmenus
304 {
305     currentRemote = [[MainController sharedController] currentRemote];
306     _currentPlaylist = [currentRemote currentPlaylistIndex];
307     _currentTrack = [currentRemote currentSongIndex];
308     _playingRadio = ([currentRemote currentPlaylistClass] == ITMTRemotePlayerRadioPlaylist);
309     
310     [_ratingMenu release];
311     [_upcomingSongsMenu release];
312     [_playlistsMenu release];
313     [_eqMenu release];
314     _ratingMenu = [self ratingMenu];
315     _upcomingSongsMenu = [self upcomingSongsMenu];
316     _playlistsMenu = [self playlistsMenu];
317     _eqMenu = [self eqMenu];
318 }
319
320 - (NSMenu *)ratingMenu
321 {
322     NSMenu *ratingMenu = [[NSMenu alloc] initWithTitle:@""];
323     NSEnumerator *itemEnum;
324     id  anItem;
325     int itemTag = 0;
326     SEL itemSelector = @selector(performRatingMenuAction:);
327     
328     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"☆☆☆☆☆"] action:nil keyEquivalent:@""];
329     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★☆☆☆☆"] action:nil keyEquivalent:@""];
330     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★☆☆☆"] action:nil keyEquivalent:@""];
331     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★★☆☆"] action:nil keyEquivalent:@""];
332     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★★★☆"] action:nil keyEquivalent:@""];
333     [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★★★★"] action:nil keyEquivalent:@""];
334     
335     itemEnum = [[ratingMenu itemArray] objectEnumerator];
336     while ( (anItem = [itemEnum nextObject]) ) {
337         [anItem setAction:itemSelector];
338         [anItem setTarget:self];
339         [anItem setTag:itemTag];
340         itemTag += 20;
341     }
342     return ratingMenu;
343 }
344
345 - (NSMenu *)upcomingSongsMenu
346 {
347     NSMenu *upcomingSongsMenu = [[NSMenu alloc] initWithTitle:@""];
348     int numSongs = [currentRemote numberOfSongsInPlaylistAtIndex:_currentPlaylist];
349     int numSongsInAdvance = [[NSUserDefaults standardUserDefaults] integerForKey:@"SongsInAdvance"];
350     
351     if (_currentPlaylist && !_playingRadio) {
352         if (numSongs > 0) {
353             int i;
354             
355             for (i = _currentTrack + 1; i <= _currentTrack + numSongsInAdvance; i++) {
356                 if (i <= numSongs) {
357                     NSString *curSong = [currentRemote songTitleAtIndex:i];
358                     NSMenuItem *songItem;
359                     songItem = [upcomingSongsMenu addItemWithTitle:curSong action:@selector(performUpcomingSongsMenuAction:) keyEquivalent:@""];
360                     [songItem setTag:i];
361                     [songItem setTarget:self];
362                 } else {
363                     break;
364                 }
365             }
366         }
367     }
368     return upcomingSongsMenu;
369 }
370
371 - (NSMenu *)playlistsMenu
372 {
373     NSMenu *playlistsMenu = [[NSMenu alloc] initWithTitle:@""];
374     NSArray *playlists = [currentRemote playlists];
375     NSMenuItem *tempItem;
376     int i;
377     
378     for (i = 0; i < [playlists count]; i++) {
379         tempItem = [playlistsMenu addItemWithTitle:[playlists objectAtIndex:i] action:@selector(performPlaylistMenuAction:) keyEquivalent:@""];
380         [tempItem setTag:i + 1];
381         [tempItem setTarget:self];
382     }
383     
384     if (!_playingRadio && _currentPlaylist) {
385         [[playlistsMenu itemAtIndex:_currentPlaylist - 1] setState:NSOnState];
386     }
387     return playlistsMenu;
388 }
389
390 - (NSMenu *)eqMenu
391 {
392     NSMenu *eqMenu = [[NSMenu alloc] initWithTitle:@""];
393     NSArray *eqPresets = [currentRemote eqPresets];
394     NSMenuItem *tempItem;
395     int i;
396     
397     for (i = 0; i < [eqPresets count]; i++) {
398         NSString *name;
399         if ( ( name = [eqPresets objectAtIndex:i] ) ) {
400             tempItem = [eqMenu addItemWithTitle:name action:@selector(performEqualizerMenuAction:) keyEquivalent:@""];
401             [tempItem setTag:i];
402             [tempItem setTarget:self];
403         }
404     }
405     return eqMenu;
406 }
407
408 - (void)performMainMenuAction:(id)sender
409 {
410     switch ( [sender tag] )
411     {
412         case MTMenuPlayPauseItem:
413             NSLog(@"MenuController: Play/Pause");
414             [[MainController sharedController] playPause];
415             break;
416         case MTMenuFastForwardItem:
417             NSLog(@"MenuController: Fast Forward");
418             [[MainController sharedController] fastForward];
419             break;
420         case MTMenuRewindItem:
421             NSLog(@"MenuController: Rewind");
422             [[MainController sharedController] rewind];
423             break;
424         case MTMenuPreviousTrackItem:
425             NSLog(@"MenuController: Previous Track");
426             [[MainController sharedController] prevSong];
427             break;
428         case MTMenuNextTrackItem:
429             NSLog(@"MenuController: Next Track");
430             [[MainController sharedController] nextSong];
431             break;
432         case MTMenuShowPlayerItem:
433             NSLog(@"MainController: Show Main Interface");
434             [[MainController sharedController] showPlayer];
435             break;
436         case MTMenuPreferencesItem:
437             NSLog(@"MenuController: Preferences...");
438             [[MainController sharedController] showPreferences];
439             break;
440         case MTMenuQuitItem:
441             NSLog(@"MenuController: Quit");
442             [[MainController sharedController] quitMenuTunes];
443             break;
444         default:
445             NSLog(@"MenuController: Unimplemented Menu Item OR Child-bearing Menu Item");
446             break;
447     }
448 }
449
450 - (void)performRatingMenuAction:(id)sender
451 {
452     [[MainController sharedController] selectSongRating:[sender tag]];
453 }
454
455 - (void)performPlaylistMenuAction:(id)sender
456 {
457     [[MainController sharedController] selectPlaylistAtIndex:[sender tag]];
458 }
459
460 - (void)performEqualizerMenuAction:(id)sender
461 {
462     [[MainController sharedController] selectEQPresetAtIndex:[sender tag]];
463 }
464
465 - (void)performUpcomingSongsMenuAction:(id)sender
466 {
467     [[MainController sharedController] selectSongAtIndex:[sender tag]];
468 }
469
470 - (void)updateMenu
471 {
472     
473     [_currentMenu update];
474 }
475
476 - (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem
477 {
478     return YES;
479 }
480
481 - (NSString *)systemUIColor
482 {
483     NSDictionary *tmpDict;
484     NSNumber *tmpNumber;
485     if ( (tmpDict = [NSDictionary dictionaryWithContentsOfFile:[@"~/Library/Preferences/.GlobalPreferences.plist" stringByExpandingTildeInPath]]) ) {
486         if ( (tmpNumber = [tmpDict objectForKey:@"AppleAquaColorVariant"]) ) {
487             if ( ([tmpNumber intValue] == 1) ) {
488                 return @"Aqua";
489             } else {
490                 return @"Graphite";
491             }
492         } else {
493             return @"Aqua";
494         }
495     } else {
496         return @"Aqua";
497     }
498 }
499
500 - (void)setKeyEquivalentForCode:(short)code andModifiers:(long)modifiers
501         onItem:(NSMenuItem *)item
502 {
503     unichar charcode = 'a';
504     int i;
505     long cocoaModifiers = 0;
506     static long carbonToCocoa[6][2] = 
507     {
508         { cmdKey, NSCommandKeyMask },
509         { optionKey, NSAlternateKeyMask },
510         { controlKey, NSControlKeyMask },
511         { shiftKey, NSShiftKeyMask },
512     };
513     
514     for (i = 0; i < 6; i++) {
515         if (modifiers & carbonToCocoa[i][0]) {
516             cocoaModifiers += carbonToCocoa[i][1];
517         }
518     }
519     [item setKeyEquivalentModifierMask:cocoaModifiers];
520     
521     //Missing key combos for some keys. Must find them later.
522     switch (code)
523     {
524         case 36:
525             charcode = '\r';
526         break;
527         
528         case 48:
529             charcode = '\t';
530         break;
531         
532         //Space -- ARGH!
533         case 49:
534         {
535             // Haven't tested this, though it should work.
536             // This doesn't work. :'(
537             unichar buffer;
538             [[NSString stringWithString:@"Space"] getCharacters:&buffer];
539             charcode = buffer;
540             /*MenuRef menuRef = _NSGetCarbonMenu([item menu]);
541             NSLog(@"%@", menuRef);
542             SetMenuItemCommandKey(menuRef, 0, NO, 49);
543             SetMenuItemModifiers(menuRef, 0, kMenuNoCommandModifier);
544             SetMenuItemKeyGlyph(menuRef, 0, kMenuBlankGlyph);
545             charcode = 'b';*/
546             
547         }
548         break;
549         
550         case 51:
551             charcode = NSDeleteFunctionKey;
552         break;
553         
554         case 53:
555             charcode = '\e';
556         break;
557         
558         case 71:
559             charcode = '\e';
560         break;
561         
562         case 76:
563             charcode = '\r';
564         break;
565         
566         case 96:
567             charcode = NSF5FunctionKey;
568         break;
569         
570         case 97:
571             charcode = NSF6FunctionKey;
572         break;
573         
574         case 98:
575             charcode = NSF7FunctionKey;
576         break;
577         
578         case 99:
579             charcode = NSF3FunctionKey;
580         break;
581         
582         case 100:
583             charcode = NSF8FunctionKey;
584         break;
585         
586         case 101:
587             charcode = NSF9FunctionKey;
588         break;
589         
590         case 103:
591             charcode = NSF11FunctionKey;
592         break;
593         
594         case 105:
595             charcode = NSF3FunctionKey;
596         break;
597         
598         case 107:
599             charcode = NSF14FunctionKey;
600         break;
601         
602         case 109:
603             charcode = NSF10FunctionKey;
604         break;
605         
606         case 111:
607             charcode = NSF12FunctionKey;
608         break;
609         
610         case 113:
611             charcode = NSF13FunctionKey;
612         break;
613         
614         case 114:
615             charcode = NSInsertFunctionKey;
616         break;
617         
618         case 115:
619             charcode = NSHomeFunctionKey;
620         break;
621         
622         case 116:
623             charcode = NSPageUpFunctionKey;
624         break;
625         
626         case 117:
627             charcode = NSDeleteFunctionKey;
628         break;
629         
630         case 118:
631             charcode = NSF4FunctionKey;
632         break;
633         
634         case 119:
635             charcode = NSEndFunctionKey;
636         break;
637         
638         case 120:
639             charcode = NSF2FunctionKey;
640         break;
641         
642         case 121:
643             charcode = NSPageDownFunctionKey;
644         break;
645         
646         case 122:
647             charcode = NSF1FunctionKey;
648         break;
649         
650         case 123:
651             charcode = NSLeftArrowFunctionKey;
652         break;
653         
654         case 124:
655             charcode = NSRightArrowFunctionKey;
656         break;
657         
658         case 125:
659             charcode = NSDownArrowFunctionKey;
660         break;
661         
662         case 126:
663             charcode = NSUpArrowFunctionKey;
664         break;
665     }
666     
667     if (charcode == 'a') {
668         unsigned long state;
669         long keyTrans;
670         char charCode;
671         Ptr kchr;
672         state = 0;
673         kchr = (Ptr) GetScriptVariable(smCurrentScript, smKCHRCache);
674         keyTrans = KeyTranslate(kchr, code, &state);
675         charCode = keyTrans;
676         [item setKeyEquivalent:[NSString stringWithCString:&charCode length:1]];
677     } else if (charcode != 'b') {
678         [item setKeyEquivalent:[NSString stringWithCharacters:&charcode length:1]];
679     }
680 }
681
682 @end