Your prescription for increased productivity and profitability
Unless you are super new to AppleScript you probably are quite familiar with modal dialog boxes. But, just to review, recall that a modal dialog box, when issued from within an application, will not allow any other activity to occur in the application until the dialog is dismissed. In this instance, the dialog will display for a maximum of 2 minutes (120 seconds) before timing out with an error.
To test, run the following script and fail to respond before two minutes have elapsed.
tell application "Adobe InDesign CC 2014" activate set userResponse to display dialog "Do you want to continue?" buttons {"Yes", "No"} default button "Yes" if button returned of userResponse is "No" then error "User Quit Application" end tell
If an AppleScript dialog is not issued from within an application, the dialog box can stay open for as long as you will let it. To test, run the following script and go on to do other tasks on the computer for over two minutes.
set d to time of (current date) set userResponse to display dialog "What is your name?" default answer "" buttons {"OK"} set b to time of (current date) set timeToAnswer to b - d if text returned of userResponse is not "" then set userName to text returned of userResponse display alert ("Hello " & userName & return & "It took you " & timeToAnswer " & " seconds to respond.") end if
Notice the code in the above that allows the script to determine the amount of time that elapsed before the dialog was dismissed.
You can limit the time an AppleScript dialog stays open by appending a giving up after statement to a display dialog or display alert. This is often used to provide a dialog that does not require a response.
display alert "Script is completed" giving up after 3
The result of a dialog set to give up after a number of seconds will return true if the dialog stays open for the allowed amount of time. If the user dismisses the dialog before that time, the result is false. Check AppleScript Editor’s Result panel to see what is returned when you run the following script. First, allow the dialog to stay open until it closes automatically, and second, dismiss the dialog by clicking the OK button.
display dialog "Click OK to dismiss dialog" buttons {"OK"} giving up after 30
Conversely you can extend the amount of time a dialog issued within an application is allowed to stay open using a with timeout statement.
tell application "Finder" with timeout of 500 seconds --a process that takes a long time end timeout end tell
A with timeout statement can be used around a choose file, choose from list, or other AppleScript statements that requires the user to respond.
set homeFolder to (path to home folder from user domain) as string set ccFolder to (homeFolder & "Creative Cloud Files") as alias tell application "Adobe InDesign CC 2014" with timeout of 500 seconds set fileChoice to choose file with prompt "Select Text File" default location ccFolder end timeout --script continues using file chosen end tell
InDesign Custom Dialogs are also modal in that the script cannot continue, nor can any user activity continue within InDesign until the dialog is dismissed.
If the dialog has a number of fields that could take the user longer than 2 minutes to complete, you might want to give the dialog some extra time using a with timeout statement. The following simplified dialog can be used for testing:
try set userResponse to doDialog() on error errStr number errorNumber if errorNumber is -1712 then --timeout error activate display alert "Error: " & errStr end try (*Sample dialog gives user up to 500 seconds to respond Assumes user interaction level of script preferences is set to interact with all*) on doDialog() tell application "Adobe InDesign CC 2014" with timeout of 500 seconds set dlgRef to make dialog with properties {name:"Demo Dialog"} tell dlgRef tell (make dialog column) tell (make dialog row) make static text with properties {static label:"Document Name"} set nameField to make text editbox with properties {min width:200, edit contents:""} end tell end tell end tell set userResponse to show dlgRef end timeout if userResponse is true then set userCancelled to false set theResult to edit contents of nameField else set userCancelled to true end if destroy dlgRef if userCancelled then error ("User Cancelled") return theResult end tell end doDialog
Notice how the call to the doDialog handler is called from within a try/on error block to handle the error thrown if user dismisses the dialog using the Cancel button. Also, notice how the error number can be used to determine the error that was thrown. Error number -1712 is a timeout error.
So what happens if the user gets interrupted right in the middle of working with a custom dialog and does not get back within the time allotted? AppleScript will raise its nasty time out error and will not let the user do anything inside InDesign until the dialog is closed.
This problem was brought to my attention recently by a user. Under most circumstances, the user can simply dismiss the error and close the dialog. However, depending on how the script is written, the user may be prevented from closing the dialog because the modal dialog is open. For this reason, you may decide to have the script close the dialog when it times out.
The following script outline can be used to programmatically force a dialog window to close when it has been left open.
--Inside an InDesign tell statement block: try with timeout of 180 seconds --or however much time you want to give the user set userResponse to my userDialog () --add your parameters here end timeout on error errStr number errorNumber if errorNumber is -1712 then --timeout error my closeWindow () --call handler to close window set userResponse to {} --no response from user end if end try --go on with script or end tell statement to InDesign (*handler to close the modal dialog*) on closeWindow() tell application "System Events" tell process "Adobe InDesign CC 2014" to keystroke return end tell end closeWindow (*handler for creating custom dialog*) on userDialog () --do whatever here --and return result end userDialog
NOTE: Keystroke return activates the default button (“OK”) for the dialog and closes it. Because the handler is technically outside of Adobe’s realm, another application can be used to have InDesign close the window using the default button.
On the side of caution: When a dialog is created, its structure is placed in memory. There it stays until destroyed. If not closed properly, that chunk of memory will stay around until you restart InDesign.
As part of cleaning up after running a script, you might want to add the following. This piece of code checks for any errant dialogs hanging around and gets rid of them.
tell application "Adobe InDesign CC 2014" set theCount to count of dialogs if theCount > 0 then destroy dialogs end if set theCount to count of dialogs end tell
Hope this little bit of review will will help you make some of your scripts a little more user friendly.
Next week, we start a blog series to help you unmask the mystery of using scripts to create animations in InDesign fixed layout EPUB projects.