is displayed in the editors’ result window, but I can’t convert it to a string.
Any ideas?
{menu bar item “Apple” of menu bar 1 of application process “Glyphs” of application “System Events”, menu “Apple” of menu bar item “Apple” of menu bar 1 of application process “Glyphs” of application “System Events”, menu item “About This Mac” of menu “Apple” of menu bar item “Apple” of menu bar 1 of application process “Glyphs” of application “System Events”, menu item “System Information…” of menu “Apple” of menu bar item “Apple” of menu bar 1 of application process “Glyphs” of application “System Events”, menu item 3 of menu “Apple” of menu bar item “Apple” of menu bar 1 of application process “Glyphs” of application “System Events”, menu item “System Preferences…, 1 update” of menu “Apple” of menu bar item “Apple” of menu bar 1 of application process “Glyphs” of application “System Events”, menu item “Location” of menu “Apple” of menu bar item “Apple” of menu bar 1 of application process “Glyphs” of application “System Events”, menu “Location” of menu item “Location” of menu “Apple” of menu bar item “Apple” of menu bar 1 of application process “Glyphs” of application “System Events”, menu item “----Wlan 2021” of menu “Location” of menu item “Location” of menu “Apple” of menu bar item “Apple” of menu bar 1 of application process “Glyphs” of application “System Events”, menu item “+++Ethernet 2021” of menu “Location” of menu item “Location” of menu “Apple” of menu bar item “Apple” of
One way I see is retrieving, then parsing the text info from error message.
property theClasses : {"«class pcap»", "«class mbar»", "«class mbri»", "«class menE»", "«class menI»"}
property textReferences : {"application process", "menu bar", "menu bar item", "menu", "menu item"}
tell application "System Events" to tell process "Finder" to tell menu bar 1
try
entire contents as text
on error errorMessage
set entireContentsAsText to text 13 thru -18 of errorMessage
end try
end tell
set ATID to AppleScript's text item delimiters
repeat with i from 1 to count theClasses
set entireContentsAsText to ¬
findAndReplaceInText(entireContentsAsText, item i of theClasses, item i of textReferences)
end repeat
set AppleScript's text item delimiters to ATID
return entireContentsAsText
on findAndReplaceInText(theText, theSearchString, theReplacementString)
set AppleScript's text item delimiters to theSearchString
set theTextItems to text items of theText
set AppleScript's text item delimiters to theReplacementString
set theText to theTextItems as string
end findAndReplaceInText
Your code relies heavily on the Script Editor document, so it doesn’t work as an application. As a script, it won’t work in another script editor either. It is better to not involve script editors at all. Only the examined process, and the AppleScript itself.
set AppleScript's text item delimiters to {"--> {", "}"}
set theLog to middle text item of theLog as text
That strips both the beginning and ending braces. I then write it to a text file and during that process, the quotes are de-escaped. This is good. Thanks again.
Even though this can’t be run as an application, I often run scripts from SE. When I’m trying to figure something out, I often want to compare sets of properties, or just review them, but it’s an awkward thing to do. With this though, I can easily save for a variety of objects (e.g. window, document, paragraph, word), or to continue with the OP’s menu bar example, for each menu’s ui elements. Maybe even collect them in a spreadsheet.
Basically, I see no point in viewing the structure of UI elements this way. Because the Script Debugger makes it easier to browse the structure of UI elements.
I see a great benefit in the ability to automatically determine the reference to the desired UI element using the Automator application. You click on a UI element of interest while recording (red button) in Automator is activated. Turn off the recording, and copy the reference that Automator graciously wrote down for you…
Automator will record any of your manual actions. To view the recorded action as a script, you drag the action to the “Drag actions or files here to…” area. I know that many users do not even know that this is possible. Therefore, I think that my post will be quite useful.
Here, the Automator graciously wrote my 3 manual actions. Then I dragged “Click the “File” menu” action to the “Drag actions or files here to…” area. Especially for users, I have highlighted (in blue) a reference for copying.
I have used this method on occasion and it is a useful tool to have. But for me, when I’m trying to learn something, I like to be able to see things at varying resolutions. At one end, ‘every ui element’ can be overwhelming (but is still useful to have). At the other end, ‘set uiscript’ is too narrow. It involves an awkward process and provides too sparse results… a single click will generate a clumsy, 20-line script. It takes just a handful of clicks to scroll off the screen. And given the clutter it generates, it is nigh on impossible to compare results.
You are right, the result of “entire contents” is not perfect. But I need an overview of all menu entries. And doing it with an iteration is really slow.
If someone has a solution to get all menu entries (including short cuts (AXMenuItemCmdChar & AXMenuItemCmdModifiers) in a list without waiting a looong time for the return, this would be great.
You cannot avoid iterations for 3 reasons: 1) retrieving menu items is a recursive process, 2) not all menu items have names, for example, dividing lines, 3) not all menu items have a keyboard shortcut.
With this in mind, you can get the names of menu items that have a keyboard shortcut and the keyboard shortcuts themselves, in the following recursive way:
-- Get shorcuts of menu items of application
property appProcessName : "Finder"
property entireMenuItems : ""
property modifierCombinations : {"Command", "Command + Shift", "Command + Option", "Command + Shift + Option", "Command + Option", "Command + Control", "Command + Option + Control", "Command + Option + Control + Shift"}
-- optional code line
tell application "TextEdit" to make new document with properties {name:"Menu Items Shortcuts"}
tell application "System Events" to tell process appProcessName
-- except of "Apple" menu bar item (if need)
-- otherway, set menuBarItems to menu bar items of menu bar 1
set menuBarItems to menu bar items 2 thru -1 of menu bar 1
repeat with menuBarItem in menuBarItems
my recurseMenuItems(menuBarItem)
end repeat
end tell
return entireMenuItems
on recurseMenuItems(anUIElement)
tell application "System Events" to tell process appProcessName
set uiElements to UI elements of anUIElement
repeat with uiElement in uiElements
set menuItems to menu items of uiElement
repeat with menuItem in menuItems
try
set cmdChar to value of attribute "AXMenuItemCmdChar" of menuItem
on error
set cmdChar to missing value
end try
if cmdChar is missing value then
-- do nothing
else
set entireMenuItems to entireMenuItems & title of menuItem & linefeed
set cmdModifiers to value of attribute "AXMenuItemCmdModifiers" of menuItem
set cmdModifiers to item (cmdModifiers + 1) of modifierCombinations
set entireMenuItems to entireMenuItems & cmdModifiers & " + \"" & cmdChar & "\""
set entireMenuItems to entireMenuItems & linefeed & linefeed
my addToTextDocument(entireMenuItems) -- optional
end if
end repeat
my recurseMenuItems(uiElement)
end repeat
end tell
end recurseMenuItems
on addToTextDocument(theText) -- optional handler
tell application "TextEdit"
activate
set text of document 1 to theText
delay 0.1
end tell
end addToTextDocument