Accessing Sub-menus with System Events--Asking for help

Hello MacScripter and scripters at large. I’ve lurked and prowled the site for some time and now I need to call on the power of the collective for a bit of help.

I’m writing a script, part of which needs to address an InDesign CS4 plugin. The plugin is scriptable, but the particular function I need is not. My best solution is to activate the panel I need to open through the System Events.

I have identified the tell structure needed through ScriptDebugger, and the documentation I have seen reflects what I’m looking at, however executing the script does not have the desired effect.

Here’s the code.

tell application "Adobe InDesign CS4"
	activate
end tell
tell application "System Events"
	tell process "Adobe InDesign CS4"
		tell menu bar 1
			tell menu bar item "File"
				tell menu "File"
					tell menu item "New"
						tell menu "New"
							tell menu item "EasyCatalog Panel..."
								tell menu "EasyCatalog Panel..."
									click menu item "<target menu item>"
									-- I have also tried this using the "set theResult to..." method in the System Events dictionary
									-- set theResult to click menu item "<target menu item>"
								end tell
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

For me, InDesign activates as requested. The rest of the script presumably runs through with no effect. There is no error, and ScriptDebugger can see the target menu item and it’s properties.

Now…oddly, I have been able to use this same structure up to the “tell menu “File”” to execute InDesign menu commands that fall directly under the main “File” menu. I cannot get ANYTHING in a sub-menu to execute, such as “File> New> Document”
GUI scripting is turned on. I’m running Snow Leopard and ScriptDebugger 4.5 and AppleScript 2.1.1

Hopefully one of you might be able to help me sort out this issue. Thanks!

Hi,

GUI scripting is a weird thing, there is no unique way.

two suggestions:

¢ a common trap are the three dots, which can be also one single character (horizontal ellipsis ⌥.)
¢ specify the submenus by index, not by name


activate application "Adobe InDesign CS4"

tell application "System Events"
	tell process "Adobe InDesign CS4"
		tell menu bar 1
			tell menu bar item "File"
				tell menu 1
					tell menu item "New"
						tell menu 1
							tell menu item "EasyCatalog Panel."
								tell menu 1
									click menu item "<target menu item>"
									-- I have also tried this using the "set theResult to..." method in the System Events dictionary
									-- set theResult to click menu item "<target menu item>"
								end tell
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

some other things you can try:

¢ use pick menu item instead or click menu item
¢ use perform action “AXsomething” instead of direct commands like press or select, Script Debugger shows the available actions in the explorer

Another trick is using delay. I found some programs have tiny pauses before submenus open or generate and that trips-up UI scripting. This is especially true if the Mac is slower or bogged-down by other things.

What I do is define delay_small, delay_medium, and delay_large variables (0.2, 0.5, a 1 respectively) and then insert delays between every step:

delay delay_medium

If it works, experiment with taking delays out. Then experiment with the smallest value of delay you can get away with.

I also recommend UI Browser by PreFab software, which can further help you with complicated UI activation blocks.

I’ve done some pretty odd things with UI scripting (like scripting the Lotus Notes client.eeeew!), but it can be a bit of voodoo at times.

I’ve had that happen – AppleScript was too fast for menu bars. I didn’t solve it, but I went on to something else. Now I know what to do when an error occurs from menu bar selection (if I would ever do that)!

Hi Kevin,

sorry, I regard delays for choosing menu items from the main menu as quite useless.
Unlike menu items of popup menus they are not traversed visibly, so time doesn’t matter.

Stefan following your suggestion, I checked this and it’s definitely not an ellipses glyph, they are three dots, but thanks for the tip, I’ll keep it in my toolbox.
Unfortunately addressing the sub-menus by index had the same effect.

I have tried these too with the same effect.
Check my code on the action though. I need to add another tell block to address the menu item directly to access it’s AXPress action right?

tell menu item "<target menu item>"
perform "AXPress"
end tell

No joy here either.

