Add Comment to selected tracks (Pro Tools)
Hi again,
trying my best to work things out before coming to you guys, but the learning curve is slow! haha
I want to make it so that I can select a group of audio tracks and with a macro, add "KICKS" etc. to the comment, I have worked out just the simple add comment to track macro but a little lost on how to execute the idea!
cheers
- OOwen Granich-Young @Owen_Granich_Young
I messed around this with this script : Copy track name and paste to PT scribble strip...
Was able to modify it so it asks for comments then fills in the selected tracks. It will replace whatever is there...
function setComments() { sf.ui.proTools.appActivateMainWindow() sf.ui.proTools.invalidate() var commentToFill = sf.interaction.displayDialog({ title: "Comment", prompt: "Enter Comments", defaultAnswer: "" }).text //Get selected Tracks const selectedTracks = sf.ui.proTools.selectedTrackHeaders //Scrool to view first track selectedTracks[0].trackScrollToView() // Open rename window selectedTracks[0].popupButtons.first.mouseClickElement({ clickCount: 2 }) // Wait for rename window sf.ui.proTools.windows.whoseTitle.is(selectedTracks[0].popupButtons.first.value.invalidate().value).first.elementWaitFor(); //Get the elements of text fields and buttons const [trackName, comments] = sf.ui.proTools.focusedWindow.invalidate().textFields.map(x => x) const [ok, cncl, pr, next] = sf.ui.proTools.focusedWindow.buttons.map(x => x) // Loop all tracks for (let i = 0; i < selectedTracks.length; i++) { let newCommments = commentToFill // Set track name in Comments { comments.elementSetTextFieldWithAreaValue({ value: newCommments }); sf.wait({ intervalMs: 5 }) }; // If its the last track press ok, else press next if (i === selectedTracks.length - 1) { ok.elementClick() } else { next.elementClick() }; }; }; setComments();
- OOwen Granich-Young @Owen_Granich_Young
Hides pesky floating windows and then puts them back now :
function setComments() { sf.ui.proTools.appActivateMainWindow() sf.ui.proTools.invalidate() var commentToFill = sf.interaction.displayDialog({ title: "Comment", prompt: "Enter Comments", defaultAnswer: "" }).text //Get selected Tracks const selectedTracks = sf.ui.proTools.selectedTrackHeaders //Scrool to view first track selectedTracks[0].trackScrollToView() // Open rename window selectedTracks[0].popupButtons.first.mouseClickElement({ clickCount: 2 }) // Wait for rename window sf.ui.proTools.windows.whoseTitle.is(selectedTracks[0].popupButtons.first.value.invalidate().value).first.elementWaitFor(); //Get the elements of text fields and buttons const [trackName, comments] = sf.ui.proTools.focusedWindow.invalidate().textFields.map(x => x) const [ok, cncl, pr, next] = sf.ui.proTools.focusedWindow.buttons.map(x => x) // Loop all tracks for (let i = 0; i < selectedTracks.length; i++) { let newCommments = commentToFill // Set track name in Comments { comments.elementSetTextFieldWithAreaValue({ value: newCommments }); sf.wait({ intervalMs: 5 }) }; // If its the last track press ok, else press next if (i === selectedTracks.length - 1) { ok.elementClick() } else { next.elementClick() }; }; }; function setupAndRestore(callback) { sf.ui.proTools.appActivateMainWindow(); const videoWinowMenuItem = sf.ui.proTools.getMenuItem('Window', 'Video'); const initialViews = { isVideoWinOpen: videoWinowMenuItem.getString('AXMenuItemMarkChar') === ('-') || videoWinowMenuItem.isMenuChecked, isFloatingWindowsEnabled: sf.ui.proTools.getMenuItem('Window', 'Hide All Floating Windows').isMenuChecked, } const { isVideoWinOpen, isFloatingWindowsEnabled } = initialViews; if (isVideoWinOpen) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Video'], }); } if (!isFloatingWindowsEnabled) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Hide All Floating Windows'], }); } try { callback(); } finally { const modifiedViews = { isVideoWinOpen: (videoWinowMenuItem.getString('AXMenuItemMarkChar') === ('-') || videoWinowMenuItem.isMenuChecked) !== initialViews.isVideoWinOpen, isFloatingWindowsEnabled: sf.ui.proTools.getMenuItem('Window', 'Hide All Floating Windows').isMenuChecked !== initialViews.isFloatingWindowsEnabled, } const { isVideoWinOpen, isFloatingWindowsEnabled } = modifiedViews; if (isVideoWinOpen) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Video'], }); } if (isFloatingWindowsEnabled) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Hide All Floating Windows'], }); } } } function main() { setupAndRestore(() => { setComments(); }); } main();
- MMatt Cahill @Matt_Cahill
Owen you absolute beast, this is perfect! thank you!!
- OOwen Granich-Young @Owen_Granich_Young
Nah, I'm just standing on the shoulders of giants. This is all @samuel_henriques I just modified his work.
- MMatt Cahill @Matt_Cahill
Well it is very good! I have run into a problem though, when I select a load of tracks that are separated by an AUX, it doesn't pick up the spacing properly and just applies it to the same amount of tracks, to if the AUXs were not there, here is a quick screen record, I hope it explains!
- OOwen Granich-Young @Owen_Granich_Young
Makes perfect sense. I've re-done it to account for this. It's not as snappy as @samuel_henriques original code this way, but it does only do the actual tracks selected.
As to your below issue I'm pretty sure you have something triggering your main deck when protools becomes active. My bud had a similar thing and tracked it down. Often when you setup soundflow it will default to include an activate protools main deck on focus trigger. Hunt around in your default package you may be able to find it. Look for a 'Show Protools Deck' macro trigger. That's what it was for him.
function setupAndRestore(callback) { sf.ui.proTools.appActivateMainWindow(); const videoWinowMenuItem = sf.ui.proTools.getMenuItem('Window', 'Video'); const initialViews = { isVideoWinOpen: videoWinowMenuItem.getString('AXMenuItemMarkChar') === ('-') || videoWinowMenuItem.isMenuChecked, isFloatingWindowsEnabled: sf.ui.proTools.getMenuItem('Window', 'Hide All Floating Windows').isMenuChecked, } const { isVideoWinOpen, isFloatingWindowsEnabled } = initialViews; if (isVideoWinOpen) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Video'], }); } if (!isFloatingWindowsEnabled) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Hide All Floating Windows'], }); } try { callback(); } finally { const modifiedViews = { isVideoWinOpen: (videoWinowMenuItem.getString('AXMenuItemMarkChar') === ('-') || videoWinowMenuItem.isMenuChecked) !== initialViews.isVideoWinOpen, isFloatingWindowsEnabled: sf.ui.proTools.getMenuItem('Window', 'Hide All Floating Windows').isMenuChecked !== initialViews.isFloatingWindowsEnabled, } const { isVideoWinOpen, isFloatingWindowsEnabled } = modifiedViews; if (isVideoWinOpen) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Video'], }); } if (isFloatingWindowsEnabled) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Hide All Floating Windows'], }); } } } function doForAllSelectedTracks(action) { var originallySelectedTrackNames = sf.ui.proTools.selectedTrackNames; try { sf.ui.proTools.selectedTrackHeaders.forEach(track => { track.trackSelect(); action(track); }); } finally { sf.ui.proTools.trackSelectByName({ names: originallySelectedTrackNames }); } } function setComments() { sf.ui.proTools.appActivateMainWindow() sf.ui.proTools.invalidate() var commentToFill = sf.interaction.displayDialog({ title: "Comment", prompt: "Enter Comments", defaultAnswer: "" }).text //Get selected Tracks const selectedTracks = sf.ui.proTools.selectedTrackHeaders //Scrool to view first track selectedTracks[0].trackScrollToView() function trackFunc(track) { sf.ui.proTools.selectedTrack.titleButton.mouseClickElement({ clickCount: 2 }); // Wait for rename window sf.ui.proTools.windows.first.children.whoseRole.is("AXStaticText").whoseValue.is("Comments:").first.elementWaitFor(); //Get the elements of text fields and buttons const [trackName, comments] = sf.ui.proTools.focusedWindow.invalidate().textFields.map(x => x) const [ok, cncl, pr, next] = sf.ui.proTools.focusedWindow.buttons.map(x => x) let newCommments = commentToFill // Set track name in Comments comments.elementSetTextFieldWithAreaValue({ value: newCommments }); sf.wait({ intervalMs: 5 }) ok.elementClick() } doForAllSelectedTracks(trackFunc); } setupAndRestore(() => { setComments(); });
Jordan Pascual @Jordan_Pascual
Hey Owen, ya wonderful human. Unfortunately, this current code is throwing an error at line 69 (teehee), and I believe this is because ProTools switched the way Line 66 works... I've tried it with this on Line 66 instead...
sf.ui.proTools.selectedTrack.trackOpenRenameDialog();
Is that the best way to do this as of PT 2023.3.1 ?
- In reply toOwen_Granich_Young⬆:MMatt Cahill @Matt_Cahill
Also, I am implementing this code as part of a larger deck, that has a main Home screen. This code is a tool on a sub deck called "Bounce" just off the home screen, the problem is, once I have entered the label and it's been pasted, every time it kicks back to the home screen (as opposed to remaining on the current deck) and I have to go back into the "Bounce" screen to do it again, any ideas?