X-Git-Url: http://git.ithinksw.org/MenuTunes.git/blobdiff_plain/c3ade301266db044b41f7e21df374fead6ff4d46..796f8360ac05b39085aef9f202f635a04ba6834e:/iTunesRemote.m diff --git a/iTunesRemote.m b/iTunesRemote.m index 5978135..5bab47e 100755 --- a/iTunesRemote.m +++ b/iTunesRemote.m @@ -14,7 +14,7 @@ - (NSString *)information; { - return @"Default MenuTunes plugin to control iTunes."; + return @"Default MenuTunes plugin to control iTunes. Written by iThink Software."; } - (NSImage *)icon @@ -26,9 +26,13 @@ { iTunesPSN = [self iTunesPSN]; + //We won't need this once we're pure AEs + asComponent = OpenDefaultComponent(kOSAComponentType, kAppleScriptSubtype); + //Register for application termination in NSWorkspace + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(applicationLaunched:) name:NSWorkspaceDidLaunchApplicationNotification object:nil]; + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(applicationTerminated:) name:NSWorkspaceDidTerminateApplicationNotification object:nil]; - NSLog(@"iTunes Plugin loaded"); return YES; } @@ -36,26 +40,75 @@ { iTunesPSN.highLongOfPSN = kNoProcess; + //We won't need this once we're pure AEs + CloseComponent(asComponent); + //Unregister for application termination in NSWorkspace + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; + return YES; } +- (BOOL)isAppRunning +{ + NSArray *apps = [[NSWorkspace sharedWorkspace] launchedApplications]; + int i; + + for (i = 0; i < [apps count]; i++) { + if ([[[apps objectAtIndex:i] objectForKey:@"NSApplicationName"] + isEqualToString:@"iTunes"]) { + return YES; + } + } + return NO; +} + +- (PlayerState)playerState +{ + NSString *result = [self runScriptAndReturnResult:@"get player state"]; + + if ([result isEqualToString:@"playing"]) { + return playing; + } else if ([result isEqualToString:@"paused"]) { + return paused; + } else if ([result isEqualToString:@"stopped"]) { + return stopped; + } else if ([result isEqualToString:@"rewinding"]) { + return rewinding; + } else if ([result isEqualToString:@"fast forwarding"]) { + return forwarding; + } + + return stopped; +} + +- (NSArray *)playlists +{ + int i; + int numPresets = [[self runScriptAndReturnResult:@"get number of playlists"] intValue]; + NSMutableArray *presets = [[NSMutableArray alloc] init]; + for (i = 1; i <= numPresets; i++) { + [presets addObject:[self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of playlist %i", i]]]; + } + + return [NSArray arrayWithArray:presets]; +} + - (int)numberOfSongsInPlaylistAtIndex:(int)index { - return [[ITAppleEventCenter sharedCenter] - sendAEWithSendStringForNumber:@"cPla" - eventClass:@"core" eventID:@"cnte" - appPSN:[self iTunesPSN]]; + NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get number of tracks in playlist %i", index]]; + return [result intValue]; } - (NSString *)classOfPlaylistAtIndex:(int)index { //Not working yet. It returns the 4 character code instead of a name. - NSString *result; + /*NSString *result; result = [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pcls" fromObjectByKey:@"pPla" eventClass:@"core" eventID:@"getd" - appPSN:[self iTunesPSN]]; + appPSN:[self iTunesPSN]];*/ + NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get class of playlist %i", index]]; return result; } @@ -71,7 +124,8 @@ - (NSString *)songTitleAtIndex:(int)index { - return nil; + NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of track %i of current playlist", index]]; + return result; } - (int)currentSongIndex @@ -114,7 +168,7 @@ - (NSString *)currentSongLength { - return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pDur" + return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pTim" fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd" appPSN:[self iTunesPSN]]; } @@ -135,7 +189,25 @@ - (NSArray *)eqPresets; { - return nil; + int i; + int numPresets = [[self runScriptAndReturnResult:@"get number of EQ presets"] intValue]; + NSMutableArray *presets = [[NSMutableArray alloc] init]; + + for (i = 1; i <= numPresets; i++) { + [presets addObject:[self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of EQ preset %i", i]]]; + } + + return [NSArray arrayWithArray:presets]; +} + +- (int)currentEQPresetIndex +{ + int result; + result = [[ITAppleEventCenter sharedCenter] + sendTwoTierAEWithRequestedKeyForNumber:@"pidx" + fromObjectByKey:@"pEQP" eventClass:@"core" eventID:@"getd" + appPSN:[self iTunesPSN]]; + return result; } - (BOOL)play @@ -154,9 +226,8 @@ - (BOOL)goToNextSong { - [self numberOfSongsInPlaylistAtIndex:1]; - //[[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Next" - // appPSN:[self iTunesPSN]]; + [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Next" + appPSN:[self iTunesPSN]]; return YES; } @@ -167,18 +238,40 @@ return YES; } +- (BOOL)fastForward +{ + [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Fast" + appPSN:[self iTunesPSN]]; + return YES; +} + +- (BOOL)rewind +{ + [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Rwnd" + appPSN:[self iTunesPSN]]; + return YES; +} + + - (BOOL)switchToPlaylistAtIndex:(int)index { + [self runScriptAndReturnResult:[NSString stringWithFormat: + @"play playlist %i", index]]; return NO; } - (BOOL)switchToSongAtIndex:(int)index { + [self runScriptAndReturnResult:[NSString stringWithFormat: + @"play track %i of current playlist", index]]; return NO; } - (BOOL)switchToEQAtIndex:(int)index { + [self runScriptAndReturnResult:[NSString stringWithFormat: + @"set current EQ preset to EQ preset %i", index]]; + [self runScriptAndReturnResult:@"set EQ enabled to 1"]; return NO; } @@ -203,4 +296,58 @@ return number; } +- (void)applicationLaunched:(NSNotification *)note +{ + NSDictionary *info = [note userInfo]; + + if ([[info objectForKey:@"NSApplicationName"] isEqualToString:@"iTunes"]) { + iTunesPSN.highLongOfPSN = [[info objectForKey:@"NSApplicationProcessSerialNumberHigh"] longValue]; + iTunesPSN.lowLongOfPSN = [[info objectForKey:@"NSApplicationProcessSerialNumberLow"] longValue]; + + [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTRemoteAppDidLaunchNotification" object:nil]; + } +} + +- (void)applicationTerminated:(NSNotification *)note +{ + NSDictionary *info = [note userInfo]; + + if ([[info objectForKey:@"NSApplicationName"] isEqualToString:@"iTunes"]) { + iTunesPSN.highLongOfPSN = kNoProcess; + [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTRemoteAppDidTerminateNotification" object:nil]; + } +} + +//This is just temporary +- (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; +} + @end