I’m really hoping this isn’t just a ‘bind spot’. The plugin developer has not included a scripting handle for an “open” action, which is really quite ridiculous to me. A script can close, sort, update, export and do a dozen other functions, but it can’t open.

Am I correct in assuming this is a plugin that adds an additional file type under File–>New?

(i.e. EasyCatalog)

Then yes, you could have hit a problem I’ve had it happen twice where what I can best describe as “dynamically-driven menu items” occurs. Lotus Notes and Adobe’s CS3 print dialogs both had pop-ups or submenus of this type and they esssentially are inaccessible because their index says one thing in the UI browser, but is actually something else (or not available or “hidden” in some fashion).

I’d be curious how UI Browser “sees” this item and if the various multitude of ways to access the File–>New make any difference.

For Reference, the “Book” item is:

menu item "Book..."  of menu 1 of menu item "New"  of menu 1 of menu bar item "File"  of menu bar 1

or

menu 1 of menu item 1  of menu 1 of menu bar item 3  of menu bar 1

So in theory yours is “menu item 5” or it’s name.

One thing UIB reminded me of, have you tried to query what UI scripting can see?

get every attribute of menu 1 of menu item 1  of menu 1 of menu bar item 3  of menu bar 1

or

get every action of menu 1 of menu item "New"  of menu 1 of menu bar item "File"  of menu bar 1

In other words hunt it down in reverse by seeing what InDesign returns from being probed for what is available.

Sorry if I seem to be winging-it, I go long gaps between having to do this sort of thing.

Typically, in GUI Scripting, you must click the menu item’s parent menu to open it before you can click the menu item. In Mac OS X, menu items don’t exist until the menu is opened.

Bill Cheeseman

Maybe you will be interested by the handlers which I use to trigger menu items thru GUIscripting.
The long versions are useful to check the menu structure.
The short versions are those used in the final script.



--=====
(*
my selectMenu("Pages",5, 12)
==== Uses GUIscripting ====
*)
on selectMenu(theApp, mt, mi)
	tell application theApp
		activate
		tell application "System Events" to tell process theApp to tell menu bar 1 to tell menu bar item mt to tell menu 1 to click menu item mi
	end tell -- application theApp
end selectMenu

--=====
(*
my selectSubMenu("Pages",6, 4, 26)
==== Uses GUIscripting ====
*)
on selectSubMenu(theApp, mt, mi, ms)
	
	tell application theApp
		activate
		tell application "System Events" to tell process theApp to tell menu bar 1 to tell menu bar item mt to tell menu 1 to tell menu item mi to tell menu 1 to click menu item ms
	end tell -- application theApp
end selectSubMenu

--=====
(*
useful to get the indexs of the triggered item
my select_Menu("Numbers", 5, 16) (* Insert > FileName *)
*)
on select_menu(theApp, mt, mi)
	tell application theApp
		activate
		tell application "System Events" to tell process theApp to tell menu bar 1
			get name of menu bar items
			(*{
			01 - "Apple", 
			02 - "Numbers", 
			03 - "Fichier", 
			04 - "Édition", 
			05 - "Insertion", 
			06 - "Tableau", 
			07 - "Format", 
			08 - "Disposition", 
			09 - "Présentation", 
			10 - "Fenêtre", 
			11 - "Partage", 
			12 - "Aide"}
			*)
			get name of menu bar item mt
			-- {"Insert"}
			tell menu bar item mt to tell menu 1
				get name of menu items
				(* {
				01 - "Feuille", 
				02 - missing value, 
				03 - "Tableau", 
				04 - "Graphique", 
				05 - "Figure", 
				06 - "Zone de texte", 
				07 - "Fonction", 
				08 - "Ligne de connexion", 
				09 - missing value, 
				10 - "Remplissage", 
				11 - missing value, 
				12 - "Rangs copiés", 
				13 - "Colonnes copiées", 
				14 - missing value, 
				15 - "Date et heure", 
				16 - "Nom du fichier", 
				17 - "Numéro de page", 
				18 - "Nombre de pages", 
				19 - missing value, 
				20 - "Commentaire", 
				21 - "Lien", 
				22 - "Saut de colonne", 
				23 - missing value, 
				24 - "Choisir."}
				*)
				get name of menu item mi
				--{"Nom du fichier"}
				click menu item mi
			end tell
			
		end tell
	end tell -- application theApp
