How do I copy and paste PT menu paths so that I don't have to type and miscapitalize
I hate to type and I'm lazy. How do I copy and paste PT menu paths so that I don't have to type and miscapitalize the paths?
Linked from:
- samuel henriques @samuel_henriques
Hello @John_Morris,
This should help you with your problem :).
To get all menu and submenu from popups:
Open the log:
and clear it, so it's easier to read the information:
Using a macro, use the action "Fetch All Items from Popup Menu" and pick the popup you want. In this example, I'm using the "Clip List" popup.
Create a new script and paste this script:
function getPopupMenuItems(popup) { // Get the popup items let popupMenuItems = popup.menuItems.map(x => x.path) //Activate Pro tools to dismiss the popup sf.ui.proTools.appActivateMainWindow() log(popupMenuItems) } //Activate Pro tools sf.ui.proTools.appActivateMainWindow() getPopupMenuItems( //==// Paste code from element between the //==//. REMEMBER TO DELETE THE LAST ; //==// )
now, go back to the macro and copy the action as Javascript:
And paste it on the script I sent you between the //==//. MAKE SURE YOU DELETE THE LAST ;
once you run the script, you will get all the menu and submenus:
From there you can copy the text to paste somewhere else.
samuel henriques @samuel_henriques
To get a list from menus,:
setup the log the same way.
menus work a bit differently. The way this script work, you need to type the menu name to get its items. Sorry but one word only.sf.ui.proTools.appActivateMainWindow() let menuItems = sf.ui.proTools.getMenuItem("Edit").children.first.children.map(c => c.title.value) log(menuItems)
When you run the script you'll get the first page.
Then you can copy the submenu name you want, Lets use "Automation" and add it to the script like so:
sf.ui.proTools.appActivateMainWindow() let menuItems = sf.ui.proTools.getMenuItem("Edit", "Automation").children.first.children.map(c => c.title.value) log(menuItems)
and now you have all the items from the submenu:
Hope this helps, let me know how it goes
- JJohn Morris @John_Morris7
Thanks, Samuel!
samuel henriques @samuel_henriques
Hello everyone, here's a little tool to ease writing of menu paths:
This is for menus only, not popupMenus and should work on any app.Use with a trigger while app is focussed.
Let me know how it works.
function prompt(item) { let ptMenuAllPrompt = sf.interaction.popupSearch({ items: item.map(x => ({ name: x })) }).item.name return ptMenuAllPrompt } /** * @param {array} path */ function menuPathPrompt(path) { let pathPrompt = sf.interaction.displayDialog({ buttons: ["Cancel", "Copy Path to Action", "Copy Path to Clipboard"], defaultButton: "Copy Path to Clipboard", cancelButton: "Cancel", title: "Menu Path Tool", prompt: path.map(function (item) { return "\"" + item + "\"" }).join(', '), }).button // Copy to Clipboard if (pathPrompt == "Copy Path to Clipboard") { sf.clipboard.setText({ text: path.map(function (item) { return "\"" + item + "\"" }).join(', '), }) } // Copy to Macro Action if (pathPrompt == "Copy Path to Action") { // Activate SoundFlow sf.ui.app("org.soundflow.sfsx.gui").appActivate() // Coundn't avoid this wait sf.wait({ intervalMs: 500 }) path.forEach(p => { sf.clipboard.setText({ text: p }); sf.ui.frontmostApp.menuClick({ menuPath: ['Edit', 'Paste'] }); sf.keyboard.press({ keys: 'return' }); }); } } const activeAppBundleID = sf.ui.frontmostApp.activeBundleID; // Array of Main Menu Items const mainMenuItems = sf.ui.app(activeAppBundleID).children.whoseRole.is("AXMenuBar").first.children.whoseRole.is("AXMenuBarItem").map(x => x.title.value) // Choose Main Menu Item const mainMenuItemsPrompt = prompt(mainMenuItems) // Array of Menu Items const menuItems = sf.ui.app(activeAppBundleID).getMenuItem(mainMenuItemsPrompt).children.first.children.map(c => c.title.value).filter(x => x) // Choose Menu Item const menuItemsPrompt = prompt(menuItems) // Array of Sub-Menu Items const subMenuItems = sf.ui.app(activeAppBundleID).getMenuItem(mainMenuItemsPrompt, menuItemsPrompt).children.first.children.map(c => c.title.value).filter(x => x) // If no Sub-Menu Exists if (subMenuItems.length == 0) { // Show Path menuPathPrompt([mainMenuItemsPrompt, menuItemsPrompt]) } else { // Choose Sub-Menu Item let subMenuItemsPrompt = prompt(subMenuItems) // Array of Sub2-Menu Items const subMenu2Items = sf.ui.app(activeAppBundleID).getMenuItem(mainMenuItemsPrompt, menuItemsPrompt, subMenuItemsPrompt).children.first.children.map(c => c.title.value).filter(x => x) // If no Sub2-Menu Exists if (subMenu2Items.length == 0) { // Show Path menuPathPrompt([mainMenuItemsPrompt, menuItemsPrompt, subMenuItemsPrompt]) } else { // Choose Sub2-Menu Item const subMenu2ItemsPrompt = prompt(subMenu2Items) // Show Path menuPathPrompt([mainMenuItemsPrompt, menuItemsPrompt, subMenuItemsPrompt, subMenu2ItemsPrompt]) } }
samuel henriques @samuel_henriques
and here's a version for Popup menus.
Pick your element and paste de code on mu script between the //==//, REMEMBER TO DELETE THE LAST ;
/** * @param {array} path */ function menuPathPrompt(path) { let pathPrompt = sf.interaction.displayDialog({ buttons: ["Cancel", "Copy Path to Action", "Copy Path to Clipboard"], defaultButton: "Copy Path to Clipboard", cancelButton: "Cancel", title: "Popup Menu Path Tool", prompt: path.map(function (item) { return "\"" + item + "\"" }).join(', '), }).button // Copy to Clipboard if (pathPrompt == "Copy Path to Clipboard") { sf.clipboard.setText({ text: path.map(function (item) { return "\"" + item + "\"" }).join(', '), }) } // Copy to Macro Action if (pathPrompt == "Copy Path to Action") { // Activate SoundFlow sf.ui.app("org.soundflow.sfsx.gui").appActivate() // Coundn't avoid this wait sf.wait({ intervalMs: 500 }) path.forEach(p => { sf.clipboard.setText({ text: p }); sf.ui.frontmostApp.menuClick({ menuPath: ['Edit', 'Paste'] }); sf.keyboard.press({ keys: 'return' }); }); } } function prompt(item) { let ptMenuAllPrompt = sf.interaction.popupSearch({ items: item.map(x => ({ name: x })) }).item.name return ptMenuAllPrompt } function onlyUnique(value, index, self) { return self.indexOf(value) === index; } function getPopupMenuItems(popup) { // Get the popup items const popupMenuItems = popup.menuItems.map(x => x.path) // Array of First Menu Items let firstMenu = popupMenuItems.map(x => x[0]).filter(onlyUnique); // Choose Menu Item const firstMenuPrompt = prompt(firstMenu) // Array of Second Menu Items const secondMenu = popup.menuItems.filter(x => x.path[0] == firstMenuPrompt).map(x => x.path[1]).filter(onlyUnique); if (secondMenu.length == 0 || secondMenu[0] == null) { // Show Path menuPathPrompt([firstMenuPrompt]) } else { // Choose Menu Item const secondMenuPrompt = prompt(secondMenu) // Array of Third Menu Items const thirdMenu = popup.menuItems.filter(x => x.path[0] == firstMenuPrompt).filter(x => x.path[1] == secondMenuPrompt).map(x => x.path[2]).filter(onlyUnique); if (thirdMenu.length == 0 || thirdMenu[0] == null) { // Show Path menuPathPrompt([firstMenuPrompt, secondMenuPrompt]) } else { // Choose Menu Item const thirdMenuPrompt = prompt(thirdMenu) // Array of Fourth Menu Items const fourthMenu = popup.menuItems.filter(x => x.path[0] == firstMenuPrompt).filter(x => x.path[1] == secondMenuPrompt).filter(x => x.path[2] == thirdMenuPrompt).map(x => x.path[3]).filter(onlyUnique); if (fourthMenu.length == 0 || fourthMenu[0] == null) { // Show Path menuPathPrompt([firstMenuPrompt, secondMenuPrompt, thirdMenuPrompt]) } else { // Choose Menu Item const fourthMenuPrompt = prompt(fourthMenu) // Show Path menuPathPrompt([firstMenuPrompt, secondMenuPrompt, thirdMenuPrompt, fourthMenuPrompt]) } } } } getPopupMenuItems( //==// Paste code from "Fech All Items From Popup Menu" element between the //==//. REMEMBER TO DELETE THE LAST ; //==// //Paste Action Code Here, REMEMBER TO DELETE THE LAST ; //==// //==// )
- In reply tosamuel_henriques⬆:
samuel henriques @samuel_henriques
UPDATE: you can now paste the path to the macro action.
Both Popup Menu Script and Menu Script have this function.Select the area you want the paste the path
Now activate the app you want to the the path from, in this case activate safari.
Then run the code with a trigger.
and choose "Copy Path to Action"
- FFukurou Toshima @Fukurou_Toshima
Hi samuel,
I wonder if I can copy ALL names of AAX plugins currently installed as it is displayed on the pop up menu on Pro Tools and make the lists of them not to miscapitalize.
Im setting up my presets for Teezio Plugin Loader but I have a plenty of plugins so it is not impractical to go back and forth between soundflow edit window and Pro Tools pop up menu.
It helps so much if there is the plugin name list as a kind of text file.
So if I use the script in this thread, which point do you think is right place to capture to obtain all names of the plugins?
- In reply toJohn_Morris⬆:Kitch Membery @Kitch2021-04-21 21:31:44.909Z
@samuel_henriques beat me to it but here is similar way,
sf.ui.proTools.appActivateMainWindow(); const proToolsMenuNames = sf.ui.proTools.childrenByRole('AXMenuBar').map(x => x.children.map(m => ({ menu: m.title.invalidate().value, menuItems: m.children.map(mi => mi.children.map(i=>i.title.invalidate().value).filter(i=>i))[0], }))); sf.file.writeJson({ path:'~/Desktop/Pro Tools Menu Items', json:proToolsMenuNames });
Run this script and it will create a JSON file on your desktop named "Pro Tools Menu Items" that has all the menu items. Open it with the text edit application and copy and paste away :-)
- JJohn Morris @John_Morris7
Thanks Kitch! It's clear you are a lazy man too!
Kitch Membery @Kitch2021-04-21 21:54:34.812Z
Hahahaha :-)
And a bad speller!
Rock on!
- In reply toKitch⬆:
samuel henriques @samuel_henriques
Nice one @Kitch, thank you!
Kitch Membery @Kitch2021-04-21 21:56:34.331Z
@samuel_henriques & @John_Morris7,
Come to think of it my method only gets one menu Item deep. I'll take a look at it over the next few days and see if I can make it dig deeper :-)
- JIn reply toJohn_Morris⬆:Jonathan Johnson @Jonathan_Johnson
hey looking at this thread, i am opening the log file ( see top of the thread) , but after i clear it , the log starts logging info immediately to the point that the page is filed in about 2 sec,
Im understanding the point here is to clear the log filets a move and copy, but the log file is auto updating very fast. seem off...