CUSTOM DIALOG FOR CREATE DOCUMENT SCRIPT

In writing a script for InDesign requiring user input, a simple dialog can be written using a number of methods in AppleScript. The demonstration script in our previous blog post used CHOOSE FROM LIST to have the user select a document preset with which to create a new document.

Get Document Preset

set presetPrompt to "Select preset for new document"
try
   set myList to getPresets(1)
   set presetName to getNameFromList(myList, presetPrompt)
on error errStr
   display alert ("Error: " & errStr)
end try

(*Returns list of names for document presets having intnet designated by list index*)
on getPresets(intentIndex)
   tell application "Adobe InDesign CC 2019"
      set intentType to item intentIndex of {print intent, web intent, mobile intent}
      set fullList to (name of document presets where intent is intentType)
   end tell
end getPresets

(*dialog for user to select item from list*)
on getNameFromList(theList, thePrompt)
   set userChoice to choose from list theList with prompt thePrompt
   if userChoice is not false then
      return item 1 of userChoice
   else
      error "User cancelled"
   end if
end getNameFromList

A second dialog was needed to have the user choose a file. When a script requires two or more dialog inputs from the user, rather than using multiple dialogs, it may be better to have one dialog window using a custom dialog. For this, InDesign provides the ability to create a custom dialog with a number of widgets for user interaction including entry fields, dropdowns, checkboxes and radio buttons. For instance, instead of using choose from list you could have a dropdown in a custom dialog provide the same capability.

CUSTOM DIALOG

To simplify the creation of a custom dialog the template provided here can be used:

Custom Dialog Template

set dlgName to "Document Preferences"
set canCancel to true
set dlgLabel to "DocPrefs"
set dlgRef to customDialog(dlgName, canCancel, dlgLabel)

on customDialog(dlgName, canCancel, dlgLabel)
   tell application "Adobe InDesign CC 2019"
      activate
      set origPrefs to user interaction level of script preferences
      set user interaction level of script preferences to interact with all
      set dialogRef to make dialog with properties {name:dlgName, can cancel:canCancel, label:dlgLabel}
      tell dialogRef
	 tell (make dialog column)
	    --set up dialog widgets here
	    tell (make dialog row)
		end tell --row
	    end tell --column
      end tell --dialog
		
      set userResponse to show dialogRef
      set returnList to {}
      if userResponse is true then
	 --get user responses here
      end if
      destroy dialogRef
      set user interaction level of script preferences to origPrefs
   end tell
   return returnList
end customDialog

Running this code will create a dialog window with buttons for OK and Cancel only.

ADD A DROPDOWN

Building on the code for the custom dialog, our “Create Document” script will use a dropdown to have the user select an item from a list. To provide the list of document presets from which to choose, the following getPresets handler will be used. Add this at the bottom of the script.

(*Returns list of names for document presets having intent designated by list index*)
on getPresets(intentIndex)
   tell application "Adobe InDesign CC 2019"
      set intentType to item intentIndex of {print intent, web intent, mobile intent}
      set fullList to (name of document presets where intent is intentType)
      return rest of fullList
   end tell
end getPresets

The handler returns a list of document presets having intent indicated by the value (1, 2, or 3) passed. Change the top of the script to add global variable declarations and the call to the handler.

global gPresetList
global gFileList
set dlgName to "Document Preferences"
set canCancel to true
set dlgLabel to "DocPrefs"
set gPresetList to getPresets(1)
set dlgRef to customDialog(dlgName, canCancel, dlgLabel)

To add the dropdown to the custom dialog, change the code inside the tell dialogRef statement block to read as follows:

tell (make dialog column)
   --set up dialog widgets here
   tell (make dialog row)
	make static text with properties {static label:"Choose document preset:"}
	set presetDrop to make dropdown with properties{string list:gPresetList, selected index:0}
   end tell --row
end tell --column

ADD ANOTHER DROPDOWN

