Copy first clip name of selected tracks, to track name
By samuel henriques @samuel_henriques
Hello @Chris_Shaw and @Matt_Friedman,
here's my take on copy the name of the first clip on selected tracks to the track name.
It should dismiss repeated track names by appending the index of the selected track at the end of name
Works if within track selection there are tracks without any clip
Select a range of tracks or pick tracks.
Let me know how it's working.
function selectFirstClip() {
const returntoZero = () => sf.ui.proTools.mainWindow.groups.allItems[5].groups.first.buttons.whoseTitle.is("Return to Zero").first.elementClick();
const selectionHasClip = () => sf.ui.proTools.getMenuItem("Clip", "Edit Lock/Unlock").isEnabled
returntoZero()
// Need a maximum of 3x shift+tab. if there is a fade on first clip, need 3x tab
// Need to start with shift+tab in case a clip starts at 0 on the timeline
sf.keyboard.press({ keys: "shift+tab" });
if (!selectionHasClip()) { sf.keyboard.press({ keys: "shift+tab" }) }
if (!selectionHasClip()) { sf.keyboard.press({ keys: "shift+tab" }) }
return selectionHasClip()
}
function getClipName() {
if (selectFirstClip()) {
sf.ui.proTools.menuClick({ menuPath: ["Clip", "Rename..."] })
const renameWin = sf.ui.proTools.windows.whoseTitle.is("Name").first.elementWaitFor().element
const clipName = renameWin.groups.whoseTitle.is("Name").first.textFields.first.value.invalidate().value
renameWin.buttons.whoseTitle.is("Cancel").first.elementClick();
renameWin.elementWaitFor({ waitType: "Disappear" })
return clipName
}
}
function getTrackClipList() {
const originalTracks = sf.ui.proTools.selectedTrackHeaders;
let trackClipList = []
originalTracks.slice().map(track => {
track.trackSelect();
track.trackScrollToView();
const clipName = getClipName()
if (clipName) {
trackClipList.push({
trackName: track,
clipName: clipName
})
}
});
sf.ui.proTools.trackSelectByName({ names: originalTracks.map(x => x.normalizedTrackName) });
return trackClipList
}
function getSelectedCount() {
const visibleTracks = sf.ui.proTools.visibleTrackNames
const selectedTracks = sf.ui.proTools.selectedTrackNames
const firstSelectedIndex = visibleTracks.indexOf(selectedTracks[0])
const lastSelectedIndex = visibleTracks.indexOf(selectedTracks[selectedTracks.length - 1])
return lastSelectedIndex - firstSelectedIndex + 1
}
function dismissNameExistsWarning(name, index, action) {
if (sf.ui.proTools.confirmationDialog.invalidate().buttons.whoseTitle.is('OK').first.exists) {
sf.ui.proTools.confirmationDialog.buttons.whoseTitle.is('OK').first.elementClick();
sf.ui.proTools.confirmationDialog.buttons.whoseTitle.is('OK').first.elementWaitFor({ waitType: "Disappear" })
sf.ui.proTools.focusedWindow.textFields.first.elementSetTextFieldWithAreaValue({
value: name + "_" + (index + 1)
});
action.elementClick()
}
}
function setTrackNames() {
const firstToLastSelectedCount = getSelectedCount()
//Get my list
const trackClipList = getTrackClipList()
//Scrool to view first track
trackClipList[0].trackName.trackSelect();
trackClipList[0].trackName.trackScrollToView()
// Open rename window
trackClipList[0].trackName.popupButtons.first.mouseClickElement({ clickCount: 2 })
// Wait for rename window
sf.ui.proTools.windows.whoseTitle.is(trackClipList[0].trackName.popupButtons.first.value.invalidate().value).first.elementWaitFor();
// //Get the elements of buttons
const [ok, cncl, pr, next] = sf.ui.proTools.focusedWindow.buttons.map(x => x)
// // Loop selected tracks
for (let i = 0; i < firstToLastSelectedCount; i++) {
const oldTrackName = () => sf.ui.proTools.focusedWindow.textFields.first.value.invalidate().value;
const newName = trackClipList.filter(x => x.trackName.normalizedTrackName == oldTrackName())[0]
if (trackClipList.some(x => x.trackName.normalizedTrackName == oldTrackName())) {
// Set track name
while (true) {
if (oldTrackName() != newName.clipName) {
sf.ui.proTools.focusedWindow.textFields.first.elementSetTextFieldWithAreaValue({
value: newName.clipName
});
sf.wait({ intervalMs: 5 })
} else {
next.elementClick()
dismissNameExistsWarning(newName.clipName, i, next)
break;
}
};
} else {
next.elementClick()
}
// If its the last track press ok
if (i === firstToLastSelectedCount - 1) {
ok.elementClick()
}
};
};
sf.ui.proTools.appActivateMainWindow()
sf.ui.proTools.invalidate()
setTrackNames()
Linked from:
- MMatt Friedman @Matt_Friedman
That works out awesome, way better than the clunky and easily broken hack I came up with!
Thanks Samuel!
- In reply tosamuel_henriques⬆:samuel henriques @samuel_henriques
Here's a new version using PT API.
// Fix if track name exists function checkTrackDuplicate(trackName) { const trackNameExists = sf.app.proTools.tracks.invalidate().allItems.find(tn => tn.name === trackName) if (trackNameExists && trackNameExists.name) { return trackName + ".1" } else { return trackName }; }; // GROUP CLIP NAMES ARE ERRONEOUS ON track widths more than mono!!! function clipNameToTrackName() { const clipInfo = sf.app.proTools.getSelectedClipInfo().clips let trackInfoFilter = [] let obj = {} for (let i = 0; i < clipInfo.length; i++) { const trackName = clipInfo[i]["TrackName"]; const clipName = clipInfo[i]["ClipName"]; const cleanClipName = clipName && clipName.split(".").slice(0, 1).join() let isClip = !clipName.startsWith("(fade ") && !clipName.endsWith(" fade)") if (!obj[trackName] && isClip) { obj[trackName] = cleanClipName trackInfoFilter.push({ trackName, clipName: cleanClipName }) }; }; trackInfoFilter.forEach(tr => { let oldName = tr.trackName let newName = tr.trackName !== tr.clipName ? checkTrackDuplicate(tr.clipName) : tr.trackName sf.app.proTools.renameTrack({ oldName, newName, onError: "Continue" }); globalState.clipNameToTrackNameUndo.push({ oldName: newName, newName: oldName }) }) }; function undoTrackRename() { globalState.clipNameToTrackNameUndo.reverse().forEach(tr => { sf.app.proTools.renameTrack({ oldName: tr.oldName, newName: tr.newName, onError: "Continue" }); }) } // Press ALT + Triger for undo. if (event.keyboardState.hasAlt) { undoTrackRename(); } else { globalState.clipNameToTrackNameUndo = [] clipNameToTrackName(); }
- MMatt Friedman @Matt_Friedman
Everything gets better with PT API!! Thanks Samuel
- AIn reply tosamuel_henriques⬆:Alessandro Tsamis @Alessandro_Tsamis
Cane someone make a version for all selected tracks?