You are not logged in.
One very common use for AppleScript is batch processing. Scripts of this nature will often loop through multiple items, performing some type of automated task for each item being processed. An example of this might be a script that loops through a folder of image files, converting each one to another format.
A script of this nature that is created with Script Editor, and then run, may work just fine. However, visually, it is less than spectacular. Other than a spinning cursor, and perhaps a dialog message displayed here or there during script execution, the user does not usually receive a very good visual representation of what is occurring.
This is where AppleScript Studio can come in handy. In this month's column, we will discuss adding progress bars and spinners to an AppleScript, in order to provide a visual representation of what is being processed, how much processing is complete, and how much processing remains during script execution.
Preparing to Follow Along
To follow along with this month's column, you will need to create a new AppleScript Studio project. Launch Xcode, and select New Project from the File menu. Next, choose the AppleScript Application template, provided by Apple. Name the project Progress Example, and save it into the desired location. Double click on MainMenu.nib to begin editing the project's interface.
Begin by dragging a text field, progress spinner, and progress bar to the main window of the interface from the Cocoa Objects Palette window. Arrange the objects as shown in the example window in figure 1. Next, select the window, and enable the awake from nib event handler in the AppleScript pane of the Inspector window. Link the event handler to the main Progress Example.applescript file in your project. See figure 1.
Applescript:
start progress indicator "spinner" of window 1
To stop a progress spinner, use the stop command. For example:
Applescript:
stop progress indicator "spinner" of window 1
Working with Progress Bars
A progress bar can be a very user friendly way of providing progress during script execution. A progress bar can be used to display incremental progress, or, like a progress spinner, indeterminate progress.
Like progress spinners, progress bars may be started and stopped. For example:
Applescript:
start progress indicator "bar" of window 1
A progress bar is indeterminate by default, but may be changed to be incremental via your project's AppleScript code, or from the Attributes pane of the Inspector palette in Interface Builder. To set a progress bar to be incremental, rather than indeterminate, from your project's code, change the boolean value of the progress indicator's indeterminate property. For example:
Applescript:
set indeterminate of progress indicator "bar" of window 1 to false
Incremental progress bars are used to display the current progress of a process. Because of this, they have a maximum value and a current value. These values may be adjusted as needed through out your code. When starting a progress bar, you will probably want to set the maximum value of the progress bar to the desired amount. This is done by setting the maximum value property of the progress indicator. For example:
Applescript:
set maximum value of progress indicator "bar" of window 1 to 10
To increment the progress bar, you will change its current value as needed, to reflect actual progress as it occurs. To do this, set the value of the content property of the progress indicator to the current progress increment. For example:
Applescript:
set content of progress indicator "bar" of window 1 to 5
Displaying Progress in Text Fields
Text fields can also be used as an effective way to display progress. By updating the content of the text field at various times during processing, you can provide a user with important information about what is occurring as the script executes.
Pulling things Together
Now we're going to pull together some the techniques that we have discussed to show different ways that progress can be indicated.
Displaying Progress Using a Progress Spinner and a Text Field
Applescript:
on awake from nib theObject
set theFolder to choose folder with prompt "Please select a folder of items to process:"
set theFolderItems to list folder theFolder without invisibles
start progress indicator "spinner" of window 1
repeat with a from 1 to length of theFolderItems
set content of text field 1 of window 1 to "Processing item " & a & " of " & (length of theFolderItems) & "..." & return & (item a of theFolderItems) as string
-- This code delays long enough to show you the results
set delayUntil to (current date) + 1
repeat until (current date) is greater than or equal to delayUntil
end repeat
end repeat
stop progress indicator "spinner" of window 1
display dialog "Done!"
quit
end awake from nib
The code above begins by prompting the user to select a folder to process. After a folder has been selected, a list of items in the folder is retrieved. Next, the progress spinner in the interface is started. The script then proceeds to loop through the items detected in the folder. The text field in the interface is updated for each item in the loop. The loop also includes some code to delay long enough to allow you to see the interface update during each iteration. Once all items in the folder have been processed, the progress spinner is stopped, and a dialog is displayed to indicate that processing is complete. The following examples will all perform in a similar fashion.
Displaying Progress Using an Indeterminate Progress Bar and a Text Field
Applescript:
on awake from nib theObject
set theFolder to choose folder with prompt "Please select a folder of items to process:"
set theFolderItems to list folder theFolder without invisibles
start progress indicator "bar" of window 1
repeat with a from 1 to length of theFolderItems
set content of text field 1 of window 1 to "Processing item " & a & " of " & (length of theFolderItems) & "..." & return & (item a of theFolderItems) as string
-- This code delays long enough to show you the results
set delayUntil to (current date) + 1
repeat until (current date) is greater than or equal to delayUntil
end repeat
end repeat
stop progress indicator "bar" of window 1
display dialog "Done!"
quit
end awake from nib
Displaying Progress Using an Incremental Progress Bar and a Text Field
Applescript:
on awake from nib theObject
set theFolder to choose folder with prompt "Please select a folder of items to process:"
set theFolderItems to list folder theFolder without invisibles
set maximum value of progress indicator "bar" of window 1 to (length of theFolderItems)
set content of progress indicator "bar" of window 1 to 0
set indeterminate of progress indicator "bar" of window 1 to false
start progress indicator "bar" of window 1
repeat with a from 1 to length of theFolderItems
set content of text field 1 of window 1 to "Processing item " & a & " of " & (length of theFolderItems) & "..." & return & (item a of theFolderItems) as string
-- This code delays long enough to show you the results
set delayUntil to (current date) + 1
repeat until (current date) is greater than or equal to delayUntil
end repeat
set content of progress indicator "bar" of window 1 to a
end repeat
stop progress indicator "bar" of window 1
display dialog "Done!"
quit
end awake from nib
Displaying Progress Using a Progress Spinner, an Incremental Progress Bar, and a Text Field
Applescript:
on awake from nib theObject
set theFolder to choose folder with prompt "Please select a folder of items to process:"
set theFolderItems to list folder theFolder without invisibles
start progress indicator "spinner" of window 1
set maximum value of progress indicator "bar" of window 1 to (length of theFolderItems)
set content of progress indicator "bar" of window 1 to 0
set indeterminate of progress indicator "bar" of window 1 to false
start progress indicator "bar" of window 1
repeat with a from 1 to length of theFolderItems
set content of text field 1 of window 1 to "Processing item " & a & " of " & (length of theFolderItems) & "..." & return & (item a of theFolderItems) as string
-- This code delays long enough to show you the results
set delayUntil to (current date) + 1
repeat until (current date) is greater than or equal to delayUntil
end repeat
set content of progress indicator "bar" of window 1 to a
end repeat
stop progress indicator "bar" of window 1
stop progress indicator "spinner" of window 1
display dialog "Done!"
quit
end awake from nib
In Conclusion
If you had trouble following along with the previous examples, you can download the example Xcode project used in the examples from here.
Until next time, just script it!
-Ben Waldie
Ben Waldie, Automated Workflows, LLC
AppleScript & Automator Tips & Articles - http://www.automatedworkflows.com/tips/tips.html
Mac Automation Made Simple Video Podcast Series - http://www.automatedworkflows.com/tips/podcast.html
Automator for Mac OS X Visual QuickStart Guide - http://www.automatedworkflows.com/books/books.html
Offline