I’ve been scratching my head for a few days about how to use a “cancel” button to exit a double nested repeat loop without actually executing anything. I’m sure there’s a solution to this but it has me baffled.
Here’s a slightly simplified version of what I have so far:
on alert ended theObject with reply theReply
set contents of text field "process info" to "Please insert a blank CD"
set visible of button "cancel burn" to true
-- Poll the optical drive to see if there's media in it. If there's not, wait a second and check again.
set mediaStatus to do shell script ("check for media")
if mediaStatus is not "No Media Inserted" then
set visible of button "cancel burn" to false
-- See if the media inserted is a recordable CD. If not, eject whatever is in there and start over.
set mediaStatus to do shell script ("check for media type")
if mediaStatus is "blank" or "overwritable" then exit repeat
set contents of text field "process info" to "CD is not recordable!"
do shell script ("drutil eject")
--script continues on from here
end alert ended
I have a cancel button at the bottom of the window that, if pressed, should just immediately kill this process of checking for a blank CD. Any ideas on how to do this? Thanks!
Is this code being run after you press another button in your interface?
It’s part of an alert ended handler. I should probably add that to the example.
The only thing I can think to do is to have the cancel button set some variable when pressed, like “set cancelButton to true”, and then create a series of “if cancelButton is true then…” statements to exit the repeat loops. This isn’t the most elegant solution though, given that it’d probably be a few seconds before the loop made it back to the point of being able to recognize the button press. The button’s responsiveness would seem erratic to the user.
Personally, I’d try to do this another way. It doesn’t seem right where you have to jump out of a nested repeat loop.
You can set a flag when the user clicks the button.
property user_canceled: false
on clicked theObject
if name of theObject is “cancel” then
set user_canceled to true
Then in the repeat loop, check user_canceled. If true, then exit inner repeat loop. In out repeat loop, check user_canceled. If true, then set user_canceled to false and exit repeat.
Another way. You could wrap the nested repeat loops in an error handler.
if user_canceled then error number -128
set user_canceled to false
Try running this in the Script editor to see what this does.
error number -128
on error _err
display dialog _err
Ah yeah, that’ll probably work. That’s similar to what I was thinking, but using an error handler is a great idea. My only concern is still the length of time it takes to make it through a single loop, but I suppose there’s no way to avoid that since the delays are caused by shell script execution. Thanks!