X-Git-Url: http://git.ithinksw.org/MenuTunes.git/blobdiff_plain/9cebb1f7452afe422cb940e970c9f30b5180a239..a876619d0c610eaee6aa5e1a105106f265b2c084:/iTunesRemote.m?ds=inline diff --git a/iTunesRemote.m b/iTunesRemote.m index b6b539c..5fb5233 100755 --- a/iTunesRemote.m +++ b/iTunesRemote.m @@ -26,12 +26,14 @@ { ITDebugLog(@"iTunesRemote begun"); savedPSN = [self iTunesPSN]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationHandler:) name:@"com.apple.iTunes.playerInfo" object:@"com.apple.iTunes.player"]; return YES; } - (BOOL)halt { ITDebugLog(@"iTunesRemote halted"); + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self]; return YES; } @@ -73,13 +75,13 @@ ([ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pvis'), from:obj { form:'indx', want:type('cBrW'), seld:1, from:'null'() } }", 'core', 'getd', &savedPSN) booleanValue] != 0) && [[[[NSWorkspace sharedWorkspace] activeApplication] objectForKey:@"NSApplicationName"] isEqualToString:@"iTunes"] ) { //set minimized of browser window 1 to true - ITSendAEWithString(@"data:long(1), '----':obj { form:'prop', want:type('prop'), seld:type('pMin'), from:obj { form:'indx', want:type('cBrW'), seld:1, from:'null'() } }", 'core', 'setd', &savedPSN); + ITSendAEWithString(@"data:long(1), '----':obj { form:'prop', want:type('prop'), seld:type('pMin'), from:obj { form:'indx', want:type('cBrW'), seld:long(1), from:'null'() } }", 'core', 'setd', &savedPSN); } else { //set minimized of browser window 1 to false - ITSendAEWithString(@"data:long(0), '----':obj { form:'prop', want:type('prop'), seld:type('pMin'), from:obj { form:'indx', want:type('cBrW'), seld:1, from:'null'() } }", 'core', 'setd', &savedPSN); + ITSendAEWithString(@"data:long(0), '----':obj { form:'prop', want:type('prop'), seld:type('pMin'), from:obj { form:'indx', want:type('cBrW'), seld:long(1), from:'null'() } }", 'core', 'setd', &savedPSN); } //set visible of browser window 1 to true - ITSendAEWithString(@"data:long(1), '----':obj { form:'prop', want:type('prop'), seld:type('pvis'), from:obj { form:'indx', want:type('cBrW'), seld:1, from:'null'() } }", 'core', 'setd', &savedPSN); + ITSendAEWithString(@"data:long(1), '----':obj { form:'prop', want:type('prop'), seld:type('pvis'), from:obj { form:'indx', want:type('cBrW'), seld:long(1), from:'null'() } }", 'core', 'setd', &savedPSN); //active iTunes ITSendAEWithString(@"data:long(1), '----':obj { form:'prop', want:type('prop'), seld:type('pisf'), from:'null'() }", 'core', 'setd', &savedPSN); ITDebugLog(@"Done showing player primary interface."); @@ -120,7 +122,7 @@ SInt32 result; ITDebugLog(@"Getting player playing state"); - result = [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pPlS'), from:'null'() }", 'core', 'getd', &savedPSN) int32Value]; + result = [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pPlS'), from:'null'() }", 'core', 'getd', &savedPSN) typeCodeValue]; switch (result) { case 'kPSP': @@ -168,6 +170,7 @@ ITDebugLog(@"Getting playlists."); if (numSources == 0) { + [allSources release]; ITDebugLog(@"No sources."); return nil; } @@ -262,9 +265,19 @@ - (int)numberOfSongsInPlaylistAtIndex:(int)index { + /* + This method only returns the proper number if there's something playing. + This is because it gets the container of the current playlist so that it + gets the playlist index from the current source. Operating this way is fine, + since MT only ever calls this method when there is something playlist. + A working version of this that works in just the main source is in the + makePlaylistWithTerm:ofType: method. + */ int temp1; + NSAppleEventDescriptor *result; ITDebugLog(@"Getting number of songs in playlist at index %i", index); - temp1 = [ITSendAEWithString([NSString stringWithFormat:@"kocl:type('cTrk'), '----':obj { form:'indx', want:type('cPly'), seld:long(%lu), from:obj { form:'prop', want:type('prop'), seld:type('ctnr'), from:obj { form:'prop', want:type('prop'), seld:type('pPla'), from:'null'() } } }",index], 'core', 'getd', &savedPSN) int32Value]; + result = ITSendAEWithString([NSString stringWithFormat:@"kocl:type('cTrk'), '----':obj { form:'indx', want:type('cPly'), seld:long(%lu), from:obj { form:'prop', want:type('prop'), seld:type('ctnr'), from:obj { form:'prop', want:type('prop'), seld:type('pPla'), from:'null'() } } }", index], 'core', 'cnte', &savedPSN); + temp1 = (result == nil) ? -1 : (int)[result int32Value]; ITDebugLog(@"Getting number of songs in playlist at index %i done", index); return temp1; } @@ -275,7 +288,7 @@ ITDebugLog(@"Getting current source."); - fourcc = [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pKnd'), from:obj { form:'prop', want:type('prop'), seld:type('ctnr'), from:obj { form:'prop', want:type('prop'), seld:type('pPla'), from:'null'() } } }", 'core', 'getd', &savedPSN) int32Value]; + fourcc = ([self isPlaying]) ? [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pKnd'), from:obj { form:'prop', want:type('prop'), seld:type('ctnr'), from:obj { form:'prop', want:type('prop'), seld:type('pPla'), from:'null'() } } }", 'core', 'getd', &savedPSN) int32Value] : 'kLib'; switch (fourcc) { case 'kTun': @@ -338,7 +351,7 @@ { int temp1; ITDebugLog(@"Getting current playlist index."); - temp1 = [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pidx'), from:obj { form:'prop', want:type('prop'), seld:type('pPla'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value]; + temp1 = ([self isPlaying] ? [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pidx'), from:obj { form:'prop', want:type('prop'), seld:type('pPla'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value] : -1); ITDebugLog(@"Getting current playlist index done."); return temp1; } @@ -377,7 +390,9 @@ NSString *temp1; ITDebugLog(@"Getting current unique identifier."); NSAppleEventDescriptor *descriptor = ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pcls'), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } }", 'core', 'getd', &savedPSN); - if (descriptor == nil) { + if ([descriptor int32Value] == 'prop') { + return @"0-0"; + } else if (descriptor == nil) { return nil; } SInt32 cls = [descriptor int32Value]; @@ -398,7 +413,7 @@ { int temp1; ITDebugLog(@"Getting current song index."); - temp1 = [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pidx'), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value]; + temp1 = ([self isPlaying] ? [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pidx'), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value] : -1); ITDebugLog(@"Getting current song index done."); return temp1; } @@ -407,16 +422,19 @@ { NSString *temp1; ITDebugLog(@"Getting current song title."); - + SInt32 result = [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pcls'), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value]; + //If we're listening to the radio. - if ([ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pcls'), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value] == 'cURT') { + if (result == 'cURT') { NSString *bad = [NSString stringWithUTF8String:"浳湧"]; temp1 = [ITSendAEWithKey('pStT', 'core', 'getd', &savedPSN) stringValue]; if ([temp1 isEqualToString:bad]) { temp1 = [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pnam'), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } }", 'core', 'getd', &savedPSN) stringValue]; } temp1 = [temp1 stringByAppendingString:@" (Stream)"]; - } else { + } else if (result == 'prop') { + temp1 = nil; + } else { temp1 = [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pnam'), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } }", 'core', 'getd', &savedPSN) stringValue]; } ITDebugLog(@"Getting current song title done."); @@ -517,7 +535,7 @@ - (NSImage *)currentSongAlbumArt { ITDebugLog(@"Getting current song album art."); - NSData *data = [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pPCT'), from:obj { form:'indx', want:type('cArt'), seld:long(1), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } } }", 'core', 'getd', &savedPSN) data]; + NSData *data = ([self isPlaying]) ? [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pPCT'), from:obj { form:'indx', want:type('cArt'), seld:long(1), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } } }", 'core', 'getd', &savedPSN) data] : nil; ITDebugLog(@"Getting current song album art done."); if (data) { return [[[NSImage alloc] initWithData:data] autorelease]; @@ -539,8 +557,7 @@ { float temp1; ITDebugLog(@"Getting current song rating."); - temp1 = ((float)[ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pRte'), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value] / 100.0); - if ( [self currentPlaylistClass] == ITMTRemotePlayerRadioPlaylist ) { temp1 = -1.0; } + temp1 = (![self isPlaying] || ([self currentPlaylistClass] == ITMTRemotePlayerRadioPlaylist)) ? -1.0 : ((float)[ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pRte'), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value] / 100.0); ITDebugLog(@"Getting current song rating done."); return temp1; } @@ -614,15 +631,9 @@ - (BOOL)shuffleEnabled { ITDebugLog(@"Getting shuffle enabled status."); - BOOL final; - int result = (int)[ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pShf'), from:obj { form:'prop', want:type('pPla'), seld:type('pEQP'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value]; - if (result != 0) { - final = YES; - } else { - final = NO; - } + int result = (int)[ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pShf'), from:obj { form:'prop', want:type('prop'), seld:type('pPla'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value]; ITDebugLog(@"Getting shuffle enabled status done."); - return final; + return (result != 0); } - (BOOL)setShuffleEnabled:(BOOL)enabled @@ -637,7 +648,7 @@ { FourCharCode m00f = 0; int result = 0; - m00f = (FourCharCode)[ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pRpt'), from:obj { form:'prop', want:type('pPla'), seld:type('pEQP'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value]; + m00f = (FourCharCode)[ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pRpt'), from:obj { form:'prop', want:type('prop'), seld:type('pPla'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value]; ITDebugLog(@"Getting repeat mode."); switch (m00f) { @@ -708,7 +719,7 @@ - (BOOL)goToPreviousSong { ITDebugLog(@"Go to previous track"); - ITSendAE('hook', 'Prev', &savedPSN); + ITSendAE('hook', 'Back', &savedPSN); ITDebugLog(@"Go to previous track done"); return YES; } @@ -766,7 +777,7 @@ - (BOOL)makePlaylistWithTerm:(NSString *)term ofType:(int)type { int i; - + //Get fixed indexing status BOOL fixed = [ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pFix'), from:'null'() }", 'core', 'getd', &savedPSN) booleanValue]; @@ -779,7 +790,7 @@ //If MenuTunes playlist exists if ([ITSendAEWithString(@"'----':obj { form:'name', want:type('cPly'), seld:\"MenuTunes\", from:'null'() }", 'core', 'doex', &savedPSN) booleanValue]) { //Clear old MenuTunes playlist - int numSongs = [ITSendAEWithString(@"kocl:type('cTrk'), '----':obj { form:'name', want:type('cPly'), seld:\"MenuTunes\", from:obj { form:'prop', want:type('prop'), seld:type('ctnr'), from:obj { form:'prop', want:type('prop'), seld:type('pPla'), from:'null'() } } }", 'core', 'cnte', &savedPSN) int32Value]; + int numSongs = [ITSendAEWithString(@"kocl:type('cTrk'), '----':obj { form:'name', want:type('cPly'), seld:\"MenuTunes\", from:'null'() }", 'core', 'cnte', &savedPSN) int32Value]; for (i = 1; i <= numSongs; i++) { ITSendAEWithString(@"'----':obj { form:'indx', want:type('cTrk'), seld:long(1), from:obj { form:'name', want:type('cPly'), seld:\"MenuTunes\", from:'null'() } }", 'core', 'delo', &savedPSN); } @@ -790,6 +801,7 @@ //Duplicate search results to playlist for (i = 1; i <= [searchResults numberOfItems]; i++) { + //NSLog(@"%@", ITSendAEWithStringAndParameter(@"'----':obj { form:'prop', want:type('prop'), seld:prop('pnam'), from:aevt(@) }", *[[searchResults descriptorAtIndex:i] aeDesc], 'core', 'getd', &savedPSN)); ITSendAEWithStringAndObject(@"insh:obj { form:'name', want:type('cPly'), seld:\"MenuTunes\", from:'null'() }", [[searchResults descriptorAtIndex:i] aeDesc], 'core', 'clon', &savedPSN); } //Reset fixed indexing @@ -801,6 +813,18 @@ return YES; } +- (BOOL)isPlaying +{ + return ([ITSendAEWithString(@"'----':obj { form:'prop', want:type('prop'), seld:type('pcls'), from:obj { form:'prop', want:type('prop'), seld:type('pTrk'), from:'null'() } }", 'core', 'getd', &savedPSN) int32Value] != 'prop'); +} + +- (void)notificationHandler:(NSNotification *)note +{ + ITDebugLog(@"Received notification: %@", note); + [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTTrackChanged" object:self userInfo:[note userInfo]]; + ITDebugLog(@"Handled notification."); +} + - (ProcessSerialNumber)iTunesPSN { /*NSArray *apps = [[NSWorkspace sharedWorkspace] launchedApplications];