fork of iTunes Remote Control with bugfixes and enhancements
at master 772 lines 32 kB view raw
1(* 2Copyright (c) 2006 James Huston 3All rights reserved. 4 5Redistribution and use in source and binary forms, with or without 6modification, are permitted provided that the following conditions 7are met: 81. Redistributions of source code must retain the above copyright 9 notice, this list of conditions and the following disclaimer. 102. Redistributions in binary form must reproduce the above copyright 11 notice, this list of conditions and the following disclaimer in the 12 documentation and/or other materials provided with the distribution. 133. The name of the author may not be used to endorse or promote products 14 derived from this software without specific prior written permission. 15 16THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26*) 27 28property indexList : {} 29property nameList : {} 30property joinedList : {} 31property tempList : {} 32property selSongRow : null 33property doWeRebuildPlaylist : true 34property fullMachineURI : "" 35property continueRefresh : false 36 37on action theObject 38 if name of theObject is "sl-volume" then 39 set newVolume to float value of theObject 40 using terms from application "iTunes" 41 tell application "iTunes" of machine fullMachineURI to set sound volume to newVolume 42 end using terms from 43 else if name of theObject is "tf-search" then 44 if contents of text field "tf-search" of window "win-main" is not "" then 45 my searchiTunes(contents of text field "tf-search" of window "win-main") 46 end if 47 end if 48end action 49 50on clicked theObject 51 try 52 if name of theObject is "but-prev" then 53 my skipTrack("prev") 54 else if name of theObject is "but-next" then 55 my skipTrack("next") 56 else if name of theObject is "but-prevalbum" then 57 my skipAlbum("prev") 58 else if name of theObject is "but-nextalbum" then 59 my skipAlbum("next") 60 else if name of theObject is "but-mute" then 61 my muteiTunes() 62 else if name of theObject is "but-shuffle" then 63 my shufflePlaylist() 64 set doWeRebuildPlaylist to true 65 if state of drawer "drawer-playlist" of window "win-main" is drawer opened then 66 my makePlaylist() 67 end if 68 else if name of theObject is "but-reload" then 69 my makePlaylist() 70 else if name of theObject is "but-eq" then 71 my setEQState(state of theObject) 72 else if name of theObject is "but-play" then 73 if title of theObject is "I>" then 74 my playTrack(true) 75 else if title of theObject is "II" then 76 my playTrack(false) 77 end if 78 end if 79 on error the error_message number the error_number 80 if error_number is equal to -600 then 81 my launchiTunes() 82 else 83 my showAlert(error_number, error_message, localized string "OKAY_BUTTON" from table "Localized", "", "", "win-main", true) 84 end if 85 end try 86end clicked 87 88on choose menu item theObject 89 try 90 if name of theObject is "menu-playlists" then 91 set userPlaylist to name of current menu item of theObject 92 my switchPlaylist(userPlaylist) 93 set tool tip of theObject to "Current Playlist: " & userPlaylist 94 set doWeRebuildPlaylist to true 95 if state of drawer "drawer-playlist" of window "win-main" is drawer opened then 96 my makePlaylist() 97 end if 98 else if name of theObject is "menu-eq" then 99 set userEQ to name of current menu item of theObject 100 my switchEQ(userEQ) 101 set tool tip of theObject to "Current EQ: " & userEQ 102 else if name of theObject is "menu-refresh" then 103 my makePlaylistMenu() 104 my makeEQMenu() 105 my setState() 106 if state of drawer "drawer-playlist" of window "win-main" is drawer opened then 107 my makePlaylist() 108 end if 109 set continueRefresh to true 110 else if name of theObject is "menu-quit" then 111 set continueRefresh to false 112 set title of window "win-main" to "iTunes Remote Control" 113 using terms from application "iTunes" 114 tell application "iTunes" of machine fullMachineURI to quit 115 end using terms from 116 end if 117 on error the error_message number the error_number 118 if error_number is equal to -600 then 119 my launchiTunes() 120 else 121 my showAlert(error_number, error_message, localized string "OKAY_BUTTON" from table "Localized", "", "", "win-main", true) 122 end if 123 end try 124end choose menu item 125 126on activated theObject 127 try 128 if continueRefresh is true then 129 my setState() 130 end if 131 on error the error_message number the error_number 132 my showAlert(error_number, error_message, localized string "OKAY_BUTTON" from table "Localized", "", "", "win-main", true) 133 end try 134end activated 135 136on idle theObject 137 try 138 if continueRefresh is true then 139 my setState() 140 if (contents of default entry "UpdateMoreOften" of user defaults as boolean) is false then 141 return 5 142 else if (contents of default entry "UpdateMoreOften" of user defaults as boolean) is true then 143 return 2 144 end if 145 end if 146 on error the error_message number the error_number 147 if error_number is equal to -600 then 148 my launchiTunes() 149 else 150 my showAlert(error_number, error_message, localized string "OKAY_BUTTON" from table "Localized", "", "", "win-main", true) 151 end if 152 end try 153end idle 154 155on double clicked theObject 156 try 157 set songID to contents of data cell "track_id" of data row selSongRow of data source of table view "tv-playlist" of scroll view "sv-playlist" of drawer "drawer-playlist" of window "win-main" as integer 158 using terms from application "iTunes" 159 tell application "iTunes" of machine fullMachineURI to play track songID of view of first browser window 160 end using terms from 161 if continueRefresh is true then 162 my setState() 163 end if 164 on error the error_message number the error_number 165 if error_number is equal to -600 then 166 my launchiTunes() 167 else 168 my showAlert(error_number, error_message, localized string "OKAY_BUTTON" from table "Localized", "", "", "win-main", true) 169 end if 170 end try 171end double clicked 172 173on launched theObject 174 try 175 if fullMachineURI is not "eppc://" then 176 my makePlaylistMenu() 177 my makeEQMenu() 178 my setState() 179 set continueRefresh to true 180 end if 181 on error the error_message number the error_number 182 if error_number is equal to -600 then 183 my launchiTunes() 184 else if error_number is not equal to -128 then 185 my showAlert(error_number, error_message, localized string "OKAY_BUTTON" from table "Localized", "", "", "win-main", true) 186 end if 187 end try 188end launched 189 190on selection changed theObject 191 set selSongRow to selected row of theObject 192end selection changed 193 194on awake from nib theObject 195 set playlistTable to data source of table view "tv-playlist" of scroll view "sv-playlist" of drawer "drawer-playlist" of window "win-main" 196 tell playlistTable 197 make new data column at the end of the data columns with properties {name:"track_id", sort type:numerical, sort case sensitivity:case insensitive} 198 make new data column at the end of the data columns with properties {name:"track_artist", sort type:alphabetical, sort case sensitivity:case insensitive} 199 make new data column at the end of the data columns with properties {name:"track_title", sort type:alphabetical, sort case sensitivity:case insensitive} 200 end tell 201 set sorted of playlistTable to true 202 set sort column of playlistTable to data column "track_id" of playlistTable 203 set data source of theObject to playlistTable 204end awake from nib 205 206on opened theObject 207 try 208 if doWeRebuildPlaylist is true then 209 my makePlaylist() 210 set doWeRebuildPlaylist to false 211 end if 212 on error the error_message number the error_number 213 my showAlert(error_number, error_message, localized string "OKAY_BUTTON" from table "Localized", "", "", "win-main", true) 214 end try 215end opened 216 217on end editing theObject 218 try 219 if name of theObject is "tf-machineURI" then 220 set machineURI to contents of text field "tf-machineuri" of window "win-prefs" 221 set fullMachineURI to "eppc://" & machineURI 222 set contents of default entry "MachineURI" of user defaults to machineURI 223 if fullMachineURI is not "eppc://" then 224 set continueRefresh to true 225 end if 226 my makePlaylistMenu() 227 my makeEQMenu() 228 my setState() 229 if state of drawer "drawer-playlist" of window "win-main" is drawer opened then 230 my makePlaylist() 231 end if 232 end if 233 on error the error_message number the error_number 234 my showAlert(error_number, error_message, localized string "OKAY_BUTTON" from table "Localized", "", "", "win-main", true) 235 end try 236end end editing 237 238on will finish launching theObject 239 make new default entry at end of default entries of user defaults with properties {name:"MachineURI", contents:""} 240 make new default entry at end of default entries of user defaults with properties {name:"refreshRate", contents:"50"} 241 make new default entry at end of default entries of user defaults with properties {name:"SUCheckAtStartup", contents:false} 242 make new default entry at end of default entries of user defaults with properties {name:"QuitiTunes", contents:false} 243 make new default entry at end of default entries of user defaults with properties {name:"ShowProgress", contents:true} 244 make new default entry at end of default entries of user defaults with properties {name:"UpdateMoreOften", contents:false} 245 make new default entry at end of default entries of user defaults with properties {name:"MainWindowPosition", contents:""} 246 make new default entry at end of default entries of user defaults with properties {name:"IncreasePlayCount", contents:false} 247 try 248 set bounds of window "win-main" to contents of default entry "MainWindowPosition" of user defaults as list 249 end try 250 set visible of progress indicator "pi-dur" of window "win-main" to (contents of default entry "ShowProgress" of user defaults) 251 set state of button "but-update" of window "win-prefs" to (contents of default entry "UpdateMoreOften" of user defaults) 252 set state of button "but-checkupdates" of window "win-prefs" to (contents of default entry "SUCheckAtStartup" of user defaults) 253 set state of button "but-showprogress" of window "win-prefs" to (contents of default entry "ShowProgress" of user defaults) 254 set state of button "but-quit" of window "win-prefs" to (contents of default entry "QuitiTunes" of user defaults) 255 set state of button "but-addplay" of window "win-prefs" to (contents of default entry "IncreasePlayCount" of user defaults) 256 set machineURI to contents of default entry "MachineURI" of user defaults 257 set refreshRate to contents of default entry "refreshRate" of user defaults 258 if machineURI is "" then 259 display dialog "Enter the address of the computer iTunes is on:" default answer "" buttons {"OK"} default button 1 260 set machineURI to text returned of the result 261 set contents of default entry "MachineURI" of user defaults to machineURI 262 end if 263 set contents of text field "tf-machineuri" of window "win-prefs" to machineURI 264 set fullMachineURI to "eppc://" & machineURI 265 set title of popup button "menu-refreshrate" of window "win-prefs" to refreshRate 266 my registerGrowl() 267 set background color of window "win-main" to {59135, 59135, 59135} 268 tell window "win-main" to update 269 set visible of window "win-main" to true 270end will finish launching 271 272on will quit theObject 273 set contents of default entry "MainWindowPosition" of user defaults to bounds of window "win-main" as list 274 if contents of default entry "QuitiTunes" of user defaults as boolean is true then 275 using terms from application "iTunes" 276 tell application "iTunes" of machine fullMachineURI to quit 277 end using terms from 278 end if 279end will quit 280 281(* START TRACK CONTROL FUNCTIONS *) 282 283on playTrack(playingState) -- playingState true=playing false=paused/stopped 284 using terms from application "iTunes" 285 tell application "iTunes" of machine fullMachineURI to playpause 286 end using terms from 287 if playingState is true then 288 set title of button "but-play" of window "win-main" to "II" 289 set title of menu item "mi-play" of popup button "menu-dock" of window "win-hiden" to "Pause" 290 my setState() 291 else if playingState is false then 292 set title of button "but-play" of window "win-main" to "I>" 293 set title of menu item "mi-play" of popup button "menu-dock" of window "win-hiden" to "Play" 294 end if 295end playTrack 296 297on stopTrack() 298 using terms from application "iTunes" 299 tell application "iTunes" of machine fullMachineURI to stop 300 end using terms from 301 set title of button "but-play" of window "win-main" to "I>" 302end stopTrack 303 304on skipTrack(direction) -- direction next=skip forward prev=skip backward 305 set addPlay to contents of default entry "IncreasePlayCount" of user defaults as boolean 306 using terms from application "iTunes" 307 if direction is "next" then 308 tell application "iTunes" of machine fullMachineURI 309 if addPlay is true then 310 try 311 set played count of current track to ((played count of current track) + 1) 312 set played date of current track to current date 313 end try 314 end if 315 next track 316 end tell 317 else if direction is "prev" then 318 tell application "iTunes" of machine fullMachineURI to back track 319 end if 320 end using terms from 321 my setState() 322 set contents of progress indicator "pi-dur" of window "win-main" to 0 323end skipTrack 324 325(* END TRACK CONTROL FUNCTIONS *) 326 327(* BEGIN ALBUM CONTROL FUNCTIONS *) 328 329on skipAlbum(direction) -- direction next=skip forward prev=skip backward 330 using terms from application "iTunes" 331 tell application "iTunes" of machine fullMachineURI 332 set currentAlbum to the album of the current track 333 if player state is playing then 334 set wasPlaying to true 335 pause 336 else 337 set wasPlaying to false 338 end if 339 340 repeat while the album of the current track is equal to currentAlbum 341 if direction is "next" then 342 next track 343 else if direction is "prev" then 344 back track 345 end if 346 end repeat 347 348 -- for skipping back an album, we're now at the last track of this previous album, 349 -- so go back again, then forward one 350 if direction is "prev" then 351 set currentAlbum to the album of the current track 352 repeat while the album of the current track is equal to currentAlbum 353 back track 354 end repeat 355 next track 356 end if 357 358 if wasPlaying is true then 359 play 360 end if 361 end tell 362 end using terms from 363 my setState() 364 set contents of progress indicator "pi-dur" of window "win-main" to 0 365end skipAlbum 366 367(* END ALBUM CONTROL FUNCTIONS *) 368 369(* BEGIN ITUNES CONTROL FUNCTIONS *) 370 371on muteiTunes() 372 using terms from application "iTunes" 373 tell application "iTunes" of machine fullMachineURI to set mute to not (mute) 374 end using terms from 375end muteiTunes 376 377on setEQState(eqState) --eqState=boolen value for on/off 378 using terms from application "iTunes" 379 tell application "iTunes" of machine fullMachineURI to set EQ enabled to eqState 380 end using terms from 381end setEQState 382 383on shufflePlaylist() 384 using terms from application "iTunes" 385 tell application "iTunes" of machine fullMachineURI 386 set shuffle of view of first browser window to not shuffle of view of first browser window 387 set shufState to shuffle of view of first browser window 388 end tell 389 end using terms from 390 set state of menu item "mi-shuffle" of popup button "menu-dock" of window "win-hiden" to shufState 391end shufflePlaylist 392 393on switchPlaylist(userPlaylist) -- userPlaylist=name of selected playlist 394 using terms from application "iTunes" 395 tell application "iTunes" of machine fullMachineURI 396 try 397 set view of first browser window to playlist userPlaylist 398 on error 399 set myCDs to every source whose kind is audio CD 400 repeat with i from 1 to count of myCDs 401 if name of audio CD playlist 1 of item i of myCDs = userPlaylist then 402 set view of first browser window to audio CD playlist 1 of item i of myCDs 403 exit repeat 404 end if 405 end repeat 406 end try 407 set shuffleState to shuffle of view of first browser window 408 end tell 409 end using terms from 410 my stopTrack() 411 my playTrack(true) 412 set state of button "but-shuffle" of window "win-main" to shuffleState 413end switchPlaylist 414 415on switchEQ(userEQ) -- userEQ=name of selected EQ 416 using terms from application "iTunes" 417 tell application "iTunes" of machine fullMachineURI to set current EQ preset to EQ preset userEQ 418 end using terms from 419end switchEQ 420 421(* END ITUNES CONTROL FUNCTIONS *) 422 423(* BEGIN ITRC STATE FUNCTIONS *) 424 425on setState() 426 set iTunesInfo to my getiTunesInfo() 427 if currentState of iTunesInfo is "playing" then 428 set title of button "but-play" of window "win-main" to "II" 429 set title of menu item "mi-play" of popup button "menu-dock" of window "win-hiden" to "Pause" 430 my trackInfo(iTunesInfo) 431 else if currentState of iTunesInfo is "paused" then 432 set title of button "but-play" of window "win-main" to "I>" 433 set title of menu item "mi-play" of popup button "menu-dock" of window "win-hiden" to "Play" 434 else if currentState of iTunesInfo is "stopped" then 435 set title of button "but-play" of window "win-main" to "I>" 436 set title of menu item "mi-play" of popup button "menu-dock" of window "win-hiden" to "Play" 437 set title of window "win-main" to "iTunes Remote Control" 438 end if 439 set contents of progress indicator "pi-dur" of window "win-main" to currentSongPosition of iTunesInfo 440 set title of popup button "menu-playlists" of window "win-main" to currentPlaylist of iTunesInfo 441 set title of popup button "menu-eq" of window "win-main" to currentEQ of iTunesInfo 442 set title of popup button "menu-rate" of window "win-main" to currentSongStar of iTunesInfo 443 set state of button "but-eq" of window "win-main" to eqState of iTunesInfo 444 set state of button "but-mute" of window "win-main" to muteState of iTunesInfo 445 set contents of slider "sl-volume" of window "win-main" to currentVolume of iTunesInfo 446 set tool tip of popup button "menu-playlists" of window "win-main" to "Current Playlist: " & currentPlaylist of iTunesInfo 447 set tool tip of popup button "menu-eq" of window "win-main" to "Current EQ: " & currentEQ of iTunesInfo 448 set ratingStars to "" 449 repeat with i from 1 to currentSongStar of iTunesInfo 450 set ratingStars to ratingStars & (localized string "STAR" from table "Localized") 451 end repeat 452 set tool tip of popup button "menu-rate" of window "win-main" to "Current Rating: " & ratingStars 453 set state of button "but-shuffle" of window "win-main" to shuffleState of iTunesInfo 454 set state of every menu item of popup button "menu-dock" of window "win-hiden" to 0 455 set state of menu item "mi-shuffle" of popup button "menu-dock" of window "win-hiden" to shuffleState of iTunesInfo 456 set state of menu item "menu-mutecomp" of menu "menu-itunes" of main menu to computerMuted of iTunesInfo 457 try 458 my setCurSong(songID of iTunesInfo) 459 end try 460end setState 461 462on getiTunesInfo() 463 set theList to {} 464 set currentState to "stopped" 465 set currentSongStar to "0" 466 set currentSongRate to 0 467 set songID to 1 468 set currentSongPosition to "0" 469 set artistName to "" 470 set trackName to "" 471 set albumName to "" 472 set trackDur to 0 473 474 using terms from application "iTunes" 475 tell application "iTunes" of machine fullMachineURI 476 if player state is playing then 477 set currentState to "playing" 478 set currentSongRate to rating of current track 479 set songID to get index of current track 480 set currentSongPosition to player position 481 set artistName to artist of current track 482 set trackName to name of current track 483 set albumName to album of current track 484 set trackDur to duration of current track 485 else if player state is paused then 486 set currentState to "paused" 487 set currentSongRate to rating of current track 488 set songID to get index of current track 489 set currentSongPosition to player position 490 set artistName to artist of current track 491 set trackName to name of current track 492 set albumName to album of current track 493 set trackDur to duration of current track 494 end if 495 496 set currentPlaylist to name of view of first browser window 497 set shuffleState to shuffle of view of first browser window 498 set muteState to mute 499 set currentVolume to sound volume 500 set currentEQ to name of current EQ preset 501 set eqState to EQ enabled 502 set computerMuted to 0 503 504 -- this fails when the computer is using digital audio output and has no volume control 505 try 506 set computerMuted to output muted of (get volume settings) as integer 507 end try 508 end tell 509 end using terms from 510 511 if currentSongRate is 20 then 512 set currentSongStar to "1" 513 else if currentSongRate is 40 then 514 set currentSongStar to "2" 515 else if currentSongRate is 60 then 516 set currentSongStar to "3" 517 else if currentSongRate is 80 then 518 set currentSongStar to "4" 519 else if currentSongRate is 100 then 520 set currentSongStar to "5" 521 else 522 set currentSongStar to "0" 523 end if 524 525 set theList to {currentState:currentState, currentPlaylist:currentPlaylist, shuffleState:shuffleState, currentSongPosition:currentSongPosition, currentSongStar:currentSongStar, muteState:muteState, currentVolume:currentVolume, currentEQ:currentEQ, songID:songID, eqState:eqState, computerMuted:computerMuted, artistName:artistName, trackName:trackName, albumName:albumName, trackDur:trackDur} 526 return theList 527end getiTunesInfo 528 529on trackInfo(cachedTrackInfo) 530 set oldTrackID to contents of text field "tf-title" of window "win-main" & contents of text field "tf-artist" of window "win-main" & contents of text field "tf-album" of window "win-main" 531 set newTrackID to trackName of cachedTrackInfo & artistName of cachedTrackInfo & albumName of cachedTrackInfo 532 set maximum value of progress indicator "pi-dur" of window "win-main" to trackDur of cachedTrackInfo 533 set contents of text field "tf-artist" of window "win-main" to artistName of cachedTrackInfo 534 set contents of text field "tf-title" of window "win-main" to trackName of cachedTrackInfo 535 set contents of text field "tf-album" of window "win-main" to albumName of cachedTrackInfo 536 try 537 set title of window "win-main" to artistName of cachedTrackInfo & " - " & trackName of cachedTrackInfo 538 on error 539 set title of window "win-main" to "Unknown" 540 end try 541 set tool tip of text field "tf-artist" of window "win-main" to artistName of cachedTrackInfo 542 set tool tip of text field "tf-title" of window "win-main" to trackName of cachedTrackInfo 543 set tool tip of text field "tf-album" of window "win-main" to albumName of cachedTrackInfo 544 set enabled of menu item "mi-artist" of popup button "menu-dock" of window "win-hiden" to false 545 set title of menu item "mi-artist" of popup button "menu-dock" of window "win-hiden" to artistName of cachedTrackInfo & " - " & trackName of cachedTrackInfo 546 if newTrackID is not oldTrackID then 547 my trackChangeGrowl(artistName of cachedTrackInfo, trackName of cachedTrackInfo, albumName of cachedTrackInfo, currentSongStar of cachedTrackInfo) 548 end if 549end trackInfo 550 551on makeEQMenu() 552 using terms from application "iTunes" 553 tell application "iTunes" of machine fullMachineURI to set eqList to name of every EQ preset 554 end using terms from 555 tell window "win-main" 556 delete every menu item of menu of popup button "menu-eq" 557 repeat with i from 1 to (count of eqList) 558 set eqName to item i of eqList 559 make new menu item at the end of menu items of menu of popup button "menu-eq" with properties {title:eqName, name:eqName, enabled:true} 560 end repeat 561 end tell 562 set eqList to {} 563end makeEQMenu 564 565on makePlaylistMenu() 566 using terms from application "iTunes" 567 tell application "iTunes" of machine fullMachineURI 568 set userPlaylists to name of every playlist 569 if "iTRC Search Results" is not in userPlaylists then 570 make new user playlist with properties {name:"iTRC Search Results"} 571 copy "iTRC Search Results" to end of userPlaylists 572 end if 573 set myCDs to every source whose kind is audio CD 574 repeat with i from 1 to count of myCDs 575 copy name of item i of myCDs to end of userPlaylists 576 end repeat 577 end tell 578 end using terms from 579 set userPlaylists to my sortList(userPlaylists) 580 tell window "win-main" 581 delete every menu item of menu of popup button "menu-playlists" 582 repeat with i from 1 to (count of userPlaylists) 583 set playlistName to item i of userPlaylists 584 make new menu item at the end of menu items of menu of popup button "menu-playlists" with properties {title:playlistName, name:playlistName, enabled:true} 585 end repeat 586 end tell 587 set userPlaylists to {} 588end makePlaylistMenu 589 590on makePlaylist() 591 try 592 set refreshRate to contents of default entry "refreshRate" of user defaults as string 593 set tempList to {} 594 set indexList to {} 595 using terms from application "iTunes" 596 tell application "iTunes" of machine fullMachineURI 597 try 598 set indexList to index of every track of view of first browser window 599 set artistList to artist of every track of view of first browser window 600 set nameList to name of every track of view of first browser window 601 end try 602 end tell 603 end using terms from 604 set totalTracks to count of indexList 605 delete every data row of data source of table view "tv-playlist" of scroll view "sv-playlist" of drawer "drawer-playlist" of window "win-main" 606 607 if totalTracks > 0 then 608 set playlistCounter to 0 609 set continueRefresh to false 610 set visible of progress indicator "pi-playlist" of window "win-main" to true 611 set visible of progress indicator "pi-dur" of window "win-main" to false 612 set maximum value of progress indicator "pi-playlist" of window "win-main" to totalTracks 613 614 repeat with i from 1 to totalTracks 615 set playlistCounter to playlistCounter + 1 616 set contents of progress indicator "pi-playlist" of window "win-main" to i 617 set tempList to {track_id:item i of indexList, track_artist:item i of artistList, track_title:item i of nameList} 618 copy tempList to end of joinedList 619 if playlistCounter as integer = refreshRate as integer then 620 append data source of table view "tv-playlist" of scroll view "sv-playlist" of drawer "drawer-playlist" of window "win-main" with joinedList 621 set joinedList to {} 622 set playlistCounter to 0 623 end if 624 set testValue to "" 625 set numlist to {} 626 set tempList to {} 627 end repeat 628 append data source of table view "tv-playlist" of scroll view "sv-playlist" of drawer "drawer-playlist" of window "win-main" with joinedList 629 630 if contents of default entry "ShowProgress" of user defaults as boolean is true then 631 set visible of progress indicator "pi-dur" of window "win-main" to true 632 end if 633 634 set visible of progress indicator "pi-playlist" of window "win-main" to false 635 set continueRefresh to true 636 my setState() 637 set joinedList to {} 638 set doWeRebuildPlaylist to false 639 end if 640 on error the error_message number the error_number 641 end try 642end makePlaylist 643 644on setCurSong(songID) -- songID=numeric ID of the song in the current playlist 645 try 646 set selected row of table view "tv-playlist" of scroll view "sv-playlist" of drawer "drawer-playlist" of window "win-main" to songID 647 end try 648end setCurSong 649 650(* END ITRC STATE FUNCTIONS *) 651 652(* BEGIN GROWL FUNCTIONS *) 653 654on checkForGrowl() 655 tell application "System Events" to set isGrowlRunning to count of (application processes whose (name is equal to "GrowlHelperApp")) 656 return isGrowlRunning 657end checkForGrowl 658 659on registerGrowl() 660 try 661 if my checkForGrowl() is not 0 then 662 set appName to "iTunes Remote Control" 663 set notificationName to {"Track Changed"} 664 using terms from application "GrowlHelperApp" 665 tell application "GrowlHelperApp" to register as application appName all notifications notificationName default notifications notificationName icon of application "iTunes" 666 end using terms from 667 end if 668 end try 669end registerGrowl 670 671on trackChangeGrowl(artistName, trackName, albumName, trackStars) 672 try 673 if my checkForGrowl() is not 0 then 674 if trackStars is "0" then 675 set starsLabel to "" 676 else 677 set starsLabel to " 678" 679 repeat with i from 1 to trackStars 680 set starsLabel to starsLabel & "★" 681 end repeat 682 end if 683 684 using terms from application "GrowlHelperApp" 685 tell application "GrowlHelperApp" to notify with name "Track Changed" title trackName application name "iTunes Remote Control" identifier "iTRC" description artistName & " 686" & albumName & starsLabel 687 end using terms from 688 end if 689 end try 690end trackChangeGrowl 691 692(* END GROWL FUNCTIONS *) 693 694(* BEGIN SEARCH FUNCTIONS *) 695 696on searchiTunes(searchTerm) 697 set continuedRefresh to false 698 if contents of default entry "ShowProgress" of user defaults as boolean is true then 699 set visible of progress indicator "pi-dur" of window "win-main" to false 700 end if 701 set visible of progress indicator "pi-playlist" of window "win-main" to true 702 set indeterminate of progress indicator "pi-playlist" of window "win-main" to true 703 set uses threaded animation of progress indicator "pi-playlist" of window "win-main" to true 704 tell progress indicator "pi-playlist" of window "win-main" to start 705 using terms from application "iTunes" 706 tell application "iTunes" of machine fullMachineURI 707 set DestPlaylist to user playlist "iTRC Search Results" 708 delete every track of DestPlaylist 709 duplicate (every track of library playlist 1 whose album contains searchTerm or artist contains searchTerm or name contains searchTerm) to DestPlaylist 710 end tell 711 end using terms from 712 set continuedRefresh to true 713 tell progress indicator "pi-playlist" of window "win-main" to stop 714 set indeterminate of progress indicator "pi-playlist" of window "win-main" to false 715 my switchPlaylist("iTRC Search Results") 716 set state of drawer "drawer-playlist" of window "win-main" to drawer opening 717 set state of button "but-playlist" of window "win-main" to 1 718 if state of drawer "drawer-playlist" of window "win-main" is drawer opened then 719 my makePlaylist() 720 else if contents of default entry "ShowProgress" of user defaults as boolean is true then 721 set visible of progress indicator "pi-playlist" of window "win-main" to false 722 set visible of progress indicator "pi-dur" of window "win-main" to true 723 set doWeRebuildPlaylist to true 724 end if 725end searchiTunes 726 727(* END SEARCH FUNCTIONS *) 728 729on launchiTunes() 730 set openiTunes to my showAlert(localized string "ITUNES_OPEN" from table "Localized", localized string "ITUNES_OPEN_TEXT" from table "Localized", localized string "OPEN_BUTTON" from table "Localized", localized string "CANCEL_BUTTON" from table "Localized", "", "win-main", false) 731 if openiTunes = 1 then 732 tell application "Finder" of machine fullMachineURI to open "/Applications/iTunes.app" as POSIX file 733 my makePlaylistMenu() 734 my makeEQMenu() 735 my setState() 736 set continueRefresh to true 737 end if 738 set userPlaylists to {} 739end launchiTunes 740 741on showAlert(dialogText, dialogMessage, defaultButtonTitle, alternateButtonTitle, otherButtonTitle, inWindow, asSheet) 742 set continueRefresh to false 743 set userPlaylists to {} 744 if asSheet is true then 745 display alert dialogText as informational message dialogMessage default button defaultButtonTitle alternate button alternateButtonTitle other button otherButtonTitle attached to window inWindow 746 else if asSheet is false then 747 set theReply to display alert dialogText as informational message dialogMessage default button defaultButtonTitle alternate button alternateButtonTitle other button otherButtonTitle 748 if (button returned of theReply) is defaultButtonTitle then 749 return 1 750 else if (button returned of theReply) is alternateButtonTitle then 751 return 2 752 else if (button returned of theReply) is otherButtonTitle then 753 return 3 754 end if 755 end if 756end showAlert 757 758on createHash(songInfo) 759 set shellScript to "/bin/echo " & quoted form of songInfo & " | /usr/bin/openssl md5" 760 set idHash to do shell script shellScript 761 return idHash 762end createHash 763 764on sortList(my_list) 765 set old_delims to AppleScript's text item delimiters 766 set AppleScript's text item delimiters to {ASCII character 10} -- always a linefeed 767 set list_string to (my_list as string) 768 set new_string to do shell script "echo " & quoted form of list_string & " | sort -f" 769 set new_list to (paragraphs of new_string) 770 set AppleScript's text item delimiters to old_delims 771 return new_list 772end sortList