• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag
 

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Scripting alerts
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Scripting alerts


  • Subject: Re: Scripting alerts
  • From: Shane Stanley <email@hidden>
  • Date: Wed, 19 Nov 2014 14:31:45 +1100

At this stage you might notice that something has been lost: display alert's giving up after parameter. It's not exactly obvious how to do the equivalent, but it's just a couple of extra lines of code. Remember, this stuff is usually best stored in a library and called from there.

The handler below has a new parameter, givingUpAfter, and it takes a number. If you don't want the alert to timeout, you pass a value of 0 and it behaves like the previous version. The handler checks this value, and if it is 0, it calls a special method of the application (aka NSApp). It tells the application to call a particular method (performSelector:), passing a parameter if it takes one (withObject:), after waiting a certain amount of time (afterDelay:), and to do it in a way that it gets triggered even while a modal panel is showing (inModes:). The method we want called after the delay is abortModal, which ends the runModal method.

But you have to be a bit careful. Suppose you schedule the abortModal method to be called after 30 seconds, and the user hits a button almost immediately. There might be another dialog showing when the 30 seconds are up, and it would be dismissed instead. So once the alert has been dismissed, you need to check whether it could have been due to a timeout (if giveUp > 0), and if so, whether the return code tells you it aborted (NSModalResponseAbort). If the former and not the latter, you need to cancel the still-scheduled call to abortModal, which you do using a special method of the NSObject class, cancelPreviousPerformRequestsWithTarget:::.

Then when you get the button number, if it is 0 you know the alert timed out, and in this case the handler sets the button name to "Gave Up".

So the previous code now looks like this:

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit" -- required for NSAlert

-- check we are running in foreground
if not (current application's NSThread's isMainThread()) as boolean then
display alert "This script must be run from the main thread." buttons {"Cancel"} as critical
error number -128
end if

-- for styleNum, 0 = warning, 1 = informational, 2 = critical; for givingUpAfter, 0 means never
on displayAlert:mainText message:theExplanaton asStyle:styleNum buttons:buttonsList suppression:showSuppression givingUpAfter:giveUp
set buttonsList to reverse of buttonsList -- because they get added in reverse order cf AS
-- create an alert
set theAlert to current application's NSAlert's alloc()'s init()
-- set up alert
tell theAlert
its setAlertStyle:styleNum
its setMessageText:mainText
its setInformativeText:theExplanaton
repeat with anEntry in buttonsList
(its addButtonWithTitle:anEntry)
end repeat
its setShowsSuppressionButton:showSuppression
end tell
-- if giveUp value > 0, tell the app to abort any modal event loop after that time, and thus close the panel
if giveUp > 0 then current application's NSApp's performSelector:"abortModal" withObject:(missing value) afterDelay:giveUp inModes:{current application's NSModalPanelRunLoopMode}
-- show alert in modal loop
set returnCode to theAlert's runModal()
-- if a giveUp time was specified and the alert didn't timeout, cancel the pending abort request
if giveUp > 0 and returnCode is not current application's NSModalResponseAbort then current application's NSObject's cancelPreviousPerformRequestsWithTarget:(current application's NSApp) selector:"abortModal" object:(missing value)
-- get values after alert is closed
set suppressedState to theAlert's suppressionButton()'s state() as boolean
set buttonNumber to returnCode mod 1000 + 1 -- where 1 = right-most button
if buttonNumber = 0 then
set buttonName to "Gave Up"
else
set buttonName to item buttonNumber of buttonsList
end if
return {buttonName, suppressedState}
end displayAlert:message:asStyle:buttons:suppression:givingUpAfter:

set {buttonName, suppressedState} to (my displayAlert:"Decision time" message:("Yae or nay?") asStyle:2 buttons:{"Cancel", "Maybe", "OK"} suppression:false givingUpAfter:3.0)
return buttonName

Next stop: accessory views.

-- 
Shane Stanley <email@hidden>
<www.macosxautomation.com/applescript/apps/>

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/archives/applescript-users

This email sent to email@hidden

  • Follow-Ups:
    • Re: Scripting alerts
      • From: Shane Stanley <email@hidden>
References: 
 >Scripting alerts (From: Shane Stanley <email@hidden>)
 >Re: Scripting alerts (From: Shane Stanley <email@hidden>)

  • Prev by Date: Re: Scripting alerts
  • Next by Date: Re: is Shane's advice being collated?
  • Previous by thread: Re: Scripting alerts
  • Next by thread: Re: Scripting alerts
  • Index(es):
    • Date
    • Thread