• 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: is Shane's advice being collated?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: is Shane's advice being collated?


  • Subject: Re: is Shane's advice being collated?
  • From: Charles Arthur <email@hidden>
  • Date: Wed, 19 Nov 2014 09:27:15 +0000

This advice of Shane's is fantastic and such a helpful resource. Is it being collected or collated or stuffed into a webpage or book or ebook anywhere?

best
Charles
(written while mobile. May contain errors.)

> On 19 Nov 2014, at 03:31, email@hidden wrote:
>
> Send AppleScript-Users mailing list submissions to
>    email@hidden
>
> To subscribe or unsubscribe via the World Wide Web, visit
>    https://lists.apple.com/mailman/listinfo/applescript-users
> or, via email, send a message with subject or body 'help' to
>    email@hidden
>
> You can reach the person managing the list at
>    email@hidden
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of AppleScript-Users digest..."
>
>
> Today's Topics:
>
>   1. Scripting alerts (Shane Stanley)
>   2. Re: Scripting alerts (Shane Stanley)
>   3. Re: Scripting alerts (Shane Stanley)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Wed, 19 Nov 2014 14:24:10 +1100
> From: Shane Stanley <email@hidden>
> To: AS users <email@hidden>
> Subject: Scripting alerts
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset="utf-8"
>
> There are times when display dialog and display alert are not quite enough. If you're running Mavericks or Yosemite, AppleScriptObjC gives you more options, in particular by giving you access to extra possibilities with alerts.
>
> Two simple possibilities are the ability to have more than three buttons -- something not really needed often, but sometimes justified -- and the ability to include a Do not show this message again checkbox, known as a suppression button. A more complex option is to include an accessory view -- an area above the buttons where you can add extra controls.
>
> Alerts also lend themselves more to being coded as handlers, making them ideal to store in script libraries. By storing them in script libraries, you also make them accessible from Mavericks. (In fact, in Mavericks they have to be in libraries.)
>
> Before getting down to code, it's probably worth discussing the process. First, you create a new NSAlert, using either the new() or alloc() and init() methods. It's roughly equivalent to "make new..." in traditional AppleScript. You can then set various properties -- alertStyle, messageText, informativeText and showsSuppressionButton. Buttons are added one at a time, from right to left, using addButtonWithTitle:. The right-most button is always the default button, and a button called "Cancel" (or localized equivalent) responds to the escape key or command-..
>
> After that, you show the dialog by calling runModal(), which returns a number that relates to the button that was pressed.
>
> The handler below takes an integer for the style, and a list of button titles from left-to-right, to match the standard AppleScript order; the code then reverses the order before adding them. It uses the result of runModal() to work out the button title, and it is ignoring the suppression button for the moment.
>
> Before you run the code, a warning: ASObjC code that involves drawing stuff on screen, like this, has to be run in the foreground on what is known as the main thread. If it is run on a background thread, the likely result is that the app will crash. Scripts are nearly always run on the main thread -- the one exception being in script editors, where they are usually run on background threads. So when you are trying out this code, you need to make sure you run it in the foreground.
>
> In Script Editor, you run a script in the foreground by holding the control key when running it, or pressing control-command-R. You can see the Run command change names in the Script menu when you hold down the control key. In ASObjC Explorer you check the 'Run in foreground' checkbox at the bottom of the script window.
>
> Because it is easy to forget when you are testing, especially in Script Editor, I've added some extra code that checks if it is running in the foreground, and if not shows a dialog and stops, rather than letting the app crash. This simply asks the NSThread class if the current code is on the main thread.
>
> 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
> on displayAlert:mainText message:theExplanaton asStyle:styleNum buttons:buttonsList
>    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 the alert
>    tell theAlert
>        its setAlertStyle:styleNum
>        its setMessageText:mainText
>        its setInformativeText:theExplanaton
>        repeat with anEntry in buttonsList
>            (its addButtonWithTitle:anEntry)
>        end repeat
>    end tell
>    -- show the alert
>    set returnCode to theAlert's runModal()
>    -- get values after alert is closed
>    set buttonNumber to returnCode mod 1000 + 1 -- where 1 = right-most button
>    set buttonName to item buttonNumber of buttonsList
>    return buttonName
> end displayAlert:message:asStyle:buttons:
>
> set buttonName to (my displayAlert:"Stay alert" message:"This is the 9 o'clock news" asStyle:2 buttons:{"Cancel", "Maybe", "Possibly", "Perhaps", "Probably", "OK"})
>
> --
> Shane Stanley <email@hidden>
> <www.macosxautomation.com/applescript/apps/>
>
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <https://lists.apple.com/mailman/private/applescript-users/attachments/20141119/ef033761/attachment.html>
>
> ------------------------------
>
> Message: 2
> Date: Wed, 19 Nov 2014 14:27:50 +1100
> From: Shane Stanley <email@hidden>
> To: AS users <email@hidden>
> Subject: Re: Scripting alerts
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset="utf-8"
>
> Now for the suppression button. This is simply a matter of making sure it shows -- by calling setShowsSuppressionButton: -- and once the alert is dismissed, checking the state of the suppression button.
>
> This code includes a repeat loop, to show how the suppression button works. Each time through the loop, a dialog appears and a voice speaks; once you click the suppress button, the dialog no longer appears.
>
> The same warning and advice about running in the foreground holds:
>
> 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
> on displayAlert:mainText message:theExplanaton asStyle:styleNum buttons:buttonsList suppression:showSuppression
>    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
>    -- show alert
>    set returnCode to theAlert's runModal()
>    -- 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
>    set buttonName to item buttonNumber of buttonsList
>    return {buttonName, suppressedState}
> end displayAlert:message:asStyle:buttons:suppression:
>
> set showDialog to true -- start off showing dialog
>
> repeat with i from 1 to 10
>    if showDialog then
>        set {buttonName, suppressedState} to (my displayAlert:"Decision time" message:("Do you want to munge item " & i & "?") asStyle:2 buttons:{"Cancel", "OK"} suppression:true)
>        -- if box was checked, we want showSuppression off next time
>        if suppressedState then set showDialog to false
>    end if
>    -- do what needs to be done, depending on buttonName, here
>    say ("Loop number " & i)
> end repeat
>
> --
> Shane Stanley <email@hidden>
> <www.macosxautomation.com/applescript/apps/>
>
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <https://lists.apple.com/mailman/private/applescript-users/attachments/20141119/b84956ce/attachment.html>
>
> ------------------------------
>
> Message: 3
> Date: Wed, 19 Nov 2014 14:31:45 +1100
> From: Shane Stanley <email@hidden>
> To: AS users <email@hidden>
> Subject: Re: Scripting alerts
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset="utf-8"
>
> 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/>
>
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <https://lists.apple.com/mailman/private/applescript-users/attachments/20141119/fe5543f2/attachment.html>
>
> ------------------------------
>
> _______________________________________________
> AppleScript-Users mailing list
> email@hidden
> https://lists.apple.com/mailman/listinfo/applescript-users
>
> End of AppleScript-Users Digest, Vol 11, Issue 448
> **************************************************

 _______________________________________________
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: is Shane's advice being collated?
      • 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: is Shane's advice being collated?
  • Index(es):
    • Date
    • Thread