The custom dialog also needs a dropdown to allow the user to select the file from which to import styles. Instead of using a CHOOSE FILE command, the dialog will provide the user a list of files found in a sub-folder of the “Styles” folder named “Print.” For our purpose here, the “Styles” folder will be in the user’s Library folder. With style files in this folder, get the file list using the following:

Get Style Files

Before the call to customDialog at the top of the script add:

set folderPath to path to library folder from user domain as string
set styleFolder to folderPath & "Styles:Print:"
set gFileList to getStyleFiles(styleFolder)

Add the following getStyleFiles handler to the bottom of the script.

(*Returns list of files in Styles folder designated*)
on getStyleFiles(styleFolder)
	set fileList to list folder styleFolder without invisibles
	return fileList
end getStyleFiles

With the style file list (gFileList<) as part of the script, the dropdown can be added. The custom dialog will also allow the user to determine if styles are to be added to the document or not. This will be done by placing the interface objects (widgets) having to do with importing styles inside an enabling group. Add the following just below the end tell–row statement that creates the first dropdown.

   set eGroup to make enabling group with properties {static label:"Import Styles", checked state:true}
   tell eGroup
      tell (make dialog column)
         tell (make dialog row)
	    make static text with properties {static label:"Select style file:"}
	    set fileDrop to make dropdown with properties {string list:gFileList, selected index:0}
	 end tell --row
      end tell --column
   end tell --enabling group

ADD RADIO BUTTONS

The script we developed in our previous blog post assumed that the user would want to import Paragraph and Object Styles. In this version, the custom dialog will allow the user to select from two radio buttons to indicate the styles to be imported. For this, change the tell eGroup block to read:

   tell eGroup
      tell (make dialog column)
	  tell (make dialog row)
	     make static text with properties {static label:"Select style file:"}
	     set fileDrop to make dropdown with properties {string list:gFileList, selected index:0}
	  end tell --row
          set styleList to {"Text and Object Styles", "All Styles"}
	  set radioGroup to make radiobutton group
	  tell radioGroup
	     make radiobutton control with properties {static label:item 1 of styleList, checked state:true}
	     make radiobutton control with properties {static label:item 2 of styleList}
	  end tell
      end tell --column
   end tell --enabling group

GET USER RESPONSES

Now that the user interface objects (widgets) have been added to the dialog, we can add the code to get the values chosen by the user and pass them back to the call to customDialog at the top of the script. Inside the if statement near the bottom of the script, change the code to read:

   --get user responses here
   set fileChoice to missing value
   set styleChoice to missing value
   set presetChoice to item ((selected index of presetDrop) + 1) of gPresetList
   if checked state of eGroup is true then
      set fileChoice to item ((selected index of fileDrop) + 1) of gFileList
      set styleIndex to selected button of radioGroup
      set styleChoice to item (styleIndex + 1) of styleList
   end if
   set returnList to {presetChoice, fileChoice, styleChoice}

CUSTOM DIALOG

The code for the Custom Dialog portion of our script in its entirety is listed below:

global gPresetList
global gFileList
set dlgName to "Document Preferences"
set canCancel to true
set dlgLabel to "DocPrefs"
set gPresetList to getPresets(1)
set folderPath to path to library folder from user domain as string
set styleFolder to folderPath & "Styles:Print:"
set gFileList to getStyleFiles(styleFolder)
set dlgResult to customDialog(dlgName, canCancel, dlgLabel)

