X-Git-Url: http://git.ithinksw.org/MenuTunes.git/blobdiff_plain/d80384d37fa13bec5d65bc6aa97248036f743052..e40a6bb44d76a738d58a321039b6932c4688b12a:/MenuTunes.m diff --git a/MenuTunes.m b/MenuTunes.m index 4398815..d2fdaf2 100755 --- a/MenuTunes.m +++ b/MenuTunes.m @@ -1,16 +1,7 @@ -/* -Things to do: -¥ Make preferences window pretty -¥ Optimize -¥ Apple Events! Apple Events! Apple Events! -¥ Manual and webpage -¥ Finish up registration frontend -*/ - #import "MenuTunes.h" #import "PreferencesController.h" #import "HotKeyCenter.h" -#import "StatusWindowController.h" +#import "StatusWindow.h" @interface MenuTunes(Private) - (ITMTRemote *)loadRemote; @@ -19,9 +10,7 @@ Things to do: - (void)rebuildPlaylistMenu; - (void)rebuildEQPresetsMenu; - (void)setupHotKeys; -- (NSString *)runScriptAndReturnResult:(NSString *)script; - (void)timerUpdate; -- (void)sendAEWithEventClass:(AEEventClass)eventClass andEventID:(AEEventID)eventID; - (void)setKeyEquivalentForCode:(short)code andModifiers:(long)modifiers onItem:(NSMenuItem *)item; @@ -38,6 +27,7 @@ Things to do: { if ( ( self = [super init] ) ) { remoteArray = [[NSMutableArray alloc] initWithCapacity:1]; + statusWindow = [StatusWindow sharedWindow]; } return self; } @@ -47,36 +37,20 @@ Things to do: currentRemote = [self loadRemote]; [currentRemote begin]; - asComponent = OpenDefaultComponent(kOSAComponentType, kAppleScriptSubtype); - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(remotePlayerTerminated:) name:@"ITMTRemoteAppDidTerminateNotification" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(remotePlayerLaunched:) name:@"ITMTRemoteAppDidLaunchNotification" object:nil]; + [self registerDefaultsIfNeeded]; menu = [[NSMenu alloc] initWithTitle:@""]; - iTunesPSN = [self iTunesPSN]; //Get PSN of iTunes if it's running - if (!((iTunesPSN.highLongOfPSN == kNoProcess) && (iTunesPSN.lowLongOfPSN == 0))) - { - [self rebuildMenu]; - refreshTimer = [NSTimer scheduledTimerWithTimeInterval:3.5 - target:self - selector:@selector(timerUpdate) - userInfo:nil - repeats:YES]; - - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(iTunesTerminated:) name:NSWorkspaceDidTerminateApplicationNotification object:nil]; - } - else - { - menu = [[NSMenu alloc] initWithTitle:@""]; - [[menu addItemWithTitle:@"Open iTunes" action:@selector(openiTunes:) keyEquivalent:@""] setTarget:self]; - [[menu addItemWithTitle:@"Preferences" action:@selector(showPreferences:) keyEquivalent:@""] setTarget:self]; - [[menu addItemWithTitle:@"Quit" action:@selector(quitMenuTunes:) keyEquivalent:@""] setTarget:self]; - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(iTunesLaunched:) name:NSWorkspaceDidLaunchApplicationNotification object:nil]; - refreshTimer = nil; + if ( ( [currentRemote playerRunningStatus] == ITMTRemotePlayerRunning ) ) { + [self remotePlayerLaunched:nil]; + } else { + [self remotePlayerTerminated:nil]; } - - statusItem = [[ITStatusItem alloc] initWithStatusBar:[NSStatusBar systemStatusBar] - withLength:NSSquareStatusItemLength]; + + statusItem = [[ITStatusItem alloc] initWithStatusBar:[NSStatusBar systemStatusBar] withLength:NSSquareStatusItemLength]; [statusItem setImage:[NSImage imageNamed:@"menu"]]; [statusItem setAlternateImage:[NSImage imageNamed:@"selected_image"]]; @@ -88,7 +62,7 @@ Things to do: - (ITMTRemote *)loadRemote { NSString *folderPath = [[NSBundle mainBundle] builtInPlugInsPath]; - + if (folderPath) { NSArray *bundlePathList = [NSBundle pathsForResourcesOfType:@"remote" inDirectory:folderPath]; NSEnumerator *enumerator = [bundlePathList objectEnumerator]; @@ -109,14 +83,14 @@ Things to do: } } -// if ( [remoteArray count] > 0 ) { +// if ( [remoteArray count] > 0 ) { // UNCOMMENT WHEN WE HAVE > 1 PLUGIN // if ( [remoteArray count] > 1 ) { // [remoteArray sortUsingSelector:@selector(sortAlpha:)]; // } // [self loadModuleAccessUI]; //Comment out this line to disable remote visibility // } } - NSLog(@"%@", [remoteArray objectAtIndex:0]); +// NSLog(@"%@", [remoteArray objectAtIndex:0]); //DEBUG return [remoteArray objectAtIndex:0]; } @@ -130,7 +104,7 @@ Things to do: { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if (![defaults objectForKey:@"menu"]) { - bool found = NO; + BOOL found = NO; NSMutableDictionary *loginwindow; NSMutableArray *loginarray; int i; @@ -145,6 +119,7 @@ Things to do: @"", @"Upcoming Songs", @"Playlists", + @"Song Rating", @"", @"PreferencesÉ", @"Quit", @@ -163,10 +138,14 @@ Things to do: } } + // + //This is teh sux + //We must fix it so it is no longer suxy if (!found) { if (NSRunInformationalAlertPanel(@"Auto-launch MenuTunes", @"Would you like MenuTunes to automatically launch at login?", @"Yes", @"No", nil) == NSOKButton) { 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]]; + ComponentInstance asComponent = OpenDefaultComponent(kOSAComponentType, kAppleScriptSubtype); AECreateDesc(typeChar, [script cString], [script cStringLength], &scriptDesc); @@ -175,6 +154,8 @@ Things to do: AEDisposeDesc(&scriptDesc); AEDisposeDesc(&resultDesc); + + CloseComponent(asComponent); } } } @@ -209,6 +190,7 @@ Things to do: trackInfoIndex = -1; lastSongIndex = -1; + lastPlaylistIndex = -1; didHaveAlbumName = ([[currentRemote currentSongAlbum] length] > 0); didHaveArtistName = ([[currentRemote currentSongArtist] length] > 0); @@ -218,6 +200,7 @@ Things to do: playPauseMenuItem = nil; upcomingSongsItem = nil; + songRatingMenuItem = nil; playlistItem = nil; [playlistMenu release]; playlistMenu = nil; @@ -234,8 +217,7 @@ Things to do: keyEquivalent:@""]; [playPauseMenuItem setTarget:self]; - if (tempCombo) - { + if (tempCombo) { [self setKeyEquivalentForCode:[tempCombo keyCode] andModifiers:[tempCombo modifiers] onItem:playPauseMenuItem]; [tempCombo release]; @@ -247,8 +229,7 @@ Things to do: keyEquivalent:@""]; [nextTrack setTarget:self]; - if (tempCombo) - { + if (tempCombo) { [self setKeyEquivalentForCode:[tempCombo keyCode] andModifiers:[tempCombo modifiers] onItem:nextTrack]; [tempCombo release]; @@ -260,45 +241,48 @@ Things to do: keyEquivalent:@""]; [prevTrack setTarget:self]; - if (tempCombo) - { + if (tempCombo) { [self setKeyEquivalentForCode:[tempCombo keyCode] andModifiers:[tempCombo modifiers] onItem:prevTrack]; [tempCombo release]; } } else if ([item isEqualToString:@"Fast Forward"]) { [[menu addItemWithTitle:@"Fast Forward" - action:@selector(fastForward:) - keyEquivalent:@""] setTarget:self]; + action:@selector(fastForward:) + keyEquivalent:@""] setTarget:self]; } else if ([item isEqualToString:@"Rewind"]) { [[menu addItemWithTitle:@"Rewind" - action:@selector(rewind:) - keyEquivalent:@""] setTarget:self]; + action:@selector(rewind:) + keyEquivalent:@""] setTarget:self]; } else if ([item isEqualToString:@"Upcoming Songs"]) { upcomingSongsItem = [menu addItemWithTitle:@"Upcoming Songs" - action:nil - keyEquivalent:@""]; + action:nil + keyEquivalent:@""]; } else if ([item isEqualToString:@"Playlists"]) { playlistItem = [menu addItemWithTitle:@"Playlists" - action:nil - keyEquivalent:@""]; + action:nil + keyEquivalent:@""]; } else if ([item isEqualToString:@"EQ Presets"]) { eqItem = [menu addItemWithTitle:@"EQ Presets" - action:nil - keyEquivalent:@""]; + action:nil + keyEquivalent:@""]; } else if ([item isEqualToString:@"PreferencesÉ"]) { [[menu addItemWithTitle:@"PreferencesÉ" - action:@selector(showPreferences:) - keyEquivalent:@""] setTarget:self]; + action:@selector(showPreferences:) + keyEquivalent:@""] setTarget:self]; } else if ([item isEqualToString:@"Quit"]) { [[menu addItemWithTitle:@"Quit" - action:@selector(quitMenuTunes:) - keyEquivalent:@""] setTarget:self]; + action:@selector(quitMenuTunes:) + keyEquivalent:@""] setTarget:self]; } else if ([item isEqualToString:@"Current Track Info"]) { trackInfoIndex = [menu numberOfItems]; [menu addItemWithTitle:@"No Song" - action:nil - keyEquivalent:@""]; + action:nil + keyEquivalent:@""]; + } else if ([item isEqualToString:@"Song Rating"]) { + songRatingMenuItem = [menu addItemWithTitle:@"Song Rating" + action:nil + keyEquivalent:@""]; } else if ([item isEqualToString:@""]) { [menu addItem:[NSMenuItem separatorItem]]; } @@ -316,7 +300,7 @@ Things to do: NSMenuItem *menuItem; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - if ((iTunesPSN.highLongOfPSN == kNoProcess) && (iTunesPSN.lowLongOfPSN == 0)) { + if ( ( isAppRunning == ITMTRemotePlayerNotRunning ) ) { return; } @@ -331,9 +315,7 @@ Things to do: if (eqItem) { [self rebuildEQPresetsMenu]; } - - if (trackInfoIndex > -1) - { + if (trackInfoIndex > -1) { NSString *curSongName, *curAlbumName = @"", *curArtistName = @""; curSongName = [currentRemote currentSongTitle]; @@ -365,33 +347,63 @@ Things to do: if (!isPlayingRadio) { if ([defaults boolForKey:@"showTime"]) { menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:@" %@", [currentRemote currentSongLength]] - action:nil - keyEquivalent:@""]; + action:nil + keyEquivalent:@""]; [menu insertItem:menuItem atIndex:trackInfoIndex + 1]; [menuItem release]; } if ([curArtistName length] > 0) { menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:@" %@", curArtistName] - action:nil - keyEquivalent:@""]; + action:nil + keyEquivalent:@""]; [menu insertItem:menuItem atIndex:trackInfoIndex + 1]; [menuItem release]; } if ([curAlbumName length] > 0) { menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:@" %@", curAlbumName] - action:nil - keyEquivalent:@""]; + action:nil + keyEquivalent:@""]; [menu insertItem:menuItem atIndex:trackInfoIndex + 1]; [menuItem release]; } + + if (songRatingMenuItem) { + int rating = (int)[currentRemote currentSongRating] * 10; + int i; + + for (i = 0; i < 5; i++) { + [[ratingMenu itemAtIndex:i] setState:NSOffState]; + } + + switch (rating) { + case 0: + [[ratingMenu itemAtIndex:5] setState:NSOnState]; + break; + case 2: + [[ratingMenu itemAtIndex:4] setState:NSOnState]; + break; + case 4: + [[ratingMenu itemAtIndex:3] setState:NSOnState]; + break; + case 6: + [[ratingMenu itemAtIndex:2] setState:NSOnState]; + break; + case 8: + [[ratingMenu itemAtIndex:1] setState:NSOnState]; + break; + case 10: + [[ratingMenu itemAtIndex:0] setState:NSOnState]; + break; + } + } } if ([defaults boolForKey:@"showName"]) { menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:@" %@", curSongName] - action:nil - keyEquivalent:@""]; + action:nil + keyEquivalent:@""]; [menu insertItem:menuItem atIndex:trackInfoIndex + 1]; [menuItem release]; } @@ -401,6 +413,9 @@ Things to do: [menu removeItemAtIndex:[menu indexOfItemWithTitle:@"No Song"]]; [menu insertItem:menuItem atIndex:trackInfoIndex]; [menuItem release]; + + [songRatingMenuItem setSubmenu:ratingMenu]; + [songRatingMenuItem setEnabled:YES]; } } else if ([menu indexOfItemWithTitle:@"No Song"] == -1) { [menu removeItemAtIndex:trackInfoIndex]; @@ -434,6 +449,7 @@ Things to do: didHaveAlbumName = (([curAlbumName length] > 0) ? YES : NO); } } + [menu update]; } //Rebuild the upcoming songs submenu. Can be improved a lot. @@ -442,6 +458,7 @@ Things to do: int curIndex = [currentRemote currentPlaylistIndex]; int numSongs = [currentRemote numberOfSongsInPlaylistAtIndex:curIndex]; int numSongsInAdvance = [[NSUserDefaults standardUserDefaults] integerForKey:@"SongsInAdvance"]; + if (!isPlayingRadio) { if (numSongs > 0) { int curTrack = [currentRemote currentSongIndex]; @@ -477,27 +494,26 @@ Things to do: NSArray *playlists = [currentRemote playlists]; int i, curPlaylist = [currentRemote currentPlaylistIndex]; - if (isPlayingRadio) - { + if (isPlayingRadio) { curPlaylist = 0; } - if (playlistMenu && ([playlists count] == [playlistMenu numberOfItems])) return; [playlistMenu release]; playlistMenu = [[NSMenu alloc] initWithTitle:@""]; - for (i = 1; i < [playlists count]; i++) { + for (i = 0; i < [playlists count]; i++) { NSString *playlistName = [playlists objectAtIndex:i]; NSMenuItem *tempItem; tempItem = [[NSMenuItem alloc] initWithTitle:playlistName action:@selector(selectPlaylist:) keyEquivalent:@""]; [tempItem setTarget:self]; - [tempItem setRepresentedObject:[NSNumber numberWithInt:i]]; + [tempItem setRepresentedObject:[NSNumber numberWithInt:i + 1]]; [playlistMenu addItem:tempItem]; [tempItem release]; } [playlistItem setSubmenu:playlistMenu]; + [playlistItem setEnabled:YES]; if (curPlaylist) { [[playlistMenu itemAtIndex:curPlaylist - 1] setState:NSOnState]; @@ -508,6 +524,7 @@ Things to do: - (void)rebuildEQPresetsMenu { NSArray *eqPresets = [currentRemote eqPresets]; + NSMenuItem *enabledItem; int i; if (eqMenu && ([[currentRemote eqPresets] count] == [eqMenu numberOfItems])) @@ -516,18 +533,30 @@ Things to do: [eqMenu release]; eqMenu = [[NSMenu alloc] initWithTitle:@""]; + enabledItem = [eqMenu addItemWithTitle:@"Disabled" + action:@selector(toggleEqualizer) + keyEquivalent:@""]; + + if ([currentRemote equalizerEnabled] == NO) { + [enabledItem setState:NSOnState]; + } + + [eqMenu addItem:[NSMenuItem separatorItem]]; + for (i = 0; i < [eqPresets count]; i++) { NSString *setName = [eqPresets objectAtIndex:i]; NSMenuItem *tempItem; + if (setName) { tempItem = [[NSMenuItem alloc] initWithTitle:setName action:@selector(selectEQPreset:) keyEquivalent:@""]; [tempItem setTarget:self]; [tempItem setRepresentedObject:[NSNumber numberWithInt:i]]; [eqMenu addItem:tempItem]; [tempItem release]; + } } [eqItem setSubmenu:eqMenu]; - [[eqMenu itemAtIndex:[currentRemote currentEQPresetIndex] - 1] setState:NSOnState]; + [[eqMenu itemAtIndex:[currentRemote currentEQPresetIndex] + 1] setState:NSOnState]; } - (void)clearHotKeys @@ -574,163 +603,163 @@ Things to do: } } -//Runs an AppleScript and returns the result as an NSString after stripping quotes, if needed. It takes in script and automatically adds the tell iTunes and end tell statements. -- (NSString *)runScriptAndReturnResult:(NSString *)script -{ - AEDesc scriptDesc, resultDesc; - Size length; - NSString *result; - Ptr buffer; - - script = [NSString stringWithFormat:@"tell application \"iTunes\"\n%@\nend tell", script]; - - AECreateDesc(typeChar, [script cString], [script cStringLength], -&scriptDesc); - - OSADoScript(asComponent, &scriptDesc, kOSANullScript, typeChar, kOSAModeCanInteract, &resultDesc); - - length = AEGetDescDataSize(&resultDesc); - buffer = malloc(length); - - AEGetDescData(&resultDesc, buffer, length); - AEDisposeDesc(&scriptDesc); - AEDisposeDesc(&resultDesc); - result = [NSString stringWithCString:buffer length:length]; - if ( (! [result isEqualToString:@""]) && - ([result characterAtIndex:0] == '\"') && - ([result characterAtIndex:[result length] - 1] == '\"') ) { - result = [result substringWithRange:NSMakeRange(1, [result length] - 2)]; - } - free(buffer); - buffer = nil; - return result; -} - //Called when the timer fires. - (void)timerUpdate { - int trackPlayingIndex = [currentRemote currentSongIndex]; int playlist = [currentRemote currentPlaylistIndex]; + ITMTRemotePlayerState playerState = [currentRemote playerState]; - if (trackPlayingIndex != lastSongIndex) { - bool wasPlayingRadio = isPlayingRadio; - isPlayingRadio = [[currentRemote classOfPlaylistAtIndex:playlist] isEqualToString:@"radio tuner playlist"]; - if (isPlayingRadio && !wasPlayingRadio) { - int i; - for (i = 0; i < [playlistMenu numberOfItems]; i++) - { - [[playlistMenu itemAtIndex:i] setState:NSOffState]; - } - } - if (wasPlayingRadio) { - NSMenuItem *temp = [[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""]; - [menu insertItem:temp atIndex:trackInfoIndex + 1]; - [temp release]; - } - [self updateMenu]; - lastSongIndex = trackPlayingIndex; - } - else - { - if (playlist != [currentRemote currentPlaylistIndex]) { - bool wasPlayingRadio = isPlayingRadio; + if ((playlist > 0) || playerState != ITMTRemotePlayerStopped) { + int trackPlayingIndex = [currentRemote currentSongIndex]; + + if (trackPlayingIndex != lastSongIndex) { + BOOL wasPlayingRadio = isPlayingRadio; isPlayingRadio = [[currentRemote classOfPlaylistAtIndex:playlist] isEqualToString:@"radio tuner playlist"]; + if (isPlayingRadio && !wasPlayingRadio) { int i; for (i = 0; i < [playlistMenu numberOfItems]; i++) { [[playlistMenu itemAtIndex:i] setState:NSOffState]; } + } else { + [[playlistMenu itemAtIndex:playlist - 1] setState:NSOnState]; } + if (wasPlayingRadio) { NSMenuItem *temp = [[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""]; [menu insertItem:temp atIndex:trackInfoIndex + 1]; [temp release]; } + [self updateMenu]; lastSongIndex = trackPlayingIndex; - } - } - //Update Play/Pause menu item - if (playPauseMenuItem){ - if ([currentRemote playerState] == playing) { - [playPauseMenuItem setTitle:@"Pause"]; } else { - [playPauseMenuItem setTitle:@"Play"]; + if (playlist != lastPlaylistIndex) { + BOOL wasPlayingRadio = isPlayingRadio; + isPlayingRadio = [[currentRemote classOfPlaylistAtIndex:playlist] isEqualToString:@"radio tuner playlist"]; + + if (isPlayingRadio && !wasPlayingRadio) { + int i; + for (i = 0; i < [playlistMenu numberOfItems]; i++) { + [[playlistMenu itemAtIndex:i] setState:NSOffState]; + } + } + + if (wasPlayingRadio) { + NSMenuItem *temp = [[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""]; + [menu insertItem:temp atIndex:trackInfoIndex + 1]; + [temp release]; + } + + if (!isPlayingRadio) { + int i; + for (i = 0; i < [playlistMenu numberOfItems]; i++) + { + [[playlistMenu itemAtIndex:i] setState:NSOffState]; + } + [[playlistMenu itemAtIndex:playlist - 1] setState:NSOnState]; + } + + [self updateMenu]; + lastSongIndex = trackPlayingIndex; + lastPlaylistIndex = playlist; + } + } + //Update Play/Pause menu item + if (playPauseMenuItem){ + if (playerState == ITMTRemotePlayerPlaying) { + [playPauseMenuItem setTitle:@"Pause"]; + } else { + [playPauseMenuItem setTitle:@"Play"]; + } } + } else if ((lastPlaylistIndex > 0) && (playlist == 0)) { + NSMenuItem *menuItem; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + //Remote the now playing item and add no song item + [menu removeItemAtIndex:trackInfoIndex]; + + if ([defaults boolForKey:@"showName"] == YES) { + [menu removeItemAtIndex:trackInfoIndex]; + } + + if ([defaults boolForKey:@"showTime"] == YES) { + [menu removeItemAtIndex:trackInfoIndex]; + } + + if (didHaveArtistName && [defaults boolForKey:@"showArtist"]) { + [menu removeItemAtIndex:trackInfoIndex]; + } + + if (didHaveAlbumName && [defaults boolForKey:@"showAlbum"]) { + [menu removeItemAtIndex:trackInfoIndex]; + } + + [playPauseMenuItem setTitle:@"Play"]; + + didHaveArtistName = NO; + didHaveAlbumName = NO; + lastPlaylistIndex = -1; + lastSongIndex = -1; + + [upcomingSongsItem setSubmenu:nil]; + [upcomingSongsItem setEnabled:NO]; + + [songRatingMenuItem setSubmenu:nil]; + [songRatingMenuItem setEnabled:NO]; + + menuItem = [[NSMenuItem alloc] initWithTitle:@"No Song" action:nil keyEquivalent:@""]; + [menu insertItem:menuItem atIndex:trackInfoIndex]; + [menuItem release]; } } -- (void)iTunesLaunched:(NSNotification *)note +- (void)remotePlayerLaunched:(NSNotification *)note { - NSDictionary *info = [note userInfo]; - - iTunesPSN.highLongOfPSN = [[info objectForKey:@"NSApplicationProcessSerialNumberHigh"] longValue]; - iTunesPSN.lowLongOfPSN = [[info objectForKey:@"NSApplicationProcessSerialNumberLow"] longValue]; + isAppRunning = ITMTRemotePlayerRunning; //Restart the timer - refreshTimer = [NSTimer scheduledTimerWithTimeInterval:3.5 target:self selector:@selector(timerUpdate) userInfo:nil repeats:YES]; + [NSThread detachNewThreadSelector:@selector(runTimerInNewThread) toTarget:self withObject:nil]; [self rebuildMenu]; //Rebuild the menu since no songs will be playing + if (playlistItem) { + [self rebuildPlaylistMenu]; + } + if (eqItem) { + [self rebuildEQPresetsMenu]; + } [statusItem setMenu:menu]; //Set the menu back to the main one - [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; - - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(iTunesTerminated:) name:NSWorkspaceDidTerminateApplicationNotification object:nil]; } -- (void)iTunesTerminated:(NSNotification *)note +- (void)runTimerInNewThread { - [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + refreshTimer = [[NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(timerUpdate) userInfo:nil repeats:YES] retain]; + [runLoop run]; + [pool release]; +} + +- (void)remotePlayerTerminated:(NSNotification *)note +{ + isAppRunning = ITMTRemotePlayerNotRunning; [menu release]; menu = [[NSMenu alloc] initWithTitle:@""]; - [[menu addItemWithTitle:@"Open iTunes" action:@selector(openiTunes:) keyEquivalent:@""] setTarget:self]; + [menu addItemWithTitle:@"Audio Player" action:NULL keyEquivalent:@""]; + [menu addItemWithTitle:@"Not Running" action:NULL keyEquivalent:@""]; + [menu addItem:[NSMenuItem separatorItem]]; [[menu addItemWithTitle:@"Preferences" action:@selector(showPreferences:) keyEquivalent:@""] setTarget:self]; [[menu addItemWithTitle:@"Quit" action:@selector(quitMenuTunes:) keyEquivalent:@""] setTarget:self]; [statusItem setMenu:menu]; - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(iTunesLaunched:) name:NSWorkspaceDidLaunchApplicationNotification object:nil]; [refreshTimer invalidate]; + [refreshTimer release]; refreshTimer = nil; [self clearHotKeys]; } -//Return the PSN of iTunes, if it's running -- (ProcessSerialNumber)iTunesPSN -{ - NSArray *apps = [[NSWorkspace sharedWorkspace] launchedApplications]; - ProcessSerialNumber number; - int i; - - number.highLongOfPSN = kNoProcess; - - for (i = 0; i < [apps count]; i++) - { - NSDictionary *curApp = [apps objectAtIndex:i]; - - if ([[curApp objectForKey:@"NSApplicationName"] isEqualToString:@"iTunes"]) - { - number.highLongOfPSN = [[curApp objectForKey:@"NSApplicationProcessSerialNumberHigh"] intValue]; - number.lowLongOfPSN = [[curApp objectForKey:@"NSApplicationProcessSerialNumberLow"] intValue]; - } - } - return number; -} - -//Send an AppleEvent with a given event ID -- (void)sendAEWithEventClass:(AEEventClass)eventClass -andEventID:(AEEventID)eventID -{ - OSType iTunesType = 'hook'; - AppleEvent event, reply; - - AEBuildAppleEvent(eventClass, eventID, typeApplSignature, &iTunesType, sizeof(iTunesType), kAutoGenerateReturnID, kAnyTransactionID, &event, nil, ""); - - AESend(&event, &reply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, nil, nil); - AEDisposeDesc(&event); - AEDisposeDesc(&reply); -} - // // // Selectors - called from status item menu @@ -750,7 +779,9 @@ andEventID:(AEEventID)eventID int playlist = [[sender representedObject] intValue]; if (!isPlayingRadio) { int curPlaylist = [currentRemote currentPlaylistIndex]; - [[playlistMenu itemAtIndex:curPlaylist - 1] setState:NSOffState]; + if (curPlaylist > 0) { + [[playlistMenu itemAtIndex:curPlaylist - 1] setState:NSOffState]; + } } [currentRemote switchToPlaylistAtIndex:playlist]; [[playlistMenu itemAtIndex:playlist - 1] setState:NSOnState]; @@ -762,19 +793,20 @@ andEventID:(AEEventID)eventID int curSet = [currentRemote currentEQPresetIndex]; int item = [[sender representedObject] intValue]; [currentRemote switchToEQAtIndex:item]; - [[eqMenu itemAtIndex:curSet - 1] setState:NSOffState]; - [[eqMenu itemAtIndex:item - 1] setState:NSOnState]; + [[eqMenu itemAtIndex:curSet + 1] setState:NSOffState]; + [[eqMenu itemAtIndex:item + 2] setState:NSOnState]; } - (void)playPause:(id)sender { - PlayerState state = [currentRemote playerState]; - if (state == playing) { + ITMTRemotePlayerState state = [currentRemote playerState]; + + if (state == ITMTRemotePlayerPlaying) { [currentRemote pause]; [playPauseMenuItem setTitle:@"Play"]; - } else if ((state == forwarding) || (state == rewinding)) { - [currentRemote play]; + } else if ((state == ITMTRemotePlayerForwarding) || (state == ITMTRemotePlayerRewinding)) { [currentRemote pause]; + [currentRemote play]; } else { [currentRemote play]; [playPauseMenuItem setTitle:@"Pause"]; @@ -793,12 +825,26 @@ andEventID:(AEEventID)eventID - (void)fastForward:(id)sender { - [currentRemote fastForward]; + [currentRemote forward]; + [playPauseMenuItem setTitle:@"Play"]; } - (void)rewind:(id)sender { [currentRemote rewind]; + [playPauseMenuItem setTitle:@"Play"]; +} + +- (void)toggleEqualizer +{ + [currentRemote setEqualizerEnabled:![currentRemote equalizerEnabled]]; +} + +- (IBAction)setSongRating:(id)sender +{ + NSLog(@"%f", [currentRemote currentSongRating]); + NSLog(@"%f", (float)[sender tag] / 100.0); + [currentRemote setCurrentSongRating:(float)[sender tag] / 100.0]; } // @@ -811,12 +857,6 @@ andEventID:(AEEventID)eventID [NSApp terminate:self]; } -//How is this going to work, now that we're pluginized? -- (void)openiTunes:(id)sender -{ - [[NSWorkspace sharedWorkspace] launchApplication:@"iTunes"]; -} - - (void)showPreferences:(id)sender { if (!prefsController) { @@ -825,10 +865,9 @@ andEventID:(AEEventID)eventID } } - - (void)closePreferences { - if (!((iTunesPSN.highLongOfPSN == kNoProcess) && (iTunesPSN.lowLongOfPSN == 0))) { + if ( ( isAppRunning == ITMTRemotePlayerRunning) ) { [self setupHotKeys]; } [prefsController release]; @@ -844,7 +883,7 @@ andEventID:(AEEventID)eventID - (void)showCurrentTrackInfo { NSString *trackName = [currentRemote currentSongTitle]; - if (!statusController && [trackName length]) { + if (!statusWindow && [trackName length]) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *stringToShow = @""; @@ -867,7 +906,6 @@ andEventID:(AEEventID)eventID if ([defaults boolForKey:@"showTime"]) { NSString *trackTime = [currentRemote currentSongLength]; - NSLog(@"%@", trackTime); if ([trackTime length]) { stringToShow = [NSString stringWithFormat:@"%@Total Time: %@\n", stringToShow, trackTime]; } @@ -885,20 +923,19 @@ andEventID:(AEEventID)eventID } } - statusController = [[StatusWindowController alloc] init]; - [statusController setTrackInfo:stringToShow]; + [statusWindow setText:stringToShow]; [NSTimer scheduledTimerWithTimeInterval:3.0 - target:self - selector:@selector(fadeAndCloseStatusWindow) - userInfo:nil - repeats:NO]; + target:self + selector:@selector(fadeAndCloseStatusWindow) + userInfo:nil + repeats:NO]; } } - (void)showUpcomingSongs { int curPlaylist = [currentRemote currentPlaylistIndex]; - if (!statusController) { + if (!statusWindow) { int numSongs = [currentRemote numberOfSongsInPlaylistAtIndex:curPlaylist]; if (numSongs > 0) { @@ -907,7 +944,7 @@ andEventID:(AEEventID)eventID int i; NSString *songs = @""; - statusController = [[StatusWindowController alloc] init]; + statusWindow = [ITTransientStatusWindow sharedWindow]; for (i = curTrack + 1; i <= curTrack + numSongsInAdvance; i++) { if (i <= numSongs) { NSString *curSong = [currentRemote songTitleAtIndex:i]; @@ -915,7 +952,7 @@ andEventID:(AEEventID)eventID songs = [songs stringByAppendingString:@"\n"]; } } - [statusController setUpcomingSongs:songs]; + [statusWindow setText:songs]; [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(fadeAndCloseStatusWindow) @@ -927,9 +964,7 @@ andEventID:(AEEventID)eventID - (void)fadeAndCloseStatusWindow { - [statusController fadeWindowOut]; - [statusController release]; - statusController = nil; + [statusWindow orderOut:self]; } - (void)setKeyEquivalentForCode:(short)code andModifiers:(long)modifiers @@ -946,10 +981,8 @@ andEventID:(AEEventID)eventID { shiftKey, NSShiftKeyMask }, }; - for (i = 0; i < 6; i++) - { - if (modifiers & carbonToCocoa[i][0]) - { + for (i = 0; i < 6; i++) { + if (modifiers & carbonToCocoa[i][0]) { cocoaModifiers += carbonToCocoa[i][1]; } } @@ -1131,9 +1164,9 @@ andEventID:(AEEventID)eventID { if (refreshTimer) { [refreshTimer invalidate]; + [refreshTimer release]; refreshTimer = nil; } - CloseComponent(asComponent); [currentRemote halt]; [statusItem release]; [menu release]; @@ -1141,4 +1174,4 @@ andEventID:(AEEventID)eventID [super dealloc]; } -@end \ No newline at end of file +@end