X-Git-Url: http://git.ithinksw.org/MenuTunes.git/blobdiff_plain/a822d608c6739b4c2cd2c39187a78ca461d4d6d4..3a1a21d1ea3e060f88ca1d24ea881f3ccb97640c:/PreferencesController.m diff --git a/PreferencesController.m b/PreferencesController.m index 82b7f82..590e6de 100755 --- a/PreferencesController.m +++ b/PreferencesController.m @@ -1,237 +1,338 @@ #import "PreferencesController.h" #import "MainController.h" -#import "HotKeyCenter.h" +#import "StatusWindow.h" +#import "StatusWindowController.h" +#import "CustomMenuTableView.h" + +#import +#import +#import +#import + +#import +#import +#import +#import +#import + + +#define SENDER_STATE (([sender state] == NSOnState) ? YES : NO) + +/*************************************************************************/ +#pragma mark - +#pragma mark PRIVATE INTERFACE +/*************************************************************************/ + +@interface PreferencesController (Private) +- (void)setupWindow; +- (void)setupCustomizationTables; +- (void)setupMenuItems; +- (void)setupUI; +- (IBAction)changeMenus:(id)sender; +- (void)setLaunchesAtLogin:(BOOL)flag; +@end + @implementation PreferencesController -- (id)initWithMenuTunes:(MainController *)tunes; + +/*************************************************************************/ +#pragma mark - +#pragma mark STATIC VARIABLES +/*************************************************************************/ + +static PreferencesController *prefs = nil; + + +/*************************************************************************/ +#pragma mark - +#pragma mark INITIALIZATION METHODS +/*************************************************************************/ + ++ (PreferencesController *)sharedPrefs; +{ + if (! prefs) { + prefs = [[self alloc] init]; + } + return prefs; +} + +- (id)init { if ( (self = [super init]) ) { - int i; - NSImageCell *imgCell = [[[NSImageCell alloc] init] autorelease]; - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - - mt = [tunes retain]; - [mt registerDefaults]; - - //Load the nib - [NSBundle loadNibNamed:@"Preferences" owner:self]; - - //Set the table view cells up - [imgCell setImageScaling:NSScaleNone]; - [[menuTableView tableColumnWithIdentifier:@"submenu"] setDataCell:imgCell]; - [[allTableView tableColumnWithIdentifier:@"submenu"] setDataCell:imgCell]; - - //Register for drag and drop - [menuTableView registerForDraggedTypes:[NSArray arrayWithObjects:@"MenuTableViewPboardType", @"AllTableViewPboardType", nil]]; - [allTableView registerForDraggedTypes:[NSArray arrayWithObjects:@"MenuTableViewPboardType", @"AllTableViewPboardType", nil]]; - - //Set the list of items you can have. - availableItems = [[NSMutableArray alloc] initWithObjects:@"Current Track Info", @"Upcoming Songs", @"Playlists", @"EQ Presets", @"Song Rating", @"Play/Pause", @"Next Track", @"Previous Track", @"Fast Forward", @"Rewind", @"", nil]; - - //Get our preferred menu - myItems = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"menu"] mutableCopy]; - - //Delete items in the availableItems array that are already part of the menu - for (i = 0; i < [myItems count]; i++) { - NSString *item = [myItems objectAtIndex:i]; - if (![item isEqualToString:@""]) - { - [availableItems removeObject:item]; - } - } - - //Items that show should a submenu image - submenuItems = [[NSArray alloc] initWithObjects:@"Upcoming Songs", @"Playlists", @"EQ Presets", @"Song Rating", nil]; - - //Fill in the number of songs in advance to show field - [songsInAdvance setIntValue:[defaults integerForKey:@"SongsInAdvance"]]; - - //Fill in hot key buttons - if ([defaults objectForKey:@"PlayPause"]){ - playPauseCombo = [defaults keyComboForKey:@"PlayPause"]; - [playPauseButton setTitle:[playPauseCombo userDisplayRep]]; - } else { - playPauseCombo = [[KeyCombo alloc] init]; - } - - if ([defaults objectForKey:@"NextTrack"]) { - nextTrackCombo = [defaults keyComboForKey:@"NextTrack"]; - [nextTrackButton setTitle:[nextTrackCombo userDisplayRep]]; - } else { - nextTrackCombo = [[KeyCombo alloc] init]; - } - - if ([defaults objectForKey:@"PrevTrack"]) { - prevTrackCombo = [defaults keyComboForKey:@"PrevTrack"]; - [previousTrackButton setTitle:[prevTrackCombo userDisplayRep]]; - } else { - prevTrackCombo = [[KeyCombo alloc] init]; - } - - if ([defaults objectForKey:@"TrackInfo"]) { - trackInfoCombo = [defaults keyComboForKey:@"TrackInfo"]; - [trackInfoButton setTitle:[trackInfoCombo userDisplayRep]]; - } else { - trackInfoCombo = [[KeyCombo alloc] init]; - } - - if ([defaults objectForKey:@"UpcomingSongs"]) { - upcomingSongsCombo = [defaults keyComboForKey:@"UpcomingSongs"]; - [upcomingSongsButton setTitle:[upcomingSongsCombo userDisplayRep]]; - } else { - upcomingSongsCombo = [[KeyCombo alloc] init]; - } - - //Check current track info buttons - [albumCheckbox setState:[defaults boolForKey:@"showAlbum"] ? NSOnState : NSOffState]; - [nameCheckbox setState:[defaults boolForKey:@"showName"] ? NSOnState : NSOffState]; - [artistCheckbox setState:[defaults boolForKey:@"showArtist"] ? NSOnState : NSOffState]; - [trackTimeCheckbox setState:[defaults boolForKey:@"showTime"] ? NSOnState : NSOffState]; - - //Set the launch at login checkbox state - { - NSMutableDictionary *loginwindow; - NSMutableArray *loginarray; - int i; - - [defaults synchronize]; - loginwindow = [[defaults persistentDomainForName:@"loginwindow"] mutableCopy]; - loginarray = [loginwindow objectForKey:@"AutoLaunchedApplicationDictionary"]; - - for (i = 0; i < [loginarray count]; i++) { - NSDictionary *tempDict = [loginarray objectAtIndex:i]; - if ([[[tempDict objectForKey:@"Path"] lastPathComponent] isEqualToString:[[[NSBundle mainBundle] bundlePath] lastPathComponent]]) { - [launchAtLoginCheckbox setState:NSOnState]; - } - } - } - - //Show our window - [window setLevel:NSStatusWindowLevel]; - [window center]; - [window makeKeyAndOrderFront:nil]; - [window setDelegate:self]; + ITDebugLog(@"Preferences initialized."); + df = [[NSUserDefaults standardUserDefaults] retain]; + hotKeysDictionary = [[NSMutableDictionary alloc] init]; + controller = nil; } return self; } -- (void)dealloc + +/*************************************************************************/ +#pragma mark - +#pragma mark ACCESSOR METHODS +/*************************************************************************/ + +- (id)controller { - [self setKeyCombo:nil]; - [playPauseCombo release]; - [nextTrackCombo release]; - [prevTrackCombo release]; - [trackInfoCombo release]; - [upcomingSongsCombo release]; - [keyComboPanel release]; - [menuTableView setDataSource:nil]; - [allTableView setDataSource:nil]; - [mt release]; - [availableItems release]; - [submenuItems release]; - [myItems release]; + return controller; } -- (IBAction)apply:(id)sender +- (void)setController:(id)object { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults setObject:myItems forKey:@"menu"]; - - //Set key combos - [defaults setKeyCombo:playPauseCombo forKey:@"PlayPause"]; - [defaults setKeyCombo:nextTrackCombo forKey:@"NextTrack"]; - [defaults setKeyCombo:prevTrackCombo forKey:@"PrevTrack"]; - [defaults setKeyCombo:trackInfoCombo forKey:@"TrackInfo"]; - [defaults setKeyCombo:upcomingSongsCombo forKey:@"UpcomingSongs"]; - - //Set info checkboxes - [defaults setBool:[albumCheckbox state] forKey:@"showAlbum"]; - [defaults setBool:[nameCheckbox state] forKey:@"showName"]; - [defaults setBool:[artistCheckbox state] forKey:@"showArtist"]; - [defaults setBool:[trackTimeCheckbox state] forKey:@"showTime"]; - - //Here we set whether we will launch at login by modifying loginwindow.plist - if ([launchAtLoginCheckbox state] == NSOnState) { - NSMutableDictionary *loginwindow; - NSMutableArray *loginarray; - ComponentInstance temp = OpenDefaultComponent(kOSAComponentType, kAppleScriptSubtype);; - int i; - BOOL skip = NO; - - [defaults synchronize]; - loginwindow = [[defaults persistentDomainForName:@"loginwindow"] mutableCopy]; - loginarray = [loginwindow objectForKey:@"AutoLaunchedApplicationDictionary"]; + [controller autorelease]; + controller = [object retain]; +} + + +/*************************************************************************/ +#pragma mark - +#pragma mark INSTANCE METHODS +/*************************************************************************/ + +- (IBAction)showPrefsWindow:(id)sender +{ + ITDebugLog(@"Showing preferences window."); + if (! window) { // If window does not exist yet, then the nib hasn't been loaded. + ITDebugLog(@"Window doesn't exist, initial setup."); + [self setupWindow]; // Load in the nib, and perform any initial setup. + [self setupCustomizationTables]; // Setup the DnD manu config tables. + [self setupMenuItems]; // Setup the arrays of menu items + [self setupUI]; // Sets up additional UI + [window setDelegate:self]; + [menuTableView reloadData]; - for (i = 0; i < [loginarray count]; i++) { - NSDictionary *tempDict = [loginarray objectAtIndex:i]; - if ([[[tempDict objectForKey:@"Path"] lastPathComponent] isEqualToString:[[[NSBundle mainBundle] bundlePath] lastPathComponent]]) { - skip = YES; - } + //Change the launch player checkbox to the proper name + [launchPlayerAtLaunchCheckbox setTitle:[NSString stringWithFormat:@"Launch %@ when MenuTunes launches", [[controller currentRemote] playerSimpleName]]]; //This isn't localized... + } + + [window center]; + [NSApp activateIgnoringOtherApps:YES]; + [window performSelector:@selector(makeKeyAndOrderFront:) withObject:self afterDelay:0.0]; +} + +- (IBAction)changeGeneralSetting:(id)sender +{ + ITDebugLog(@"Changing general setting of tag %i.", [sender tag]); + if ( [sender tag] == 1010) { + [self setLaunchesAtLogin:SENDER_STATE]; + } else if ( [sender tag] == 1020) { + [df setBool:SENDER_STATE forKey:@"LaunchPlayerWithMT"]; + } else if ( [sender tag] == 1030) { + [df setInteger:[sender intValue] forKey:@"SongsInAdvance"]; + + } else if ( [sender tag] == 1040) { + // This will not be executed. Song info always shows the title of the song. + // [df setBool:SENDER_STATE forKey:@"showName"]; + } else if ( [sender tag] == 1050) { + [df setBool:SENDER_STATE forKey:@"showArtist"]; + } else if ( [sender tag] == 1060) { + [df setBool:SENDER_STATE forKey:@"showAlbum"]; + } else if ( [sender tag] == 1070) { + [df setBool:SENDER_STATE forKey:@"showTime"]; + } else if ( [sender tag] == 1080) { + [df setBool:SENDER_STATE forKey:@"showTrackNumber"]; + } else if ( [sender tag] == 1090) { + [df setBool:SENDER_STATE forKey:@"showTrackRating"]; + } + [df synchronize]; +} + +- (IBAction)changeStatusWindowSetting:(id)sender +{ + StatusWindow *sw = [StatusWindow sharedWindow]; + ITDebugLog(@"Changing status window setting of tag %i", [sender tag]); + if ( [sender tag] == 2010) { + [df setInteger:[sender selectedRow] forKey:@"statusWindowVerticalPosition"]; + [df setInteger:[sender selectedColumn] forKey:@"statusWindowHorizontalPosition"]; + // update the window's position here + } else if ( [sender tag] == 2020) { + // update screen selection + } else if ( [sender tag] == 2030) { + int effectTag = [[sender selectedItem] tag]; + float time = ([df floatForKey:@"statusWindowAppearanceSpeed"] ? [df floatForKey:@"statusWindowAppearanceSpeed"] : 0.8); + [df setInteger:effectTag forKey:@"statusWindowAppearanceEffect"]; + + if ( effectTag == 2100 ) { + [sw setEntryEffect:[[[ITCutWindowEffect alloc] initWithWindow:sw] autorelease]]; + } else if ( effectTag == 2101 ) { + [sw setEntryEffect:[[[ITDissolveWindowEffect alloc] initWithWindow:sw] autorelease]]; + } else if ( effectTag == 2102 ) { + [sw setEntryEffect:[[[ITSlideVerticallyWindowEffect alloc] initWithWindow:sw] autorelease]]; + } else if ( effectTag == 2103 ) { + [sw setEntryEffect:[[[ITSlideHorizontallyWindowEffect alloc] initWithWindow:sw] autorelease]]; + } else if ( effectTag == 2104 ) { + NSLog(@"dflhgldf"); + [sw setEntryEffect:[[[ITPivotWindowEffect alloc] initWithWindow:sw] autorelease]]; } + + [[sw entryEffect] setEffectTime:time]; - if (!skip) { - AEDesc scriptDesc, resultDesc; - NSString *script = [NSString stringWithFormat:@"tell application \"System Events\"\nmake new login item at end of login items with properties {path:\"%@\", kind:\"APPLICATION\"}\nend tell", [[NSBundle mainBundle] bundlePath]]; - - AECreateDesc(typeChar, [script cString], [script cStringLength], - &scriptDesc); - - OSADoScript(temp, &scriptDesc, kOSANullScript, typeChar, kOSAModeCanInteract, &resultDesc); - - AEDisposeDesc(&scriptDesc); - AEDisposeDesc(&resultDesc); - CloseComponent(temp); - } - } else { - NSMutableDictionary *loginwindow; - NSMutableArray *loginarray; - int i; + } else if ( [sender tag] == 2040) { + int effectTag = [[sender selectedItem] tag]; + float time = ([df floatForKey:@"statusWindowVanishSpeed"] ? [df floatForKey:@"statusWindowVanishSpeed"] : 0.8); - [[NSUserDefaults standardUserDefaults] synchronize]; - loginwindow = [[[NSUserDefaults standardUserDefaults] persistentDomainForName:@"loginwindow"] mutableCopy]; - loginarray = [loginwindow objectForKey:@"AutoLaunchedApplicationDictionary"]; + [df setInteger:[[sender selectedItem] tag] forKey:@"statusWindowVanishEffect"]; - for (i = 0; i < [loginarray count]; i++) { - NSDictionary *tempDict = [loginarray objectAtIndex:i]; - if ([[[tempDict objectForKey:@"Path"] lastPathComponent] isEqualToString:[[[NSBundle mainBundle] bundlePath] lastPathComponent]]) { - [loginarray removeObjectAtIndex:i]; - [defaults setPersistentDomain:loginwindow forName:@"loginwindow"]; - [defaults synchronize]; - break; - } + if ( effectTag == 2100 ) { + [sw setExitEffect:[[[ITCutWindowEffect alloc] initWithWindow:sw] autorelease]]; + } else if ( effectTag == 2101 ) { + [sw setExitEffect:[[[ITDissolveWindowEffect alloc] initWithWindow:sw] autorelease]]; + } else if ( effectTag == 2102 ) { + [sw setExitEffect:[[[ITSlideVerticallyWindowEffect alloc] initWithWindow:sw] autorelease]]; + } else if ( effectTag == 2103 ) { + [sw setExitEffect:[[[ITSlideHorizontallyWindowEffect alloc] initWithWindow:sw] autorelease]]; + } else if ( effectTag == 2104 ) { + [sw setExitEffect:[[[ITPivotWindowEffect alloc] initWithWindow:sw] autorelease]]; } + + [[sw exitEffect] setEffectTime:time]; + + } else if ( [sender tag] == 2050) { + float newTime = (-([sender floatValue])); + [df setFloat:newTime forKey:@"statusWindowAppearanceSpeed"]; + [[sw entryEffect] setEffectTime:newTime]; + } else if ( [sender tag] == 2060) { + float newTime = (-([sender floatValue])); + [df setFloat:newTime forKey:@"statusWindowVanishSpeed"]; + [[sw exitEffect] setEffectTime:newTime]; + } else if ( [sender tag] == 2070) { + [df setFloat:[sender floatValue] forKey:@"statusWindowVanishDelay"]; + [sw setExitDelay:[sender floatValue]]; + } else if ( [sender tag] == 2080) { + [df setBool:SENDER_STATE forKey:@"showSongInfoOnChange"]; } - - //Set songs in advance - if ([songsInAdvance intValue]) { - [defaults setInteger:[songsInAdvance intValue] forKey:@"SongsInAdvance"]; - } else { - [defaults setInteger:5 forKey:@"SongsInAdvance"]; + [df synchronize]; +} + +- (IBAction)changeHotKey:(id)sender +{ + ITDebugLog(@"Changing hot keys."); + [controller clearHotKeys]; + switch ([sender tag]) + { + case 4010: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"PlayPause"]]; + [self setCurrentHotKey:@"PlayPause"]; + break; + case 4020: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"NextTrack"]]; + [self setCurrentHotKey:@"NextTrack"]; + break; + case 4030: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"PrevTrack"]]; + [self setCurrentHotKey:@"PrevTrack"]; + break; + case 4035: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"ShowPlayer"]]; + [self setCurrentHotKey:@"ShowPlayer"]; + break; + case 4040: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"ToggleLoop"]]; + [self setCurrentHotKey:@"ToggleLoop"]; + break; + case 4050: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"ToggleShuffle"]]; + [self setCurrentHotKey:@"ToggleShuffle"]; + break; + case 4060: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"TrackInfo"]]; + [self setCurrentHotKey:@"TrackInfo"]; + break; + case 4070: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"UpcomingSongs"]]; + [self setCurrentHotKey:@"UpcomingSongs"]; + break; + case 4080: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"IncrementVolume"]]; + [self setCurrentHotKey:@"IncrementVolume"]; + break; + case 4090: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"DecrementVolume"]]; + [self setCurrentHotKey:@"DecrementVolume"]; + break; + case 4100: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"IncrementRating"]]; + [self setCurrentHotKey:@"IncrementRating"]; + break; + case 4110: + [self setKeyCombo:[hotKeysDictionary objectForKey:@"DecrementRating"]]; + [self setCurrentHotKey:@"DecrementRating"]; + break; } +} + +- (void)registerDefaults +{ + BOOL found = NO; + NSMutableDictionary *loginWindow; + NSMutableArray *loginArray; + NSEnumerator *loginEnum; + id anItem; + ITDebugLog(@"Registering defaults."); + [df setObject:[NSArray arrayWithObjects: + @"playPause", + @"prevTrack", + @"nextTrack", + @"fastForward", + @"rewind", + @"showPlayer", + @"separator", + @"songRating", + @"eqPresets", + @"playlists", + @"upcomingSongs", + @"separator", + @"preferences", + @"quit", + @"separator", + @"trackInfo", + nil] forKey:@"menu"]; + + [df setInteger:5 forKey:@"SongsInAdvance"]; + // [df setBool:YES forKey:@"showName"]; // Song info will always show song title. + [df setBool:YES forKey:@"showArtist"]; + [df setBool:NO forKey:@"showAlbum"]; + [df setBool:NO forKey:@"showTime"]; + + [df synchronize]; - /*{ - NSArray *apps = [[NSWorkspace sharedWorkspace] launchedApplications]; - int i; - - for (i = 0; i < [apps count]; i++) { - if ([[[apps objectAtIndex:i] objectForKey:@"NSApplicationName"] - isEqualToString:@"iTunes"]) { - [mt rebuildMenu]; - } + loginWindow = [[df persistentDomainForName:@"loginwindow"] mutableCopy]; + loginArray = [loginWindow objectForKey:@"AutoLaunchedApplicationDictionary"]; + loginEnum = [loginArray objectEnumerator]; + + while ( (anItem = [loginEnum nextObject]) ) { + if ( [[[anItem objectForKey:@"Path"] lastPathComponent] isEqualToString:[[[NSBundle mainBundle] bundlePath] lastPathComponent]] ) { + found = YES; } - }*/ - [mt clearHotKeys]; + } + [loginWindow release]; + + if (!found) { + [[StatusWindowController sharedController] showSetupQueryWindow]; + } } -- (IBAction)cancel:(id)sender +- (void)autoLaunchOK { - [window close]; - [mt closePreferences]; + [[StatusWindow sharedWindow] setLocked:NO]; + [[StatusWindow sharedWindow] vanish:self]; + [[StatusWindow sharedWindow] setIgnoresMouseEvents:YES]; + + [self setLaunchesAtLogin:YES]; +} + +- (void)autoLaunchCancel +{ + [[StatusWindow sharedWindow] setLocked:NO]; + [[StatusWindow sharedWindow] vanish:self]; + [[StatusWindow sharedWindow] setIgnoresMouseEvents:YES]; } - (IBAction)cancelHotKey:(id)sender { + ITDebugLog(@"Hot key canceled."); [[NSNotificationCenter defaultCenter] removeObserver:self]; [NSApp endSheet:keyComboPanel]; [keyComboPanel orderOut:nil]; @@ -239,172 +340,444 @@ - (IBAction)clearHotKey:(id)sender { - [self setKeyCombo:[KeyCombo clearKeyCombo]]; + ITDebugLog(@"Hot key cleared."); + [self setKeyCombo:[ITKeyCombo clearKeyCombo]]; } - (IBAction)okHotKey:(id)sender { - NSString *string = [combo userDisplayRep]; + NSString *string = [combo description]; + NSEnumerator *enumerator = [hotKeysDictionary keyEnumerator]; + NSString *enumKey; + + ITDebugLog(@"Hot key ok'd, saving."); if (string == nil) { - string = @"None"; + string = @""; } - if ([setHotKey isEqualToString:@"PlayPause"]) { - if (([combo isEqual:nextTrackCombo] || [combo isEqual:prevTrackCombo] || - [combo isEqual:trackInfoCombo] || [combo isEqual:upcomingSongsCombo]) && - !(([combo modifiers] == -1) && ([combo keyCode] == -1))) { - - [window setLevel:NSNormalWindowLevel]; - NSRunAlertPanel(@"Duplicate Key Combo", @"Please choose a unique key combo.", @"OK", nil, nil, nil); - [window setLevel:NSStatusWindowLevel]; - return; + + ITDebugLog(@"Checking for duplicate hot keys."); + while ( (enumKey = [enumerator nextObject]) ) { + if (![enumKey isEqualToString:currentHotKey]) { + if (![combo isEqual:[ITKeyCombo clearKeyCombo]] && + [combo isEqual:[hotKeysDictionary objectForKey:enumKey]]) { + [window setLevel:NSNormalWindowLevel]; + ITDebugLog(@"Duplicate hot key found: %@", enumKey); + if ( NSRunAlertPanel(NSLocalizedString(@"duplicateCombo", @"Duplicate Key Combo") , NSLocalizedString(@"duplicateCombo_msg", @"The specified key combo is already in use..."), NSLocalizedString(@"replace", @"Replace"), NSLocalizedString(@"cancel", @"Cancel"), nil) ) { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:currentHotKey]; + if ([enumKey isEqualToString:@"PlayPause"]) { + [playPauseButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"NextTrack"]) { + [nextTrackButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"PrevTrack"]) { + [previousTrackButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"ShowPlayer"]) { + [showPlayerButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"TrackInfo"]) { + [trackInfoButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"UpcomingSongs"]) { + [upcomingSongsButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"IncrementVolume"]) { + [volumeIncrementButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"DecrementVolume"]) { + [volumeDecrementButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"IncrementRating"]) { + [ratingIncrementButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"DecrementRating"]) { + [ratingDecrementButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"ToggleShuffle"]) { + [toggleShuffleButton setTitle:@"(None)"]; + } else if ([enumKey isEqualToString:@"ToggleLoop"]) { + [toggleLoopButton setTitle:@"(None)"]; + } + ITDebugLog(@"Saved hot key named %@.", enumKey); + [df setObject:[[ITKeyCombo clearKeyCombo] plistRepresentation] forKey:enumKey]; + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:enumKey]; + } else { + return; + } + [window setLevel:NSStatusWindowLevel]; + } } - playPauseCombo = [combo copy]; - [playPauseButton setTitle:string]; } - else if ([setHotKey isEqualToString:@"NextTrack"]) - { - if (([combo isEqual:playPauseCombo] || [combo isEqual:prevTrackCombo] || - [combo isEqual:trackInfoCombo] || [combo isEqual:upcomingSongsCombo]) && - !(([combo modifiers] == -1) && ([combo keyCode] == -1))) { - - [window setLevel:NSNormalWindowLevel]; - NSRunAlertPanel(@"Duplicate Key Combo", @"Please choose a unique key combo.", @"OK", nil, nil, nil); - [window setLevel:NSStatusWindowLevel]; - return; - } - nextTrackCombo = [combo copy]; + + ITDebugLog(@"Saved hot key named %@.", currentHotKey); + [hotKeysDictionary setObject:combo forKey:currentHotKey]; + [df setObject:[combo plistRepresentation] forKey:currentHotKey]; + + ITDebugLog(@"Setting button name."); + if ([currentHotKey isEqualToString:@"PlayPause"]) { + [playPauseButton setTitle:string]; + } else if ([currentHotKey isEqualToString:@"NextTrack"]) { [nextTrackButton setTitle:string]; - } - else if ([setHotKey isEqualToString:@"PrevTrack"]) - { - if (([combo isEqual:nextTrackCombo] || [combo isEqual:playPauseCombo] || - [combo isEqual:trackInfoCombo] || [combo isEqual:upcomingSongsCombo]) && - !(([combo modifiers] == -1) && ([combo keyCode] == -1))) { - - [window setLevel:NSNormalWindowLevel]; - NSRunAlertPanel(@"Duplicate Key Combo", @"Please choose a unique key combo.", @"OK", nil, nil, nil); - [window setLevel:NSStatusWindowLevel]; - return; - } - prevTrackCombo = [combo copy]; + } else if ([currentHotKey isEqualToString:@"PrevTrack"]) { [previousTrackButton setTitle:string]; - } - else if ([setHotKey isEqualToString:@"TrackInfo"]) - { - if (([combo isEqual:nextTrackCombo] || [combo isEqual:prevTrackCombo] || - [combo isEqual:playPauseCombo] || [combo isEqual:upcomingSongsCombo]) && - !(([combo modifiers] == -1) && ([combo keyCode] == -1))) { - - [window setLevel:NSNormalWindowLevel]; - NSRunAlertPanel(@"Duplicate Key Combo", @"Please choose a unique key combo.", @"OK", nil, nil, nil); - [window setLevel:NSStatusWindowLevel]; - return; - } - trackInfoCombo = [combo copy]; + } else if ([currentHotKey isEqualToString:@"ShowPlayer"]) { + [showPlayerButton setTitle:string]; + } else if ([currentHotKey isEqualToString:@"TrackInfo"]) { [trackInfoButton setTitle:string]; - } - else if ([setHotKey isEqualToString:@"UpcomingSongs"]) - { - if (([combo isEqual:nextTrackCombo] || [combo isEqual:prevTrackCombo] || - [combo isEqual:trackInfoCombo] || [combo isEqual:playPauseCombo]) && - !(([combo modifiers] == -1) && ([combo keyCode] == -1))) { - - [window setLevel:NSNormalWindowLevel]; - NSRunAlertPanel(@"Duplicate Key Combo", @"Please choose a unique key combo.", @"OK", nil, nil, nil); - [window setLevel:NSStatusWindowLevel]; - return; - } - upcomingSongsCombo = [combo copy]; + } else if ([currentHotKey isEqualToString:@"UpcomingSongs"]) { [upcomingSongsButton setTitle:string]; + } else if ([currentHotKey isEqualToString:@"IncrementVolume"]) { + [volumeIncrementButton setTitle:string]; + } else if ([currentHotKey isEqualToString:@"DecrementVolume"]) { + [volumeDecrementButton setTitle:string]; + } else if ([currentHotKey isEqualToString:@"IncrementRating"]) { + [ratingIncrementButton setTitle:string]; + } else if ([currentHotKey isEqualToString:@"DecrementRating"]) { + [ratingDecrementButton setTitle:string]; + } else if ([currentHotKey isEqualToString:@"ToggleShuffle"]) { + [toggleShuffleButton setTitle:string]; + } else if ([currentHotKey isEqualToString:@"ToggleLoop"]) { + [toggleLoopButton setTitle:string]; } + [controller setupHotKeys]; [self cancelHotKey:sender]; } -- (IBAction)save:(id)sender +- (void)deletePressedInTableView:(NSTableView *)tableView { - [self apply:nil]; - [window close]; - [mt closePreferences]; + if (tableView == menuTableView) { + int selRow = [tableView selectedRow]; + ITDebugLog(@"Delete pressed in menu table view."); + if (selRow != - 1) { + NSString *object = [myItems objectAtIndex:selRow]; + + if ([object isEqualToString:@"preferences"]) { + NSBeep(); + return; + } + + if (![object isEqualToString:@"separator"]) + [availableItems addObject:object]; + ITDebugLog(@"Removing object named %@", object); + [myItems removeObjectAtIndex:selRow]; + [menuTableView reloadData]; + [allTableView reloadData]; + } + [self changeMenus:self]; + } } -- (IBAction)setCurrentTrackInfo:(id)sender + +/*************************************************************************/ +#pragma mark - +#pragma mark HOTKEY SUPPORT METHODS +/*************************************************************************/ + +- (void)setCurrentHotKey:(NSString *)key { - [self setKeyCombo:trackInfoCombo]; - [self setHotKey:@"TrackInfo"]; + ITDebugLog(@"Setting current hot key to %@", key); + [currentHotKey autorelease]; + currentHotKey = [key copy]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyEvent:) name:ITKeyBroadcasterKeyEvent object:nil]; + [NSApp beginSheet:keyComboPanel modalForWindow:window modalDelegate:self didEndSelector:nil contextInfo:nil]; } -- (IBAction)setNextTrack:(id)sender +- (void)keyEvent:(NSNotification *)note { - [self setKeyCombo:nextTrackCombo]; - [self setHotKey:@"NextTrack"]; + [self setKeyCombo:[[[note userInfo] objectForKey:@"keyCombo"] copy]]; } -- (IBAction)setPlayPause:(id)sender +- (void)setKeyCombo:(ITKeyCombo *)newCombo { - [self setKeyCombo:playPauseCombo]; - [self setHotKey:@"PlayPause"]; + NSString *string; + [combo release]; + combo = [newCombo copy]; + ITDebugLog(@"Setting key combo to %@", newCombo); + string = [combo description]; + if (string == nil) { + string = @"(None)"; + } + [keyComboField setStringValue:string]; } -- (IBAction)setPreviousTrack:(id)sender + +/*************************************************************************/ +#pragma mark - +#pragma mark PRIVATE METHOD IMPLEMENTATIONS +/*************************************************************************/ + +- (void)setupWindow { - [self setKeyCombo:prevTrackCombo]; - [self setHotKey:@"PrevTrack"]; + ITDebugLog(@"Loading Preferences.nib."); + if (![NSBundle loadNibNamed:@"Preferences" owner:self]) { + ITDebugLog(@"Failed to load Preferences.nib."); + NSBeep(); + return; + } } -- (IBAction)setUpcomingSongs:(id)sender +- (void)setupCustomizationTables { - [self setKeyCombo:upcomingSongsCombo]; - [self setHotKey:@"UpcomingSongs"]; + NSImageCell *imgCell = [[[NSImageCell alloc] initImageCell:nil] autorelease]; + ITDebugLog(@"Setting up table views."); + // Set the table view cells up + [imgCell setImageScaling:NSScaleNone]; + [[menuTableView tableColumnWithIdentifier:@"submenu"] setDataCell:imgCell]; + [[allTableView tableColumnWithIdentifier:@"submenu"] setDataCell:imgCell]; + + // Register for drag and drop + [menuTableView registerForDraggedTypes:[NSArray arrayWithObjects: + @"MenuTableViewPboardType", + @"AllTableViewPboardType", + nil]]; + [allTableView registerForDraggedTypes:[NSArray arrayWithObjects: + @"MenuTableViewPboardType", + @"AllTableViewPboardType", + nil]]; } -- (void)setHotKey:(NSString *)key +- (void)setupMenuItems { - setHotKey = key; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyEvent:) name:@"KeyBroadcasterEvent" object:nil]; - [NSApp beginSheet:keyComboPanel modalForWindow:window modalDelegate:self didEndSelector:nil contextInfo:nil]; + NSEnumerator *itemEnum; + id anItem; + ITDebugLog(@"Setting up table view arrays."); + // Set the list of items you can have. + availableItems = [[NSMutableArray alloc] initWithObjects: + @"separator", + @"trackInfo", + @"upcomingSongs", + @"playlists", + @"eqPresets", + @"songRating", + @"playPause", + @"nextTrack", + @"prevTrack", + @"fastForward", + @"rewind", + @"showPlayer", + @"quit", + nil]; + + // Get our preferred menu + myItems = [[df arrayForKey:@"menu"] mutableCopy]; + + // Delete items in the availableItems array that are already part of the menu + itemEnum = [myItems objectEnumerator]; + while ( (anItem = [itemEnum nextObject]) ) { + if (![anItem isEqualToString:@"separator"]) { + [availableItems removeObject:anItem]; + } + } + + // Items that show should a submenu image + submenuItems = [[NSArray alloc] initWithObjects: + @"upcomingSongs", + @"playlists", + @"eqPresets", + @"songRating", + nil]; } -- (void)keyEvent:(NSNotification *)note +- (void)setupUI { - NSDictionary *info = [note userInfo]; - short keyCode; - long modifiers; - KeyCombo *newCombo; + NSMutableDictionary *loginwindow; + NSMutableArray *loginarray; + NSEnumerator *loginEnum; + id anItem; + ITDebugLog(@"Setting up preferences UI."); + // Fill in the number of songs in advance to show field + [songsInAdvance setIntValue:[df integerForKey:@"SongsInAdvance"]]; + + // Fill in hot key buttons + if ([df objectForKey:@"PlayPause"]) { + ITDebugLog(@"Setting up \"PlayPause\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"PlayPause"]]; + [hotKeysDictionary setObject:anItem forKey:@"PlayPause"]; + [playPauseButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"PlayPause"]; + [playPauseButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } + + if ([df objectForKey:@"NextTrack"]) { + ITDebugLog(@"Setting up \"NextTrack\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"NextTrack"]]; + [hotKeysDictionary setObject:anItem forKey:@"NextTrack"]; + [nextTrackButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"NextTrack"]; + [nextTrackButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } + + if ([df objectForKey:@"PrevTrack"]) { + ITDebugLog(@"Setting up \"PrevTrack\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"PrevTrack"]]; + [hotKeysDictionary setObject:anItem forKey:@"PrevTrack"]; + [previousTrackButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"PrevTrack"]; + [previousTrackButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } + + if ([df objectForKey:@"ShowPlayer"]) { + ITDebugLog(@"Setting up \"ShowPlayer\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"ShowPlayer"]]; + [hotKeysDictionary setObject:anItem forKey:@"ShowPlayer"]; + [showPlayerButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"ShowPlayer"]; + [showPlayerButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } - keyCode = [[info objectForKey:@"KeyCode"] shortValue]; - modifiers = [[info objectForKey:@"Modifiers"] longValue]; + if ([df objectForKey:@"TrackInfo"]) { + ITDebugLog(@"Setting up \"TrackInfo\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"TrackInfo"]]; + [hotKeysDictionary setObject:anItem forKey:@"TrackInfo"]; + [trackInfoButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"TrackInfo"]; + [trackInfoButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } - newCombo = [[KeyCombo alloc] initWithKeyCode:keyCode andModifiers:modifiers]; - [self setKeyCombo:newCombo]; + if ([df objectForKey:@"UpcomingSongs"]) { + ITDebugLog(@"Setting up \"UpcomingSongs\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"UpcomingSongs"]]; + [hotKeysDictionary setObject:anItem forKey:@"UpcomingSongs"]; + [upcomingSongsButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"UpcomingSongs"]; + [upcomingSongsButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } + + if ([df objectForKey:@"IncrementVolume"]) { + ITDebugLog(@"Setting up \"IncrementVolume\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"IncrementVolume"]]; + [hotKeysDictionary setObject:anItem forKey:@"IncrementVolume"]; + [volumeIncrementButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"IncrementVolume"]; + [volumeIncrementButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } + + if ([df objectForKey:@"DecrementVolume"]) { + ITDebugLog(@"Setting up \"DecrementVolume\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"DecrementVolume"]]; + [hotKeysDictionary setObject:anItem forKey:@"DecrementVolume"]; + [volumeDecrementButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"DecrementVolume"]; + [volumeDecrementButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } + + if ([df objectForKey:@"IncrementRating"]) { + ITDebugLog(@"Setting up \"IncrementRating\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"IncrementRating"]]; + [hotKeysDictionary setObject:anItem forKey:@"IncrementRating"]; + [ratingIncrementButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"IncrementRating"]; + [ratingIncrementButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } + + if ([df objectForKey:@"DecrementRating"]) { + ITDebugLog(@"Setting up \"DecrementRating\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"DecrementRating"]]; + [hotKeysDictionary setObject:anItem forKey:@"DecrementRating"]; + [ratingDecrementButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"DecrementRating"]; + [ratingDecrementButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } + + if ([df objectForKey:@"ToggleLoop"]) { + ITDebugLog(@"Setting up \"ToggleLoop\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"ToggleLoop"]]; + [hotKeysDictionary setObject:anItem forKey:@"ToggleLoop"]; + [toggleLoopButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"ToggleLoop"]; + [toggleLoopButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } + + if ([df objectForKey:@"ToggleShuffle"]) { + ITDebugLog(@"Setting up \"ToggleShuffle\" hot key."); + anItem = [ITKeyCombo keyComboWithPlistRepresentation:[df objectForKey:@"ToggleShuffle"]]; + [hotKeysDictionary setObject:anItem forKey:@"ToggleShuffle"]; + [toggleShuffleButton setTitle:[anItem description]]; + } else { + [hotKeysDictionary setObject:[ITKeyCombo clearKeyCombo] forKey:@"ToggleShuffle"]; + [toggleShuffleButton setTitle:[[ITKeyCombo clearKeyCombo] description]]; + } + + ITDebugLog(@"Setting up track info checkboxes."); + // Check current track info buttons + [albumCheckbox setState:[df boolForKey:@"showAlbum"] ? NSOnState : NSOffState]; + [nameCheckbox setState:NSOnState]; // Song info will ALWAYS show song title. + [nameCheckbox setEnabled:NO]; // Song info will ALWAYS show song title. + [artistCheckbox setState:[df boolForKey:@"showArtist"] ? NSOnState : NSOffState]; + [trackTimeCheckbox setState:[df boolForKey:@"showTime"] ? NSOnState : NSOffState]; + [trackNumberCheckbox setState:[df boolForKey:@"showTrackNumber"] ? NSOnState : NSOffState]; + [ratingCheckbox setState:[df boolForKey:@"showTrackRating"] ? NSOnState : NSOffState]; + + // Set the launch at login checkbox state + ITDebugLog(@"Setting launch at login state."); + [df synchronize]; + loginwindow = [[df persistentDomainForName:@"loginwindow"] mutableCopy]; + loginarray = [loginwindow objectForKey:@"AutoLaunchedApplicationDictionary"]; + + loginEnum = [loginarray objectEnumerator]; + while ( (anItem = [loginEnum nextObject]) ) { + if ([[[anItem objectForKey:@"Path"] lastPathComponent] isEqualToString:[[[NSBundle mainBundle] bundlePath] lastPathComponent]]) { + [launchAtLoginCheckbox setState:NSOnState]; + } + } } -- (void)setKeyCombo:(KeyCombo *)newCombo +- (IBAction)changeMenus:(id)sender { - NSString *string; - [combo release]; - combo = [newCombo copy]; + ITDebugLog(@"Synchronizing menus"); + [df setObject:myItems forKey:@"menu"]; + [df synchronize]; +} + +- (void)setLaunchesAtLogin:(BOOL)flag +{ + NSMutableDictionary *loginwindow; + NSMutableArray *loginarray; + ITDebugLog(@"Setting launches at login: %i", flag); + [df synchronize]; + loginwindow = [[df persistentDomainForName:@"loginwindow"] mutableCopy]; + loginarray = [loginwindow objectForKey:@"AutoLaunchedApplicationDictionary"]; - string = [combo userDisplayRep]; - if (string == nil) { - string = @""; + if (flag) { + NSDictionary *itemDict = [NSDictionary dictionaryWithObjectsAndKeys: + [[NSBundle mainBundle] bundlePath], @"Path", + [NSNumber numberWithInt:0], @"Hide", nil]; + [loginarray addObject:itemDict]; + } else { + int i; + for (i = 0; i < [loginarray count]; i++) { + NSDictionary *tempDict = [loginarray objectAtIndex:i]; + if ([[[tempDict objectForKey:@"Path"] lastPathComponent] isEqualToString:[[[NSBundle mainBundle] bundlePath] lastPathComponent]]) { + [loginarray removeObjectAtIndex:i]; + break; + } + } } - [keyComboField setStringValue:string]; + [df setPersistentDomain:loginwindow forName:@"loginwindow"]; + [df synchronize]; + [loginwindow release]; + ITDebugLog(@"Finished setting launches at login."); } -// -// + +/*************************************************************************/ +#pragma mark - +#pragma mark NSWindow DELEGATE METHODS +/*************************************************************************/ - (void)windowWillClose:(NSNotification *)note { - [mt closePreferences]; + [(MainController *)controller closePreferences]; } -// -// -// Table View Datasource Methods -// -// + +/*************************************************************************/ +#pragma mark - +#pragma mark NSTableView DATASOURCE METHODS +/*************************************************************************/ - (int)numberOfRowsInTableView:(NSTableView *)aTableView { @@ -418,10 +791,14 @@ - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { if (aTableView == menuTableView) { + NSString *object = [myItems objectAtIndex:rowIndex]; if ([[aTableColumn identifier] isEqualToString:@"name"]) { - return [myItems objectAtIndex:rowIndex]; + if ([object isEqualToString:@"showPlayer"]) { + return [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"show", @"Show"), [[controller currentRemote] playerSimpleName]]; + } + return NSLocalizedString(object, @"ERROR"); } else { - if ([submenuItems containsObject:[myItems objectAtIndex:rowIndex]]) + if ([submenuItems containsObject:object]) { return [NSImage imageNamed:@"submenu"]; } else { @@ -429,10 +806,14 @@ } } } else { + NSString *object = [availableItems objectAtIndex:rowIndex]; if ([[aTableColumn identifier] isEqualToString:@"name"]) { - return [availableItems objectAtIndex:rowIndex]; + if ([object isEqualToString:@"showPlayer"]) { + return [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"show", @"Show"), [[controller currentRemote] playerSimpleName]]; + } + return NSLocalizedString(object, @"ERROR"); } else { - if ([submenuItems containsObject:[availableItems objectAtIndex:rowIndex]]) { + if ([submenuItems containsObject:object]) { return [NSImage imageNamed:@"submenu"]; } else { return nil; @@ -469,32 +850,35 @@ dragData = [pb stringForType:@"MenuTableViewPboardType"]; dragRow = [dragData intValue]; temp = [myItems objectAtIndex:dragRow]; - [myItems removeObjectAtIndex:dragRow]; if (tableView == menuTableView) { + [myItems insertObject:temp atIndex:row]; if (row > dragRow) { - [myItems insertObject:temp atIndex:row - 1]; + [myItems removeObjectAtIndex:dragRow]; } else { - [myItems insertObject:temp atIndex:row]; + [myItems removeObjectAtIndex:dragRow + 1]; } } else { - if (![temp isEqualToString:@""]) { + if (![temp isEqualToString:@"separator"]) { [availableItems addObject:temp]; } + [myItems removeObjectAtIndex:dragRow]; } } else if ([[pb types] containsObject:@"AllTableViewPboardType"]) { dragData = [pb stringForType:@"AllTableViewPboardType"]; dragRow = [dragData intValue]; temp = [availableItems objectAtIndex:dragRow]; - if (![temp isEqualToString:@""]) { + [myItems insertObject:temp atIndex:row]; + + if (![temp isEqualToString:@"separator"]) { [availableItems removeObjectAtIndex:dragRow]; } - [myItems insertObject:temp atIndex:row]; } [menuTableView reloadData]; [allTableView reloadData]; + [self changeMenus:self]; return YES; } @@ -507,7 +891,7 @@ if ([[[info draggingPasteboard] types] containsObject:@"MenuTableViewPboardType"]) { NSString *item = [myItems objectAtIndex:[[[info draggingPasteboard] stringForType:@"MenuTableViewPboardType"] intValue]]; - if ([item isEqualToString:@"PreferencesÉ"] || [item isEqualToString:@"Quit"]) { + if ([item isEqualToString:@"preferences"]) { return NSDragOperationNone; } } @@ -524,4 +908,25 @@ return NSDragOperationGeneric; } + +/*************************************************************************/ +#pragma mark - +#pragma mark DEALLOCATION METHODS +/*************************************************************************/ + +- (void)dealloc +{ + [self setKeyCombo:nil]; + [hotKeysDictionary release]; + [keyComboPanel release]; + [menuTableView setDataSource:nil]; + [allTableView setDataSource:nil]; + [controller release]; + [availableItems release]; + [submenuItems release]; + [myItems release]; + [df release]; +} + + @end