PDA

View Full Version : Simple progress bar example




SouthernAtHeart
Feb 3, 2012, 07:30 PM
I am dabbling in AppleScript and would like to try adding a progress bar to my script so I downloaded Xcode 4. I found a couple examples That seem real easy to follow, but they must be an old version of Xcode because i can't get anywhere in my Xcode 4. Here's one tutorial that seems real easy to follow:
http://macscripter.net/viewtopic.php?id=24760

Is there something like this for the new Xcode? Or should I download an older version of Xcode
Thanks



Red Menace
Feb 3, 2012, 07:55 PM
If all you are familiar with is AppleScript Studio (or just regular AppleScript), there isn't a whole lot out there that demonstrates the new AppleScript Objective-C framework - mostly it is a matter of converting from the existing Objective-C documentation.

There is an example project in Shane Stanley's AppleScriptObjC Explored (http://www.macosxautomation.com/applescript/apps/index.html) ebook, which is pretty much the handbook for ASObjC. Lion's AppleScript Editor has the ability to create applications using ASObj-C, so if you are just wanting to put a progress indicator into a regular AppleScript, there are also some Cocoa-AppleScript examples (http://macosxautomation.com/lion/applescript.html).

SouthernAtHeart
Feb 3, 2012, 08:49 PM
If all you are familiar with is AppleScript Studio (or just regular AppleScript), there isn't a whole lot out there that demonstrates the new AppleScript Objective-C framework - mostly it is a matter of converting from the existing Objective-C documentation.

There is an example project in Shane Stanley's AppleScriptObjC Explored (http://www.macosxautomation.com/applescript/apps/index.html) ebook, which is pretty much the handbook for ASObjC. Lion's AppleScript Editor has the ability to create applications using ASObj-C, so if you are just wanting to put a progress indicator into a regular AppleScript, there are also some Cocoa-AppleScript examples (http://macosxautomation.com/lion/applescript.html).
I'm looking at these links you mentioned. I think it's a bit over my head though. I have scripts that do things like organize contacts and other things with contacts in the address book, and sometimes it takes it awhile (30 seconds)so I thought a progress bar would let the user know my script didn't crash on them, but it looks loke it's pretty complex to just add a progress bar. Its too bad, because that example of a progressbar in the old Xcode looked sumer enough to follow.
Thanks for the input

Red Menace
Feb 3, 2012, 09:14 PM
The Cocoa-AppleScript template isn't too complicated (I have a version that uses a controller script similar to the old BP Progress bar), although you need to be able to break the task up into enough pieces to make the progress bar meaningful. Maybe you could just put up an indeterminate progress indicator (a spinner or barber pole).

SouthernAtHeart
Feb 3, 2012, 09:17 PM
The Cocoa-AppleScript template isn't too complicated (I have a version that uses a controller script similar to the old BP Progress bar), although you need to be able to break the task up into enough pieces to make the progress bar meaningful. Maybe you could just put up an indeterminate progress indicator (a spinner or barber pole).

...that would be great. Can you do that will plain old AppleScript? I'll do some research...

SouthernAtHeart
Feb 3, 2012, 09:38 PM
Here's one of my scripts that can take long enough that a user might think its not doing anything.

Is there just a few lines to add that would show some kind of barberpole? I searched for AppleScript barberpole but didn't come up with any examples.


set BadList to {"(", ")", " "}
set Changes to "Person--Phone--OldNo--NewNo" & return
tell application "Address Book"
repeat with Acontact in people in the group named theirGroup
repeat with APhone in phones of Acontact
set newtarget to ""
set Target to value of APhone
repeat with achar in characters of Target
if achar is not in BadList then set newtarget to newtarget & achar
if achar is in {" "} then
if (count of newtarget) < 12 then set newtarget to newtarget & "-"
end if
end repeat
if not (Target = newtarget) then
set theChange to (name of Acontact) & " -- " & (label of APhone)
set theChange to theChange & " -- " & Target & " -- " & newtarget
set Changes to Changes & theChange & return
set value of APhone to newtarget
save
end if
end repeat
end repeat

end tell
Changes

Red Menace
Feb 3, 2012, 09:53 PM
You wouldn't need to break anything up to use the barberpole. Your script repeats through the people in a group though, so you could count the total, and increment the progress indicator each time through the loop.

My template is set up right now to process files, but it can be changed easily enough. The Changes/log variable would need to be put in a dialog or something, since the Cocoa-AppleScript can only be run as an application. Is that the compete script? I'm noticing that the theirGroup variable is not set.

SouthernAtHeart
Feb 3, 2012, 10:39 PM
You wouldn't need to break anything up to use the barberpole. Your script repeats through the people in a group though, so you could count the total, and increment the progress indicator each time through the loop.

My template is set up right now to process files, but it can be changed easily enough. The Changes/log variable would need to be put in a dialog or something, since the Cocoa-AppleScript can only be run as an application. Is that the compete script? I'm noticing that the theirGroup variable is not set.

...sorry I copied this out of a series of steps, so theirgroup was set at the beginning. But basically each step is like this, running through the contacts making a change like this. You mentioned you template? Did you post an example you made, I'm not seeing it I guess...
I tried looking at the example script folder under help in the Appllescript editor, but didn't see anything there that helped.
If you have an example similar to what I'm trying to do, I'd like to see it.
Thanks,

Red Menace
Feb 3, 2012, 11:45 PM
I didn't post the template, it is an application bundle that I have on my AppleScriptObjectiveC home page - the direct link is here (http://www.users.qwest.net/~red_menace/Files/AppleScript/Cocoa%20AppleScript/Progress%20Window%20Template.zip).

As I mentioned earlier, the template is set up as an example using a progress bar for some files (it doesn't actually do anything with them, though), so the main script would need to be reworked to use the Address Book script. If the script works as posted, you should be able to replace the main script in the template with yours, adding the commands to the progress bar (see the ProgressBarController.scpt in the application bundle). It is getting late here, but I will post a modified script later.

SouthernAtHeart
Feb 3, 2012, 11:55 PM
I didn't post the template, it is an application bundle that I have on my AppleScriptObjectiveC home page - the direct link is here (http://www.users.qwest.net/~red_menace/Files/AppleScript/Cocoa%20AppleScript/Progress%20Window%20Template.zip).

As I mentioned earlier, the template is set up as an example using a progress bar for some files (it doesn't actually do anything with them, though), so the main script would need to be reworked to use the Address Book script. If the script works as posted, you should be able to replace the main script in the template with yours, adding the commands to the progress bar (see the ProgressBarController.scpt in the application bundle). It is getting late here, but I will post a modified script later.

Thanks. I bought that book you mentioned, will give it a reading over the next few days. It may be over my head.
I've made custom forms with VBA in MS Access. I see in Xcode 4 there are button, text boxes, even a progress bar. It would be great if I could made little AppleScript utilities and turn them into professional looking apps with this stuff. I'm hoping this book is for beginners.
Getting late here, too

Red Menace
Feb 4, 2012, 10:31 AM
Give this a try. Using my progress bar template, make a new application and replace the main script with:

property myProgressController : missing value -- the controller script instance

on run
set myProgressController to current application's ProgressBarController's alloc's init() -- create instance
try
doStuff()
on error errmess number errnum
display alert "error number " & errnum message errmess
end try
tell me to quit
end run

on doStuff()
set theirGroup to "test" -- fill in the blank
set badList to {"(", ")", " "} -- a list of characters to clean
set changes to {"Person -- Phone -- Old# -- New#"} -- this will be a list of changes

tell application "Address Book"
set theContacts to (people in group theirGroup)

set theCount to (count theContacts) -- get a maximum count for the progress bar
tell myProgressController -- set up and show the progress bar
createProgressWindow()
setBarberPole_(false)
setupProgressWithTopText_bottomText_maxValue_("Fixing phone numbers...", "", theCount)
delay 1
end tell

repeat with this from 1 to theCount
set aContact to item this of theContacts

set theName to name of aContact
tell myProgressController -- increment the progress bar
updateProgressByAmount_topText_bottomText_(1, "Processing item " & this & " of " & theCount, theName)
doEventFetch() -- keep event queue cleared
-- delay 0.25
end tell

repeat with aPhone in phones of aContact
set newTarget to ""
set target to (value of aPhone)
repeat with aChar in (characters of target)
if aChar is not in badList then set newTarget to newTarget & aChar
if aChar is in {" "} then
if (count of newTarget) < 12 then set newTarget to newTarget & "-"
end if
end repeat
if not (target = newTarget) then
set theChange to (name of aContact) & " -- " & (label of aPhone)
set theChange to theChange & " -- " & target & " -- " & newTarget
set the end of changes to theChange
set value of aPhone to (newTarget as text)
save
end if
end repeat
end repeat
delay 0.5
end tell

if (count changes) is greater than 1 then (choose from list changes with empty selection allowed) -- show any changes
end doStuff

SouthernAtHeart
Feb 5, 2012, 05:37 PM
I'll definitely look into this. I've started reading this ebook you mentioned. It's VERY helpful.


Give this a try. Using my progress bar template, make a new application and replace the main script with:

property myProgressController : missing value -- the controller script instance

on run
set myProgressController to current application's ProgressBarController's alloc's init() -- create instance
try
doStuff()
on error errmess number errnum
display alert "error number " & errnum message errmess
end try
tell me to quit
end run

on doStuff()
set theirGroup to "test" -- fill in the blank
set badList to {"(", ")", " "} -- a list of characters to clean
set changes to {"Person -- Phone -- Old# -- New#"} -- this will be a list of changes

tell application "Address Book"
set theContacts to (people in group theirGroup)

set theCount to (count theContacts) -- get a maximum count for the progress bar
tell myProgressController -- set up and show the progress bar
createProgressWindow()
setBarberPole_(false)
setupProgressWithTopText_bottomText_maxValue_("Fixing phone numbers...", "", theCount)
delay 1
end tell

repeat with this from 1 to theCount
set aContact to item this of theContacts

set theName to name of aContact
tell myProgressController -- increment the progress bar
updateProgressByAmount_topText_bottomText_(1, "Processing item " & this & " of " & theCount, theName)
doEventFetch() -- keep event queue cleared
-- delay 0.25
end tell

repeat with aPhone in phones of aContact
set newTarget to ""
set target to (value of aPhone)
repeat with aChar in (characters of target)
if aChar is not in badList then set newTarget to newTarget & aChar
if aChar is in {" "} then
if (count of newTarget) < 12 then set newTarget to newTarget & "-"
end if
end repeat
if not (target = newTarget) then
set theChange to (name of aContact) & " -- " & (label of aPhone)
set theChange to theChange & " -- " & target & " -- " & newTarget
set the end of changes to theChange
set value of aPhone to (newTarget as text)
save
end if
end repeat
end repeat
delay 0.5
end tell

if (count changes) is greater than 1 then (choose from list changes with empty selection allowed) -- show any changes
end doStuff