end select_menu

--=====
(*
useful to get the indexs of the triggered item
my select_SubMenu("Numbers", 6, 14, 3) (* Table > Footer rows > 2 *)
*)
on select_SubMenu(theApp, mt, mi, ms)
	
	tell application theApp
		activate
		tell application "System Events" to tell process theApp to tell menu bar 1
			get name of menu bar items
			(*{
			01 - "Apple", 
			02 - "Numbers", 
			03 - "Fichier", 
			04 - "Édition", 
			05 - "Insertion", 
			06 - "Tableau", 
			07 - "Format", 
			08 - "Disposition", 
			09 - "Présentation", 
			10 - "Fenêtre", 
			11 - "Partage", 
			12 - "Aide"}
			*)
			get name of menu bar item mt
			-- {"Tableau"}
			tell menu bar item mt to tell menu 1
				get name of menu items
				(* {01 - "Insérer un rang au-dessus", 
				02 - "Insérer un rang en dessous", 
				03 - missing value, 
				04 - "Insérer une colonne avant", 
				05 - "Insérer une colonne après", 
				06 - missing value, 
				07 - "Supprimer le rang", 
				08 - "Supprimer la colonne", 
				09 - missing value, 
				10 - "Rangs d'en-tête", 
				11 - "Colonnes d'en-tête", 
				12 - "Bloquer les rangs d'en-tête", 
				13 - "Bloquer les colonnes d'en-tête", 
				14 - "Rangs de bas de tableau", 
				15 - missing value, 
				16 - "Ajuster les rangs au contenu", 
				17 - "Ajuster les colonnes au contenu", 
				18 - missing value, 
				19 - "Afficher tous les rangs", 
				20 - "Afficher toutes les colonnes", 
				21 - "Activer toutes les catégories", 
				22 - missing value, 
				23 - "Fusionner les cellules", 
				24 - "Diviser en rangs", 
				25 - "Diviser en colonnes", 
				26 - missing value, 
				27 - "Répartir les rangs uniformément", 
				28 - "Répartir les colonnes uniformément", 
				29 - missing value, 
				30 - "Autoriser la sélection de bordure", 
				31 - missing value, 
				32 - "Afficher le panneau de réorganisation"}
				*)
				get name of menu item mi
				--"Rangs de bas de tableau"
				tell menu item mi to tell menu 1
					get name of menu items
					(* {
					1 - "0", 
					2 - "1", 
					3 - "2", 
					4 - "3", 
					5 - "4", 
					6 - "5"}
					*)
					get name of menu item ms
					-- "2"
					click menu item ms
				end tell
				
			end tell
			
		end tell
	end tell -- application theApp
end select_SubMenu

--=====


Yvan KOENIG (VALLAURIS, France) samedi 3 avril 2010 16:37:35

OH! This was the key that opened it!

Here is the result that is doing what I need it to do!


activate application "Adobe InDesign CS4"

tell application "System Events"
	tell process "Adobe InDesign CS4"
		tell menu bar 1
			tell menu bar item "File"
				pick
				tell menu 1
					tell menu item "New"
						pick
						tell menu 1
							tell menu item "EasyCatalog Panel..."
								pick
								tell menu 1
									pick menu item "<Target Menu Item>"
								end tell
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

Thanks so much, Bill!
Stefan and everyone else that offered solutions, I appreciate the time taken to share what you know.

Next is to deal with the resulting dialog box that pops up confirming the selection.

Donnie Clark

