|
|
#1 |
|
Prospect
Join Date: Feb 2003
Posts: 31
|
Need Help with a Progress Bar
Hi,
I have an applescript which queries a website to annotate songs in my iTunes library. It works fine (with an occasional error I'm separately trying to track down) but I decided to try xcode for the first time to add a progress bar indicator to let me know how much longer it has to go. I was loosely following a procedure found here. The article is outdated, but it gave me an idea of what to look for. I can get the xcode project to run and annotate the songs, but only if I leave the progress window defunct. As soon as I try to uncomment the code which tries to initialize and update the progress bar, it won't compile. Here's the code - edited for brevity. I'll also paste the app interface below (generated by a script I found). Code:
script Comment_3AppDelegate
property parent : class "NSObject"
property separator : ";"
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
try
activate
set numtracks to 0
set sel to {}
tell application "iTunes"
-- copy (a reference to (get view of front window)) to thePlaylist
set thePlaylist to view of front browser window
if selection is not {} then
set sel to a reference to selection
else -- its the whole playlist
if thePlaylist is not library playlist 1 then
set sel to a reference to every track of thePlaylist
else
display dialog "Select some tracks" buttons {"Cancel"} default button 1 with icon 2 giving up after 15
end if
end if
set appendum to (display dialog "Search to Comment, Version 3
Append search result before or after existing comments?" buttons {"Cancel", "Before", "After"} default button 2 with icon 1 giving up after 60)
end tell
set tracknum to 0
set numtracks to number of items of sel
activate
open window "Comment 3"
--This is the section that will not compile - as you can see I've tried different things. I've commented them out here...
--set maximum value of progress indicator 1 of window "Comment 3" of application process "Comment 3" of application "System Events" to numtracks
--tell progress indicator "Progress Bar" of window "Comment 3"
--set visible to true
-- set uses threaded animation to true
-- set indeterminate to false
-- set maximum value to numtracks
-- start
--end tell
--set indeterminate of progress indicator "Progress Bar" of window "Comment 3" to false
tell application "iTunes"
repeat with this_track in sel
try
set theTitle to this_track's name as text
set theArtist to this_track's artist as text
on error
error "Could not set either track name or artist of track " & tracknum & " as text: [" & name of this_track & ", " & artist of this_track & "]"
end try
set tracknum to tracknum + 1
--set contents of text field "ProgressText" of window "ProgressWindow" to "Processing track " & tracknum & " of " & numtracks & ": " & theTitle & " by " & theArtist
--set content of progress indicator "ProgressBar" of window "ProgressWindow" to tracknum
--update window "ProgressWindow"
set command to "~/Library/iTunes/Scripts/search.pl -n \"" & theTitle & "\" -a \"" & theArtist & "\""
try
set theresult to do shell script command
on error
error "Command failed: [" & command & "]"
end try
try
set theLastCharPos to length of (get this_track's comment)
on error
error "Could not get length of current track's comment"
set theLastCharPos to 0
end try
try
if theLastCharPos is greater than 0 then
if button returned of appendum is "Before" then
set this_track's comment to (theresult & separator & (get this_track's comment))
else
set this_track's comment to ((get this_track's comment) & separator & theresult)
end if
else
set this_track's comment to theresult
end if
on error
error "Could not annotate the current track"
end try
end repeat
end tell
quit
on error theErrorMessage number theErrorNumber
if theErrorNumber = -128 then quit
error theErrorMessage number theErrorNumber
end try
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return current application's NSTerminateNow
end applicationShouldTerminate_
end script
Code:
window "ASCAP to Comment 3" of application process "ASCAP to Comment 3" of application "System Events" button 1 button 2 button 3 progress indicator 1 text field 1 static text "ASCAP to Comment 3" ----- menu bar 1 of application process "ASCAP to Comment 3" of application "System Events" menu bar item "Apple" menu "Apple" ... The errors I get for various lines are along the lines of: Code:
Comment_3AppDelegate.applescript:49: error: A identifier can’t go after this identifier. (-2740) Command /usr/bin/osacompile failed with exit code 1 Code:
set maximum value of progress indicator 1 of window "Comment 3" of application process "Comment 3" of application "System Events" to numtracks Thanks, Rob |
|
|
|
|
|
#2 |
|
All Star
Join Date: Mar 2006
Location: Littleton, Colorado, USA
Posts: 506
|
You are using AppleScript Studio terminology (which was deprecated in Snow Leopard) in an AppleScriptObjC project. One of the main differences when using ASOC is that the various UI objects are referenced by properties and not by the name and hierarchy (that `progress indicator "Progress Bar" of window "Comment 3"` stuff).
Typically you would add some instance properties to your project for the UI objects you want to deal with, and then from the Interface Editor connect the UI objects to their respective properties (properties set to 'missing value' will show up in the Editor): Code:
property myProgressBar : missing value -- connected to the progress bar property myTextField : missing value -- connected to the text field Code:
tell myProgressBar setMaxValue_(numtracks) setUsesThreadedAnimation_(true) setIndeterminate_(false) end tell Code:
myTextField's setStringValue_("Processing track " & tracknum & " of " & numtracks & ": " & theTitle & " by " & theArtist)
tell myProgressBar
incrementBy_(1)
display()
end tell
__________________
MacBook Pro / OS X Mountain Lion (10.8.3) / Xcode 4.6 / [various (much) older stuff keeping dust off the shelves] |
|
|
|
|
|
#3 |
|
Prospect
Join Date: Feb 2003
Posts: 31
|
Progress on progress bar
Wow, thanks Red Menace. Thanks to you, I've made quite a bit of progress on my progress bar.
I created the properties and connected them in the Interface builder. Feeling ambitious during the effort, I also added a stop button (which actually works!). Here's where I'm stuck however... With the code inserted as-is, as you suggested (except I added a "start" command - otherwise the window doesn't show up (alternatively I tried setting the visibility and simply opening the window to the same effect)), what happens is the progress window appears but the script does not progress from there. The progress bar does not fill and the annotations don't get added to my tracks. If I simply comment out the start command, the progress window does not appear and the tracks get annotated.I added dialog windows for debugging. The one right before the progress window setup appears, but the others do not show up unless I comment out the "start" command (which causes the progress window to now appear). I also tried "start_()". Anyone know where to go from here? Here's the new code: Code:
script Comment_3AppDelegate
property parent : class "NSObject"
property separator : ";"
property myProgressBar : missing value
property myProgressText : missing value
on buttonClicked_(sender)
quit
end buttonClicked_
on applicationDidFinishLaunching_(aNotification)
try
activate
set numtracks to 0
set sel to {}
tell application "iTunes"
-- copy (a reference to (get view of front window)) to thePlaylist
set thePlaylist to view of front browser window
if selection is not {} then
set sel to a reference to selection
else -- its the whole playlist
if thePlaylist is not library playlist 1 then
set sel to a reference to every track of thePlaylist
else
display dialog "Select some tracks." buttons {"Cancel"} default button 1 with icon 2 giving up after 15
end if
end if
set appendum to (display dialog "Search to Comment, Version 3
Append search result before or after existing comments?" buttons {"Cancel", "Before", "After"} default button 2 with icon 1 giving up after 60)
set tracknum to 0
set numtracks to number of items of sel
display dialog "About to start progress bar" buttons {"Cancel", "OK"} default button 2 with icon 1 giving up after 60
tell myProgressBar
setMaxValue_(numtracks)
setUsesThreadedAnimation_(true)
setIndeterminate_(false)
start
end tell
display dialog "Progress Bar Started" buttons {"Cancel", "OK"} default button 2 with icon 1 giving up after 60
repeat with this_track in sel
try
set theTitle to this_track's name as text
set theArtist to this_track's artist as text
on error
error "Could not set either track name or artist of track " & tracknum & " as text: [" & name of this_track & ", " & artist of this_track & "]"
end try
set tracknum to tracknum + 1
display dialog "Doing a track" buttons {"Cancel", "OK"} default button 2 with icon 1 giving up after 60
myProgressText's setStringValue_("Processing track " & tracknum & " of " & numtracks & ": " & theTitle & " by " & theArtist)
tell myProgressBar
incrementBy_(1)
display()
end tell
set command to "~/Library/iTunes/Scripts/search.pl -n \"" & theTitle & "\" -a \"" & theArtist & "\""
try
set searchresult to do shell script command
on error
error "Command failed: [" & command & "]"
end try
try
set theLastCharPos to length of (get this_track's comment)
on error
error "Could not get length of current track's comment"
set theLastCharPos to 0
end try
try
if theLastCharPos is greater than 0 then
if button returned of appendum is "Before" then
set this_track's comment to (searchresult & separator & (get this_track's comment))
else
set this_track's comment to ((get this_track's comment) & separator & searchresult)
end if
else
set this_track's comment to searchresult
end if
on error
error "Could not annotate the current track"
end try
end repeat
end tell
quit
on error theErrorMessage number theErrorNumber
if theErrorNumber = -128 then quit
error theErrorMessage number theErrorNumber
end try
end applicationDidFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return current application's NSTerminateNow
end applicationShouldTerminate_
end script
Rob |
|
|
|
|
|
#4 |
|
All Star
Join Date: Mar 2006
Location: Littleton, Colorado, USA
Posts: 506
|
It sounds like you don't have the progress bar set to display if it is stopped (in the Interface Editor's Attributes Inspector), although when you start incrementing it it should appear. A progress indicator doesn't have a start method, so the error is skipping the rest of the code - you can look at the debug console to see if there are any errors (log statements are also placed in the console).
__________________
MacBook Pro / OS X Mountain Lion (10.8.3) / Xcode 4.6 / [various (much) older stuff keeping dust off the shelves] |
|
|
|
|
|
#5 |
|
Prospect
Join Date: Feb 2003
Posts: 31
|
Finally got around to playing with this again. The progress bar is set to display as far as I can tell (clicked on the progress bar in Interface Builder and hidden is unchecked). Even though the progress window is set to be "Visible at Launch", it does not appear unless I set the visible to true in the applescript code (or simply open the window via applescript). Oddly, the tracks get annotated unless the window is visible... I looked into console and this is all I get:
Code:
1/7/13 2:22:58.759 PM ASCAP to Comment 3: *** -[Comment_3AppDelegate applicationDidFinishLaunching:]: iTunes got an error: Unknown object type. (error -1731) Code:
1/7/13 2:29:52.225 PM com.apple.backupd: Waiting for index to be ready (101) 1/7/13 2:30:52.580 PM com.apple.backupd: Waiting for index to be ready (101) 1/7/13 2:31:52.853 PM com.apple.backupd: Waiting for index to be ready (100) Perhaps this little project is simply more than I can chew... I'm going to see if I can find any current tutorials on making progress bars for applescripts. Rob |
|
|
|
|
|
#6 |
|
All Star
Join Date: Mar 2006
Location: Littleton, Colorado, USA
Posts: 506
|
One of the big differences when using AppleScript in Xcode is that you need to watch out about blocking the user interface. If your application immediately starts doing stuff and doesn't let the system handle events, for example staying in a repeat loop, the UI will not do what you want it to.
If I make a minimal script that just steps through the iTunes selection, nothing will happen unless I give the system some time to do its thing. The following example works for me - try commenting out the fetchEvents() hander calls to see what I am talking about: Code:
script AppDelegate
##################################################
# MARK: -
# MARK: Script Properties
#
property parent : class "NSObject"
##################################################
# MARK: -
# MARK: Interface Editor Outlets
#
property myWindow : missing value -- connected to the window
property myTextField : missing value -- connected to the text field
property myProgressBar : missing value -- connected to the progress bar
##################################################
# MARK: -
# MARK: Interface Editor Actions
#
on buttonClicked_(sender)
log "quitting..."
tell me to quit
end buttonClicked_
##################################################
# MARK: -
# MARK: Delegate Handlers
#
on applicationDidFinishLaunching_(aNotification)
tell myProgressBar
setUsesThreadedAnimation_(true)
setIndeterminate_(false)
end tell
delay 4 -- give window time to show up
doStuff()
end applicationDidFinishLaunching_
on applicationShouldTerminate_(sender)
return current application's NSTerminateNow
end applicationShouldTerminate_
##################################################
# MARK: -
# MARK: Script Handlers
#
on doStuff() -- step through iTunes selection
tell application "iTunes" to set sel to selection
set numtracks to (count sel)
log (numtracks as text) & " items selected"
tell myProgressBar to setMaxValue_(numtracks)
tell application "iTunes" to repeat with this_track from 1 to numtracks
my fetchEvents()
set theTitle to name of (item this_track of sel)
set theArtist to artist of (item this_track of sel)
set theText to ("Processing track " & this_track & " of " & numtracks & ": " & theTitle & " by " & theArtist)
tell me to log theText
tell myTextField
setStringValue_(theText)
-- display()
end tell
tell myProgressBar
incrementBy_(1)
-- display()
end tell
delay 1 -- slow down a bit so you can see the progress
my fetchEvents()
end repeat
tell me to quit
end doStuff
on fetchEvents() -- handle user events to keep the queue from filling up (Shane Stanley)
repeat -- forever
tell current application's NSApp to set theEvent to nextEventMatchingMask_untilDate_inMode_dequeue_(current application's NSAnyEventMask, missing value, current application's NSEventTrackingRunLoopMode, true)
if theEvent is missing value then -- none left
exit repeat
else
tell current application's NSApp to sendEvent_(theEvent) -- pass it on
end if
end repeat
return
end fetchEvents
end script
__________________
MacBook Pro / OS X Mountain Lion (10.8.3) / Xcode 4.6 / [various (much) older stuff keeping dust off the shelves] |
|
|
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|