No internet connection
  1. Home
  2. How to

Open all nested folders

By Keith Smith @Keith_Smith
    2024-12-26 06:13:12.300Z

    I'm attempting to write a script that will open a selected parent folder and all children folders at once. Here's what I've got, but something isn't working....

    function getTrackDepth(track) {
    return Math.floor((track.titleButton.frame.x - track.frame.x) / 15);
    }

    function getTrackFolderStructure() {
    var root = { children: [] };
    var stack = [];
    stack[0] = root;
    var flatList = sf.ui.proTools.visibleTrackHeaders.map(t => ({ track: t, depth: getTrackDepth(t) }));
    for (var i = 0; i < flatList.length; i++) {
    var flatItem = flatList[i];
    var node = {
    name: flatItem.track.normalizedTrackName,
    type: flatItem.track.title.value.match(/ - ([^-]+)$/)[1].trim().replace(/track$/i, '').trim().toLowerCase(),
    track: flatItem.track,
    children: []
    };
    stack[flatItem.depth] = node;
    stack[flatItem.depth - 1].children.push(node);
    }
    return root;
    }

    function findNearestParentFolder(root, trackName) {
    var folderStack = [];
    function walk(node) {
    var isFolder = node.type && node.type.indexOf('folder') >= 0;
    if (isFolder) {
    folderStack.push(node);
    }
    if (node.name === trackName) {
    return folderStack.slice(-1)[0];
    }
    for (var i = 0; i < node.children.length; i++) {
    var res = walk(node.children[i]);
    if (res) return res;
    }
    if (isFolder) {
    folderStack.pop();
    }
    }
    return walk(root);
    }

    function expandAllFoldersInNode(node) {
    if (node.type.includes('folder')) {
    node.track.folderTrackSetOpen({ targetValue: "Enable" });
    for (var i = 0; i < node.children.length; i++) {
    expandAllFoldersInNode(node.children[i]);
    }
    }
    }

    function expandSelectedParentFolder() {
    // Bring Pro Tools to the front
    sf.ui.proTools.appActivate();

    // Wait for Pro Tools to be active
    setTimeout(() => {
        // Get the track folder structure
        var root = getTrackFolderStructure();
    
        // Get the selected track
        var selectedTrack = sf.ui.proTools.selectedTrackHeaders[0];
        if (!selectedTrack) {
            console.error("No track is selected.");
            return;
        }
    
        // Find the nearest parent folder of the selected track
        var nearestFolder = findNearestParentFolder(root, selectedTrack.normalizedTrackName);
        if (!nearestFolder) {
            console.error("No parent folder found.");
            return;
        }
    
        // Expand the parent folder and all nested children folders
        expandAllFoldersInNode(nearestFolder);
    }, 2000);
    

    }

    expandSelectedParentFolder();

    Thanks for the help!

    • 1 replies
    1. S
      Sreejesh Nair @Sreejesh_Nair
        2024-12-26 07:36:50.954Z

        If you have the parent folder selected, then the below code is a quick way to open all the nested folders. If the parent is open then it will close and reopen all the folders within that parent.

        sf.ui.proTools.appActivate();
        sf.ui.proTools.invalidate();
        
        if (sf.ui.proTools.selectedTrack.openCloseFolderButton.value.value != "Selected") {
            sf.ui.proTools.selectedTrack.openCloseFolderButton.mouseClickElement({ isCommand: true });
        } else {
            sf.ui.proTools.selectedTrack.openCloseFolderButton.mouseClickElement({ isCommand: true });
            sf.ui.proTools.invalidate();
            sf.waitFor({
                callback: () => sf.ui.proTools.selectedTrack.openCloseFolderButton.value.value != "Selected"
            })
            sf.ui.proTools.selectedTrack.openCloseFolderButton.mouseClickElement({ isCommand: true });
        }
        

        The ideal way would be to get the entire folder structure, and pass the folder names into an array called foldersToOpen within that to

                sf.app.proTools.setTrackOpenState({
                    enabled: true,
                    trackNames: foldersToOpen,
                });