on customDialog(dlgName, canCancel, dlgLabel)
   tell application "Adobe InDesign CC 2019"
	activate
	set origPrefs to user interaction level of script preferences
	set user interaction level of script preferences to interact with all
	set dialogRef to make dialog with properties {name:dlgName, can cancel:canCancel, label:dlgLabel}
	tell dialogRef
	   tell (make dialog column)
		tell (make dialog row)
		   make static text with properties {static label:"Select document preset:"}
		   set presetDrop to make dropdown with properties {string list:gPresetList, selected index:0}
		end tell --row
		set eGroup to make enabling group with properties {static label:"Import Styles", checked state:true}
		tell eGroup
		   tell (make dialog column)
			tell (make dialog row)
			   make static text with properties {static label:"Select style file:"}
			   set fileDrop to make dropdown with properties {string list:gFileList, selected index:0}
			end tell --row
			set radioGroup to make radiobutton group
			set styleList to {"Text and Object Styles", "All Styles"}
			tell radioGroup
			   make radiobutton control with properties {static label:item 1 of styleList, checked state:true}
			   make radiobutton control with properties {static label:item 2 of styleList}
			end tell
		   end tell --column
		end tell --enabling group
	   end tell --column
	end tell -- dialog	
	set userResponse to show dialogRef
	set returnList to {}
	if userResponse is true then
	   --get user responses here
	   set fileChoice to missing value
	   set styleChoice to missing value
	   set presetChoice to item ((selected index of presetDrop) + 1) of gPresetList
	   if checked state of eGroup is true then
		set fileChoice to item ((selected index of fileDrop) + 1) of gFileList
		set styleIndex to selected button of radioGroup
		set styleChoice to item (styleIndex + 1) of styleList
	   end if
	   set returnList to {presetChoice, fileChoice, styleChoice}
	end if
	destroy dialogRef
	set user interaction level of script preferences to origPrefs
   end tell
   return returnList
end customDialog

(*Returns list of names for document presets having intent designated by list index*)
on getPresets(intentIndex)
	tell application "Adobe InDesign CC 2019"
		set intentType to item intentIndex of {print intent, web intent, mobile intent}
		set fullList to (name of document presets where intent is intentType)
		return rest of fullList
	end tell
end getPresets

(*Returns list of files in Styles folder designated*)
on getStyleFiles(styleFolder)
	set fileList to list folder styleFolder without invisibles
	return fileList
end getStyleFiles

CREATE DOCUMENT

The code above provides the information needed to create the InDesign document. To complete the script, add the following to the top of the script as follows: This will test the value for dlgResult and call one of two handlers to create a document based on the value for fileChoice returned from the custom dialog.

if dlgResult is not {} then
   copy dlgResult to {presetChoice, fileChoice, styleChoice}
   if fileChoice is not missing value then
      set styleSourceFile to (styleFolder & fileChoice) as alias
      set docRef to createDocWithStyles(presetChoice, styleSourceFile, styleChoice)
    else
      set docRef to createDocWithPreset(presetChoice)
    end if
end if

The handlers for creating the document are as follows:

(*Creates document using document preset and imports styles from style file*)
on createDocWithStyles(presetChoice, styleSourceFile, styleChoice)
   tell application "Adobe InDesign CC 2019"
      set docPreset to document preset presetChoice
      set docRef to make document with properties {document preset:docPreset}
      tell docRef
	 if styleChoice = "All Styles" then
	    import styles format table styles format from styleSourceFile
	    import styles format text styles format from styleSourceFile
	    import styles format object styles format from styleSourceFile
	 else if styleChoice = "Text and Object Styles" then
	    import styles format text styles format from styleSourceFile
	    import styles format object styles format from styleSourceFile
	 end if
      end tell
   end tell
   return styleChoice
end createDocWithStyles

(*Creates document using document preset*)
on createDocWithPreset(presetName)
   tell application "Adobe InDesign CC 2019"
      set docRef to make document with properties {document preset:presetName}
   end tell
   return docRef
end createDocWithPreset

ONWARD AND UPWARD

You may want to enclose the code at the top of the script with a try/on error/end try trap. This could be used to notify the user in the event the user clicks the Cancel button for the custom dialog. Other errors will be generated if you attempt to use the getPresets handler with any value for intentIndex other than 1. Our next blog post will discuss some of the problems in working with document presets and intent. Meanwhile, think of other properties for the document  that you might want to add to the script. How would you modify the script above to add this functionality?

Disclaimer:
Scripts provided are for demonstration and educational purposes. No representation is made as to their accuracy or completeness. Readers are advised to use the code at their own risk.