I was wondering how to ensure that All groups are suspended. I got as far as ensuring the Goups Window is open an clicking "Suspend All Groups" but trying to set to 'Enable' doesn't seem to work if Suspend All groups is already enabled - if it is I want the script to do nothing.
here's what I've come up with so far
sf.ui.proTools.groupsEnsureGroupListIsVisible();
var groupListPopup = sf.ui.proTools.groupsOpenListPopupMenu().popupMenu;
groupListPopup.menuClickPopupMenu({
menuPath: ["Suspend All Groups"],
targetValue: 'Enable'
});
- Christian Scheuer @chrscheuer2020-04-24 10:06:20.939Z
It appears to work - almost - here, in that if Suspend All Groups is already enabled, the script doesn't click it.
However, the script only knows that Suspend All Groups is already enabled after it has opened the popup menu. It doesn't care to dismiss the popup menu afterwards if it didn't need to click it (which you can argue is kind-of a bug).You can work around this by inserting an
appActivateMainWindow
call after the popup call though, which then in the case where the groups are already suspended, will just trigger a short flicker of the popup menu.So in total, your script would be:
sf.ui.proTools.groupsEnsureGroupListIsVisible(); var groupListPopup = sf.ui.proTools.groupsOpenListPopupMenu().popupMenu; groupListPopup.menuClickPopupMenu({ menuPath: ["Suspend All Groups"], targetValue: 'Enable' }); sf.ui.proTools.appActivateMainWindow();
- In reply toChris_Shaw⬆:Chris Shaw @Chris_Shaw2020-04-24 17:07:42.874Z
Follow up question.
I would like to query the status of Suspend All Groups and store it's state into a variable before turning it on or off so that when my script completes I can return Suspend All Groups to the state it was in before the script was run.Christian Scheuer @chrscheuer2020-04-24 17:11:18.062Z
Then you'd do like this:
The
menuClickPopupMenu
action returns a propertymenuWasClicked
that tells you whether or not the action needed to click the menu item to get to the desiredtargetValue
.Inside the
finally
block I'm then checking to see, if the menu was clicked, it should be clicked again, this time disregarding any targetValue.The
try/finally
block is there to make sure that even if the script fails inside thetry
block, it's always gonna run thefinally
block, and so even upon a failure, the Suspend state should be returned to normal.sf.ui.proTools.groupsEnsureGroupListIsVisible(); var groupListPopup = sf.ui.proTools.groupsOpenListPopupMenu().popupMenu; var menuWasClicked = groupListPopup.menuClickPopupMenu({ menuPath: ["Suspend All Groups"], targetValue: 'Enable' }).menuWasClicked; sf.ui.proTools.appActivateMainWindow(); try { //Do something with groups suspended... } finally { if (menuWasClicked) { groupListPopup.menuClickPopupMenu({ menuPath: ["Suspend All Groups"] }); } }
Christian Scheuer @chrscheuer2020-04-24 17:12:50.936Z
Note, this can be made into a reusable function, which is probably how I would use it:
function doWithGroupsSuspended(callback) { sf.ui.proTools.groupsEnsureGroupListIsVisible(); var groupListPopup = sf.ui.proTools.groupsOpenListPopupMenu().popupMenu; var menuWasClicked = groupListPopup.menuClickPopupMenu({ menuPath: ["Suspend All Groups"], targetValue: 'Enable' }).menuWasClicked; sf.ui.proTools.appActivateMainWindow(); try { callback(); } finally { if (menuWasClicked) { groupListPopup.menuClickPopupMenu({ menuPath: ["Suspend All Groups"] }); } } } doWithGroupsSuspended(function(){ //Do stuff here... });
Chris Shaw @Chris_Shaw2020-04-24 17:26:30.071Z
Off to JavaScript school to wrap my head around this. :)
Thanks!Christian Scheuer @chrscheuer2020-04-24 17:29:39.454Z
Haha yea :)
If I haven't already linked you there, make sure to check this:
https://soundflow.org/docs/how-to/custom-commands/javascript-resources
- In reply tochrscheuer⬆:
Jack Green @Jack_Green
So im trying to adapt this to work with the Link Track and Edit Selection option in the options menu. I want to make sure it's enabled but then return it to its original state. Ive tried to adapt your code but fear i have made a mess of it...
var trackClipLink = sf.ui.proTools.menuClick ({"Options"}); var menuWasClicked = trackClipLink.menuClick({ menuPath: ["Link Track and Edit Selection"], targetValue: 'Enable' }).menuWasClicked; sf.ui.proTools.appActivateMainWindow(); try { //Do something with groups suspended... } finally { if (menuWasClicked) { groupListPopup.menuClickPopupMenu({ menuPath: ["Suspend All Groups"] }); } }
Thanks
Jack !
- In reply toChris_Shaw⬆:Chris Shaw @Chris_Shaw2020-04-24 19:44:33.194Z
Hmm, I'm getting an error when trying to implement either of these two methods.
I'm just inserting a simplesf.ui.proTools.menuClick({ menuPath: ["Edit", "Copy"],
function where you have//Do stuff here...
in the script
It works fine when the script is executed with Suspend All Groups inactive but if Suspend All groups is active when the script is run it throws "kAXErrorInvalidUIElement" error at thegroupListPopup.menuClickPopupMenu
line under thefinally
routine.Kitch Membery @Kitch2020-11-10 22:40:43.012Z
Hi @chrscheuer,
I've been trying to use the
doWithGroupsSuspended
callback function as a part of a larger script;function doWithGroupsSuspended(callback) { sf.ui.proTools.groupsEnsureGroupListIsVisible(); var groupListPopup = sf.ui.proTools.groupsOpenListPopupMenu().popupMenu; var menuWasClicked = groupListPopup.menuClickPopupMenu({ menuPath: ["Suspend All Groups"], targetValue: 'Enable' }).menuWasClicked; sf.ui.proTools.appActivateMainWindow(); try { callback(); } finally { if (menuWasClicked) { groupListPopup.menuClickPopupMenu({ menuPath: ["Suspend All Groups"], }); } } } doWithGroupsSuspended(function () { log('Test Log'); });
But I get this error;
10.11.2020 14:27:55.63 <info> [Backend]: #Key: ctrl+x (7) -> TEST SCRIPT [ckhci226h0005wq10g46xe1kp] 10.11.2020 14:27:55.63 <info> [Backend]: >> Command: TEST SCRIPT [user:ckgsisa950009c110xlamn0jq:ckh3rxrhz000aw610yf08ycy2#ckh3rcyxr0005w610trwlwksj] 10.11.2020 14:27:55.71 <info> [Backend]: Clicking with mouse here: 219, 1112 10.11.2020 14:27:55.86 <info> [Backend]: PopupMenu full role:AXMenu 10.11.2020 14:27:55.86 <info> [Backend]: Clicking popup menu element: Suspend All Groups 10.11.2020 14:27:56.28 <info> [Backend]: Clicking with mouse here: 72, 30 10.11.2020 14:27:56.31 <info> [Backend]: [LOG] Test 10.11.2020 14:27:57.06 <info> [Backend]: Logging unknown error in action (02) ClickPopupMenuAction: kAXErrorInvalidUIElement Logging unknown error in action (02) RunCommandAction: Setup: Track Name to Comments: Line 117 !! Command Error: TEST SCRIPT [user:ckgsisa950009c110xlamn0jq:ckh3rxrhz000aw610yf08ycy2#ckh3rcyxr0005w610trwlwksj]: kAXErrorInvalidUIElement (Setup: Track Name to Comments: Line 117) SoundFlow.Shortcuts.AXUIElementException: kAXErrorInvalidUIElement at SoundFlow.Shortcuts.AXUIElement.GetSubElements(String) + 0x1a5 at SoundFlow.Shortcuts.AXUIElement.GetPopupMenuPathRecursive(String[], List`1, Boolean&, Boolean) + 0x447 at SoundFlow.Shortcuts.AXUIElement.GetPopupMenuPath(Boolean, String[]) + 0x4f at SoundFlow.Shortcuts.Automation.Actions.ClickPopupMenuAction.<Execute>d__16.MoveNext() + 0x69 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x1c at sfbackend!<BaseAddress>+0x168260b at sfbackend!<BaseAddress>+0x1682546 at SoundFlow.Shortcuts.Automation.AutoAction`1.<Run>d__20.MoveNext() + 0x317 << Command: TEST SCRIPT [user:ckgsisa950009c110xlamn0jq:ckh3rxrhz000aw610yf08ycy2#ckh3rcyxr0005w610trwlwksj]
Any thoughts on how to get around this?
Note: The error only occurs when "Suspend All Groups" is checked in the "Groups List Popup Menu" prior to running the script.
Thanks in advance!
Kitch Membery @Kitch2020-11-10 23:05:51.308Z
I think I've figured it out. I'll report back with my workaround asap :-)
- In reply toKitch⬆:
Kitch Membery @Kitch2020-11-10 23:10:35.177Z2020-11-10 23:25:45.071Z
Boom! Fixed with some menu filtering :-)
function doWithGroupsSuspended(callback) { sf.ui.proTools.groupsEnsureGroupListIsVisible(); const groupListPopup = sf.ui.proTools.mainWindow.groupListPopupButton; var menuWasClicked = groupListPopup.popupMenuFetchAllItems().menuItems .filter(menuItem => menuItem.element.isMenuChecked) .filter(checkedItems => checkedItems.names.includes('Suspend All Groups')).length === 1; sf.ui.proTools.appActivateMainWindow(); if (!menuWasClicked) { groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], }); } try { callback(); } finally { if (!menuWasClicked) { groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], }); } } } doWithGroupsSuspended(function () { log('Test Log'); });
- In reply toChris_Shaw⬆:Brett Ryan Stewart @Brett_Ryan_Stewart
Hey @Kitch , @Chris_Shaw and @chrscheuer ! Just resurrecting this thread to see if I can implement it in to my macros..
Basically I want to do what Chris suggested, which is to Suspend All Groups (IF not already suspended), run the macro, then return Group status to the state it was before running.
I see this as javascript here, but I'm a macro builder and hoping someone could break it in to 1 or 2 pieces of code I can put at the beginning and ending of my action chain. If that's possible that would be ideal!
If not, here is the script version of my macros. Maybe we can just implement the code correctly in here?
Script one:sf.ui.proTools.mainWindow.elementRaise(); /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s") sf.soundflow.runCommand({ commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i', props: { viewInsertsAE: "Enable", viewInsertsFJ: "Enable", viewSendsAE: "Enable", viewSendsFJ: "Enable", } }); */ //Calling command "!Remove Inactive Inserts ONLY" from package "Default Package" sf.soundflow.runCommand({ commandId: 'package:ckyhvbsc10004tg10x77xsc1s', props: {} }); /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s") sf.soundflow.runCommand({ commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i', props: { viewInsertsAE: "Disable", viewInsertsFJ: "Disable", viewSendsAE: "Disable", viewSendsFJ: "Disable", } }); */
SCRIPT 2:
sf.ui.proTools.mainWindow.elementRaise(); /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s") sf.soundflow.runCommand({ commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i', props: { viewInsertsAE: "Enable", viewInsertsFJ: "Enable", viewSendsAE: "Enable", viewSendsFJ: "Enable", } }); */ //Calling command "!Remove Inactive SENDS " from package "Default Package" sf.soundflow.runCommand({ commandId: 'package:ckyhvcbiz0005tg101ttt6xeg', props: {} }); /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s") sf.soundflow.runCommand({ commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i', props: { viewInsertsAE: "Disable", viewInsertsFJ: "Disable", viewSendsAE: "Disable", viewSendsFJ: "Disable", } }); */
Kitch Membery @Kitch2022-04-17 19:11:44.839Z
I think I have a function that does this already... I'll take a look and get back to you. :-)
- In reply toBrett_Ryan_Stewart⬆:
Kitch Membery @Kitch2022-04-17 19:22:24.993Z
Hi Brett_Ryan_Stewart,
Untested, but this should do the trick...
function doWithGroupsSuspended(callback) { sf.ui.proTools.groupsEnsureGroupListIsVisible(); const groupListPopup = sf.ui.proTools.mainWindow.groupListPopupButton; var menuWasClicked = groupListPopup.popupMenuFetchAllItems().menuItems .filter(menuItem => menuItem.element.isMenuChecked) .filter(checkedItems => checkedItems.names.includes('Suspend All Groups')).length === 1; sf.ui.proTools.appActivateMainWindow(); if (!menuWasClicked) { //Toggle Suspend All Groups via Groups List Popup menu. groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], }); //Toggle Suspend All Groups with Keyboard Shortcut //sf.keyboard.press({ keys: "cmd+shift+g", }); } try { callback(); } finally { if (!menuWasClicked) { //Toggle Suspend All Groups via Groups List Popup menu. groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], }); //Toggle Suspend All Groups with Keyboard Shortcut //sf.keyboard.press({ keys: "cmd+shift+g", }); } } } function main() { sf.ui.proTools.mainWindow.elementRaise(); /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s") sf.soundflow.runCommand({ commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i', props: { viewInsertsAE: "Enable", viewInsertsFJ: "Enable", viewSendsAE: "Enable", viewSendsFJ: "Enable", } }); */ //Calling command "!Remove Inactive Inserts ONLY" from package "Default Package" sf.soundflow.runCommand({ commandId: 'package:ckyhvbsc10004tg10x77xsc1s', props: {} }); /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s") sf.soundflow.runCommand({ commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i', props: { viewInsertsAE: "Disable", viewInsertsFJ: "Disable", viewSendsAE: "Disable", viewSendsFJ: "Disable", } }); */ } doWithGroupsSuspended(() => { main(); });
You can apply this to your other script by replacing the contents of the
main
function with your code.Essentially what it does is runs all the code before the try section of the
doWithGroupsSuspended
then runs the callback (which is the main function), then finally once it completes that runs thefinally
block of thedoWithGroupsSuspended
function.I hope that helps.
Rock on!
Brett Ryan Stewart @Brett_Ryan_Stewart
@Kitch you're a wiz! Thank you, it's working great. What can be added to change the track height in Edit window to make all Insert / Send slots visible?
This full command is intended to remove all inactive plugins from selected tracks, but it's not working unless the track(s) is at a height where all slots are visible vertically.
This is the script so far:
function doWithGroupsSuspended(callback) { sf.ui.proTools.groupsEnsureGroupListIsVisible(); const groupListPopup = sf.ui.proTools.mainWindow.groupListPopupButton; var menuWasClicked = groupListPopup.popupMenuFetchAllItems().menuItems .filter(menuItem => menuItem.element.isMenuChecked) .filter(checkedItems => checkedItems.names.includes('Suspend All Groups')).length === 1; sf.ui.proTools.appActivateMainWindow(); if (!menuWasClicked) { //Toggle Suspend All Groups via Groups List Popup menu. groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], }); //Toggle Suspend All Groups with Keyboard Shortcut //sf.keyboard.press({ keys: "cmd+shift+g", }); } try { callback(); } finally { if (!menuWasClicked) { //Toggle Suspend All Groups via Groups List Popup menu. groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], }); //Toggle Suspend All Groups with Keyboard Shortcut //sf.keyboard.press({ keys: "cmd+shift+g", }); } } } function main() { sf.ui.proTools.mainWindow.elementRaise(); /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s") sf.soundflow.runCommand({ commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i', props: { viewInsertsAE: "Enable", viewInsertsFJ: "Enable", viewSendsAE: "Enable", viewSendsFJ: "Enable", } }); */ //Calling command "!Remove Inactive Inserts ONLY" from package "Default Package" sf.soundflow.runCommand({ commandId: 'package:ckyhvbsc10004tg10x77xsc1s', props: {} }); /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s") sf.soundflow.runCommand({ commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i', props: { viewInsertsAE: "Disable", viewInsertsFJ: "Disable", viewSendsAE: "Disable", viewSendsFJ: "Disable", } }); */ } doWithGroupsSuspended(() => { main(); });
Kitch Membery @Kitch2022-04-21 09:54:12.126Z
You can use a function like this to set all the track heights to medium :-)
function setTrackHeight(height) { sf.ui.proTools.appActivateMainWindow(); var f = sf.ui.proTools.selectedTrack.frame; var popupMenu = sf.ui.proTools.selectedTrack.popupMenuOpenFromElement({ relativePosition: { x: f.w - 10, y: 5 }, isOption: true, //isShift: true, }).popupMenu; popupMenu.menuClickPopupMenu({ menuPath: [height] }); } setTrackHeight("medium");
Brett Ryan Stewart @Brett_Ryan_Stewart
awesome thanks!!
- JIn reply toChris_Shaw⬆:Jonathan McPherson @Jonathan_McPherson
Hey guys, thanks for this post! I'm trying to use this with PT Studio 2024.6.0, to have a Suspend Groups button on my Stream Deck, but no luck here. Any chance you could revisit the code for it? Thank you!