Interesting, I’ve never done this for accessing menu items of a main menu, but of course for popup button menus.
Could it be that this “rule” affects only Carbon applications?

Was just checking new posts to the site while experimenting with GUI of MS Word in order to access sub-menu without activating (in window) the main menu.

Am very new to this. But came across -

it could be that, in some applications, if you just make your script aware of the main menu of the application it can then access its sub-menus without actually opening all the menus - ie silent ----- but quite/very slow

The script below works for me in MS Word. (Clear Formatting of selection)

set theApp to "Microsoft Word"
tell application theApp
	activate
	tell application "System Events" to tell process theApp to tell menu bar 1
		get name of menu bar items
		click menu item 1 of menu 1 of menu item 12 of menu 1 of menu bar item 4
	end tell
end tell 

AppleScript: 2.3(118)
Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)

Same comment.
I never used the pick function in my numerous scripts triggering menu items.

Yvan KOENIG (VALLAURIS, France) lundi 5 avril 2010 19:44:31

Folks-

Having trouble with this script. It does not error out, but it doesn’t open a panel either. If I pass it a string NOT corresponding to an existing panel, it throws an error.

tell application "System Events"
	tell process "Adobe InDesign CS3"
		activate
		tell menu bar 1
			tell menu bar item "File"
				click
				tell menu 1
					tell menu item "New"
						click
						tell menu 1
							tell menu item "EasyCatalog Panel..."
								click
								tell menu 1
									click menu item "Adv_TurnoverRate.txt"
								end tell
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

Any ideas?

thanks,

Ralph

I’m trying to script that ugly little critter called “Cell Styles” which is a panel window that pops up after you click on “Cell Styles” of “Type & Tables” of “Window” of the main menu.

I took your suggestion and used System Events to get to the first “Cell Styles” menu.

Problem is, how do you get the script to jump to the new “Cell Styles” panel menu that just popped up.

you don’t need system events to script styling.

to make a cell style:


tell application "Adobe InDesign CS3"
	tell document 1
		set Instructions_Cell_Style to make new cell style with properties {name:"Instructions", bottom edge stroke weight:0.0, left edge stroke tint:100.0, left edge stroke weight:0.5, right edge stroke tint:100.0, right edge stroke weight:0.5, top edge stroke tint:100.0, top edge stroke weight:0.5, vertical justification:top align, fill color:color id ColorBlack, fill tint:0.0, bottom inset:0.0, left inset:0.0, right inset:0.0, top inset:0.0625}
		tell Instructions_Cell_Style
			set applied paragraph style to "Instructions"
		end tell
	end tell
end tell

to apply a cell style:


to applyCellStyle(theproperties, theTable, theCoordinates) --				({coordinates:{1, 1}, whichTable:myTable, dimensions:{1.5938, 1}, styleName:"Instructions"})
	tell application "Adobe InDesign CS3"
		tell cell id theCoordinates of theTable
			set properties to theproperties
		end tell
	end tell
end applyCellStyle

-Ralph

Thanks for advice to get me started on this.

I’m trying to open a dialog box of a plugin that resizes pages dynamically. I’ve written this sequence that works when activated from outside ID CS4 in the AS editor but when placed in the InDesign Scripts folder, it fails. I’m assuming it fails because if it’s in the ID scripts folder, it must stay in InDesign and this script accesses the “System Events” app.

I’d like to have this in the scripts folder so I can assign a shortcut key to it. I’m stumped. Can anyone give advice?

activate application "Adobe InDesign CS4"

tell application "System Events"
	tell process "Adobe InDesign CS4"
		tell menu bar 1
			tell menu bar item "Window"
				pick
				tell menu 1
					tell menu item "Dynamic Resize"
						pick
						tell menu 1
							pick menu item "Resize Document"
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

Model: Mac Pro
AppleScript: 2.1.2
Browser: Firefox 6.0.2
Operating System: Mac OS X (10.6)